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)
118 return OC_STACK_INVALID_PARAM;
122 char * securityData = NULL;
124 if(cbor_value_is_map(arrayVal))
127 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
129 if(cbor_value_is_valid(&curVal))
132 err = err || cbor_value_dup_text_string(&curVal, &securityData, &len, NULL);
137 OC_LOG(ERROR, TAG, "Cbor main value not a map");
138 return OC_STACK_MALFORMED_RESPONSE;
141 err = err || cbor_value_advance(arrayVal);
145 OC_LOG(ERROR, TAG, "Cbor in error condition");
146 OICFree(securityData);
147 return OC_STACK_MALFORMED_RESPONSE;
150 *outPayload = (OCPayload*)OCSecurityPayloadCreate(securityData);
151 OICFree(securityData);
157 static OCStackResult OCParseDiscoveryPayload(OCPayload** outPayload, CborValue* arrayVal)
161 return OC_STACK_INVALID_PARAM;
166 OCDiscoveryPayload* out = OCDiscoveryPayloadCreate();
170 return OC_STACK_NO_MEMORY;
173 size_t resourceCount = 0;
175 cbor_value_is_map(arrayVal))
177 OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
180 OC_LOG(ERROR, TAG, "Memory allocation failed");
181 OCDiscoveryPayloadDestroy(out);
182 return OC_STACK_NO_MEMORY;
187 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
189 err = err || cbor_value_dup_text_string(&curVal, &(resource->uri), &len, NULL);
192 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_SERVER_INSTANCE_ID, &curVal);
193 err = err || cbor_value_dup_byte_string(&curVal, &(resource->sid), &len, NULL);
197 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_PROPERTY, &curVal);
200 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_RESOURCE_TYPE, &rtArray);
203 err = err || cbor_value_enter_container(&rtArray, &rtVal);
205 OCStringLL* llPtr = NULL;
206 while(!err && cbor_value_is_text_string(&rtVal))
208 if(resource->types == NULL)
210 resource->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
211 llPtr = resource->types;
214 OC_LOG(ERROR, TAG, "Memory allocation failed");
215 OICFree(resource->uri);
216 OICFree(resource->sid);
218 OCDiscoveryPayloadDestroy(out);
219 return OC_STACK_NO_MEMORY;
224 llPtr->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
228 OC_LOG(ERROR, TAG, "Memory allocation failed");
229 OICFree(resource->uri);
230 OICFree(resource->sid);
231 OCFreeOCStringLL(resource->types);
233 OCDiscoveryPayloadDestroy(out);
234 return OC_STACK_NO_MEMORY;
239 OC_LOG(ERROR, TAG, "Unknown state in resource type copying");
240 OICFree(resource->uri);
241 OICFree(resource->sid);
242 OCFreeOCStringLL(resource->types);
244 OCDiscoveryPayloadDestroy(out);
245 return OC_STACK_NO_MEMORY;
248 err = err || cbor_value_dup_text_string(&rtVal, &(llPtr->value), &len, NULL);
249 err = err || cbor_value_advance(&rtVal);
252 err = err || cbor_value_leave_container(&rtArray, &rtVal);
256 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_INTERFACE, &ifArray);
258 err = err || cbor_value_enter_container(&ifArray, &ifVal);
261 while(!err && cbor_value_is_text_string(&ifVal))
263 if(resource->interfaces == NULL)
265 resource->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
266 llPtr = resource->interfaces;
269 OC_LOG(ERROR, TAG, "Memory allocation failed");
270 OICFree(resource->uri);
271 OICFree(resource->sid);
272 OCFreeOCStringLL(resource->types);
274 OCDiscoveryPayloadDestroy(out);
275 return OC_STACK_NO_MEMORY;
280 llPtr->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
284 OC_LOG(ERROR, TAG, "Memory allocation failed");
285 OICFree(resource->uri);
286 OICFree(resource->sid);
287 OCFreeOCStringLL(resource->types);
288 OCFreeOCStringLL(resource->interfaces);
290 OCDiscoveryPayloadDestroy(out);
291 return OC_STACK_NO_MEMORY;
296 OC_LOG(ERROR, TAG, "Unknown state in resource interfaces copying");
297 OICFree(resource->uri);
298 OICFree(resource->sid);
299 OCFreeOCStringLL(resource->types);
301 OCDiscoveryPayloadDestroy(out);
302 return OC_STACK_NO_MEMORY;
305 err = err || cbor_value_dup_text_string(&ifVal, &(llPtr->value), &len, NULL);
306 err = err || cbor_value_advance(&ifVal);
308 err = err || cbor_value_leave_container(&ifArray, &ifVal);
313 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_POLICY, &policyMap);
317 err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &val);
319 err = err || cbor_value_get_uint64(&val, &temp);
320 resource->bitmap = (uint8_t)temp;
322 err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &val);
323 if(cbor_value_is_valid(&val))
325 err = err || cbor_value_get_boolean(&val, &(resource->secure));
328 err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT,
330 if(cbor_value_is_valid(&port))
332 err = err || cbor_value_get_uint64(&port, &temp);
333 resource->port = (uint16_t)temp;
339 err = err || cbor_value_advance(arrayVal);
342 OICFree(resource->uri);
343 OICFree(resource->sid);
344 OCFreeOCStringLL(resource->types);
345 OCFreeOCStringLL(resource->interfaces);
347 OCDiscoveryPayloadDestroy(out);
348 OC_LOG_V(ERROR, TAG, "CBOR in error condition", err);
349 return OC_STACK_MALFORMED_RESPONSE;
352 OCDiscoveryPayloadAddNewResource(out, resource);
357 OCDiscoveryPayloadDestroy(out);
358 return OC_STACK_MALFORMED_RESPONSE;
362 *outPayload = (OCPayload*)out;
367 static OCStackResult OCParseDevicePayload(OCPayload** outPayload, CborValue* arrayVal)
371 return OC_STACK_INVALID_PARAM;
376 if(cbor_value_is_map(arrayVal))
381 char* specVer = NULL;
384 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
386 err = err || cbor_value_dup_text_string(&curVal, &uri, &len, NULL);
390 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
394 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DEVICE_ID, &repVal);
395 err = err || cbor_value_dup_byte_string(&repVal, &sid, &len, NULL);
397 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DEVICE_NAME, &repVal);
398 err = err || cbor_value_dup_text_string(&repVal, &dname, &len, NULL);
399 // Device Spec Version
400 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SPEC_VERSION, &repVal);
401 err = err || cbor_value_dup_text_string(&repVal, &specVer, &len, NULL);
402 // Data Model Version
403 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DATA_MODEL_VERSION, &repVal);
404 err = err || cbor_value_dup_text_string(&repVal, &dmVer, &len, NULL);
408 err = err || cbor_value_advance(arrayVal);
417 OC_LOG_V(ERROR, TAG, "CBOR in error condition %d", err);
418 return OC_STACK_MALFORMED_RESPONSE;
421 *outPayload = (OCPayload*)OCDevicePayloadCreate(uri, sid, dname, specVer, dmVer);
430 return OC_STACK_NO_MEMORY;
437 OC_LOG(ERROR, TAG, "Root device node was not a map");
438 return OC_STACK_MALFORMED_RESPONSE;
443 static OCStackResult OCParsePlatformPayload(OCPayload** outPayload, CborValue* arrayVal)
447 return OC_STACK_INVALID_PARAM;
452 if(cbor_value_is_map(arrayVal))
455 OCPlatformInfo info = {0};
457 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
459 err = err || cbor_value_dup_text_string(&curVal, &uri, &len, NULL);
463 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
467 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_PLATFORM_ID, &repVal);
468 err = err || cbor_value_dup_text_string(&repVal, &(info.platformID), &len, NULL);
471 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_NAME, &repVal);
472 err = err || cbor_value_dup_text_string(&repVal, &(info.manufacturerName), &len, NULL);
475 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_URL, &repVal);
476 if(cbor_value_is_valid(&repVal))
478 err = err || cbor_value_dup_text_string(&repVal, &(info.manufacturerUrl), &len, NULL);
482 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MODEL_NUM, &repVal);
483 if(cbor_value_is_valid(&repVal))
485 err = err || cbor_value_dup_text_string(&repVal, &(info.modelNumber), &len, NULL);
489 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_DATE, &repVal);
490 if(cbor_value_is_valid(&repVal))
492 err = err || cbor_value_dup_text_string(&repVal, &(info.dateOfManufacture), &len,
497 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_PLATFORM_VERSION, &repVal);
498 if(cbor_value_is_valid(&repVal))
500 err = err || cbor_value_dup_text_string(&repVal, &(info.platformVersion), &len,
505 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_OS_VERSION, &repVal);
506 if(cbor_value_is_valid(&repVal))
508 err = err || cbor_value_dup_text_string(&repVal, &(info.operatingSystemVersion),
513 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_HARDWARE_VERSION, &repVal);
514 if(cbor_value_is_valid(&repVal))
516 err = err || cbor_value_dup_text_string(&repVal, &(info.hardwareVersion), &len,
521 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_FIRMWARE_VERSION, &repVal);
522 if(cbor_value_is_valid(&repVal))
524 err = err || cbor_value_dup_text_string(&repVal, &(info.firmwareVersion), &len,
529 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SUPPORT_URL, &repVal);
530 if(cbor_value_is_valid(&repVal))
532 err = err || cbor_value_dup_text_string(&repVal, &(info.supportUrl), &len, NULL);
536 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SYSTEM_TIME, &repVal);
537 if(cbor_value_is_valid(&repVal))
539 err = err || cbor_value_dup_text_string(&repVal, &(info.systemTime), &len, NULL);
543 err = err || cbor_value_advance(arrayVal);
547 OICFree(info.dateOfManufacture);
548 OICFree(info.firmwareVersion);
549 OICFree(info.hardwareVersion);
550 OICFree(info.manufacturerName);
551 OICFree(info.manufacturerUrl);
552 OICFree(info.modelNumber);
553 OICFree(info.operatingSystemVersion);
554 OICFree(info.platformID);
555 OICFree(info.platformVersion);
556 OICFree(info.supportUrl);
557 OICFree(info.systemTime);
558 OC_LOG(ERROR, TAG, "CBOR error In ParsePlatformPayload");
559 return OC_STACK_MALFORMED_RESPONSE;
562 *outPayload = (OCPayload*)OCPlatformPayloadCreateAsOwner(uri, &info);
566 return OC_STACK_NO_MEMORY;
573 OC_LOG(ERROR, TAG, "Root device node was not a map");
574 return OC_STACK_MALFORMED_RESPONSE;
578 static OCRepPayloadPropType DecodeCborType(CborType type)
583 return OCREP_PROP_NULL;
584 case CborIntegerType:
585 return OCREP_PROP_INT;
587 return OCREP_PROP_DOUBLE;
588 case CborBooleanType:
589 return OCREP_PROP_BOOL;
590 case CborTextStringType:
591 return OCREP_PROP_STRING;
593 return OCREP_PROP_OBJECT;
595 return OCREP_PROP_ARRAY;
597 return OCREP_PROP_NULL;
600 static bool OCParseArrayFindDimensionsAndType(const CborValue* parent, size_t dimensions[MAX_REP_ARRAY_DEPTH],
601 OCRepPayloadPropType* type)
604 CborValue insideArray;
605 *type = OCREP_PROP_NULL;
606 dimensions[0] = dimensions[1] = dimensions[2] = 0;
608 err = err || cbor_value_enter_container(parent, &insideArray);
610 while (cbor_value_is_valid(&insideArray))
612 OCRepPayloadPropType tempType = DecodeCborType(cbor_value_get_type(&insideArray));
614 if (tempType == OCREP_PROP_ARRAY)
616 size_t subdim[MAX_REP_ARRAY_DEPTH];
617 tempType = OCREP_PROP_NULL;
618 err = err || OCParseArrayFindDimensionsAndType(&insideArray, subdim, &tempType);
622 OC_LOG(ERROR, TAG, "Parse array helper, sub-array too deep");
625 dimensions[1] = dimensions[1] >= subdim[0] ? dimensions[1] : subdim[0];
626 dimensions[2] = dimensions[2] >= subdim[1] ? dimensions[2] : subdim[1];
628 if (*type != OCREP_PROP_NULL && tempType != OCREP_PROP_NULL
629 && *type != tempType)
631 OC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed (subtype)");
634 else if (*type == OCREP_PROP_NULL)
636 // We don't know the type of this array yet, so the assignment is OK
640 else if (*type == OCREP_PROP_NULL)
642 // We don't know the type of this array yet, so the assignment is OK
645 // tempType is allowed to be NULL, since it might now know the answer yet
646 else if (tempType != OCREP_PROP_NULL && *type != tempType)
648 // this is an invalid situation!
649 OC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed");
654 cbor_value_advance(&insideArray);
660 static size_t getAllocSize(OCRepPayloadPropType type)
665 return sizeof (int64_t);
666 case OCREP_PROP_DOUBLE:
667 return sizeof (double);
668 case OCREP_PROP_BOOL:
669 return sizeof (bool);
670 case OCREP_PROP_STRING:
671 return sizeof (char*);
672 case OCREP_PROP_OBJECT:
673 return sizeof (OCRepPayload*);
679 static size_t arrayStep(size_t dimensions[MAX_REP_ARRAY_DEPTH], size_t elementNum)
682 (dimensions[1] == 0 ? 1 : dimensions[1]) *
683 (dimensions[2] == 0 ? 1 : dimensions[2]) *
687 static bool OCParseArrayFillArray(const CborValue* parent, size_t dimensions[MAX_REP_ARRAY_DEPTH],
688 OCRepPayloadPropType type, void* targetArray)
691 CborValue insideArray;
693 err = err || cbor_value_enter_container(parent, &insideArray);
696 char* tempStr = NULL;
698 OCRepPayload* tempPl = NULL;
700 size_t newdim[MAX_REP_ARRAY_DEPTH];
701 newdim[0] = dimensions[1];
702 newdim[1] = dimensions[2];
705 while (!err && i < dimensions[0] && cbor_value_is_valid(&insideArray))
707 if (cbor_value_get_type(&insideArray) != CborNullType)
712 if (dimensions[1] == 0)
714 err = err || cbor_value_get_int64(&insideArray,
715 &(((int64_t*)targetArray)[i]));
719 err = err || OCParseArrayFillArray(&insideArray, newdim,
721 &(((int64_t*)targetArray)[arrayStep(dimensions, i)])
725 case OCREP_PROP_DOUBLE:
726 if (dimensions[1] == 0)
728 err = err || cbor_value_get_double(&insideArray,
729 &(((double*)targetArray)[i]));
733 err = err || OCParseArrayFillArray(&insideArray, newdim,
735 &(((double*)targetArray)[arrayStep(dimensions, i)])
739 case OCREP_PROP_BOOL:
740 if (dimensions[1] == 0)
742 err = err || cbor_value_get_boolean(&insideArray,
743 &(((bool*)targetArray)[i]));
747 err = err || OCParseArrayFillArray(&insideArray, newdim,
749 &(((bool*)targetArray)[arrayStep(dimensions, i)])
753 case OCREP_PROP_STRING:
754 if (dimensions[1] == 0)
756 err = err || cbor_value_dup_text_string(&insideArray,
757 &tempStr, &tempLen, NULL);
758 ((char**)targetArray)[i] = tempStr;
763 err = err || OCParseArrayFillArray(&insideArray, newdim,
765 &(((char**)targetArray)[arrayStep(dimensions, i)])
769 case OCREP_PROP_OBJECT:
770 if (dimensions[1] == 0)
772 err = err || OCParseSingleRepPayload(&tempPl, &insideArray);
773 ((OCRepPayload**)targetArray)[i] = tempPl;
778 err = err || OCParseArrayFillArray(&insideArray, newdim,
780 &(((OCRepPayload**)targetArray)[arrayStep(dimensions, i)])
785 OC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
791 err = err || cbor_value_advance(&insideArray);
797 static bool OCParseArray(OCRepPayload* out, const char* name, CborValue* container)
799 OCRepPayloadPropType type;
800 size_t dimensions[MAX_REP_ARRAY_DEPTH];
801 bool err = OCParseArrayFindDimensionsAndType(container, dimensions, &type);
805 OC_LOG(ERROR, TAG, "Array details weren't clear");
809 if (type == OCREP_PROP_NULL)
811 err = err || OCRepPayloadSetNull(out, name);
812 err = err || cbor_value_advance(container);
816 size_t dimTotal = calcDimTotal(dimensions);
817 size_t allocSize = getAllocSize(type);
818 void* arr = OICCalloc(dimTotal, allocSize);
822 OC_LOG(ERROR, TAG, "Array Parse allocation failed");
826 err = err || OCParseArrayFillArray(container, dimensions, type, arr);
831 if (err || !OCRepPayloadSetIntArrayAsOwner(out, name, (int64_t*)arr, dimensions))
837 case OCREP_PROP_DOUBLE:
838 if (err || !OCRepPayloadSetDoubleArrayAsOwner(out, name, (double*)arr, dimensions))
844 case OCREP_PROP_BOOL:
845 if (err || !OCRepPayloadSetBoolArrayAsOwner(out, name, (bool*)arr, dimensions))
851 case OCREP_PROP_STRING:
852 if (err || !OCRepPayloadSetStringArrayAsOwner(out, name, (char**)arr, dimensions))
854 for(size_t i = 0; i < dimTotal; ++i)
856 OICFree(((char**)arr)[i]);
862 case OCREP_PROP_OBJECT:
863 if (err || !OCRepPayloadSetPropObjectArrayAsOwner(out, name, (OCRepPayload**)arr, dimensions))
865 for(size_t i = 0; i < dimTotal; ++i)
867 OCRepPayloadDestroy(((OCRepPayload**)arr)[i]);
874 OC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
882 static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue* repParent)
889 *outPayload = OCRepPayloadCreate();
890 OCRepPayload* curPayload = *outPayload;
894 return CborErrorOutOfMemory;
899 err = err || cbor_value_map_find_value(repParent, OC_RSRVD_HREF, &curVal);
900 if(cbor_value_is_valid(&curVal))
902 err = err || cbor_value_dup_text_string(&curVal, &curPayload->uri, &len,
906 err = err || cbor_value_map_find_value(repParent, OC_RSRVD_PROPERTY, &curVal);
907 if(cbor_value_is_valid(&curVal))
909 CborValue insidePropArray = {0};
910 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_RESOURCE_TYPE,
913 if(cbor_value_is_array(&insidePropArray))
916 err = err || cbor_value_enter_container(&insidePropArray, &rtArray);
918 while(!err && cbor_value_is_valid(&rtArray))
921 err = err || cbor_value_dup_text_string(&rtArray, &curRt, &len, NULL);
922 err = err || cbor_value_advance(&rtArray);
923 OCRepPayloadAddResourceTypeAsOwner(curPayload, curRt);
926 err = err || cbor_value_leave_container(&insidePropArray, &rtArray);
929 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_INTERFACE, &insidePropArray);
931 if(cbor_value_is_array(&insidePropArray))
934 err = err || cbor_value_enter_container(&insidePropArray, &ifArray);
936 while(!err && cbor_value_is_valid(&ifArray))
939 err = err || cbor_value_dup_text_string(&ifArray, &curIf, &len, NULL);
940 err = err || cbor_value_advance(&ifArray);
941 OCRepPayloadAddInterfaceAsOwner(curPayload, curIf);
944 err = err || cbor_value_leave_container(&insidePropArray, &ifArray);
948 err = err || cbor_value_map_find_value(repParent, OC_RSRVD_REPRESENTATION, &curVal);
949 if(cbor_value_is_map(&curVal))
952 err = err || cbor_value_enter_container(&curVal, &repMap);
954 while(!err && cbor_value_is_valid(&repMap))
957 err = err || cbor_value_dup_text_string(&repMap, &name, &len, NULL);
959 err = err || cbor_value_advance(&repMap);
962 bool boolval = false;
964 double doubleval = 0;
967 switch(cbor_value_get_type(&repMap))
970 err = !OCRepPayloadSetNull(curPayload, name);
972 case CborIntegerType:
973 err = err || cbor_value_get_int64(&repMap, &intval);
976 err = !OCRepPayloadSetPropInt(curPayload, name, intval);
980 err = err || cbor_value_get_double(&repMap, &doubleval);
983 err = !OCRepPayloadSetPropDouble(curPayload, name, doubleval);
986 case CborBooleanType:
987 err = err || cbor_value_get_boolean(&repMap, &boolval);
990 err = !OCRepPayloadSetPropBool(curPayload, name, boolval);
993 case CborTextStringType:
994 err = err || cbor_value_dup_text_string(&repMap, &strval, &len, NULL);
997 err = !OCRepPayloadSetPropStringAsOwner(curPayload, name, strval);
1001 err = err || OCParseSingleRepPayload(&pl, &repMap);
1004 err = !OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl);
1008 err = err || OCParseArray(curPayload, name, &repMap);
1011 OC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type);
1015 err = err || cbor_value_advance(&repMap);
1018 err = err || cbor_value_leave_container(&curVal, &repMap);
1023 OCRepPayloadDestroy(*outPayload);
1029 static OCStackResult OCParseRepPayload(OCPayload** outPayload, CborValue* arrayVal)
1033 return OC_STACK_INVALID_PARAM;
1038 OCRepPayload* rootPayload = NULL;
1039 OCRepPayload* curPayload = NULL;
1040 OCRepPayload* temp = NULL;
1041 while(!err && cbor_value_is_map(arrayVal))
1043 err = err || OCParseSingleRepPayload(&temp, arrayVal);
1045 if(rootPayload == NULL)
1052 curPayload->next = temp;
1053 curPayload = curPayload->next;
1057 err = err || cbor_value_advance(arrayVal);
1060 OCRepPayloadDestroy(rootPayload);
1061 OC_LOG(ERROR, TAG, "CBOR error in ParseRepPayload");
1062 return OC_STACK_MALFORMED_RESPONSE;
1066 *outPayload = (OCPayload*)rootPayload;
1071 static OCStackResult OCParsePresencePayload(OCPayload** outPayload, CborValue* arrayVal)
1075 return OC_STACK_INVALID_PARAM;
1079 if(cbor_value_is_map(arrayVal))
1081 uint64_t seqNum = 0;
1082 uint64_t maxAge = 0;
1083 OCPresenceTrigger trigger = OC_PRESENCE_TRIGGER_CREATE;
1084 char* tempStr = NULL;
1089 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_NONCE, &curVal);
1090 err = err || cbor_value_get_uint64(&curVal, &seqNum);
1093 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_TTL, &curVal);
1094 err = err || cbor_value_get_uint64(&curVal, &maxAge);
1097 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_TRIGGER, &curVal);
1098 err = err || cbor_value_dup_text_string(&curVal, &tempStr, &len, NULL);
1099 trigger = convertTriggerStringToEnum(tempStr);
1103 // Resource type name
1104 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_RESOURCE_TYPE, &curVal);
1105 if(cbor_value_is_valid(&curVal))
1107 err = err || cbor_value_dup_text_string(&curVal, &tempStr, &len, NULL);
1110 err = err || cbor_value_advance(arrayVal);
1114 *outPayload = (OCPayload*)OCPresencePayloadCreate(seqNum, maxAge, trigger, tempStr);
1120 OCPayloadDestroy(*outPayload);
1121 OC_LOG(ERROR, TAG, "CBOR error Parse Presence Payload");
1122 return OC_STACK_MALFORMED_RESPONSE;
1127 return OC_STACK_NO_MEMORY;
1134 OC_LOG(ERROR, TAG, "Root presence node was not a map");
1135 return OC_STACK_MALFORMED_RESPONSE;