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", 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, payload, payloadSize);
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, const uint8_t *payload,
108 *outPayload = (OCPayload *)OCSecurityPayloadCBORCreate(payload, size);
117 static char* InPlaceStringTrim(char* str)
119 while (str[0] == ' ')
124 size_t lastchar = strlen(str);
126 while (str[lastchar] == ' ')
128 str[lastchar] = '\0';
135 static CborError OCParseStringLL(CborValue *map, char *type, OCStringLL **resource)
138 CborError err = cbor_value_map_find_value(map, type, &val);
139 VERIFY_CBOR_SUCCESS(TAG, err, "to find StringLL TAG");
141 if (cbor_value_is_text_string(&val))
144 char *savePtr = NULL;
147 err = cbor_value_dup_text_string(&val, &input, &len, NULL);
148 VERIFY_CBOR_SUCCESS(TAG, err, "to find StringLL value");
152 char *curPtr = strtok_r(input, " ", &savePtr);
155 char *trimmed = InPlaceStringTrim(curPtr);
156 if (trimmed[0] !='\0')
158 if (!OCResourcePayloadAddStringLL(resource, trimmed))
160 return CborErrorOutOfMemory;
163 curPtr = strtok_r(NULL, " ", &savePtr);
172 static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *rootValue)
174 OCStackResult ret = OC_STACK_INVALID_PARAM;
175 OCResourcePayload *resource = NULL;
176 OCDiscoveryPayload *out = NULL;
178 CborError err = CborNoError;
181 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
182 VERIFY_PARAM_NON_NULL(TAG, rootValue, "Invalid Parameter rootValue");
184 // Root value is already inside the main root array
186 ret = OC_STACK_NO_MEMORY;
187 out = OCDiscoveryPayloadCreate();
188 VERIFY_PARAM_NON_NULL(TAG, out, "Failed error initializing discovery payload");
190 // Enter the main root map
191 ret = OC_STACK_MALFORMED_RESPONSE;
192 err = cbor_value_enter_container(rootValue, &rootMap);
193 VERIFY_CBOR_SUCCESS(TAG, err, "to enter root map container");
197 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_DEVICE_ID, &curVal);
198 VERIFY_CBOR_SUCCESS(TAG, err, "to find device id tag");
199 if (cbor_value_is_valid(&curVal))
201 if (cbor_value_is_byte_string(&curVal))
203 err = cbor_value_dup_byte_string(&curVal, (uint8_t **)&(out->sid), &len, NULL);
204 VERIFY_CBOR_SUCCESS(TAG, err, "to copy device id value");
206 else if (cbor_value_is_text_string(&curVal))
208 err = cbor_value_dup_text_string(&curVal, &(out->sid), &len, NULL);
209 VERIFY_CBOR_SUCCESS(TAG, err, "to copy device id value");
213 // BaseURI - Not a mandatory field
214 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_BASE_URI, &curVal);
215 if (cbor_value_is_valid(&curVal))
217 err = cbor_value_dup_text_string(&curVal, &(out->baseURI), &len, NULL);
218 VERIFY_CBOR_SUCCESS(TAG, err, "to find base uri value");
221 // Look for Links which will have an array as the value
223 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_LINKS, &linkMap);
224 VERIFY_CBOR_SUCCESS(TAG, err, "to find links tag");
226 // Enter the links array and start iterating through the array processing
227 // each resource which shows up as a map.
228 CborValue resourceMap;
229 err = cbor_value_enter_container(&linkMap, &resourceMap);
230 VERIFY_CBOR_SUCCESS(TAG, err, "to enter link map");
232 while (cbor_value_is_map(&resourceMap))
234 resource = (OCResourcePayload *)OICCalloc(1, sizeof(OCResourcePayload));
235 VERIFY_PARAM_NON_NULL(TAG, resource, "Failed allocating resource payload");
238 err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_HREF, &curVal);
239 VERIFY_CBOR_SUCCESS(TAG, err, "to find href tag");
240 err = cbor_value_dup_text_string(&curVal, &(resource->uri), &len, NULL);
241 VERIFY_CBOR_SUCCESS(TAG, err, "to find href value");
244 err = OCParseStringLL(&resourceMap, OC_RSRVD_RESOURCE_TYPE, &resource->types);
245 VERIFY_CBOR_SUCCESS(TAG, err, "to find resource type tag/value");
248 err = OCParseStringLL(&resourceMap, OC_RSRVD_INTERFACE, &resource->interfaces);
249 if (CborNoError != err)
251 if (!OCResourcePayloadAddStringLL(&resource->interfaces, OC_RSRVD_INTERFACE_LL))
253 err = CborErrorOutOfMemory;
259 err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_POLICY, &policyMap);
260 VERIFY_CBOR_SUCCESS(TAG, err, "to find policy tag");
263 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &curVal);
264 VERIFY_CBOR_SUCCESS(TAG, err, "to find bitmap tag");
265 err = cbor_value_get_int(&curVal, (int *)&resource->bitmap);
266 VERIFY_CBOR_SUCCESS(TAG, err, "to find bitmap value");
269 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &curVal);
270 if (cbor_value_is_valid(&curVal))
272 err = cbor_value_get_boolean(&curVal, &(resource->secure));
273 VERIFY_CBOR_SUCCESS(TAG, err, "to find secure value");
277 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT, &curVal);
278 if (cbor_value_is_valid(&curVal))
280 err = cbor_value_get_int(&curVal, (int *)&resource->port);
281 VERIFY_CBOR_SUCCESS(TAG, err, "to find port value");
284 err = cbor_value_advance(&resourceMap);
285 VERIFY_CBOR_SUCCESS(TAG, err, "to advance resource map");
287 OCDiscoveryPayloadAddNewResource(out, resource);
290 err = cbor_value_leave_container(rootValue, &resourceMap);
291 VERIFY_CBOR_SUCCESS(TAG, err, "to advance resource map");
293 *outPayload = (OCPayload *)out;
297 OCDiscoveryResourceDestroy(resource);
298 OCDiscoveryPayloadDestroy(out);
302 static OCStackResult OCParseDevicePayload(OCPayload **outPayload, CborValue *rootValue)
304 OCStackResult ret = OC_STACK_INVALID_PARAM;
305 CborError err = CborNoError;
306 OCDevicePayload *out = NULL;
307 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid param outPayload");
308 VERIFY_PARAM_NON_NULL(TAG, rootValue, "Invalid param rootValue");
312 out = (OCDevicePayload *)OICCalloc(1, sizeof(OCDevicePayload));
313 VERIFY_PARAM_NON_NULL(TAG, out, "Failed allocating device payload")
314 out->base.type = PAYLOAD_TYPE_DEVICE;
315 ret = OC_STACK_MALFORMED_RESPONSE;
317 if (cbor_value_is_map(rootValue))
321 err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &curVal);
322 if (cbor_value_is_valid(&curVal))
324 err = OCParseStringLL(rootValue, OC_RSRVD_RESOURCE_TYPE, &out->types);
325 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find rt type tag/value");
329 err = cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_ID, &curVal);
330 if (cbor_value_is_valid(&curVal))
332 if (cbor_value_is_byte_string(&curVal))
334 err = cbor_value_dup_byte_string(&curVal, (uint8_t **)&out->sid, &len, NULL);
335 VERIFY_CBOR_SUCCESS(TAG, err, "to find device id in device payload");
337 else if (cbor_value_is_text_string(&curVal))
339 err = cbor_value_dup_text_string(&curVal, &out->sid, &len, NULL);
340 VERIFY_CBOR_SUCCESS(TAG, err, "to find device id in device payload");
344 err = cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_NAME, &curVal);
345 if (cbor_value_is_valid(&curVal))
347 err = cbor_value_dup_text_string(&curVal, &out->deviceName, &len, NULL);
348 VERIFY_CBOR_SUCCESS(TAG, err, "to find device name in device payload");
350 // Device Spec Version
351 err = cbor_value_map_find_value(rootValue, OC_RSRVD_SPEC_VERSION, &curVal);
352 if (cbor_value_is_valid(&curVal))
354 err = cbor_value_dup_text_string(&curVal, &out->specVersion, &len, NULL);
355 VERIFY_CBOR_SUCCESS(TAG, err, "to find spec version in device payload");
357 // Data Model Version
358 err = cbor_value_map_find_value(rootValue, OC_RSRVD_DATA_MODEL_VERSION, &curVal);
359 if (cbor_value_is_valid(&curVal))
361 err = cbor_value_dup_text_string(&curVal, &out->dataModelVersion, &len, NULL);
362 VERIFY_CBOR_SUCCESS(TAG, err, "to find data model version in device payload");
364 err = cbor_value_advance(rootValue);
365 VERIFY_CBOR_SUCCESS(TAG, err, "to advance device payload");
367 *outPayload = (OCPayload *)out;
372 OCDevicePayloadDestroy(out);
376 static OCStackResult OCParsePlatformPayload(OCPayload **outPayload, CborValue *rootValue)
378 OCStackResult ret = OC_STACK_INVALID_PARAM;
379 CborError err = CborNoError;
380 OCPlatformInfo info = {0};
382 OCStringLL* interfaces = NULL;
383 OCPlatformPayload* out = NULL;
385 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
387 if (cbor_value_is_map(rootValue))
391 ret = OC_STACK_MALFORMED_RESPONSE;
394 err = cbor_value_map_find_value(rootValue, OC_RSRVD_PLATFORM_ID, &repVal);
395 if (cbor_value_is_valid(&repVal))
397 err = cbor_value_dup_text_string(&repVal, &(info.platformID), &len, NULL);
398 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find platformID in the platform payload");
401 err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_NAME, &repVal);
402 if (cbor_value_is_valid(&repVal))
404 err = cbor_value_dup_text_string(&repVal, &(info.manufacturerName), &len, NULL);
405 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find manufactureName in the platform payload");
408 err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_URL, &repVal);
409 if (cbor_value_is_valid(&repVal))
411 err = cbor_value_dup_text_string(&repVal, &(info.manufacturerUrl), &len, NULL);
412 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find manufactureUrl in the platform payload");
415 err = cbor_value_map_find_value(rootValue, OC_RSRVD_MODEL_NUM, &repVal);
416 if (cbor_value_is_valid(&repVal))
418 err = cbor_value_dup_text_string(&repVal, &(info.modelNumber), &len, NULL);
419 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find modelNumber in the platform payload");
422 err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_DATE, &repVal);
423 if (cbor_value_is_valid(&repVal))
425 err = cbor_value_dup_text_string(&repVal, &(info.dateOfManufacture), &len, NULL);
426 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find dateOfManufacture in the platform payload");
429 err = cbor_value_map_find_value(rootValue, OC_RSRVD_PLATFORM_VERSION, &repVal);
430 if (cbor_value_is_valid(&repVal))
432 err = cbor_value_dup_text_string(&repVal, &(info.platformVersion), &len, NULL);
433 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find platformVersion in the platform payload");
436 err = cbor_value_map_find_value(rootValue, OC_RSRVD_OS_VERSION, &repVal);
437 if (cbor_value_is_valid(&repVal))
439 err = cbor_value_dup_text_string(&repVal, &(info.operatingSystemVersion), &len, NULL);
440 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find OSVersion in the platform payload");
443 err = cbor_value_map_find_value(rootValue, OC_RSRVD_HARDWARE_VERSION, &repVal);
444 if(cbor_value_is_valid(&repVal))
446 err = cbor_value_dup_text_string(&repVal, &(info.hardwareVersion), &len, NULL);
447 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find HWVersion in the platform payload");
450 err = cbor_value_map_find_value(rootValue, OC_RSRVD_FIRMWARE_VERSION, &repVal);
451 if(cbor_value_is_valid(&repVal))
453 err = cbor_value_dup_text_string(&repVal, &(info.firmwareVersion), &len, NULL);
454 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find firmwareVersion in the platform payload");
457 err = cbor_value_map_find_value(rootValue, OC_RSRVD_SUPPORT_URL, &repVal);
458 if(cbor_value_is_valid(&repVal))
460 err = cbor_value_dup_text_string(&repVal, &(info.supportUrl), &len, NULL);
461 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find supportUrl in the platform payload");
464 err = cbor_value_map_find_value(rootValue, OC_RSRVD_SYSTEM_TIME, &repVal);
465 if(cbor_value_is_valid(&repVal))
467 err = cbor_value_dup_text_string(&repVal, &(info.systemTime), &len, NULL);
468 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find systemTume in the platform payload");
472 err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &repVal);
473 if(cbor_value_is_valid(&repVal))
475 err = cbor_value_dup_text_string(&repVal, &rt, &len, NULL);
476 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find resource type in the platform payload");
480 err = cbor_value_map_find_value(rootValue, OC_RSRVD_INTERFACE, &repVal);
481 if(cbor_value_is_valid(&repVal))
483 err = OCParseStringLL(rootValue, OC_RSRVD_INTERFACE, &interfaces);
484 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find interfaces tag/value");
487 err = cbor_value_advance(rootValue);
488 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find supportUrl in the platform payload");
490 out = (OCPlatformPayload *)OCPlatformPayloadCreateAsOwner(&info);
492 out->interfaces = interfaces;
493 *outPayload = (OCPayload *)out;
498 OCPlatformInfoDestroy(&info);
499 OIC_LOG(ERROR, TAG, "CBOR error In ParsePlatformPayload");
503 static OCRepPayloadPropType DecodeCborType(CborType type)
508 return OCREP_PROP_NULL;
509 case CborIntegerType:
510 return OCREP_PROP_INT;
513 return OCREP_PROP_DOUBLE;
514 case CborBooleanType:
515 return OCREP_PROP_BOOL;
516 case CborTextStringType:
517 return OCREP_PROP_STRING;
518 case CborByteStringType:
519 return OCREP_PROP_BYTE_STRING;
521 return OCREP_PROP_OBJECT;
523 return OCREP_PROP_ARRAY;
525 return OCREP_PROP_NULL;
528 static CborError OCParseArrayFindDimensionsAndType(const CborValue *parent,
529 size_t dimensions[MAX_REP_ARRAY_DEPTH], OCRepPayloadPropType *type)
531 CborValue insideArray;
532 *type = OCREP_PROP_NULL;
533 dimensions[0] = dimensions[1] = dimensions[2] = 0;
535 CborError err = cbor_value_enter_container(parent, &insideArray);
536 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to enter container");
538 while (cbor_value_is_valid(&insideArray))
540 OCRepPayloadPropType tempType = DecodeCborType(cbor_value_get_type(&insideArray));
542 if (tempType == OCREP_PROP_ARRAY)
544 size_t subdim[MAX_REP_ARRAY_DEPTH];
545 tempType = OCREP_PROP_NULL;
546 err = OCParseArrayFindDimensionsAndType(&insideArray, subdim, &tempType);
547 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to parse array");
551 OIC_LOG(ERROR, TAG, "Parse array helper, sub-array too deep");
554 dimensions[1] = dimensions[1] >= subdim[0] ? dimensions[1] : subdim[0];
555 dimensions[2] = dimensions[2] >= subdim[1] ? dimensions[2] : subdim[1];
557 if (*type != OCREP_PROP_NULL && tempType != OCREP_PROP_NULL && *type != tempType)
559 OIC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed (subtype)");
560 return CborUnknownError;
562 else if (*type == OCREP_PROP_NULL)
564 // We don't know the type of this array yet, so the assignment is OK
568 else if (*type == OCREP_PROP_NULL)
570 // We don't know the type of this array yet, so the assignment is OK
573 // tempType is allowed to be NULL, since it might now know the answer yet
574 else if (tempType != OCREP_PROP_NULL && *type != tempType)
576 // this is an invalid situation!
577 OIC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed");
578 return CborUnknownError;
582 err = cbor_value_advance(&insideArray);
583 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to advance array");
590 static size_t getAllocSize(OCRepPayloadPropType type)
595 return sizeof (int64_t);
596 case OCREP_PROP_DOUBLE:
597 return sizeof (double);
598 case OCREP_PROP_BOOL:
599 return sizeof (bool);
600 case OCREP_PROP_STRING:
601 return sizeof (char*);
602 case OCREP_PROP_BYTE_STRING:
603 return sizeof (OCByteString);
604 case OCREP_PROP_OBJECT:
605 return sizeof (OCRepPayload*);
611 static size_t arrayStep(size_t dimensions[MAX_REP_ARRAY_DEPTH], size_t elementNum)
614 (dimensions[1] == 0 ? 1 : dimensions[1]) *
615 (dimensions[2] == 0 ? 1 : dimensions[2]) *
619 static CborError OCParseArrayFillArray(const CborValue *parent,
620 size_t dimensions[MAX_REP_ARRAY_DEPTH], OCRepPayloadPropType type, void *targetArray)
622 CborValue insideArray;
625 char *tempStr = NULL;
626 OCByteString ocByteStr = { .bytes = NULL, .len = 0};
628 OCRepPayload *tempPl = NULL;
630 size_t newdim[MAX_REP_ARRAY_DEPTH];
631 newdim[0] = dimensions[1];
632 newdim[1] = dimensions[2];
635 CborError err = cbor_value_enter_container(parent, &insideArray);
636 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to enter container");
638 while (!err && i < dimensions[0] && cbor_value_is_valid(&insideArray))
640 bool noAdvance = false;
641 if (cbor_value_get_type(&insideArray) != CborNullType)
646 if (dimensions[1] == 0)
648 err = cbor_value_get_int64(&insideArray, &(((int64_t*)targetArray)[i]));
652 err = OCParseArrayFillArray(&insideArray, newdim, type,
653 &(((int64_t*)targetArray)[arrayStep(dimensions, i)]));
656 case OCREP_PROP_DOUBLE:
657 if (dimensions[1] == 0)
659 double *d = &(((double*)targetArray)[i]);
660 if (cbor_value_get_type(&insideArray) == CborDoubleType)
662 err = cbor_value_get_double(&insideArray, d);
668 err = cbor_value_get_float(&insideArray, &f);
675 err = OCParseArrayFillArray(&insideArray, newdim, type,
676 &(((double*)targetArray)[arrayStep(dimensions, i)]));
679 case OCREP_PROP_BOOL:
680 if (dimensions[1] == 0)
682 err = cbor_value_get_boolean(&insideArray, &(((bool*)targetArray)[i]));
686 err = OCParseArrayFillArray(&insideArray, newdim, type,
687 &(((bool*)targetArray)[arrayStep(dimensions, i)]));
690 case OCREP_PROP_STRING:
691 if (dimensions[1] == 0)
693 err = cbor_value_dup_text_string(&insideArray, &tempStr, &tempLen, NULL);
694 ((char**)targetArray)[i] = tempStr;
699 err = OCParseArrayFillArray(&insideArray, newdim, type,
700 &(((char**)targetArray)[arrayStep(dimensions, i)]));
703 case OCREP_PROP_BYTE_STRING:
704 if (dimensions[1] == 0)
706 err = cbor_value_dup_byte_string(&insideArray, &(ocByteStr.bytes),
707 &(ocByteStr.len), NULL);
708 ((OCByteString*)targetArray)[i] = ocByteStr;
712 err = OCParseArrayFillArray(&insideArray, newdim, type,
713 &(((OCByteString*)targetArray)[arrayStep(dimensions, i)]));
716 case OCREP_PROP_OBJECT:
717 if (dimensions[1] == 0)
719 err = OCParseSingleRepPayload(&tempPl, &insideArray, false);
720 ((OCRepPayload**)targetArray)[i] = tempPl;
726 err = OCParseArrayFillArray(&insideArray, newdim, type,
727 &(((OCRepPayload**)targetArray)[arrayStep(dimensions, i)]));
731 OIC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
732 err = CborErrorUnknownType;
735 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting repPayload");
738 if (!noAdvance && cbor_value_is_valid(&insideArray))
740 err = cbor_value_advance(&insideArray);
741 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advnce insideArray");
749 static CborError OCParseArray(OCRepPayload *out, const char *name, CborValue *container)
752 OCRepPayloadPropType type;
753 size_t dimensions[MAX_REP_ARRAY_DEPTH];
755 size_t allocSize = 0;
757 CborError err = OCParseArrayFindDimensionsAndType(container, dimensions, &type);
758 VERIFY_CBOR_SUCCESS(TAG, err, "Array details weren't clear");
760 if (type == OCREP_PROP_NULL)
762 res = OCRepPayloadSetNull(out, name);
763 err = (CborError) !res;
764 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting value");
765 err = cbor_value_advance(container);
766 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing container");
770 dimTotal = calcDimTotal(dimensions);
771 allocSize = getAllocSize(type);
772 arr = OICCalloc(dimTotal, allocSize);
773 VERIFY_PARAM_NON_NULL(TAG, arr, "Array Parse allocation failed");
775 res = OCParseArrayFillArray(container, dimensions, type, arr);
776 VERIFY_CBOR_SUCCESS(TAG, err, "Failed parse array");
781 res = OCRepPayloadSetIntArrayAsOwner(out, name, (int64_t *)arr, dimensions);
783 case OCREP_PROP_DOUBLE:
784 res = OCRepPayloadSetDoubleArrayAsOwner(out, name, (double *)arr, dimensions);
786 case OCREP_PROP_BOOL:
787 res = OCRepPayloadSetBoolArrayAsOwner(out, name, (bool *)arr, dimensions);
789 case OCREP_PROP_STRING:
790 res = OCRepPayloadSetStringArrayAsOwner(out, name, (char **)arr, dimensions);
792 case OCREP_PROP_BYTE_STRING:
793 res = OCRepPayloadSetByteStringArrayAsOwner(out, name, (OCByteString *)arr, dimensions);
795 case OCREP_PROP_OBJECT:
796 res = OCRepPayloadSetPropObjectArrayAsOwner(out, name, (OCRepPayload**)arr, dimensions);
799 OIC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
802 err = (CborError) !res;
803 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting array parameter");
806 if (type == OCREP_PROP_STRING)
808 for(size_t i = 0; i < dimTotal; ++i)
810 OICFree(((char**)arr)[i]);
813 if (type == OCREP_PROP_BYTE_STRING)
815 for(size_t i = 0; i < dimTotal; ++i)
817 OICFree(((OCByteString*)arr)[i].bytes);
820 if (type == OCREP_PROP_OBJECT)
822 for(size_t i = 0; i < dimTotal; ++i)
824 OCRepPayloadDestroy(((OCRepPayload**)arr)[i]);
831 static CborError OCParseSingleRepPayload(OCRepPayload **outPayload, CborValue *objMap, bool isRoot)
833 CborError err = CborUnknownError;
836 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
837 VERIFY_PARAM_NON_NULL(TAG, objMap, "Invalid Parameter objMap");
839 if (cbor_value_is_map(objMap))
843 *outPayload = OCRepPayloadCreate();
846 return CborErrorOutOfMemory;
850 OCRepPayload *curPayload = *outPayload;
854 err = cbor_value_enter_container(objMap, &repMap);
855 VERIFY_CBOR_SUCCESS(TAG, err, "Failed entering repMap");
857 while (!err && cbor_value_is_valid(&repMap))
859 if (cbor_value_is_text_string(&repMap))
861 err = cbor_value_dup_text_string(&repMap, &name, &len, NULL);
862 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding tag name in the map");
863 err = cbor_value_advance(&repMap);
864 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing rootMap");
867 ((0 == strcmp(OC_RSRVD_HREF, name)) ||
868 (0 == strcmp(OC_RSRVD_RESOURCE_TYPE, name)) ||
869 (0 == strcmp(OC_RSRVD_INTERFACE, name))))
871 err = cbor_value_advance(&repMap);
876 CborType type = cbor_value_get_type(&repMap);
880 res = OCRepPayloadSetNull(curPayload, name);
882 case CborIntegerType:
885 err = cbor_value_get_int64(&repMap, &intval);
886 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting int value");
887 res = OCRepPayloadSetPropInt(curPayload, name, intval);
892 double doubleval = 0;
893 err = cbor_value_get_double(&repMap, &doubleval);
894 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting double value");
895 res = OCRepPayloadSetPropDouble(curPayload, name, doubleval);
898 case CborBooleanType:
900 bool boolval = false;
901 err = cbor_value_get_boolean(&repMap, &boolval);
902 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting boolean value");
903 res = OCRepPayloadSetPropBool(curPayload, name, boolval);
906 case CborTextStringType:
909 err = cbor_value_dup_text_string(&repMap, &strval, &len, NULL);
910 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting string value");
911 res = OCRepPayloadSetPropStringAsOwner(curPayload, name, strval);
914 case CborByteStringType:
916 uint8_t* bytestrval = NULL;
917 err = cbor_value_dup_byte_string(&repMap, &bytestrval, &len, NULL);
918 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting byte string value");
919 OCByteString tmp = {.bytes = bytestrval, .len = len};
920 res = OCRepPayloadSetPropByteStringAsOwner(curPayload, name, &tmp);
925 OCRepPayload *pl = NULL;
926 err = OCParseSingleRepPayload(&pl, &repMap, false);
927 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting parse single rep");
928 res = OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl);
932 err = OCParseArray(curPayload, name, &repMap);
935 OIC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type);
938 if (type != CborArrayType)
940 err = (CborError) !res;
942 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting value");
944 if (type != CborMapType && cbor_value_is_valid(&repMap))
946 err = cbor_value_advance(&repMap);
947 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advance repMap");
952 if (cbor_value_is_container(objMap))
954 err = cbor_value_leave_container(objMap, &repMap);
955 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to leave container");
962 OCRepPayloadDestroy(*outPayload);
967 static OCStackResult OCParseRepPayload(OCPayload **outPayload, CborValue *root)
969 OCStackResult ret = OC_STACK_INVALID_PARAM;
971 OCRepPayload *temp = NULL;
972 OCRepPayload *rootPayload = NULL;
973 OCRepPayload *curPayload = NULL;
974 CborValue rootMap = *root;
975 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
976 VERIFY_PARAM_NON_NULL(TAG, root, "Invalid Parameter root");
979 if (cbor_value_is_array(root))
981 err = cbor_value_enter_container(root, &rootMap);
983 while (cbor_value_is_valid(&rootMap))
985 temp = OCRepPayloadCreate();
986 ret = OC_STACK_NO_MEMORY;
987 VERIFY_PARAM_NON_NULL(TAG, temp, "Failed allocating memory");
990 ret = OC_STACK_MALFORMED_RESPONSE;
992 if (cbor_value_is_map(&rootMap))
994 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_HREF, &curVal);
995 if (cbor_value_is_valid(&curVal))
998 err = cbor_value_dup_text_string(&curVal, &temp->uri, &len, NULL);
999 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find uri");
1003 if (cbor_value_is_map(&rootMap))
1005 if (CborNoError == cbor_value_map_find_value(&rootMap, OC_RSRVD_RESOURCE_TYPE, &curVal))
1007 err = OCParseStringLL(&rootMap, OC_RSRVD_RESOURCE_TYPE, &temp->types);
1008 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find rt type tag/value");
1013 if (cbor_value_is_map(&rootMap))
1015 if (CborNoError == cbor_value_map_find_value(&rootMap, OC_RSRVD_INTERFACE, &curVal))
1017 err = OCParseStringLL(&rootMap, OC_RSRVD_INTERFACE, &temp->interfaces);
1018 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find interfaces tag/value");
1022 if (cbor_value_is_map(&rootMap))
1024 err = OCParseSingleRepPayload(&temp, &rootMap, true);
1025 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to parse single rep payload");
1027 if(rootPayload == NULL)
1034 curPayload->next = temp;
1035 curPayload = curPayload->next;
1038 if (cbor_value_is_array(&rootMap))
1040 err = cbor_value_advance(&rootMap);
1041 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to advance single rep payload");
1044 *outPayload = (OCPayload *)rootPayload;
1048 OCRepPayloadDestroy(temp);
1049 OCRepPayloadDestroy(rootPayload);
1050 OIC_LOG(ERROR, TAG, "CBOR error in ParseRepPayload");
1054 static OCStackResult OCParsePresencePayload(OCPayload **outPayload, CborValue *rootValue)
1056 OCStackResult ret = OC_STACK_INVALID_PARAM;
1057 OCPresencePayload *payload = NULL;
1058 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
1062 payload = (OCPresencePayload *)OICCalloc(1, sizeof(OCPresencePayload));
1063 ret = OC_STACK_NO_MEMORY;
1064 VERIFY_PARAM_NON_NULL(TAG, payload, "Failed allocating presence payload");
1065 payload->base.type = PAYLOAD_TYPE_PRESENCE;
1066 ret = OC_STACK_MALFORMED_RESPONSE;
1068 if (cbor_value_is_map(rootValue))
1073 CborError err = cbor_value_map_find_value(rootValue, OC_RSRVD_NONCE, &curVal);
1074 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding nonce tag");
1075 err = cbor_value_get_uint64(&curVal, (uint64_t *)&payload->sequenceNumber);
1076 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding nonce value");
1079 err = cbor_value_map_find_value(rootValue, OC_RSRVD_TTL, &curVal);
1080 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding ttl tag");
1081 err = cbor_value_get_uint64(&curVal, (uint64_t *)&payload->maxAge);
1082 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding ttl value");
1085 err = cbor_value_map_find_value(rootValue, OC_RSRVD_TRIGGER, &curVal);
1086 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding trigger tag");
1087 err = cbor_value_get_simple_type(&curVal, (uint8_t *)&payload->trigger);
1088 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding trigger value");
1090 // Resource type name
1091 err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &curVal);
1092 if (cbor_value_is_valid(&curVal))
1095 err = cbor_value_dup_text_string(&curVal, &payload->resourceType, &len, NULL);
1096 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding resource type value");
1099 err = cbor_value_advance(rootValue);
1100 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing root value");
1102 *outPayload = (OCPayload *)payload;
1106 OIC_LOG(ERROR, TAG, "CBOR error Parse Presence Payload");
1107 OCPresencePayloadDestroy(payload);