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_string.h"
25 #include "oic_malloc.h"
26 #include "ocstackinternal.h"
27 #include "ocpayload.h"
29 #include "payload_logging.h"
30 #include "rdpayload.h"
32 #define TAG "OCPayloadParse"
34 static OCStackResult OCParseDiscoveryPayload(OCPayload** outPayload, CborValue* arrayVal);
35 static OCStackResult OCParseDevicePayload(OCPayload** outPayload, CborValue* arrayVal);
36 static OCStackResult OCParsePlatformPayload(OCPayload** outPayload, CborValue* arrayVal);
37 static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue* repParent);
38 static OCStackResult OCParseRepPayload(OCPayload** outPayload, CborValue* arrayVal);
39 static OCStackResult OCParsePresencePayload(OCPayload** outPayload, CborValue* arrayVal);
40 static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* arrayVal);
42 OCStackResult OCParsePayload(OCPayload** outPayload, OCPayloadType payloadType,
43 const uint8_t* payload, size_t payloadSize)
49 OC_LOG_V(INFO, TAG, "CBOR Parsing size: %d %d", payloadSize, payloadType);
50 if((err = cbor_parser_init(payload, payloadSize, 0, &parser, &rootValue)) != false)
52 OC_LOG_V(ERROR, TAG, "CBOR Parser init failed: %d", err);
53 return OC_STACK_ERROR;
56 if(!cbor_value_is_array(&rootValue))
58 OC_LOG_V(ERROR, TAG, "CBOR payload root object is not an array :%x", rootValue.type);
59 return OC_STACK_MALFORMED_RESPONSE;
64 err = err || cbor_value_enter_container(&rootValue, &arrayValue);
68 OC_LOG_V(ERROR, TAG, "CBOR payload parse failed :%d", err);
69 return OC_STACK_MALFORMED_RESPONSE;
72 OCStackResult result = OC_STACK_ERROR;
75 case PAYLOAD_TYPE_DISCOVERY:
76 result = OCParseDiscoveryPayload(outPayload, &arrayValue);
78 case PAYLOAD_TYPE_DEVICE:
79 result = OCParseDevicePayload(outPayload, &arrayValue);
81 case PAYLOAD_TYPE_PLATFORM:
82 result = OCParsePlatformPayload(outPayload, &arrayValue);
84 case PAYLOAD_TYPE_REPRESENTATION:
85 result = OCParseRepPayload(outPayload, &arrayValue);
87 case PAYLOAD_TYPE_PRESENCE:
88 result = OCParsePresencePayload(outPayload, &arrayValue);
90 case PAYLOAD_TYPE_SECURITY:
91 result = OCParseSecurityPayload(outPayload, &arrayValue);
94 result = OCRDCborToPayload(&arrayValue, outPayload);
97 OC_LOG_V(ERROR, TAG, "ParsePayload Type default: %d", payloadType);
98 result = OC_STACK_ERROR;
102 if(result == OC_STACK_OK)
104 err = err || cbor_value_leave_container(&rootValue, &arrayValue);
105 if(err != CborNoError)
107 return OC_STACK_MALFORMED_RESPONSE;
112 OC_LOG_V(INFO, TAG, "Finished parse payload, result is %d", result);
118 void OCFreeOCStringLL(OCStringLL* ll);
120 static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* arrayVal)
124 return OC_STACK_INVALID_PARAM;
128 char * securityData = NULL;
130 if(cbor_value_is_map(arrayVal))
133 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
135 if(cbor_value_is_valid(&curVal))
138 err = err || cbor_value_dup_text_string(&curVal, &securityData, &len, NULL);
143 OC_LOG(ERROR, TAG, "Cbor main value not a map");
144 return OC_STACK_MALFORMED_RESPONSE;
147 err = err || cbor_value_advance(arrayVal);
151 OC_LOG(ERROR, TAG, "Cbor in error condition");
152 OICFree(securityData);
153 return OC_STACK_MALFORMED_RESPONSE;
156 *outPayload = (OCPayload*)OCSecurityPayloadCreate(securityData);
157 OICFree(securityData);
163 static OCStackResult OCParseDiscoveryPayload(OCPayload** outPayload, CborValue* arrayVal)
167 return OC_STACK_INVALID_PARAM;
172 OCDiscoveryPayload* out = OCDiscoveryPayloadCreate();
176 return OC_STACK_NO_MEMORY;
179 if (cbor_value_is_array(arrayVal))
181 OCLinksPayload *linksPayload = NULL;
182 OCTagsPayload *tagsPayload = NULL;
183 while (cbor_value_is_container(arrayVal))
187 CborValue colResources;
188 CborError cborFindResult = cbor_value_enter_container(arrayVal, &colResources);
189 if (CborNoError != cborFindResult)
194 if (OC_STACK_OK != OCTagsCborToPayload(&colResources, &tagsPayload))
196 OC_LOG(ERROR, TAG, "Tags cbor parsing failed.");
197 OCFreeTagsResource(tagsPayload);
201 if (OC_STACK_OK != OCLinksCborToPayload(&colResources, &linksPayload))
203 OC_LOG(ERROR, TAG, "Links cbor parsing failed.");
204 OCFreeTagsResource(tagsPayload);
205 OCFreeLinksResource(linksPayload);
209 if (OC_STACK_OK != OCDiscoveryCollectionPayloadAddResource(out, tagsPayload, linksPayload))
211 OC_LOG(ERROR, TAG, "Memory allocation failed");
212 OCFreeLinksResource(linksPayload);
213 OCFreeTagsResource(tagsPayload);
214 OCDiscoveryPayloadDestroy(out);
215 return OC_STACK_NO_MEMORY;
217 if (CborNoError != cbor_value_advance(arrayVal))
219 OC_LOG(ERROR, TAG, "Cbor value advanced failed.");
224 if (cbor_value_is_map(arrayVal))
226 size_t resourceCount = 0;
228 cbor_value_is_map(arrayVal))
230 OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
233 OC_LOG(ERROR, TAG, "Memory allocation failed");
234 OCDiscoveryPayloadDestroy(out);
235 return OC_STACK_NO_MEMORY;
240 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
242 err = err || cbor_value_dup_text_string(&curVal, &(resource->uri), &len, NULL);
245 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_SERVER_INSTANCE_ID, &curVal);
246 err = err || cbor_value_dup_byte_string(&curVal, &(resource->sid), &len, NULL);
250 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_PROPERTY, &curVal);
253 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_RESOURCE_TYPE, &rtArray);
256 err = err || cbor_value_enter_container(&rtArray, &rtVal);
258 OCStringLL* llPtr = NULL;
259 while(!err && cbor_value_is_text_string(&rtVal))
261 if(resource->types == NULL)
263 resource->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
264 llPtr = resource->types;
267 OC_LOG(ERROR, TAG, "Memory allocation failed");
268 OICFree(resource->uri);
269 OICFree(resource->sid);
271 OCDiscoveryPayloadDestroy(out);
272 return OC_STACK_NO_MEMORY;
277 llPtr->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
281 OC_LOG(ERROR, TAG, "Memory allocation failed");
282 OICFree(resource->uri);
283 OICFree(resource->sid);
284 OCFreeOCStringLL(resource->types);
286 OCDiscoveryPayloadDestroy(out);
287 return OC_STACK_NO_MEMORY;
292 OC_LOG(ERROR, TAG, "Unknown state in resource type copying");
293 OICFree(resource->uri);
294 OICFree(resource->sid);
295 OCFreeOCStringLL(resource->types);
297 OCDiscoveryPayloadDestroy(out);
298 return OC_STACK_NO_MEMORY;
301 err = err || cbor_value_dup_text_string(&rtVal, &(llPtr->value), &len, NULL);
302 err = err || cbor_value_advance(&rtVal);
305 err = err || cbor_value_leave_container(&rtArray, &rtVal);
309 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_INTERFACE, &ifArray);
311 err = err || cbor_value_enter_container(&ifArray, &ifVal);
314 while(!err && cbor_value_is_text_string(&ifVal))
316 if(resource->interfaces == NULL)
318 resource->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
319 llPtr = resource->interfaces;
322 OC_LOG(ERROR, TAG, "Memory allocation failed");
323 OICFree(resource->uri);
324 OICFree(resource->sid);
325 OCFreeOCStringLL(resource->types);
327 OCDiscoveryPayloadDestroy(out);
328 return OC_STACK_NO_MEMORY;
333 llPtr->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
337 OC_LOG(ERROR, TAG, "Memory allocation failed");
338 OICFree(resource->uri);
339 OICFree(resource->sid);
340 OCFreeOCStringLL(resource->types);
341 OCFreeOCStringLL(resource->interfaces);
343 OCDiscoveryPayloadDestroy(out);
344 return OC_STACK_NO_MEMORY;
349 OC_LOG(ERROR, TAG, "Unknown state in resource interfaces copying");
350 OICFree(resource->uri);
351 OICFree(resource->sid);
352 OCFreeOCStringLL(resource->types);
354 OCDiscoveryPayloadDestroy(out);
355 return OC_STACK_NO_MEMORY;
358 err = err || cbor_value_dup_text_string(&ifVal, &(llPtr->value), &len, NULL);
359 err = err || cbor_value_advance(&ifVal);
361 err = err || cbor_value_leave_container(&ifArray, &ifVal);
366 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_POLICY, &policyMap);
370 err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &val);
372 err = err || cbor_value_get_uint64(&val, &temp);
373 resource->bitmap = (uint8_t)temp;
375 err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &val);
376 if(cbor_value_is_valid(&val))
378 err = err || cbor_value_get_boolean(&val, &(resource->secure));
381 err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT,
383 if(cbor_value_is_valid(&port))
385 err = err || cbor_value_get_uint64(&port, &temp);
386 resource->port = (uint16_t)temp;
392 err = err || cbor_value_advance(arrayVal);
395 OICFree(resource->uri);
396 OICFree(resource->sid);
397 OCFreeOCStringLL(resource->types);
398 OCFreeOCStringLL(resource->interfaces);
400 OCDiscoveryPayloadDestroy(out);
401 OC_LOG_V(ERROR, TAG, "CBOR in error condition: %d", err);
402 return OC_STACK_MALFORMED_RESPONSE;
405 OCDiscoveryPayloadAddNewResource(out, resource);
411 OCDiscoveryPayloadDestroy(out);
412 return OC_STACK_MALFORMED_RESPONSE;
416 *outPayload = (OCPayload*)out;
420 OCDiscoveryCollectionPayloadDestroy(out);
421 return OC_STACK_MALFORMED_RESPONSE;
424 static OCStackResult OCParseDevicePayload(OCPayload** outPayload, CborValue* arrayVal)
428 return OC_STACK_INVALID_PARAM;
433 if(cbor_value_is_map(arrayVal))
438 char* specVer = NULL;
441 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
443 err = err || cbor_value_dup_text_string(&curVal, &uri, &len, NULL);
447 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
451 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DEVICE_ID, &repVal);
452 err = err || cbor_value_dup_byte_string(&repVal, &sid, &len, NULL);
454 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DEVICE_NAME, &repVal);
455 err = err || cbor_value_dup_text_string(&repVal, &dname, &len, NULL);
456 // Device Spec Version
457 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SPEC_VERSION, &repVal);
458 err = err || cbor_value_dup_text_string(&repVal, &specVer, &len, NULL);
459 // Data Model Version
460 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DATA_MODEL_VERSION, &repVal);
461 err = err || cbor_value_dup_text_string(&repVal, &dmVer, &len, NULL);
465 err = err || cbor_value_advance(arrayVal);
474 OC_LOG_V(ERROR, TAG, "CBOR in error condition %d", err);
475 return OC_STACK_MALFORMED_RESPONSE;
478 *outPayload = (OCPayload*)OCDevicePayloadCreate(uri, sid, dname, specVer, dmVer);
487 return OC_STACK_NO_MEMORY;
494 OC_LOG(ERROR, TAG, "Root device node was not a map");
495 return OC_STACK_MALFORMED_RESPONSE;
500 static OCStackResult OCParsePlatformPayload(OCPayload** outPayload, CborValue* arrayVal)
504 return OC_STACK_INVALID_PARAM;
509 if(cbor_value_is_map(arrayVal))
512 OCPlatformInfo info = {0};
514 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
516 err = err || cbor_value_dup_text_string(&curVal, &uri, &len, NULL);
520 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
524 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_PLATFORM_ID, &repVal);
525 err = err || cbor_value_dup_text_string(&repVal, &(info.platformID), &len, NULL);
528 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_NAME, &repVal);
529 err = err || cbor_value_dup_text_string(&repVal, &(info.manufacturerName), &len, NULL);
532 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_URL, &repVal);
533 if(cbor_value_is_valid(&repVal))
535 err = err || cbor_value_dup_text_string(&repVal, &(info.manufacturerUrl), &len, NULL);
539 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MODEL_NUM, &repVal);
540 if(cbor_value_is_valid(&repVal))
542 err = err || cbor_value_dup_text_string(&repVal, &(info.modelNumber), &len, NULL);
546 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_DATE, &repVal);
547 if(cbor_value_is_valid(&repVal))
549 err = err || cbor_value_dup_text_string(&repVal, &(info.dateOfManufacture), &len,
554 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_PLATFORM_VERSION, &repVal);
555 if(cbor_value_is_valid(&repVal))
557 err = err || cbor_value_dup_text_string(&repVal, &(info.platformVersion), &len,
562 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_OS_VERSION, &repVal);
563 if(cbor_value_is_valid(&repVal))
565 err = err || cbor_value_dup_text_string(&repVal, &(info.operatingSystemVersion),
570 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_HARDWARE_VERSION, &repVal);
571 if(cbor_value_is_valid(&repVal))
573 err = err || cbor_value_dup_text_string(&repVal, &(info.hardwareVersion), &len,
578 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_FIRMWARE_VERSION, &repVal);
579 if(cbor_value_is_valid(&repVal))
581 err = err || cbor_value_dup_text_string(&repVal, &(info.firmwareVersion), &len,
586 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SUPPORT_URL, &repVal);
587 if(cbor_value_is_valid(&repVal))
589 err = err || cbor_value_dup_text_string(&repVal, &(info.supportUrl), &len, NULL);
593 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SYSTEM_TIME, &repVal);
594 if(cbor_value_is_valid(&repVal))
596 err = err || cbor_value_dup_text_string(&repVal, &(info.systemTime), &len, NULL);
600 err = err || cbor_value_advance(arrayVal);
604 OICFree(info.dateOfManufacture);
605 OICFree(info.firmwareVersion);
606 OICFree(info.hardwareVersion);
607 OICFree(info.manufacturerName);
608 OICFree(info.manufacturerUrl);
609 OICFree(info.modelNumber);
610 OICFree(info.operatingSystemVersion);
611 OICFree(info.platformID);
612 OICFree(info.platformVersion);
613 OICFree(info.supportUrl);
614 OICFree(info.systemTime);
615 OC_LOG(ERROR, TAG, "CBOR error In ParsePlatformPayload");
616 return OC_STACK_MALFORMED_RESPONSE;
619 *outPayload = (OCPayload*)OCPlatformPayloadCreateAsOwner(uri, &info);
623 return OC_STACK_NO_MEMORY;
630 OC_LOG(ERROR, TAG, "Root device node was not a map");
631 return OC_STACK_MALFORMED_RESPONSE;
635 static OCRepPayloadPropType DecodeCborType(CborType type)
640 return OCREP_PROP_NULL;
641 case CborIntegerType:
642 return OCREP_PROP_INT;
644 return OCREP_PROP_DOUBLE;
645 case CborBooleanType:
646 return OCREP_PROP_BOOL;
647 case CborTextStringType:
648 return OCREP_PROP_STRING;
650 return OCREP_PROP_OBJECT;
652 return OCREP_PROP_ARRAY;
654 return OCREP_PROP_NULL;
657 static bool OCParseArrayFindDimensionsAndType(const CborValue* parent, size_t dimensions[MAX_REP_ARRAY_DEPTH],
658 OCRepPayloadPropType* type)
661 CborValue insideArray;
662 *type = OCREP_PROP_NULL;
663 dimensions[0] = dimensions[1] = dimensions[2] = 0;
665 err = err || cbor_value_enter_container(parent, &insideArray);
667 while (cbor_value_is_valid(&insideArray))
669 OCRepPayloadPropType tempType = DecodeCborType(cbor_value_get_type(&insideArray));
671 if (tempType == OCREP_PROP_ARRAY)
673 size_t subdim[MAX_REP_ARRAY_DEPTH];
674 tempType = OCREP_PROP_NULL;
675 err = err || OCParseArrayFindDimensionsAndType(&insideArray, subdim, &tempType);
679 OC_LOG(ERROR, TAG, "Parse array helper, sub-array too deep");
682 dimensions[1] = dimensions[1] >= subdim[0] ? dimensions[1] : subdim[0];
683 dimensions[2] = dimensions[2] >= subdim[1] ? dimensions[2] : subdim[1];
685 if (*type != OCREP_PROP_NULL && tempType != OCREP_PROP_NULL
686 && *type != tempType)
688 OC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed (subtype)");
691 else if (*type == OCREP_PROP_NULL)
693 // We don't know the type of this array yet, so the assignment is OK
697 else if (*type == OCREP_PROP_NULL)
699 // We don't know the type of this array yet, so the assignment is OK
702 // tempType is allowed to be NULL, since it might now know the answer yet
703 else if (tempType != OCREP_PROP_NULL && *type != tempType)
705 // this is an invalid situation!
706 OC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed");
711 cbor_value_advance(&insideArray);
717 static size_t getAllocSize(OCRepPayloadPropType type)
722 return sizeof (int64_t);
723 case OCREP_PROP_DOUBLE:
724 return sizeof (double);
725 case OCREP_PROP_BOOL:
726 return sizeof (bool);
727 case OCREP_PROP_STRING:
728 return sizeof (char*);
729 case OCREP_PROP_OBJECT:
730 return sizeof (OCRepPayload*);
736 static size_t arrayStep(size_t dimensions[MAX_REP_ARRAY_DEPTH], size_t elementNum)
739 (dimensions[1] == 0 ? 1 : dimensions[1]) *
740 (dimensions[2] == 0 ? 1 : dimensions[2]) *
744 static bool OCParseArrayFillArray(const CborValue* parent, size_t dimensions[MAX_REP_ARRAY_DEPTH],
745 OCRepPayloadPropType type, void* targetArray)
748 CborValue insideArray;
750 err = err || cbor_value_enter_container(parent, &insideArray);
753 char* tempStr = NULL;
755 OCRepPayload* tempPl = NULL;
757 size_t newdim[MAX_REP_ARRAY_DEPTH];
758 newdim[0] = dimensions[1];
759 newdim[1] = dimensions[2];
762 while (!err && i < dimensions[0] && cbor_value_is_valid(&insideArray))
764 if (cbor_value_get_type(&insideArray) != CborNullType)
769 if (dimensions[1] == 0)
771 err = err || cbor_value_get_int64(&insideArray,
772 &(((int64_t*)targetArray)[i]));
776 err = err || OCParseArrayFillArray(&insideArray, newdim,
778 &(((int64_t*)targetArray)[arrayStep(dimensions, i)])
782 case OCREP_PROP_DOUBLE:
783 if (dimensions[1] == 0)
785 err = err || cbor_value_get_double(&insideArray,
786 &(((double*)targetArray)[i]));
790 err = err || OCParseArrayFillArray(&insideArray, newdim,
792 &(((double*)targetArray)[arrayStep(dimensions, i)])
796 case OCREP_PROP_BOOL:
797 if (dimensions[1] == 0)
799 err = err || cbor_value_get_boolean(&insideArray,
800 &(((bool*)targetArray)[i]));
804 err = err || OCParseArrayFillArray(&insideArray, newdim,
806 &(((bool*)targetArray)[arrayStep(dimensions, i)])
810 case OCREP_PROP_STRING:
811 if (dimensions[1] == 0)
813 err = err || cbor_value_dup_text_string(&insideArray,
814 &tempStr, &tempLen, NULL);
815 ((char**)targetArray)[i] = tempStr;
820 err = err || OCParseArrayFillArray(&insideArray, newdim,
822 &(((char**)targetArray)[arrayStep(dimensions, i)])
826 case OCREP_PROP_OBJECT:
827 if (dimensions[1] == 0)
829 err = err || OCParseSingleRepPayload(&tempPl, &insideArray);
830 ((OCRepPayload**)targetArray)[i] = tempPl;
835 err = err || OCParseArrayFillArray(&insideArray, newdim,
837 &(((OCRepPayload**)targetArray)[arrayStep(dimensions, i)])
842 OC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
848 err = err || cbor_value_advance(&insideArray);
854 static bool OCParseArray(OCRepPayload* out, const char* name, CborValue* container)
856 OCRepPayloadPropType type;
857 size_t dimensions[MAX_REP_ARRAY_DEPTH];
858 bool err = OCParseArrayFindDimensionsAndType(container, dimensions, &type);
862 OC_LOG(ERROR, TAG, "Array details weren't clear");
866 if (type == OCREP_PROP_NULL)
868 err = err || OCRepPayloadSetNull(out, name);
869 err = err || cbor_value_advance(container);
873 size_t dimTotal = calcDimTotal(dimensions);
874 size_t allocSize = getAllocSize(type);
875 void* arr = OICCalloc(dimTotal, allocSize);
879 OC_LOG(ERROR, TAG, "Array Parse allocation failed");
883 err = err || OCParseArrayFillArray(container, dimensions, type, arr);
888 if (err || !OCRepPayloadSetIntArrayAsOwner(out, name, (int64_t*)arr, dimensions))
894 case OCREP_PROP_DOUBLE:
895 if (err || !OCRepPayloadSetDoubleArrayAsOwner(out, name, (double*)arr, dimensions))
901 case OCREP_PROP_BOOL:
902 if (err || !OCRepPayloadSetBoolArrayAsOwner(out, name, (bool*)arr, dimensions))
908 case OCREP_PROP_STRING:
909 if (err || !OCRepPayloadSetStringArrayAsOwner(out, name, (char**)arr, dimensions))
911 for(size_t i = 0; i < dimTotal; ++i)
913 OICFree(((char**)arr)[i]);
919 case OCREP_PROP_OBJECT:
920 if (err || !OCRepPayloadSetPropObjectArrayAsOwner(out, name, (OCRepPayload**)arr, dimensions))
922 for(size_t i = 0; i < dimTotal; ++i)
924 OCRepPayloadDestroy(((OCRepPayload**)arr)[i]);
931 OC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
939 static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue* repParent)
946 *outPayload = OCRepPayloadCreate();
947 OCRepPayload* curPayload = *outPayload;
951 return CborErrorOutOfMemory;
956 err = err || cbor_value_map_find_value(repParent, OC_RSRVD_HREF, &curVal);
957 if(cbor_value_is_valid(&curVal))
959 err = err || cbor_value_dup_text_string(&curVal, &curPayload->uri, &len,
963 err = err || cbor_value_map_find_value(repParent, OC_RSRVD_PROPERTY, &curVal);
964 if(cbor_value_is_valid(&curVal))
966 CborValue insidePropArray = {0};
967 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_RESOURCE_TYPE,
970 if(cbor_value_is_array(&insidePropArray))
973 err = err || cbor_value_enter_container(&insidePropArray, &rtArray);
975 while(!err && cbor_value_is_valid(&rtArray))
978 err = err || cbor_value_dup_text_string(&rtArray, &curRt, &len, NULL);
979 err = err || cbor_value_advance(&rtArray);
980 OCRepPayloadAddResourceTypeAsOwner(curPayload, curRt);
983 err = err || cbor_value_leave_container(&insidePropArray, &rtArray);
986 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_INTERFACE, &insidePropArray);
988 if(cbor_value_is_array(&insidePropArray))
991 err = err || cbor_value_enter_container(&insidePropArray, &ifArray);
993 while(!err && cbor_value_is_valid(&ifArray))
996 err = err || cbor_value_dup_text_string(&ifArray, &curIf, &len, NULL);
997 err = err || cbor_value_advance(&ifArray);
998 OCRepPayloadAddInterfaceAsOwner(curPayload, curIf);
1001 err = err || cbor_value_leave_container(&insidePropArray, &ifArray);
1005 err = err || cbor_value_map_find_value(repParent, OC_RSRVD_REPRESENTATION, &curVal);
1006 if(cbor_value_is_map(&curVal))
1009 err = err || cbor_value_enter_container(&curVal, &repMap);
1011 while(!err && cbor_value_is_valid(&repMap))
1014 err = err || cbor_value_dup_text_string(&repMap, &name, &len, NULL);
1016 err = err || cbor_value_advance(&repMap);
1019 bool boolval = false;
1020 char* strval = NULL;
1021 double doubleval = 0;
1024 switch(cbor_value_get_type(&repMap))
1027 err = !OCRepPayloadSetNull(curPayload, name);
1029 case CborIntegerType:
1030 err = err || cbor_value_get_int64(&repMap, &intval);
1033 err = !OCRepPayloadSetPropInt(curPayload, name, intval);
1036 case CborDoubleType:
1037 err = err || cbor_value_get_double(&repMap, &doubleval);
1040 err = !OCRepPayloadSetPropDouble(curPayload, name, doubleval);
1043 case CborBooleanType:
1044 err = err || cbor_value_get_boolean(&repMap, &boolval);
1047 err = !OCRepPayloadSetPropBool(curPayload, name, boolval);
1050 case CborTextStringType:
1051 err = err || cbor_value_dup_text_string(&repMap, &strval, &len, NULL);
1054 err = !OCRepPayloadSetPropStringAsOwner(curPayload, name, strval);
1058 err = err || OCParseSingleRepPayload(&pl, &repMap);
1061 err = !OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl);
1065 err = err || OCParseArray(curPayload, name, &repMap);
1068 OC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type);
1072 err = err || cbor_value_advance(&repMap);
1075 err = err || cbor_value_leave_container(&curVal, &repMap);
1080 OCRepPayloadDestroy(*outPayload);
1086 static OCStackResult OCParseRepPayload(OCPayload** outPayload, CborValue* arrayVal)
1090 return OC_STACK_INVALID_PARAM;
1095 OCRepPayload* rootPayload = NULL;
1096 OCRepPayload* curPayload = NULL;
1097 OCRepPayload* temp = NULL;
1098 while(!err && cbor_value_is_map(arrayVal))
1100 err = err || OCParseSingleRepPayload(&temp, arrayVal);
1102 if(rootPayload == NULL)
1109 curPayload->next = temp;
1110 curPayload = curPayload->next;
1114 err = err || cbor_value_advance(arrayVal);
1117 OCRepPayloadDestroy(rootPayload);
1118 OC_LOG(ERROR, TAG, "CBOR error in ParseRepPayload");
1119 return OC_STACK_MALFORMED_RESPONSE;
1123 *outPayload = (OCPayload*)rootPayload;
1128 static OCStackResult OCParsePresencePayload(OCPayload** outPayload, CborValue* arrayVal)
1132 return OC_STACK_INVALID_PARAM;
1136 if(cbor_value_is_map(arrayVal))
1138 uint64_t seqNum = 0;
1139 uint64_t maxAge = 0;
1140 OCPresenceTrigger trigger = OC_PRESENCE_TRIGGER_CREATE;
1141 char* tempStr = NULL;
1146 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_NONCE, &curVal);
1147 err = err || cbor_value_get_uint64(&curVal, &seqNum);
1150 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_TTL, &curVal);
1151 err = err || cbor_value_get_uint64(&curVal, &maxAge);
1154 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_TRIGGER, &curVal);
1155 err = err || cbor_value_dup_text_string(&curVal, &tempStr, &len, NULL);
1156 trigger = convertTriggerStringToEnum(tempStr);
1160 // Resource type name
1161 err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_RESOURCE_TYPE, &curVal);
1162 if(cbor_value_is_valid(&curVal))
1164 err = err || cbor_value_dup_text_string(&curVal, &tempStr, &len, NULL);
1167 err = err || cbor_value_advance(arrayVal);
1171 *outPayload = (OCPayload*)OCPresencePayloadCreate(seqNum, maxAge, trigger, tempStr);
1177 OCPayloadDestroy(*outPayload);
1178 OC_LOG(ERROR, TAG, "CBOR error Parse Presence Payload");
1179 return OC_STACK_MALFORMED_RESPONSE;
1184 return OC_STACK_NO_MEMORY;
1191 OC_LOG(ERROR, TAG, "Root presence node was not a map");
1192 return OC_STACK_MALFORMED_RESPONSE;