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"
38 #include "platform_features.h"
40 #define TAG "OIC_RI_PAYLOADPARSE"
42 static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *arrayVal);
43 static OCStackResult OCParseDevicePayload(OCPayload **outPayload, CborValue *arrayVal);
44 static OCStackResult OCParsePlatformPayload(OCPayload **outPayload, CborValue *arrayVal);
45 static CborError OCParseSingleRepPayload(OCRepPayload **outPayload, CborValue *repParent, bool isRoot);
46 static OCStackResult OCParseRepPayload(OCPayload **outPayload, CborValue *arrayVal);
47 static OCStackResult OCParsePresencePayload(OCPayload **outPayload, CborValue *arrayVal);
48 static OCStackResult OCParseSecurityPayload(OCPayload **outPayload, const uint8_t *payload, size_t size);
50 OCStackResult OCParsePayload(OCPayload **outPayload, OCPayloadType payloadType,
51 const uint8_t *payload, size_t payloadSize)
53 OCStackResult result = OC_STACK_MALFORMED_RESPONSE;
56 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Conversion of outPayload failed");
57 VERIFY_PARAM_NON_NULL(TAG, payload, "Invalid cbor payload value");
59 OIC_LOG_V(INFO, TAG, "CBOR Parsing size: %zu of Payload Type: %d, Payload:",
60 payloadSize, payloadType);
61 OIC_LOG_BUFFER(DEBUG, TAG, payload, payloadSize);
66 err = cbor_parser_init(payload, payloadSize, 0, &parser, &rootValue);
67 VERIFY_CBOR_SUCCESS(TAG, err, "Failed initializing init value")
71 case PAYLOAD_TYPE_DISCOVERY:
72 result = OCParseDiscoveryPayload(outPayload, &rootValue);
74 case PAYLOAD_TYPE_DEVICE:
75 result = OCParseDevicePayload(outPayload, &rootValue);
77 case PAYLOAD_TYPE_PLATFORM:
78 result = OCParsePlatformPayload(outPayload, &rootValue);
80 case PAYLOAD_TYPE_REPRESENTATION:
81 result = OCParseRepPayload(outPayload, &rootValue);
83 case PAYLOAD_TYPE_PRESENCE:
84 result = OCParsePresencePayload(outPayload, &rootValue);
86 case PAYLOAD_TYPE_SECURITY:
87 result = OCParseSecurityPayload(outPayload, payload, payloadSize);
90 result = OCRDCborToPayload(&rootValue, outPayload);
93 OIC_LOG_V(ERROR, TAG, "ParsePayload Type default: %d", payloadType);
94 result = OC_STACK_INVALID_PARAM;
98 OIC_LOG_V(INFO, TAG, "Finished parse payload, result is %d", result);
104 void OCFreeOCStringLL(OCStringLL* ll);
106 static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, const uint8_t *payload,
111 *outPayload = (OCPayload *)OCSecurityPayloadCreate(payload, size);
120 static char* InPlaceStringTrim(char* str)
122 while (str[0] == ' ')
127 size_t lastchar = strlen(str);
129 while (str[lastchar] == ' ')
131 str[lastchar] = '\0';
138 static CborError OCParseStringLL(CborValue *map, char *type, OCStringLL **resource)
141 CborError err = cbor_value_map_find_value(map, type, &val);
142 VERIFY_CBOR_SUCCESS(TAG, err, "to find StringLL TAG");
144 if (cbor_value_is_array(&val))
147 err = cbor_value_enter_container(&val, &txtStr);
148 VERIFY_CBOR_SUCCESS(TAG, err, "to enter container");
149 while (cbor_value_is_text_string(&txtStr))
153 err = cbor_value_dup_text_string(&txtStr, &input, &len, NULL);
154 VERIFY_CBOR_SUCCESS(TAG, err, "to find StringLL value.");
157 char *savePtr = NULL;
158 char *curPtr = strtok_r(input, " ", &savePtr);
161 char *trimmed = InPlaceStringTrim(curPtr);
162 if (trimmed[0] !='\0')
164 if (!OCResourcePayloadAddStringLL(resource, trimmed))
166 return CborErrorOutOfMemory;
169 curPtr = strtok_r(NULL, " ", &savePtr);
173 if (cbor_value_is_text_string(&txtStr))
175 err = cbor_value_advance(&txtStr);
176 VERIFY_CBOR_SUCCESS(TAG, err, "to advance string value");
184 static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *rootValue)
186 OCStackResult ret = OC_STACK_INVALID_PARAM;
187 OCResourcePayload *resource = NULL;
188 OCDiscoveryPayload *out = NULL;
190 CborError err = CborNoError;
193 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
194 VERIFY_PARAM_NON_NULL(TAG, rootValue, "Invalid Parameter rootValue");
195 if (cbor_value_is_array(rootValue))
197 // Root value is already inside the main root array
199 ret = OC_STACK_NO_MEMORY;
200 out = OCDiscoveryPayloadCreate();
201 VERIFY_PARAM_NON_NULL(TAG, out, "Failed error initializing discovery payload");
203 // Enter the main root map
204 ret = OC_STACK_MALFORMED_RESPONSE;
205 err = cbor_value_enter_container(rootValue, &rootMap);
206 VERIFY_CBOR_SUCCESS(TAG, err, "to enter root map container");
210 if (!cbor_value_is_map(&rootMap))
212 OIC_LOG(ERROR, TAG, "Malformed packet!!");
215 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_DEVICE_ID, &curVal);
216 VERIFY_CBOR_SUCCESS(TAG, err, "to find device id tag");
217 if (cbor_value_is_valid(&curVal))
219 if (cbor_value_is_byte_string(&curVal))
221 err = cbor_value_dup_byte_string(&curVal, (uint8_t **)&(out->sid), &len, NULL);
222 VERIFY_CBOR_SUCCESS(TAG, err, "to copy device id value");
224 else if (cbor_value_is_text_string(&curVal))
226 err = cbor_value_dup_text_string(&curVal, &(out->sid), &len, NULL);
227 VERIFY_CBOR_SUCCESS(TAG, err, "to copy device id value");
231 // BaseURI - Not a mandatory field
232 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_BASE_URI, &curVal);
233 VERIFY_CBOR_SUCCESS(TAG, err, "to find uri tag");
234 if (cbor_value_is_valid(&curVal))
236 err = cbor_value_dup_text_string(&curVal, &(out->baseURI), &len, NULL);
237 VERIFY_CBOR_SUCCESS(TAG, err, "to find base uri value");
240 // HREF - Not a mandatory field
241 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_HREF, &curVal);
242 if (cbor_value_is_valid(&curVal))
244 err = cbor_value_dup_text_string(&curVal, &(out->uri), &len, NULL);
245 VERIFY_CBOR_SUCCESS(TAG, err, "to find uri value");
248 // RT - Not a mandatory field
249 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_RESOURCE_TYPE, &curVal);
250 if (cbor_value_is_valid(&curVal))
252 err = cbor_value_dup_text_string(&curVal, &(out->type), &len, NULL);
253 VERIFY_CBOR_SUCCESS(TAG, err, "to find base uri value");
256 // IF - Not a mandatory field
257 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_INTERFACE, &curVal);
258 if (cbor_value_is_valid(&curVal))
260 err = OCParseStringLL(&rootMap, OC_RSRVD_INTERFACE, &out->iface);
264 if (!OCResourcePayloadAddStringLL(&out->iface, OC_RSRVD_INTERFACE_LL))
266 err = CborErrorOutOfMemory;
270 // Name - Not a mandatory field
271 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_DEVICE_NAME, &curVal);
272 if (cbor_value_is_valid(&curVal))
274 err = cbor_value_dup_text_string(&curVal, &out->name, &len, NULL);
275 VERIFY_CBOR_SUCCESS(TAG, err, "to find device name");
278 // Look for Links which will have an array as the value
280 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_LINKS, &linkMap);
281 VERIFY_CBOR_SUCCESS(TAG, err, "to find links tag");
283 // Enter the links array and start iterating through the array processing
284 // each resource which shows up as a map.
285 CborValue resourceMap;
286 err = cbor_value_enter_container(&linkMap, &resourceMap);
287 VERIFY_CBOR_SUCCESS(TAG, err, "to enter link map");
289 while (cbor_value_is_map(&resourceMap))
291 resource = (OCResourcePayload *)OICCalloc(1, sizeof(OCResourcePayload));
292 VERIFY_PARAM_NON_NULL(TAG, resource, "Failed allocating resource payload");
295 err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_HREF, &curVal);
296 VERIFY_CBOR_SUCCESS(TAG, err, "to find href tag");
297 err = cbor_value_dup_text_string(&curVal, &(resource->uri), &len, NULL);
298 VERIFY_CBOR_SUCCESS(TAG, err, "to find href value");
301 err = OCParseStringLL(&resourceMap, OC_RSRVD_RESOURCE_TYPE, &resource->types);
302 VERIFY_CBOR_SUCCESS(TAG, err, "to find resource type tag/value");
305 err = OCParseStringLL(&resourceMap, OC_RSRVD_INTERFACE, &resource->interfaces);
306 if (CborNoError != err)
308 if (!OCResourcePayloadAddStringLL(&resource->interfaces, OC_RSRVD_INTERFACE_LL))
310 OIC_LOG(ERROR, TAG, "Failed to add string to StringLL");
317 err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_POLICY, &policyMap);
318 VERIFY_CBOR_SUCCESS(TAG, err, "to find policy tag");
321 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &curVal);
322 VERIFY_CBOR_SUCCESS(TAG, err, "to find bitmap tag");
323 err = cbor_value_get_int(&curVal, (int *)&resource->bitmap);
324 VERIFY_CBOR_SUCCESS(TAG, err, "to find bitmap value");
327 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &curVal);
328 VERIFY_CBOR_SUCCESS(TAG, err, "to find secure tag");
329 if (cbor_value_is_valid(&curVal))
331 err = cbor_value_get_boolean(&curVal, &(resource->secure));
332 VERIFY_CBOR_SUCCESS(TAG, err, "to find secure value");
336 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT, &curVal);
337 VERIFY_CBOR_SUCCESS(TAG, err, "to find port tag");
338 if (cbor_value_is_valid(&curVal))
340 err = cbor_value_get_int(&curVal, (int *)&resource->port);
341 VERIFY_CBOR_SUCCESS(TAG, err, "to find port value");
346 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_TCP_PORT, &curVal);
347 if (cbor_value_is_valid(&curVal))
349 err = cbor_value_get_int(&curVal, (int *)&resource->tcpPort);
350 VERIFY_CBOR_SUCCESS(TAG, err, "to find tcp port value");
354 err = cbor_value_advance(&resourceMap);
355 VERIFY_CBOR_SUCCESS(TAG, err, "to advance resource map");
357 OCDiscoveryPayloadAddNewResource(out, resource);
360 err = cbor_value_leave_container(rootValue, &resourceMap);
361 VERIFY_CBOR_SUCCESS(TAG, err, "to advance resource map");
365 OIC_LOG(ERROR, TAG, "Malformed packet ");
369 *outPayload = (OCPayload *)out;
370 OIC_LOG_PAYLOAD(DEBUG, *outPayload);
375 OCDiscoveryResourceDestroy(resource);
376 OCDiscoveryPayloadDestroy(out);
380 static OCStackResult OCParseDevicePayload(OCPayload **outPayload, CborValue *rootValue)
382 OCStackResult ret = OC_STACK_INVALID_PARAM;
383 CborError err = CborNoError;
384 OCDevicePayload *out = NULL;
385 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid param outPayload");
386 VERIFY_PARAM_NON_NULL(TAG, rootValue, "Invalid param rootValue");
390 out = (OCDevicePayload *)OICCalloc(1, sizeof(OCDevicePayload));
391 VERIFY_PARAM_NON_NULL(TAG, out, "Failed allocating device payload")
392 out->base.type = PAYLOAD_TYPE_DEVICE;
393 ret = OC_STACK_MALFORMED_RESPONSE;
395 if (cbor_value_is_map(rootValue))
399 err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &curVal);
400 VERIFY_CBOR_SUCCESS(TAG, err, "to find resource type tag");
402 if (cbor_value_is_valid(&curVal))
404 err = OCParseStringLL(rootValue, OC_RSRVD_RESOURCE_TYPE, &out->types);
405 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find rt type tag/value");
408 err = cbor_value_map_find_value(rootValue, OC_RSRVD_INTERFACE, &curVal);
409 VERIFY_CBOR_SUCCESS(TAG, err, "to find interface tag");
410 if (cbor_value_is_valid(&curVal))
412 err = OCParseStringLL(rootValue, OC_RSRVD_INTERFACE, &out->interfaces);
413 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find interfaces tag/value");
417 err = cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_ID, &curVal);
418 VERIFY_CBOR_SUCCESS(TAG, err, "to find device id tag");
419 if (cbor_value_is_valid(&curVal))
421 if (cbor_value_is_byte_string(&curVal))
423 err = cbor_value_dup_byte_string(&curVal, (uint8_t **)&out->sid, &len, NULL);
424 VERIFY_CBOR_SUCCESS(TAG, err, "to find device id in device payload");
426 else if (cbor_value_is_text_string(&curVal))
428 err = cbor_value_dup_text_string(&curVal, &out->sid, &len, NULL);
429 VERIFY_CBOR_SUCCESS(TAG, err, "to find device id in device payload");
433 err = cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_NAME, &curVal);
434 VERIFY_CBOR_SUCCESS(TAG, err, "to find device name tag");
435 if (cbor_value_is_valid(&curVal))
437 err = cbor_value_dup_text_string(&curVal, &out->deviceName, &len, NULL);
438 VERIFY_CBOR_SUCCESS(TAG, err, "to find device name in device payload");
440 // Device Spec Version
441 err = cbor_value_map_find_value(rootValue, OC_RSRVD_SPEC_VERSION, &curVal);
442 VERIFY_CBOR_SUCCESS(TAG, err, "to find spec ver tag");
443 if (cbor_value_is_valid(&curVal))
445 err = cbor_value_dup_text_string(&curVal, &out->specVersion, &len, NULL);
446 VERIFY_CBOR_SUCCESS(TAG, err, "to find spec version in device payload");
448 // Data Model Version
449 err = cbor_value_map_find_value(rootValue, OC_RSRVD_DATA_MODEL_VERSION, &curVal);
450 VERIFY_CBOR_SUCCESS(TAG, err, "to find data model ver tag");
451 if (cbor_value_is_valid(&curVal))
453 err = cbor_value_dup_text_string(&curVal, &out->dataModelVersion, &len, NULL);
454 VERIFY_CBOR_SUCCESS(TAG, err, "to find data model version in device payload");
456 err = cbor_value_advance(rootValue);
457 VERIFY_CBOR_SUCCESS(TAG, err, "to advance device payload");
459 *outPayload = (OCPayload *)out;
464 OCDevicePayloadDestroy(out);
468 static OCStackResult OCParsePlatformPayload(OCPayload **outPayload, CborValue *rootValue)
470 OCStackResult ret = OC_STACK_INVALID_PARAM;
471 CborError err = CborNoError;
472 OCPlatformInfo info = {0};
474 OCStringLL* interfaces = NULL;
475 OCPlatformPayload* out = NULL;
477 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
479 if (cbor_value_is_map(rootValue))
483 ret = OC_STACK_MALFORMED_RESPONSE;
486 err = cbor_value_map_find_value(rootValue, OC_RSRVD_PLATFORM_ID, &repVal);
487 VERIFY_CBOR_SUCCESS(TAG, err, "to find platform id tag");
488 if (cbor_value_is_valid(&repVal))
490 err = cbor_value_dup_text_string(&repVal, &(info.platformID), &len, NULL);
491 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find platformID in the platform payload");
494 err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_NAME, &repVal);
495 VERIFY_CBOR_SUCCESS(TAG, err, "to find mfg name tag");
496 if (cbor_value_is_valid(&repVal))
498 err = cbor_value_dup_text_string(&repVal, &(info.manufacturerName), &len, NULL);
499 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find manufactureName in the platform payload");
502 err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_URL, &repVal);
503 VERIFY_CBOR_SUCCESS(TAG, err, "to find mfg url tag");
504 if (cbor_value_is_valid(&repVal))
506 err = cbor_value_dup_text_string(&repVal, &(info.manufacturerUrl), &len, NULL);
507 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find manufactureUrl in the platform payload");
510 err = cbor_value_map_find_value(rootValue, OC_RSRVD_MODEL_NUM, &repVal);
511 VERIFY_CBOR_SUCCESS(TAG, err, "to find model num tag");
512 if (cbor_value_is_valid(&repVal))
514 err = cbor_value_dup_text_string(&repVal, &(info.modelNumber), &len, NULL);
515 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find modelNumber in the platform payload");
518 err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_DATE, &repVal);
519 VERIFY_CBOR_SUCCESS(TAG, err, "to find mfg date tag");
520 if (cbor_value_is_valid(&repVal))
522 err = cbor_value_dup_text_string(&repVal, &(info.dateOfManufacture), &len, NULL);
523 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find dateOfManufacture in the platform payload");
526 err = cbor_value_map_find_value(rootValue, OC_RSRVD_PLATFORM_VERSION, &repVal);
527 VERIFY_CBOR_SUCCESS(TAG, err, "to find platform ver tag");
528 if (cbor_value_is_valid(&repVal))
530 err = cbor_value_dup_text_string(&repVal, &(info.platformVersion), &len, NULL);
531 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find platformVersion in the platform payload");
534 err = cbor_value_map_find_value(rootValue, OC_RSRVD_OS_VERSION, &repVal);
535 VERIFY_CBOR_SUCCESS(TAG, err, "to find os ver tag");
536 if (cbor_value_is_valid(&repVal))
538 err = cbor_value_dup_text_string(&repVal, &(info.operatingSystemVersion), &len, NULL);
539 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find OSVersion in the platform payload");
542 err = cbor_value_map_find_value(rootValue, OC_RSRVD_HARDWARE_VERSION, &repVal);
543 VERIFY_CBOR_SUCCESS(TAG, err, "to find hw ver tag");
544 if(cbor_value_is_valid(&repVal))
546 err = cbor_value_dup_text_string(&repVal, &(info.hardwareVersion), &len, NULL);
547 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find HWVersion in the platform payload");
550 err = cbor_value_map_find_value(rootValue, OC_RSRVD_FIRMWARE_VERSION, &repVal);
551 VERIFY_CBOR_SUCCESS(TAG, err, "to find fw ver tag");
552 if(cbor_value_is_valid(&repVal))
554 err = cbor_value_dup_text_string(&repVal, &(info.firmwareVersion), &len, NULL);
555 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find firmwareVersion in the platform payload");
558 err = cbor_value_map_find_value(rootValue, OC_RSRVD_SUPPORT_URL, &repVal);
559 VERIFY_CBOR_SUCCESS(TAG, err, "to find support url tag");
560 if(cbor_value_is_valid(&repVal))
562 err = cbor_value_dup_text_string(&repVal, &(info.supportUrl), &len, NULL);
563 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find supportUrl in the platform payload");
566 err = cbor_value_map_find_value(rootValue, OC_RSRVD_SYSTEM_TIME, &repVal);
567 VERIFY_CBOR_SUCCESS(TAG, err, "to find sys time tag");
568 if(cbor_value_is_valid(&repVal))
570 err = cbor_value_dup_text_string(&repVal, &(info.systemTime), &len, NULL);
571 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find systemTume in the platform payload");
575 err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &repVal);
576 VERIFY_CBOR_SUCCESS(TAG, err, "to find resource type tag");
578 if(cbor_value_is_valid(&repVal))
580 err = cbor_value_dup_text_string(&repVal, &rt, &len, NULL);
581 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find resource type in the platform payload");
585 err = cbor_value_map_find_value(rootValue, OC_RSRVD_INTERFACE, &repVal);
586 VERIFY_CBOR_SUCCESS(TAG, err, "to find interface tag");
588 if(cbor_value_is_valid(&repVal))
590 err = OCParseStringLL(rootValue, OC_RSRVD_INTERFACE, &interfaces);
591 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find interfaces tag/value");
594 err = cbor_value_advance(rootValue);
595 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find supportUrl in the platform payload");
597 out = (OCPlatformPayload *)OCPlatformPayloadCreateAsOwner(&info);
599 out->interfaces = interfaces;
600 *outPayload = (OCPayload *)out;
601 OIC_LOG_PAYLOAD(DEBUG, *outPayload);
606 OCPlatformInfoDestroy(&info);
607 OIC_LOG(ERROR, TAG, "CBOR error In ParsePlatformPayload");
611 static OCRepPayloadPropType DecodeCborType(CborType type)
616 return OCREP_PROP_NULL;
617 case CborIntegerType:
618 return OCREP_PROP_INT;
621 return OCREP_PROP_DOUBLE;
622 case CborBooleanType:
623 return OCREP_PROP_BOOL;
624 case CborTextStringType:
625 return OCREP_PROP_STRING;
626 case CborByteStringType:
627 return OCREP_PROP_BYTE_STRING;
629 return OCREP_PROP_OBJECT;
631 return OCREP_PROP_ARRAY;
633 return OCREP_PROP_NULL;
636 static CborError OCParseArrayFindDimensionsAndType(const CborValue *parent,
637 size_t dimensions[MAX_REP_ARRAY_DEPTH], OCRepPayloadPropType *type)
639 CborValue insideArray;
640 *type = OCREP_PROP_NULL;
641 dimensions[0] = dimensions[1] = dimensions[2] = 0;
643 CborError err = cbor_value_enter_container(parent, &insideArray);
644 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to enter container");
646 while (cbor_value_is_valid(&insideArray))
648 OCRepPayloadPropType tempType = DecodeCborType(cbor_value_get_type(&insideArray));
650 if (tempType == OCREP_PROP_ARRAY)
652 size_t subdim[MAX_REP_ARRAY_DEPTH];
653 tempType = OCREP_PROP_NULL;
654 err = OCParseArrayFindDimensionsAndType(&insideArray, subdim, &tempType);
655 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to parse array");
659 OIC_LOG(ERROR, TAG, "Parse array helper, sub-array too deep");
662 dimensions[1] = dimensions[1] >= subdim[0] ? dimensions[1] : subdim[0];
663 dimensions[2] = dimensions[2] >= subdim[1] ? dimensions[2] : subdim[1];
665 if (*type != OCREP_PROP_NULL && tempType != OCREP_PROP_NULL && *type != tempType)
667 OIC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed (subtype)");
668 return CborUnknownError;
670 else if (*type == OCREP_PROP_NULL)
672 // We don't know the type of this array yet, so the assignment is OK
676 else if (*type == OCREP_PROP_NULL)
678 // We don't know the type of this array yet, so the assignment is OK
681 // tempType is allowed to be NULL, since it might now know the answer yet
682 else if (tempType != OCREP_PROP_NULL && *type != tempType)
684 // this is an invalid situation!
685 OIC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed");
686 return CborUnknownError;
690 err = cbor_value_advance(&insideArray);
691 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to advance array");
698 static size_t getAllocSize(OCRepPayloadPropType type)
703 return sizeof (int64_t);
704 case OCREP_PROP_DOUBLE:
705 return sizeof (double);
706 case OCREP_PROP_BOOL:
707 return sizeof (bool);
708 case OCREP_PROP_STRING:
709 return sizeof (char*);
710 case OCREP_PROP_BYTE_STRING:
711 return sizeof (OCByteString);
712 case OCREP_PROP_OBJECT:
713 return sizeof (OCRepPayload*);
719 static size_t arrayStep(size_t dimensions[MAX_REP_ARRAY_DEPTH], size_t elementNum)
722 (dimensions[1] == 0 ? 1 : dimensions[1]) *
723 (dimensions[2] == 0 ? 1 : dimensions[2]) *
727 static CborError OCParseArrayFillArray(const CborValue *parent,
728 size_t dimensions[MAX_REP_ARRAY_DEPTH], OCRepPayloadPropType type, void *targetArray)
730 CborValue insideArray;
733 char *tempStr = NULL;
734 OCByteString ocByteStr = { .bytes = NULL, .len = 0};
736 OCRepPayload *tempPl = NULL;
738 size_t newdim[MAX_REP_ARRAY_DEPTH];
739 newdim[0] = dimensions[1];
740 newdim[1] = dimensions[2];
743 CborError err = cbor_value_enter_container(parent, &insideArray);
744 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to enter container");
746 while (!err && i < dimensions[0] && cbor_value_is_valid(&insideArray))
748 bool noAdvance = false;
749 if (cbor_value_get_type(&insideArray) != CborNullType)
754 if (dimensions[1] == 0)
756 err = cbor_value_get_int64(&insideArray, &(((int64_t*)targetArray)[i]));
760 err = OCParseArrayFillArray(&insideArray, newdim, type,
761 &(((int64_t*)targetArray)[arrayStep(dimensions, i)]));
764 case OCREP_PROP_DOUBLE:
765 if (dimensions[1] == 0)
767 double *d = &(((double*)targetArray)[i]);
768 if (cbor_value_get_type(&insideArray) == CborDoubleType)
770 err = cbor_value_get_double(&insideArray, d);
776 err = cbor_value_get_float(&insideArray, &f);
783 err = OCParseArrayFillArray(&insideArray, newdim, type,
784 &(((double*)targetArray)[arrayStep(dimensions, i)]));
787 case OCREP_PROP_BOOL:
788 if (dimensions[1] == 0)
790 err = cbor_value_get_boolean(&insideArray, &(((bool*)targetArray)[i]));
794 err = OCParseArrayFillArray(&insideArray, newdim, type,
795 &(((bool*)targetArray)[arrayStep(dimensions, i)]));
798 case OCREP_PROP_STRING:
799 if (dimensions[1] == 0)
801 err = cbor_value_dup_text_string(&insideArray, &tempStr, &tempLen, NULL);
802 ((char**)targetArray)[i] = tempStr;
807 err = OCParseArrayFillArray(&insideArray, newdim, type,
808 &(((char**)targetArray)[arrayStep(dimensions, i)]));
811 case OCREP_PROP_BYTE_STRING:
812 if (dimensions[1] == 0)
814 err = cbor_value_dup_byte_string(&insideArray, &(ocByteStr.bytes),
815 &(ocByteStr.len), NULL);
816 ((OCByteString*)targetArray)[i] = ocByteStr;
820 err = OCParseArrayFillArray(&insideArray, newdim, type,
821 &(((OCByteString*)targetArray)[arrayStep(dimensions, i)]));
824 case OCREP_PROP_OBJECT:
825 if (dimensions[1] == 0)
827 err = OCParseSingleRepPayload(&tempPl, &insideArray, false);
828 ((OCRepPayload**)targetArray)[i] = tempPl;
834 err = OCParseArrayFillArray(&insideArray, newdim, type,
835 &(((OCRepPayload**)targetArray)[arrayStep(dimensions, i)]));
839 OIC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
840 err = CborErrorUnknownType;
843 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting repPayload");
846 if (!noAdvance && cbor_value_is_valid(&insideArray))
848 err = cbor_value_advance(&insideArray);
849 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advnce insideArray");
857 static CborError OCParseArray(OCRepPayload *out, const char *name, CborValue *container)
861 OCRepPayloadPropType type = OCREP_PROP_NULL;
862 size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
865 size_t allocSize = 0;
867 CborError err = OCParseArrayFindDimensionsAndType(container, dimensions, &type);
868 VERIFY_CBOR_SUCCESS(TAG, err, "Array details weren't clear");
870 if (type == OCREP_PROP_NULL)
872 res = OCRepPayloadSetNull(out, name);
873 err = (CborError) !res;
874 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting value");
875 err = cbor_value_advance(container);
876 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing container");
880 dimTotal = calcDimTotal(dimensions);
881 allocSize = getAllocSize(type);
882 arr = OICCalloc(dimTotal, allocSize);
883 VERIFY_PARAM_NON_NULL(TAG, arr, "Array Parse allocation failed");
885 res = OCParseArrayFillArray(container, dimensions, type, arr);
886 VERIFY_CBOR_SUCCESS(TAG, err, "Failed parse array");
891 res = OCRepPayloadSetIntArrayAsOwner(out, name, (int64_t *)arr, dimensions);
893 case OCREP_PROP_DOUBLE:
894 res = OCRepPayloadSetDoubleArrayAsOwner(out, name, (double *)arr, dimensions);
896 case OCREP_PROP_BOOL:
897 res = OCRepPayloadSetBoolArrayAsOwner(out, name, (bool *)arr, dimensions);
899 case OCREP_PROP_STRING:
900 res = OCRepPayloadSetStringArrayAsOwner(out, name, (char **)arr, dimensions);
902 case OCREP_PROP_BYTE_STRING:
903 res = OCRepPayloadSetByteStringArrayAsOwner(out, name, (OCByteString *)arr, dimensions);
905 case OCREP_PROP_OBJECT:
906 res = OCRepPayloadSetPropObjectArrayAsOwner(out, name, (OCRepPayload**)arr, dimensions);
909 OIC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
912 err = (CborError) !res;
913 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting array parameter");
916 if (type == OCREP_PROP_STRING)
918 for(size_t i = 0; i < dimTotal; ++i)
920 OICFree(((char**)arr)[i]);
923 if (type == OCREP_PROP_BYTE_STRING)
925 for(size_t i = 0; i < dimTotal; ++i)
927 OICFree(((OCByteString*)arr)[i].bytes);
930 if (type == OCREP_PROP_OBJECT)
932 for(size_t i = 0; i < dimTotal; ++i)
934 OCRepPayloadDestroy(((OCRepPayload**)arr)[i]);
941 static CborError OCParseSingleRepPayload(OCRepPayload **outPayload, CborValue *objMap, bool isRoot)
943 CborError err = CborUnknownError;
946 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
947 VERIFY_PARAM_NON_NULL(TAG, objMap, "Invalid Parameter objMap");
949 if (cbor_value_is_map(objMap))
953 *outPayload = OCRepPayloadCreate();
956 return CborErrorOutOfMemory;
960 OCRepPayload *curPayload = *outPayload;
964 err = cbor_value_enter_container(objMap, &repMap);
965 VERIFY_CBOR_SUCCESS(TAG, err, "Failed entering repMap");
967 while (!err && cbor_value_is_valid(&repMap))
969 if (cbor_value_is_text_string(&repMap))
971 err = cbor_value_dup_text_string(&repMap, &name, &len, NULL);
972 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding tag name in the map");
973 err = cbor_value_advance(&repMap);
974 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing rootMap");
977 ((0 == strcmp(OC_RSRVD_HREF, name)) ||
978 (0 == strcmp(OC_RSRVD_RESOURCE_TYPE, name)) ||
979 (0 == strcmp(OC_RSRVD_INTERFACE, name))))
981 err = cbor_value_advance(&repMap);
986 CborType type = cbor_value_get_type(&repMap);
990 res = OCRepPayloadSetNull(curPayload, name);
992 case CborIntegerType:
995 err = cbor_value_get_int64(&repMap, &intval);
996 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting int value");
997 res = OCRepPayloadSetPropInt(curPayload, name, intval);
1000 case CborDoubleType:
1002 double doubleval = 0;
1003 err = cbor_value_get_double(&repMap, &doubleval);
1004 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting double value");
1005 res = OCRepPayloadSetPropDouble(curPayload, name, doubleval);
1008 case CborBooleanType:
1010 bool boolval = false;
1011 err = cbor_value_get_boolean(&repMap, &boolval);
1012 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting boolean value");
1013 res = OCRepPayloadSetPropBool(curPayload, name, boolval);
1016 case CborTextStringType:
1018 char *strval = NULL;
1019 err = cbor_value_dup_text_string(&repMap, &strval, &len, NULL);
1020 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting string value");
1021 res = OCRepPayloadSetPropStringAsOwner(curPayload, name, strval);
1024 case CborByteStringType:
1026 uint8_t* bytestrval = NULL;
1027 err = cbor_value_dup_byte_string(&repMap, &bytestrval, &len, NULL);
1028 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting byte string value");
1029 OCByteString tmp = {.bytes = bytestrval, .len = len};
1030 res = OCRepPayloadSetPropByteStringAsOwner(curPayload, name, &tmp);
1035 OCRepPayload *pl = NULL;
1036 err = OCParseSingleRepPayload(&pl, &repMap, false);
1037 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting parse single rep");
1038 res = OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl);
1042 err = OCParseArray(curPayload, name, &repMap);
1045 OIC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type);
1048 if (type != CborArrayType)
1050 err = (CborError) !res;
1052 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting value");
1054 if (type != CborMapType && cbor_value_is_valid(&repMap))
1056 err = cbor_value_advance(&repMap);
1057 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advance repMap");
1062 if (cbor_value_is_container(objMap))
1064 err = cbor_value_leave_container(objMap, &repMap);
1065 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to leave container");
1072 OCRepPayloadDestroy(*outPayload);
1077 static OCStackResult OCParseRepPayload(OCPayload **outPayload, CborValue *root)
1079 OCStackResult ret = OC_STACK_INVALID_PARAM;
1081 OCRepPayload *temp = NULL;
1082 OCRepPayload *rootPayload = NULL;
1083 OCRepPayload *curPayload = NULL;
1084 CborValue rootMap = *root;
1085 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
1086 VERIFY_PARAM_NON_NULL(TAG, root, "Invalid Parameter root");
1089 if (cbor_value_is_array(root))
1091 err = cbor_value_enter_container(root, &rootMap);
1092 VERIFY_CBOR_SUCCESS(TAG, err, "Failed entering repMap");
1094 while (cbor_value_is_valid(&rootMap))
1096 temp = OCRepPayloadCreate();
1097 ret = OC_STACK_NO_MEMORY;
1098 VERIFY_PARAM_NON_NULL(TAG, temp, "Failed allocating memory");
1101 ret = OC_STACK_MALFORMED_RESPONSE;
1103 // temporary fix to check for malformed cbor payload
1104 if (!cbor_value_is_map(&rootMap) && !cbor_value_is_array(&rootMap)){
1108 if (cbor_value_is_map(&rootMap))
1110 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_HREF, &curVal);
1111 VERIFY_CBOR_SUCCESS(TAG, err, "to find href tag");
1112 if (cbor_value_is_valid(&curVal))
1115 err = cbor_value_dup_text_string(&curVal, &temp->uri, &len, NULL);
1116 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find uri");
1121 if (cbor_value_is_map(&rootMap))
1123 if (CborNoError == cbor_value_map_find_value(&rootMap, OC_RSRVD_RESOURCE_TYPE, &curVal))
1125 err = OCParseStringLL(&rootMap, OC_RSRVD_RESOURCE_TYPE, &temp->types);
1126 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find rt type tag/value");
1131 if (cbor_value_is_map(&rootMap))
1133 if (CborNoError == cbor_value_map_find_value(&rootMap, OC_RSRVD_INTERFACE, &curVal))
1135 err = OCParseStringLL(&rootMap, OC_RSRVD_INTERFACE, &temp->interfaces);
1136 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find interfaces tag/value");
1140 if (cbor_value_is_map(&rootMap))
1142 err = OCParseSingleRepPayload(&temp, &rootMap, true);
1143 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to parse single rep payload");
1146 if(rootPayload == NULL)
1153 curPayload->next = temp;
1154 curPayload = curPayload->next;
1157 if (cbor_value_is_array(&rootMap))
1159 err = cbor_value_advance(&rootMap);
1160 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to advance single rep payload");
1163 *outPayload = (OCPayload *)rootPayload;
1167 OCRepPayloadDestroy(temp);
1168 OCRepPayloadDestroy(rootPayload);
1169 OIC_LOG(ERROR, TAG, "CBOR error in ParseRepPayload");
1173 static OCStackResult OCParsePresencePayload(OCPayload **outPayload, CborValue *rootValue)
1175 OCStackResult ret = OC_STACK_INVALID_PARAM;
1176 OCPresencePayload *payload = NULL;
1177 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
1181 payload = (OCPresencePayload *)OICCalloc(1, sizeof(OCPresencePayload));
1182 ret = OC_STACK_NO_MEMORY;
1183 VERIFY_PARAM_NON_NULL(TAG, payload, "Failed allocating presence payload");
1184 payload->base.type = PAYLOAD_TYPE_PRESENCE;
1185 ret = OC_STACK_MALFORMED_RESPONSE;
1187 if (cbor_value_is_map(rootValue))
1192 CborError err = cbor_value_map_find_value(rootValue, OC_RSRVD_NONCE, &curVal);
1193 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding nonce tag");
1194 err = cbor_value_get_uint64(&curVal, (uint64_t *)&payload->sequenceNumber);
1195 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding nonce value");
1198 err = cbor_value_map_find_value(rootValue, OC_RSRVD_TTL, &curVal);
1199 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding ttl tag");
1200 err = cbor_value_get_uint64(&curVal, (uint64_t *)&payload->maxAge);
1201 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding ttl value");
1204 err = cbor_value_map_find_value(rootValue, OC_RSRVD_TRIGGER, &curVal);
1205 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding trigger tag");
1206 err = cbor_value_get_simple_type(&curVal, (uint8_t *)&payload->trigger);
1207 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding trigger value");
1209 // Resource type name
1210 err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &curVal);
1211 VERIFY_CBOR_SUCCESS(TAG, err, "to find res type tag");
1212 if (cbor_value_is_valid(&curVal))
1215 err = cbor_value_dup_text_string(&curVal, &payload->resourceType, &len, NULL);
1216 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding resource type value");
1219 err = cbor_value_advance(rootValue);
1220 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing root value");
1222 *outPayload = (OCPayload *)payload;
1226 OIC_LOG(ERROR, TAG, "CBOR error Parse Presence Payload");
1227 OCPresencePayloadDestroy(payload);