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_malloc.h"
34 #include "ocstackinternal.h"
35 #include "ocpayload.h"
37 #include "oic_string.h"
39 #define TAG "OCPayloadParse"
41 static OCStackResult OCParseDiscoveryPayload(OCPayload** outPayload, CborValue* arrayVal);
42 static OCStackResult OCParseDevicePayload(OCPayload** outPayload, CborValue* arrayVal);
43 static OCStackResult OCParsePlatformPayload(OCPayload** outPayload, CborValue* arrayVal);
44 static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue* repParent);
45 static OCStackResult OCParseRepPayload(OCPayload** outPayload, CborValue* arrayVal);
46 static OCStackResult OCParsePresencePayload(OCPayload** outPayload, CborValue* arrayVal);
47 static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* arrayVal);
49 OCStackResult OCParsePayload(OCPayload** outPayload, OCPayloadType payloadType,
50 const uint8_t* payload, size_t payloadSize)
56 OC_LOG_V(INFO, TAG, "CBOR Parsing size: %d", payloadSize, payload);
57 if((err = cbor_parser_init(payload, payloadSize, 0, &parser, &rootValue)) != false)
59 OC_LOG_V(ERROR, TAG, "CBOR Parser init failed: %d", err);
60 return OC_STACK_ERROR;
63 if(!cbor_value_is_array(&rootValue))
65 OC_LOG_V(ERROR, TAG, "CBOR payload root object is not an array :%x", rootValue.type);
66 return OC_STACK_MALFORMED_RESPONSE;
71 err = err || cbor_value_enter_container(&rootValue, &arrayValue);
73 if(err || arrayValue.type != CborMapType)
75 OC_LOG_V(ERROR, TAG, "CBOR payload parse failed :%d", err);
76 return OC_STACK_MALFORMED_RESPONSE;
79 OCStackResult result = OC_STACK_ERROR;
82 case PAYLOAD_TYPE_DISCOVERY:
83 result = OCParseDiscoveryPayload(outPayload, &arrayValue);
85 case PAYLOAD_TYPE_DEVICE:
86 result = OCParseDevicePayload(outPayload, &arrayValue);
88 case PAYLOAD_TYPE_PLATFORM:
89 result = OCParsePlatformPayload(outPayload, &arrayValue);
91 case PAYLOAD_TYPE_REPRESENTATION:
92 result = OCParseRepPayload(outPayload, &arrayValue);
94 case PAYLOAD_TYPE_PRESENCE:
95 result = OCParsePresencePayload(outPayload, &arrayValue);
97 case PAYLOAD_TYPE_SECURITY:
98 result = OCParseSecurityPayload(outPayload, &arrayValue);
101 OC_LOG_V(ERROR, TAG, "ParsePayload Type default: %d", payloadType);
102 result = OC_STACK_ERROR;
106 if(result == OC_STACK_OK)
108 err = err || cbor_value_leave_container(&rootValue, &arrayValue);
109 if(err != CborNoError)
111 return OC_STACK_MALFORMED_RESPONSE;
116 OC_LOG_V(INFO, TAG, "Finished parse payload, result is %d", result);
122 void OCFreeOCStringLL(OCStringLL* ll);
124 static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* arrayVal)
128 return OC_STACK_INVALID_PARAM;
132 char * securityData = NULL;
134 if(cbor_value_is_map(arrayVal))
137 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
139 if(cbor_value_is_valid(&curVal))
142 err = err || cbor_value_dup_text_string(&curVal, &securityData, &len, NULL);
147 OC_LOG(ERROR, TAG, "Cbor main value not a map");
148 return OC_STACK_MALFORMED_RESPONSE;
151 err = err || cbor_value_advance(arrayVal);
155 OC_LOG(ERROR, TAG, "Cbor in error condition");
156 OICFree(securityData);
157 return OC_STACK_MALFORMED_RESPONSE;
160 *outPayload = (OCPayload*)OCSecurityPayloadCreate(securityData);
161 OICFree(securityData);
167 static char* InPlaceStringTrim(char* str)
169 while (str[0] == ' ')
174 size_t lastchar = strlen(str);
176 while (str[lastchar] == ' ')
178 str[lastchar] = '\0';
185 static OCStackResult OCParseDiscoveryPayload(OCPayload** outPayload, CborValue* arrayVal)
189 return OC_STACK_INVALID_PARAM;
194 OCDiscoveryPayload* out = OCDiscoveryPayloadCreate();
198 return OC_STACK_NO_MEMORY;
201 size_t resourceCount = 0;
203 cbor_value_is_map(arrayVal))
205 OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
208 OC_LOG(ERROR, TAG, "Memory allocation failed");
209 OCDiscoveryPayloadDestroy(out);
210 return OC_STACK_NO_MEMORY;
215 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
217 err = err || cbor_value_dup_text_string(&curVal, &(resource->uri), &len, NULL);
220 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_SERVER_INSTANCE_ID, &curVal);
221 err = err || cbor_value_dup_byte_string(&curVal, &(resource->sid), &len, NULL);
225 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_PROPERTY, &curVal);
228 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_RESOURCE_TYPE, &rtVal);
230 if (!err && cbor_value_is_text_string(&rtVal))
234 err = err || cbor_value_dup_text_string(&rtVal, &input, &len, NULL);
238 char* curPtr = strtok_r(input, " ", &savePtr);
242 char* trimmed = InPlaceStringTrim(curPtr);
243 if (trimmed[0] !='\0')
245 if (!OCResourcePayloadAddResourceType(resource, trimmed))
247 OICFree(resource->uri);
248 OICFree(resource->sid);
249 OCFreeOCStringLL(resource->types);
251 OCDiscoveryPayloadDestroy(out);
252 return OC_STACK_NO_MEMORY;
255 curPtr = strtok_r(NULL, " ", &savePtr);
263 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_INTERFACE, &ifVal);
265 if (!err && cbor_value_is_text_string(&ifVal))
269 err = err || cbor_value_dup_text_string(&ifVal, &input, &len, NULL);
273 char* curPtr = strtok_r(input, " ", &savePtr);
277 char* trimmed = InPlaceStringTrim(curPtr);
278 if (trimmed[0] !='\0')
280 if (!OCResourcePayloadAddInterface(resource, trimmed))
282 OICFree(resource->uri);
283 OICFree(resource->sid);
284 OCFreeOCStringLL(resource->types);
286 OCDiscoveryPayloadDestroy(out);
287 return OC_STACK_NO_MEMORY;
290 curPtr = strtok_r(NULL, " ", &savePtr);
299 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_POLICY, &policyMap);
303 err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &val);
305 err = err || cbor_value_get_uint64(&val, &temp);
306 resource->bitmap = (uint8_t)temp;
308 err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &val);
309 if(cbor_value_is_valid(&val))
311 err = err || cbor_value_get_boolean(&val, &(resource->secure));
314 err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT,
316 if(cbor_value_is_valid(&port))
318 err = err || cbor_value_get_uint64(&port, &temp);
319 resource->port = (uint16_t)temp;
325 err = err || cbor_value_advance(arrayVal);
328 OICFree(resource->uri);
329 OICFree(resource->sid);
330 OCFreeOCStringLL(resource->types);
331 OCFreeOCStringLL(resource->interfaces);
333 OCDiscoveryPayloadDestroy(out);
334 OC_LOG_V(ERROR, TAG, "CBOR in error condition", err);
335 return OC_STACK_MALFORMED_RESPONSE;
338 OCDiscoveryPayloadAddNewResource(out, resource);
343 OCDiscoveryPayloadDestroy(out);
344 return OC_STACK_MALFORMED_RESPONSE;
348 *outPayload = (OCPayload*)out;
353 static OCStackResult OCParseDevicePayload(OCPayload** outPayload, CborValue* arrayVal)
357 return OC_STACK_INVALID_PARAM;
362 if(cbor_value_is_map(arrayVal))
367 char* specVer = NULL;
370 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
372 err = err || cbor_value_dup_text_string(&curVal, &uri, &len, NULL);
376 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
380 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DEVICE_ID, &repVal);
381 if(cbor_value_is_valid(&repVal))
383 err = err || cbor_value_dup_byte_string(&repVal, &sid, &len, NULL);
386 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DEVICE_NAME, &repVal);
387 if(cbor_value_is_valid(&repVal))
389 err = err || cbor_value_dup_text_string(&repVal, &dname, &len, NULL);
391 // Device Spec Version
392 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SPEC_VERSION, &repVal);
393 if(cbor_value_is_valid(&repVal))
395 err = err || cbor_value_dup_text_string(&repVal, &specVer, &len, NULL);
398 // Data Model Version
399 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DATA_MODEL_VERSION, &repVal);
400 if (cbor_value_is_valid(&repVal))
402 err = err || cbor_value_dup_text_string(&repVal, &dmVer, &len, NULL);
406 err = err || cbor_value_advance(arrayVal);
415 OC_LOG_V(ERROR, TAG, "CBOR in error condition %d", err);
416 return OC_STACK_MALFORMED_RESPONSE;
419 *outPayload = (OCPayload*)OCDevicePayloadCreate(uri, sid, dname, specVer, dmVer);
428 return OC_STACK_NO_MEMORY;
435 OC_LOG(ERROR, TAG, "Root device node was not a map");
436 return OC_STACK_MALFORMED_RESPONSE;
441 static OCStackResult OCParsePlatformPayload(OCPayload** outPayload, CborValue* arrayVal)
445 return OC_STACK_INVALID_PARAM;
450 if(cbor_value_is_map(arrayVal))
453 OCPlatformInfo info = {0};
455 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
457 err = err || cbor_value_dup_text_string(&curVal, &uri, &len, NULL);
461 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
465 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_PLATFORM_ID, &repVal);
466 if(cbor_value_is_valid(&repVal))
468 err = err || cbor_value_dup_text_string(&repVal, &(info.platformID), &len, NULL);
472 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_NAME, &repVal);
473 if(cbor_value_is_valid(&repVal))
475 err = err || cbor_value_dup_text_string(&repVal, &(info.manufacturerName), &len, NULL);
479 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_URL, &repVal);
480 if(cbor_value_is_valid(&repVal))
482 err = err || cbor_value_dup_text_string(&repVal, &(info.manufacturerUrl), &len, NULL);
486 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MODEL_NUM, &repVal);
487 if(cbor_value_is_valid(&repVal))
489 err = err || cbor_value_dup_text_string(&repVal, &(info.modelNumber), &len, NULL);
493 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_DATE, &repVal);
494 if(cbor_value_is_valid(&repVal))
496 err = err || cbor_value_dup_text_string(&repVal, &(info.dateOfManufacture), &len,
501 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_PLATFORM_VERSION, &repVal);
502 if(cbor_value_is_valid(&repVal))
504 err = err || cbor_value_dup_text_string(&repVal, &(info.platformVersion), &len,
509 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_OS_VERSION, &repVal);
510 if(cbor_value_is_valid(&repVal))
512 err = err || cbor_value_dup_text_string(&repVal, &(info.operatingSystemVersion),
517 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_HARDWARE_VERSION, &repVal);
518 if(cbor_value_is_valid(&repVal))
520 err = err || cbor_value_dup_text_string(&repVal, &(info.hardwareVersion), &len,
525 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_FIRMWARE_VERSION, &repVal);
526 if(cbor_value_is_valid(&repVal))
528 err = err || cbor_value_dup_text_string(&repVal, &(info.firmwareVersion), &len,
533 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SUPPORT_URL, &repVal);
534 if(cbor_value_is_valid(&repVal))
536 err = err || cbor_value_dup_text_string(&repVal, &(info.supportUrl), &len, NULL);
540 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SYSTEM_TIME, &repVal);
541 if(cbor_value_is_valid(&repVal))
543 err = err || cbor_value_dup_text_string(&repVal, &(info.systemTime), &len, NULL);
547 err = err || cbor_value_advance(arrayVal);
551 OICFree(info.dateOfManufacture);
552 OICFree(info.firmwareVersion);
553 OICFree(info.hardwareVersion);
554 OICFree(info.manufacturerName);
555 OICFree(info.manufacturerUrl);
556 OICFree(info.modelNumber);
557 OICFree(info.operatingSystemVersion);
558 OICFree(info.platformID);
559 OICFree(info.platformVersion);
560 OICFree(info.supportUrl);
561 OICFree(info.systemTime);
562 OC_LOG(ERROR, TAG, "CBOR error In ParsePlatformPayload");
563 return OC_STACK_MALFORMED_RESPONSE;
566 *outPayload = (OCPayload*)OCPlatformPayloadCreateAsOwner(uri, &info);
570 return OC_STACK_NO_MEMORY;
577 OC_LOG(ERROR, TAG, "Root device node was not a map");
578 return OC_STACK_MALFORMED_RESPONSE;
582 static OCRepPayloadPropType DecodeCborType(CborType type)
587 return OCREP_PROP_NULL;
588 case CborIntegerType:
589 return OCREP_PROP_INT;
591 return OCREP_PROP_DOUBLE;
592 case CborBooleanType:
593 return OCREP_PROP_BOOL;
594 case CborTextStringType:
595 return OCREP_PROP_STRING;
597 return OCREP_PROP_OBJECT;
599 return OCREP_PROP_ARRAY;
601 return OCREP_PROP_NULL;
604 static bool OCParseArrayFindDimensionsAndType(const CborValue* parent, size_t dimensions[MAX_REP_ARRAY_DEPTH],
605 OCRepPayloadPropType* type)
608 CborValue insideArray;
609 *type = OCREP_PROP_NULL;
610 dimensions[0] = dimensions[1] = dimensions[2] = 0;
612 err = err || cbor_value_enter_container(parent, &insideArray);
614 while (cbor_value_is_valid(&insideArray))
616 OCRepPayloadPropType tempType = DecodeCborType(cbor_value_get_type(&insideArray));
618 if (tempType == OCREP_PROP_ARRAY)
620 size_t subdim[MAX_REP_ARRAY_DEPTH];
621 tempType = OCREP_PROP_NULL;
622 err = err || OCParseArrayFindDimensionsAndType(&insideArray, subdim, &tempType);
626 OC_LOG(ERROR, TAG, "Parse array helper, sub-array too deep");
629 dimensions[1] = dimensions[1] >= subdim[0] ? dimensions[1] : subdim[0];
630 dimensions[2] = dimensions[2] >= subdim[1] ? dimensions[2] : subdim[1];
632 if (*type != OCREP_PROP_NULL && tempType != OCREP_PROP_NULL
633 && *type != tempType)
635 OC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed (subtype)");
638 else if (*type == OCREP_PROP_NULL)
640 // We don't know the type of this array yet, so the assignment is OK
644 else if (*type == OCREP_PROP_NULL)
646 // We don't know the type of this array yet, so the assignment is OK
649 // tempType is allowed to be NULL, since it might now know the answer yet
650 else if (tempType != OCREP_PROP_NULL && *type != tempType)
652 // this is an invalid situation!
653 OC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed");
658 cbor_value_advance(&insideArray);
664 static size_t getAllocSize(OCRepPayloadPropType type)
669 return sizeof (int64_t);
670 case OCREP_PROP_DOUBLE:
671 return sizeof (double);
672 case OCREP_PROP_BOOL:
673 return sizeof (bool);
674 case OCREP_PROP_STRING:
675 return sizeof (char*);
676 case OCREP_PROP_OBJECT:
677 return sizeof (OCRepPayload*);
683 static size_t arrayStep(size_t dimensions[MAX_REP_ARRAY_DEPTH], size_t elementNum)
686 (dimensions[1] == 0 ? 1 : dimensions[1]) *
687 (dimensions[2] == 0 ? 1 : dimensions[2]) *
691 static bool OCParseArrayFillArray(const CborValue* parent, size_t dimensions[MAX_REP_ARRAY_DEPTH],
692 OCRepPayloadPropType type, void* targetArray)
695 CborValue insideArray;
697 err = err || cbor_value_enter_container(parent, &insideArray);
700 char* tempStr = NULL;
702 OCRepPayload* tempPl = NULL;
704 size_t newdim[MAX_REP_ARRAY_DEPTH];
705 newdim[0] = dimensions[1];
706 newdim[1] = dimensions[2];
709 while (!err && i < dimensions[0] && cbor_value_is_valid(&insideArray))
711 if (cbor_value_get_type(&insideArray) != CborNullType)
716 if (dimensions[1] == 0)
718 err = err || cbor_value_get_int64(&insideArray,
719 &(((int64_t*)targetArray)[i]));
723 err = err || OCParseArrayFillArray(&insideArray, newdim,
725 &(((int64_t*)targetArray)[arrayStep(dimensions, i)])
729 case OCREP_PROP_DOUBLE:
730 if (dimensions[1] == 0)
732 err = err || cbor_value_get_double(&insideArray,
733 &(((double*)targetArray)[i]));
737 err = err || OCParseArrayFillArray(&insideArray, newdim,
739 &(((double*)targetArray)[arrayStep(dimensions, i)])
743 case OCREP_PROP_BOOL:
744 if (dimensions[1] == 0)
746 err = err || cbor_value_get_boolean(&insideArray,
747 &(((bool*)targetArray)[i]));
751 err = err || OCParseArrayFillArray(&insideArray, newdim,
753 &(((bool*)targetArray)[arrayStep(dimensions, i)])
757 case OCREP_PROP_STRING:
758 if (dimensions[1] == 0)
760 err = err || cbor_value_dup_text_string(&insideArray,
761 &tempStr, &tempLen, NULL);
762 ((char**)targetArray)[i] = tempStr;
767 err = err || OCParseArrayFillArray(&insideArray, newdim,
769 &(((char**)targetArray)[arrayStep(dimensions, i)])
773 case OCREP_PROP_OBJECT:
774 if (dimensions[1] == 0)
776 err = err || OCParseSingleRepPayload(&tempPl, &insideArray);
777 ((OCRepPayload**)targetArray)[i] = tempPl;
782 err = err || OCParseArrayFillArray(&insideArray, newdim,
784 &(((OCRepPayload**)targetArray)[arrayStep(dimensions, i)])
789 OC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
795 err = err || cbor_value_advance(&insideArray);
801 static bool OCParseArray(OCRepPayload* out, const char* name, CborValue* container)
803 OCRepPayloadPropType type;
804 size_t dimensions[MAX_REP_ARRAY_DEPTH];
805 bool err = OCParseArrayFindDimensionsAndType(container, dimensions, &type);
809 OC_LOG(ERROR, TAG, "Array details weren't clear");
813 if (type == OCREP_PROP_NULL)
815 err = err || OCRepPayloadSetNull(out, name);
816 err = err || cbor_value_advance(container);
820 size_t dimTotal = calcDimTotal(dimensions);
821 size_t allocSize = getAllocSize(type);
822 void* arr = OICCalloc(dimTotal, allocSize);
826 OC_LOG(ERROR, TAG, "Array Parse allocation failed");
830 err = err || OCParseArrayFillArray(container, dimensions, type, arr);
835 if (err || !OCRepPayloadSetIntArrayAsOwner(out, name, (int64_t*)arr, dimensions))
841 case OCREP_PROP_DOUBLE:
842 if (err || !OCRepPayloadSetDoubleArrayAsOwner(out, name, (double*)arr, dimensions))
848 case OCREP_PROP_BOOL:
849 if (err || !OCRepPayloadSetBoolArrayAsOwner(out, name, (bool*)arr, dimensions))
855 case OCREP_PROP_STRING:
856 if (err || !OCRepPayloadSetStringArrayAsOwner(out, name, (char**)arr, dimensions))
858 for(size_t i = 0; i < dimTotal; ++i)
860 OICFree(((char**)arr)[i]);
866 case OCREP_PROP_OBJECT:
867 if (err || !OCRepPayloadSetPropObjectArrayAsOwner(out, name, (OCRepPayload**)arr, dimensions))
869 for(size_t i = 0; i < dimTotal; ++i)
871 OCRepPayloadDestroy(((OCRepPayload**)arr)[i]);
878 OC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
886 static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue* repParent)
893 *outPayload = OCRepPayloadCreate();
894 OCRepPayload* curPayload = *outPayload;
898 return CborErrorOutOfMemory;
903 err = err || cbor_value_map_find_value(repParent, OC_RSRVD_HREF, &curVal);
904 if(cbor_value_is_valid(&curVal))
906 err = err || cbor_value_dup_text_string(&curVal, &curPayload->uri, &len,
910 err = err || cbor_value_map_find_value(repParent, OC_RSRVD_PROPERTY, &curVal);
911 if(cbor_value_is_valid(&curVal))
913 CborValue insidePropValue = {0};
914 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_RESOURCE_TYPE,
917 if(cbor_value_is_text_string(&insidePropValue))
920 err = err || cbor_value_dup_text_string(&insidePropValue, &allRt, &len, NULL);
926 char* curPtr = strtok_r(allRt, " ", &savePtr);
930 char* trimmed = InPlaceStringTrim(curPtr);
931 if (trimmed[0] != '\0')
933 OCRepPayloadAddResourceType(curPayload, curPtr);
935 curPtr = strtok_r(NULL, " ", &savePtr);
941 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_INTERFACE, &insidePropValue);
943 if(cbor_value_is_text_string(&insidePropValue))
946 err = err || cbor_value_dup_text_string(&insidePropValue, &allIf, &len, NULL);
952 char* curPtr = strtok_r(allIf, " ", &savePtr);
956 char* trimmed = InPlaceStringTrim(curPtr);
957 if (trimmed[0] != '\0')
959 OCRepPayloadAddInterface(curPayload, curPtr);
961 curPtr = strtok_r(NULL, " ", &savePtr);
968 err = err || cbor_value_map_find_value(repParent, OC_RSRVD_REPRESENTATION, &curVal);
969 if(cbor_value_is_map(&curVal))
972 err = err || cbor_value_enter_container(&curVal, &repMap);
974 while(!err && cbor_value_is_valid(&repMap))
977 err = err || cbor_value_dup_text_string(&repMap, &name, &len, NULL);
979 err = err || cbor_value_advance(&repMap);
982 bool boolval = false;
984 double doubleval = 0;
987 switch(cbor_value_get_type(&repMap))
990 err = !OCRepPayloadSetNull(curPayload, name);
992 case CborIntegerType:
993 err = err || cbor_value_get_int64(&repMap, &intval);
996 err = !OCRepPayloadSetPropInt(curPayload, name, intval);
1000 err = err || cbor_value_get_double(&repMap, &doubleval);
1003 err = !OCRepPayloadSetPropDouble(curPayload, name, doubleval);
1006 case CborBooleanType:
1007 err = err || cbor_value_get_boolean(&repMap, &boolval);
1010 err = !OCRepPayloadSetPropBool(curPayload, name, boolval);
1013 case CborTextStringType:
1014 err = err || cbor_value_dup_text_string(&repMap, &strval, &len, NULL);
1017 err = !OCRepPayloadSetPropStringAsOwner(curPayload, name, strval);
1021 err = err || OCParseSingleRepPayload(&pl, &repMap);
1024 err = !OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl);
1028 err = err || OCParseArray(curPayload, name, &repMap);
1031 OC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type);
1035 err = err || cbor_value_advance(&repMap);
1038 err = err || cbor_value_leave_container(&curVal, &repMap);
1043 OCRepPayloadDestroy(*outPayload);
1049 static OCStackResult OCParseRepPayload(OCPayload** outPayload, CborValue* arrayVal)
1053 return OC_STACK_INVALID_PARAM;
1058 OCRepPayload* rootPayload = NULL;
1059 OCRepPayload* curPayload = NULL;
1060 OCRepPayload* temp = NULL;
1061 while(!err && cbor_value_is_map(arrayVal))
1063 err = err || OCParseSingleRepPayload(&temp, arrayVal);
1065 if(rootPayload == NULL)
1072 curPayload->next = temp;
1073 curPayload = curPayload->next;
1077 err = err || cbor_value_advance(arrayVal);
1080 OCRepPayloadDestroy(rootPayload);
1081 OC_LOG(ERROR, TAG, "CBOR error in ParseRepPayload");
1082 return OC_STACK_MALFORMED_RESPONSE;
1086 *outPayload = (OCPayload*)rootPayload;
1091 static OCStackResult OCParsePresencePayload(OCPayload** outPayload, CborValue* arrayVal)
1095 return OC_STACK_INVALID_PARAM;
1099 if(cbor_value_is_map(arrayVal))
1101 uint64_t seqNum = 0;
1102 uint64_t maxAge = 0;
1103 OCPresenceTrigger trigger = OC_PRESENCE_TRIGGER_CREATE;
1104 char* tempStr = NULL;
1109 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_NONCE, &curVal);
1110 err = err || cbor_value_get_uint64(&curVal, &seqNum);
1113 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_TTL, &curVal);
1114 err = err || cbor_value_get_uint64(&curVal, &maxAge);
1117 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_TRIGGER, &curVal);
1118 err = err || cbor_value_dup_text_string(&curVal, &tempStr, &len, NULL);
1119 trigger = convertTriggerStringToEnum(tempStr);
1123 // Resource type name
1124 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_RESOURCE_TYPE, &curVal);
1125 if(cbor_value_is_valid(&curVal))
1127 err = err || cbor_value_dup_text_string(&curVal, &tempStr, &len, NULL);
1130 err = err || cbor_value_advance(arrayVal);
1134 *outPayload = (OCPayload*)OCPresencePayloadCreate(seqNum, maxAge, trigger, tempStr);
1140 OCPayloadDestroy(*outPayload);
1141 OC_LOG(ERROR, TAG, "CBOR error Parse Presence Payload");
1142 return OC_STACK_MALFORMED_RESPONSE;
1147 return OC_STACK_NO_MEMORY;
1154 OC_LOG(ERROR, TAG, "Root presence node was not a map");
1155 return OC_STACK_MALFORMED_RESPONSE;