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 #include "ocpayloadcbor.h"
24 #include "oic_malloc.h"
25 #include "ocstackinternal.h"
26 #include "ocpayload.h"
29 #define TAG "OCPayloadParse"
31 static OCStackResult OCParseDiscoveryPayload(OCPayload** outPayload, CborValue* arrayVal);
32 static OCStackResult OCParseDevicePayload(OCPayload** outPayload, CborValue* arrayVal);
33 static OCStackResult OCParsePlatformPayload(OCPayload** outPayload, CborValue* arrayVal);
34 static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue* repParent);
35 static OCStackResult OCParseRepPayload(OCPayload** outPayload, CborValue* arrayVal);
36 static OCStackResult OCParsePresencePayload(OCPayload** outPayload, CborValue* arrayVal);
37 static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* arrayVal);
39 OCStackResult OCParsePayload(OCPayload** outPayload, OCPayloadType payloadType,
40 const uint8_t* payload, size_t payloadSize)
46 OC_LOG_V(INFO, TAG, "CBOR Parsing size: %d", payloadSize, payload);
47 if((err = cbor_parser_init(payload, payloadSize, 0, &parser, &rootValue)) != false)
49 OC_LOG_V(ERROR, TAG, "CBOR Parser init failed: %d", err);
50 return OC_STACK_ERROR;
53 if(!cbor_value_is_array(&rootValue))
55 OC_LOG_V(ERROR, TAG, "CBOR payload root object is not an array :%x", rootValue.type);
56 return OC_STACK_MALFORMED_RESPONSE;
61 err = err || cbor_value_enter_container(&rootValue, &arrayValue);
63 if(err || arrayValue.type != CborMapType)
65 OC_LOG_V(ERROR, TAG, "CBOR payload parse failed :%d", err);
66 return OC_STACK_MALFORMED_RESPONSE;
69 OCStackResult result = OC_STACK_ERROR;
72 case PAYLOAD_TYPE_DISCOVERY:
73 result = OCParseDiscoveryPayload(outPayload, &arrayValue);
75 case PAYLOAD_TYPE_DEVICE:
76 result = OCParseDevicePayload(outPayload, &arrayValue);
78 case PAYLOAD_TYPE_PLATFORM:
79 result = OCParsePlatformPayload(outPayload, &arrayValue);
81 case PAYLOAD_TYPE_REPRESENTATION:
82 result = OCParseRepPayload(outPayload, &arrayValue);
84 case PAYLOAD_TYPE_PRESENCE:
85 result = OCParsePresencePayload(outPayload, &arrayValue);
87 case PAYLOAD_TYPE_SECURITY:
88 result = OCParseSecurityPayload(outPayload, &arrayValue);
91 OC_LOG_V(ERROR, TAG, "ParsePayload Type default: %d", payloadType);
92 result = OC_STACK_ERROR;
96 if(result == OC_STACK_OK)
98 err = err || cbor_value_leave_container(&rootValue, &arrayValue);
99 if(err != CborNoError)
101 return OC_STACK_MALFORMED_RESPONSE;
106 OC_LOG_V(INFO, TAG, "Finished parse payload, result is %d", result);
112 void OCFreeOCStringLL(OCStringLL* ll);
114 static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* arrayVal)
117 char * securityData = NULL;
119 if(cbor_value_is_map(arrayVal))
122 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
124 if(cbor_value_is_valid(&curVal))
127 err = err || cbor_value_dup_text_string(&curVal, &securityData, &len, NULL);
132 OC_LOG(ERROR, TAG, "Cbor main value not a map");
133 return OC_STACK_MALFORMED_RESPONSE;
136 err = err || cbor_value_advance(arrayVal);
140 OC_LOG(ERROR, TAG, "Cbor in error condition");
141 OICFree(securityData);
142 return OC_STACK_MALFORMED_RESPONSE;
145 *outPayload = (OCPayload*)OCSecurityPayloadCreate(securityData);
146 OICFree(securityData);
152 static OCStackResult OCParseDiscoveryPayload(OCPayload** outPayload, CborValue* arrayVal)
156 OCDiscoveryPayload* out = OCDiscoveryPayloadCreate();
160 return OC_STACK_NO_MEMORY;
163 size_t resourceCount = 0;
165 cbor_value_is_map(arrayVal))
167 OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
170 OC_LOG(ERROR, TAG, "Memory allocation failed");
171 OCDiscoveryPayloadDestroy(out);
172 return OC_STACK_NO_MEMORY;
177 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
179 err = err || cbor_value_dup_text_string(&curVal, &(resource->uri), &len, NULL);
182 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_SERVER_INSTANCE_ID, &curVal);
183 err = err || cbor_value_dup_byte_string(&curVal, &(resource->sid), &len, NULL);
187 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_PROPERTY, &curVal);
190 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_RESOURCE_TYPE, &rtArray);
193 err = err || cbor_value_enter_container(&rtArray, &rtVal);
195 OCStringLL* llPtr = NULL;
196 while(!err && cbor_value_is_text_string(&rtVal))
198 if(resource->types == NULL)
200 resource->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
201 llPtr = resource->types;
204 OC_LOG(ERROR, TAG, "Memory allocation failed");
205 OICFree(resource->uri);
206 OICFree(resource->sid);
208 OCDiscoveryPayloadDestroy(out);
209 return OC_STACK_NO_MEMORY;
214 llPtr->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
218 OC_LOG(ERROR, TAG, "Memory allocation failed");
219 OICFree(resource->uri);
220 OICFree(resource->sid);
221 OCFreeOCStringLL(resource->types);
223 OCDiscoveryPayloadDestroy(out);
224 return OC_STACK_NO_MEMORY;
229 OC_LOG(ERROR, TAG, "Unknown state in resource type copying");
230 OICFree(resource->uri);
231 OICFree(resource->sid);
232 OCFreeOCStringLL(resource->types);
234 OCDiscoveryPayloadDestroy(out);
235 return OC_STACK_NO_MEMORY;
238 err = err || cbor_value_dup_text_string(&rtVal, &(llPtr->value), &len, NULL);
239 err = err || cbor_value_advance(&rtVal);
242 err = err || cbor_value_leave_container(&rtArray, &rtVal);
246 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_INTERFACE, &ifArray);
248 err = err || cbor_value_enter_container(&ifArray, &ifVal);
251 while(!err && cbor_value_is_text_string(&ifVal))
253 if(resource->interfaces == NULL)
255 resource->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
256 llPtr = resource->interfaces;
259 OC_LOG(ERROR, TAG, "Memory allocation failed");
260 OICFree(resource->uri);
261 OICFree(resource->sid);
262 OCFreeOCStringLL(resource->types);
264 OCDiscoveryPayloadDestroy(out);
265 return OC_STACK_NO_MEMORY;
270 llPtr->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
274 OC_LOG(ERROR, TAG, "Memory allocation failed");
275 OICFree(resource->uri);
276 OICFree(resource->sid);
277 OCFreeOCStringLL(resource->types);
278 OCFreeOCStringLL(resource->interfaces);
280 OCDiscoveryPayloadDestroy(out);
281 return OC_STACK_NO_MEMORY;
286 OC_LOG(ERROR, TAG, "Unknown state in resource interfaces copying");
287 OICFree(resource->uri);
288 OICFree(resource->sid);
289 OCFreeOCStringLL(resource->types);
291 OCDiscoveryPayloadDestroy(out);
292 return OC_STACK_NO_MEMORY;
295 err = err || cbor_value_dup_text_string(&ifVal, &(llPtr->value), &len, NULL);
296 err = err || cbor_value_advance(&ifVal);
298 err = err || cbor_value_leave_container(&ifArray, &ifVal);
303 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_POLICY, &policyMap);
307 err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &val);
309 err = err || cbor_value_get_uint64(&val, &temp);
310 resource->bitmap = (uint8_t)temp;
312 err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &val);
313 if(cbor_value_is_valid(&val))
315 err = err || cbor_value_get_boolean(&val, &(resource->secure));
318 err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT,
320 if(cbor_value_is_valid(&port))
322 err = err || cbor_value_get_uint64(&port, &temp);
323 resource->port = (uint16_t)temp;
329 err = err || cbor_value_advance(arrayVal);
332 OICFree(resource->uri);
333 OICFree(resource->sid);
334 OCFreeOCStringLL(resource->types);
335 OCFreeOCStringLL(resource->interfaces);
337 OCDiscoveryPayloadDestroy(out);
338 OC_LOG_V(ERROR, TAG, "CBOR in error condition", err);
339 return OC_STACK_MALFORMED_RESPONSE;
342 OCDiscoveryPayloadAddNewResource(out, resource);
347 OCDiscoveryPayloadDestroy(out);
348 return OC_STACK_MALFORMED_RESPONSE;
352 *outPayload = (OCPayload*)out;
357 static OCStackResult OCParseDevicePayload(OCPayload** outPayload, CborValue* arrayVal)
361 if(cbor_value_is_map(arrayVal))
366 char* specVer = NULL;
369 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
371 err = err || cbor_value_dup_text_string(&curVal, &uri, &len, NULL);
375 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
379 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DEVICE_ID, &repVal);
380 err = err || cbor_value_dup_byte_string(&repVal, &sid, &len, NULL);
382 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DEVICE_NAME, &repVal);
383 err = err || cbor_value_dup_text_string(&repVal, &dname, &len, NULL);
384 // Device Spec Version
385 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SPEC_VERSION, &repVal);
386 err = err || cbor_value_dup_text_string(&repVal, &specVer, &len, NULL);
387 // Data Model Version
388 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DATA_MODEL_VERSION, &repVal);
389 err = err || cbor_value_dup_text_string(&repVal, &dmVer, &len, NULL);
393 err = err || cbor_value_advance(arrayVal);
402 OC_LOG_V(ERROR, TAG, "CBOR in error condition %d", err);
403 return OC_STACK_MALFORMED_RESPONSE;
406 *outPayload = (OCPayload*)OCDevicePayloadCreate(uri, sid, dname, specVer, dmVer);
415 return OC_STACK_NO_MEMORY;
422 OC_LOG(ERROR, TAG, "Root device node was not a map");
423 return OC_STACK_MALFORMED_RESPONSE;
428 static OCStackResult OCParsePlatformPayload(OCPayload** outPayload, CborValue* arrayVal)
432 if(cbor_value_is_map(arrayVal))
435 OCPlatformInfo info = {0};
437 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
439 err = err || cbor_value_dup_text_string(&curVal, &uri, &len, NULL);
443 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
447 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_PLATFORM_ID, &repVal);
448 err = err || cbor_value_dup_text_string(&repVal, &(info.platformID), &len, NULL);
451 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_NAME, &repVal);
452 err = err || cbor_value_dup_text_string(&repVal, &(info.manufacturerName), &len, NULL);
455 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_URL, &repVal);
456 if(cbor_value_is_valid(&repVal))
458 err = err || cbor_value_dup_text_string(&repVal, &(info.manufacturerUrl), &len, NULL);
462 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MODEL_NUM, &repVal);
463 if(cbor_value_is_valid(&repVal))
465 err = err || cbor_value_dup_text_string(&repVal, &(info.modelNumber), &len, NULL);
469 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_DATE, &repVal);
470 if(cbor_value_is_valid(&repVal))
472 err = err || cbor_value_dup_text_string(&repVal, &(info.dateOfManufacture), &len,
477 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_PLATFORM_VERSION, &repVal);
478 if(cbor_value_is_valid(&repVal))
480 err = err || cbor_value_dup_text_string(&repVal, &(info.platformVersion), &len,
485 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_OS_VERSION, &repVal);
486 if(cbor_value_is_valid(&repVal))
488 err = err || cbor_value_dup_text_string(&repVal, &(info.operatingSystemVersion),
493 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_HARDWARE_VERSION, &repVal);
494 if(cbor_value_is_valid(&repVal))
496 err = err || cbor_value_dup_text_string(&repVal, &(info.hardwareVersion), &len,
501 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_FIRMWARE_VERSION, &repVal);
502 if(cbor_value_is_valid(&repVal))
504 err = err || cbor_value_dup_text_string(&repVal, &(info.firmwareVersion), &len,
509 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SUPPORT_URL, &repVal);
510 if(cbor_value_is_valid(&repVal))
512 err = err || cbor_value_dup_text_string(&repVal, &(info.supportUrl), &len, NULL);
516 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SYSTEM_TIME, &repVal);
517 if(cbor_value_is_valid(&repVal))
519 err = err || cbor_value_dup_text_string(&repVal, &(info.systemTime), &len, NULL);
523 err = err || cbor_value_advance(arrayVal);
527 OICFree(info.dateOfManufacture);
528 OICFree(info.firmwareVersion);
529 OICFree(info.hardwareVersion);
530 OICFree(info.manufacturerName);
531 OICFree(info.manufacturerUrl);
532 OICFree(info.modelNumber);
533 OICFree(info.operatingSystemVersion);
534 OICFree(info.platformID);
535 OICFree(info.platformVersion);
536 OICFree(info.supportUrl);
537 OICFree(info.systemTime);
538 OC_LOG(ERROR, TAG, "CBOR error In ParsePlatformPayload");
539 return OC_STACK_MALFORMED_RESPONSE;
542 *outPayload = (OCPayload*)OCPlatformPayloadCreateAsOwner(uri, &info);
546 return OC_STACK_NO_MEMORY;
553 OC_LOG(ERROR, TAG, "Root device node was not a map");
554 return OC_STACK_MALFORMED_RESPONSE;
558 static OCRepPayloadPropType DecodeCborType(CborType type)
563 return OCREP_PROP_NULL;
564 case CborIntegerType:
565 return OCREP_PROP_INT;
567 return OCREP_PROP_DOUBLE;
568 case CborBooleanType:
569 return OCREP_PROP_BOOL;
570 case CborTextStringType:
571 return OCREP_PROP_STRING;
573 return OCREP_PROP_OBJECT;
575 return OCREP_PROP_ARRAY;
577 return OCREP_PROP_NULL;
580 static bool OCParseArrayFindDimensionsAndType(const CborValue* parent, size_t dimensions[MAX_REP_ARRAY_DEPTH],
581 OCRepPayloadPropType* type)
584 CborValue insideArray;
585 *type = OCREP_PROP_NULL;
586 dimensions[0] = dimensions[1] = dimensions[2] = 0;
588 err = err || cbor_value_enter_container(parent, &insideArray);
590 while (cbor_value_is_valid(&insideArray))
592 OCRepPayloadPropType tempType = DecodeCborType(cbor_value_get_type(&insideArray));
594 if (tempType == OCREP_PROP_ARRAY)
596 size_t subdim[MAX_REP_ARRAY_DEPTH];
597 tempType = OCREP_PROP_NULL;
598 err = err || OCParseArrayFindDimensionsAndType(&insideArray, subdim, &tempType);
602 OC_LOG(ERROR, TAG, "Parse array helper, sub-array too deep");
605 dimensions[1] = dimensions[1] >= subdim[0] ? dimensions[1] : subdim[0];
606 dimensions[2] = dimensions[2] >= subdim[1] ? dimensions[2] : subdim[1];
608 if (*type != OCREP_PROP_NULL && tempType != OCREP_PROP_NULL
609 && *type != tempType)
611 OC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed (subtype)");
614 else if (*type == OCREP_PROP_NULL)
616 // We don't know the type of this array yet, so the assignment is OK
620 else if (*type == OCREP_PROP_NULL)
622 // We don't know the type of this array yet, so the assignment is OK
625 // tempType is allowed to be NULL, since it might now know the answer yet
626 else if (tempType != OCREP_PROP_NULL && *type != tempType)
628 // this is an invalid situation!
629 OC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed");
634 cbor_value_advance(&insideArray);
640 static size_t getAllocSize(OCRepPayloadPropType type)
645 return sizeof (int64_t);
646 case OCREP_PROP_DOUBLE:
647 return sizeof (double);
648 case OCREP_PROP_BOOL:
649 return sizeof (bool);
650 case OCREP_PROP_STRING:
651 return sizeof (char*);
652 case OCREP_PROP_OBJECT:
653 return sizeof (OCRepPayload*);
659 static size_t arrayStep(size_t dimensions[MAX_REP_ARRAY_DEPTH], size_t elementNum)
662 (dimensions[1] == 0 ? 1 : dimensions[1]) *
663 (dimensions[2] == 0 ? 1 : dimensions[2]) *
667 static bool OCParseArrayFillArray(const CborValue* parent, size_t dimensions[MAX_REP_ARRAY_DEPTH],
668 OCRepPayloadPropType type, void* targetArray)
671 CborValue insideArray;
673 err = err || cbor_value_enter_container(parent, &insideArray);
676 char* tempStr = NULL;
678 OCRepPayload* tempPl = NULL;
680 size_t newdim[MAX_REP_ARRAY_DEPTH];
681 newdim[0] = dimensions[1];
682 newdim[1] = dimensions[2];
685 while (!err && i < dimensions[0] && cbor_value_is_valid(&insideArray))
687 if (cbor_value_get_type(&insideArray) != CborNullType)
692 if (dimensions[1] == 0)
694 err = err || cbor_value_get_int64(&insideArray,
695 &(((int64_t*)targetArray)[i]));
699 err = err || OCParseArrayFillArray(&insideArray, newdim,
701 &(((int64_t*)targetArray)[arrayStep(dimensions, i)])
705 case OCREP_PROP_DOUBLE:
706 if (dimensions[1] == 0)
708 err = err || cbor_value_get_double(&insideArray,
709 &(((double*)targetArray)[i]));
713 err = err || OCParseArrayFillArray(&insideArray, newdim,
715 &(((double*)targetArray)[arrayStep(dimensions, i)])
719 case OCREP_PROP_BOOL:
720 if (dimensions[1] == 0)
722 err = err || cbor_value_get_boolean(&insideArray,
723 &(((bool*)targetArray)[i]));
727 err = err || OCParseArrayFillArray(&insideArray, newdim,
729 &(((bool*)targetArray)[arrayStep(dimensions, i)])
733 case OCREP_PROP_STRING:
734 if (dimensions[1] == 0)
736 err = err || cbor_value_dup_text_string(&insideArray,
737 &tempStr, &tempLen, NULL);
738 ((char**)targetArray)[i] = tempStr;
743 err = err || OCParseArrayFillArray(&insideArray, newdim,
745 &(((char**)targetArray)[arrayStep(dimensions, i)])
749 case OCREP_PROP_OBJECT:
750 if (dimensions[1] == 0)
752 err = err || OCParseSingleRepPayload(&tempPl, &insideArray);
753 ((OCRepPayload**)targetArray)[i] = tempPl;
758 err = err || OCParseArrayFillArray(&insideArray, newdim,
760 &(((OCRepPayload**)targetArray)[arrayStep(dimensions, i)])
765 OC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
771 err = err || cbor_value_advance(&insideArray);
777 static bool OCParseArray(OCRepPayload* out, const char* name, CborValue* container)
779 OCRepPayloadPropType type;
780 size_t dimensions[MAX_REP_ARRAY_DEPTH];
781 bool err = OCParseArrayFindDimensionsAndType(container, dimensions, &type);
785 OC_LOG(ERROR, TAG, "Array details weren't clear");
789 if (type == OCREP_PROP_NULL)
791 err = err || OCRepPayloadSetNull(out, name);
792 err = err || cbor_value_advance(container);
796 size_t dimTotal = calcDimTotal(dimensions);
797 size_t allocSize = getAllocSize(type);
798 void* arr = OICCalloc(dimTotal, allocSize);
802 OC_LOG(ERROR, TAG, "Array Parse allocation failed");
806 err = err || OCParseArrayFillArray(container, dimensions, type, arr);
811 if (err || !OCRepPayloadSetIntArrayAsOwner(out, name, (int64_t*)arr, dimensions))
817 case OCREP_PROP_DOUBLE:
818 if (err || !OCRepPayloadSetDoubleArrayAsOwner(out, name, (double*)arr, dimensions))
824 case OCREP_PROP_BOOL:
825 if (err || !OCRepPayloadSetBoolArrayAsOwner(out, name, (bool*)arr, dimensions))
831 case OCREP_PROP_STRING:
832 if (err || !OCRepPayloadSetStringArrayAsOwner(out, name, (char**)arr, dimensions))
834 for(size_t i = 0; i < dimTotal; ++i)
836 OICFree(((char**)arr)[i]);
842 case OCREP_PROP_OBJECT:
843 if (err || !OCRepPayloadSetPropObjectArrayAsOwner(out, name, (OCRepPayload**)arr, dimensions))
845 for(size_t i = 0; i < dimTotal; ++i)
847 OCRepPayloadDestroy(((OCRepPayload**)arr)[i]);
854 OC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
862 static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue* repParent)
864 *outPayload = OCRepPayloadCreate();
865 OCRepPayload* curPayload = *outPayload;
869 return CborErrorOutOfMemory;
874 err = err || cbor_value_map_find_value(repParent, OC_RSRVD_HREF, &curVal);
875 if(cbor_value_is_valid(&curVal))
877 err = err || cbor_value_dup_text_string(&curVal, &curPayload->uri, &len,
881 err = err || cbor_value_map_find_value(repParent, OC_RSRVD_PROPERTY, &curVal);
882 if(cbor_value_is_valid(&curVal))
884 CborValue insidePropArray = {0};
885 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_RESOURCE_TYPE,
888 if(cbor_value_is_array(&insidePropArray))
891 err = err || cbor_value_enter_container(&insidePropArray, &rtArray);
893 while(!err && cbor_value_is_valid(&rtArray))
896 err = err || cbor_value_dup_text_string(&rtArray, &curRt, &len, NULL);
897 err = err || cbor_value_advance(&rtArray);
898 OCRepPayloadAddResourceTypeAsOwner(curPayload, curRt);
901 err = err || cbor_value_leave_container(&insidePropArray, &rtArray);
904 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_INTERFACE, &insidePropArray);
906 if(cbor_value_is_array(&insidePropArray))
909 err = err || cbor_value_enter_container(&insidePropArray, &ifArray);
911 while(!err && cbor_value_is_valid(&ifArray))
914 err = err || cbor_value_dup_text_string(&ifArray, &curIf, &len, NULL);
915 err = err || cbor_value_advance(&ifArray);
916 OCRepPayloadAddInterfaceAsOwner(curPayload, curIf);
919 err = err || cbor_value_leave_container(&insidePropArray, &ifArray);
923 err = err || cbor_value_map_find_value(repParent, OC_RSRVD_REPRESENTATION, &curVal);
924 if(cbor_value_is_map(&curVal))
927 err = err || cbor_value_enter_container(&curVal, &repMap);
929 while(!err && cbor_value_is_valid(&repMap))
932 err = err || cbor_value_dup_text_string(&repMap, &name, &len, NULL);
934 err = err || cbor_value_advance(&repMap);
937 bool boolval = false;
939 double doubleval = 0;
942 switch(cbor_value_get_type(&repMap))
945 err = !OCRepPayloadSetNull(curPayload, name);
947 case CborIntegerType:
948 err = err || cbor_value_get_int64(&repMap, &intval);
951 err = !OCRepPayloadSetPropInt(curPayload, name, intval);
955 err = err || cbor_value_get_double(&repMap, &doubleval);
958 err = !OCRepPayloadSetPropDouble(curPayload, name, doubleval);
961 case CborBooleanType:
962 err = err || cbor_value_get_boolean(&repMap, &boolval);
965 err = !OCRepPayloadSetPropBool(curPayload, name, boolval);
968 case CborTextStringType:
969 err = err || cbor_value_dup_text_string(&repMap, &strval, &len, NULL);
972 err = !OCRepPayloadSetPropStringAsOwner(curPayload, name, strval);
976 err = err || OCParseSingleRepPayload(&pl, &repMap);
979 err = !OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl);
983 err = err || OCParseArray(curPayload, name, &repMap);
986 OC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type);
990 err = err || cbor_value_advance(&repMap);
993 err = err || cbor_value_leave_container(&curVal, &repMap);
998 OCRepPayloadDestroy(*outPayload);
1004 static OCStackResult OCParseRepPayload(OCPayload** outPayload, CborValue* arrayVal)
1008 OCRepPayload* rootPayload = NULL;
1009 OCRepPayload* curPayload = NULL;
1010 OCRepPayload* temp = NULL;
1011 while(!err && cbor_value_is_map(arrayVal))
1013 err = err || OCParseSingleRepPayload(&temp, arrayVal);
1015 if(rootPayload == NULL)
1022 curPayload->next = temp;
1023 curPayload = curPayload->next;
1027 err = err || cbor_value_advance(arrayVal);
1030 OCRepPayloadDestroy(rootPayload);
1031 OC_LOG(ERROR, TAG, "CBOR error in ParseRepPayload");
1032 return OC_STACK_MALFORMED_RESPONSE;
1036 *outPayload = (OCPayload*)rootPayload;
1041 static OCStackResult OCParsePresencePayload(OCPayload** outPayload, CborValue* arrayVal)
1044 if(cbor_value_is_map(arrayVal))
1046 uint64_t seqNum = 0;
1047 uint64_t maxAge = 0;
1048 OCPresenceTrigger trigger = OC_PRESENCE_TRIGGER_CREATE;
1049 char* tempStr = NULL;
1054 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_NONCE, &curVal);
1055 err = err || cbor_value_get_uint64(&curVal, &seqNum);
1058 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_TTL, &curVal);
1059 err = err || cbor_value_get_uint64(&curVal, &maxAge);
1062 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_TRIGGER, &curVal);
1063 err = err || cbor_value_dup_text_string(&curVal, &tempStr, &len, NULL);
1064 trigger = convertTriggerStringToEnum(tempStr);
1068 // Resource type name
1069 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_RESOURCE_TYPE, &curVal);
1070 if(cbor_value_is_valid(&curVal))
1072 err = err || cbor_value_dup_text_string(&curVal, &tempStr, &len, NULL);
1075 err = err || cbor_value_advance(arrayVal);
1079 *outPayload = (OCPayload*)OCPresencePayloadCreate(seqNum, maxAge, trigger, tempStr);
1085 OCPayloadDestroy(*outPayload);
1086 OC_LOG(ERROR, TAG, "CBOR error Parse Presence Payload");
1087 return OC_STACK_MALFORMED_RESPONSE;
1092 return OC_STACK_NO_MEMORY;
1099 OC_LOG(ERROR, TAG, "Root presence node was not a map");
1100 return OC_STACK_MALFORMED_RESPONSE;