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 "OCPayloadParse"
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 OC_LOG_V(INFO, TAG, "CBOR Parsing size: %d", payloadSize);
60 if((err = cbor_parser_init(payload, payloadSize, 0, &parser, &rootValue)) != false)
62 OC_LOG_V(ERROR, TAG, "CBOR Parser init failed: %d", err);
63 return OC_STACK_ERROR;
66 if(!cbor_value_is_array(&rootValue))
68 OC_LOG_V(ERROR, TAG, "CBOR payload root object is not an array :%x", rootValue.type);
69 return OC_STACK_MALFORMED_RESPONSE;
74 err = err || cbor_value_enter_container(&rootValue, &arrayValue);
78 OC_LOG_V(ERROR, TAG, "CBOR payload parse failed :%d", err);
79 return OC_STACK_MALFORMED_RESPONSE;
82 OCStackResult result = OC_STACK_ERROR;
85 case PAYLOAD_TYPE_DISCOVERY:
86 result = OCParseDiscoveryPayload(outPayload, &arrayValue);
88 case PAYLOAD_TYPE_DEVICE:
89 result = OCParseDevicePayload(outPayload, &arrayValue);
91 case PAYLOAD_TYPE_PLATFORM:
92 result = OCParsePlatformPayload(outPayload, &arrayValue);
94 case PAYLOAD_TYPE_REPRESENTATION:
95 result = OCParseRepPayload(outPayload, &arrayValue);
97 case PAYLOAD_TYPE_PRESENCE:
98 result = OCParsePresencePayload(outPayload, &arrayValue);
100 case PAYLOAD_TYPE_SECURITY:
101 result = OCParseSecurityPayload(outPayload, &arrayValue);
103 case PAYLOAD_TYPE_RD:
104 result = OCRDCborToPayload(&arrayValue, outPayload);
107 OC_LOG_V(ERROR, TAG, "ParsePayload Type default: %d", payloadType);
108 result = OC_STACK_ERROR;
112 if(result == OC_STACK_OK)
114 err = err || cbor_value_leave_container(&rootValue, &arrayValue);
115 if(err != CborNoError)
117 return OC_STACK_MALFORMED_RESPONSE;
122 OC_LOG_V(INFO, TAG, "Finished parse payload, result is %d", result);
128 void OCFreeOCStringLL(OCStringLL* ll);
130 static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* arrayVal)
134 return OC_STACK_INVALID_PARAM;
138 char * securityData = NULL;
140 if(cbor_value_is_map(arrayVal))
143 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
145 if(cbor_value_is_valid(&curVal))
148 err = err || cbor_value_dup_text_string(&curVal, &securityData, &len, NULL);
153 OC_LOG(ERROR, TAG, "Cbor main value not a map");
154 return OC_STACK_MALFORMED_RESPONSE;
157 err = err || cbor_value_advance(arrayVal);
161 OC_LOG(ERROR, TAG, "Cbor in error condition");
162 OICFree(securityData);
163 return OC_STACK_MALFORMED_RESPONSE;
166 *outPayload = (OCPayload*)OCSecurityPayloadCreate(securityData);
167 OICFree(securityData);
173 static char* InPlaceStringTrim(char* str)
175 while (str[0] == ' ')
180 size_t lastchar = strlen(str);
182 while (str[lastchar] == ' ')
184 str[lastchar] = '\0';
191 static OCStackResult OCParseDiscoveryPayload(OCPayload** outPayload, CborValue* arrayVal)
195 return OC_STACK_INVALID_PARAM;
199 OCResourcePayload* resource = NULL;
201 OCDiscoveryPayload* out = OCDiscoveryPayloadCreate();
204 return OC_STACK_NO_MEMORY;
207 if (cbor_value_is_array(arrayVal))
209 OCLinksPayload *linksPayload = NULL;
210 OCTagsPayload *tagsPayload = NULL;
211 while (cbor_value_is_container(arrayVal))
215 CborValue colResources;
216 CborError cborFindResult = cbor_value_enter_container(arrayVal, &colResources);
217 if (CborNoError != cborFindResult)
222 if (OC_STACK_OK != OCTagsCborToPayload(&colResources, &tagsPayload))
224 OC_LOG(ERROR, TAG, "Tags cbor parsing failed.");
225 OCFreeTagsResource(tagsPayload);
229 if (OC_STACK_OK != OCLinksCborToPayload(&colResources, &linksPayload))
231 OC_LOG(ERROR, TAG, "Links cbor parsing failed.");
232 OCFreeTagsResource(tagsPayload);
233 OCFreeLinksResource(linksPayload);
237 if (OC_STACK_OK != OCDiscoveryCollectionPayloadAddResource(out, tagsPayload, linksPayload))
239 OC_LOG(ERROR, TAG, "Memory allocation failed");
240 OCFreeLinksResource(linksPayload);
241 OCFreeTagsResource(tagsPayload);
242 OCDiscoveryPayloadDestroy(out);
243 return OC_STACK_NO_MEMORY;
245 if (CborNoError != cbor_value_advance(arrayVal))
247 OC_LOG(ERROR, TAG, "Cbor value advanced failed.");
252 if (cbor_value_is_map(arrayVal))
254 size_t resourceCount = 0;
255 while (cbor_value_is_map(arrayVal))
257 resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
260 OC_LOG(ERROR, TAG, "Memory allocation failed");
261 OCDiscoveryPayloadDestroy(out);
262 return OC_STACK_NO_MEMORY;
266 err = cbor_value_map_find_value(arrayVal, OC_RSRVD_DEVICE_ID, &curVal);
267 if (CborNoError != err)
269 OC_LOG(ERROR, TAG, "Cbor find value failed.");
273 err = cbor_value_dup_byte_string(&curVal, &(resource->sid), &len, NULL);
274 if (CborNoError != err)
276 OC_LOG(ERROR, TAG, "Cbor di finding failed.");
282 err = cbor_value_map_find_value(arrayVal, OC_RSRVD_LINKS, &linkArray);
283 if (CborNoError != err)
285 OC_LOG(ERROR, TAG, "Cbor links finding failed.");
289 err = cbor_value_enter_container(&linkArray, &linkMap);
290 if (CborNoError != err)
292 OC_LOG(ERROR, TAG, "Cbor entering map failed.");
296 err = cbor_value_map_find_value(&linkMap, OC_RSRVD_HREF, &curVal);
297 if (CborNoError != err)
299 OC_LOG(ERROR, TAG, "Cbor finding href type failed.");
302 err = cbor_value_dup_text_string(&curVal, &(resource->uri), &len, NULL);
303 if (CborNoError != err)
305 OC_LOG(ERROR, TAG, "Cbor finding href value failed.");
310 err = cbor_value_map_find_value(&linkMap, OC_RSRVD_RESOURCE_TYPE, &rtVal);
311 if (CborNoError != err)
313 OC_LOG(ERROR, TAG, "Cbor finding rt type failed.");
316 if (cbor_value_is_text_string(&rtVal))
320 err = cbor_value_dup_text_string(&rtVal, &input, &len, NULL);
321 if (CborNoError != err)
323 OC_LOG(ERROR, TAG, "Cbor finding rt value failed.");
328 char* curPtr = strtok_r(input, " ", &savePtr);
332 char* trimmed = InPlaceStringTrim(curPtr);
333 if (trimmed[0] !='\0')
335 if (!OCResourcePayloadAddResourceType(resource, trimmed))
337 OICFree(resource->uri);
338 OICFree(resource->sid);
339 OCFreeOCStringLL(resource->types);
341 OCDiscoveryPayloadDestroy(out);
342 return OC_STACK_NO_MEMORY;
345 curPtr = strtok_r(NULL, " ", &savePtr);
353 err = cbor_value_map_find_value(&linkMap, OC_RSRVD_INTERFACE, &ifVal);
354 if (CborNoError != err)
356 OC_LOG(ERROR, TAG, "Cbor finding if type failed.");
359 if (!err && cbor_value_is_text_string(&ifVal))
363 err = cbor_value_dup_text_string(&ifVal, &input, &len, NULL);
364 if (CborNoError != err)
366 OC_LOG(ERROR, TAG, "Cbor finding if value failed.");
371 char* curPtr = strtok_r(input, " ", &savePtr);
375 char* trimmed = InPlaceStringTrim(curPtr);
376 if (trimmed[0] !='\0')
378 if (!OCResourcePayloadAddInterface(resource, trimmed))
380 OICFree(resource->uri);
381 OICFree(resource->sid);
382 OCFreeOCStringLL(resource->types);
384 OCDiscoveryPayloadDestroy(out);
385 return OC_STACK_NO_MEMORY;
388 curPtr = strtok_r(NULL, " ", &savePtr);
396 err = cbor_value_map_find_value(&linkMap, OC_RSRVD_POLICY, &policyMap);
397 if (CborNoError != err)
399 OC_LOG(ERROR, TAG, "Cbor finding policy type failed.");
404 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &val);
405 if (CborNoError != err)
407 OC_LOG(ERROR, TAG, "Cbor finding bitmap type failed.");
411 err = cbor_value_get_uint64(&val, &temp);
412 if (CborNoError != err)
414 OC_LOG(ERROR, TAG, "Cbor finding bitmap value failed.");
417 resource->bitmap = (uint8_t)temp;
419 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &val);
420 if (CborNoError != err)
422 OC_LOG(ERROR, TAG, "Cbor finding secure type failed.");
425 if(cbor_value_is_valid(&val))
427 err = cbor_value_get_boolean(&val, &(resource->secure));
428 if (CborNoError != err)
430 OC_LOG(ERROR, TAG, "Cbor finding secure value failed.");
435 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT,
437 if (CborNoError != err)
439 OC_LOG(ERROR, TAG, "Cbor finding port type failed.");
442 if(cbor_value_is_valid(&port))
444 err = cbor_value_get_uint64(&port, &temp);
445 if (CborNoError != err)
447 OC_LOG(ERROR, TAG, "Cbor finding port value failed.");
450 resource->port = (uint16_t)temp;
455 err = cbor_value_advance(arrayVal);
456 if (CborNoError != err)
458 OC_LOG(ERROR, TAG, "Cbor advance value failed.");
462 OCDiscoveryPayloadAddNewResource(out, resource);
466 *outPayload = (OCPayload*)out;
470 OICFree(resource->uri);
471 OICFree(resource->sid);
472 OCFreeOCStringLL(resource->types);
473 OCFreeOCStringLL(resource->interfaces);
475 OCDiscoveryPayloadDestroy(out);
476 return OC_STACK_MALFORMED_RESPONSE;
479 OCDiscoveryCollectionPayloadDestroy(out);
480 return OC_STACK_MALFORMED_RESPONSE;
483 static OCStackResult OCParseDevicePayload(OCPayload** outPayload, CborValue* arrayVal)
487 return OC_STACK_INVALID_PARAM;
492 if(cbor_value_is_map(arrayVal))
497 char* specVer = NULL;
500 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
502 err = err || cbor_value_dup_text_string(&curVal, &uri, &len, NULL);
506 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
510 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DEVICE_ID, &repVal);
511 if(cbor_value_is_valid(&repVal))
513 err = err || cbor_value_dup_byte_string(&repVal, &sid, &len, NULL);
516 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DEVICE_NAME, &repVal);
517 if(cbor_value_is_valid(&repVal))
519 err = err || cbor_value_dup_text_string(&repVal, &dname, &len, NULL);
521 // Device Spec Version
522 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SPEC_VERSION, &repVal);
523 if(cbor_value_is_valid(&repVal))
525 err = err || cbor_value_dup_text_string(&repVal, &specVer, &len, NULL);
528 // Data Model Version
529 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DATA_MODEL_VERSION, &repVal);
530 if (cbor_value_is_valid(&repVal))
532 err = err || cbor_value_dup_text_string(&repVal, &dmVer, &len, NULL);
536 err = err || cbor_value_advance(arrayVal);
545 OC_LOG_V(ERROR, TAG, "CBOR in error condition %d", err);
546 return OC_STACK_MALFORMED_RESPONSE;
549 *outPayload = (OCPayload*)OCDevicePayloadCreate(uri, sid, dname, specVer, dmVer);
558 return OC_STACK_NO_MEMORY;
565 OC_LOG(ERROR, TAG, "Root device node was not a map");
566 return OC_STACK_MALFORMED_RESPONSE;
571 static OCStackResult OCParsePlatformPayload(OCPayload** outPayload, CborValue* arrayVal)
575 return OC_STACK_INVALID_PARAM;
580 if(cbor_value_is_map(arrayVal))
583 OCPlatformInfo info = {0};
585 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
587 err = err || cbor_value_dup_text_string(&curVal, &uri, &len, NULL);
591 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
595 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_PLATFORM_ID, &repVal);
596 if(cbor_value_is_valid(&repVal))
598 err = err || cbor_value_dup_text_string(&repVal, &(info.platformID), &len, NULL);
602 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_NAME, &repVal);
603 if(cbor_value_is_valid(&repVal))
605 err = err || cbor_value_dup_text_string(&repVal, &(info.manufacturerName), &len, NULL);
609 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_URL, &repVal);
610 if(cbor_value_is_valid(&repVal))
612 err = err || cbor_value_dup_text_string(&repVal, &(info.manufacturerUrl), &len, NULL);
616 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MODEL_NUM, &repVal);
617 if(cbor_value_is_valid(&repVal))
619 err = err || cbor_value_dup_text_string(&repVal, &(info.modelNumber), &len, NULL);
623 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_DATE, &repVal);
624 if(cbor_value_is_valid(&repVal))
626 err = err || cbor_value_dup_text_string(&repVal, &(info.dateOfManufacture), &len,
631 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_PLATFORM_VERSION, &repVal);
632 if(cbor_value_is_valid(&repVal))
634 err = err || cbor_value_dup_text_string(&repVal, &(info.platformVersion), &len,
639 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_OS_VERSION, &repVal);
640 if(cbor_value_is_valid(&repVal))
642 err = err || cbor_value_dup_text_string(&repVal, &(info.operatingSystemVersion),
647 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_HARDWARE_VERSION, &repVal);
648 if(cbor_value_is_valid(&repVal))
650 err = err || cbor_value_dup_text_string(&repVal, &(info.hardwareVersion), &len,
655 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_FIRMWARE_VERSION, &repVal);
656 if(cbor_value_is_valid(&repVal))
658 err = err || cbor_value_dup_text_string(&repVal, &(info.firmwareVersion), &len,
663 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SUPPORT_URL, &repVal);
664 if(cbor_value_is_valid(&repVal))
666 err = err || cbor_value_dup_text_string(&repVal, &(info.supportUrl), &len, NULL);
670 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SYSTEM_TIME, &repVal);
671 if(cbor_value_is_valid(&repVal))
673 err = err || cbor_value_dup_text_string(&repVal, &(info.systemTime), &len, NULL);
677 err = err || cbor_value_advance(arrayVal);
681 OICFree(info.dateOfManufacture);
682 OICFree(info.firmwareVersion);
683 OICFree(info.hardwareVersion);
684 OICFree(info.manufacturerName);
685 OICFree(info.manufacturerUrl);
686 OICFree(info.modelNumber);
687 OICFree(info.operatingSystemVersion);
688 OICFree(info.platformID);
689 OICFree(info.platformVersion);
690 OICFree(info.supportUrl);
691 OICFree(info.systemTime);
692 OC_LOG(ERROR, TAG, "CBOR error In ParsePlatformPayload");
693 return OC_STACK_MALFORMED_RESPONSE;
696 *outPayload = (OCPayload*)OCPlatformPayloadCreateAsOwner(uri, &info);
700 return OC_STACK_NO_MEMORY;
707 OC_LOG(ERROR, TAG, "Root device node was not a map");
708 return OC_STACK_MALFORMED_RESPONSE;
712 static OCRepPayloadPropType DecodeCborType(CborType type)
717 return OCREP_PROP_NULL;
718 case CborIntegerType:
719 return OCREP_PROP_INT;
721 return OCREP_PROP_DOUBLE;
722 case CborBooleanType:
723 return OCREP_PROP_BOOL;
724 case CborTextStringType:
725 return OCREP_PROP_STRING;
727 return OCREP_PROP_OBJECT;
729 return OCREP_PROP_ARRAY;
731 return OCREP_PROP_NULL;
734 static bool OCParseArrayFindDimensionsAndType(const CborValue* parent, size_t dimensions[MAX_REP_ARRAY_DEPTH],
735 OCRepPayloadPropType* type)
738 CborValue insideArray;
739 *type = OCREP_PROP_NULL;
740 dimensions[0] = dimensions[1] = dimensions[2] = 0;
742 err = err || cbor_value_enter_container(parent, &insideArray);
744 while (cbor_value_is_valid(&insideArray))
746 OCRepPayloadPropType tempType = DecodeCborType(cbor_value_get_type(&insideArray));
748 if (tempType == OCREP_PROP_ARRAY)
750 size_t subdim[MAX_REP_ARRAY_DEPTH];
751 tempType = OCREP_PROP_NULL;
752 err = err || OCParseArrayFindDimensionsAndType(&insideArray, subdim, &tempType);
756 OC_LOG(ERROR, TAG, "Parse array helper, sub-array too deep");
759 dimensions[1] = dimensions[1] >= subdim[0] ? dimensions[1] : subdim[0];
760 dimensions[2] = dimensions[2] >= subdim[1] ? dimensions[2] : subdim[1];
762 if (*type != OCREP_PROP_NULL && tempType != OCREP_PROP_NULL
763 && *type != tempType)
765 OC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed (subtype)");
768 else if (*type == OCREP_PROP_NULL)
770 // We don't know the type of this array yet, so the assignment is OK
774 else if (*type == OCREP_PROP_NULL)
776 // We don't know the type of this array yet, so the assignment is OK
779 // tempType is allowed to be NULL, since it might now know the answer yet
780 else if (tempType != OCREP_PROP_NULL && *type != tempType)
782 // this is an invalid situation!
783 OC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed");
788 cbor_value_advance(&insideArray);
794 static size_t getAllocSize(OCRepPayloadPropType type)
799 return sizeof (int64_t);
800 case OCREP_PROP_DOUBLE:
801 return sizeof (double);
802 case OCREP_PROP_BOOL:
803 return sizeof (bool);
804 case OCREP_PROP_STRING:
805 return sizeof (char*);
806 case OCREP_PROP_OBJECT:
807 return sizeof (OCRepPayload*);
813 static size_t arrayStep(size_t dimensions[MAX_REP_ARRAY_DEPTH], size_t elementNum)
816 (dimensions[1] == 0 ? 1 : dimensions[1]) *
817 (dimensions[2] == 0 ? 1 : dimensions[2]) *
821 static bool OCParseArrayFillArray(const CborValue* parent, size_t dimensions[MAX_REP_ARRAY_DEPTH],
822 OCRepPayloadPropType type, void* targetArray)
825 CborValue insideArray;
827 err = err || cbor_value_enter_container(parent, &insideArray);
830 char* tempStr = NULL;
832 OCRepPayload* tempPl = NULL;
834 size_t newdim[MAX_REP_ARRAY_DEPTH];
835 newdim[0] = dimensions[1];
836 newdim[1] = dimensions[2];
839 while (!err && i < dimensions[0] && cbor_value_is_valid(&insideArray))
841 if (cbor_value_get_type(&insideArray) != CborNullType)
846 if (dimensions[1] == 0)
848 err = err || cbor_value_get_int64(&insideArray,
849 &(((int64_t*)targetArray)[i]));
853 err = err || OCParseArrayFillArray(&insideArray, newdim,
855 &(((int64_t*)targetArray)[arrayStep(dimensions, i)])
859 case OCREP_PROP_DOUBLE:
860 if (dimensions[1] == 0)
862 err = err || cbor_value_get_double(&insideArray,
863 &(((double*)targetArray)[i]));
867 err = err || OCParseArrayFillArray(&insideArray, newdim,
869 &(((double*)targetArray)[arrayStep(dimensions, i)])
873 case OCREP_PROP_BOOL:
874 if (dimensions[1] == 0)
876 err = err || cbor_value_get_boolean(&insideArray,
877 &(((bool*)targetArray)[i]));
881 err = err || OCParseArrayFillArray(&insideArray, newdim,
883 &(((bool*)targetArray)[arrayStep(dimensions, i)])
887 case OCREP_PROP_STRING:
888 if (dimensions[1] == 0)
890 err = err || cbor_value_dup_text_string(&insideArray,
891 &tempStr, &tempLen, NULL);
892 ((char**)targetArray)[i] = tempStr;
897 err = err || OCParseArrayFillArray(&insideArray, newdim,
899 &(((char**)targetArray)[arrayStep(dimensions, i)])
903 case OCREP_PROP_OBJECT:
904 if (dimensions[1] == 0)
906 err = err || OCParseSingleRepPayload(&tempPl, &insideArray);
907 ((OCRepPayload**)targetArray)[i] = tempPl;
912 err = err || OCParseArrayFillArray(&insideArray, newdim,
914 &(((OCRepPayload**)targetArray)[arrayStep(dimensions, i)])
919 OC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
925 err = err || cbor_value_advance(&insideArray);
931 static bool OCParseArray(OCRepPayload* out, const char* name, CborValue* container)
933 OCRepPayloadPropType type;
934 size_t dimensions[MAX_REP_ARRAY_DEPTH];
935 bool err = OCParseArrayFindDimensionsAndType(container, dimensions, &type);
939 OC_LOG(ERROR, TAG, "Array details weren't clear");
943 if (type == OCREP_PROP_NULL)
945 err = err || OCRepPayloadSetNull(out, name);
946 err = err || cbor_value_advance(container);
950 size_t dimTotal = calcDimTotal(dimensions);
951 size_t allocSize = getAllocSize(type);
952 void* arr = OICCalloc(dimTotal, allocSize);
956 OC_LOG(ERROR, TAG, "Array Parse allocation failed");
960 err = err || OCParseArrayFillArray(container, dimensions, type, arr);
965 if (err || !OCRepPayloadSetIntArrayAsOwner(out, name, (int64_t*)arr, dimensions))
971 case OCREP_PROP_DOUBLE:
972 if (err || !OCRepPayloadSetDoubleArrayAsOwner(out, name, (double*)arr, dimensions))
978 case OCREP_PROP_BOOL:
979 if (err || !OCRepPayloadSetBoolArrayAsOwner(out, name, (bool*)arr, dimensions))
985 case OCREP_PROP_STRING:
986 if (err || !OCRepPayloadSetStringArrayAsOwner(out, name, (char**)arr, dimensions))
988 for(size_t i = 0; i < dimTotal; ++i)
990 OICFree(((char**)arr)[i]);
996 case OCREP_PROP_OBJECT:
997 if (err || !OCRepPayloadSetPropObjectArrayAsOwner(out, name, (OCRepPayload**)arr, dimensions))
999 for(size_t i = 0; i < dimTotal; ++i)
1001 OCRepPayloadDestroy(((OCRepPayload**)arr)[i]);
1008 OC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
1016 static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue* repParent)
1023 *outPayload = OCRepPayloadCreate();
1024 OCRepPayload* curPayload = *outPayload;
1028 return CborErrorOutOfMemory;
1033 err = err || cbor_value_map_find_value(repParent, OC_RSRVD_HREF, &curVal);
1034 if(cbor_value_is_valid(&curVal))
1036 err = err || cbor_value_dup_text_string(&curVal, &curPayload->uri, &len,
1040 err = err || cbor_value_map_find_value(repParent, OC_RSRVD_PROPERTY, &curVal);
1041 if(cbor_value_is_valid(&curVal))
1043 CborValue insidePropValue = {0};
1044 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_RESOURCE_TYPE,
1047 if(cbor_value_is_text_string(&insidePropValue))
1050 err = err || cbor_value_dup_text_string(&insidePropValue, &allRt, &len, NULL);
1056 char* curPtr = strtok_r(allRt, " ", &savePtr);
1060 char* trimmed = InPlaceStringTrim(curPtr);
1061 if (trimmed[0] != '\0')
1063 OCRepPayloadAddResourceType(curPayload, curPtr);
1065 curPtr = strtok_r(NULL, " ", &savePtr);
1071 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_INTERFACE, &insidePropValue);
1073 if(cbor_value_is_text_string(&insidePropValue))
1076 err = err || cbor_value_dup_text_string(&insidePropValue, &allIf, &len, NULL);
1082 char* curPtr = strtok_r(allIf, " ", &savePtr);
1086 char* trimmed = InPlaceStringTrim(curPtr);
1087 if (trimmed[0] != '\0')
1089 OCRepPayloadAddInterface(curPayload, curPtr);
1091 curPtr = strtok_r(NULL, " ", &savePtr);
1098 err = err || cbor_value_map_find_value(repParent, OC_RSRVD_REPRESENTATION, &curVal);
1099 if(cbor_value_is_map(&curVal))
1102 err = err || cbor_value_enter_container(&curVal, &repMap);
1104 while(!err && cbor_value_is_valid(&repMap))
1107 err = err || cbor_value_dup_text_string(&repMap, &name, &len, NULL);
1109 err = err || cbor_value_advance(&repMap);
1112 bool boolval = false;
1113 char* strval = NULL;
1114 double doubleval = 0;
1117 switch(cbor_value_get_type(&repMap))
1120 err = !OCRepPayloadSetNull(curPayload, name);
1122 case CborIntegerType:
1123 err = err || cbor_value_get_int64(&repMap, &intval);
1126 err = !OCRepPayloadSetPropInt(curPayload, name, intval);
1129 case CborDoubleType:
1130 err = err || cbor_value_get_double(&repMap, &doubleval);
1133 err = !OCRepPayloadSetPropDouble(curPayload, name, doubleval);
1136 case CborBooleanType:
1137 err = err || cbor_value_get_boolean(&repMap, &boolval);
1140 err = !OCRepPayloadSetPropBool(curPayload, name, boolval);
1143 case CborTextStringType:
1144 err = err || cbor_value_dup_text_string(&repMap, &strval, &len, NULL);
1147 err = !OCRepPayloadSetPropStringAsOwner(curPayload, name, strval);
1151 err = err || OCParseSingleRepPayload(&pl, &repMap);
1154 err = !OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl);
1158 err = err || OCParseArray(curPayload, name, &repMap);
1161 OC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type);
1165 err = err || cbor_value_advance(&repMap);
1168 err = err || cbor_value_leave_container(&curVal, &repMap);
1173 OCRepPayloadDestroy(*outPayload);
1179 static OCStackResult OCParseRepPayload(OCPayload** outPayload, CborValue* arrayVal)
1183 return OC_STACK_INVALID_PARAM;
1188 OCRepPayload* rootPayload = NULL;
1189 OCRepPayload* curPayload = NULL;
1190 OCRepPayload* temp = NULL;
1191 while(!err && cbor_value_is_map(arrayVal))
1193 err = err || OCParseSingleRepPayload(&temp, arrayVal);
1195 if(rootPayload == NULL)
1202 curPayload->next = temp;
1203 curPayload = curPayload->next;
1207 err = err || cbor_value_advance(arrayVal);
1210 OCRepPayloadDestroy(rootPayload);
1211 OC_LOG(ERROR, TAG, "CBOR error in ParseRepPayload");
1212 return OC_STACK_MALFORMED_RESPONSE;
1216 *outPayload = (OCPayload*)rootPayload;
1221 static OCStackResult OCParsePresencePayload(OCPayload** outPayload, CborValue* arrayVal)
1225 return OC_STACK_INVALID_PARAM;
1229 if(cbor_value_is_map(arrayVal))
1231 uint64_t seqNum = 0;
1232 uint64_t maxAge = 0;
1233 OCPresenceTrigger trigger = OC_PRESENCE_TRIGGER_CREATE;
1234 char* tempStr = NULL;
1239 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_NONCE, &curVal);
1240 err = err || cbor_value_get_uint64(&curVal, &seqNum);
1243 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_TTL, &curVal);
1244 err = err || cbor_value_get_uint64(&curVal, &maxAge);
1247 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_TRIGGER, &curVal);
1248 err = err || cbor_value_dup_text_string(&curVal, &tempStr, &len, NULL);
1249 trigger = convertTriggerStringToEnum(tempStr);
1253 // Resource type name
1254 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_RESOURCE_TYPE, &curVal);
1255 if(cbor_value_is_valid(&curVal))
1257 err = err || cbor_value_dup_text_string(&curVal, &tempStr, &len, NULL);
1260 err = err || cbor_value_advance(arrayVal);
1264 *outPayload = (OCPayload*)OCPresencePayloadCreate(seqNum, maxAge, trigger, tempStr);
1270 OCPayloadDestroy(*outPayload);
1271 OC_LOG(ERROR, TAG, "CBOR error Parse Presence Payload");
1272 return OC_STACK_MALFORMED_RESPONSE;
1277 return OC_STACK_NO_MEMORY;
1284 OC_LOG(ERROR, TAG, "Root presence node was not a map");
1285 return OC_STACK_MALFORMED_RESPONSE;