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, 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);
140 static char* InPlaceStringTrim(char* str)
142 while (str[0] == ' ')
147 size_t lastchar = strlen(str);
149 while (str[lastchar] == ' ')
151 str[lastchar] = '\0';
158 static CborError OCParseStringLL(CborValue *map, char *type, OCStringLL **resource)
161 CborError err = cbor_value_map_find_value(map, type, &val);
162 VERIFY_CBOR_SUCCESS(TAG, err, "to find StringLL TAG");
164 if (cbor_value_is_text_string(&val))
167 char *savePtr = NULL;
170 err = cbor_value_dup_text_string(&val, &input, &len, NULL);
171 VERIFY_CBOR_SUCCESS(TAG, err, "to find StringLL value");
175 char *curPtr = strtok_r(input, " ", &savePtr);
178 char *trimmed = InPlaceStringTrim(curPtr);
179 if (trimmed[0] !='\0')
181 if (!OCResourcePayloadAddStringLL(resource, trimmed))
183 return CborErrorOutOfMemory;
186 curPtr = strtok_r(NULL, " ", &savePtr);
195 static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *rootValue)
197 OCStackResult ret = OC_STACK_INVALID_PARAM;
198 OCResourcePayload *resource = NULL;
199 OCDiscoveryPayload *out = NULL;
201 CborError err = CborNoError;
204 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
205 VERIFY_PARAM_NON_NULL(TAG, rootValue, "Invalid Parameter rootValue");
207 // Root value is already inside the main root array
209 ret = OC_STACK_NO_MEMORY;
210 out = OCDiscoveryPayloadCreate();
211 VERIFY_PARAM_NON_NULL(TAG, out, "Failed error initializing discovery payload");
213 // Enter the main root map
214 ret = OC_STACK_MALFORMED_RESPONSE;
215 err = cbor_value_enter_container(rootValue, &rootMap);
216 VERIFY_CBOR_SUCCESS(TAG, err, "to enter root map container");
220 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_DEVICE_ID, &curVal);
221 VERIFY_CBOR_SUCCESS(TAG, err, "to find device id tag");
222 if (cbor_value_is_valid(&curVal))
224 if (cbor_value_is_byte_string(&curVal))
226 err = cbor_value_dup_byte_string(&curVal, (uint8_t **)&(out->sid), &len, NULL);
227 VERIFY_CBOR_SUCCESS(TAG, err, "to copy device id value");
229 else if (cbor_value_is_text_string(&curVal))
231 err = cbor_value_dup_text_string(&curVal, &(out->sid), &len, NULL);
232 VERIFY_CBOR_SUCCESS(TAG, err, "to copy device id value");
236 // BaseURI - Not a mandatory field
237 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_BASE_URI, &curVal);
238 if (cbor_value_is_valid(&curVal))
240 err = cbor_value_dup_text_string(&curVal, &(out->baseURI), &len, NULL);
241 VERIFY_CBOR_SUCCESS(TAG, err, "to find base uri value");
244 // Look for Links which will have an array as the value
246 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_LINKS, &linkMap);
247 VERIFY_CBOR_SUCCESS(TAG, err, "to find links tag");
249 // Enter the links array and start iterating through the array processing
250 // each resource which shows up as a map.
251 CborValue resourceMap;
252 err = cbor_value_enter_container(&linkMap, &resourceMap);
253 VERIFY_CBOR_SUCCESS(TAG, err, "to enter link map");
255 while (cbor_value_is_map(&resourceMap))
257 resource = (OCResourcePayload *)OICCalloc(1, sizeof(OCResourcePayload));
258 VERIFY_PARAM_NON_NULL(TAG, resource, "Failed allocating resource payload");
261 err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_HREF, &curVal);
262 VERIFY_CBOR_SUCCESS(TAG, err, "to find href tag");
263 err = cbor_value_dup_text_string(&curVal, &(resource->uri), &len, NULL);
264 VERIFY_CBOR_SUCCESS(TAG, err, "to find href value");
267 err = OCParseStringLL(&resourceMap, OC_RSRVD_RESOURCE_TYPE, &resource->types);
268 VERIFY_CBOR_SUCCESS(TAG, err, "to find resource type tag/value");
271 err = OCParseStringLL(&resourceMap, OC_RSRVD_INTERFACE, &resource->interfaces);
272 VERIFY_CBOR_SUCCESS(TAG, err, "to find interface tag/value");
276 err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_POLICY, &policyMap);
277 VERIFY_CBOR_SUCCESS(TAG, err, "to find policy tag");
280 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &curVal);
281 VERIFY_CBOR_SUCCESS(TAG, err, "to find bitmap tag");
282 err = cbor_value_get_int(&curVal, (int *)&resource->bitmap);
283 VERIFY_CBOR_SUCCESS(TAG, err, "to find bitmap value");
286 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &curVal);
287 if (cbor_value_is_valid(&curVal))
289 err = cbor_value_get_boolean(&curVal, &(resource->secure));
290 VERIFY_CBOR_SUCCESS(TAG, err, "to find secure value");
294 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT, &curVal);
295 if (cbor_value_is_valid(&curVal))
297 err = cbor_value_get_int(&curVal, (int *)&resource->port);
298 VERIFY_CBOR_SUCCESS(TAG, err, "to find port value");
301 err = cbor_value_advance(&resourceMap);
302 VERIFY_CBOR_SUCCESS(TAG, err, "to advance resource map");
304 OCDiscoveryPayloadAddNewResource(out, resource);
307 err = cbor_value_leave_container(rootValue, &resourceMap);
308 VERIFY_CBOR_SUCCESS(TAG, err, "to advance resource map");
310 *outPayload = (OCPayload *)out;
314 OCDiscoveryResourceDestroy(resource);
315 OCDiscoveryPayloadDestroy(out);
319 static OCStackResult OCParseDevicePayload(OCPayload **outPayload, CborValue *rootValue)
321 OCStackResult ret = OC_STACK_INVALID_PARAM;
322 CborError err = CborNoError;
323 OCDevicePayload *out = NULL;
324 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid param outPayload");
325 VERIFY_PARAM_NON_NULL(TAG, rootValue, "Invalid param rootValue");
329 out = (OCDevicePayload *)OICCalloc(1, sizeof(OCDevicePayload));
330 VERIFY_PARAM_NON_NULL(TAG, out, "Failed allocating device payload")
331 out->base.type = PAYLOAD_TYPE_DEVICE;
332 ret = OC_STACK_MALFORMED_RESPONSE;
334 if (cbor_value_is_map(rootValue))
339 err = cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_ID, &curVal);
340 if (cbor_value_is_valid(&curVal))
342 if (cbor_value_is_byte_string(&curVal))
344 err = cbor_value_dup_byte_string(&curVal, (uint8_t **)&out->sid, &len, NULL);
345 VERIFY_CBOR_SUCCESS(TAG, err, "to find device id in device payload");
347 else if (cbor_value_is_text_string(&curVal))
349 err = cbor_value_dup_text_string(&curVal, &out->sid, &len, NULL);
350 VERIFY_CBOR_SUCCESS(TAG, err, "to find device id in device payload");
354 err = cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_NAME, &curVal);
355 if (cbor_value_is_valid(&curVal))
357 err = cbor_value_dup_text_string(&curVal, &out->deviceName, &len, NULL);
358 VERIFY_CBOR_SUCCESS(TAG, err, "to find device name in device payload");
360 // Device Spec Version
361 err = cbor_value_map_find_value(rootValue, OC_RSRVD_SPEC_VERSION, &curVal);
362 if (cbor_value_is_valid(&curVal))
364 err = cbor_value_dup_text_string(&curVal, &out->specVersion, &len, NULL);
365 VERIFY_CBOR_SUCCESS(TAG, err, "to find spec version in device payload");
367 // Data Model Version
368 err = cbor_value_map_find_value(rootValue, OC_RSRVD_DATA_MODEL_VERSION, &curVal);
369 if (cbor_value_is_valid(&curVal))
371 err = cbor_value_dup_text_string(&curVal, &out->dataModelVersion, &len, NULL);
372 VERIFY_CBOR_SUCCESS(TAG, err, "to find data model version in device payload");
374 err = cbor_value_advance(rootValue);
375 VERIFY_CBOR_SUCCESS(TAG, err, "to advance device payload");
377 *outPayload = (OCPayload *)out;
382 OCDevicePayloadDestroy(out);
386 static OCStackResult OCParsePlatformPayload(OCPayload **outPayload, CborValue *rootValue)
388 OCStackResult ret = OC_STACK_INVALID_PARAM;
389 CborError err = CborNoError;
390 OCPlatformInfo info = {0};
392 OCStringLL* interfaces = NULL;
393 OCPlatformPayload* out = NULL;
395 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
397 if (cbor_value_is_map(rootValue))
401 ret = OC_STACK_MALFORMED_RESPONSE;
404 err = cbor_value_map_find_value(rootValue, OC_RSRVD_PLATFORM_ID, &repVal);
405 if (cbor_value_is_valid(&repVal))
407 err = cbor_value_dup_text_string(&repVal, &(info.platformID), &len, NULL);
408 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find platformID in the platform payload");
411 err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_NAME, &repVal);
412 if (cbor_value_is_valid(&repVal))
414 err = cbor_value_dup_text_string(&repVal, &(info.manufacturerName), &len, NULL);
415 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find manufactureName in the platform payload");
418 err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_URL, &repVal);
419 if (cbor_value_is_valid(&repVal))
421 err = cbor_value_dup_text_string(&repVal, &(info.manufacturerUrl), &len, NULL);
422 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find manufactureUrl in the platform payload");
425 err = cbor_value_map_find_value(rootValue, OC_RSRVD_MODEL_NUM, &repVal);
426 if (cbor_value_is_valid(&repVal))
428 err = cbor_value_dup_text_string(&repVal, &(info.modelNumber), &len, NULL);
429 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find modelNumber in the platform payload");
432 err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_DATE, &repVal);
433 if (cbor_value_is_valid(&repVal))
435 err = cbor_value_dup_text_string(&repVal, &(info.dateOfManufacture), &len, NULL);
436 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find dateOfManufacture in the platform payload");
439 err = cbor_value_map_find_value(rootValue, OC_RSRVD_PLATFORM_VERSION, &repVal);
440 if (cbor_value_is_valid(&repVal))
442 err = cbor_value_dup_text_string(&repVal, &(info.platformVersion), &len, NULL);
443 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find platformVersion in the platform payload");
446 err = cbor_value_map_find_value(rootValue, OC_RSRVD_OS_VERSION, &repVal);
447 if (cbor_value_is_valid(&repVal))
449 err = cbor_value_dup_text_string(&repVal, &(info.operatingSystemVersion), &len, NULL);
450 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find OSVersion in the platform payload");
453 err = cbor_value_map_find_value(rootValue, OC_RSRVD_HARDWARE_VERSION, &repVal);
454 if(cbor_value_is_valid(&repVal))
456 err = cbor_value_dup_text_string(&repVal, &(info.hardwareVersion), &len, NULL);
457 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find HWVersion in the platform payload");
460 err = cbor_value_map_find_value(rootValue, OC_RSRVD_FIRMWARE_VERSION, &repVal);
461 if(cbor_value_is_valid(&repVal))
463 err = cbor_value_dup_text_string(&repVal, &(info.firmwareVersion), &len, NULL);
464 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find firmwareVersion in the platform payload");
467 err = cbor_value_map_find_value(rootValue, OC_RSRVD_SUPPORT_URL, &repVal);
468 if(cbor_value_is_valid(&repVal))
470 err = cbor_value_dup_text_string(&repVal, &(info.supportUrl), &len, NULL);
471 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find supportUrl in the platform payload");
474 err = cbor_value_map_find_value(rootValue, OC_RSRVD_SYSTEM_TIME, &repVal);
475 if(cbor_value_is_valid(&repVal))
477 err = cbor_value_dup_text_string(&repVal, &(info.systemTime), &len, NULL);
478 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find systemTume in the platform payload");
482 err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &repVal);
483 if(cbor_value_is_valid(&repVal))
485 err = cbor_value_dup_text_string(&repVal, &rt, &len, NULL);
486 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find resource type in the platform payload");
490 err = cbor_value_map_find_value(rootValue, OC_RSRVD_INTERFACE, &repVal);
491 if(cbor_value_is_valid(&repVal))
493 err = OCParseStringLL(rootValue, OC_RSRVD_INTERFACE, &interfaces);
494 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find interfaces tag/value");
497 err = cbor_value_advance(rootValue);
498 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find supportUrl in the platform payload");
500 out = (OCPlatformPayload *)OCPlatformPayloadCreateAsOwner(&info);
502 out->interfaces = interfaces;
503 *outPayload = (OCPayload *)out;
508 OCPlatformInfoDestroy(&info);
509 OIC_LOG(ERROR, TAG, "CBOR error In ParsePlatformPayload");
513 static OCRepPayloadPropType DecodeCborType(CborType type)
518 return OCREP_PROP_NULL;
519 case CborIntegerType:
520 return OCREP_PROP_INT;
522 return OCREP_PROP_DOUBLE;
523 case CborBooleanType:
524 return OCREP_PROP_BOOL;
525 case CborTextStringType:
526 return OCREP_PROP_STRING;
527 case CborByteStringType:
528 return OCREP_PROP_BYTE_STRING;
530 return OCREP_PROP_OBJECT;
532 return OCREP_PROP_ARRAY;
534 return OCREP_PROP_NULL;
537 static CborError OCParseArrayFindDimensionsAndType(const CborValue *parent,
538 size_t dimensions[MAX_REP_ARRAY_DEPTH], OCRepPayloadPropType *type)
540 CborValue insideArray;
541 *type = OCREP_PROP_NULL;
542 dimensions[0] = dimensions[1] = dimensions[2] = 0;
544 CborError err = cbor_value_enter_container(parent, &insideArray);
545 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to enter container");
547 while (cbor_value_is_valid(&insideArray))
549 OCRepPayloadPropType tempType = DecodeCborType(cbor_value_get_type(&insideArray));
551 if (tempType == OCREP_PROP_ARRAY)
553 size_t subdim[MAX_REP_ARRAY_DEPTH];
554 tempType = OCREP_PROP_NULL;
555 err = OCParseArrayFindDimensionsAndType(&insideArray, subdim, &tempType);
556 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to parse array");
560 OIC_LOG(ERROR, TAG, "Parse array helper, sub-array too deep");
563 dimensions[1] = dimensions[1] >= subdim[0] ? dimensions[1] : subdim[0];
564 dimensions[2] = dimensions[2] >= subdim[1] ? dimensions[2] : subdim[1];
566 if (*type != OCREP_PROP_NULL && tempType != OCREP_PROP_NULL && *type != tempType)
568 OIC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed (subtype)");
569 return CborUnknownError;
571 else if (*type == OCREP_PROP_NULL)
573 // We don't know the type of this array yet, so the assignment is OK
577 else if (*type == OCREP_PROP_NULL)
579 // We don't know the type of this array yet, so the assignment is OK
582 // tempType is allowed to be NULL, since it might now know the answer yet
583 else if (tempType != OCREP_PROP_NULL && *type != tempType)
585 // this is an invalid situation!
586 OIC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed");
587 return CborUnknownError;
591 err = cbor_value_advance(&insideArray);
592 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to advance array");
599 static size_t getAllocSize(OCRepPayloadPropType type)
604 return sizeof (int64_t);
605 case OCREP_PROP_DOUBLE:
606 return sizeof (double);
607 case OCREP_PROP_BOOL:
608 return sizeof (bool);
609 case OCREP_PROP_STRING:
610 return sizeof (char*);
611 case OCREP_PROP_BYTE_STRING:
612 return sizeof (OCByteString);
613 case OCREP_PROP_OBJECT:
614 return sizeof (OCRepPayload*);
620 static size_t arrayStep(size_t dimensions[MAX_REP_ARRAY_DEPTH], size_t elementNum)
623 (dimensions[1] == 0 ? 1 : dimensions[1]) *
624 (dimensions[2] == 0 ? 1 : dimensions[2]) *
628 static CborError OCParseArrayFillArray(const CborValue *parent,
629 size_t dimensions[MAX_REP_ARRAY_DEPTH], OCRepPayloadPropType type, void *targetArray)
631 CborValue insideArray;
634 char *tempStr = NULL;
635 OCByteString ocByteStr = { .bytes = NULL, .len = 0};
637 OCRepPayload *tempPl = NULL;
639 size_t newdim[MAX_REP_ARRAY_DEPTH];
640 newdim[0] = dimensions[1];
641 newdim[1] = dimensions[2];
644 CborError err = cbor_value_enter_container(parent, &insideArray);
645 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to enter container");
647 while (!err && i < dimensions[0] && cbor_value_is_valid(&insideArray))
649 bool noAdvance = false;
650 if (cbor_value_get_type(&insideArray) != CborNullType)
655 if (dimensions[1] == 0)
657 err = cbor_value_get_int64(&insideArray, &(((int64_t*)targetArray)[i]));
661 err = OCParseArrayFillArray(&insideArray, newdim, type,
662 &(((int64_t*)targetArray)[arrayStep(dimensions, i)]));
665 case OCREP_PROP_DOUBLE:
666 if (dimensions[1] == 0)
668 err = cbor_value_get_double(&insideArray, &(((double*)targetArray)[i]));
672 err = OCParseArrayFillArray(&insideArray, newdim, type,
673 &(((double*)targetArray)[arrayStep(dimensions, i)]));
676 case OCREP_PROP_BOOL:
677 if (dimensions[1] == 0)
679 err = cbor_value_get_boolean(&insideArray, &(((bool*)targetArray)[i]));
683 err = OCParseArrayFillArray(&insideArray, newdim, type,
684 &(((bool*)targetArray)[arrayStep(dimensions, i)]));
687 case OCREP_PROP_STRING:
688 if (dimensions[1] == 0)
690 err = cbor_value_dup_text_string(&insideArray, &tempStr, &tempLen, NULL);
691 ((char**)targetArray)[i] = tempStr;
696 err = OCParseArrayFillArray(&insideArray, newdim, type,
697 &(((char**)targetArray)[arrayStep(dimensions, i)]));
700 case OCREP_PROP_BYTE_STRING:
701 if (dimensions[1] == 0)
703 err = cbor_value_dup_byte_string(&insideArray, &(ocByteStr.bytes),
704 &(ocByteStr.len), NULL);
705 ((OCByteString*)targetArray)[i] = ocByteStr;
709 err = OCParseArrayFillArray(&insideArray, newdim, type,
710 &(((OCByteString*)targetArray)[arrayStep(dimensions, i)]));
713 case OCREP_PROP_OBJECT:
714 if (dimensions[1] == 0)
716 err = OCParseSingleRepPayload(&tempPl, &insideArray, false);
717 ((OCRepPayload**)targetArray)[i] = tempPl;
723 err = OCParseArrayFillArray(&insideArray, newdim, type,
724 &(((OCRepPayload**)targetArray)[arrayStep(dimensions, i)]));
728 OIC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
729 err = CborErrorUnknownType;
732 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting repPayload");
735 if (!noAdvance && cbor_value_is_valid(&insideArray))
737 err = cbor_value_advance(&insideArray);
738 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advnce insideArray");
746 static CborError OCParseArray(OCRepPayload *out, const char *name, CborValue *container)
749 OCRepPayloadPropType type;
750 size_t dimensions[MAX_REP_ARRAY_DEPTH];
754 CborError err = OCParseArrayFindDimensionsAndType(container, dimensions, &type);
755 VERIFY_CBOR_SUCCESS(TAG, err, "Array details weren't clear");
757 if (type == OCREP_PROP_NULL)
759 res = OCRepPayloadSetNull(out, name);
760 err = (CborError) !res;
761 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting value");
762 err = cbor_value_advance(container);
763 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing container");
767 dimTotal = calcDimTotal(dimensions);
768 allocSize = getAllocSize(type);
769 arr = OICCalloc(dimTotal, allocSize);
770 VERIFY_PARAM_NON_NULL(TAG, arr, "Array Parse allocation failed");
772 res = OCParseArrayFillArray(container, dimensions, type, arr);
773 VERIFY_CBOR_SUCCESS(TAG, err, "Failed parse array");
778 res = OCRepPayloadSetIntArrayAsOwner(out, name, (int64_t *)arr, dimensions);
780 case OCREP_PROP_DOUBLE:
781 res = OCRepPayloadSetDoubleArrayAsOwner(out, name, (double *)arr, dimensions);
783 case OCREP_PROP_BOOL:
784 res = OCRepPayloadSetBoolArrayAsOwner(out, name, (bool *)arr, dimensions);
786 case OCREP_PROP_STRING:
787 res = OCRepPayloadSetStringArrayAsOwner(out, name, (char **)arr, dimensions);
789 case OCREP_PROP_BYTE_STRING:
790 res = OCRepPayloadSetByteStringArrayAsOwner(out, name, (OCByteString *)arr, dimensions);
792 case OCREP_PROP_OBJECT:
793 res = OCRepPayloadSetPropObjectArrayAsOwner(out, name, (OCRepPayload**)arr, dimensions);
796 OIC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
799 err = (CborError) !res;
800 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting array parameter");
803 if (type == OCREP_PROP_STRING)
805 for(size_t i = 0; i < dimTotal; ++i)
807 OICFree(((char**)arr)[i]);
810 if (type == OCREP_PROP_BYTE_STRING)
812 for(size_t i = 0; i < dimTotal; ++i)
814 OICFree(((OCByteString*)arr)[i].bytes);
817 if (type == OCREP_PROP_OBJECT)
819 for(size_t i = 0; i < dimTotal; ++i)
821 OCRepPayloadDestroy(((OCRepPayload**)arr)[i]);
828 static CborError OCParseSingleRepPayload(OCRepPayload **outPayload, CborValue *objMap, bool isRoot)
830 CborError err = CborUnknownError;
833 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
834 VERIFY_PARAM_NON_NULL(TAG, objMap, "Invalid Parameter objMap");
836 if (cbor_value_is_map(objMap))
840 *outPayload = OCRepPayloadCreate();
843 return CborErrorOutOfMemory;
847 OCRepPayload *curPayload = *outPayload;
851 err = cbor_value_enter_container(objMap, &repMap);
852 VERIFY_CBOR_SUCCESS(TAG, err, "Failed entering repMap");
854 while (!err && cbor_value_is_valid(&repMap))
856 if (cbor_value_is_text_string(&repMap))
858 err = cbor_value_dup_text_string(&repMap, &name, &len, NULL);
859 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding tag name in the map");
860 err = cbor_value_advance(&repMap);
861 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing rootMap");
864 ((0 == strcmp(OC_RSRVD_HREF, name)) ||
865 (0 == strcmp(OC_RSRVD_RESOURCE_TYPE, name)) ||
866 (0 == strcmp(OC_RSRVD_INTERFACE, name))))
868 err = cbor_value_advance(&repMap);
873 CborType type = cbor_value_get_type(&repMap);
877 res = OCRepPayloadSetNull(curPayload, name);
879 case CborIntegerType:
882 err = cbor_value_get_int64(&repMap, &intval);
883 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting int value");
884 res = OCRepPayloadSetPropInt(curPayload, name, intval);
889 double doubleval = 0;
890 err = cbor_value_get_double(&repMap, &doubleval);
891 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting double value");
892 res = OCRepPayloadSetPropDouble(curPayload, name, doubleval);
895 case CborBooleanType:
897 bool boolval = false;
898 err = cbor_value_get_boolean(&repMap, &boolval);
899 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting boolean value");
900 res = OCRepPayloadSetPropBool(curPayload, name, boolval);
903 case CborTextStringType:
906 err = cbor_value_dup_text_string(&repMap, &strval, &len, NULL);
907 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting string value");
908 res = OCRepPayloadSetPropStringAsOwner(curPayload, name, strval);
911 case CborByteStringType:
913 uint8_t* bytestrval = NULL;
914 err = cbor_value_dup_byte_string(&repMap, &bytestrval, &len, NULL);
915 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting byte string value");
916 OCByteString tmp = {.bytes = bytestrval, .len = len};
917 res = OCRepPayloadSetPropByteStringAsOwner(curPayload, name, &tmp);
922 OCRepPayload *pl = NULL;
923 err = OCParseSingleRepPayload(&pl, &repMap, false);
924 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting parse single rep");
925 res = OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl);
929 err = OCParseArray(curPayload, name, &repMap);
932 OIC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type);
935 if (type != CborArrayType)
937 err = (CborError) !res;
939 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting value");
941 if (type != CborMapType && cbor_value_is_valid(&repMap))
943 err = cbor_value_advance(&repMap);
944 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advance repMap");
949 if (cbor_value_is_container(objMap))
951 err = cbor_value_leave_container(objMap, &repMap);
952 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to leave container");
959 OCRepPayloadDestroy(*outPayload);
964 static OCStackResult OCParseRepPayload(OCPayload **outPayload, CborValue *root)
966 OCStackResult ret = OC_STACK_INVALID_PARAM;
968 OCRepPayload *temp = NULL;
969 OCRepPayload *rootPayload = NULL;
970 OCRepPayload *curPayload = NULL;
971 CborValue rootMap = *root;
972 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
973 VERIFY_PARAM_NON_NULL(TAG, root, "Invalid Parameter root");
976 if (cbor_value_is_array(root))
978 err = cbor_value_enter_container(root, &rootMap);
980 while (cbor_value_is_valid(&rootMap))
982 temp = OCRepPayloadCreate();
983 ret = OC_STACK_NO_MEMORY;
984 VERIFY_PARAM_NON_NULL(TAG, temp, "Failed allocating memory");
987 ret = OC_STACK_MALFORMED_RESPONSE;
989 if (cbor_value_is_map(&rootMap))
991 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_HREF, &curVal);
992 if (cbor_value_is_valid(&curVal))
995 err = cbor_value_dup_text_string(&curVal, &temp->uri, &len, NULL);
996 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find uri");
1000 if (cbor_value_is_map(&rootMap))
1002 if (CborNoError == cbor_value_map_find_value(&rootMap, OC_RSRVD_RESOURCE_TYPE, &curVal))
1004 err = OCParseStringLL(&rootMap, OC_RSRVD_RESOURCE_TYPE, &temp->types);
1005 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find rt type tag/value");
1010 if (cbor_value_is_map(&rootMap))
1012 if (CborNoError == cbor_value_map_find_value(&rootMap, OC_RSRVD_INTERFACE, &curVal))
1014 err = OCParseStringLL(&rootMap, OC_RSRVD_INTERFACE, &temp->interfaces);
1015 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find interfaces tag/value");
1019 if (cbor_value_is_map(&rootMap))
1021 err = OCParseSingleRepPayload(&temp, &rootMap, true);
1022 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to parse single rep payload");
1024 if(rootPayload == NULL)
1031 curPayload->next = temp;
1032 curPayload = curPayload->next;
1035 if (cbor_value_is_array(&rootMap))
1037 err = cbor_value_advance(&rootMap);
1038 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to advance single rep payload");
1041 *outPayload = (OCPayload *)rootPayload;
1045 OCRepPayloadDestroy(temp);
1046 OCRepPayloadDestroy(rootPayload);
1047 OIC_LOG(ERROR, TAG, "CBOR error in ParseRepPayload");
1051 static OCStackResult OCParsePresencePayload(OCPayload **outPayload, CborValue *rootValue)
1053 OCStackResult ret = OC_STACK_INVALID_PARAM;
1054 OCPresencePayload *payload = NULL;
1055 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
1059 payload = (OCPresencePayload *)OICCalloc(1, sizeof(OCPresencePayload));
1060 ret = OC_STACK_NO_MEMORY;
1061 VERIFY_PARAM_NON_NULL(TAG, payload, "Failed allocating presence payload");
1062 payload->base.type = PAYLOAD_TYPE_PRESENCE;
1063 ret = OC_STACK_MALFORMED_RESPONSE;
1065 if (cbor_value_is_map(rootValue))
1070 CborError err = cbor_value_map_find_value(rootValue, OC_RSRVD_NONCE, &curVal);
1071 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding nonce tag");
1072 err = cbor_value_get_uint64(&curVal, (uint64_t *)&payload->sequenceNumber);
1073 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding nonce value");
1076 err = cbor_value_map_find_value(rootValue, OC_RSRVD_TTL, &curVal);
1077 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding ttl tag");
1078 err = cbor_value_get_uint64(&curVal, (uint64_t *)&payload->maxAge);
1079 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding ttl value");
1082 err = cbor_value_map_find_value(rootValue, OC_RSRVD_TRIGGER, &curVal);
1083 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding trigger tag");
1084 err = cbor_value_get_simple_type(&curVal, (uint8_t *)&payload->trigger);
1085 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding trigger value");
1087 // Resource type name
1088 err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &curVal);
1089 if (cbor_value_is_valid(&curVal))
1092 err = cbor_value_dup_text_string(&curVal, &payload->resourceType, &len, NULL);
1093 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding resource type value");
1096 err = cbor_value_advance(rootValue);
1097 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing root value");
1099 *outPayload = (OCPayload *)payload;
1103 OIC_LOG(ERROR, TAG, "CBOR error Parse Presence Payload");
1104 OCPresencePayloadDestroy(payload);