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
32 #include "oic_string.h"
33 #include "oic_malloc.h"
34 #include "ocpayload.h"
35 #include "ocpayloadcbor.h"
36 #include "ocstackinternal.h"
37 #include "payload_logging.h"
38 #include "platform_features.h"
40 #define TAG "OIC_RI_PAYLOADPARSE"
42 static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *arrayVal);
43 static CborError OCParseSingleRepPayload(OCRepPayload **outPayload, CborValue *repParent, bool isRoot);
44 static OCStackResult OCParseRepPayload(OCPayload **outPayload, CborValue *arrayVal);
45 static OCStackResult OCParsePresencePayload(OCPayload **outPayload, CborValue *arrayVal);
46 static OCStackResult OCParseSecurityPayload(OCPayload **outPayload, const uint8_t *payload, size_t size);
48 OCStackResult OCParsePayload(OCPayload **outPayload, OCPayloadType payloadType,
49 const uint8_t *payload, size_t payloadSize)
51 OCStackResult result = OC_STACK_MALFORMED_RESPONSE;
54 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Conversion of outPayload failed");
55 VERIFY_PARAM_NON_NULL(TAG, payload, "Invalid cbor payload value");
57 OIC_LOG_V(INFO, TAG, "CBOR Parsing size: %zu of Payload Type: %d, Payload:",
58 payloadSize, payloadType);
59 OIC_LOG_BUFFER(DEBUG, TAG, payload, payloadSize);
64 err = cbor_parser_init(payload, payloadSize, 0, &parser, &rootValue);
65 VERIFY_CBOR_SUCCESS(TAG, err, "Failed initializing init value")
69 case PAYLOAD_TYPE_DISCOVERY:
70 result = OCParseDiscoveryPayload(outPayload, &rootValue);
72 case PAYLOAD_TYPE_REPRESENTATION:
73 result = OCParseRepPayload(outPayload, &rootValue);
75 case PAYLOAD_TYPE_PRESENCE:
76 result = OCParsePresencePayload(outPayload, &rootValue);
78 case PAYLOAD_TYPE_SECURITY:
79 result = OCParseSecurityPayload(outPayload, payload, payloadSize);
82 OIC_LOG_V(ERROR, TAG, "ParsePayload Type default: %d", payloadType);
83 result = OC_STACK_INVALID_PARAM;
87 OIC_LOG_V(INFO, TAG, "Finished parse payload, result is %d", result);
93 static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, const uint8_t *payload,
98 *outPayload = (OCPayload *)OCSecurityPayloadCreate(payload, size);
107 static char* InPlaceStringTrim(char* str)
109 while (str[0] == ' ')
114 size_t lastchar = strlen(str);
116 while (str[lastchar] == ' ')
118 str[lastchar] = '\0';
125 static CborError OCParseStringLL(CborValue *map, char *type, OCStringLL **resource)
128 CborError err = cbor_value_map_find_value(map, type, &val);
129 VERIFY_CBOR_SUCCESS(TAG, err, "to find StringLL TAG");
131 if (cbor_value_is_array(&val))
134 err = cbor_value_enter_container(&val, &txtStr);
135 VERIFY_CBOR_SUCCESS(TAG, err, "to enter container");
136 while (cbor_value_is_text_string(&txtStr))
140 err = cbor_value_dup_text_string(&txtStr, &input, &len, NULL);
141 VERIFY_CBOR_SUCCESS(TAG, err, "to find StringLL value.");
144 char *savePtr = NULL;
145 char *curPtr = strtok_r(input, " ", &savePtr);
148 char *trimmed = InPlaceStringTrim(curPtr);
149 if (trimmed && strlen(trimmed) > 0)
151 if (!OCResourcePayloadAddStringLL(resource, trimmed))
153 return CborErrorOutOfMemory;
156 curPtr = strtok_r(NULL, " ", &savePtr);
160 if (cbor_value_is_text_string(&txtStr))
162 err = cbor_value_advance(&txtStr);
163 VERIFY_CBOR_SUCCESS(TAG, err, "to advance string value");
171 static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *rootValue)
173 OCStackResult ret = OC_STACK_INVALID_PARAM;
174 OCResourcePayload *resource = NULL;
175 OCDiscoveryPayload *temp = NULL;
176 OCDiscoveryPayload *rootPayload = NULL;
177 OCDiscoveryPayload *curPayload = NULL;
179 CborError err = CborNoError;
182 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
183 VERIFY_PARAM_NON_NULL(TAG, rootValue, "Invalid Parameter rootValue");
184 if (cbor_value_is_array(rootValue))
186 // Root value is already inside the main root array
189 // Enter the main root map
190 ret = OC_STACK_MALFORMED_RESPONSE;
191 err = cbor_value_enter_container(rootValue, &rootMap);
192 VERIFY_CBOR_SUCCESS(TAG, err, "to enter root map container");
193 while (cbor_value_is_map(&rootMap))
195 ret = OC_STACK_NO_MEMORY;
196 temp = OCDiscoveryPayloadCreate();
197 VERIFY_PARAM_NON_NULL(TAG, temp, "Failed error initializing discovery payload");
201 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_DEVICE_ID, &curVal);
202 VERIFY_CBOR_SUCCESS(TAG, err, "to find device id tag");
203 if (cbor_value_is_valid(&curVal))
205 if (cbor_value_is_byte_string(&curVal))
207 err = cbor_value_dup_byte_string(&curVal, (uint8_t **)&(temp->sid), &len, NULL);
208 VERIFY_CBOR_SUCCESS(TAG, err, "to copy device id value");
210 else if (cbor_value_is_text_string(&curVal))
212 err = cbor_value_dup_text_string(&curVal, &(temp->sid), &len, NULL);
213 VERIFY_CBOR_SUCCESS(TAG, err, "to copy device id value");
217 // BaseURI - Not a mandatory field
218 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_BASE_URI, &curVal);
219 VERIFY_CBOR_SUCCESS(TAG, err, "to find uri tag");
220 if (cbor_value_is_valid(&curVal))
222 err = cbor_value_dup_text_string(&curVal, &(temp->baseURI), &len, NULL);
223 VERIFY_CBOR_SUCCESS(TAG, err, "to find base uri value");
226 // HREF - Not a mandatory field
227 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_HREF, &curVal);
228 if (cbor_value_is_valid(&curVal))
230 err = cbor_value_dup_text_string(&curVal, &(temp->uri), &len, NULL);
231 VERIFY_CBOR_SUCCESS(TAG, err, "to find uri value");
234 // RT - Not a mandatory field
235 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_RESOURCE_TYPE, &curVal);
236 if (cbor_value_is_valid(&curVal))
238 err = OCParseStringLL(&rootMap, OC_RSRVD_RESOURCE_TYPE, &temp->type);
239 VERIFY_CBOR_SUCCESS(TAG, err, "to find base uri value");
242 // IF - Not a mandatory field
243 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_INTERFACE, &curVal);
244 if (cbor_value_is_valid(&curVal))
246 err = OCParseStringLL(&rootMap, OC_RSRVD_INTERFACE, &temp->iface);
250 if (!OCResourcePayloadAddStringLL(&temp->iface, OC_RSRVD_INTERFACE_LL))
252 err = CborErrorOutOfMemory;
256 // Name - Not a mandatory field
257 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_DEVICE_NAME, &curVal);
258 if (cbor_value_is_valid(&curVal))
260 err = cbor_value_dup_text_string(&curVal, &temp->name, &len, NULL);
261 VERIFY_CBOR_SUCCESS(TAG, err, "to find device name");
264 // Look for Links which will have an array as the value
266 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_LINKS, &linkMap);
267 VERIFY_CBOR_SUCCESS(TAG, err, "to find links tag");
269 // Enter the links array and start iterating through the array processing
270 // each resource which shows up as a map.
271 CborValue resourceMap;
272 err = cbor_value_enter_container(&linkMap, &resourceMap);
273 VERIFY_CBOR_SUCCESS(TAG, err, "to enter link map");
275 while (cbor_value_is_map(&resourceMap))
279 resource = (OCResourcePayload *)OICCalloc(1, sizeof(OCResourcePayload));
280 VERIFY_PARAM_NON_NULL(TAG, resource, "Failed allocating resource payload");
283 err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_HREF, &curVal);
284 VERIFY_CBOR_SUCCESS(TAG, err, "to find href tag");
285 err = cbor_value_dup_text_string(&curVal, &(resource->uri), &len, NULL);
286 VERIFY_CBOR_SUCCESS(TAG, err, "to find href value");
289 err = OCParseStringLL(&resourceMap, OC_RSRVD_RESOURCE_TYPE, &resource->types);
290 VERIFY_CBOR_SUCCESS(TAG, err, "to find resource type tag/value");
293 err = OCParseStringLL(&resourceMap, OC_RSRVD_INTERFACE, &resource->interfaces);
294 if (CborNoError != err)
296 if (!OCResourcePayloadAddStringLL(&resource->interfaces, OC_RSRVD_INTERFACE_LL))
298 OIC_LOG(ERROR, TAG, "Failed to add string to StringLL");
305 err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_POLICY, &policyMap);
306 VERIFY_CBOR_SUCCESS(TAG, err, "to find policy tag");
309 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &curVal);
310 VERIFY_CBOR_SUCCESS(TAG, err, "to find bitmap tag");
311 err = cbor_value_get_int(&curVal, &bitmap);
312 VERIFY_CBOR_SUCCESS(TAG, err, "to find bitmap value");
313 resource->bitmap = (uint8_t)bitmap;
316 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &curVal);
317 VERIFY_CBOR_SUCCESS(TAG, err, "to find secure tag");
318 if (cbor_value_is_valid(&curVal))
320 err = cbor_value_get_boolean(&curVal, &(resource->secure));
321 VERIFY_CBOR_SUCCESS(TAG, err, "to find secure value");
325 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT, &curVal);
326 VERIFY_CBOR_SUCCESS(TAG, err, "to find port tag");
327 if (cbor_value_is_valid(&curVal))
331 err = cbor_value_get_int(&curVal, &port);
332 VERIFY_CBOR_SUCCESS(TAG, err, "to find port value");
333 resource->port = (uint16_t)port;
338 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_TCP_PORT, &curVal);
339 if (cbor_value_is_valid(&curVal))
343 err = cbor_value_get_int(&curVal, &tcpPort);
344 VERIFY_CBOR_SUCCESS(TAG, err, "to find tcp port value");
345 resource->tcpPort = (uint16_t)tcpPort;
350 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_TLS_PORT, &curVal);
351 if (cbor_value_is_valid(&curVal))
355 err = cbor_value_get_int(&curVal, &tlsPort);
356 VERIFY_CBOR_SUCCESS(TAG, err, "to find tcp tls port value");
357 resource->tcpPort = (uint16_t)tlsPort;
362 err = cbor_value_advance(&resourceMap);
363 VERIFY_CBOR_SUCCESS(TAG, err, "to advance resource map");
365 OCDiscoveryPayloadAddNewResource(temp, resource);
368 err = cbor_value_leave_container(&linkMap, &resourceMap);
369 VERIFY_CBOR_SUCCESS(TAG, err, "to leave resource map");
371 err = cbor_value_advance(&rootMap);
372 VERIFY_CBOR_SUCCESS(TAG, err, "to advance root map");
374 if(rootPayload == NULL)
381 curPayload->next = temp;
382 curPayload = curPayload->next;
386 err = cbor_value_leave_container(rootValue, &rootMap);
387 VERIFY_CBOR_SUCCESS(TAG, err, "to leave root map");
392 OIC_LOG(ERROR, TAG, "Malformed packet ");
396 *outPayload = (OCPayload *)rootPayload;
397 OIC_LOG_PAYLOAD(DEBUG, *outPayload);
402 OCDiscoveryResourceDestroy(resource);
403 OCDiscoveryPayloadDestroy(rootPayload);
407 static OCRepPayloadPropType DecodeCborType(CborType type)
412 return OCREP_PROP_NULL;
413 case CborIntegerType:
414 return OCREP_PROP_INT;
417 return OCREP_PROP_DOUBLE;
418 case CborBooleanType:
419 return OCREP_PROP_BOOL;
420 case CborTextStringType:
421 return OCREP_PROP_STRING;
422 case CborByteStringType:
423 return OCREP_PROP_BYTE_STRING;
425 return OCREP_PROP_OBJECT;
427 return OCREP_PROP_ARRAY;
429 return OCREP_PROP_NULL;
432 static CborError OCParseArrayFindDimensionsAndType(const CborValue *parent,
433 size_t dimensions[MAX_REP_ARRAY_DEPTH], OCRepPayloadPropType *type)
435 CborValue insideArray;
436 *type = OCREP_PROP_NULL;
437 dimensions[0] = dimensions[1] = dimensions[2] = 0;
439 CborError err = cbor_value_enter_container(parent, &insideArray);
440 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to enter container");
442 while (cbor_value_is_valid(&insideArray))
444 OCRepPayloadPropType tempType = DecodeCborType(cbor_value_get_type(&insideArray));
446 if (tempType == OCREP_PROP_ARRAY)
448 size_t subdim[MAX_REP_ARRAY_DEPTH];
449 tempType = OCREP_PROP_NULL;
450 err = OCParseArrayFindDimensionsAndType(&insideArray, subdim, &tempType);
451 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to parse array");
455 OIC_LOG(ERROR, TAG, "Parse array helper, sub-array too deep");
458 dimensions[1] = dimensions[1] >= subdim[0] ? dimensions[1] : subdim[0];
459 dimensions[2] = dimensions[2] >= subdim[1] ? dimensions[2] : subdim[1];
461 if (*type != OCREP_PROP_NULL && tempType != OCREP_PROP_NULL && *type != tempType)
463 OIC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed (subtype)");
464 return CborUnknownError;
466 else if (*type == OCREP_PROP_NULL)
468 // We don't know the type of this array yet, so the assignment is OK
472 else if (*type == OCREP_PROP_NULL)
474 // We don't know the type of this array yet, so the assignment is OK
477 // tempType is allowed to be NULL, since it might now know the answer yet
478 else if (tempType != OCREP_PROP_NULL && *type != tempType)
480 // this is an invalid situation!
481 OIC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed");
482 return CborUnknownError;
486 err = cbor_value_advance(&insideArray);
487 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to advance array");
494 static size_t getAllocSize(OCRepPayloadPropType type)
499 return sizeof (int64_t);
500 case OCREP_PROP_DOUBLE:
501 return sizeof (double);
502 case OCREP_PROP_BOOL:
503 return sizeof (bool);
504 case OCREP_PROP_STRING:
505 return sizeof (char*);
506 case OCREP_PROP_BYTE_STRING:
507 return sizeof (OCByteString);
508 case OCREP_PROP_OBJECT:
509 return sizeof (OCRepPayload*);
515 static size_t arrayStep(size_t dimensions[MAX_REP_ARRAY_DEPTH], size_t elementNum)
518 (dimensions[1] == 0 ? 1 : dimensions[1]) *
519 (dimensions[2] == 0 ? 1 : dimensions[2]) *
523 static CborError OCParseArrayFillArray(const CborValue *parent,
524 size_t dimensions[MAX_REP_ARRAY_DEPTH], OCRepPayloadPropType type, void *targetArray)
526 CborValue insideArray;
529 char *tempStr = NULL;
530 OCByteString ocByteStr = { .bytes = NULL, .len = 0};
532 OCRepPayload *tempPl = NULL;
534 size_t newdim[MAX_REP_ARRAY_DEPTH];
535 newdim[0] = dimensions[1];
536 newdim[1] = dimensions[2];
539 CborError err = cbor_value_enter_container(parent, &insideArray);
540 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to enter container");
542 while (!err && i < dimensions[0] && cbor_value_is_valid(&insideArray))
544 bool noAdvance = false;
545 if (cbor_value_get_type(&insideArray) != CborNullType)
550 if (dimensions[1] == 0)
552 err = cbor_value_get_int64(&insideArray, &(((int64_t*)targetArray)[i]));
556 err = OCParseArrayFillArray(&insideArray, newdim, type,
557 &(((int64_t*)targetArray)[arrayStep(dimensions, i)]));
560 case OCREP_PROP_DOUBLE:
561 if (dimensions[1] == 0)
563 double *d = &(((double*)targetArray)[i]);
564 if (cbor_value_get_type(&insideArray) == CborDoubleType)
566 err = cbor_value_get_double(&insideArray, d);
572 err = cbor_value_get_float(&insideArray, &f);
579 err = OCParseArrayFillArray(&insideArray, newdim, type,
580 &(((double*)targetArray)[arrayStep(dimensions, i)]));
583 case OCREP_PROP_BOOL:
584 if (dimensions[1] == 0)
586 err = cbor_value_get_boolean(&insideArray, &(((bool*)targetArray)[i]));
590 err = OCParseArrayFillArray(&insideArray, newdim, type,
591 &(((bool*)targetArray)[arrayStep(dimensions, i)]));
594 case OCREP_PROP_STRING:
595 if (dimensions[1] == 0)
597 err = cbor_value_dup_text_string(&insideArray, &tempStr, &tempLen, NULL);
598 ((char**)targetArray)[i] = tempStr;
603 err = OCParseArrayFillArray(&insideArray, newdim, type,
604 &(((char**)targetArray)[arrayStep(dimensions, i)]));
607 case OCREP_PROP_BYTE_STRING:
608 if (dimensions[1] == 0)
610 err = cbor_value_dup_byte_string(&insideArray, &(ocByteStr.bytes),
611 &(ocByteStr.len), NULL);
612 ((OCByteString*)targetArray)[i] = ocByteStr;
616 err = OCParseArrayFillArray(&insideArray, newdim, type,
617 &(((OCByteString*)targetArray)[arrayStep(dimensions, i)]));
620 case OCREP_PROP_OBJECT:
621 if (dimensions[1] == 0)
623 err = OCParseSingleRepPayload(&tempPl, &insideArray, false);
624 ((OCRepPayload**)targetArray)[i] = tempPl;
630 err = OCParseArrayFillArray(&insideArray, newdim, type,
631 &(((OCRepPayload**)targetArray)[arrayStep(dimensions, i)]));
635 OIC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
636 err = CborErrorUnknownType;
639 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting repPayload");
642 if (!noAdvance && cbor_value_is_valid(&insideArray))
644 err = cbor_value_advance(&insideArray);
645 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advnce insideArray");
653 static CborError OCParseArray(OCRepPayload *out, const char *name, CborValue *container)
657 OCRepPayloadPropType type = OCREP_PROP_NULL;
658 size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
661 size_t allocSize = 0;
663 CborError err = OCParseArrayFindDimensionsAndType(container, dimensions, &type);
664 VERIFY_CBOR_SUCCESS(TAG, err, "Array details weren't clear");
666 if (type == OCREP_PROP_NULL)
668 res = OCRepPayloadSetNull(out, name);
669 err = (CborError) !res;
670 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting value");
671 container = container + 1;
675 dimTotal = calcDimTotal(dimensions);
676 allocSize = getAllocSize(type);
677 arr = OICCalloc(dimTotal, allocSize);
678 VERIFY_PARAM_NON_NULL(TAG, arr, "Array Parse allocation failed");
680 res = OCParseArrayFillArray(container, dimensions, type, arr);
681 VERIFY_CBOR_SUCCESS(TAG, err, "Failed parse array");
686 res = OCRepPayloadSetIntArrayAsOwner(out, name, (int64_t *)arr, dimensions);
688 case OCREP_PROP_DOUBLE:
689 res = OCRepPayloadSetDoubleArrayAsOwner(out, name, (double *)arr, dimensions);
691 case OCREP_PROP_BOOL:
692 res = OCRepPayloadSetBoolArrayAsOwner(out, name, (bool *)arr, dimensions);
694 case OCREP_PROP_STRING:
695 res = OCRepPayloadSetStringArrayAsOwner(out, name, (char **)arr, dimensions);
697 case OCREP_PROP_BYTE_STRING:
698 res = OCRepPayloadSetByteStringArrayAsOwner(out, name, (OCByteString *)arr, dimensions);
700 case OCREP_PROP_OBJECT:
701 res = OCRepPayloadSetPropObjectArrayAsOwner(out, name, (OCRepPayload**)arr, dimensions);
704 OIC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
707 err = (CborError) !res;
708 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting array parameter");
711 if (type == OCREP_PROP_STRING)
713 for(size_t i = 0; i < dimTotal; ++i)
715 OICFree(((char**)arr)[i]);
718 if (type == OCREP_PROP_BYTE_STRING)
720 for(size_t i = 0; i < dimTotal; ++i)
722 OICFree(((OCByteString*)arr)[i].bytes);
725 if (type == OCREP_PROP_OBJECT)
727 for(size_t i = 0; i < dimTotal; ++i)
729 OCRepPayloadDestroy(((OCRepPayload**)arr)[i]);
736 static CborError OCParseSingleRepPayload(OCRepPayload **outPayload, CborValue *objMap, bool isRoot)
738 CborError err = CborUnknownError;
741 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
742 VERIFY_PARAM_NON_NULL(TAG, objMap, "Invalid Parameter objMap");
744 if (cbor_value_is_map(objMap))
748 *outPayload = OCRepPayloadCreate();
751 return CborErrorOutOfMemory;
755 OCRepPayload *curPayload = *outPayload;
759 err = cbor_value_enter_container(objMap, &repMap);
760 VERIFY_CBOR_SUCCESS(TAG, err, "Failed entering repMap");
762 while (!err && cbor_value_is_valid(&repMap))
764 if (cbor_value_is_text_string(&repMap))
766 err = cbor_value_dup_text_string(&repMap, &name, &len, NULL);
767 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding tag name in the map");
768 err = cbor_value_advance(&repMap);
769 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing rootMap");
772 ((0 == strcmp(OC_RSRVD_HREF, name)) ||
773 (0 == strcmp(OC_RSRVD_RESOURCE_TYPE, name)) ||
774 (0 == strcmp(OC_RSRVD_INTERFACE, name))))
776 err = cbor_value_advance(&repMap);
781 CborType type = cbor_value_get_type(&repMap);
785 res = OCRepPayloadSetNull(curPayload, name);
787 case CborIntegerType:
790 err = cbor_value_get_int64(&repMap, &intval);
791 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting int value");
792 res = OCRepPayloadSetPropInt(curPayload, name, intval);
797 double doubleval = 0;
798 err = cbor_value_get_double(&repMap, &doubleval);
799 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting double value");
800 res = OCRepPayloadSetPropDouble(curPayload, name, doubleval);
803 case CborBooleanType:
805 bool boolval = false;
806 err = cbor_value_get_boolean(&repMap, &boolval);
807 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting boolean value");
808 res = OCRepPayloadSetPropBool(curPayload, name, boolval);
811 case CborTextStringType:
814 err = cbor_value_dup_text_string(&repMap, &strval, &len, NULL);
815 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting string value");
816 res = OCRepPayloadSetPropStringAsOwner(curPayload, name, strval);
819 case CborByteStringType:
821 uint8_t* bytestrval = NULL;
822 err = cbor_value_dup_byte_string(&repMap, &bytestrval, &len, NULL);
823 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting byte string value");
824 OCByteString tmp = {.bytes = bytestrval, .len = len};
825 res = OCRepPayloadSetPropByteStringAsOwner(curPayload, name, &tmp);
830 OCRepPayload *pl = NULL;
831 err = OCParseSingleRepPayload(&pl, &repMap, false);
832 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting parse single rep");
833 res = OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl);
837 err = OCParseArray(curPayload, name, &repMap);
840 OIC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type);
843 if (type != CborArrayType)
845 err = (CborError) !res;
847 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting value");
849 if (type != CborMapType && cbor_value_is_valid(&repMap))
851 err = cbor_value_advance(&repMap);
852 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advance repMap");
857 if (cbor_value_is_container(objMap))
859 err = cbor_value_leave_container(objMap, &repMap);
860 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to leave container");
867 OCRepPayloadDestroy(*outPayload);
872 static OCStackResult OCParseRepPayload(OCPayload **outPayload, CborValue *root)
874 OCStackResult ret = OC_STACK_INVALID_PARAM;
876 OCRepPayload *temp = NULL;
877 OCRepPayload *rootPayload = NULL;
878 OCRepPayload *curPayload = NULL;
879 CborValue rootMap = *root;
880 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
881 VERIFY_PARAM_NON_NULL(TAG, root, "Invalid Parameter root");
884 if (cbor_value_is_array(root))
886 err = cbor_value_enter_container(root, &rootMap);
887 VERIFY_CBOR_SUCCESS(TAG, err, "Failed entering repMap");
889 while (cbor_value_is_valid(&rootMap))
891 temp = OCRepPayloadCreate();
892 ret = OC_STACK_NO_MEMORY;
893 VERIFY_PARAM_NON_NULL(TAG, temp, "Failed allocating memory");
896 ret = OC_STACK_MALFORMED_RESPONSE;
898 // temporary fix to check for malformed cbor payload
899 if (!cbor_value_is_map(&rootMap) && !cbor_value_is_array(&rootMap)){
903 if (cbor_value_is_map(&rootMap))
905 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_HREF, &curVal);
906 VERIFY_CBOR_SUCCESS(TAG, err, "to find href tag");
907 if (cbor_value_is_valid(&curVal))
910 err = cbor_value_dup_text_string(&curVal, &temp->uri, &len, NULL);
911 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find uri");
916 if (cbor_value_is_map(&rootMap))
918 if (CborNoError == cbor_value_map_find_value(&rootMap, OC_RSRVD_RESOURCE_TYPE, &curVal))
920 err = OCParseStringLL(&rootMap, OC_RSRVD_RESOURCE_TYPE, &temp->types);
921 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find rt type tag/value");
926 if (cbor_value_is_map(&rootMap))
928 if (CborNoError == cbor_value_map_find_value(&rootMap, OC_RSRVD_INTERFACE, &curVal))
930 err = OCParseStringLL(&rootMap, OC_RSRVD_INTERFACE, &temp->interfaces);
931 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find interfaces tag/value");
935 if (cbor_value_is_map(&rootMap))
937 err = OCParseSingleRepPayload(&temp, &rootMap, true);
938 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to parse single rep payload");
941 if(rootPayload == NULL)
948 curPayload->next = temp;
949 curPayload = curPayload->next;
952 if (cbor_value_is_array(&rootMap))
954 err = cbor_value_advance(&rootMap);
955 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to advance single rep payload");
958 *outPayload = (OCPayload *)rootPayload;
962 OCRepPayloadDestroy(temp);
963 OCRepPayloadDestroy(rootPayload);
964 OIC_LOG(ERROR, TAG, "CBOR error in ParseRepPayload");
968 static OCStackResult OCParsePresencePayload(OCPayload **outPayload, CborValue *rootValue)
970 OCStackResult ret = OC_STACK_INVALID_PARAM;
971 OCPresencePayload *payload = NULL;
972 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
976 payload = (OCPresencePayload *)OICCalloc(1, sizeof(OCPresencePayload));
977 ret = OC_STACK_NO_MEMORY;
978 VERIFY_PARAM_NON_NULL(TAG, payload, "Failed allocating presence payload");
979 payload->base.type = PAYLOAD_TYPE_PRESENCE;
980 ret = OC_STACK_MALFORMED_RESPONSE;
982 if (cbor_value_is_map(rootValue))
989 CborError err = cbor_value_map_find_value(rootValue, OC_RSRVD_NONCE, &curVal);
990 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding nonce tag");
991 err = cbor_value_get_uint64(&curVal, &temp);
992 payload->sequenceNumber = (uint32_t)temp;
993 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding nonce value");
996 err = cbor_value_map_find_value(rootValue, OC_RSRVD_TTL, &curVal);
997 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding ttl tag");
999 err = cbor_value_get_uint64(&curVal, &temp);
1000 payload->maxAge = (uint32_t)temp;
1001 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding ttl value");
1004 err = cbor_value_map_find_value(rootValue, OC_RSRVD_TRIGGER, &curVal);
1005 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding trigger tag");
1006 err = cbor_value_get_simple_type(&curVal, &trigger);
1007 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding trigger value");
1008 payload->trigger = (OCPresenceTrigger)trigger;
1010 // Resource type name
1011 err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &curVal);
1012 VERIFY_CBOR_SUCCESS(TAG, err, "to find res type tag");
1013 if (cbor_value_is_valid(&curVal))
1016 err = cbor_value_dup_text_string(&curVal, &payload->resourceType, &len, NULL);
1017 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding resource type value");
1020 err = cbor_value_advance(rootValue);
1021 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing root value");
1023 *outPayload = (OCPayload *)payload;
1027 OIC_LOG(ERROR, TAG, "CBOR error Parse Presence Payload");
1028 OCPresencePayloadDestroy(payload);