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 err = err || cbor_value_dup_byte_string(&repVal, &sid, &len, NULL);
383 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DEVICE_NAME, &repVal);
384 err = err || cbor_value_dup_text_string(&repVal, &dname, &len, NULL);
385 // Device Spec Version
386 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SPEC_VERSION, &repVal);
387 err = err || cbor_value_dup_text_string(&repVal, &specVer, &len, NULL);
388 // Data Model Version
389 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DATA_MODEL_VERSION, &repVal);
390 err = err || cbor_value_dup_text_string(&repVal, &dmVer, &len, NULL);
394 err = err || cbor_value_advance(arrayVal);
403 OC_LOG_V(ERROR, TAG, "CBOR in error condition %d", err);
404 return OC_STACK_MALFORMED_RESPONSE;
407 *outPayload = (OCPayload*)OCDevicePayloadCreate(uri, sid, dname, specVer, dmVer);
416 return OC_STACK_NO_MEMORY;
423 OC_LOG(ERROR, TAG, "Root device node was not a map");
424 return OC_STACK_MALFORMED_RESPONSE;
429 static OCStackResult OCParsePlatformPayload(OCPayload** outPayload, CborValue* arrayVal)
433 return OC_STACK_INVALID_PARAM;
438 if(cbor_value_is_map(arrayVal))
441 OCPlatformInfo info = {0};
443 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
445 err = err || cbor_value_dup_text_string(&curVal, &uri, &len, NULL);
449 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
453 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_PLATFORM_ID, &repVal);
454 err = err || cbor_value_dup_text_string(&repVal, &(info.platformID), &len, NULL);
457 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_NAME, &repVal);
458 err = err || cbor_value_dup_text_string(&repVal, &(info.manufacturerName), &len, NULL);
461 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_URL, &repVal);
462 if(cbor_value_is_valid(&repVal))
464 err = err || cbor_value_dup_text_string(&repVal, &(info.manufacturerUrl), &len, NULL);
468 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MODEL_NUM, &repVal);
469 if(cbor_value_is_valid(&repVal))
471 err = err || cbor_value_dup_text_string(&repVal, &(info.modelNumber), &len, NULL);
475 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_DATE, &repVal);
476 if(cbor_value_is_valid(&repVal))
478 err = err || cbor_value_dup_text_string(&repVal, &(info.dateOfManufacture), &len,
483 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_PLATFORM_VERSION, &repVal);
484 if(cbor_value_is_valid(&repVal))
486 err = err || cbor_value_dup_text_string(&repVal, &(info.platformVersion), &len,
491 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_OS_VERSION, &repVal);
492 if(cbor_value_is_valid(&repVal))
494 err = err || cbor_value_dup_text_string(&repVal, &(info.operatingSystemVersion),
499 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_HARDWARE_VERSION, &repVal);
500 if(cbor_value_is_valid(&repVal))
502 err = err || cbor_value_dup_text_string(&repVal, &(info.hardwareVersion), &len,
507 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_FIRMWARE_VERSION, &repVal);
508 if(cbor_value_is_valid(&repVal))
510 err = err || cbor_value_dup_text_string(&repVal, &(info.firmwareVersion), &len,
515 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SUPPORT_URL, &repVal);
516 if(cbor_value_is_valid(&repVal))
518 err = err || cbor_value_dup_text_string(&repVal, &(info.supportUrl), &len, NULL);
522 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SYSTEM_TIME, &repVal);
523 if(cbor_value_is_valid(&repVal))
525 err = err || cbor_value_dup_text_string(&repVal, &(info.systemTime), &len, NULL);
529 err = err || cbor_value_advance(arrayVal);
533 OICFree(info.dateOfManufacture);
534 OICFree(info.firmwareVersion);
535 OICFree(info.hardwareVersion);
536 OICFree(info.manufacturerName);
537 OICFree(info.manufacturerUrl);
538 OICFree(info.modelNumber);
539 OICFree(info.operatingSystemVersion);
540 OICFree(info.platformID);
541 OICFree(info.platformVersion);
542 OICFree(info.supportUrl);
543 OICFree(info.systemTime);
544 OC_LOG(ERROR, TAG, "CBOR error In ParsePlatformPayload");
545 return OC_STACK_MALFORMED_RESPONSE;
548 *outPayload = (OCPayload*)OCPlatformPayloadCreateAsOwner(uri, &info);
552 return OC_STACK_NO_MEMORY;
559 OC_LOG(ERROR, TAG, "Root device node was not a map");
560 return OC_STACK_MALFORMED_RESPONSE;
564 static OCRepPayloadPropType DecodeCborType(CborType type)
569 return OCREP_PROP_NULL;
570 case CborIntegerType:
571 return OCREP_PROP_INT;
573 return OCREP_PROP_DOUBLE;
574 case CborBooleanType:
575 return OCREP_PROP_BOOL;
576 case CborTextStringType:
577 return OCREP_PROP_STRING;
579 return OCREP_PROP_OBJECT;
581 return OCREP_PROP_ARRAY;
583 return OCREP_PROP_NULL;
586 static bool OCParseArrayFindDimensionsAndType(const CborValue* parent, size_t dimensions[MAX_REP_ARRAY_DEPTH],
587 OCRepPayloadPropType* type)
590 CborValue insideArray;
591 *type = OCREP_PROP_NULL;
592 dimensions[0] = dimensions[1] = dimensions[2] = 0;
594 err = err || cbor_value_enter_container(parent, &insideArray);
596 while (cbor_value_is_valid(&insideArray))
598 OCRepPayloadPropType tempType = DecodeCborType(cbor_value_get_type(&insideArray));
600 if (tempType == OCREP_PROP_ARRAY)
602 size_t subdim[MAX_REP_ARRAY_DEPTH];
603 tempType = OCREP_PROP_NULL;
604 err = err || OCParseArrayFindDimensionsAndType(&insideArray, subdim, &tempType);
608 OC_LOG(ERROR, TAG, "Parse array helper, sub-array too deep");
611 dimensions[1] = dimensions[1] >= subdim[0] ? dimensions[1] : subdim[0];
612 dimensions[2] = dimensions[2] >= subdim[1] ? dimensions[2] : subdim[1];
614 if (*type != OCREP_PROP_NULL && tempType != OCREP_PROP_NULL
615 && *type != tempType)
617 OC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed (subtype)");
620 else if (*type == OCREP_PROP_NULL)
622 // We don't know the type of this array yet, so the assignment is OK
626 else if (*type == OCREP_PROP_NULL)
628 // We don't know the type of this array yet, so the assignment is OK
631 // tempType is allowed to be NULL, since it might now know the answer yet
632 else if (tempType != OCREP_PROP_NULL && *type != tempType)
634 // this is an invalid situation!
635 OC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed");
640 cbor_value_advance(&insideArray);
646 static size_t getAllocSize(OCRepPayloadPropType type)
651 return sizeof (int64_t);
652 case OCREP_PROP_DOUBLE:
653 return sizeof (double);
654 case OCREP_PROP_BOOL:
655 return sizeof (bool);
656 case OCREP_PROP_STRING:
657 return sizeof (char*);
658 case OCREP_PROP_OBJECT:
659 return sizeof (OCRepPayload*);
665 static size_t arrayStep(size_t dimensions[MAX_REP_ARRAY_DEPTH], size_t elementNum)
668 (dimensions[1] == 0 ? 1 : dimensions[1]) *
669 (dimensions[2] == 0 ? 1 : dimensions[2]) *
673 static bool OCParseArrayFillArray(const CborValue* parent, size_t dimensions[MAX_REP_ARRAY_DEPTH],
674 OCRepPayloadPropType type, void* targetArray)
677 CborValue insideArray;
679 err = err || cbor_value_enter_container(parent, &insideArray);
682 char* tempStr = NULL;
684 OCRepPayload* tempPl = NULL;
686 size_t newdim[MAX_REP_ARRAY_DEPTH];
687 newdim[0] = dimensions[1];
688 newdim[1] = dimensions[2];
691 while (!err && i < dimensions[0] && cbor_value_is_valid(&insideArray))
693 if (cbor_value_get_type(&insideArray) != CborNullType)
698 if (dimensions[1] == 0)
700 err = err || cbor_value_get_int64(&insideArray,
701 &(((int64_t*)targetArray)[i]));
705 err = err || OCParseArrayFillArray(&insideArray, newdim,
707 &(((int64_t*)targetArray)[arrayStep(dimensions, i)])
711 case OCREP_PROP_DOUBLE:
712 if (dimensions[1] == 0)
714 err = err || cbor_value_get_double(&insideArray,
715 &(((double*)targetArray)[i]));
719 err = err || OCParseArrayFillArray(&insideArray, newdim,
721 &(((double*)targetArray)[arrayStep(dimensions, i)])
725 case OCREP_PROP_BOOL:
726 if (dimensions[1] == 0)
728 err = err || cbor_value_get_boolean(&insideArray,
729 &(((bool*)targetArray)[i]));
733 err = err || OCParseArrayFillArray(&insideArray, newdim,
735 &(((bool*)targetArray)[arrayStep(dimensions, i)])
739 case OCREP_PROP_STRING:
740 if (dimensions[1] == 0)
742 err = err || cbor_value_dup_text_string(&insideArray,
743 &tempStr, &tempLen, NULL);
744 ((char**)targetArray)[i] = tempStr;
749 err = err || OCParseArrayFillArray(&insideArray, newdim,
751 &(((char**)targetArray)[arrayStep(dimensions, i)])
755 case OCREP_PROP_OBJECT:
756 if (dimensions[1] == 0)
758 err = err || OCParseSingleRepPayload(&tempPl, &insideArray);
759 ((OCRepPayload**)targetArray)[i] = tempPl;
764 err = err || OCParseArrayFillArray(&insideArray, newdim,
766 &(((OCRepPayload**)targetArray)[arrayStep(dimensions, i)])
771 OC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
777 err = err || cbor_value_advance(&insideArray);
783 static bool OCParseArray(OCRepPayload* out, const char* name, CborValue* container)
785 OCRepPayloadPropType type;
786 size_t dimensions[MAX_REP_ARRAY_DEPTH];
787 bool err = OCParseArrayFindDimensionsAndType(container, dimensions, &type);
791 OC_LOG(ERROR, TAG, "Array details weren't clear");
795 if (type == OCREP_PROP_NULL)
797 err = err || OCRepPayloadSetNull(out, name);
798 err = err || cbor_value_advance(container);
802 size_t dimTotal = calcDimTotal(dimensions);
803 size_t allocSize = getAllocSize(type);
804 void* arr = OICCalloc(dimTotal, allocSize);
808 OC_LOG(ERROR, TAG, "Array Parse allocation failed");
812 err = err || OCParseArrayFillArray(container, dimensions, type, arr);
817 if (err || !OCRepPayloadSetIntArrayAsOwner(out, name, (int64_t*)arr, dimensions))
823 case OCREP_PROP_DOUBLE:
824 if (err || !OCRepPayloadSetDoubleArrayAsOwner(out, name, (double*)arr, dimensions))
830 case OCREP_PROP_BOOL:
831 if (err || !OCRepPayloadSetBoolArrayAsOwner(out, name, (bool*)arr, dimensions))
837 case OCREP_PROP_STRING:
838 if (err || !OCRepPayloadSetStringArrayAsOwner(out, name, (char**)arr, dimensions))
840 for(size_t i = 0; i < dimTotal; ++i)
842 OICFree(((char**)arr)[i]);
848 case OCREP_PROP_OBJECT:
849 if (err || !OCRepPayloadSetPropObjectArrayAsOwner(out, name, (OCRepPayload**)arr, dimensions))
851 for(size_t i = 0; i < dimTotal; ++i)
853 OCRepPayloadDestroy(((OCRepPayload**)arr)[i]);
860 OC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
868 static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue* repParent)
875 *outPayload = OCRepPayloadCreate();
876 OCRepPayload* curPayload = *outPayload;
880 return CborErrorOutOfMemory;
885 err = err || cbor_value_map_find_value(repParent, OC_RSRVD_HREF, &curVal);
886 if(cbor_value_is_valid(&curVal))
888 err = err || cbor_value_dup_text_string(&curVal, &curPayload->uri, &len,
892 err = err || cbor_value_map_find_value(repParent, OC_RSRVD_PROPERTY, &curVal);
893 if(cbor_value_is_valid(&curVal))
895 CborValue insidePropValue = {0};
896 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_RESOURCE_TYPE,
899 if(cbor_value_is_text_string(&insidePropValue))
902 err = err || cbor_value_dup_text_string(&insidePropValue, &allRt, &len, NULL);
908 char* curPtr = strtok_r(allRt, " ", &savePtr);
912 char* trimmed = InPlaceStringTrim(curPtr);
913 if (trimmed[0] != '\0')
915 OCRepPayloadAddResourceType(curPayload, curPtr);
917 curPtr = strtok_r(NULL, " ", &savePtr);
923 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_INTERFACE, &insidePropValue);
925 if(cbor_value_is_text_string(&insidePropValue))
928 err = err || cbor_value_dup_text_string(&insidePropValue, &allIf, &len, NULL);
934 char* curPtr = strtok_r(allIf, " ", &savePtr);
938 char* trimmed = InPlaceStringTrim(curPtr);
939 if (trimmed[0] != '\0')
941 OCRepPayloadAddInterface(curPayload, curPtr);
943 curPtr = strtok_r(NULL, " ", &savePtr);
950 err = err || cbor_value_map_find_value(repParent, OC_RSRVD_REPRESENTATION, &curVal);
951 if(cbor_value_is_map(&curVal))
954 err = err || cbor_value_enter_container(&curVal, &repMap);
956 while(!err && cbor_value_is_valid(&repMap))
959 err = err || cbor_value_dup_text_string(&repMap, &name, &len, NULL);
961 err = err || cbor_value_advance(&repMap);
964 bool boolval = false;
966 double doubleval = 0;
969 switch(cbor_value_get_type(&repMap))
972 err = !OCRepPayloadSetNull(curPayload, name);
974 case CborIntegerType:
975 err = err || cbor_value_get_int64(&repMap, &intval);
978 err = !OCRepPayloadSetPropInt(curPayload, name, intval);
982 err = err || cbor_value_get_double(&repMap, &doubleval);
985 err = !OCRepPayloadSetPropDouble(curPayload, name, doubleval);
988 case CborBooleanType:
989 err = err || cbor_value_get_boolean(&repMap, &boolval);
992 err = !OCRepPayloadSetPropBool(curPayload, name, boolval);
995 case CborTextStringType:
996 err = err || cbor_value_dup_text_string(&repMap, &strval, &len, NULL);
999 err = !OCRepPayloadSetPropStringAsOwner(curPayload, name, strval);
1003 err = err || OCParseSingleRepPayload(&pl, &repMap);
1006 err = !OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl);
1010 err = err || OCParseArray(curPayload, name, &repMap);
1013 OC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type);
1017 err = err || cbor_value_advance(&repMap);
1020 err = err || cbor_value_leave_container(&curVal, &repMap);
1025 OCRepPayloadDestroy(*outPayload);
1031 static OCStackResult OCParseRepPayload(OCPayload** outPayload, CborValue* arrayVal)
1035 return OC_STACK_INVALID_PARAM;
1040 OCRepPayload* rootPayload = NULL;
1041 OCRepPayload* curPayload = NULL;
1042 OCRepPayload* temp = NULL;
1043 while(!err && cbor_value_is_map(arrayVal))
1045 err = err || OCParseSingleRepPayload(&temp, arrayVal);
1047 if(rootPayload == NULL)
1054 curPayload->next = temp;
1055 curPayload = curPayload->next;
1059 err = err || cbor_value_advance(arrayVal);
1062 OCRepPayloadDestroy(rootPayload);
1063 OC_LOG(ERROR, TAG, "CBOR error in ParseRepPayload");
1064 return OC_STACK_MALFORMED_RESPONSE;
1068 *outPayload = (OCPayload*)rootPayload;
1073 static OCStackResult OCParsePresencePayload(OCPayload** outPayload, CborValue* arrayVal)
1077 return OC_STACK_INVALID_PARAM;
1081 if(cbor_value_is_map(arrayVal))
1083 uint64_t seqNum = 0;
1084 uint64_t maxAge = 0;
1085 OCPresenceTrigger trigger = OC_PRESENCE_TRIGGER_CREATE;
1086 char* tempStr = NULL;
1091 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_NONCE, &curVal);
1092 err = err || cbor_value_get_uint64(&curVal, &seqNum);
1095 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_TTL, &curVal);
1096 err = err || cbor_value_get_uint64(&curVal, &maxAge);
1099 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_TRIGGER, &curVal);
1100 err = err || cbor_value_dup_text_string(&curVal, &tempStr, &len, NULL);
1101 trigger = convertTriggerStringToEnum(tempStr);
1105 // Resource type name
1106 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_RESOURCE_TYPE, &curVal);
1107 if(cbor_value_is_valid(&curVal))
1109 err = err || cbor_value_dup_text_string(&curVal, &tempStr, &len, NULL);
1112 err = err || cbor_value_advance(arrayVal);
1116 *outPayload = (OCPayload*)OCPresencePayloadCreate(seqNum, maxAge, trigger, tempStr);
1122 OCPayloadDestroy(*outPayload);
1123 OC_LOG(ERROR, TAG, "CBOR error Parse Presence Payload");
1124 return OC_STACK_MALFORMED_RESPONSE;
1129 return OC_STACK_NO_MEMORY;
1136 OC_LOG(ERROR, TAG, "Root presence node was not a map");
1137 return OC_STACK_MALFORMED_RESPONSE;