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 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 OC_LOG_V(ERROR, TAG, "ParsePayload Type default: %d", payloadType);
92 result = OC_STACK_ERROR;
96 if(result != OC_STACK_OK)
98 OC_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;
118 err = err || cbor_value_enter_container(rootValue, &map);
119 err = err || cbor_value_dup_text_string(&map, &securityData, &len, NULL);
120 err = err || cbor_value_leave_container(rootValue, &map);
124 OC_LOG(ERROR, TAG, "Cbor in error condition");
125 OICFree(securityData);
126 return OC_STACK_MALFORMED_RESPONSE;
129 *outPayload = (OCPayload*)OCSecurityPayloadCreate(securityData);
130 OICFree(securityData);
136 static char* InPlaceStringTrim(char* str)
138 while (str[0] == ' ')
143 size_t lastchar = strlen(str);
145 while (str[lastchar] == ' ')
147 str[lastchar] = '\0';
154 static OCStackResult OCParseDiscoveryPayload(OCPayload** outPayload, CborValue* rootValue)
158 return OC_STACK_INVALID_PARAM;
162 OCResourcePayload* resource = NULL;
163 uint16_t resourceCount = 0;
164 CborValue resourceMap = {};
166 OCDiscoveryPayload* out = OCDiscoveryPayloadCreate();
169 return OC_STACK_NO_MEMORY;
172 // Root value is already inside the main root array
173 CborValue rootMap = {};
175 // Enter the main root map
176 err = err || cbor_value_enter_container(rootValue, &rootMap);
178 CborValue curVal = {};
179 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_DEVICE_ID, &curVal);
180 if (CborNoError != err)
182 OC_LOG(ERROR, TAG, "Cbor find value failed.");
186 err = cbor_value_dup_byte_string(&curVal, &(out->sid), &len, NULL);
188 // Look for Links which will have an array as the value
189 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_LINKS, &curVal);
190 if (CborNoError != err)
192 OC_LOG(ERROR, TAG, "Cbor find value failed.");
196 // Enter the links array and start iterating through the array processing
197 // each resource which shows up as a map.
198 err = err || cbor_value_enter_container(&curVal, &resourceMap);
200 while (cbor_value_is_map(&resourceMap))
202 resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
205 OC_LOG(ERROR, TAG, "Memory allocation failed");
206 OCDiscoveryPayloadDestroy(out);
207 return OC_STACK_NO_MEMORY;
211 CborValue uriVal = {};
212 err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_HREF, &uriVal);
213 if (CborNoError != err)
215 OC_LOG(ERROR, TAG, "Cbor finding href type failed.");
218 err = cbor_value_dup_text_string(&uriVal, &(resource->uri), &len, NULL);
219 if (CborNoError != err)
221 OC_LOG(ERROR, TAG, "Cbor finding href value failed.");
225 CborValue rtVal = {};
226 err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_RESOURCE_TYPE, &rtVal);
227 if (CborNoError != err)
229 OC_LOG(ERROR, TAG, "Cbor finding rt type failed.");
232 if (cbor_value_is_text_string(&rtVal))
236 err = cbor_value_dup_text_string(&rtVal, &input, &len, NULL);
237 if (CborNoError != err)
239 OC_LOG(ERROR, TAG, "Cbor finding rt value failed.");
244 char* curPtr = strtok_r(input, " ", &savePtr);
248 char* trimmed = InPlaceStringTrim(curPtr);
249 if (trimmed[0] !='\0')
251 if (!OCResourcePayloadAddResourceType(resource, trimmed))
253 OICFree(resource->uri);
254 OCFreeOCStringLL(resource->types);
256 OCDiscoveryPayloadDestroy(out);
257 return OC_STACK_NO_MEMORY;
260 curPtr = strtok_r(NULL, " ", &savePtr);
267 CborValue ifVal = {};
268 err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_INTERFACE, &ifVal);
269 if (CborNoError != err)
271 OC_LOG(ERROR, TAG, "Cbor finding if type failed.");
274 if (!err && cbor_value_is_text_string(&ifVal))
278 err = cbor_value_dup_text_string(&ifVal, &input, &len, NULL);
279 if (CborNoError != err)
281 OC_LOG(ERROR, TAG, "Cbor finding if value failed.");
286 char* curPtr = strtok_r(input, " ", &savePtr);
290 char* trimmed = InPlaceStringTrim(curPtr);
291 if (trimmed[0] !='\0')
293 if (!OCResourcePayloadAddInterface(resource, trimmed))
295 OICFree(resource->uri);
296 OCFreeOCStringLL(resource->types);
298 OCDiscoveryPayloadDestroy(out);
299 return OC_STACK_NO_MEMORY;
302 curPtr = strtok_r(NULL, " ", &savePtr);
309 CborValue policyMap = {};
310 err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_POLICY, &policyMap);
311 if (CborNoError != err)
313 OC_LOG(ERROR, TAG, "Cbor finding policy type failed.");
318 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &val);
319 if (CborNoError != err)
321 OC_LOG(ERROR, TAG, "Cbor finding bitmap type failed.");
325 err = cbor_value_get_uint64(&val, &temp);
326 if (CborNoError != err)
328 OC_LOG(ERROR, TAG, "Cbor finding bitmap value failed.");
331 resource->bitmap = (uint8_t)temp;
333 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &val);
334 if (CborNoError != err)
336 OC_LOG(ERROR, TAG, "Cbor finding secure type failed.");
339 if(cbor_value_is_valid(&val))
341 err = cbor_value_get_boolean(&val, &(resource->secure));
342 if (CborNoError != err)
344 OC_LOG(ERROR, TAG, "Cbor finding secure value failed.");
349 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT,
351 if (CborNoError != err)
353 OC_LOG(ERROR, TAG, "Cbor finding port type failed.");
356 if(cbor_value_is_valid(&port))
358 err = cbor_value_get_uint64(&port, &temp);
359 if (CborNoError != err)
361 OC_LOG(ERROR, TAG, "Cbor finding port value failed.");
364 resource->port = (uint16_t)temp;
368 err = cbor_value_advance(&resourceMap);
369 if (CborNoError != err)
371 OC_LOG(ERROR, TAG, "Cbor advance value failed.");
375 OCDiscoveryPayloadAddNewResource(out, resource);
378 err = err || cbor_value_leave_container(rootValue, &resourceMap);
380 *outPayload = (OCPayload*)out;
384 OICFree(resource->uri);
385 OCFreeOCStringLL(resource->types);
386 OCFreeOCStringLL(resource->interfaces);
388 OCDiscoveryPayloadDestroy(out);
389 return OC_STACK_MALFORMED_RESPONSE;
392 OCDiscoveryCollectionPayloadDestroy(out);
393 return OC_STACK_MALFORMED_RESPONSE;
396 static OCStackResult OCParseDevicePayload(OCPayload** outPayload, CborValue* rootValue)
400 return OC_STACK_INVALID_PARAM;
405 if(cbor_value_is_map(rootValue))
409 char* specVer = NULL;
414 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_ID, &repVal);
416 if(cbor_value_is_valid(&repVal))
418 err = err || cbor_value_dup_byte_string(&repVal, &sid, &len, NULL);
421 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_NAME, &repVal);
422 if(cbor_value_is_valid(&repVal))
424 err = err || cbor_value_dup_text_string(&repVal, &dname, &len, NULL);
426 // Device Spec Version
427 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_SPEC_VERSION, &repVal);
428 if(cbor_value_is_valid(&repVal))
430 err = err || cbor_value_dup_text_string(&repVal, &specVer, &len, NULL);
432 // Data Model Version
433 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_DATA_MODEL_VERSION, &repVal);
434 if (cbor_value_is_valid(&repVal))
436 err = err || cbor_value_dup_text_string(&repVal, &dmVer, &len, NULL);
439 err = err || cbor_value_advance(rootValue);
447 OC_LOG_V(ERROR, TAG, "CBOR in error condition %d", err);
448 return OC_STACK_MALFORMED_RESPONSE;
451 *outPayload = (OCPayload*)OCDevicePayloadCreate(sid, dname, specVer, dmVer);
459 return OC_STACK_NO_MEMORY;
466 OC_LOG(ERROR, TAG, "Root device node was not a map");
467 return OC_STACK_MALFORMED_RESPONSE;
472 static OCStackResult OCParsePlatformPayload(OCPayload** outPayload, CborValue* rootValue)
476 return OC_STACK_INVALID_PARAM;
481 if(cbor_value_is_map(rootValue))
483 OCPlatformInfo info = {0};
488 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_PLATFORM_ID, &repVal);
489 if(cbor_value_is_valid(&repVal))
491 err = err || cbor_value_dup_text_string(&repVal, &(info.platformID), &len, NULL);
495 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_NAME, &repVal);
496 if(cbor_value_is_valid(&repVal))
498 err = err || cbor_value_dup_text_string(&repVal, &(info.manufacturerName), &len, NULL);
502 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_URL, &repVal);
503 if(cbor_value_is_valid(&repVal))
505 err = err || cbor_value_dup_text_string(&repVal, &(info.manufacturerUrl), &len, NULL);
509 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_MODEL_NUM, &repVal);
510 if(cbor_value_is_valid(&repVal))
512 err = err || cbor_value_dup_text_string(&repVal, &(info.modelNumber), &len, NULL);
516 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_DATE, &repVal);
517 if(cbor_value_is_valid(&repVal))
519 err = err || cbor_value_dup_text_string(&repVal, &(info.dateOfManufacture), &len,
524 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_PLATFORM_VERSION, &repVal);
525 if(cbor_value_is_valid(&repVal))
527 err = err || cbor_value_dup_text_string(&repVal, &(info.platformVersion), &len, NULL);
531 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_OS_VERSION, &repVal);
532 if(cbor_value_is_valid(&repVal))
534 err = err || cbor_value_dup_text_string(&repVal, &(info.operatingSystemVersion),
539 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_HARDWARE_VERSION, &repVal);
540 if(cbor_value_is_valid(&repVal))
542 err = err || cbor_value_dup_text_string(&repVal, &(info.hardwareVersion), &len,
547 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_FIRMWARE_VERSION, &repVal);
548 if(cbor_value_is_valid(&repVal))
550 err = err || cbor_value_dup_text_string(&repVal, &(info.firmwareVersion), &len,
555 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_SUPPORT_URL, &repVal);
556 if(cbor_value_is_valid(&repVal))
558 err = err || cbor_value_dup_text_string(&repVal, &(info.supportUrl), &len, NULL);
562 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_SYSTEM_TIME, &repVal);
563 if(cbor_value_is_valid(&repVal))
565 err = err || cbor_value_dup_text_string(&repVal, &(info.systemTime), &len, NULL);
568 err = err || cbor_value_advance(rootValue);
572 OICFree(info.dateOfManufacture);
573 OICFree(info.firmwareVersion);
574 OICFree(info.hardwareVersion);
575 OICFree(info.manufacturerName);
576 OICFree(info.manufacturerUrl);
577 OICFree(info.modelNumber);
578 OICFree(info.operatingSystemVersion);
579 OICFree(info.platformID);
580 OICFree(info.platformVersion);
581 OICFree(info.supportUrl);
582 OICFree(info.systemTime);
583 OC_LOG(ERROR, TAG, "CBOR error In ParsePlatformPayload");
584 return OC_STACK_MALFORMED_RESPONSE;
587 *outPayload = (OCPayload*)OCPlatformPayloadCreateAsOwner(&info);
591 return OC_STACK_NO_MEMORY;
598 OC_LOG(ERROR, TAG, "Root device node was not a map");
599 return OC_STACK_MALFORMED_RESPONSE;
603 static OCRepPayloadPropType DecodeCborType(CborType type)
608 return OCREP_PROP_NULL;
609 case CborIntegerType:
610 return OCREP_PROP_INT;
612 return OCREP_PROP_DOUBLE;
613 case CborBooleanType:
614 return OCREP_PROP_BOOL;
615 case CborTextStringType:
616 return OCREP_PROP_STRING;
617 case CborByteStringType:
618 return OCREP_PROP_BYTE_STRING;
620 return OCREP_PROP_OBJECT;
622 return OCREP_PROP_ARRAY;
624 return OCREP_PROP_NULL;
627 static bool OCParseArrayFindDimensionsAndType(const CborValue* parent, size_t dimensions[MAX_REP_ARRAY_DEPTH],
628 OCRepPayloadPropType* type)
631 CborValue insideArray;
632 *type = OCREP_PROP_NULL;
633 dimensions[0] = dimensions[1] = dimensions[2] = 0;
635 err = err || cbor_value_enter_container(parent, &insideArray);
637 while (cbor_value_is_valid(&insideArray))
639 OCRepPayloadPropType tempType = DecodeCborType(cbor_value_get_type(&insideArray));
641 if (tempType == OCREP_PROP_ARRAY)
643 size_t subdim[MAX_REP_ARRAY_DEPTH];
644 tempType = OCREP_PROP_NULL;
645 err = err || OCParseArrayFindDimensionsAndType(&insideArray, subdim, &tempType);
649 OC_LOG(ERROR, TAG, "Parse array helper, sub-array too deep");
652 dimensions[1] = dimensions[1] >= subdim[0] ? dimensions[1] : subdim[0];
653 dimensions[2] = dimensions[2] >= subdim[1] ? dimensions[2] : subdim[1];
655 if (*type != OCREP_PROP_NULL && tempType != OCREP_PROP_NULL
656 && *type != tempType)
658 OC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed (subtype)");
661 else if (*type == OCREP_PROP_NULL)
663 // We don't know the type of this array yet, so the assignment is OK
667 else if (*type == OCREP_PROP_NULL)
669 // We don't know the type of this array yet, so the assignment is OK
672 // tempType is allowed to be NULL, since it might now know the answer yet
673 else if (tempType != OCREP_PROP_NULL && *type != tempType)
675 // this is an invalid situation!
676 OC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed");
681 cbor_value_advance(&insideArray);
687 static size_t getAllocSize(OCRepPayloadPropType type)
692 return sizeof (int64_t);
693 case OCREP_PROP_DOUBLE:
694 return sizeof (double);
695 case OCREP_PROP_BOOL:
696 return sizeof (bool);
697 case OCREP_PROP_STRING:
698 return sizeof (char*);
699 case OCREP_PROP_BYTE_STRING:
700 return sizeof (OCByteString);
701 case OCREP_PROP_OBJECT:
702 return sizeof (OCRepPayload*);
708 static size_t arrayStep(size_t dimensions[MAX_REP_ARRAY_DEPTH], size_t elementNum)
711 (dimensions[1] == 0 ? 1 : dimensions[1]) *
712 (dimensions[2] == 0 ? 1 : dimensions[2]) *
716 static bool OCParseArrayFillArray(const CborValue* parent, size_t dimensions[MAX_REP_ARRAY_DEPTH],
717 OCRepPayloadPropType type, void* targetArray)
720 CborValue insideArray;
722 err = err || cbor_value_enter_container(parent, &insideArray);
725 char* tempStr = NULL;
726 OCByteString ocByteStr = { .bytes = NULL, .len = 0};
728 OCRepPayload* tempPl = NULL;
730 size_t newdim[MAX_REP_ARRAY_DEPTH];
731 newdim[0] = dimensions[1];
732 newdim[1] = dimensions[2];
735 while (!err && i < dimensions[0] && cbor_value_is_valid(&insideArray))
737 bool noAdvance = false;
738 if (cbor_value_get_type(&insideArray) != CborNullType)
743 if (dimensions[1] == 0)
745 err = err || cbor_value_get_int64(&insideArray,
746 &(((int64_t*)targetArray)[i]));
750 err = err || OCParseArrayFillArray(&insideArray, newdim,
752 &(((int64_t*)targetArray)[arrayStep(dimensions, i)])
756 case OCREP_PROP_DOUBLE:
757 if (dimensions[1] == 0)
759 err = err || cbor_value_get_double(&insideArray,
760 &(((double*)targetArray)[i]));
764 err = err || OCParseArrayFillArray(&insideArray, newdim,
766 &(((double*)targetArray)[arrayStep(dimensions, i)])
770 case OCREP_PROP_BOOL:
771 if (dimensions[1] == 0)
773 err = err || cbor_value_get_boolean(&insideArray,
774 &(((bool*)targetArray)[i]));
778 err = err || OCParseArrayFillArray(&insideArray, newdim,
780 &(((bool*)targetArray)[arrayStep(dimensions, i)])
784 case OCREP_PROP_STRING:
785 if (dimensions[1] == 0)
787 err = err || cbor_value_dup_text_string(&insideArray,
788 &tempStr, &tempLen, NULL);
789 ((char**)targetArray)[i] = tempStr;
794 err = err || OCParseArrayFillArray(&insideArray, newdim,
796 &(((char**)targetArray)[arrayStep(dimensions, i)])
800 case OCREP_PROP_BYTE_STRING:
801 if (dimensions[1] == 0)
803 err = err || cbor_value_dup_byte_string(&insideArray,
804 &(ocByteStr.bytes), &(ocByteStr.len), NULL);
805 ((OCByteString*)targetArray)[i] = ocByteStr;
809 err = err || OCParseArrayFillArray(&insideArray, newdim,
811 &(((OCByteString*)targetArray)[arrayStep(dimensions, i)])
815 case OCREP_PROP_OBJECT:
816 if (dimensions[1] == 0)
818 err = err || OCParseSingleRepPayload(&tempPl, &insideArray);
819 ((OCRepPayload**)targetArray)[i] = tempPl;
825 err = err || OCParseArrayFillArray(&insideArray, newdim,
827 &(((OCRepPayload**)targetArray)[arrayStep(dimensions, i)])
832 OC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
838 if (!noAdvance && cbor_value_is_valid(&insideArray))
840 err = err || cbor_value_advance(&insideArray);
847 static bool OCParseArray(OCRepPayload* out, const char* name, CborValue* container)
849 OCRepPayloadPropType type;
850 size_t dimensions[MAX_REP_ARRAY_DEPTH];
851 bool err = OCParseArrayFindDimensionsAndType(container, dimensions, &type);
855 OC_LOG(ERROR, TAG, "Array details weren't clear");
859 if (type == OCREP_PROP_NULL)
861 err = err || OCRepPayloadSetNull(out, name);
862 err = err || cbor_value_advance(container);
866 size_t dimTotal = calcDimTotal(dimensions);
867 size_t allocSize = getAllocSize(type);
868 void* arr = OICCalloc(dimTotal, allocSize);
872 OC_LOG(ERROR, TAG, "Array Parse allocation failed");
876 err = err || OCParseArrayFillArray(container, dimensions, type, arr);
881 if (err || !OCRepPayloadSetIntArrayAsOwner(out, name, (int64_t*)arr, dimensions))
887 case OCREP_PROP_DOUBLE:
888 if (err || !OCRepPayloadSetDoubleArrayAsOwner(out, name, (double*)arr, dimensions))
894 case OCREP_PROP_BOOL:
895 if (err || !OCRepPayloadSetBoolArrayAsOwner(out, name, (bool*)arr, dimensions))
901 case OCREP_PROP_STRING:
902 if (err || !OCRepPayloadSetStringArrayAsOwner(out, name, (char**)arr, dimensions))
904 for(size_t i = 0; i < dimTotal; ++i)
906 OICFree(((char**)arr)[i]);
912 case OCREP_PROP_BYTE_STRING:
913 if (err || !OCRepPayloadSetByteStringArrayAsOwner(out, name, (OCByteString*)arr, dimensions))
915 for (size_t i = 0; i < dimTotal; ++i)
917 OICFree(((OCByteString*)arr)[i].bytes);
923 case OCREP_PROP_OBJECT:
924 if (err || !OCRepPayloadSetPropObjectArrayAsOwner(out, name, (OCRepPayload**)arr, dimensions))
926 for(size_t i = 0; i < dimTotal; ++i)
928 OCRepPayloadDestroy(((OCRepPayload**)arr)[i]);
935 OC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
943 static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue *objMap)
952 if (cbor_value_is_map(objMap))
956 *outPayload = OCRepPayloadCreate();
959 return CborErrorOutOfMemory;
963 OCRepPayload* curPayload = *outPayload;
967 err = err || cbor_value_enter_container(objMap, &repMap);
969 while(!err && cbor_value_is_valid(&repMap))
972 err = err || cbor_value_dup_text_string(&repMap, &name, &len, NULL);
973 err = err || cbor_value_advance(&repMap);
975 CborType type = cbor_value_get_type(&repMap);
979 err = !OCRepPayloadSetNull(curPayload, name);
981 case CborIntegerType:
984 err = err || cbor_value_get_int64(&repMap, &intval);
987 err = !OCRepPayloadSetPropInt(curPayload, name, intval);
993 double doubleval = 0;
994 err = err || cbor_value_get_double(&repMap, &doubleval);
997 err = !OCRepPayloadSetPropDouble(curPayload, name, doubleval);
1001 case CborBooleanType:
1003 bool boolval = false;
1004 err = err || cbor_value_get_boolean(&repMap, &boolval);
1007 err = !OCRepPayloadSetPropBool(curPayload, name, boolval);
1011 case CborTextStringType:
1013 char* strval = NULL;
1014 err = err || cbor_value_dup_text_string(&repMap, &strval, &len, NULL);
1017 err = !OCRepPayloadSetPropStringAsOwner(curPayload, name, strval);
1021 case CborByteStringType:
1023 uint8_t* bytestrval = NULL;
1024 err = err || cbor_value_dup_byte_string(&repMap, &bytestrval, &len, NULL);
1027 OCByteString tmp = {.bytes = bytestrval, .len = len};
1028 err = !OCRepPayloadSetPropByteStringAsOwner(curPayload, name, &tmp);
1034 OCRepPayload *pl = NULL;
1035 err = err || OCParseSingleRepPayload(&pl, &repMap);
1038 err = !OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl);
1043 err = err || OCParseArray(curPayload, name, &repMap);
1046 OC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type);
1050 if (type != CborMapType && cbor_value_is_valid(&repMap))
1052 err = err || cbor_value_advance(&repMap);
1057 err = err || cbor_value_leave_container(objMap, &repMap);
1061 OCRepPayloadDestroy(*outPayload);
1069 static OCStackResult OCParseRepPayload(OCPayload** outPayload, CborValue* rootMap)
1073 return OC_STACK_INVALID_PARAM;
1076 OCRepPayload *rootPayload = NULL;
1077 OCRepPayload *curPayload = NULL;
1078 OCRepPayload *temp = OCRepPayloadCreate();
1081 return OC_STACK_NO_MEMORY;
1087 err = err || cbor_value_map_find_value(rootMap, OC_RSRVD_RESOURCE_TYPE, &curVal);
1088 if(cbor_value_is_text_string(&curVal))
1091 err = err || cbor_value_dup_text_string(&curVal, &allRt, &len, NULL);
1095 char* curPtr = strtok_r(allRt, " ", &savePtr);
1098 char* trimmed = InPlaceStringTrim(curPtr);
1099 if (trimmed[0] != '\0')
1101 OCRepPayloadAddResourceType(temp, curPtr);
1103 curPtr = strtok_r(NULL, " ", &savePtr);
1109 err = err || cbor_value_map_find_value(rootMap, OC_RSRVD_INTERFACE, &curVal);
1110 if(cbor_value_is_text_string(&curVal))
1113 err = err || cbor_value_dup_text_string(&curVal, &allIf, &len, NULL);
1117 char* curPtr = strtok_r(allIf, " ", &savePtr);
1120 char* trimmed = InPlaceStringTrim(curPtr);
1121 if (trimmed[0] != '\0')
1123 OCRepPayloadAddInterface(temp, curPtr);
1125 curPtr = strtok_r(NULL, " ", &savePtr);
1131 while (!err && cbor_value_is_map(rootMap))
1133 err = err || OCParseSingleRepPayload(&temp, rootMap);
1135 if(rootPayload == NULL)
1142 curPayload->next = temp;
1143 curPayload = curPayload->next;
1146 if (cbor_value_is_valid(rootMap))
1148 err = err || cbor_value_advance(rootMap);
1153 OCRepPayloadDestroy(rootPayload);
1154 OC_LOG(ERROR, TAG, "CBOR error in ParseRepPayload");
1155 return OC_STACK_MALFORMED_RESPONSE;
1159 *outPayload = (OCPayload*)rootPayload;
1164 static OCStackResult OCParsePresencePayload(OCPayload** outPayload, CborValue* rootValue)
1168 return OC_STACK_INVALID_PARAM;
1172 if(cbor_value_is_map(rootValue))
1174 uint64_t seqNum = 0;
1175 uint64_t maxAge = 0;
1176 OCPresenceTrigger trigger = OC_PRESENCE_TRIGGER_CREATE;
1177 char* tempStr = NULL;
1182 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_NONCE, &curVal);
1183 err = err || cbor_value_get_uint64(&curVal, &seqNum);
1186 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_TTL, &curVal);
1187 err = err || cbor_value_get_uint64(&curVal, &maxAge);
1190 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_TRIGGER, &curVal);
1191 err = err || cbor_value_dup_text_string(&curVal, &tempStr, &len, NULL);
1192 trigger = convertTriggerStringToEnum(tempStr);
1196 // Resource type name
1197 err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &curVal);
1198 if(cbor_value_is_valid(&curVal))
1200 err = err || cbor_value_dup_text_string(&curVal, &tempStr, &len, NULL);
1203 err = err || cbor_value_advance(rootValue);
1207 *outPayload = (OCPayload*)OCPresencePayloadCreate(seqNum, maxAge, trigger, tempStr);
1213 OCPayloadDestroy(*outPayload);
1214 OC_LOG(ERROR, TAG, "CBOR error Parse Presence Payload");
1215 return OC_STACK_MALFORMED_RESPONSE;
1220 return OC_STACK_NO_MEMORY;
1227 OC_LOG(ERROR, TAG, "Root presence node was not a map");
1228 return OC_STACK_MALFORMED_RESPONSE;