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 *)OCSecurityPayloadCreate(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_array(&val))
146 err = cbor_value_enter_container(&val, &txtStr);
147 VERIFY_CBOR_SUCCESS(TAG, err, "to enter container");
148 while (cbor_value_is_text_string(&txtStr))
152 err = cbor_value_dup_text_string(&txtStr, &input, &len, NULL);
153 VERIFY_CBOR_SUCCESS(TAG, err, "to find StringLL value.");
156 char *savePtr = NULL;
157 char *curPtr = strtok_r(input, " ", &savePtr);
160 char *trimmed = InPlaceStringTrim(curPtr);
161 if (trimmed[0] !='\0')
163 if (!OCResourcePayloadAddStringLL(resource, trimmed))
165 return CborErrorOutOfMemory;
168 curPtr = strtok_r(NULL, " ", &savePtr);
172 if (cbor_value_is_text_string(&txtStr))
174 err = cbor_value_advance(&txtStr);
175 VERIFY_CBOR_SUCCESS(TAG, err, "to advance string value");
183 static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *rootValue)
185 OCStackResult ret = OC_STACK_INVALID_PARAM;
186 OCResourcePayload *resource = NULL;
187 OCDiscoveryPayload *out = NULL;
189 CborError err = CborNoError;
192 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
193 VERIFY_PARAM_NON_NULL(TAG, rootValue, "Invalid Parameter rootValue");
194 if (cbor_value_is_array(rootValue))
196 // Root value is already inside the main root array
198 ret = OC_STACK_NO_MEMORY;
199 out = OCDiscoveryPayloadCreate();
200 VERIFY_PARAM_NON_NULL(TAG, out, "Failed error initializing discovery payload");
202 // Enter the main root map
203 ret = OC_STACK_MALFORMED_RESPONSE;
204 err = cbor_value_enter_container(rootValue, &rootMap);
205 VERIFY_CBOR_SUCCESS(TAG, err, "to enter root map container");
209 if (!cbor_value_is_map(&rootMap))
211 OIC_LOG(ERROR, TAG, "Malformed packet!!");
214 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_DEVICE_ID, &curVal);
215 VERIFY_CBOR_SUCCESS(TAG, err, "to find device id tag");
216 if (cbor_value_is_valid(&curVal))
218 if (cbor_value_is_byte_string(&curVal))
220 err = cbor_value_dup_byte_string(&curVal, (uint8_t **)&(out->sid), &len, NULL);
221 VERIFY_CBOR_SUCCESS(TAG, err, "to copy device id value");
223 else if (cbor_value_is_text_string(&curVal))
225 err = cbor_value_dup_text_string(&curVal, &(out->sid), &len, NULL);
226 VERIFY_CBOR_SUCCESS(TAG, err, "to copy device id value");
230 // BaseURI - Not a mandatory field
231 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_BASE_URI, &curVal);
232 VERIFY_CBOR_SUCCESS(TAG, err, "to find uri tag");
233 if (cbor_value_is_valid(&curVal))
235 err = cbor_value_dup_text_string(&curVal, &(out->baseURI), &len, NULL);
236 VERIFY_CBOR_SUCCESS(TAG, err, "to find base uri value");
239 // HREF - Not a mandatory field
240 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_HREF, &curVal);
241 if (cbor_value_is_valid(&curVal))
243 err = cbor_value_dup_text_string(&curVal, &(out->uri), &len, NULL);
244 VERIFY_CBOR_SUCCESS(TAG, err, "to find uri value");
247 // RT - Not a mandatory field
248 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_RESOURCE_TYPE, &curVal);
249 if (cbor_value_is_valid(&curVal))
251 err = OCParseStringLL(&rootMap, OC_RSRVD_RESOURCE_TYPE, &out->type);
252 VERIFY_CBOR_SUCCESS(TAG, err, "to find base uri value");
255 // IF - Not a mandatory field
256 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_INTERFACE, &curVal);
257 if (cbor_value_is_valid(&curVal))
259 err = OCParseStringLL(&rootMap, OC_RSRVD_INTERFACE, &out->interface);
263 if (!OCResourcePayloadAddStringLL(&out->interface, OC_RSRVD_INTERFACE_LL))
265 err = CborErrorOutOfMemory;
269 // Name - Not a mandatory field
270 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_DEVICE_NAME, &curVal);
271 if (cbor_value_is_valid(&curVal))
273 err = cbor_value_dup_text_string(&curVal, &out->name, &len, NULL);
274 VERIFY_CBOR_SUCCESS(TAG, err, "to find device name");
277 // Look for Links which will have an array as the value
279 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_LINKS, &linkMap);
280 VERIFY_CBOR_SUCCESS(TAG, err, "to find links tag");
282 // Enter the links array and start iterating through the array processing
283 // each resource which shows up as a map.
284 CborValue resourceMap;
285 err = cbor_value_enter_container(&linkMap, &resourceMap);
286 VERIFY_CBOR_SUCCESS(TAG, err, "to enter link map");
288 while (cbor_value_is_map(&resourceMap))
290 resource = (OCResourcePayload *)OICCalloc(1, sizeof(OCResourcePayload));
291 VERIFY_PARAM_NON_NULL(TAG, resource, "Failed allocating resource payload");
294 err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_HREF, &curVal);
295 VERIFY_CBOR_SUCCESS(TAG, err, "to find href tag");
296 err = cbor_value_dup_text_string(&curVal, &(resource->uri), &len, NULL);
297 VERIFY_CBOR_SUCCESS(TAG, err, "to find href value");
300 err = OCParseStringLL(&resourceMap, OC_RSRVD_RESOURCE_TYPE, &resource->types);
301 VERIFY_CBOR_SUCCESS(TAG, err, "to find resource type tag/value");
304 err = OCParseStringLL(&resourceMap, OC_RSRVD_INTERFACE, &resource->interfaces);
305 if (CborNoError != err)
307 if (!OCResourcePayloadAddStringLL(&resource->interfaces, OC_RSRVD_INTERFACE_LL))
309 OIC_LOG(ERROR, TAG, "Failed to add string to StringLL");
316 err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_POLICY, &policyMap);
317 VERIFY_CBOR_SUCCESS(TAG, err, "to find policy tag");
320 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &curVal);
321 VERIFY_CBOR_SUCCESS(TAG, err, "to find bitmap tag");
322 err = cbor_value_get_int(&curVal, (int *)&resource->bitmap);
323 VERIFY_CBOR_SUCCESS(TAG, err, "to find bitmap value");
326 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &curVal);
327 VERIFY_CBOR_SUCCESS(TAG, err, "to find secure tag");
328 if (cbor_value_is_valid(&curVal))
330 err = cbor_value_get_boolean(&curVal, &(resource->secure));
331 VERIFY_CBOR_SUCCESS(TAG, err, "to find secure value");
335 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT, &curVal);
336 VERIFY_CBOR_SUCCESS(TAG, err, "to find port tag");
337 if (cbor_value_is_valid(&curVal))
339 err = cbor_value_get_int(&curVal, (int *)&resource->port);
340 VERIFY_CBOR_SUCCESS(TAG, err, "to find port value");
345 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_TCP_PORT, &curVal);
346 if (cbor_value_is_valid(&curVal))
348 err = cbor_value_get_int(&curVal, (int *)&resource->tcpPort);
349 VERIFY_CBOR_SUCCESS(TAG, err, "to find tcp port value");
353 err = cbor_value_advance(&resourceMap);
354 VERIFY_CBOR_SUCCESS(TAG, err, "to advance resource map");
356 OCDiscoveryPayloadAddNewResource(out, resource);
359 err = cbor_value_leave_container(rootValue, &resourceMap);
360 VERIFY_CBOR_SUCCESS(TAG, err, "to advance resource map");
364 OIC_LOG(ERROR, TAG, "Malformed packet ");
368 *outPayload = (OCPayload *)out;
369 OIC_LOG_PAYLOAD(DEBUG, *outPayload);
374 OCDiscoveryResourceDestroy(resource);
375 OCDiscoveryPayloadDestroy(out);
379 static OCStackResult OCParseDevicePayload(OCPayload **outPayload, CborValue *rootValue)
381 OCStackResult ret = OC_STACK_INVALID_PARAM;
382 CborError err = CborNoError;
383 OCDevicePayload *out = NULL;
384 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid param outPayload");
385 VERIFY_PARAM_NON_NULL(TAG, rootValue, "Invalid param rootValue");
389 out = (OCDevicePayload *)OICCalloc(1, sizeof(OCDevicePayload));
390 VERIFY_PARAM_NON_NULL(TAG, out, "Failed allocating device payload")
391 out->base.type = PAYLOAD_TYPE_DEVICE;
392 ret = OC_STACK_MALFORMED_RESPONSE;
394 if (cbor_value_is_map(rootValue))
398 err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &curVal);
399 VERIFY_CBOR_SUCCESS(TAG, err, "to find resource type tag");
401 if (cbor_value_is_valid(&curVal))
403 err = OCParseStringLL(rootValue, OC_RSRVD_RESOURCE_TYPE, &out->types);
404 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find rt type tag/value");
407 err = cbor_value_map_find_value(rootValue, OC_RSRVD_INTERFACE, &curVal);
408 VERIFY_CBOR_SUCCESS(TAG, err, "to find interface tag");
409 if (cbor_value_is_valid(&curVal))
411 err = OCParseStringLL(rootValue, OC_RSRVD_INTERFACE, &out->interfaces);
412 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find interfaces tag/value");
416 err = cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_ID, &curVal);
417 VERIFY_CBOR_SUCCESS(TAG, err, "to find device id tag");
418 if (cbor_value_is_valid(&curVal))
420 if (cbor_value_is_byte_string(&curVal))
422 err = cbor_value_dup_byte_string(&curVal, (uint8_t **)&out->sid, &len, NULL);
423 VERIFY_CBOR_SUCCESS(TAG, err, "to find device id in device payload");
425 else if (cbor_value_is_text_string(&curVal))
427 err = cbor_value_dup_text_string(&curVal, &out->sid, &len, NULL);
428 VERIFY_CBOR_SUCCESS(TAG, err, "to find device id in device payload");
432 err = cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_NAME, &curVal);
433 VERIFY_CBOR_SUCCESS(TAG, err, "to find device name tag");
434 if (cbor_value_is_valid(&curVal))
436 err = cbor_value_dup_text_string(&curVal, &out->deviceName, &len, NULL);
437 VERIFY_CBOR_SUCCESS(TAG, err, "to find device name in device payload");
439 // Device Spec Version
440 err = cbor_value_map_find_value(rootValue, OC_RSRVD_SPEC_VERSION, &curVal);
441 VERIFY_CBOR_SUCCESS(TAG, err, "to find spec ver tag");
442 if (cbor_value_is_valid(&curVal))
444 err = cbor_value_dup_text_string(&curVal, &out->specVersion, &len, NULL);
445 VERIFY_CBOR_SUCCESS(TAG, err, "to find spec version in device payload");
447 // Data Model Versions
448 err = cbor_value_map_find_value(rootValue, OC_RSRVD_DATA_MODEL_VERSION, &curVal);
449 VERIFY_CBOR_SUCCESS(TAG, err, "to find data model versions tag");
450 if (cbor_value_is_valid(&curVal))
454 err = cbor_value_dup_text_string(&curVal, &str, &len, NULL);
455 VERIFY_CBOR_SUCCESS(TAG, err, "to find data model versions in device payload");
456 out->dataModelVersions = OCCreateOCStringLL(str);
459 err = cbor_value_advance(rootValue);
460 VERIFY_CBOR_SUCCESS(TAG, err, "to advance device payload");
462 *outPayload = (OCPayload *)out;
467 OCDevicePayloadDestroy(out);
471 static OCStackResult OCParsePlatformPayload(OCPayload **outPayload, CborValue *rootValue)
473 OCStackResult ret = OC_STACK_INVALID_PARAM;
474 CborError err = CborNoError;
475 OCPlatformInfo info = {0};
476 OCStringLL* rt = NULL;
477 OCStringLL* interfaces = NULL;
478 OCPlatformPayload* out = NULL;
480 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
482 if (cbor_value_is_map(rootValue))
486 ret = OC_STACK_MALFORMED_RESPONSE;
489 err = cbor_value_map_find_value(rootValue, OC_RSRVD_PLATFORM_ID, &repVal);
490 VERIFY_CBOR_SUCCESS(TAG, err, "to find platform id tag");
491 if (cbor_value_is_valid(&repVal))
493 err = cbor_value_dup_text_string(&repVal, &(info.platformID), &len, NULL);
494 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find platformID in the platform payload");
497 err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_NAME, &repVal);
498 VERIFY_CBOR_SUCCESS(TAG, err, "to find mfg name tag");
499 if (cbor_value_is_valid(&repVal))
501 err = cbor_value_dup_text_string(&repVal, &(info.manufacturerName), &len, NULL);
502 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find manufactureName in the platform payload");
505 err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_URL, &repVal);
506 VERIFY_CBOR_SUCCESS(TAG, err, "to find mfg url tag");
507 if (cbor_value_is_valid(&repVal))
509 err = cbor_value_dup_text_string(&repVal, &(info.manufacturerUrl), &len, NULL);
510 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find manufactureUrl in the platform payload");
513 err = cbor_value_map_find_value(rootValue, OC_RSRVD_MODEL_NUM, &repVal);
514 VERIFY_CBOR_SUCCESS(TAG, err, "to find model num tag");
515 if (cbor_value_is_valid(&repVal))
517 err = cbor_value_dup_text_string(&repVal, &(info.modelNumber), &len, NULL);
518 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find modelNumber in the platform payload");
521 err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_DATE, &repVal);
522 VERIFY_CBOR_SUCCESS(TAG, err, "to find mfg date tag");
523 if (cbor_value_is_valid(&repVal))
525 err = cbor_value_dup_text_string(&repVal, &(info.dateOfManufacture), &len, NULL);
526 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find dateOfManufacture in the platform payload");
529 err = cbor_value_map_find_value(rootValue, OC_RSRVD_PLATFORM_VERSION, &repVal);
530 VERIFY_CBOR_SUCCESS(TAG, err, "to find platform ver tag");
531 if (cbor_value_is_valid(&repVal))
533 err = cbor_value_dup_text_string(&repVal, &(info.platformVersion), &len, NULL);
534 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find platformVersion in the platform payload");
537 err = cbor_value_map_find_value(rootValue, OC_RSRVD_OS_VERSION, &repVal);
538 VERIFY_CBOR_SUCCESS(TAG, err, "to find os ver tag");
539 if (cbor_value_is_valid(&repVal))
541 err = cbor_value_dup_text_string(&repVal, &(info.operatingSystemVersion), &len, NULL);
542 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find OSVersion in the platform payload");
545 err = cbor_value_map_find_value(rootValue, OC_RSRVD_HARDWARE_VERSION, &repVal);
546 VERIFY_CBOR_SUCCESS(TAG, err, "to find hw ver tag");
547 if(cbor_value_is_valid(&repVal))
549 err = cbor_value_dup_text_string(&repVal, &(info.hardwareVersion), &len, NULL);
550 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find HWVersion in the platform payload");
553 err = cbor_value_map_find_value(rootValue, OC_RSRVD_FIRMWARE_VERSION, &repVal);
554 VERIFY_CBOR_SUCCESS(TAG, err, "to find fw ver tag");
555 if(cbor_value_is_valid(&repVal))
557 err = cbor_value_dup_text_string(&repVal, &(info.firmwareVersion), &len, NULL);
558 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find firmwareVersion in the platform payload");
561 err = cbor_value_map_find_value(rootValue, OC_RSRVD_SUPPORT_URL, &repVal);
562 VERIFY_CBOR_SUCCESS(TAG, err, "to find support url tag");
563 if(cbor_value_is_valid(&repVal))
565 err = cbor_value_dup_text_string(&repVal, &(info.supportUrl), &len, NULL);
566 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find supportUrl in the platform payload");
569 err = cbor_value_map_find_value(rootValue, OC_RSRVD_SYSTEM_TIME, &repVal);
570 VERIFY_CBOR_SUCCESS(TAG, err, "to find sys time tag");
571 if(cbor_value_is_valid(&repVal))
573 err = cbor_value_dup_text_string(&repVal, &(info.systemTime), &len, NULL);
574 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find systemTume in the platform payload");
578 err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &repVal);
579 VERIFY_CBOR_SUCCESS(TAG, err, "to find resource type tag");
581 if(cbor_value_is_valid(&repVal))
583 err = OCParseStringLL(rootValue, OC_RSRVD_RESOURCE_TYPE, &rt);
584 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find resource type in the platform payload");
588 err = cbor_value_map_find_value(rootValue, OC_RSRVD_INTERFACE, &repVal);
589 VERIFY_CBOR_SUCCESS(TAG, err, "to find interface tag");
591 if(cbor_value_is_valid(&repVal))
593 err = OCParseStringLL(rootValue, OC_RSRVD_INTERFACE, &interfaces);
594 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find interfaces tag/value");
597 err = cbor_value_advance(rootValue);
598 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find supportUrl in the platform payload");
600 out = (OCPlatformPayload *)OCPlatformPayloadCreateAsOwner(&info);
602 out->interfaces = interfaces;
603 *outPayload = (OCPayload *)out;
604 OIC_LOG_PAYLOAD(DEBUG, *outPayload);
609 OCPlatformInfoDestroy(&info);
610 OIC_LOG(ERROR, TAG, "CBOR error In ParsePlatformPayload");
614 static OCRepPayloadPropType DecodeCborType(CborType type)
619 return OCREP_PROP_NULL;
620 case CborIntegerType:
621 return OCREP_PROP_INT;
624 return OCREP_PROP_DOUBLE;
625 case CborBooleanType:
626 return OCREP_PROP_BOOL;
627 case CborTextStringType:
628 return OCREP_PROP_STRING;
629 case CborByteStringType:
630 return OCREP_PROP_BYTE_STRING;
632 return OCREP_PROP_OBJECT;
634 return OCREP_PROP_ARRAY;
636 return OCREP_PROP_NULL;
639 static CborError OCParseArrayFindDimensionsAndType(const CborValue *parent,
640 size_t dimensions[MAX_REP_ARRAY_DEPTH], OCRepPayloadPropType *type)
642 CborValue insideArray;
643 *type = OCREP_PROP_NULL;
644 dimensions[0] = dimensions[1] = dimensions[2] = 0;
646 CborError err = cbor_value_enter_container(parent, &insideArray);
647 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to enter container");
649 while (cbor_value_is_valid(&insideArray))
651 OCRepPayloadPropType tempType = DecodeCborType(cbor_value_get_type(&insideArray));
653 if (tempType == OCREP_PROP_ARRAY)
655 size_t subdim[MAX_REP_ARRAY_DEPTH];
656 tempType = OCREP_PROP_NULL;
657 err = OCParseArrayFindDimensionsAndType(&insideArray, subdim, &tempType);
658 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to parse array");
662 OIC_LOG(ERROR, TAG, "Parse array helper, sub-array too deep");
665 dimensions[1] = dimensions[1] >= subdim[0] ? dimensions[1] : subdim[0];
666 dimensions[2] = dimensions[2] >= subdim[1] ? dimensions[2] : subdim[1];
668 if (*type != OCREP_PROP_NULL && tempType != OCREP_PROP_NULL && *type != tempType)
670 OIC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed (subtype)");
671 return CborUnknownError;
673 else if (*type == OCREP_PROP_NULL)
675 // We don't know the type of this array yet, so the assignment is OK
679 else if (*type == OCREP_PROP_NULL)
681 // We don't know the type of this array yet, so the assignment is OK
684 // tempType is allowed to be NULL, since it might now know the answer yet
685 else if (tempType != OCREP_PROP_NULL && *type != tempType)
687 // this is an invalid situation!
688 OIC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed");
689 return CborUnknownError;
693 err = cbor_value_advance(&insideArray);
694 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to advance array");
701 static size_t getAllocSize(OCRepPayloadPropType type)
706 return sizeof (int64_t);
707 case OCREP_PROP_DOUBLE:
708 return sizeof (double);
709 case OCREP_PROP_BOOL:
710 return sizeof (bool);
711 case OCREP_PROP_STRING:
712 return sizeof (char*);
713 case OCREP_PROP_BYTE_STRING:
714 return sizeof (OCByteString);
715 case OCREP_PROP_OBJECT:
716 return sizeof (OCRepPayload*);
722 static size_t arrayStep(size_t dimensions[MAX_REP_ARRAY_DEPTH], size_t elementNum)
725 (dimensions[1] == 0 ? 1 : dimensions[1]) *
726 (dimensions[2] == 0 ? 1 : dimensions[2]) *
730 static CborError OCParseArrayFillArray(const CborValue *parent,
731 size_t dimensions[MAX_REP_ARRAY_DEPTH], OCRepPayloadPropType type, void *targetArray)
733 CborValue insideArray;
736 char *tempStr = NULL;
737 OCByteString ocByteStr = { .bytes = NULL, .len = 0};
739 OCRepPayload *tempPl = NULL;
741 size_t newdim[MAX_REP_ARRAY_DEPTH];
742 newdim[0] = dimensions[1];
743 newdim[1] = dimensions[2];
746 CborError err = cbor_value_enter_container(parent, &insideArray);
747 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to enter container");
749 while (!err && i < dimensions[0] && cbor_value_is_valid(&insideArray))
751 bool noAdvance = false;
752 if (cbor_value_get_type(&insideArray) != CborNullType)
757 if (dimensions[1] == 0)
759 err = cbor_value_get_int64(&insideArray, &(((int64_t*)targetArray)[i]));
763 err = OCParseArrayFillArray(&insideArray, newdim, type,
764 &(((int64_t*)targetArray)[arrayStep(dimensions, i)]));
767 case OCREP_PROP_DOUBLE:
768 if (dimensions[1] == 0)
770 double *d = &(((double*)targetArray)[i]);
771 if (cbor_value_get_type(&insideArray) == CborDoubleType)
773 err = cbor_value_get_double(&insideArray, d);
779 err = cbor_value_get_float(&insideArray, &f);
786 err = OCParseArrayFillArray(&insideArray, newdim, type,
787 &(((double*)targetArray)[arrayStep(dimensions, i)]));
790 case OCREP_PROP_BOOL:
791 if (dimensions[1] == 0)
793 err = cbor_value_get_boolean(&insideArray, &(((bool*)targetArray)[i]));
797 err = OCParseArrayFillArray(&insideArray, newdim, type,
798 &(((bool*)targetArray)[arrayStep(dimensions, i)]));
801 case OCREP_PROP_STRING:
802 if (dimensions[1] == 0)
804 err = cbor_value_dup_text_string(&insideArray, &tempStr, &tempLen, NULL);
805 ((char**)targetArray)[i] = tempStr;
810 err = OCParseArrayFillArray(&insideArray, newdim, type,
811 &(((char**)targetArray)[arrayStep(dimensions, i)]));
814 case OCREP_PROP_BYTE_STRING:
815 if (dimensions[1] == 0)
817 err = cbor_value_dup_byte_string(&insideArray, &(ocByteStr.bytes),
818 &(ocByteStr.len), NULL);
819 ((OCByteString*)targetArray)[i] = ocByteStr;
823 err = OCParseArrayFillArray(&insideArray, newdim, type,
824 &(((OCByteString*)targetArray)[arrayStep(dimensions, i)]));
827 case OCREP_PROP_OBJECT:
828 if (dimensions[1] == 0)
830 err = OCParseSingleRepPayload(&tempPl, &insideArray, false);
831 ((OCRepPayload**)targetArray)[i] = tempPl;
837 err = OCParseArrayFillArray(&insideArray, newdim, type,
838 &(((OCRepPayload**)targetArray)[arrayStep(dimensions, i)]));
842 OIC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
843 err = CborErrorUnknownType;
846 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting repPayload");
849 if (!noAdvance && cbor_value_is_valid(&insideArray))
851 err = cbor_value_advance(&insideArray);
852 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advnce insideArray");
860 static CborError OCParseArray(OCRepPayload *out, const char *name, CborValue *container)
864 OCRepPayloadPropType type = OCREP_PROP_NULL;
865 size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
868 size_t allocSize = 0;
870 CborError err = OCParseArrayFindDimensionsAndType(container, dimensions, &type);
871 VERIFY_CBOR_SUCCESS(TAG, err, "Array details weren't clear");
873 if (type == OCREP_PROP_NULL)
875 res = OCRepPayloadSetNull(out, name);
876 err = (CborError) !res;
877 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting value");
878 err = cbor_value_advance(container);
879 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing container");
883 dimTotal = calcDimTotal(dimensions);
884 allocSize = getAllocSize(type);
885 arr = OICCalloc(dimTotal, allocSize);
886 VERIFY_PARAM_NON_NULL(TAG, arr, "Array Parse allocation failed");
888 res = OCParseArrayFillArray(container, dimensions, type, arr);
889 VERIFY_CBOR_SUCCESS(TAG, err, "Failed parse array");
894 res = OCRepPayloadSetIntArrayAsOwner(out, name, (int64_t *)arr, dimensions);
896 case OCREP_PROP_DOUBLE:
897 res = OCRepPayloadSetDoubleArrayAsOwner(out, name, (double *)arr, dimensions);
899 case OCREP_PROP_BOOL:
900 res = OCRepPayloadSetBoolArrayAsOwner(out, name, (bool *)arr, dimensions);
902 case OCREP_PROP_STRING:
903 res = OCRepPayloadSetStringArrayAsOwner(out, name, (char **)arr, dimensions);
905 case OCREP_PROP_BYTE_STRING:
906 res = OCRepPayloadSetByteStringArrayAsOwner(out, name, (OCByteString *)arr, dimensions);
908 case OCREP_PROP_OBJECT:
909 res = OCRepPayloadSetPropObjectArrayAsOwner(out, name, (OCRepPayload**)arr, dimensions);
912 OIC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
915 err = (CborError) !res;
916 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting array parameter");
919 if (type == OCREP_PROP_STRING)
921 for(size_t i = 0; i < dimTotal; ++i)
923 OICFree(((char**)arr)[i]);
926 if (type == OCREP_PROP_BYTE_STRING)
928 for(size_t i = 0; i < dimTotal; ++i)
930 OICFree(((OCByteString*)arr)[i].bytes);
933 if (type == OCREP_PROP_OBJECT)
935 for(size_t i = 0; i < dimTotal; ++i)
937 OCRepPayloadDestroy(((OCRepPayload**)arr)[i]);
944 static CborError OCParseSingleRepPayload(OCRepPayload **outPayload, CborValue *objMap, bool isRoot)
946 CborError err = CborUnknownError;
949 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
950 VERIFY_PARAM_NON_NULL(TAG, objMap, "Invalid Parameter objMap");
952 if (cbor_value_is_map(objMap))
956 *outPayload = OCRepPayloadCreate();
959 return CborErrorOutOfMemory;
963 OCRepPayload *curPayload = *outPayload;
967 err = cbor_value_enter_container(objMap, &repMap);
968 VERIFY_CBOR_SUCCESS(TAG, err, "Failed entering repMap");
970 while (!err && cbor_value_is_valid(&repMap))
972 if (cbor_value_is_text_string(&repMap))
974 err = cbor_value_dup_text_string(&repMap, &name, &len, NULL);
975 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding tag name in the map");
976 err = cbor_value_advance(&repMap);
977 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing rootMap");
980 ((0 == strcmp(OC_RSRVD_HREF, name)) ||
981 (0 == strcmp(OC_RSRVD_RESOURCE_TYPE, name)) ||
982 (0 == strcmp(OC_RSRVD_INTERFACE, name))))
984 err = cbor_value_advance(&repMap);
989 CborType type = cbor_value_get_type(&repMap);
993 res = OCRepPayloadSetNull(curPayload, name);
995 case CborIntegerType:
998 err = cbor_value_get_int64(&repMap, &intval);
999 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting int value");
1000 res = OCRepPayloadSetPropInt(curPayload, name, intval);
1003 case CborDoubleType:
1005 double doubleval = 0;
1006 err = cbor_value_get_double(&repMap, &doubleval);
1007 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting double value");
1008 res = OCRepPayloadSetPropDouble(curPayload, name, doubleval);
1011 case CborBooleanType:
1013 bool boolval = false;
1014 err = cbor_value_get_boolean(&repMap, &boolval);
1015 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting boolean value");
1016 res = OCRepPayloadSetPropBool(curPayload, name, boolval);
1019 case CborTextStringType:
1021 char *strval = NULL;
1022 err = cbor_value_dup_text_string(&repMap, &strval, &len, NULL);
1023 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting string value");
1024 res = OCRepPayloadSetPropStringAsOwner(curPayload, name, strval);
1027 case CborByteStringType:
1029 uint8_t* bytestrval = NULL;
1030 err = cbor_value_dup_byte_string(&repMap, &bytestrval, &len, NULL);
1031 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting byte string value");
1032 OCByteString tmp = {.bytes = bytestrval, .len = len};
1033 res = OCRepPayloadSetPropByteStringAsOwner(curPayload, name, &tmp);
1038 OCRepPayload *pl = NULL;
1039 err = OCParseSingleRepPayload(&pl, &repMap, false);
1040 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting parse single rep");
1041 res = OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl);
1045 err = OCParseArray(curPayload, name, &repMap);
1048 OIC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type);
1051 if (type != CborArrayType)
1053 err = (CborError) !res;
1055 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting value");
1057 if (type != CborMapType && cbor_value_is_valid(&repMap))
1059 err = cbor_value_advance(&repMap);
1060 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advance repMap");
1065 if (cbor_value_is_container(objMap))
1067 err = cbor_value_leave_container(objMap, &repMap);
1068 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to leave container");
1075 OCRepPayloadDestroy(*outPayload);
1080 static OCStackResult OCParseRepPayload(OCPayload **outPayload, CborValue *root)
1082 OCStackResult ret = OC_STACK_INVALID_PARAM;
1084 OCRepPayload *temp = NULL;
1085 OCRepPayload *rootPayload = NULL;
1086 OCRepPayload *curPayload = NULL;
1087 CborValue rootMap = *root;
1088 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
1089 VERIFY_PARAM_NON_NULL(TAG, root, "Invalid Parameter root");
1092 if (cbor_value_is_array(root))
1094 err = cbor_value_enter_container(root, &rootMap);
1095 VERIFY_CBOR_SUCCESS(TAG, err, "Failed entering repMap");
1097 while (cbor_value_is_valid(&rootMap))
1099 temp = OCRepPayloadCreate();
1100 ret = OC_STACK_NO_MEMORY;
1101 VERIFY_PARAM_NON_NULL(TAG, temp, "Failed allocating memory");
1104 ret = OC_STACK_MALFORMED_RESPONSE;
1106 // temporary fix to check for malformed cbor payload
1107 if (!cbor_value_is_map(&rootMap) && !cbor_value_is_array(&rootMap)){
1111 if (cbor_value_is_map(&rootMap))
1113 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_HREF, &curVal);
1114 VERIFY_CBOR_SUCCESS(TAG, err, "to find href tag");
1115 if (cbor_value_is_valid(&curVal))
1118 err = cbor_value_dup_text_string(&curVal, &temp->uri, &len, NULL);
1119 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find uri");
1124 if (cbor_value_is_map(&rootMap))
1126 if (CborNoError == cbor_value_map_find_value(&rootMap, OC_RSRVD_RESOURCE_TYPE, &curVal))
1128 err = OCParseStringLL(&rootMap, OC_RSRVD_RESOURCE_TYPE, &temp->types);
1129 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find rt type tag/value");
1134 if (cbor_value_is_map(&rootMap))
1136 if (CborNoError == cbor_value_map_find_value(&rootMap, OC_RSRVD_INTERFACE, &curVal))
1138 err = OCParseStringLL(&rootMap, OC_RSRVD_INTERFACE, &temp->interfaces);
1139 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find interfaces tag/value");
1143 if (cbor_value_is_map(&rootMap))
1145 err = OCParseSingleRepPayload(&temp, &rootMap, true);
1146 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to parse single rep payload");
1149 if(rootPayload == NULL)
1156 curPayload->next = temp;
1157 curPayload = curPayload->next;
1160 if (cbor_value_is_array(&rootMap))
1162 err = cbor_value_advance(&rootMap);
1163 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to advance single rep payload");
1166 *outPayload = (OCPayload *)rootPayload;
1170 OCRepPayloadDestroy(temp);
1171 OCRepPayloadDestroy(rootPayload);
1172 OIC_LOG(ERROR, TAG, "CBOR error in ParseRepPayload");
1176 static OCStackResult OCParsePresencePayload(OCPayload **outPayload, CborValue *rootValue)
1178 OCStackResult ret = OC_STACK_INVALID_PARAM;
1179 OCPresencePayload *payload = NULL;
1180 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
1184 payload = (OCPresencePayload *)OICCalloc(1, sizeof(OCPresencePayload));
1185 ret = OC_STACK_NO_MEMORY;
1186 VERIFY_PARAM_NON_NULL(TAG, payload, "Failed allocating presence payload");
1187 payload->base.type = PAYLOAD_TYPE_PRESENCE;
1188 ret = OC_STACK_MALFORMED_RESPONSE;
1190 if (cbor_value_is_map(rootValue))
1196 CborError err = cbor_value_map_find_value(rootValue, OC_RSRVD_NONCE, &curVal);
1197 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding nonce tag");
1198 err = cbor_value_get_uint64(&curVal, &temp);
1199 payload->sequenceNumber = (uint32_t)temp;
1200 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding nonce value");
1203 err = cbor_value_map_find_value(rootValue, OC_RSRVD_TTL, &curVal);
1204 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding ttl tag");
1206 err = cbor_value_get_uint64(&curVal, &temp);
1207 payload->maxAge = (uint32_t)temp;
1208 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding ttl value");
1211 err = cbor_value_map_find_value(rootValue, OC_RSRVD_TRIGGER, &curVal);
1212 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding trigger tag");
1213 err = cbor_value_get_simple_type(&curVal, (uint8_t *)&payload->trigger);
1214 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding trigger value");
1216 // Resource type name
1217 err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &curVal);
1218 VERIFY_CBOR_SUCCESS(TAG, err, "to find res type tag");
1219 if (cbor_value_is_valid(&curVal))
1222 err = cbor_value_dup_text_string(&curVal, &payload->resourceType, &len, NULL);
1223 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding resource type value");
1226 err = cbor_value_advance(rootValue);
1227 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing root value");
1229 *outPayload = (OCPayload *)payload;
1233 OIC_LOG(ERROR, TAG, "CBOR error Parse Presence Payload");
1234 OCPresencePayloadDestroy(payload);