1 //******************************************************************
3 // Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 // Defining _POSIX_C_SOURCE macro with 200112L (or greater) as value
22 // causes header files to expose definitions
23 // corresponding to the POSIX.1-2001 base
24 // specification (excluding the XSI extension).
25 // For POSIX.1-2001 base specification,
26 // Refer http://pubs.opengroup.org/onlinepubs/009695399/
27 // Required for strok_r
28 #define _POSIX_C_SOURCE 200112L
30 #include "ocpayloadcbor.h"
33 #include "oic_string.h"
34 #include "oic_malloc.h"
35 #include "ocstackinternal.h"
36 #include "ocpayload.h"
38 #include "oic_string.h"
39 #include "payload_logging.h"
40 #include "rdpayload.h"
42 #define TAG "OIC_RI_PAYLOADPARSE"
44 static OCStackResult OCParseDiscoveryPayload(OCPayload** outPayload, CborValue* arrayVal);
45 static OCStackResult OCParseDevicePayload(OCPayload** outPayload, CborValue* arrayVal);
46 static OCStackResult OCParsePlatformPayload(OCPayload** outPayload, CborValue* arrayVal);
47 static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue* repParent);
48 static OCStackResult OCParseRepPayload(OCPayload** outPayload, CborValue* arrayVal);
49 static OCStackResult OCParsePresencePayload(OCPayload** outPayload, CborValue* arrayVal);
50 static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* arrayVal);
52 OCStackResult OCParsePayload(OCPayload** outPayload, OCPayloadType payloadType,
53 const uint8_t* payload, size_t payloadSize)
59 OIC_LOG_V(INFO, TAG, "CBOR Parsing size: %zu", payloadSize);
60 if((err = cbor_parser_init(payload, payloadSize, 0, &parser, &rootValue)) != false)
62 OIC_LOG_V(ERROR, TAG, "CBOR Parser init failed: %d", err);
63 return OC_STACK_ERROR;
66 OCStackResult result = OC_STACK_ERROR;
69 case PAYLOAD_TYPE_DISCOVERY:
70 result = OCParseDiscoveryPayload(outPayload, &rootValue);
72 case PAYLOAD_TYPE_DEVICE:
73 result = OCParseDevicePayload(outPayload, &rootValue);
75 case PAYLOAD_TYPE_PLATFORM:
76 result = OCParsePlatformPayload(outPayload, &rootValue);
78 case PAYLOAD_TYPE_REPRESENTATION:
79 result = OCParseRepPayload(outPayload, &rootValue);
81 case PAYLOAD_TYPE_PRESENCE:
82 result = OCParsePresencePayload(outPayload, &rootValue);
84 case PAYLOAD_TYPE_SECURITY:
85 result = OCParseSecurityPayload(outPayload, &rootValue);
88 result = OCRDCborToPayload(&rootValue, outPayload);
91 OIC_LOG_V(ERROR, TAG, "ParsePayload Type default: %d", payloadType);
92 result = OC_STACK_ERROR;
96 if(result != OC_STACK_OK)
98 OIC_LOG_V(INFO, TAG, "Finished parse payload, result is %d", result);
104 void OCFreeOCStringLL(OCStringLL* ll);
106 static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* rootValue)
110 return OC_STACK_INVALID_PARAM;
114 char * securityData = NULL;
115 CborValue strVal = {0};
118 err = cbor_value_enter_container(rootValue, &strVal);
119 if(CborNoError == err && cbor_value_is_text_string(&strVal))
121 err = cbor_value_dup_text_string(&strVal, &securityData, &len, NULL);
126 OIC_LOG(ERROR, TAG, "Cbor in error condition");
127 OICFree(securityData);
128 return OC_STACK_MALFORMED_RESPONSE;
131 *outPayload = (OCPayload*)OCSecurityPayloadCreate(securityData);
132 OICFree(securityData);
138 static char* InPlaceStringTrim(char* str)
140 while (str[0] == ' ')
145 size_t lastchar = strlen(str);
147 while (str[lastchar] == ' ')
149 str[lastchar] = '\0';
156 static OCStackResult OCParseDiscoveryPayload(OCPayload** outPayload, CborValue* rootValue)
160 return OC_STACK_INVALID_PARAM;
164 OCResourcePayload* resource = NULL;
165 uint16_t resourceCount = 0;
166 CborValue resourceMap = { 0 };
168 OCDiscoveryPayload* out = OCDiscoveryPayloadCreate();
171 return OC_STACK_NO_MEMORY;
174 // Root value is already inside the main root array
175 CborValue rootMap = { 0 };
177 // Enter the main root map
178 err = err || cbor_value_enter_container(rootValue, &rootMap);
180 CborValue curVal = { 0 };
181 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_DEVICE_ID, &curVal);
182 if (CborNoError != err)
184 OIC_LOG(ERROR, TAG, "Cbor find value failed.");
188 err = cbor_value_dup_byte_string(&curVal, &(out->sid), &len, NULL);
190 // BaseURI - Not a mandatory field
191 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_BASE_URI, &curVal);
192 if (CborNoError == err && cbor_value_is_valid(&curVal))
194 err = cbor_value_dup_text_string(&curVal, &(out->baseURI), &len, NULL);
195 if (CborNoError != err)
197 OIC_LOG(ERROR, TAG, "baseURI failed.");
202 // Look for Links which will have an array as the value
203 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_LINKS, &curVal);
204 if (CborNoError != err)
206 OIC_LOG(ERROR, TAG, "Cbor find value failed.");
210 // Enter the links array and start iterating through the array processing
211 // each resource which shows up as a map.
212 err = err || cbor_value_enter_container(&curVal, &resourceMap);
214 while (cbor_value_is_map(&resourceMap))
216 resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
219 OIC_LOG(ERROR, TAG, "Memory allocation failed");
220 OCDiscoveryPayloadDestroy(out);
221 return OC_STACK_NO_MEMORY;
225 CborValue uriVal = { 0 };
226 err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_HREF, &uriVal);
227 if (CborNoError != err)
229 OIC_LOG(ERROR, TAG, "Cbor finding href type failed.");
232 err = cbor_value_dup_text_string(&uriVal, &(resource->uri), &len, NULL);
233 if (CborNoError != err)
235 OIC_LOG(ERROR, TAG, "Cbor finding href value failed.");
239 CborValue rtVal = { 0 };
240 err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_RESOURCE_TYPE, &rtVal);
241 if (CborNoError != err)
243 OIC_LOG(ERROR, TAG, "Cbor finding rt type failed.");
246 if (cbor_value_is_text_string(&rtVal))
250 err = cbor_value_dup_text_string(&rtVal, &input, &len, NULL);
251 if (CborNoError != err)
253 OIC_LOG(ERROR, TAG, "Cbor finding rt value failed.");
258 char* curPtr = strtok_r(input, " ", &savePtr);
262 char* trimmed = InPlaceStringTrim(curPtr);
263 if (trimmed[0] !='\0')
265 if (!OCResourcePayloadAddResourceType(resource, trimmed))
267 OICFree(resource->uri);
268 OCFreeOCStringLL(resource->types);
270 OCDiscoveryPayloadDestroy(out);
271 return OC_STACK_NO_MEMORY;
274 curPtr = strtok_r(NULL, " ", &savePtr);
281 CborValue ifVal = { 0 };
282 err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_INTERFACE, &ifVal);
283 if (CborNoError != err)
285 OIC_LOG(ERROR, TAG, "Cbor finding if type failed.");
288 if (!err && cbor_value_is_text_string(&ifVal))
292 err = cbor_value_dup_text_string(&ifVal, &input, &len, NULL);
293 if (CborNoError != err)
295 OIC_LOG(ERROR, TAG, "Cbor finding if value failed.");
300 char* curPtr = strtok_r(input, " ", &savePtr);
304 char* trimmed = InPlaceStringTrim(curPtr);
305 if (trimmed[0] !='\0')
307 if (!OCResourcePayloadAddInterface(resource, trimmed))
309 OICFree(resource->uri);
310 OCFreeOCStringLL(resource->types);
312 OCDiscoveryPayloadDestroy(out);
313 return OC_STACK_NO_MEMORY;
316 curPtr = strtok_r(NULL, " ", &savePtr);
323 CborValue policyMap = { 0 };
324 err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_POLICY, &policyMap);
325 if (CborNoError != err)
327 OIC_LOG(ERROR, TAG, "Cbor finding policy type failed.");
331 CborValue val = { 0 };
332 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &val);
333 if (CborNoError != err)
335 OIC_LOG(ERROR, TAG, "Cbor finding bitmap type failed.");
339 err = cbor_value_get_uint64(&val, &temp);
340 if (CborNoError != err)
342 OIC_LOG(ERROR, TAG, "Cbor finding bitmap value failed.");
345 resource->bitmap = (uint8_t)temp;
347 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &val);
348 if (CborNoError != err)
350 OIC_LOG(ERROR, TAG, "Cbor finding secure type failed.");
353 if(cbor_value_is_valid(&val))
355 err = cbor_value_get_boolean(&val, &(resource->secure));
356 if (CborNoError != err)
358 OIC_LOG(ERROR, TAG, "Cbor finding secure value failed.");
362 CborValue port = { 0 };
363 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT,
365 if (CborNoError != err)
367 OIC_LOG(ERROR, TAG, "Cbor finding port type failed.");
370 if (cbor_value_is_valid(&port))
372 err = cbor_value_get_uint64(&port, &temp);
373 if (CborNoError != err)
375 OIC_LOG(ERROR, TAG, "Cbor finding port value failed.");
378 resource->port = (uint16_t)temp;
381 else if (out->baseURI)
384 CborValue port = { 0 };
385 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT, &port);
386 if (CborNoError != err)
388 OIC_LOG(ERROR, TAG, "Cbor finding port type failed.");
391 if(cbor_value_is_valid(&port))
393 err = cbor_value_get_uint64(&port, &temp);
394 if (CborNoError != err)
396 OIC_LOG(ERROR, TAG, "Cbor finding port value failed.");
399 resource->port = (uint16_t)temp;
403 err = cbor_value_advance(&resourceMap);
404 if (CborNoError != err)
406 OIC_LOG(ERROR, TAG, "Cbor advance value failed.");
410 OCDiscoveryPayloadAddNewResource(out, resource);
413 err = err || cbor_value_leave_container(rootValue, &resourceMap);
415 *outPayload = (OCPayload*)out;
419 OICFree(resource->uri);
420 OCFreeOCStringLL(resource->types);
421 OCFreeOCStringLL(resource->interfaces);
423 OCDiscoveryPayloadDestroy(out);
424 return OC_STACK_MALFORMED_RESPONSE;
427 static OCStackResult OCParseDevicePayload(OCPayload** outPayload, CborValue* rootValue)
431 return OC_STACK_INVALID_PARAM;
436 if(cbor_value_is_map(rootValue))
440 char* specVer = NULL;
445 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_ID, &repVal);
447 if(cbor_value_is_valid(&repVal))
449 err = err || cbor_value_dup_byte_string(&repVal, &sid, &len, NULL);
452 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_NAME, &repVal);
453 if(cbor_value_is_valid(&repVal))
455 err = err || cbor_value_dup_text_string(&repVal, &dname, &len, NULL);
457 // Device Spec Version
458 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_SPEC_VERSION, &repVal);
459 if(cbor_value_is_valid(&repVal))
461 err = err || cbor_value_dup_text_string(&repVal, &specVer, &len, NULL);
464 // Data Model Version
465 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_DATA_MODEL_VERSION, &repVal);
466 if (cbor_value_is_valid(&repVal))
468 err = err || cbor_value_dup_text_string(&repVal, &dmVer, &len, NULL);
471 err = err || cbor_value_advance(rootValue);
479 OIC_LOG_V(ERROR, TAG, "CBOR in error condition %d", err);
480 return OC_STACK_MALFORMED_RESPONSE;
483 *outPayload = (OCPayload*)OCDevicePayloadCreate(sid, dname, specVer, dmVer);
491 return OC_STACK_NO_MEMORY;
498 OIC_LOG(ERROR, TAG, "Root device node was not a map");
499 return OC_STACK_MALFORMED_RESPONSE;
504 static OCStackResult OCParsePlatformPayload(OCPayload** outPayload, CborValue* rootValue)
508 return OC_STACK_INVALID_PARAM;
513 if(cbor_value_is_map(rootValue))
515 OCPlatformInfo info = {0};
520 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_PLATFORM_ID, &repVal);
521 if(cbor_value_is_valid(&repVal))
523 err = err || cbor_value_dup_text_string(&repVal, &(info.platformID), &len, NULL);
527 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_NAME, &repVal);
528 if(cbor_value_is_valid(&repVal))
530 err = err || cbor_value_dup_text_string(&repVal, &(info.manufacturerName), &len, NULL);
534 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_URL, &repVal);
535 if(cbor_value_is_valid(&repVal))
537 err = err || cbor_value_dup_text_string(&repVal, &(info.manufacturerUrl), &len, NULL);
541 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_MODEL_NUM, &repVal);
542 if(cbor_value_is_valid(&repVal))
544 err = err || cbor_value_dup_text_string(&repVal, &(info.modelNumber), &len, NULL);
548 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_DATE, &repVal);
549 if(cbor_value_is_valid(&repVal))
551 err = err || cbor_value_dup_text_string(&repVal, &(info.dateOfManufacture), &len,
556 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_PLATFORM_VERSION, &repVal);
557 if(cbor_value_is_valid(&repVal))
559 err = err || cbor_value_dup_text_string(&repVal, &(info.platformVersion), &len, NULL);
563 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_OS_VERSION, &repVal);
564 if(cbor_value_is_valid(&repVal))
566 err = err || cbor_value_dup_text_string(&repVal, &(info.operatingSystemVersion),
571 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_HARDWARE_VERSION, &repVal);
572 if(cbor_value_is_valid(&repVal))
574 err = err || cbor_value_dup_text_string(&repVal, &(info.hardwareVersion), &len,
579 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_FIRMWARE_VERSION, &repVal);
580 if(cbor_value_is_valid(&repVal))
582 err = err || cbor_value_dup_text_string(&repVal, &(info.firmwareVersion), &len,
587 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_SUPPORT_URL, &repVal);
588 if(cbor_value_is_valid(&repVal))
590 err = err || cbor_value_dup_text_string(&repVal, &(info.supportUrl), &len, NULL);
594 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_SYSTEM_TIME, &repVal);
595 if(cbor_value_is_valid(&repVal))
597 err = err || cbor_value_dup_text_string(&repVal, &(info.systemTime), &len, NULL);
600 err = err || cbor_value_advance(rootValue);
604 OICFree(info.dateOfManufacture);
605 OICFree(info.firmwareVersion);
606 OICFree(info.hardwareVersion);
607 OICFree(info.manufacturerName);
608 OICFree(info.manufacturerUrl);
609 OICFree(info.modelNumber);
610 OICFree(info.operatingSystemVersion);
611 OICFree(info.platformID);
612 OICFree(info.platformVersion);
613 OICFree(info.supportUrl);
614 OICFree(info.systemTime);
615 OIC_LOG(ERROR, TAG, "CBOR error In ParsePlatformPayload");
616 return OC_STACK_MALFORMED_RESPONSE;
619 *outPayload = (OCPayload*)OCPlatformPayloadCreateAsOwner(&info);
623 return OC_STACK_NO_MEMORY;
630 OIC_LOG(ERROR, TAG, "Root device node was not a map");
631 return OC_STACK_MALFORMED_RESPONSE;
635 static OCRepPayloadPropType DecodeCborType(CborType type)
640 return OCREP_PROP_NULL;
641 case CborIntegerType:
642 return OCREP_PROP_INT;
644 return OCREP_PROP_DOUBLE;
645 case CborBooleanType:
646 return OCREP_PROP_BOOL;
647 case CborTextStringType:
648 return OCREP_PROP_STRING;
649 case CborByteStringType:
650 return OCREP_PROP_BYTE_STRING;
652 return OCREP_PROP_OBJECT;
654 return OCREP_PROP_ARRAY;
656 return OCREP_PROP_NULL;
659 static bool OCParseArrayFindDimensionsAndType(const CborValue* parent, size_t dimensions[MAX_REP_ARRAY_DEPTH],
660 OCRepPayloadPropType* type)
663 CborValue insideArray;
664 *type = OCREP_PROP_NULL;
665 dimensions[0] = dimensions[1] = dimensions[2] = 0;
667 err = err || cbor_value_enter_container(parent, &insideArray);
669 while (cbor_value_is_valid(&insideArray))
671 OCRepPayloadPropType tempType = DecodeCborType(cbor_value_get_type(&insideArray));
673 if (tempType == OCREP_PROP_ARRAY)
675 size_t subdim[MAX_REP_ARRAY_DEPTH];
676 tempType = OCREP_PROP_NULL;
677 err = err || OCParseArrayFindDimensionsAndType(&insideArray, subdim, &tempType);
681 OIC_LOG(ERROR, TAG, "Parse array helper, sub-array too deep");
684 dimensions[1] = dimensions[1] >= subdim[0] ? dimensions[1] : subdim[0];
685 dimensions[2] = dimensions[2] >= subdim[1] ? dimensions[2] : subdim[1];
687 if (*type != OCREP_PROP_NULL && tempType != OCREP_PROP_NULL
688 && *type != tempType)
690 OIC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed (subtype)");
693 else if (*type == OCREP_PROP_NULL)
695 // We don't know the type of this array yet, so the assignment is OK
699 else if (*type == OCREP_PROP_NULL)
701 // We don't know the type of this array yet, so the assignment is OK
704 // tempType is allowed to be NULL, since it might now know the answer yet
705 else if (tempType != OCREP_PROP_NULL && *type != tempType)
707 // this is an invalid situation!
708 OIC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed");
713 cbor_value_advance(&insideArray);
719 static size_t getAllocSize(OCRepPayloadPropType type)
724 return sizeof (int64_t);
725 case OCREP_PROP_DOUBLE:
726 return sizeof (double);
727 case OCREP_PROP_BOOL:
728 return sizeof (bool);
729 case OCREP_PROP_STRING:
730 return sizeof (char*);
731 case OCREP_PROP_BYTE_STRING:
732 return sizeof (OCByteString);
733 case OCREP_PROP_OBJECT:
734 return sizeof (OCRepPayload*);
740 static size_t arrayStep(size_t dimensions[MAX_REP_ARRAY_DEPTH], size_t elementNum)
743 (dimensions[1] == 0 ? 1 : dimensions[1]) *
744 (dimensions[2] == 0 ? 1 : dimensions[2]) *
748 static bool OCParseArrayFillArray(const CborValue* parent, size_t dimensions[MAX_REP_ARRAY_DEPTH],
749 OCRepPayloadPropType type, void* targetArray)
752 CborValue insideArray;
754 err = err || cbor_value_enter_container(parent, &insideArray);
757 char* tempStr = NULL;
758 OCByteString ocByteStr = { .bytes = NULL, .len = 0};
760 OCRepPayload* tempPl = NULL;
762 size_t newdim[MAX_REP_ARRAY_DEPTH];
763 newdim[0] = dimensions[1];
764 newdim[1] = dimensions[2];
767 while (!err && i < dimensions[0] && cbor_value_is_valid(&insideArray))
769 bool noAdvance = false;
770 if (cbor_value_get_type(&insideArray) != CborNullType)
775 if (dimensions[1] == 0)
777 err = err || cbor_value_get_int64(&insideArray,
778 &(((int64_t*)targetArray)[i]));
782 err = err || OCParseArrayFillArray(&insideArray, newdim,
784 &(((int64_t*)targetArray)[arrayStep(dimensions, i)])
788 case OCREP_PROP_DOUBLE:
789 if (dimensions[1] == 0)
791 err = err || cbor_value_get_double(&insideArray,
792 &(((double*)targetArray)[i]));
796 err = err || OCParseArrayFillArray(&insideArray, newdim,
798 &(((double*)targetArray)[arrayStep(dimensions, i)])
802 case OCREP_PROP_BOOL:
803 if (dimensions[1] == 0)
805 err = err || cbor_value_get_boolean(&insideArray,
806 &(((bool*)targetArray)[i]));
810 err = err || OCParseArrayFillArray(&insideArray, newdim,
812 &(((bool*)targetArray)[arrayStep(dimensions, i)])
816 case OCREP_PROP_STRING:
817 if (dimensions[1] == 0)
819 err = err || cbor_value_dup_text_string(&insideArray,
820 &tempStr, &tempLen, NULL);
821 ((char**)targetArray)[i] = tempStr;
826 err = err || OCParseArrayFillArray(&insideArray, newdim,
828 &(((char**)targetArray)[arrayStep(dimensions, i)])
832 case OCREP_PROP_BYTE_STRING:
833 if (dimensions[1] == 0)
835 err = err || cbor_value_dup_byte_string(&insideArray,
836 &(ocByteStr.bytes), &(ocByteStr.len), NULL);
837 ((OCByteString*)targetArray)[i] = ocByteStr;
841 err = err || OCParseArrayFillArray(&insideArray, newdim,
843 &(((OCByteString*)targetArray)[arrayStep(dimensions, i)])
847 case OCREP_PROP_OBJECT:
848 if (dimensions[1] == 0)
850 err = err || OCParseSingleRepPayload(&tempPl, &insideArray);
851 ((OCRepPayload**)targetArray)[i] = tempPl;
857 err = err || OCParseArrayFillArray(&insideArray, newdim,
859 &(((OCRepPayload**)targetArray)[arrayStep(dimensions, i)])
864 OIC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
870 if (!noAdvance && cbor_value_is_valid(&insideArray))
872 err = err || cbor_value_advance(&insideArray);
879 static bool OCParseArray(OCRepPayload* out, const char* name, CborValue* container)
881 OCRepPayloadPropType type;
882 size_t dimensions[MAX_REP_ARRAY_DEPTH];
883 bool err = OCParseArrayFindDimensionsAndType(container, dimensions, &type);
887 OIC_LOG(ERROR, TAG, "Array details weren't clear");
891 if (type == OCREP_PROP_NULL)
893 err = err || OCRepPayloadSetNull(out, name);
894 err = err || cbor_value_advance(container);
898 size_t dimTotal = calcDimTotal(dimensions);
899 size_t allocSize = getAllocSize(type);
900 void* arr = OICCalloc(dimTotal, allocSize);
904 OIC_LOG(ERROR, TAG, "Array Parse allocation failed");
908 err = err || OCParseArrayFillArray(container, dimensions, type, arr);
913 if (err || !OCRepPayloadSetIntArrayAsOwner(out, name, (int64_t*)arr, dimensions))
919 case OCREP_PROP_DOUBLE:
920 if (err || !OCRepPayloadSetDoubleArrayAsOwner(out, name, (double*)arr, dimensions))
926 case OCREP_PROP_BOOL:
927 if (err || !OCRepPayloadSetBoolArrayAsOwner(out, name, (bool*)arr, dimensions))
933 case OCREP_PROP_STRING:
934 if (err || !OCRepPayloadSetStringArrayAsOwner(out, name, (char**)arr, dimensions))
936 for(size_t i = 0; i < dimTotal; ++i)
938 OICFree(((char**)arr)[i]);
944 case OCREP_PROP_BYTE_STRING:
945 if (err || !OCRepPayloadSetByteStringArrayAsOwner(out, name, (OCByteString*)arr, dimensions))
947 for (size_t i = 0; i < dimTotal; ++i)
949 OICFree(((OCByteString*)arr)[i].bytes);
955 case OCREP_PROP_OBJECT:
956 if (err || !OCRepPayloadSetPropObjectArrayAsOwner(out, name, (OCRepPayload**)arr, dimensions))
958 for(size_t i = 0; i < dimTotal; ++i)
960 OCRepPayloadDestroy(((OCRepPayload**)arr)[i]);
967 OIC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
975 static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue *objMap)
984 if (cbor_value_is_map(objMap))
988 *outPayload = OCRepPayloadCreate();
991 return CborErrorOutOfMemory;
995 OCRepPayload* curPayload = *outPayload;
999 err = err || cbor_value_enter_container(objMap, &repMap);
1001 while(!err && cbor_value_is_valid(&repMap))
1004 err = err || cbor_value_dup_text_string(&repMap, &name, &len, NULL);
1005 err = err || cbor_value_advance(&repMap);
1007 CborType type = cbor_value_get_type(&repMap);
1011 err = !OCRepPayloadSetNull(curPayload, name);
1013 case CborIntegerType:
1016 err = err || cbor_value_get_int64(&repMap, &intval);
1019 err = !OCRepPayloadSetPropInt(curPayload, name, intval);
1023 case CborDoubleType:
1025 double doubleval = 0;
1026 err = err || cbor_value_get_double(&repMap, &doubleval);
1029 err = !OCRepPayloadSetPropDouble(curPayload, name, doubleval);
1033 case CborBooleanType:
1035 bool boolval = false;
1036 err = err || cbor_value_get_boolean(&repMap, &boolval);
1039 err = !OCRepPayloadSetPropBool(curPayload, name, boolval);
1043 case CborTextStringType:
1045 char* strval = NULL;
1046 err = err || cbor_value_dup_text_string(&repMap, &strval, &len, NULL);
1049 err = !OCRepPayloadSetPropStringAsOwner(curPayload, name, strval);
1053 case CborByteStringType:
1055 uint8_t* bytestrval = NULL;
1056 err = err || cbor_value_dup_byte_string(&repMap, &bytestrval, &len, NULL);
1059 OCByteString tmp = {.bytes = bytestrval, .len = len};
1060 err = !OCRepPayloadSetPropByteStringAsOwner(curPayload, name, &tmp);
1066 OCRepPayload *pl = NULL;
1067 err = err || OCParseSingleRepPayload(&pl, &repMap);
1070 err = !OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl);
1075 err = err || OCParseArray(curPayload, name, &repMap);
1078 OIC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type);
1082 if (type != CborMapType && cbor_value_is_valid(&repMap))
1084 err = err || cbor_value_advance(&repMap);
1089 err = err || cbor_value_leave_container(objMap, &repMap);
1093 OCRepPayloadDestroy(*outPayload);
1101 static OCStackResult OCParseRepPayload(OCPayload** outPayload, CborValue* rootMap)
1105 return OC_STACK_INVALID_PARAM;
1108 OCRepPayload *rootPayload = NULL;
1109 OCRepPayload *curPayload = NULL;
1110 OCRepPayload *temp = OCRepPayloadCreate();
1113 return OC_STACK_NO_MEMORY;
1119 err = err || cbor_value_map_find_value(rootMap, OC_RSRVD_RESOURCE_TYPE, &curVal);
1120 if(cbor_value_is_text_string(&curVal))
1123 err = err || cbor_value_dup_text_string(&curVal, &allRt, &len, NULL);
1127 char* curPtr = strtok_r(allRt, " ", &savePtr);
1130 char* trimmed = InPlaceStringTrim(curPtr);
1131 if (trimmed[0] != '\0')
1133 OCRepPayloadAddResourceType(temp, curPtr);
1135 curPtr = strtok_r(NULL, " ", &savePtr);
1141 err = err || cbor_value_map_find_value(rootMap, OC_RSRVD_INTERFACE, &curVal);
1142 if(cbor_value_is_text_string(&curVal))
1145 err = err || cbor_value_dup_text_string(&curVal, &allIf, &len, NULL);
1149 char* curPtr = strtok_r(allIf, " ", &savePtr);
1152 char* trimmed = InPlaceStringTrim(curPtr);
1153 if (trimmed[0] != '\0')
1155 OCRepPayloadAddInterface(temp, curPtr);
1157 curPtr = strtok_r(NULL, " ", &savePtr);
1163 while (!err && cbor_value_is_map(rootMap))
1165 err = err || OCParseSingleRepPayload(&temp, rootMap);
1167 if(rootPayload == NULL)
1174 curPayload->next = temp;
1175 curPayload = curPayload->next;
1178 if (cbor_value_is_valid(rootMap))
1180 err = err || cbor_value_advance(rootMap);
1185 OCRepPayloadDestroy(rootPayload);
1186 OIC_LOG(ERROR, TAG, "CBOR error in ParseRepPayload");
1187 return OC_STACK_MALFORMED_RESPONSE;
1191 *outPayload = (OCPayload*)rootPayload;
1196 static OCStackResult OCParsePresencePayload(OCPayload** outPayload, CborValue* rootValue)
1200 return OC_STACK_INVALID_PARAM;
1205 if(cbor_value_is_map(rootValue))
1207 uint64_t seqNum = 0;
1208 uint64_t maxAge = 0;
1209 OCPresenceTrigger trigger = OC_PRESENCE_TRIGGER_CREATE;
1210 char* tempStr = NULL;
1215 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_NONCE, &curVal);
1216 err = err || cbor_value_get_uint64(&curVal, &seqNum);
1219 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_TTL, &curVal);
1220 err = err || cbor_value_get_uint64(&curVal, &maxAge);
1223 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_TRIGGER, &curVal);
1224 err = err || cbor_value_dup_text_string(&curVal, &tempStr, &len, NULL);
1225 trigger = convertTriggerStringToEnum(tempStr);
1229 // Resource type name
1230 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &curVal);
1231 if(cbor_value_is_valid(&curVal))
1233 err = err || cbor_value_dup_text_string(&curVal, &tempStr, &len, NULL);
1236 err = err || cbor_value_advance(rootValue);
1240 *outPayload = (OCPayload*)OCPresencePayloadCreate(seqNum, maxAge, trigger, tempStr);
1246 OCPayloadDestroy(*outPayload);
1247 OIC_LOG(ERROR, TAG, "CBOR error Parse Presence Payload");
1248 return OC_STACK_MALFORMED_RESPONSE;
1253 return OC_STACK_NO_MEMORY;
1260 OIC_LOG(ERROR, TAG, "Root presence node was not a map");
1261 return OC_STACK_MALFORMED_RESPONSE;