1 //******************************************************************
3 // Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 // Defining _POSIX_C_SOURCE macro with 200112L (or greater) as value
22 // causes header files to expose definitions
23 // corresponding to the POSIX.1-2001 base
24 // specification (excluding the XSI extension).
25 // For POSIX.1-2001 base specification,
26 // Refer http://pubs.opengroup.org/onlinepubs/009695399/
27 // Required for strok_r
28 #define _POSIX_C_SOURCE 200112L
31 #include "oic_string.h"
32 #include "oic_malloc.h"
33 #include "ocpayload.h"
34 #include "ocpayloadcbor.h"
35 #include "ocstackinternal.h"
36 #include "payload_logging.h"
37 #include "rdpayload.h"
39 #define TAG "OIC_RI_PAYLOADPARSE"
41 static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *arrayVal);
42 static OCStackResult OCParseDevicePayload(OCPayload **outPayload, CborValue *arrayVal);
43 static OCStackResult OCParsePlatformPayload(OCPayload **outPayload, CborValue *arrayVal);
44 static CborError OCParseSingleRepPayload(OCRepPayload **outPayload, CborValue *repParent, bool isRoot);
45 static OCStackResult OCParseRepPayload(OCPayload **outPayload, CborValue *arrayVal);
46 static OCStackResult OCParsePresencePayload(OCPayload **outPayload, CborValue *arrayVal);
47 static OCStackResult OCParseSecurityPayload(OCPayload **outPayload, const uint8_t *payload, size_t size);
49 OCStackResult OCParsePayload(OCPayload **outPayload, OCPayloadType payloadType,
50 const uint8_t *payload, size_t payloadSize)
52 OCStackResult result = OC_STACK_MALFORMED_RESPONSE;
55 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Conversion of outPayload failed");
56 VERIFY_PARAM_NON_NULL(TAG, payload, "Invalid cbor payload value");
58 OIC_LOG_V(INFO, TAG, "CBOR Parsing size: %zu of Payload Type: %d, Payload:",
59 payloadSize, payloadType);
60 OIC_LOG_BUFFER(DEBUG, TAG, payload, payloadSize);
65 err = cbor_parser_init(payload, payloadSize, 0, &parser, &rootValue);
66 VERIFY_CBOR_SUCCESS(TAG, err, "Failed initializing init value")
70 case PAYLOAD_TYPE_DISCOVERY:
71 result = OCParseDiscoveryPayload(outPayload, &rootValue);
73 case PAYLOAD_TYPE_DEVICE:
74 result = OCParseDevicePayload(outPayload, &rootValue);
76 case PAYLOAD_TYPE_PLATFORM:
77 result = OCParsePlatformPayload(outPayload, &rootValue);
79 case PAYLOAD_TYPE_REPRESENTATION:
80 result = OCParseRepPayload(outPayload, &rootValue);
82 case PAYLOAD_TYPE_PRESENCE:
83 result = OCParsePresencePayload(outPayload, &rootValue);
85 case PAYLOAD_TYPE_SECURITY:
86 result = OCParseSecurityPayload(outPayload, payload, payloadSize);
89 result = OCRDCborToPayload(&rootValue, outPayload);
92 OIC_LOG_V(ERROR, TAG, "ParsePayload Type default: %d", payloadType);
93 result = OC_STACK_INVALID_PARAM;
97 OIC_LOG_V(INFO, TAG, "Finished parse payload, result is %d", result);
103 void OCFreeOCStringLL(OCStringLL* ll);
105 static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, const uint8_t *payload,
110 *outPayload = (OCPayload *)OCSecurityPayloadCBORCreate(payload, size);
119 static char* InPlaceStringTrim(char* str)
121 while (str[0] == ' ')
126 size_t lastchar = strlen(str);
128 while (str[lastchar] == ' ')
130 str[lastchar] = '\0';
137 static CborError OCParseStringLL(CborValue *map, char *type, OCStringLL **resource)
140 CborError err = cbor_value_map_find_value(map, type, &val);
141 VERIFY_CBOR_SUCCESS(TAG, err, "to find StringLL TAG");
143 if (cbor_value_is_text_string(&val))
146 char *savePtr = NULL;
149 err = cbor_value_dup_text_string(&val, &input, &len, NULL);
150 VERIFY_CBOR_SUCCESS(TAG, err, "to find StringLL value");
154 char *curPtr = strtok_r(input, " ", &savePtr);
157 char *trimmed = InPlaceStringTrim(curPtr);
158 if (trimmed[0] !='\0')
160 if (!OCResourcePayloadAddStringLL(resource, trimmed))
162 return CborErrorOutOfMemory;
165 curPtr = strtok_r(NULL, " ", &savePtr);
174 static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *rootValue)
176 OCStackResult ret = OC_STACK_INVALID_PARAM;
177 OCResourcePayload *resource = NULL;
178 OCDiscoveryPayload *out = NULL;
180 CborError err = CborNoError;
183 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
184 VERIFY_PARAM_NON_NULL(TAG, rootValue, "Invalid Parameter rootValue");
186 // Root value is already inside the main root array
188 ret = OC_STACK_NO_MEMORY;
189 out = OCDiscoveryPayloadCreate();
190 VERIFY_PARAM_NON_NULL(TAG, out, "Failed error initializing discovery payload");
192 // Enter the main root map
193 ret = OC_STACK_MALFORMED_RESPONSE;
194 err = cbor_value_enter_container(rootValue, &rootMap);
195 VERIFY_CBOR_SUCCESS(TAG, err, "to enter root map container");
199 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_DEVICE_ID, &curVal);
200 VERIFY_CBOR_SUCCESS(TAG, err, "to find device id tag");
201 if (cbor_value_is_valid(&curVal))
203 if (cbor_value_is_byte_string(&curVal))
205 err = cbor_value_dup_byte_string(&curVal, (uint8_t **)&(out->sid), &len, NULL);
206 VERIFY_CBOR_SUCCESS(TAG, err, "to copy device id value");
208 else if (cbor_value_is_text_string(&curVal))
210 err = cbor_value_dup_text_string(&curVal, &(out->sid), &len, NULL);
211 VERIFY_CBOR_SUCCESS(TAG, err, "to copy device id value");
215 // BaseURI - Not a mandatory field
216 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_BASE_URI, &curVal);
217 if (cbor_value_is_valid(&curVal))
219 err = cbor_value_dup_text_string(&curVal, &(out->baseURI), &len, NULL);
220 VERIFY_CBOR_SUCCESS(TAG, err, "to find base uri value");
223 // Look for Links which will have an array as the value
225 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_LINKS, &linkMap);
226 VERIFY_CBOR_SUCCESS(TAG, err, "to find links tag");
228 // Enter the links array and start iterating through the array processing
229 // each resource which shows up as a map.
230 CborValue resourceMap;
231 err = cbor_value_enter_container(&linkMap, &resourceMap);
232 VERIFY_CBOR_SUCCESS(TAG, err, "to enter link map");
234 while (cbor_value_is_map(&resourceMap))
236 resource = (OCResourcePayload *)OICCalloc(1, sizeof(OCResourcePayload));
237 VERIFY_PARAM_NON_NULL(TAG, resource, "Failed allocating resource payload");
240 err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_HREF, &curVal);
241 VERIFY_CBOR_SUCCESS(TAG, err, "to find href tag");
242 err = cbor_value_dup_text_string(&curVal, &(resource->uri), &len, NULL);
243 VERIFY_CBOR_SUCCESS(TAG, err, "to find href value");
246 err = OCParseStringLL(&resourceMap, OC_RSRVD_RESOURCE_TYPE, &resource->types);
247 VERIFY_CBOR_SUCCESS(TAG, err, "to find resource type tag/value");
250 err = OCParseStringLL(&resourceMap, OC_RSRVD_INTERFACE, &resource->interfaces);
251 if (CborNoError != err)
253 if (!OCResourcePayloadAddStringLL(&resource->interfaces, OC_RSRVD_INTERFACE_LL))
255 err = CborErrorOutOfMemory;
261 err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_POLICY, &policyMap);
262 VERIFY_CBOR_SUCCESS(TAG, err, "to find policy tag");
265 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &curVal);
266 VERIFY_CBOR_SUCCESS(TAG, err, "to find bitmap tag");
267 err = cbor_value_get_int(&curVal, (int *)&resource->bitmap);
268 VERIFY_CBOR_SUCCESS(TAG, err, "to find bitmap value");
271 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &curVal);
272 if (cbor_value_is_valid(&curVal))
274 err = cbor_value_get_boolean(&curVal, &(resource->secure));
275 VERIFY_CBOR_SUCCESS(TAG, err, "to find secure value");
279 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT, &curVal);
280 if (cbor_value_is_valid(&curVal))
282 err = cbor_value_get_int(&curVal, (int *)&resource->port);
283 VERIFY_CBOR_SUCCESS(TAG, err, "to find port value");
286 err = cbor_value_advance(&resourceMap);
287 VERIFY_CBOR_SUCCESS(TAG, err, "to advance resource map");
289 OCDiscoveryPayloadAddNewResource(out, resource);
292 err = cbor_value_leave_container(rootValue, &resourceMap);
293 VERIFY_CBOR_SUCCESS(TAG, err, "to advance resource map");
295 *outPayload = (OCPayload *)out;
299 OCDiscoveryResourceDestroy(resource);
300 OCDiscoveryPayloadDestroy(out);
304 static OCStackResult OCParseDevicePayload(OCPayload **outPayload, CborValue *rootValue)
306 OCStackResult ret = OC_STACK_INVALID_PARAM;
307 CborError err = CborNoError;
308 OCDevicePayload *out = NULL;
309 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid param outPayload");
310 VERIFY_PARAM_NON_NULL(TAG, rootValue, "Invalid param rootValue");
314 out = (OCDevicePayload *)OICCalloc(1, sizeof(OCDevicePayload));
315 VERIFY_PARAM_NON_NULL(TAG, out, "Failed allocating device payload")
316 out->base.type = PAYLOAD_TYPE_DEVICE;
317 ret = OC_STACK_MALFORMED_RESPONSE;
319 if (cbor_value_is_map(rootValue))
323 err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &curVal);
324 if (cbor_value_is_valid(&curVal))
326 err = OCParseStringLL(rootValue, OC_RSRVD_RESOURCE_TYPE, &out->types);
327 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find rt type tag/value");
331 err = cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_ID, &curVal);
332 if (cbor_value_is_valid(&curVal))
334 if (cbor_value_is_byte_string(&curVal))
336 err = cbor_value_dup_byte_string(&curVal, (uint8_t **)&out->sid, &len, NULL);
337 VERIFY_CBOR_SUCCESS(TAG, err, "to find device id in device payload");
339 else if (cbor_value_is_text_string(&curVal))
341 err = cbor_value_dup_text_string(&curVal, &out->sid, &len, NULL);
342 VERIFY_CBOR_SUCCESS(TAG, err, "to find device id in device payload");
346 err = cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_NAME, &curVal);
347 if (cbor_value_is_valid(&curVal))
349 err = cbor_value_dup_text_string(&curVal, &out->deviceName, &len, NULL);
350 VERIFY_CBOR_SUCCESS(TAG, err, "to find device name in device payload");
352 // Device Spec Version
353 err = cbor_value_map_find_value(rootValue, OC_RSRVD_SPEC_VERSION, &curVal);
354 if (cbor_value_is_valid(&curVal))
356 err = cbor_value_dup_text_string(&curVal, &out->specVersion, &len, NULL);
357 VERIFY_CBOR_SUCCESS(TAG, err, "to find spec version in device payload");
359 // Data Model Version
360 err = cbor_value_map_find_value(rootValue, OC_RSRVD_DATA_MODEL_VERSION, &curVal);
361 if (cbor_value_is_valid(&curVal))
363 err = cbor_value_dup_text_string(&curVal, &out->dataModelVersion, &len, NULL);
364 VERIFY_CBOR_SUCCESS(TAG, err, "to find data model version in device payload");
366 err = cbor_value_advance(rootValue);
367 VERIFY_CBOR_SUCCESS(TAG, err, "to advance device payload");
369 *outPayload = (OCPayload *)out;
374 OCDevicePayloadDestroy(out);
378 static OCStackResult OCParsePlatformPayload(OCPayload **outPayload, CborValue *rootValue)
380 OCStackResult ret = OC_STACK_INVALID_PARAM;
381 CborError err = CborNoError;
382 OCPlatformInfo info = {0};
384 OCStringLL* interfaces = NULL;
385 OCPlatformPayload* out = NULL;
387 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
389 if (cbor_value_is_map(rootValue))
393 ret = OC_STACK_MALFORMED_RESPONSE;
396 err = cbor_value_map_find_value(rootValue, OC_RSRVD_PLATFORM_ID, &repVal);
397 if (cbor_value_is_valid(&repVal))
399 err = cbor_value_dup_text_string(&repVal, &(info.platformID), &len, NULL);
400 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find platformID in the platform payload");
403 err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_NAME, &repVal);
404 if (cbor_value_is_valid(&repVal))
406 err = cbor_value_dup_text_string(&repVal, &(info.manufacturerName), &len, NULL);
407 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find manufactureName in the platform payload");
410 err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_URL, &repVal);
411 if (cbor_value_is_valid(&repVal))
413 err = cbor_value_dup_text_string(&repVal, &(info.manufacturerUrl), &len, NULL);
414 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find manufactureUrl in the platform payload");
417 err = cbor_value_map_find_value(rootValue, OC_RSRVD_MODEL_NUM, &repVal);
418 if (cbor_value_is_valid(&repVal))
420 err = cbor_value_dup_text_string(&repVal, &(info.modelNumber), &len, NULL);
421 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find modelNumber in the platform payload");
424 err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_DATE, &repVal);
425 if (cbor_value_is_valid(&repVal))
427 err = cbor_value_dup_text_string(&repVal, &(info.dateOfManufacture), &len, NULL);
428 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find dateOfManufacture in the platform payload");
431 err = cbor_value_map_find_value(rootValue, OC_RSRVD_PLATFORM_VERSION, &repVal);
432 if (cbor_value_is_valid(&repVal))
434 err = cbor_value_dup_text_string(&repVal, &(info.platformVersion), &len, NULL);
435 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find platformVersion in the platform payload");
438 err = cbor_value_map_find_value(rootValue, OC_RSRVD_OS_VERSION, &repVal);
439 if (cbor_value_is_valid(&repVal))
441 err = cbor_value_dup_text_string(&repVal, &(info.operatingSystemVersion), &len, NULL);
442 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find OSVersion in the platform payload");
445 err = cbor_value_map_find_value(rootValue, OC_RSRVD_HARDWARE_VERSION, &repVal);
446 if(cbor_value_is_valid(&repVal))
448 err = cbor_value_dup_text_string(&repVal, &(info.hardwareVersion), &len, NULL);
449 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find HWVersion in the platform payload");
452 err = cbor_value_map_find_value(rootValue, OC_RSRVD_FIRMWARE_VERSION, &repVal);
453 if(cbor_value_is_valid(&repVal))
455 err = cbor_value_dup_text_string(&repVal, &(info.firmwareVersion), &len, NULL);
456 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find firmwareVersion in the platform payload");
459 err = cbor_value_map_find_value(rootValue, OC_RSRVD_SUPPORT_URL, &repVal);
460 if(cbor_value_is_valid(&repVal))
462 err = cbor_value_dup_text_string(&repVal, &(info.supportUrl), &len, NULL);
463 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find supportUrl in the platform payload");
466 err = cbor_value_map_find_value(rootValue, OC_RSRVD_SYSTEM_TIME, &repVal);
467 if(cbor_value_is_valid(&repVal))
469 err = cbor_value_dup_text_string(&repVal, &(info.systemTime), &len, NULL);
470 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find systemTume in the platform payload");
474 err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &repVal);
475 if(cbor_value_is_valid(&repVal))
477 err = cbor_value_dup_text_string(&repVal, &rt, &len, NULL);
478 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find resource type in the platform payload");
482 err = cbor_value_map_find_value(rootValue, OC_RSRVD_INTERFACE, &repVal);
483 if(cbor_value_is_valid(&repVal))
485 err = OCParseStringLL(rootValue, OC_RSRVD_INTERFACE, &interfaces);
486 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find interfaces tag/value");
489 err = cbor_value_advance(rootValue);
490 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find supportUrl in the platform payload");
492 out = (OCPlatformPayload *)OCPlatformPayloadCreateAsOwner(&info);
494 out->interfaces = interfaces;
495 *outPayload = (OCPayload *)out;
500 OCPlatformInfoDestroy(&info);
501 OIC_LOG(ERROR, TAG, "CBOR error In ParsePlatformPayload");
505 static OCRepPayloadPropType DecodeCborType(CborType type)
510 return OCREP_PROP_NULL;
511 case CborIntegerType:
512 return OCREP_PROP_INT;
515 return OCREP_PROP_DOUBLE;
516 case CborBooleanType:
517 return OCREP_PROP_BOOL;
518 case CborTextStringType:
519 return OCREP_PROP_STRING;
520 case CborByteStringType:
521 return OCREP_PROP_BYTE_STRING;
523 return OCREP_PROP_OBJECT;
525 return OCREP_PROP_ARRAY;
527 return OCREP_PROP_NULL;
530 static CborError OCParseArrayFindDimensionsAndType(const CborValue *parent,
531 size_t dimensions[MAX_REP_ARRAY_DEPTH], OCRepPayloadPropType *type)
533 CborValue insideArray;
534 *type = OCREP_PROP_NULL;
535 dimensions[0] = dimensions[1] = dimensions[2] = 0;
537 CborError err = cbor_value_enter_container(parent, &insideArray);
538 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to enter container");
540 while (cbor_value_is_valid(&insideArray))
542 OCRepPayloadPropType tempType = DecodeCborType(cbor_value_get_type(&insideArray));
544 if (tempType == OCREP_PROP_ARRAY)
546 size_t subdim[MAX_REP_ARRAY_DEPTH];
547 tempType = OCREP_PROP_NULL;
548 err = OCParseArrayFindDimensionsAndType(&insideArray, subdim, &tempType);
549 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to parse array");
553 OIC_LOG(ERROR, TAG, "Parse array helper, sub-array too deep");
556 dimensions[1] = dimensions[1] >= subdim[0] ? dimensions[1] : subdim[0];
557 dimensions[2] = dimensions[2] >= subdim[1] ? dimensions[2] : subdim[1];
559 if (*type != OCREP_PROP_NULL && tempType != OCREP_PROP_NULL && *type != tempType)
561 OIC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed (subtype)");
562 return CborUnknownError;
564 else if (*type == OCREP_PROP_NULL)
566 // We don't know the type of this array yet, so the assignment is OK
570 else if (*type == OCREP_PROP_NULL)
572 // We don't know the type of this array yet, so the assignment is OK
575 // tempType is allowed to be NULL, since it might now know the answer yet
576 else if (tempType != OCREP_PROP_NULL && *type != tempType)
578 // this is an invalid situation!
579 OIC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed");
580 return CborUnknownError;
584 err = cbor_value_advance(&insideArray);
585 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to advance array");
592 static size_t getAllocSize(OCRepPayloadPropType type)
597 return sizeof (int64_t);
598 case OCREP_PROP_DOUBLE:
599 return sizeof (double);
600 case OCREP_PROP_BOOL:
601 return sizeof (bool);
602 case OCREP_PROP_STRING:
603 return sizeof (char*);
604 case OCREP_PROP_BYTE_STRING:
605 return sizeof (OCByteString);
606 case OCREP_PROP_OBJECT:
607 return sizeof (OCRepPayload*);
613 static size_t arrayStep(size_t dimensions[MAX_REP_ARRAY_DEPTH], size_t elementNum)
616 (dimensions[1] == 0 ? 1 : dimensions[1]) *
617 (dimensions[2] == 0 ? 1 : dimensions[2]) *
621 static CborError OCParseArrayFillArray(const CborValue *parent,
622 size_t dimensions[MAX_REP_ARRAY_DEPTH], OCRepPayloadPropType type, void *targetArray)
624 CborValue insideArray;
627 char *tempStr = NULL;
628 OCByteString ocByteStr = { .bytes = NULL, .len = 0};
630 OCRepPayload *tempPl = NULL;
632 size_t newdim[MAX_REP_ARRAY_DEPTH];
633 newdim[0] = dimensions[1];
634 newdim[1] = dimensions[2];
637 CborError err = cbor_value_enter_container(parent, &insideArray);
638 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to enter container");
640 while (!err && i < dimensions[0] && cbor_value_is_valid(&insideArray))
642 bool noAdvance = false;
643 if (cbor_value_get_type(&insideArray) != CborNullType)
648 if (dimensions[1] == 0)
650 err = cbor_value_get_int64(&insideArray, &(((int64_t*)targetArray)[i]));
654 err = OCParseArrayFillArray(&insideArray, newdim, type,
655 &(((int64_t*)targetArray)[arrayStep(dimensions, i)]));
658 case OCREP_PROP_DOUBLE:
659 if (dimensions[1] == 0)
661 double *d = &(((double*)targetArray)[i]);
662 if (cbor_value_get_type(&insideArray) == CborDoubleType)
664 err = cbor_value_get_double(&insideArray, d);
670 err = cbor_value_get_float(&insideArray, &f);
677 err = OCParseArrayFillArray(&insideArray, newdim, type,
678 &(((double*)targetArray)[arrayStep(dimensions, i)]));
681 case OCREP_PROP_BOOL:
682 if (dimensions[1] == 0)
684 err = cbor_value_get_boolean(&insideArray, &(((bool*)targetArray)[i]));
688 err = OCParseArrayFillArray(&insideArray, newdim, type,
689 &(((bool*)targetArray)[arrayStep(dimensions, i)]));
692 case OCREP_PROP_STRING:
693 if (dimensions[1] == 0)
695 err = cbor_value_dup_text_string(&insideArray, &tempStr, &tempLen, NULL);
696 ((char**)targetArray)[i] = tempStr;
701 err = OCParseArrayFillArray(&insideArray, newdim, type,
702 &(((char**)targetArray)[arrayStep(dimensions, i)]));
705 case OCREP_PROP_BYTE_STRING:
706 if (dimensions[1] == 0)
708 err = cbor_value_dup_byte_string(&insideArray, &(ocByteStr.bytes),
709 &(ocByteStr.len), NULL);
710 ((OCByteString*)targetArray)[i] = ocByteStr;
714 err = OCParseArrayFillArray(&insideArray, newdim, type,
715 &(((OCByteString*)targetArray)[arrayStep(dimensions, i)]));
718 case OCREP_PROP_OBJECT:
719 if (dimensions[1] == 0)
721 err = OCParseSingleRepPayload(&tempPl, &insideArray, false);
722 ((OCRepPayload**)targetArray)[i] = tempPl;
728 err = OCParseArrayFillArray(&insideArray, newdim, type,
729 &(((OCRepPayload**)targetArray)[arrayStep(dimensions, i)]));
733 OIC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
734 err = CborErrorUnknownType;
737 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting repPayload");
740 if (!noAdvance && cbor_value_is_valid(&insideArray))
742 err = cbor_value_advance(&insideArray);
743 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advnce insideArray");
751 static CborError OCParseArray(OCRepPayload *out, const char *name, CborValue *container)
754 OCRepPayloadPropType type;
755 size_t dimensions[MAX_REP_ARRAY_DEPTH];
757 size_t allocSize = 0;
759 CborError err = OCParseArrayFindDimensionsAndType(container, dimensions, &type);
760 VERIFY_CBOR_SUCCESS(TAG, err, "Array details weren't clear");
762 if (type == OCREP_PROP_NULL)
764 res = OCRepPayloadSetNull(out, name);
765 err = (CborError) !res;
766 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting value");
767 err = cbor_value_advance(container);
768 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing container");
772 dimTotal = calcDimTotal(dimensions);
773 allocSize = getAllocSize(type);
774 arr = OICCalloc(dimTotal, allocSize);
775 VERIFY_PARAM_NON_NULL(TAG, arr, "Array Parse allocation failed");
777 res = OCParseArrayFillArray(container, dimensions, type, arr);
778 VERIFY_CBOR_SUCCESS(TAG, err, "Failed parse array");
783 res = OCRepPayloadSetIntArrayAsOwner(out, name, (int64_t *)arr, dimensions);
785 case OCREP_PROP_DOUBLE:
786 res = OCRepPayloadSetDoubleArrayAsOwner(out, name, (double *)arr, dimensions);
788 case OCREP_PROP_BOOL:
789 res = OCRepPayloadSetBoolArrayAsOwner(out, name, (bool *)arr, dimensions);
791 case OCREP_PROP_STRING:
792 res = OCRepPayloadSetStringArrayAsOwner(out, name, (char **)arr, dimensions);
794 case OCREP_PROP_BYTE_STRING:
795 res = OCRepPayloadSetByteStringArrayAsOwner(out, name, (OCByteString *)arr, dimensions);
797 case OCREP_PROP_OBJECT:
798 res = OCRepPayloadSetPropObjectArrayAsOwner(out, name, (OCRepPayload**)arr, dimensions);
801 OIC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
804 err = (CborError) !res;
805 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting array parameter");
808 if (type == OCREP_PROP_STRING)
810 for(size_t i = 0; i < dimTotal; ++i)
812 OICFree(((char**)arr)[i]);
815 if (type == OCREP_PROP_BYTE_STRING)
817 for(size_t i = 0; i < dimTotal; ++i)
819 OICFree(((OCByteString*)arr)[i].bytes);
822 if (type == OCREP_PROP_OBJECT)
824 for(size_t i = 0; i < dimTotal; ++i)
826 OCRepPayloadDestroy(((OCRepPayload**)arr)[i]);
833 static CborError OCParseSingleRepPayload(OCRepPayload **outPayload, CborValue *objMap, bool isRoot)
835 CborError err = CborUnknownError;
838 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
839 VERIFY_PARAM_NON_NULL(TAG, objMap, "Invalid Parameter objMap");
841 if (cbor_value_is_map(objMap))
845 *outPayload = OCRepPayloadCreate();
848 return CborErrorOutOfMemory;
852 OCRepPayload *curPayload = *outPayload;
856 err = cbor_value_enter_container(objMap, &repMap);
857 VERIFY_CBOR_SUCCESS(TAG, err, "Failed entering repMap");
859 while (!err && cbor_value_is_valid(&repMap))
861 if (cbor_value_is_text_string(&repMap))
863 err = cbor_value_dup_text_string(&repMap, &name, &len, NULL);
864 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding tag name in the map");
865 err = cbor_value_advance(&repMap);
866 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing rootMap");
869 ((0 == strcmp(OC_RSRVD_HREF, name)) ||
870 (0 == strcmp(OC_RSRVD_RESOURCE_TYPE, name)) ||
871 (0 == strcmp(OC_RSRVD_INTERFACE, name))))
873 err = cbor_value_advance(&repMap);
878 CborType type = cbor_value_get_type(&repMap);
882 res = OCRepPayloadSetNull(curPayload, name);
884 case CborIntegerType:
887 err = cbor_value_get_int64(&repMap, &intval);
888 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting int value");
889 res = OCRepPayloadSetPropInt(curPayload, name, intval);
894 double doubleval = 0;
895 err = cbor_value_get_double(&repMap, &doubleval);
896 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting double value");
897 res = OCRepPayloadSetPropDouble(curPayload, name, doubleval);
900 case CborBooleanType:
902 bool boolval = false;
903 err = cbor_value_get_boolean(&repMap, &boolval);
904 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting boolean value");
905 res = OCRepPayloadSetPropBool(curPayload, name, boolval);
908 case CborTextStringType:
911 err = cbor_value_dup_text_string(&repMap, &strval, &len, NULL);
912 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting string value");
913 res = OCRepPayloadSetPropStringAsOwner(curPayload, name, strval);
916 case CborByteStringType:
918 uint8_t* bytestrval = NULL;
919 err = cbor_value_dup_byte_string(&repMap, &bytestrval, &len, NULL);
920 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting byte string value");
921 OCByteString tmp = {.bytes = bytestrval, .len = len};
922 res = OCRepPayloadSetPropByteStringAsOwner(curPayload, name, &tmp);
927 OCRepPayload *pl = NULL;
928 err = OCParseSingleRepPayload(&pl, &repMap, false);
929 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting parse single rep");
930 res = OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl);
934 err = OCParseArray(curPayload, name, &repMap);
937 OIC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type);
940 if (type != CborArrayType)
942 err = (CborError) !res;
944 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting value");
946 if (type != CborMapType && cbor_value_is_valid(&repMap))
948 err = cbor_value_advance(&repMap);
949 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advance repMap");
954 if (cbor_value_is_container(objMap))
956 err = cbor_value_leave_container(objMap, &repMap);
957 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to leave container");
964 OCRepPayloadDestroy(*outPayload);
969 static OCStackResult OCParseRepPayload(OCPayload **outPayload, CborValue *root)
971 OCStackResult ret = OC_STACK_INVALID_PARAM;
973 OCRepPayload *temp = NULL;
974 OCRepPayload *rootPayload = NULL;
975 OCRepPayload *curPayload = NULL;
976 CborValue rootMap = *root;
977 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
978 VERIFY_PARAM_NON_NULL(TAG, root, "Invalid Parameter root");
981 if (cbor_value_is_array(root))
983 err = cbor_value_enter_container(root, &rootMap);
985 while (cbor_value_is_valid(&rootMap))
987 temp = OCRepPayloadCreate();
988 ret = OC_STACK_NO_MEMORY;
989 VERIFY_PARAM_NON_NULL(TAG, temp, "Failed allocating memory");
992 ret = OC_STACK_MALFORMED_RESPONSE;
994 if (cbor_value_is_map(&rootMap))
996 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_HREF, &curVal);
997 if (cbor_value_is_valid(&curVal))
1000 err = cbor_value_dup_text_string(&curVal, &temp->uri, &len, NULL);
1001 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find uri");
1005 if (cbor_value_is_map(&rootMap))
1007 if (CborNoError == cbor_value_map_find_value(&rootMap, OC_RSRVD_RESOURCE_TYPE, &curVal))
1009 err = OCParseStringLL(&rootMap, OC_RSRVD_RESOURCE_TYPE, &temp->types);
1010 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find rt type tag/value");
1015 if (cbor_value_is_map(&rootMap))
1017 if (CborNoError == cbor_value_map_find_value(&rootMap, OC_RSRVD_INTERFACE, &curVal))
1019 err = OCParseStringLL(&rootMap, OC_RSRVD_INTERFACE, &temp->interfaces);
1020 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find interfaces tag/value");
1024 if (cbor_value_is_map(&rootMap))
1026 err = OCParseSingleRepPayload(&temp, &rootMap, true);
1027 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to parse single rep payload");
1029 if(rootPayload == NULL)
1036 curPayload->next = temp;
1037 curPayload = curPayload->next;
1040 if (cbor_value_is_array(&rootMap))
1042 err = cbor_value_advance(&rootMap);
1043 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to advance single rep payload");
1046 *outPayload = (OCPayload *)rootPayload;
1050 OCRepPayloadDestroy(temp);
1051 OCRepPayloadDestroy(rootPayload);
1052 OIC_LOG(ERROR, TAG, "CBOR error in ParseRepPayload");
1056 static OCStackResult OCParsePresencePayload(OCPayload **outPayload, CborValue *rootValue)
1058 OCStackResult ret = OC_STACK_INVALID_PARAM;
1059 OCPresencePayload *payload = NULL;
1060 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
1064 payload = (OCPresencePayload *)OICCalloc(1, sizeof(OCPresencePayload));
1065 ret = OC_STACK_NO_MEMORY;
1066 VERIFY_PARAM_NON_NULL(TAG, payload, "Failed allocating presence payload");
1067 payload->base.type = PAYLOAD_TYPE_PRESENCE;
1068 ret = OC_STACK_MALFORMED_RESPONSE;
1070 if (cbor_value_is_map(rootValue))
1075 CborError err = cbor_value_map_find_value(rootValue, OC_RSRVD_NONCE, &curVal);
1076 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding nonce tag");
1077 err = cbor_value_get_uint64(&curVal, (uint64_t *)&payload->sequenceNumber);
1078 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding nonce value");
1081 err = cbor_value_map_find_value(rootValue, OC_RSRVD_TTL, &curVal);
1082 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding ttl tag");
1083 err = cbor_value_get_uint64(&curVal, (uint64_t *)&payload->maxAge);
1084 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding ttl value");
1087 err = cbor_value_map_find_value(rootValue, OC_RSRVD_TRIGGER, &curVal);
1088 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding trigger tag");
1089 err = cbor_value_get_simple_type(&curVal, (uint8_t *)&payload->trigger);
1090 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding trigger value");
1092 // Resource type name
1093 err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &curVal);
1094 if (cbor_value_is_valid(&curVal))
1097 err = cbor_value_dup_text_string(&curVal, &payload->resourceType, &len, NULL);
1098 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding resource type value");
1101 err = cbor_value_advance(rootValue);
1102 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing root value");
1104 *outPayload = (OCPayload *)payload;
1108 OIC_LOG(ERROR, TAG, "CBOR error Parse Presence Payload");
1109 OCPresencePayloadDestroy(payload);