1 /*
2 * Copyright (C) 2023-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "attribute.h"
17
18 #include "securec.h"
19
20 #include "adaptor_log.h"
21 #include "adaptor_memory.h"
22
23 #ifdef IAM_TEST_ENABLE
24 #define IAM_STATIC
25 #else
26 #define IAM_STATIC static
27 #endif
28
29 #define SUCCESS RESULT_SUCCESS
30 #define GENERAL_ERROR RESULT_GENERAL_ERROR
31 #define INVALID_PARAMETERS RESULT_BAD_PARAM
32
33 AttributeKey g_attributeKeyArray[] = {
34 ATTR_RESULT_CODE,
35 ATTR_SIGNATURE,
36 ATTR_IDENTIFY_MODE,
37 ATTR_TEMPLATE_ID,
38 ATTR_TEMPLATE_ID_LIST,
39 ATTR_REMAIN_ATTEMPTS,
40 ATTR_LOCKOUT_DURATION,
41 ATTR_SCHEDULE_ID,
42 ATTR_DATA,
43 ATTR_PIN_SUB_TYPE,
44 ATTR_SCHEDULE_MODE,
45 ATTR_PROPERTY_MODE,
46 ATTR_TYPE,
47 ATTR_CREDENTIAL_ID,
48 ATTR_CONTROLLER,
49 ATTR_CALLER_UID,
50 ATTR_RESULT,
51 ATTR_CAPABILITY_LEVEL,
52 ATTR_ALGORITHM_INFO,
53 ATTR_TIME_STAMP,
54 ATTR_ROOT_SECRET,
55 ATTR_ROOT,
56 ATTR_ATTRS,
57 ATTR_EXECUTOR_INDEX,
58 ATTR_PUBLIC_KEY,
59 ATTR_EXECUTOR_MATCHER,
60 ATTR_LOCAL_UDID,
61 ATTR_PEER_UDID,
62 ATTR_LOCKOUT_DURATION,
63 ATTR_REMAIN_ATTEMPTS,
64 ATTR_USER_ID,
65 ATTR_TOKEN,
66 ATTR_EXECUTOR_ROLE,
67 ATTR_ESL,
68 ATTR_VERIFIER_UDID,
69 ATTR_COLLECTOR_UDID,
70 ATTR_CHALLENGE,
71 ATTR_EXPIRED_SYS_TIME,
72 };
73
74 #define ARRAY_LENGTH(array) (uint32_t)(sizeof(array) / sizeof((array)[0]))
75 #define ATTRIBUTE_LEN (ARRAY_LENGTH(g_attributeKeyArray))
76
77 typedef struct {
78 Uint8Array *values[ATTRIBUTE_LEN];
79 } AttributeImpl;
80
Ntohl32(uint32_t in)81 IAM_STATIC uint32_t Ntohl32(uint32_t in)
82 {
83 return in;
84 }
85
Htonl32(uint32_t in)86 IAM_STATIC uint32_t Htonl32(uint32_t in)
87 {
88 return in;
89 }
90
Ntohl64(uint64_t in)91 IAM_STATIC uint64_t Ntohl64(uint64_t in)
92 {
93 return in;
94 }
95
Htonl64(uint64_t in)96 IAM_STATIC uint64_t Htonl64(uint64_t in)
97 {
98 return in;
99 }
100
Ntohl64Array(Uint64Array * array)101 IAM_STATIC void Ntohl64Array(Uint64Array *array)
102 {
103 for (uint32_t i = 0; i < array->len; i++) {
104 array->data[i] = Ntohl64(array->data[i]);
105 }
106 }
107
Htonl64Array(Uint64Array * array)108 IAM_STATIC void Htonl64Array(Uint64Array *array)
109 {
110 for (uint32_t i = 0; i < array->len; i++) {
111 array->data[i] = Htonl64(array->data[i]);
112 }
113 }
114
GetAttributeIndex(AttributeKey key,uint32_t * index)115 IAM_STATIC ResultCode GetAttributeIndex(AttributeKey key, uint32_t *index)
116 {
117 for (uint32_t i = 0; i < ATTRIBUTE_LEN; ++i) {
118 if (g_attributeKeyArray[i] == key) {
119 *index = i;
120 return SUCCESS;
121 }
122 }
123
124 return GENERAL_ERROR;
125 }
126
ReadDataFromMsg(const Uint8Array msg,uint32_t * readIndex,Uint8Array * retData)127 IAM_STATIC ResultCode ReadDataFromMsg(const Uint8Array msg, uint32_t *readIndex, Uint8Array *retData)
128 {
129 if (msg.len <= *readIndex) {
130 LOG_ERROR("msg length is not enough");
131 return GENERAL_ERROR;
132 }
133
134 if (msg.len - *readIndex < retData->len) {
135 LOG_ERROR("remain data length is not enough");
136 return GENERAL_ERROR;
137 }
138
139 if (memcpy_s(retData->data, retData->len, msg.data + *readIndex, retData->len) != EOK) {
140 LOG_ERROR("memcpy_s fail");
141 return GENERAL_ERROR;
142 }
143
144 *readIndex += retData->len;
145 return SUCCESS;
146 }
147
ReadUint32FromMsg(const Uint8Array msg,uint32_t * readIndex,uint32_t * retValue)148 IAM_STATIC ResultCode ReadUint32FromMsg(const Uint8Array msg, uint32_t *readIndex, uint32_t *retValue)
149 {
150 uint32_t netOrderValue;
151 Uint8Array uint8Data = { (uint8_t *)&netOrderValue, sizeof(netOrderValue) };
152 ResultCode result = ReadDataFromMsg(msg, readIndex, &uint8Data);
153 if (result != SUCCESS) {
154 LOG_ERROR("read data fail");
155 return GENERAL_ERROR;
156 }
157
158 *retValue = Ntohl32(netOrderValue);
159 return SUCCESS;
160 }
161
WriteDataToMsg(Uint8Array * msg,uint32_t * writeIndex,const Uint8Array data)162 IAM_STATIC ResultCode WriteDataToMsg(Uint8Array *msg, uint32_t *writeIndex, const Uint8Array data)
163 {
164 if (msg->len <= *writeIndex) {
165 LOG_ERROR("msg length is not enough");
166 return GENERAL_ERROR;
167 }
168
169 if (msg->len - *writeIndex < data.len) {
170 LOG_ERROR("remain data size is not enough");
171 return GENERAL_ERROR;
172 }
173
174 if (memcpy_s(msg->data + *writeIndex, msg->len - *writeIndex, data.data, data.len) != EOK) {
175 LOG_ERROR("memcpy_s fail");
176 return GENERAL_ERROR;
177 }
178
179 *writeIndex += data.len;
180 return SUCCESS;
181 }
182
WriteUInt32ToMsg(Uint8Array * msg,uint32_t * writeIndex,uint32_t value)183 IAM_STATIC ResultCode WriteUInt32ToMsg(Uint8Array *msg, uint32_t *writeIndex, uint32_t value)
184 {
185 uint32_t netOrderValue = Htonl32(value);
186 ResultCode result =
187 WriteDataToMsg(msg, writeIndex, (Uint8Array){ (uint8_t *)&netOrderValue, sizeof(netOrderValue) });
188 if (result != SUCCESS) {
189 LOG_ERROR("write data fail");
190 return GENERAL_ERROR;
191 }
192 return SUCCESS;
193 }
194
ParseAttributeSerializedMsgInner(Attribute * attribute,const Uint8Array msg,const Uint8Array * readBuffer)195 IAM_STATIC ResultCode ParseAttributeSerializedMsgInner(Attribute *attribute, const Uint8Array msg,
196 const Uint8Array *readBuffer)
197 {
198 uint32_t readIndex = 0;
199 while (readIndex < msg.len) {
200 uint32_t type;
201 ResultCode readTypeResult = ReadUint32FromMsg(msg, &readIndex, &type);
202 IF_TRUE_LOGE_AND_RETURN_VAL(readTypeResult != SUCCESS, GENERAL_ERROR);
203
204 uint32_t length;
205 ResultCode readLengthResult = ReadUint32FromMsg(msg, &readIndex, &length);
206 IF_TRUE_LOGE_AND_RETURN_VAL(readLengthResult != SUCCESS, GENERAL_ERROR);
207 IF_TRUE_LOGE_AND_RETURN_VAL(length > readBuffer->len, GENERAL_ERROR);
208
209 Uint8Array readData = { readBuffer->data, length };
210 if (length > 0) {
211 ResultCode readDataResult = ReadDataFromMsg(msg, &readIndex, &readData);
212 IF_TRUE_LOGE_AND_RETURN_VAL(readDataResult != SUCCESS, GENERAL_ERROR);
213 }
214
215 ResultCode setAttrResult = SetAttributeUint8Array(attribute, type, readData);
216 IF_TRUE_LOGE_AND_RETURN_VAL(setAttrResult != SUCCESS, GENERAL_ERROR);
217 }
218
219 return SUCCESS;
220 }
221
ParseAttributeSerializedMsg(Attribute * attribute,const Uint8Array msg)222 IAM_STATIC ResultCode ParseAttributeSerializedMsg(Attribute *attribute, const Uint8Array msg)
223 {
224 Uint8Array *readBuffer = CreateUint8ArrayBySize(MAX_EXECUTOR_MSG_LEN);
225 IF_TRUE_LOGE_AND_RETURN_VAL(readBuffer == NULL, GENERAL_ERROR);
226
227 ResultCode result = ParseAttributeSerializedMsgInner(attribute, msg, readBuffer);
228 if (result != SUCCESS) {
229 LOG_ERROR("ParseAttributeSerializedMsgInner fail");
230 }
231 DestroyUint8Array(&readBuffer);
232
233 return result;
234 }
235
ParseMultiDataSerializedMsg(const Uint8Array msg,Uint8Array * subMsgData,int * subMsgSize)236 ResultCode ParseMultiDataSerializedMsg(const Uint8Array msg, Uint8Array *subMsgData, int *subMsgSize)
237 {
238 IF_TRUE_LOGE_AND_RETURN_VAL(subMsgSize == NULL, GENERAL_ERROR);
239 IF_TRUE_LOGE_AND_RETURN_VAL(subMsgData == NULL, GENERAL_ERROR);
240
241 uint32_t readIndex = 0;
242 uint32_t subMsgIndex = 0;
243 while (readIndex < msg.len) {
244 uint32_t length;
245 ResultCode readLengthResult = ReadUint32FromMsg(msg, &readIndex, &length);
246 IF_TRUE_LOGE_AND_RETURN_VAL(readLengthResult != SUCCESS, GENERAL_ERROR);
247
248 if (length > 0) {
249 IF_TRUE_LOGE_AND_RETURN_VAL(subMsgIndex >= *subMsgSize, GENERAL_ERROR);
250 // subMsgData is freed in outer function
251 subMsgData[subMsgIndex] = (Uint8Array){ Malloc(length), length };
252 IF_TRUE_LOGE_AND_RETURN_VAL(subMsgData[subMsgIndex].data == NULL, GENERAL_ERROR);
253 ResultCode readDataResult = ReadDataFromMsg(msg, &readIndex, &subMsgData[subMsgIndex]);
254 IF_TRUE_LOGE_AND_RETURN_VAL(readDataResult != SUCCESS, GENERAL_ERROR);
255 subMsgIndex++;
256 }
257 }
258
259 *subMsgSize = subMsgIndex;
260 return SUCCESS;
261 }
262
CreateEmptyAttribute(void)263 Attribute *CreateEmptyAttribute(void)
264 {
265 AttributeImpl *attribute = Malloc(sizeof(AttributeImpl));
266 IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, NULL);
267 (void)memset_s(attribute, sizeof(AttributeImpl), 0, sizeof(AttributeImpl));
268
269 return attribute;
270 }
271
CreateAttributeFromSerializedMsg(const Uint8Array msg)272 Attribute *CreateAttributeFromSerializedMsg(const Uint8Array msg)
273 {
274 IF_TRUE_LOGE_AND_RETURN_VAL(IS_ARRAY_NULL(msg), NULL);
275
276 Attribute *attribute = CreateEmptyAttribute();
277 if (attribute == NULL) {
278 LOG_ERROR("CreateEmptyAttribute failed");
279 return NULL;
280 }
281
282 ResultCode result = ParseAttributeSerializedMsg(attribute, msg);
283 if (result != SUCCESS) {
284 LOG_ERROR("ParseAttributeSerializedMsg failed");
285 FreeAttribute((Attribute **)&attribute);
286 return NULL;
287 }
288
289 return attribute;
290 }
291
GetAttributeSerializedMsg(const Attribute * attributePublic,Uint8Array * retMsg)292 ResultCode GetAttributeSerializedMsg(const Attribute *attributePublic, Uint8Array *retMsg)
293 {
294 IF_TRUE_LOGE_AND_RETURN_VAL(attributePublic == NULL, INVALID_PARAMETERS);
295 IF_TRUE_LOGE_AND_RETURN_VAL(retMsg == NULL, INVALID_PARAMETERS);
296 IF_TRUE_LOGE_AND_RETURN_VAL(IS_ARRAY_NULL(*retMsg), INVALID_PARAMETERS);
297
298 const AttributeImpl *attribute = (const AttributeImpl *)attributePublic;
299 uint32_t writeIndex = 0;
300 for (uint32_t i = 0; i < ATTRIBUTE_LEN; i++) {
301 Uint8Array *array = attribute->values[i];
302 if (array == NULL) {
303 continue;
304 }
305
306 ResultCode writeTypeResult = WriteUInt32ToMsg(retMsg, &writeIndex, g_attributeKeyArray[i]);
307 IF_TRUE_LOGE_AND_RETURN_VAL(writeTypeResult != SUCCESS, GENERAL_ERROR);
308
309 ResultCode writeLengthResult = WriteUInt32ToMsg(retMsg, &writeIndex, array->len);
310 IF_TRUE_LOGE_AND_RETURN_VAL(writeLengthResult != SUCCESS, GENERAL_ERROR);
311
312 if (array->len == 0) {
313 continue;
314 }
315 ResultCode writeDataResult =
316 WriteDataToMsg(retMsg, &writeIndex, *array);
317 IF_TRUE_LOGE_AND_RETURN_VAL(writeDataResult != SUCCESS, GENERAL_ERROR);
318 }
319
320 retMsg->len = writeIndex;
321 return SUCCESS;
322 }
323
FreeAttribute(Attribute ** attribute)324 void FreeAttribute(Attribute **attribute)
325 {
326 IF_TRUE_LOGE_AND_RETURN(attribute == NULL);
327 IF_TRUE_LOGE_AND_RETURN(*attribute == NULL);
328 AttributeImpl *impl = (AttributeImpl *)*attribute;
329 for (uint32_t i = 0; i < ATTRIBUTE_LEN; ++i) {
330 DestroyUint8Array(&impl->values[i]);
331 }
332
333 IAM_FREE_AND_SET_NULL(*attribute);
334 }
335
GetAttributeUint32(const Attribute * attribute,AttributeKey key,uint32_t * value)336 ResultCode GetAttributeUint32(const Attribute *attribute, AttributeKey key, uint32_t *value)
337 {
338 IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
339 IF_TRUE_LOGE_AND_RETURN_VAL(value == NULL, INVALID_PARAMETERS);
340
341 uint32_t netOrderValue;
342 Uint8Array uint32Data = { (uint8_t *)&netOrderValue, sizeof(netOrderValue) };
343 ResultCode getAttrResult = GetAttributeUint8Array(attribute, key, &uint32Data);
344 IF_TRUE_LOGE_AND_RETURN_VAL(getAttrResult != SUCCESS, GENERAL_ERROR);
345 IF_TRUE_LOGE_AND_RETURN_VAL(uint32Data.len != sizeof(netOrderValue), GENERAL_ERROR);
346
347 *value = Ntohl32(netOrderValue);
348 return SUCCESS;
349 }
350
SetAttributeUint32(Attribute * attribute,AttributeKey key,const uint32_t value)351 ResultCode SetAttributeUint32(Attribute *attribute, AttributeKey key, const uint32_t value)
352 {
353 IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
354
355 uint32_t netOrderValue = Htonl32(value);
356 ResultCode result =
357 SetAttributeUint8Array(attribute, key, (Uint8Array) { (uint8_t *)&netOrderValue, sizeof(netOrderValue) });
358 IF_TRUE_LOGE_AND_RETURN_VAL(result != SUCCESS, GENERAL_ERROR);
359
360 return result;
361 }
362
GetAttributeInt32(const Attribute * attribute,AttributeKey key,int32_t * retValue)363 ResultCode GetAttributeInt32(const Attribute *attribute, AttributeKey key, int32_t *retValue)
364 {
365 IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
366 IF_TRUE_LOGE_AND_RETURN_VAL(retValue == NULL, INVALID_PARAMETERS);
367
368 return GetAttributeUint32(attribute, key, (uint32_t *)retValue);
369 }
370
SetAttributeInt32(Attribute * attribute,AttributeKey key,const int32_t value)371 ResultCode SetAttributeInt32(Attribute *attribute, AttributeKey key, const int32_t value)
372 {
373 IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
374
375 return SetAttributeUint32(attribute, key, (uint32_t)value);
376 }
377
GetAttributeUint64(const Attribute * attribute,AttributeKey key,uint64_t * retValue)378 ResultCode GetAttributeUint64(const Attribute *attribute, AttributeKey key, uint64_t *retValue)
379 {
380 IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
381 IF_TRUE_LOGE_AND_RETURN_VAL(retValue == NULL, INVALID_PARAMETERS);
382
383 uint64_t netOrderValue;
384 Uint8Array uint64Data = { (uint8_t *)&netOrderValue, sizeof(netOrderValue) };
385 ResultCode getAttrResult = GetAttributeUint8Array(attribute, key, &uint64Data);
386 IF_TRUE_LOGE_AND_RETURN_VAL(getAttrResult != SUCCESS, GENERAL_ERROR);
387 IF_TRUE_LOGE_AND_RETURN_VAL(uint64Data.len != sizeof(netOrderValue), GENERAL_ERROR);
388
389 *retValue = Ntohl64(netOrderValue);
390 return SUCCESS;
391 }
392
SetAttributeUint64(Attribute * attribute,AttributeKey key,const uint64_t value)393 ResultCode SetAttributeUint64(Attribute *attribute, AttributeKey key, const uint64_t value)
394 {
395 IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
396
397 uint64_t netOrderValue = Htonl64(value);
398 ResultCode setAttrResult =
399 SetAttributeUint8Array(attribute, key, (Uint8Array){ (uint8_t *)&netOrderValue, sizeof(netOrderValue) });
400 IF_TRUE_LOGE_AND_RETURN_VAL(setAttrResult != SUCCESS, GENERAL_ERROR);
401
402 return SUCCESS;
403 }
404
GetAttributeUint8Array(const Attribute * attributePub,AttributeKey key,Uint8Array * retData)405 ResultCode GetAttributeUint8Array(const Attribute *attributePub, AttributeKey key, Uint8Array *retData)
406 {
407 IF_TRUE_LOGE_AND_RETURN_VAL(attributePub == NULL, INVALID_PARAMETERS);
408 IF_TRUE_LOGE_AND_RETURN_VAL(retData == NULL, INVALID_PARAMETERS);
409 IF_TRUE_LOGE_AND_RETURN_VAL(IS_ARRAY_NULL(*retData), INVALID_PARAMETERS);
410
411 const AttributeImpl *attribute = (const AttributeImpl *)attributePub;
412
413 uint32_t attributeIndex;
414 ResultCode getAttrIndexResult = GetAttributeIndex(key, &attributeIndex);
415 IF_TRUE_LOGE_AND_RETURN_VAL(getAttrIndexResult != SUCCESS, GENERAL_ERROR);
416
417 if (attribute->values[attributeIndex] == NULL) {
418 LOG_ERROR("data is not set");
419 return GENERAL_ERROR;
420 }
421
422 if (attribute->values[attributeIndex]->data != NULL && attribute->values[attributeIndex]->len != 0) {
423 errno_t memcpyRet = memcpy_s(retData->data, retData->len, attribute->values[attributeIndex]->data,
424 attribute->values[attributeIndex]->len);
425 IF_TRUE_LOGE_AND_RETURN_VAL(memcpyRet != EOK, GENERAL_ERROR);
426 } else {
427 LOG_INFO("the current data is an empty array");
428 }
429 retData->len = attribute->values[attributeIndex]->len;
430
431 return SUCCESS;
432 }
433
SetAttributeUint8Array(Attribute * attributePub,AttributeKey key,const Uint8Array data)434 ResultCode SetAttributeUint8Array(Attribute *attributePub, AttributeKey key, const Uint8Array data)
435 {
436 IF_TRUE_LOGE_AND_RETURN_VAL(attributePub == NULL, INVALID_PARAMETERS);
437 IF_TRUE_LOGE_AND_RETURN_VAL(!IS_ARRAY_VALID(data), INVALID_PARAMETERS);
438
439 AttributeImpl *attribute = (AttributeImpl *)attributePub;
440
441 uint32_t attributeIndex;
442 ResultCode getAttrIndexResult = GetAttributeIndex(key, &attributeIndex);
443 IF_TRUE_LOGE_AND_RETURN_VAL(getAttrIndexResult != SUCCESS, GENERAL_ERROR);
444
445 DestroyUint8Array(&attribute->values[attributeIndex]);
446 attribute->values[attributeIndex] = CreateUint8ArrayByData(data.data, data.len);
447 if (attribute->values[attributeIndex] == NULL) {
448 LOG_ERROR("CreateUint8ArrayByData fail");
449 return GENERAL_ERROR;
450 }
451
452 return SUCCESS;
453 }
454
GetAttributeUint64Array(const Attribute * attribute,AttributeKey key,Uint64Array * retData)455 ResultCode GetAttributeUint64Array(const Attribute *attribute, AttributeKey key, Uint64Array *retData)
456 {
457 IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
458 IF_TRUE_LOGE_AND_RETURN_VAL(retData == NULL, INVALID_PARAMETERS);
459 IF_TRUE_LOGE_AND_RETURN_VAL(IS_ARRAY_NULL(*retData), INVALID_PARAMETERS);
460
461 Uint8Array uint64ArrayData = { (uint8_t *)retData->data, retData->len * sizeof(uint64_t) };
462 ResultCode getAttrResult = GetAttributeUint8Array(attribute, key, &uint64ArrayData);
463 IF_TRUE_LOGE_AND_RETURN_VAL(getAttrResult != SUCCESS, GENERAL_ERROR);
464 if (uint64ArrayData.len % sizeof(uint64_t) != 0) {
465 LOG_ERROR("uint8 length %u is incorrect", uint64ArrayData.len);
466 return GENERAL_ERROR;
467 }
468 Ntohl64Array(retData);
469
470 retData->len = uint64ArrayData.len / sizeof(uint64_t);
471 return SUCCESS;
472 }
473
SetAttributeUint64Array(Attribute * attribute,AttributeKey key,const Uint64Array data)474 ResultCode SetAttributeUint64Array(Attribute *attribute, AttributeKey key, const Uint64Array data)
475 {
476 IF_TRUE_LOGE_AND_RETURN_VAL(attribute == NULL, INVALID_PARAMETERS);
477 IF_TRUE_LOGE_AND_RETURN_VAL(!IS_ARRAY_VALID(data), INVALID_PARAMETERS);
478
479 Uint64Array *netOrderData = CreateUint64ArrayByData(data.data, data.len);
480 IF_TRUE_LOGE_AND_RETURN_VAL(netOrderData == NULL, GENERAL_ERROR);
481
482 ResultCode result = GENERAL_ERROR;
483 do {
484 Htonl64Array(netOrderData);
485 if (netOrderData->len > UINT32_MAX / sizeof(uint64_t)) {
486 LOG_ERROR("netOrderData->len is invalid");
487 break;
488 }
489 result = SetAttributeUint8Array(attribute, key,
490 (Uint8Array) { (uint8_t *)netOrderData->data, netOrderData->len * sizeof(uint64_t) });
491 if (result != SUCCESS) {
492 LOG_ERROR("SetAttributeUint8Array fail");
493 break;
494 }
495 } while (0);
496
497 DestroyUint64Array(&netOrderData);
498 return result;
499 }
500
GetMultiDataSerializedMsg(Uint8Array * sourceArrayMsg,uint32_t size,Uint8Array * retMsg)501 ResultCode GetMultiDataSerializedMsg(Uint8Array *sourceArrayMsg, uint32_t size, Uint8Array *retMsg)
502 {
503 IF_TRUE_LOGE_AND_RETURN_VAL(sourceArrayMsg == NULL, INVALID_PARAMETERS);
504 IF_TRUE_LOGE_AND_RETURN_VAL(retMsg == NULL, INVALID_PARAMETERS);
505 IF_TRUE_LOGE_AND_RETURN_VAL(IS_ARRAY_NULL(*retMsg), INVALID_PARAMETERS);
506
507 uint32_t writeIndex = 0;
508 for (uint32_t i = 0; i < size; i++) {
509 IF_TRUE_LOGE_AND_RETURN_VAL(sourceArrayMsg[i].data == NULL, GENERAL_ERROR);
510 Uint8Array sourceMsg = sourceArrayMsg[i];
511 if (sourceMsg.len == 0) {
512 continue;
513 }
514 ResultCode writeLengthResult = WriteUInt32ToMsg(retMsg, &writeIndex, sourceMsg.len);
515 IF_TRUE_LOGE_AND_RETURN_VAL(writeLengthResult != SUCCESS, GENERAL_ERROR);
516
517 ResultCode writeDataResult = WriteDataToMsg(retMsg, &writeIndex, sourceMsg);
518 IF_TRUE_LOGE_AND_RETURN_VAL(writeDataResult != SUCCESS, GENERAL_ERROR);
519 }
520 retMsg->len = writeIndex;
521 return SUCCESS;
522 }
523