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);
45 static OCStackResult OCParseRepPayload(OCPayload **outPayload, CborValue *arrayVal);
46 static OCStackResult OCParsePresencePayload(OCPayload **outPayload, CborValue *arrayVal);
47 static OCStackResult OCParseSecurityPayload(OCPayload **outPayload, CborValue * rrayVal);
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", payloadSize);
63 err = cbor_parser_init(payload, payloadSize, 0, &parser, &rootValue);
64 VERIFY_CBOR_SUCCESS(TAG, err, "Failed initializing init value")
68 case PAYLOAD_TYPE_DISCOVERY:
69 result = OCParseDiscoveryPayload(outPayload, &rootValue);
71 case PAYLOAD_TYPE_DEVICE:
72 result = OCParseDevicePayload(outPayload, &rootValue);
74 case PAYLOAD_TYPE_PLATFORM:
75 result = OCParsePlatformPayload(outPayload, &rootValue);
77 case PAYLOAD_TYPE_REPRESENTATION:
78 result = OCParseRepPayload(outPayload, &rootValue);
80 case PAYLOAD_TYPE_PRESENCE:
81 result = OCParsePresencePayload(outPayload, &rootValue);
83 case PAYLOAD_TYPE_SECURITY:
84 result = OCParseSecurityPayload(outPayload, &rootValue);
87 result = OCRDCborToPayload(&rootValue, outPayload);
90 OIC_LOG_V(ERROR, TAG, "ParsePayload Type default: %d", payloadType);
91 result = OC_STACK_INVALID_PARAM;
95 OIC_LOG_V(INFO, TAG, "Finished parse payload, result is %d", result);
101 void OCFreeOCStringLL(OCStringLL* ll);
103 static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* rootValue)
105 OCStackResult ret = OC_STACK_ERROR;
107 char *securityData = NULL;
110 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid parameter outPayload");
111 VERIFY_PARAM_NON_NULL(TAG, rootValue, "Invalid parameter rootValue");
114 err = cbor_value_enter_container(rootValue, &strVal);
115 VERIFY_CBOR_SUCCESS(TAG, err, "Failed entering container");
117 if (cbor_value_is_text_string(&strVal))
120 err = cbor_value_dup_text_string(&strVal, &securityData, &len, NULL);
121 VERIFY_CBOR_SUCCESS(TAG, err, "Failed reading security data");
122 *outPayload = (OCPayload *)OCSecurityPayloadCreate(securityData);
123 VERIFY_PARAM_NON_NULL(TAG, *outPayload, "Invalid cbor");
126 else if(cbor_value_is_valid(&strVal))
132 ret = OC_STACK_MALFORMED_RESPONSE;
136 OICFree(securityData);
141 static char* InPlaceStringTrim(char* str)
143 while (str[0] == ' ')
148 size_t lastchar = strlen(str);
150 while (str[lastchar] == ' ')
152 str[lastchar] = '\0';
159 static CborError OCParseStringLL(CborValue *map, char *type, OCStringLL **resource)
162 CborError err = cbor_value_map_find_value(map, type, &val);
163 VERIFY_CBOR_SUCCESS(TAG, err, "to find StringLL TAG");
165 if (cbor_value_is_text_string(&val))
168 char *savePtr = NULL;
171 err = cbor_value_dup_text_string(&val, &input, &len, NULL);
172 VERIFY_CBOR_SUCCESS(TAG, err, "to find StringLL value");
176 char *curPtr = strtok_r(input, " ", &savePtr);
179 char *trimmed = InPlaceStringTrim(curPtr);
180 if (trimmed[0] !='\0')
182 if (!OCResourcePayloadAddStringLL(resource, trimmed))
184 return CborErrorOutOfMemory;
187 curPtr = strtok_r(NULL, " ", &savePtr);
196 static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *rootValue)
198 OCStackResult ret = OC_STACK_INVALID_PARAM;
199 OCResourcePayload *resource = NULL;
200 OCDiscoveryPayload *out = NULL;
202 CborError err = CborNoError;
205 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
206 VERIFY_PARAM_NON_NULL(TAG, rootValue, "Invalid Parameter rootValue");
208 // Root value is already inside the main root array
210 ret = OC_STACK_NO_MEMORY;
211 out = OCDiscoveryPayloadCreate();
212 VERIFY_PARAM_NON_NULL(TAG, out, "Failed error initializing discovery payload");
214 // Enter the main root map
215 ret = OC_STACK_MALFORMED_RESPONSE;
216 err = cbor_value_enter_container(rootValue, &rootMap);
217 VERIFY_CBOR_SUCCESS(TAG, err, "to enter root map container");
221 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_DEVICE_ID, &curVal);
222 VERIFY_CBOR_SUCCESS(TAG, err, "to find device id tag");
224 err = cbor_value_dup_byte_string(&curVal, &(out->sid), &len, NULL);
225 VERIFY_CBOR_SUCCESS(TAG, err, "to copy device id value");
228 // BaseURI - Not a mandatory field
229 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_BASE_URI, &curVal);
230 if (cbor_value_is_valid(&curVal))
232 err = cbor_value_dup_text_string(&curVal, &(out->baseURI), &len, NULL);
233 VERIFY_CBOR_SUCCESS(TAG, err, "to find base uri value");
236 // Look for Links which will have an array as the value
238 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_LINKS, &linkMap);
239 VERIFY_CBOR_SUCCESS(TAG, err, "to find links tag");
241 // Enter the links array and start iterating through the array processing
242 // each resource which shows up as a map.
243 CborValue resourceMap;
244 err = cbor_value_enter_container(&linkMap, &resourceMap);
245 VERIFY_CBOR_SUCCESS(TAG, err, "to enter link map");
247 while (cbor_value_is_map(&resourceMap))
249 resource = (OCResourcePayload *)OICCalloc(1, sizeof(OCResourcePayload));
250 VERIFY_PARAM_NON_NULL(TAG, resource, "Failed allocating resource payload");
253 err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_HREF, &curVal);
254 VERIFY_CBOR_SUCCESS(TAG, err, "to find href tag");
255 err = cbor_value_dup_text_string(&curVal, &(resource->uri), &len, NULL);
256 VERIFY_CBOR_SUCCESS(TAG, err, "to find href value");
259 err = OCParseStringLL(&resourceMap, OC_RSRVD_RESOURCE_TYPE, &resource->types);
260 VERIFY_CBOR_SUCCESS(TAG, err, "to find resource type tag/value");
263 err = OCParseStringLL(&resourceMap, OC_RSRVD_INTERFACE, &resource->interfaces);
264 VERIFY_CBOR_SUCCESS(TAG, err, "to find interface tag/value");
268 err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_POLICY, &policyMap);
269 VERIFY_CBOR_SUCCESS(TAG, err, "to find policy tag");
272 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &curVal);
273 VERIFY_CBOR_SUCCESS(TAG, err, "to find bitmap tag");
274 err = cbor_value_get_int(&curVal, (int *)&resource->bitmap);
275 VERIFY_CBOR_SUCCESS(TAG, err, "to find bitmap value");
278 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &curVal);
279 if (cbor_value_is_valid(&curVal))
281 err = cbor_value_get_boolean(&curVal, &(resource->secure));
282 VERIFY_CBOR_SUCCESS(TAG, err, "to find secure value");
286 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT, &curVal);
287 if (cbor_value_is_valid(&curVal))
289 err = cbor_value_get_int(&curVal, (int *)&resource->port);
290 VERIFY_CBOR_SUCCESS(TAG, err, "to find port value");
293 err = cbor_value_advance(&resourceMap);
294 VERIFY_CBOR_SUCCESS(TAG, err, "to advance resource map");
296 OCDiscoveryPayloadAddNewResource(out, resource);
299 err = cbor_value_leave_container(rootValue, &resourceMap);
300 VERIFY_CBOR_SUCCESS(TAG, err, "to advance resource map");
302 *outPayload = (OCPayload *)out;
306 OCDiscoveryResourceDestroy(resource);
307 OCDiscoveryPayloadDestroy(out);
311 static OCStackResult OCParseDevicePayload(OCPayload **outPayload, CborValue *rootValue)
313 OCStackResult ret = OC_STACK_INVALID_PARAM;
314 CborError err = CborNoError;
315 OCDevicePayload *out = NULL;
316 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid param outPayload");
317 VERIFY_PARAM_NON_NULL(TAG, rootValue, "Invalid param rootValue");
321 out = (OCDevicePayload *)OICCalloc(1, sizeof(OCDevicePayload));
322 VERIFY_PARAM_NON_NULL(TAG, out, "Failed allocating device payload")
323 out->base.type = PAYLOAD_TYPE_DEVICE;
324 ret = OC_STACK_MALFORMED_RESPONSE;
326 if (cbor_value_is_map(rootValue))
331 err = cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_ID, &curVal);
332 if (cbor_value_is_valid(&curVal))
334 err = cbor_value_dup_byte_string(&curVal, &out->sid, &len, NULL);
335 VERIFY_CBOR_SUCCESS(TAG, err, "to find device id in device payload");
338 err = cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_NAME, &curVal);
339 if (cbor_value_is_valid(&curVal))
341 err = cbor_value_dup_text_string(&curVal, &out->deviceName, &len, NULL);
342 VERIFY_CBOR_SUCCESS(TAG, err, "to find device name in device payload");
344 // Device Spec Version
345 err = cbor_value_map_find_value(rootValue, OC_RSRVD_SPEC_VERSION, &curVal);
346 if (cbor_value_is_valid(&curVal))
348 err = cbor_value_dup_text_string(&curVal, &out->specVersion, &len, NULL);
349 VERIFY_CBOR_SUCCESS(TAG, err, "to find spec version in device payload");
351 // Data Model Version
352 err = cbor_value_map_find_value(rootValue, OC_RSRVD_DATA_MODEL_VERSION, &curVal);
353 if (cbor_value_is_valid(&curVal))
355 err = cbor_value_dup_text_string(&curVal, &out->dataModelVersion, &len, NULL);
356 VERIFY_CBOR_SUCCESS(TAG, err, "to find data model version in device payload");
358 err = cbor_value_advance(rootValue);
359 VERIFY_CBOR_SUCCESS(TAG, err, "to advance device payload");
361 *outPayload = (OCPayload *)out;
366 OCDevicePayloadDestroy(out);
370 static OCStackResult OCParsePlatformPayload(OCPayload **outPayload, CborValue *rootValue)
372 OCStackResult ret = OC_STACK_INVALID_PARAM;
373 CborError err = CborNoError;
374 OCPlatformInfo info = {0};
376 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
378 if (cbor_value_is_map(rootValue))
382 ret = OC_STACK_MALFORMED_RESPONSE;
385 err = cbor_value_map_find_value(rootValue, OC_RSRVD_PLATFORM_ID, &repVal);
386 if (cbor_value_is_valid(&repVal))
388 err = cbor_value_dup_text_string(&repVal, &(info.platformID), &len, NULL);
389 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find platformID in the platform payload");
392 err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_NAME, &repVal);
393 if (cbor_value_is_valid(&repVal))
395 err = cbor_value_dup_text_string(&repVal, &(info.manufacturerName), &len, NULL);
396 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find manufactureName in the platform payload");
399 err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_URL, &repVal);
400 if (cbor_value_is_valid(&repVal))
402 err = cbor_value_dup_text_string(&repVal, &(info.manufacturerUrl), &len, NULL);
403 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find manufactureUrl in the platform payload");
406 err = cbor_value_map_find_value(rootValue, OC_RSRVD_MODEL_NUM, &repVal);
407 if (cbor_value_is_valid(&repVal))
409 err = cbor_value_dup_text_string(&repVal, &(info.modelNumber), &len, NULL);
410 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find modelNumber in the platform payload");
413 err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_DATE, &repVal);
414 if (cbor_value_is_valid(&repVal))
416 err = cbor_value_dup_text_string(&repVal, &(info.dateOfManufacture), &len, NULL);
417 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find dateOfManufacture in the platform payload");
420 err = cbor_value_map_find_value(rootValue, OC_RSRVD_PLATFORM_VERSION, &repVal);
421 if (cbor_value_is_valid(&repVal))
423 err = cbor_value_dup_text_string(&repVal, &(info.platformVersion), &len, NULL);
424 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find platformVersion in the platform payload");
427 err = cbor_value_map_find_value(rootValue, OC_RSRVD_OS_VERSION, &repVal);
428 if (cbor_value_is_valid(&repVal))
430 err = cbor_value_dup_text_string(&repVal, &(info.operatingSystemVersion), &len, NULL);
431 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find OSVersion in the platform payload");
434 err = cbor_value_map_find_value(rootValue, OC_RSRVD_HARDWARE_VERSION, &repVal);
435 if(cbor_value_is_valid(&repVal))
437 err = cbor_value_dup_text_string(&repVal, &(info.hardwareVersion), &len, NULL);
438 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find HWVersion in the platform payload");
441 err = cbor_value_map_find_value(rootValue, OC_RSRVD_FIRMWARE_VERSION, &repVal);
442 if(cbor_value_is_valid(&repVal))
444 err = cbor_value_dup_text_string(&repVal, &(info.firmwareVersion), &len, NULL);
445 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find firmwareVersion in the platform payload");
448 err = cbor_value_map_find_value(rootValue, OC_RSRVD_SUPPORT_URL, &repVal);
449 if(cbor_value_is_valid(&repVal))
451 err = cbor_value_dup_text_string(&repVal, &(info.supportUrl), &len, NULL);
452 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find supportUrl in the platform payload");
455 err = cbor_value_map_find_value(rootValue, OC_RSRVD_SYSTEM_TIME, &repVal);
456 if(cbor_value_is_valid(&repVal))
458 err = cbor_value_dup_text_string(&repVal, &(info.systemTime), &len, NULL);
459 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find systemTume in the platform payload");
462 err = cbor_value_advance(rootValue);
463 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find supportUrl in the platform payload");
465 *outPayload = (OCPayload *)OCPlatformPayloadCreateAsOwner(&info);
470 OCPlatformInfoDestroy(&info);
471 OIC_LOG(ERROR, TAG, "CBOR error In ParsePlatformPayload");
475 static OCRepPayloadPropType DecodeCborType(CborType type)
480 return OCREP_PROP_NULL;
481 case CborIntegerType:
482 return OCREP_PROP_INT;
484 return OCREP_PROP_DOUBLE;
485 case CborBooleanType:
486 return OCREP_PROP_BOOL;
487 case CborTextStringType:
488 return OCREP_PROP_STRING;
489 case CborByteStringType:
490 return OCREP_PROP_BYTE_STRING;
492 return OCREP_PROP_OBJECT;
494 return OCREP_PROP_ARRAY;
496 return OCREP_PROP_NULL;
499 static CborError OCParseArrayFindDimensionsAndType(const CborValue *parent,
500 size_t dimensions[MAX_REP_ARRAY_DEPTH], OCRepPayloadPropType *type)
502 CborValue insideArray;
503 *type = OCREP_PROP_NULL;
504 dimensions[0] = dimensions[1] = dimensions[2] = 0;
506 CborError err = cbor_value_enter_container(parent, &insideArray);
507 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to enter container");
509 while (cbor_value_is_valid(&insideArray))
511 OCRepPayloadPropType tempType = DecodeCborType(cbor_value_get_type(&insideArray));
513 if (tempType == OCREP_PROP_ARRAY)
515 size_t subdim[MAX_REP_ARRAY_DEPTH];
516 tempType = OCREP_PROP_NULL;
517 err = OCParseArrayFindDimensionsAndType(&insideArray, subdim, &tempType);
518 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to parse array");
522 OIC_LOG(ERROR, TAG, "Parse array helper, sub-array too deep");
525 dimensions[1] = dimensions[1] >= subdim[0] ? dimensions[1] : subdim[0];
526 dimensions[2] = dimensions[2] >= subdim[1] ? dimensions[2] : subdim[1];
528 if (*type != OCREP_PROP_NULL && tempType != OCREP_PROP_NULL && *type != tempType)
530 OIC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed (subtype)");
531 return CborUnknownError;
533 else if (*type == OCREP_PROP_NULL)
535 // We don't know the type of this array yet, so the assignment is OK
539 else if (*type == OCREP_PROP_NULL)
541 // We don't know the type of this array yet, so the assignment is OK
544 // tempType is allowed to be NULL, since it might now know the answer yet
545 else if (tempType != OCREP_PROP_NULL && *type != tempType)
547 // this is an invalid situation!
548 OIC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed");
549 return CborUnknownError;
553 err = cbor_value_advance(&insideArray);
554 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to advance array");
561 static size_t getAllocSize(OCRepPayloadPropType type)
566 return sizeof (int64_t);
567 case OCREP_PROP_DOUBLE:
568 return sizeof (double);
569 case OCREP_PROP_BOOL:
570 return sizeof (bool);
571 case OCREP_PROP_STRING:
572 return sizeof (char*);
573 case OCREP_PROP_BYTE_STRING:
574 return sizeof (OCByteString);
575 case OCREP_PROP_OBJECT:
576 return sizeof (OCRepPayload*);
582 static size_t arrayStep(size_t dimensions[MAX_REP_ARRAY_DEPTH], size_t elementNum)
585 (dimensions[1] == 0 ? 1 : dimensions[1]) *
586 (dimensions[2] == 0 ? 1 : dimensions[2]) *
590 static CborError OCParseArrayFillArray(const CborValue *parent,
591 size_t dimensions[MAX_REP_ARRAY_DEPTH], OCRepPayloadPropType type, void *targetArray)
593 CborValue insideArray;
596 char *tempStr = NULL;
597 OCByteString ocByteStr = { .bytes = NULL, .len = 0};
599 OCRepPayload *tempPl = NULL;
601 size_t newdim[MAX_REP_ARRAY_DEPTH];
602 newdim[0] = dimensions[1];
603 newdim[1] = dimensions[2];
606 CborError err = cbor_value_enter_container(parent, &insideArray);
607 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to enter container");
609 while (!err && i < dimensions[0] && cbor_value_is_valid(&insideArray))
611 bool noAdvance = false;
612 if (cbor_value_get_type(&insideArray) != CborNullType)
617 if (dimensions[1] == 0)
619 err = cbor_value_get_int64(&insideArray, &(((int64_t*)targetArray)[i]));
623 err = OCParseArrayFillArray(&insideArray, newdim, type,
624 &(((int64_t*)targetArray)[arrayStep(dimensions, i)]));
627 case OCREP_PROP_DOUBLE:
628 if (dimensions[1] == 0)
630 err = cbor_value_get_double(&insideArray, &(((double*)targetArray)[i]));
634 err = OCParseArrayFillArray(&insideArray, newdim, type,
635 &(((double*)targetArray)[arrayStep(dimensions, i)]));
638 case OCREP_PROP_BOOL:
639 if (dimensions[1] == 0)
641 err = cbor_value_get_boolean(&insideArray, &(((bool*)targetArray)[i]));
645 err = OCParseArrayFillArray(&insideArray, newdim, type,
646 &(((bool*)targetArray)[arrayStep(dimensions, i)]));
649 case OCREP_PROP_STRING:
650 if (dimensions[1] == 0)
652 err = cbor_value_dup_text_string(&insideArray, &tempStr, &tempLen, NULL);
653 ((char**)targetArray)[i] = tempStr;
658 err = OCParseArrayFillArray(&insideArray, newdim, type,
659 &(((char**)targetArray)[arrayStep(dimensions, i)]));
662 case OCREP_PROP_BYTE_STRING:
663 if (dimensions[1] == 0)
665 err = cbor_value_dup_byte_string(&insideArray, &(ocByteStr.bytes),
666 &(ocByteStr.len), NULL);
667 ((OCByteString*)targetArray)[i] = ocByteStr;
671 err = OCParseArrayFillArray(&insideArray, newdim, type,
672 &(((OCByteString*)targetArray)[arrayStep(dimensions, i)]));
675 case OCREP_PROP_OBJECT:
676 if (dimensions[1] == 0)
678 err = OCParseSingleRepPayload(&tempPl, &insideArray);
679 ((OCRepPayload**)targetArray)[i] = tempPl;
685 err = OCParseArrayFillArray(&insideArray, newdim, type,
686 &(((OCRepPayload**)targetArray)[arrayStep(dimensions, i)]));
690 OIC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
691 err = CborErrorUnknownType;
694 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting repPayload");
697 if (!noAdvance && cbor_value_is_valid(&insideArray))
699 err = cbor_value_advance(&insideArray);
700 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advnce insideArray");
708 static CborError OCParseArray(OCRepPayload *out, const char *name, CborValue *container)
711 OCRepPayloadPropType type;
712 size_t dimensions[MAX_REP_ARRAY_DEPTH];
716 CborError err = OCParseArrayFindDimensionsAndType(container, dimensions, &type);
717 VERIFY_CBOR_SUCCESS(TAG, err, "Array details weren't clear");
719 if (type == OCREP_PROP_NULL)
721 res = OCRepPayloadSetNull(out, name);
722 err = (CborError) !res;
723 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting value");
724 err = cbor_value_advance(container);
725 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing container");
729 dimTotal = calcDimTotal(dimensions);
730 allocSize = getAllocSize(type);
731 arr = OICCalloc(dimTotal, allocSize);
732 VERIFY_PARAM_NON_NULL(TAG, arr, "Array Parse allocation failed");
734 res = OCParseArrayFillArray(container, dimensions, type, arr);
735 VERIFY_CBOR_SUCCESS(TAG, err, "Failed parse array");
740 res = OCRepPayloadSetIntArrayAsOwner(out, name, (int64_t *)arr, dimensions);
742 case OCREP_PROP_DOUBLE:
743 res = OCRepPayloadSetDoubleArrayAsOwner(out, name, (double *)arr, dimensions);
745 case OCREP_PROP_BOOL:
746 res = OCRepPayloadSetBoolArrayAsOwner(out, name, (bool *)arr, dimensions);
748 case OCREP_PROP_STRING:
749 res = OCRepPayloadSetStringArrayAsOwner(out, name, (char **)arr, dimensions);
751 case OCREP_PROP_BYTE_STRING:
752 res = OCRepPayloadSetByteStringArrayAsOwner(out, name, (OCByteString *)arr, dimensions);
754 case OCREP_PROP_OBJECT:
755 res = OCRepPayloadSetPropObjectArrayAsOwner(out, name, (OCRepPayload**)arr, dimensions);
758 OIC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
761 err = (CborError) !res;
762 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting array parameter");
765 if (type == OCREP_PROP_STRING)
767 for(size_t i = 0; i < dimTotal; ++i)
769 OICFree(((char**)arr)[i]);
772 if (type == OCREP_PROP_BYTE_STRING)
774 for(size_t i = 0; i < dimTotal; ++i)
776 OICFree(((OCByteString*)arr)[i].bytes);
779 if (type == OCREP_PROP_OBJECT)
781 for(size_t i = 0; i < dimTotal; ++i)
783 OCRepPayloadDestroy(((OCRepPayload**)arr)[i]);
790 static CborError OCParseSingleRepPayload(OCRepPayload **outPayload, CborValue *objMap)
792 CborError err = CborUnknownError;
795 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
796 VERIFY_PARAM_NON_NULL(TAG, objMap, "Invalid Parameter objMap");
798 if (cbor_value_is_map(objMap))
802 *outPayload = OCRepPayloadCreate();
805 return CborErrorOutOfMemory;
809 OCRepPayload *curPayload = *outPayload;
813 err = cbor_value_enter_container(objMap, &repMap);
814 VERIFY_CBOR_SUCCESS(TAG, err, "Failed entering repMap");
816 while (!err && cbor_value_is_valid(&repMap))
818 if (cbor_value_is_text_string(&repMap))
820 err = cbor_value_dup_text_string(&repMap, &name, &len, NULL);
821 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding tag name in the map");
822 err = cbor_value_advance(&repMap);
823 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing rootMap");
825 ((0 == strcmp(OC_RSRVD_HREF, name)) ||
826 (0 == strcmp(OC_RSRVD_RESOURCE_TYPE, name)) ||
827 (0 == strcmp(OC_RSRVD_INTERFACE, name))))
829 err = cbor_value_advance(&repMap);
834 CborType type = cbor_value_get_type(&repMap);
838 res = OCRepPayloadSetNull(curPayload, name);
840 case CborIntegerType:
843 err = cbor_value_get_int64(&repMap, &intval);
844 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting int value");
845 res = OCRepPayloadSetPropInt(curPayload, name, intval);
850 double doubleval = 0;
851 err = cbor_value_get_double(&repMap, &doubleval);
852 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting double value");
853 res = OCRepPayloadSetPropDouble(curPayload, name, doubleval);
856 case CborBooleanType:
858 bool boolval = false;
859 err = cbor_value_get_boolean(&repMap, &boolval);
860 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting boolean value");
861 res = OCRepPayloadSetPropBool(curPayload, name, boolval);
864 case CborTextStringType:
867 err = cbor_value_dup_text_string(&repMap, &strval, &len, NULL);
868 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting string value");
869 res = OCRepPayloadSetPropStringAsOwner(curPayload, name, strval);
872 case CborByteStringType:
874 uint8_t* bytestrval = NULL;
875 err = cbor_value_dup_byte_string(&repMap, &bytestrval, &len, NULL);
876 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting byte string value");
877 OCByteString tmp = {.bytes = bytestrval, .len = len};
878 res = OCRepPayloadSetPropByteStringAsOwner(curPayload, name, &tmp);
883 OCRepPayload *pl = NULL;
884 err = OCParseSingleRepPayload(&pl, &repMap);
885 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting parse single rep");
886 res = OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl);
890 err = OCParseArray(curPayload, name, &repMap);
893 OIC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type);
896 if (type != CborArrayType)
898 err = (CborError) !res;
900 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting value");
902 if (type != CborMapType && cbor_value_is_valid(&repMap))
904 err = cbor_value_advance(&repMap);
905 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advance repMap");
910 if (cbor_value_is_container(objMap))
912 err = cbor_value_leave_container(objMap, &repMap);
913 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to leave container");
920 OCRepPayloadDestroy(*outPayload);
925 static OCStackResult OCParseRepPayload(OCPayload **outPayload, CborValue *root)
927 OCStackResult ret = OC_STACK_INVALID_PARAM;
929 OCRepPayload *temp = NULL;
930 OCRepPayload *rootPayload = NULL;
931 OCRepPayload *curPayload = NULL;
932 CborValue rootMap = *root;
933 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
934 VERIFY_PARAM_NON_NULL(TAG, root, "Invalid Parameter root");
938 if (cbor_value_is_array(root))
940 err = cbor_value_enter_container(root, &rootMap);
942 while (cbor_value_is_valid(&rootMap))
944 temp = OCRepPayloadCreate();
945 ret = OC_STACK_NO_MEMORY;
946 VERIFY_PARAM_NON_NULL(TAG, temp, "Failed allocating memory");
949 ret = OC_STACK_MALFORMED_RESPONSE;
951 if (cbor_value_is_map(&rootMap))
953 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_HREF, &curVal);
954 if (cbor_value_is_valid(&curVal))
957 err = cbor_value_dup_text_string(&curVal, &temp->uri, &len, NULL);
958 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find uri");
962 if (cbor_value_is_map(&rootMap))
964 if (CborNoError == cbor_value_map_find_value(&rootMap, OC_RSRVD_RESOURCE_TYPE, &curVal))
966 err = OCParseStringLL(&rootMap, OC_RSRVD_RESOURCE_TYPE, &temp->types);
967 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find rt type tag/value");
972 if (cbor_value_is_map(&rootMap))
974 if (CborNoError == cbor_value_map_find_value(&rootMap, OC_RSRVD_INTERFACE, &curVal))
976 err = OCParseStringLL(&rootMap, OC_RSRVD_INTERFACE, &temp->interfaces);
977 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find interfaces tag/value");
981 if (cbor_value_is_map(&rootMap))
983 err = OCParseSingleRepPayload(&temp, &rootMap);
984 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to parse single rep payload");
986 if(rootPayload == NULL)
993 curPayload->next = temp;
994 curPayload = curPayload->next;
997 if (cbor_value_is_array(&rootMap))
999 err = cbor_value_advance(&rootMap);
1000 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to advance single rep payload");
1003 *outPayload = (OCPayload *)rootPayload;
1007 OCRepPayloadDestroy(temp);
1008 OCRepPayloadDestroy(rootPayload);
1009 OIC_LOG(ERROR, TAG, "CBOR error in ParseRepPayload");
1013 static OCStackResult OCParsePresencePayload(OCPayload **outPayload, CborValue *rootValue)
1015 OCStackResult ret = OC_STACK_INVALID_PARAM;
1016 OCPresencePayload *payload = NULL;
1017 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
1021 payload = (OCPresencePayload *)OICCalloc(1, sizeof(OCPresencePayload));
1022 ret = OC_STACK_NO_MEMORY;
1023 VERIFY_PARAM_NON_NULL(TAG, payload, "Failed allocating presence payload");
1024 payload->base.type = PAYLOAD_TYPE_PRESENCE;
1025 ret = OC_STACK_MALFORMED_RESPONSE;
1027 if (cbor_value_is_map(rootValue))
1032 CborError err = cbor_value_map_find_value(rootValue, OC_RSRVD_NONCE, &curVal);
1033 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding nonce tag");
1034 err = cbor_value_get_uint64(&curVal, (uint64_t *)&payload->sequenceNumber);
1035 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding nonce value");
1038 err = cbor_value_map_find_value(rootValue, OC_RSRVD_TTL, &curVal);
1039 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding ttl tag");
1040 err = cbor_value_get_uint64(&curVal, (uint64_t *)&payload->maxAge);
1041 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding ttl value");
1044 err = cbor_value_map_find_value(rootValue, OC_RSRVD_TRIGGER, &curVal);
1045 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding trigger tag");
1046 err = cbor_value_get_simple_type(&curVal, (uint8_t *)&payload->trigger);
1047 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding trigger value");
1049 // Resource type name
1050 err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &curVal);
1051 if (cbor_value_is_valid(&curVal))
1054 err = cbor_value_dup_text_string(&curVal, &payload->resourceType, &len, NULL);
1055 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding resource type value");
1058 err = cbor_value_advance(rootValue);
1059 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing root value");
1061 *outPayload = (OCPayload *)payload;
1065 OIC_LOG(ERROR, TAG, "CBOR error Parse Presence Payload");
1066 OCPresencePayloadDestroy(payload);