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);
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);
92 result = OCRDCborToPayload(&arrayValue, outPayload);
96 OC_LOG_V(ERROR, TAG, "ParsePayload Type default: %d", payloadType);
97 result = OC_STACK_ERROR;
101 if(result == OC_STACK_OK)
103 err = err || cbor_value_leave_container(&rootValue, &arrayValue);
104 if(err != CborNoError)
106 return OC_STACK_MALFORMED_RESPONSE;
111 OC_LOG_V(INFO, TAG, "Finished parse payload, result is %d", result);
117 void OCFreeOCStringLL(OCStringLL* ll);
119 static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* arrayVal)
123 return OC_STACK_INVALID_PARAM;
127 char * securityData = NULL;
129 if(cbor_value_is_map(arrayVal))
132 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
134 if(cbor_value_is_valid(&curVal))
137 err = err || cbor_value_dup_text_string(&curVal, &securityData, &len, NULL);
142 OC_LOG(ERROR, TAG, "Cbor main value not a map");
143 return OC_STACK_MALFORMED_RESPONSE;
146 err = err || cbor_value_advance(arrayVal);
150 OC_LOG(ERROR, TAG, "Cbor in error condition");
151 OICFree(securityData);
152 return OC_STACK_MALFORMED_RESPONSE;
155 *outPayload = (OCPayload*)OCSecurityPayloadCreate(securityData);
156 OICFree(securityData);
162 static OCStackResult OCParseDiscoveryPayload(OCPayload** outPayload, CborValue* arrayVal)
166 return OC_STACK_INVALID_PARAM;
171 OCDiscoveryPayload* out = OCDiscoveryPayloadCreate();
175 return OC_STACK_NO_MEMORY;
178 size_t resourceCount = 0;
180 cbor_value_is_map(arrayVal))
182 OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
185 OC_LOG(ERROR, TAG, "Memory allocation failed");
186 OCDiscoveryPayloadDestroy(out);
187 return OC_STACK_NO_MEMORY;
192 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
194 err = err || cbor_value_dup_text_string(&curVal, &(resource->uri), &len, NULL);
197 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_SERVER_INSTANCE_ID, &curVal);
198 err = err || cbor_value_dup_byte_string(&curVal, &(resource->sid), &len, NULL);
202 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_PROPERTY, &curVal);
205 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_RESOURCE_TYPE, &rtArray);
208 err = err || cbor_value_enter_container(&rtArray, &rtVal);
210 OCStringLL* llPtr = NULL;
211 while(!err && cbor_value_is_text_string(&rtVal))
213 if(resource->types == NULL)
215 resource->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
216 llPtr = resource->types;
219 OC_LOG(ERROR, TAG, "Memory allocation failed");
220 OICFree(resource->uri);
221 OICFree(resource->sid);
223 OCDiscoveryPayloadDestroy(out);
224 return OC_STACK_NO_MEMORY;
229 llPtr->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
233 OC_LOG(ERROR, TAG, "Memory allocation failed");
234 OICFree(resource->uri);
235 OICFree(resource->sid);
236 OCFreeOCStringLL(resource->types);
238 OCDiscoveryPayloadDestroy(out);
239 return OC_STACK_NO_MEMORY;
244 OC_LOG(ERROR, TAG, "Unknown state in resource type copying");
245 OICFree(resource->uri);
246 OICFree(resource->sid);
247 OCFreeOCStringLL(resource->types);
249 OCDiscoveryPayloadDestroy(out);
250 return OC_STACK_NO_MEMORY;
253 err = err || cbor_value_dup_text_string(&rtVal, &(llPtr->value), &len, NULL);
254 err = err || cbor_value_advance(&rtVal);
257 err = err || cbor_value_leave_container(&rtArray, &rtVal);
261 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_INTERFACE, &ifArray);
263 err = err || cbor_value_enter_container(&ifArray, &ifVal);
266 while(!err && cbor_value_is_text_string(&ifVal))
268 if(resource->interfaces == NULL)
270 resource->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
271 llPtr = resource->interfaces;
274 OC_LOG(ERROR, TAG, "Memory allocation failed");
275 OICFree(resource->uri);
276 OICFree(resource->sid);
277 OCFreeOCStringLL(resource->types);
279 OCDiscoveryPayloadDestroy(out);
280 return OC_STACK_NO_MEMORY;
285 llPtr->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
289 OC_LOG(ERROR, TAG, "Memory allocation failed");
290 OICFree(resource->uri);
291 OICFree(resource->sid);
292 OCFreeOCStringLL(resource->types);
293 OCFreeOCStringLL(resource->interfaces);
295 OCDiscoveryPayloadDestroy(out);
296 return OC_STACK_NO_MEMORY;
301 OC_LOG(ERROR, TAG, "Unknown state in resource interfaces copying");
302 OICFree(resource->uri);
303 OICFree(resource->sid);
304 OCFreeOCStringLL(resource->types);
306 OCDiscoveryPayloadDestroy(out);
307 return OC_STACK_NO_MEMORY;
310 err = err || cbor_value_dup_text_string(&ifVal, &(llPtr->value), &len, NULL);
311 err = err || cbor_value_advance(&ifVal);
313 err = err || cbor_value_leave_container(&ifArray, &ifVal);
318 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_POLICY, &policyMap);
322 err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &val);
324 err = err || cbor_value_get_uint64(&val, &temp);
325 resource->bitmap = (uint8_t)temp;
327 err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &val);
328 if(cbor_value_is_valid(&val))
330 err = err || cbor_value_get_boolean(&val, &(resource->secure));
333 err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT,
335 if(cbor_value_is_valid(&port))
337 err = err || cbor_value_get_uint64(&port, &temp);
338 resource->port = (uint16_t)temp;
344 err = err || cbor_value_advance(arrayVal);
347 OICFree(resource->uri);
348 OICFree(resource->sid);
349 OCFreeOCStringLL(resource->types);
350 OCFreeOCStringLL(resource->interfaces);
352 OCDiscoveryPayloadDestroy(out);
353 OC_LOG_V(ERROR, TAG, "CBOR in error condition", err);
354 return OC_STACK_MALFORMED_RESPONSE;
357 OCDiscoveryPayloadAddNewResource(out, resource);
362 OCDiscoveryPayloadDestroy(out);
363 return OC_STACK_MALFORMED_RESPONSE;
367 *outPayload = (OCPayload*)out;
372 static OCStackResult OCParseDevicePayload(OCPayload** outPayload, CborValue* arrayVal)
376 return OC_STACK_INVALID_PARAM;
381 if(cbor_value_is_map(arrayVal))
386 char* specVer = NULL;
389 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
391 err = err || cbor_value_dup_text_string(&curVal, &uri, &len, NULL);
395 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
399 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DEVICE_ID, &repVal);
400 err = err || cbor_value_dup_byte_string(&repVal, &sid, &len, NULL);
402 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DEVICE_NAME, &repVal);
403 err = err || cbor_value_dup_text_string(&repVal, &dname, &len, NULL);
404 // Device Spec Version
405 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SPEC_VERSION, &repVal);
406 err = err || cbor_value_dup_text_string(&repVal, &specVer, &len, NULL);
407 // Data Model Version
408 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DATA_MODEL_VERSION, &repVal);
409 err = err || cbor_value_dup_text_string(&repVal, &dmVer, &len, NULL);
413 err = err || cbor_value_advance(arrayVal);
422 OC_LOG_V(ERROR, TAG, "CBOR in error condition %d", err);
423 return OC_STACK_MALFORMED_RESPONSE;
426 *outPayload = (OCPayload*)OCDevicePayloadCreate(uri, sid, dname, specVer, dmVer);
435 return OC_STACK_NO_MEMORY;
442 OC_LOG(ERROR, TAG, "Root device node was not a map");
443 return OC_STACK_MALFORMED_RESPONSE;
448 static OCStackResult OCParsePlatformPayload(OCPayload** outPayload, CborValue* arrayVal)
452 return OC_STACK_INVALID_PARAM;
457 if(cbor_value_is_map(arrayVal))
460 OCPlatformInfo info = {0};
462 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
464 err = err || cbor_value_dup_text_string(&curVal, &uri, &len, NULL);
468 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
472 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_PLATFORM_ID, &repVal);
473 err = err || cbor_value_dup_text_string(&repVal, &(info.platformID), &len, NULL);
476 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_NAME, &repVal);
477 err = err || cbor_value_dup_text_string(&repVal, &(info.manufacturerName), &len, NULL);
480 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_URL, &repVal);
481 if(cbor_value_is_valid(&repVal))
483 err = err || cbor_value_dup_text_string(&repVal, &(info.manufacturerUrl), &len, NULL);
487 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MODEL_NUM, &repVal);
488 if(cbor_value_is_valid(&repVal))
490 err = err || cbor_value_dup_text_string(&repVal, &(info.modelNumber), &len, NULL);
494 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_DATE, &repVal);
495 if(cbor_value_is_valid(&repVal))
497 err = err || cbor_value_dup_text_string(&repVal, &(info.dateOfManufacture), &len,
502 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_PLATFORM_VERSION, &repVal);
503 if(cbor_value_is_valid(&repVal))
505 err = err || cbor_value_dup_text_string(&repVal, &(info.platformVersion), &len,
510 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_OS_VERSION, &repVal);
511 if(cbor_value_is_valid(&repVal))
513 err = err || cbor_value_dup_text_string(&repVal, &(info.operatingSystemVersion),
518 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_HARDWARE_VERSION, &repVal);
519 if(cbor_value_is_valid(&repVal))
521 err = err || cbor_value_dup_text_string(&repVal, &(info.hardwareVersion), &len,
526 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_FIRMWARE_VERSION, &repVal);
527 if(cbor_value_is_valid(&repVal))
529 err = err || cbor_value_dup_text_string(&repVal, &(info.firmwareVersion), &len,
534 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SUPPORT_URL, &repVal);
535 if(cbor_value_is_valid(&repVal))
537 err = err || cbor_value_dup_text_string(&repVal, &(info.supportUrl), &len, NULL);
541 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SYSTEM_TIME, &repVal);
542 if(cbor_value_is_valid(&repVal))
544 err = err || cbor_value_dup_text_string(&repVal, &(info.systemTime), &len, NULL);
548 err = err || cbor_value_advance(arrayVal);
552 OICFree(info.dateOfManufacture);
553 OICFree(info.firmwareVersion);
554 OICFree(info.hardwareVersion);
555 OICFree(info.manufacturerName);
556 OICFree(info.manufacturerUrl);
557 OICFree(info.modelNumber);
558 OICFree(info.operatingSystemVersion);
559 OICFree(info.platformID);
560 OICFree(info.platformVersion);
561 OICFree(info.supportUrl);
562 OICFree(info.systemTime);
563 OC_LOG(ERROR, TAG, "CBOR error In ParsePlatformPayload");
564 return OC_STACK_MALFORMED_RESPONSE;
567 *outPayload = (OCPayload*)OCPlatformPayloadCreateAsOwner(uri, &info);
571 return OC_STACK_NO_MEMORY;
578 OC_LOG(ERROR, TAG, "Root device node was not a map");
579 return OC_STACK_MALFORMED_RESPONSE;
583 static OCRepPayloadPropType DecodeCborType(CborType type)
588 return OCREP_PROP_NULL;
589 case CborIntegerType:
590 return OCREP_PROP_INT;
592 return OCREP_PROP_DOUBLE;
593 case CborBooleanType:
594 return OCREP_PROP_BOOL;
595 case CborTextStringType:
596 return OCREP_PROP_STRING;
598 return OCREP_PROP_OBJECT;
600 return OCREP_PROP_ARRAY;
602 return OCREP_PROP_NULL;
605 static bool OCParseArrayFindDimensionsAndType(const CborValue* parent, size_t dimensions[MAX_REP_ARRAY_DEPTH],
606 OCRepPayloadPropType* type)
609 CborValue insideArray;
610 *type = OCREP_PROP_NULL;
611 dimensions[0] = dimensions[1] = dimensions[2] = 0;
613 err = err || cbor_value_enter_container(parent, &insideArray);
615 while (cbor_value_is_valid(&insideArray))
617 OCRepPayloadPropType tempType = DecodeCborType(cbor_value_get_type(&insideArray));
619 if (tempType == OCREP_PROP_ARRAY)
621 size_t subdim[MAX_REP_ARRAY_DEPTH];
622 tempType = OCREP_PROP_NULL;
623 err = err || OCParseArrayFindDimensionsAndType(&insideArray, subdim, &tempType);
627 OC_LOG(ERROR, TAG, "Parse array helper, sub-array too deep");
630 dimensions[1] = dimensions[1] >= subdim[0] ? dimensions[1] : subdim[0];
631 dimensions[2] = dimensions[2] >= subdim[1] ? dimensions[2] : subdim[1];
633 if (*type != OCREP_PROP_NULL && tempType != OCREP_PROP_NULL
634 && *type != tempType)
636 OC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed (subtype)");
639 else if (*type == OCREP_PROP_NULL)
641 // We don't know the type of this array yet, so the assignment is OK
645 else if (*type == OCREP_PROP_NULL)
647 // We don't know the type of this array yet, so the assignment is OK
650 // tempType is allowed to be NULL, since it might now know the answer yet
651 else if (tempType != OCREP_PROP_NULL && *type != tempType)
653 // this is an invalid situation!
654 OC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed");
659 cbor_value_advance(&insideArray);
665 static size_t getAllocSize(OCRepPayloadPropType type)
670 return sizeof (int64_t);
671 case OCREP_PROP_DOUBLE:
672 return sizeof (double);
673 case OCREP_PROP_BOOL:
674 return sizeof (bool);
675 case OCREP_PROP_STRING:
676 return sizeof (char*);
677 case OCREP_PROP_OBJECT:
678 return sizeof (OCRepPayload*);
684 static size_t arrayStep(size_t dimensions[MAX_REP_ARRAY_DEPTH], size_t elementNum)
687 (dimensions[1] == 0 ? 1 : dimensions[1]) *
688 (dimensions[2] == 0 ? 1 : dimensions[2]) *
692 static bool OCParseArrayFillArray(const CborValue* parent, size_t dimensions[MAX_REP_ARRAY_DEPTH],
693 OCRepPayloadPropType type, void* targetArray)
696 CborValue insideArray;
698 err = err || cbor_value_enter_container(parent, &insideArray);
701 char* tempStr = NULL;
703 OCRepPayload* tempPl = NULL;
705 size_t newdim[MAX_REP_ARRAY_DEPTH];
706 newdim[0] = dimensions[1];
707 newdim[1] = dimensions[2];
710 while (!err && i < dimensions[0] && cbor_value_is_valid(&insideArray))
712 if (cbor_value_get_type(&insideArray) != CborNullType)
717 if (dimensions[1] == 0)
719 err = err || cbor_value_get_int64(&insideArray,
720 &(((int64_t*)targetArray)[i]));
724 err = err || OCParseArrayFillArray(&insideArray, newdim,
726 &(((int64_t*)targetArray)[arrayStep(dimensions, i)])
730 case OCREP_PROP_DOUBLE:
731 if (dimensions[1] == 0)
733 err = err || cbor_value_get_double(&insideArray,
734 &(((double*)targetArray)[i]));
738 err = err || OCParseArrayFillArray(&insideArray, newdim,
740 &(((double*)targetArray)[arrayStep(dimensions, i)])
744 case OCREP_PROP_BOOL:
745 if (dimensions[1] == 0)
747 err = err || cbor_value_get_boolean(&insideArray,
748 &(((bool*)targetArray)[i]));
752 err = err || OCParseArrayFillArray(&insideArray, newdim,
754 &(((bool*)targetArray)[arrayStep(dimensions, i)])
758 case OCREP_PROP_STRING:
759 if (dimensions[1] == 0)
761 err = err || cbor_value_dup_text_string(&insideArray,
762 &tempStr, &tempLen, NULL);
763 ((char**)targetArray)[i] = tempStr;
768 err = err || OCParseArrayFillArray(&insideArray, newdim,
770 &(((char**)targetArray)[arrayStep(dimensions, i)])
774 case OCREP_PROP_OBJECT:
775 if (dimensions[1] == 0)
777 err = err || OCParseSingleRepPayload(&tempPl, &insideArray);
778 ((OCRepPayload**)targetArray)[i] = tempPl;
783 err = err || OCParseArrayFillArray(&insideArray, newdim,
785 &(((OCRepPayload**)targetArray)[arrayStep(dimensions, i)])
790 OC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
796 err = err || cbor_value_advance(&insideArray);
802 static bool OCParseArray(OCRepPayload* out, const char* name, CborValue* container)
804 OCRepPayloadPropType type;
805 size_t dimensions[MAX_REP_ARRAY_DEPTH];
806 bool err = OCParseArrayFindDimensionsAndType(container, dimensions, &type);
810 OC_LOG(ERROR, TAG, "Array details weren't clear");
814 if (type == OCREP_PROP_NULL)
816 err = err || OCRepPayloadSetNull(out, name);
817 err = err || cbor_value_advance(container);
821 size_t dimTotal = calcDimTotal(dimensions);
822 size_t allocSize = getAllocSize(type);
823 void* arr = OICCalloc(dimTotal, allocSize);
827 OC_LOG(ERROR, TAG, "Array Parse allocation failed");
831 err = err || OCParseArrayFillArray(container, dimensions, type, arr);
836 if (err || !OCRepPayloadSetIntArrayAsOwner(out, name, (int64_t*)arr, dimensions))
842 case OCREP_PROP_DOUBLE:
843 if (err || !OCRepPayloadSetDoubleArrayAsOwner(out, name, (double*)arr, dimensions))
849 case OCREP_PROP_BOOL:
850 if (err || !OCRepPayloadSetBoolArrayAsOwner(out, name, (bool*)arr, dimensions))
856 case OCREP_PROP_STRING:
857 if (err || !OCRepPayloadSetStringArrayAsOwner(out, name, (char**)arr, dimensions))
859 for(size_t i = 0; i < dimTotal; ++i)
861 OICFree(((char**)arr)[i]);
867 case OCREP_PROP_OBJECT:
868 if (err || !OCRepPayloadSetPropObjectArrayAsOwner(out, name, (OCRepPayload**)arr, dimensions))
870 for(size_t i = 0; i < dimTotal; ++i)
872 OCRepPayloadDestroy(((OCRepPayload**)arr)[i]);
879 OC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
887 static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue* repParent)
894 *outPayload = OCRepPayloadCreate();
895 OCRepPayload* curPayload = *outPayload;
899 return CborErrorOutOfMemory;
904 err = err || cbor_value_map_find_value(repParent, OC_RSRVD_HREF, &curVal);
905 if(cbor_value_is_valid(&curVal))
907 err = err || cbor_value_dup_text_string(&curVal, &curPayload->uri, &len,
911 err = err || cbor_value_map_find_value(repParent, OC_RSRVD_PROPERTY, &curVal);
912 if(cbor_value_is_valid(&curVal))
914 CborValue insidePropArray = {0};
915 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_RESOURCE_TYPE,
918 if(cbor_value_is_array(&insidePropArray))
921 err = err || cbor_value_enter_container(&insidePropArray, &rtArray);
923 while(!err && cbor_value_is_valid(&rtArray))
926 err = err || cbor_value_dup_text_string(&rtArray, &curRt, &len, NULL);
927 err = err || cbor_value_advance(&rtArray);
928 OCRepPayloadAddResourceTypeAsOwner(curPayload, curRt);
931 err = err || cbor_value_leave_container(&insidePropArray, &rtArray);
934 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_INTERFACE, &insidePropArray);
936 if(cbor_value_is_array(&insidePropArray))
939 err = err || cbor_value_enter_container(&insidePropArray, &ifArray);
941 while(!err && cbor_value_is_valid(&ifArray))
944 err = err || cbor_value_dup_text_string(&ifArray, &curIf, &len, NULL);
945 err = err || cbor_value_advance(&ifArray);
946 OCRepPayloadAddInterfaceAsOwner(curPayload, curIf);
949 err = err || cbor_value_leave_container(&insidePropArray, &ifArray);
953 err = err || cbor_value_map_find_value(repParent, OC_RSRVD_REPRESENTATION, &curVal);
954 if(cbor_value_is_map(&curVal))
957 err = err || cbor_value_enter_container(&curVal, &repMap);
959 while(!err && cbor_value_is_valid(&repMap))
962 err = err || cbor_value_dup_text_string(&repMap, &name, &len, NULL);
964 err = err || cbor_value_advance(&repMap);
967 bool boolval = false;
969 double doubleval = 0;
972 switch(cbor_value_get_type(&repMap))
975 err = !OCRepPayloadSetNull(curPayload, name);
977 case CborIntegerType:
978 err = err || cbor_value_get_int64(&repMap, &intval);
981 err = !OCRepPayloadSetPropInt(curPayload, name, intval);
985 err = err || cbor_value_get_double(&repMap, &doubleval);
988 err = !OCRepPayloadSetPropDouble(curPayload, name, doubleval);
991 case CborBooleanType:
992 err = err || cbor_value_get_boolean(&repMap, &boolval);
995 err = !OCRepPayloadSetPropBool(curPayload, name, boolval);
998 case CborTextStringType:
999 err = err || cbor_value_dup_text_string(&repMap, &strval, &len, NULL);
1002 err = !OCRepPayloadSetPropStringAsOwner(curPayload, name, strval);
1006 err = err || OCParseSingleRepPayload(&pl, &repMap);
1009 err = !OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl);
1013 err = err || OCParseArray(curPayload, name, &repMap);
1016 OC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type);
1020 err = err || cbor_value_advance(&repMap);
1023 err = err || cbor_value_leave_container(&curVal, &repMap);
1028 OCRepPayloadDestroy(*outPayload);
1034 static OCStackResult OCParseRepPayload(OCPayload** outPayload, CborValue* arrayVal)
1038 return OC_STACK_INVALID_PARAM;
1043 OCRepPayload* rootPayload = NULL;
1044 OCRepPayload* curPayload = NULL;
1045 OCRepPayload* temp = NULL;
1046 while(!err && cbor_value_is_map(arrayVal))
1048 err = err || OCParseSingleRepPayload(&temp, arrayVal);
1050 if(rootPayload == NULL)
1057 curPayload->next = temp;
1058 curPayload = curPayload->next;
1062 err = err || cbor_value_advance(arrayVal);
1065 OCRepPayloadDestroy(rootPayload);
1066 OC_LOG(ERROR, TAG, "CBOR error in ParseRepPayload");
1067 return OC_STACK_MALFORMED_RESPONSE;
1071 *outPayload = (OCPayload*)rootPayload;
1076 static OCStackResult OCParsePresencePayload(OCPayload** outPayload, CborValue* arrayVal)
1080 return OC_STACK_INVALID_PARAM;
1084 if(cbor_value_is_map(arrayVal))
1086 uint64_t seqNum = 0;
1087 uint64_t maxAge = 0;
1088 OCPresenceTrigger trigger = OC_PRESENCE_TRIGGER_CREATE;
1089 char* tempStr = NULL;
1094 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_NONCE, &curVal);
1095 err = err || cbor_value_get_uint64(&curVal, &seqNum);
1098 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_TTL, &curVal);
1099 err = err || cbor_value_get_uint64(&curVal, &maxAge);
1102 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_TRIGGER, &curVal);
1103 err = err || cbor_value_dup_text_string(&curVal, &tempStr, &len, NULL);
1104 trigger = convertTriggerStringToEnum(tempStr);
1108 // Resource type name
1109 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_RESOURCE_TYPE, &curVal);
1110 if(cbor_value_is_valid(&curVal))
1112 err = err || cbor_value_dup_text_string(&curVal, &tempStr, &len, NULL);
1115 err = err || cbor_value_advance(arrayVal);
1119 *outPayload = (OCPayload*)OCPresencePayloadCreate(seqNum, maxAge, trigger, tempStr);
1125 OCPayloadDestroy(*outPayload);
1126 OC_LOG(ERROR, TAG, "CBOR error Parse Presence Payload");
1127 return OC_STACK_MALFORMED_RESPONSE;
1132 return OC_STACK_NO_MEMORY;
1139 OC_LOG(ERROR, TAG, "Root presence node was not a map");
1140 return OC_STACK_MALFORMED_RESPONSE;