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);
46 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);
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_REPRESENTATION:
74 result = OCParseRepPayload(outPayload, &rootValue);
77 case PAYLOAD_TYPE_PRESENCE:
78 result = OCParsePresencePayload(outPayload, &rootValue);
81 case PAYLOAD_TYPE_SECURITY:
82 result = OCParseSecurityPayload(outPayload, payload, payloadSize);
85 OIC_LOG_V(ERROR, TAG, "ParsePayload Type default: %d", payloadType);
86 result = OC_STACK_INVALID_PARAM;
90 OIC_LOG_V(INFO, TAG, "Finished parse payload, result is %d", result);
96 static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, const uint8_t *payload,
101 *outPayload = (OCPayload *)OCSecurityPayloadCreate(payload, size);
110 static char* InPlaceStringTrim(char* str)
112 while (str[0] == ' ')
117 size_t lastchar = strlen(str);
119 while (str[lastchar] == ' ')
121 str[lastchar] = '\0';
128 static CborError OCParseStringLL(CborValue *map, char *type, OCStringLL **resource)
131 CborError err = cbor_value_map_find_value(map, type, &val);
132 VERIFY_CBOR_SUCCESS(TAG, err, "to find StringLL TAG");
134 if (cbor_value_is_array(&val))
137 err = cbor_value_enter_container(&val, &txtStr);
138 VERIFY_CBOR_SUCCESS(TAG, err, "to enter container");
139 while (cbor_value_is_text_string(&txtStr))
143 err = cbor_value_dup_text_string(&txtStr, &input, &len, NULL);
144 VERIFY_CBOR_SUCCESS(TAG, err, "to find StringLL value.");
147 char *savePtr = NULL;
148 char *curPtr = strtok_r(input, " ", &savePtr);
151 char *trimmed = InPlaceStringTrim(curPtr);
152 if (trimmed && strlen(trimmed) > 0)
154 if (!OCResourcePayloadAddStringLL(resource, trimmed))
156 return CborErrorOutOfMemory;
159 curPtr = strtok_r(NULL, " ", &savePtr);
163 if (cbor_value_is_text_string(&txtStr))
165 err = cbor_value_advance(&txtStr);
166 VERIFY_CBOR_SUCCESS(TAG, err, "to advance string value");
174 static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *rootValue)
176 OCStackResult ret = OC_STACK_INVALID_PARAM;
177 OCResourcePayload *resource = NULL;
178 OCDiscoveryPayload *temp = NULL;
179 OCDiscoveryPayload *rootPayload = NULL;
180 OCDiscoveryPayload *curPayload = NULL;
182 CborError err = CborNoError;
185 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
186 VERIFY_PARAM_NON_NULL(TAG, rootValue, "Invalid Parameter rootValue");
187 if (cbor_value_is_array(rootValue))
189 // Root value is already inside the main root array
192 // Enter the main root map
193 ret = OC_STACK_MALFORMED_RESPONSE;
194 err = cbor_value_enter_container(rootValue, &rootMap);
195 VERIFY_CBOR_SUCCESS(TAG, err, "to enter root map container");
196 while (cbor_value_is_map(&rootMap))
198 ret = OC_STACK_NO_MEMORY;
199 temp = OCDiscoveryPayloadCreate();
200 VERIFY_PARAM_NON_NULL(TAG, temp, "Failed error initializing discovery payload");
204 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_DEVICE_ID, &curVal);
205 VERIFY_CBOR_SUCCESS(TAG, err, "to find device id tag");
206 if (cbor_value_is_valid(&curVal))
208 if (cbor_value_is_byte_string(&curVal))
210 err = cbor_value_dup_byte_string(&curVal, (uint8_t **)&(temp->sid), &len, NULL);
211 VERIFY_CBOR_SUCCESS(TAG, err, "to copy device id value");
213 else if (cbor_value_is_text_string(&curVal))
215 err = cbor_value_dup_text_string(&curVal, &(temp->sid), &len, NULL);
216 VERIFY_CBOR_SUCCESS(TAG, err, "to copy device id value");
220 // BaseURI - Not a mandatory field
221 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_BASE_URI, &curVal);
222 VERIFY_CBOR_SUCCESS(TAG, err, "to find uri tag");
223 if (cbor_value_is_text_string(&curVal))
225 err = cbor_value_dup_text_string(&curVal, &(temp->baseURI), &len, NULL);
226 VERIFY_CBOR_SUCCESS(TAG, err, "to find base uri value");
229 // RT - Not a mandatory field
230 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_RESOURCE_TYPE, &curVal);
231 if (cbor_value_is_valid(&curVal))
233 err = OCParseStringLL(&rootMap, OC_RSRVD_RESOURCE_TYPE, &temp->type);
234 VERIFY_CBOR_SUCCESS(TAG, err, "to find resource type");
237 // IF - Not a mandatory field
238 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_INTERFACE, &curVal);
239 if (cbor_value_is_valid(&curVal))
241 err = OCParseStringLL(&rootMap, OC_RSRVD_INTERFACE, &temp->iface);
242 VERIFY_CBOR_SUCCESS(TAG, err, "to find interface");
245 // Name - Not a mandatory field
246 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_DEVICE_NAME, &curVal);
247 if (cbor_value_is_text_string(&curVal))
249 err = cbor_value_dup_text_string(&curVal, &temp->name, &len, NULL);
250 VERIFY_CBOR_SUCCESS(TAG, err, "to find device name");
253 // Look for Links which will have an array as the value
255 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_LINKS, &linkMap);
256 VERIFY_CBOR_SUCCESS(TAG, err, "to find links tag");
258 // Enter the links array and start iterating through the array processing
259 // each resource which shows up as a map.
260 CborValue resourceMap;
261 err = cbor_value_enter_container(&linkMap, &resourceMap);
262 VERIFY_CBOR_SUCCESS(TAG, err, "to enter link map");
264 while (cbor_value_is_map(&resourceMap))
268 resource = (OCResourcePayload *)OICCalloc(1, sizeof(OCResourcePayload));
269 VERIFY_PARAM_NON_NULL(TAG, resource, "Failed allocating resource payload");
272 err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_HREF, &curVal);
273 VERIFY_CBOR_SUCCESS(TAG, err, "to find href tag");
274 err = cbor_value_dup_text_string(&curVal, &(resource->uri), &len, NULL);
275 VERIFY_CBOR_SUCCESS(TAG, err, "to find href value");
278 err = OCParseStringLL(&resourceMap, OC_RSRVD_RESOURCE_TYPE, &resource->types);
279 VERIFY_CBOR_SUCCESS(TAG, err, "to find resource type tag/value");
282 err = OCParseStringLL(&resourceMap, OC_RSRVD_INTERFACE, &resource->interfaces);
283 if (CborNoError != err)
285 if (!OCResourcePayloadAddStringLL(&resource->interfaces, OC_RSRVD_INTERFACE_LL))
287 OIC_LOG(ERROR, TAG, "Failed to add string to StringLL");
294 err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_POLICY, &policyMap);
295 VERIFY_CBOR_SUCCESS(TAG, err, "to find policy tag");
298 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &curVal);
299 VERIFY_CBOR_SUCCESS(TAG, err, "to find bitmap tag");
300 err = cbor_value_get_int(&curVal, &bitmap);
301 VERIFY_CBOR_SUCCESS(TAG, err, "to find bitmap value");
302 resource->bitmap = (uint8_t)bitmap;
305 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &curVal);
306 VERIFY_CBOR_SUCCESS(TAG, err, "to find secure tag");
307 if (cbor_value_is_boolean(&curVal))
309 err = cbor_value_get_boolean(&curVal, &(resource->secure));
310 VERIFY_CBOR_SUCCESS(TAG, err, "to find secure value");
314 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT, &curVal);
315 VERIFY_CBOR_SUCCESS(TAG, err, "to find port tag");
316 if (cbor_value_is_integer(&curVal))
320 err = cbor_value_get_int(&curVal, &port);
321 VERIFY_CBOR_SUCCESS(TAG, err, "to find port value");
322 resource->port = (uint16_t)port;
327 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_TCP_PORT, &curVal);
328 if (cbor_value_is_integer(&curVal))
332 err = cbor_value_get_int(&curVal, &tcpPort);
333 VERIFY_CBOR_SUCCESS(TAG, err, "to find tcp port value");
334 resource->tcpPort = (uint16_t)tcpPort;
339 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_TLS_PORT, &curVal);
340 if (cbor_value_is_integer(&curVal))
344 err = cbor_value_get_int(&curVal, &tlsPort);
345 VERIFY_CBOR_SUCCESS(TAG, err, "to find tcp tls port value");
346 resource->tcpPort = (uint16_t)tlsPort;
351 err = cbor_value_advance(&resourceMap);
352 VERIFY_CBOR_SUCCESS(TAG, err, "to advance resource map");
354 OCDiscoveryPayloadAddNewResource(temp, resource);
357 err = cbor_value_leave_container(&linkMap, &resourceMap);
358 VERIFY_CBOR_SUCCESS(TAG, err, "to leave resource map");
360 err = cbor_value_advance(&rootMap);
361 VERIFY_CBOR_SUCCESS(TAG, err, "to advance root map");
363 if(rootPayload == NULL)
370 curPayload->next = temp;
371 curPayload = curPayload->next;
375 err = cbor_value_leave_container(rootValue, &rootMap);
376 VERIFY_CBOR_SUCCESS(TAG, err, "to leave root map");
381 OIC_LOG(ERROR, TAG, "Malformed packet ");
385 *outPayload = (OCPayload *)rootPayload;
386 OIC_LOG_PAYLOAD(DEBUG, *outPayload);
391 OCDiscoveryResourceDestroy(resource);
392 OCDiscoveryPayloadDestroy(rootPayload);
396 static OCRepPayloadPropType DecodeCborType(CborType type)
401 return OCREP_PROP_NULL;
402 case CborIntegerType:
403 return OCREP_PROP_INT;
406 return OCREP_PROP_DOUBLE;
407 case CborBooleanType:
408 return OCREP_PROP_BOOL;
409 case CborTextStringType:
410 return OCREP_PROP_STRING;
411 case CborByteStringType:
412 return OCREP_PROP_BYTE_STRING;
414 return OCREP_PROP_OBJECT;
416 return OCREP_PROP_ARRAY;
418 return OCREP_PROP_NULL;
421 static CborError OCParseArrayFindDimensionsAndType(const CborValue *parent,
422 size_t dimensions[MAX_REP_ARRAY_DEPTH], OCRepPayloadPropType *type)
424 CborValue insideArray;
425 *type = OCREP_PROP_NULL;
426 dimensions[0] = dimensions[1] = dimensions[2] = 0;
428 CborError err = cbor_value_enter_container(parent, &insideArray);
429 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to enter container");
431 while (cbor_value_is_valid(&insideArray))
433 OCRepPayloadPropType tempType = DecodeCborType(cbor_value_get_type(&insideArray));
435 if (tempType == OCREP_PROP_ARRAY)
437 size_t subdim[MAX_REP_ARRAY_DEPTH];
438 tempType = OCREP_PROP_NULL;
439 err = OCParseArrayFindDimensionsAndType(&insideArray, subdim, &tempType);
440 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to parse array");
444 OIC_LOG(ERROR, TAG, "Parse array helper, sub-array too deep");
447 dimensions[1] = dimensions[1] >= subdim[0] ? dimensions[1] : subdim[0];
448 dimensions[2] = dimensions[2] >= subdim[1] ? dimensions[2] : subdim[1];
450 if (*type != OCREP_PROP_NULL && tempType != OCREP_PROP_NULL && *type != tempType)
452 OIC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed (subtype)");
453 return CborUnknownError;
455 else if (*type == OCREP_PROP_NULL)
457 // We don't know the type of this array yet, so the assignment is OK
461 else if (*type == OCREP_PROP_NULL)
463 // We don't know the type of this array yet, so the assignment is OK
466 // tempType is allowed to be NULL, since it might now know the answer yet
467 else if (tempType != OCREP_PROP_NULL && *type != tempType)
469 // this is an invalid situation!
470 OIC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed");
471 return CborUnknownError;
475 err = cbor_value_advance(&insideArray);
476 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to advance array");
483 static size_t getAllocSize(OCRepPayloadPropType type)
488 return sizeof (int64_t);
489 case OCREP_PROP_DOUBLE:
490 return sizeof (double);
491 case OCREP_PROP_BOOL:
492 return sizeof (bool);
493 case OCREP_PROP_STRING:
494 return sizeof (char*);
495 case OCREP_PROP_BYTE_STRING:
496 return sizeof (OCByteString);
497 case OCREP_PROP_OBJECT:
498 return sizeof (OCRepPayload*);
504 static size_t arrayStep(size_t dimensions[MAX_REP_ARRAY_DEPTH], size_t elementNum)
507 (dimensions[1] == 0 ? 1 : dimensions[1]) *
508 (dimensions[2] == 0 ? 1 : dimensions[2]) *
512 static CborError OCParseArrayFillArray(const CborValue *parent,
513 size_t dimensions[MAX_REP_ARRAY_DEPTH], OCRepPayloadPropType type, void *targetArray)
515 CborValue insideArray;
518 char *tempStr = NULL;
519 OCByteString ocByteStr = { .bytes = NULL, .len = 0};
521 OCRepPayload *tempPl = NULL;
523 size_t newdim[MAX_REP_ARRAY_DEPTH];
524 newdim[0] = dimensions[1];
525 newdim[1] = dimensions[2];
528 CborError err = cbor_value_enter_container(parent, &insideArray);
529 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to enter container");
531 while (!err && i < dimensions[0] && cbor_value_is_valid(&insideArray))
533 bool noAdvance = false;
534 if (cbor_value_get_type(&insideArray) != CborNullType)
539 if (dimensions[1] == 0)
541 err = cbor_value_get_int64(&insideArray, &(((int64_t*)targetArray)[i]));
545 err = OCParseArrayFillArray(&insideArray, newdim, type,
546 &(((int64_t*)targetArray)[arrayStep(dimensions, i)]));
549 case OCREP_PROP_DOUBLE:
550 if (dimensions[1] == 0)
552 double *d = &(((double*)targetArray)[i]);
553 if (cbor_value_get_type(&insideArray) == CborDoubleType)
555 err = cbor_value_get_double(&insideArray, d);
561 err = cbor_value_get_float(&insideArray, &f);
568 err = OCParseArrayFillArray(&insideArray, newdim, type,
569 &(((double*)targetArray)[arrayStep(dimensions, i)]));
572 case OCREP_PROP_BOOL:
573 if (dimensions[1] == 0)
575 err = cbor_value_get_boolean(&insideArray, &(((bool*)targetArray)[i]));
579 err = OCParseArrayFillArray(&insideArray, newdim, type,
580 &(((bool*)targetArray)[arrayStep(dimensions, i)]));
583 case OCREP_PROP_STRING:
584 if (dimensions[1] == 0)
586 err = cbor_value_dup_text_string(&insideArray, &tempStr, &tempLen, NULL);
587 ((char**)targetArray)[i] = tempStr;
592 err = OCParseArrayFillArray(&insideArray, newdim, type,
593 &(((char**)targetArray)[arrayStep(dimensions, i)]));
596 case OCREP_PROP_BYTE_STRING:
597 if (dimensions[1] == 0)
599 err = cbor_value_dup_byte_string(&insideArray, &(ocByteStr.bytes),
600 &(ocByteStr.len), NULL);
601 ((OCByteString*)targetArray)[i] = ocByteStr;
605 err = OCParseArrayFillArray(&insideArray, newdim, type,
606 &(((OCByteString*)targetArray)[arrayStep(dimensions, i)]));
609 case OCREP_PROP_OBJECT:
610 if (dimensions[1] == 0)
612 err = OCParseSingleRepPayload(&tempPl, &insideArray, false);
613 ((OCRepPayload**)targetArray)[i] = tempPl;
619 err = OCParseArrayFillArray(&insideArray, newdim, type,
620 &(((OCRepPayload**)targetArray)[arrayStep(dimensions, i)]));
624 OIC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
625 err = CborErrorUnknownType;
628 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting repPayload");
631 if (!noAdvance && cbor_value_is_valid(&insideArray))
633 err = cbor_value_advance(&insideArray);
634 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advnce insideArray");
642 static CborError OCParseArray(OCRepPayload *out, const char *name, CborValue *container)
646 OCRepPayloadPropType type = OCREP_PROP_NULL;
647 size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
650 size_t allocSize = 0;
652 CborError err = OCParseArrayFindDimensionsAndType(container, dimensions, &type);
653 VERIFY_CBOR_SUCCESS(TAG, err, "Array details weren't clear");
655 if (type == OCREP_PROP_NULL)
657 res = OCRepPayloadSetNull(out, name);
658 err = (CborError) !res;
659 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting value");
660 container = container + 1;
664 dimTotal = calcDimTotal(dimensions);
665 allocSize = getAllocSize(type);
666 arr = OICCalloc(dimTotal, allocSize);
667 VERIFY_PARAM_NON_NULL(TAG, arr, "Array Parse allocation failed");
669 res = OCParseArrayFillArray(container, dimensions, type, arr);
670 VERIFY_CBOR_SUCCESS(TAG, err, "Failed parse array");
675 res = OCRepPayloadSetIntArrayAsOwner(out, name, (int64_t *)arr, dimensions);
677 case OCREP_PROP_DOUBLE:
678 res = OCRepPayloadSetDoubleArrayAsOwner(out, name, (double *)arr, dimensions);
680 case OCREP_PROP_BOOL:
681 res = OCRepPayloadSetBoolArrayAsOwner(out, name, (bool *)arr, dimensions);
683 case OCREP_PROP_STRING:
684 res = OCRepPayloadSetStringArrayAsOwner(out, name, (char **)arr, dimensions);
686 case OCREP_PROP_BYTE_STRING:
687 res = OCRepPayloadSetByteStringArrayAsOwner(out, name, (OCByteString *)arr, dimensions);
689 case OCREP_PROP_OBJECT:
690 res = OCRepPayloadSetPropObjectArrayAsOwner(out, name, (OCRepPayload**)arr, dimensions);
693 OIC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
696 err = (CborError) !res;
697 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting array parameter");
700 if (type == OCREP_PROP_STRING)
702 for(size_t i = 0; i < dimTotal; ++i)
704 OICFree(((char**)arr)[i]);
707 if (type == OCREP_PROP_BYTE_STRING)
709 for(size_t i = 0; i < dimTotal; ++i)
711 OICFree(((OCByteString*)arr)[i].bytes);
714 if (type == OCREP_PROP_OBJECT)
716 for(size_t i = 0; i < dimTotal; ++i)
718 OCRepPayloadDestroy(((OCRepPayload**)arr)[i]);
725 static CborError OCParseSingleRepPayload(OCRepPayload **outPayload, CborValue *objMap, bool isRoot)
727 CborError err = CborUnknownError;
730 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
731 VERIFY_PARAM_NON_NULL(TAG, objMap, "Invalid Parameter objMap");
733 if (cbor_value_is_map(objMap))
737 *outPayload = OCRepPayloadCreate();
740 return CborErrorOutOfMemory;
744 OCRepPayload *curPayload = *outPayload;
748 err = cbor_value_enter_container(objMap, &repMap);
749 VERIFY_CBOR_SUCCESS(TAG, err, "Failed entering repMap");
751 while (!err && cbor_value_is_valid(&repMap))
753 if (cbor_value_is_text_string(&repMap))
755 err = cbor_value_dup_text_string(&repMap, &name, &len, NULL);
756 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding tag name in the map");
757 err = cbor_value_advance(&repMap);
758 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing rootMap");
761 ((0 == strcmp(OC_RSRVD_HREF, name)) ||
762 (0 == strcmp(OC_RSRVD_RESOURCE_TYPE, name)) ||
763 (0 == strcmp(OC_RSRVD_INTERFACE, name))))
765 err = cbor_value_advance(&repMap);
771 CborType type = cbor_value_get_type(&repMap);
775 res = OCRepPayloadSetNull(curPayload, name);
777 case CborIntegerType:
780 err = cbor_value_get_int64(&repMap, &intval);
781 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting int value");
782 res = OCRepPayloadSetPropInt(curPayload, name, intval);
787 double doubleval = 0;
788 err = cbor_value_get_double(&repMap, &doubleval);
789 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting double value");
790 res = OCRepPayloadSetPropDouble(curPayload, name, doubleval);
793 case CborBooleanType:
795 bool boolval = false;
796 err = cbor_value_get_boolean(&repMap, &boolval);
797 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting boolean value");
798 res = OCRepPayloadSetPropBool(curPayload, name, boolval);
801 case CborTextStringType:
804 err = cbor_value_dup_text_string(&repMap, &strval, &len, NULL);
805 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting string value");
806 res = OCRepPayloadSetPropStringAsOwner(curPayload, name, strval);
809 case CborByteStringType:
811 uint8_t* bytestrval = NULL;
812 err = cbor_value_dup_byte_string(&repMap, &bytestrval, &len, NULL);
813 VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting byte string value");
814 OCByteString tmp = {.bytes = bytestrval, .len = len};
815 res = OCRepPayloadSetPropByteStringAsOwner(curPayload, name, &tmp);
820 OCRepPayload *pl = NULL;
821 err = OCParseSingleRepPayload(&pl, &repMap, false);
822 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting parse single rep");
823 res = OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl);
827 err = OCParseArray(curPayload, name, &repMap);
830 OIC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type);
833 if (type != CborArrayType)
835 err = (CborError) !res;
837 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting value");
839 if (type != CborMapType && cbor_value_is_valid(&repMap))
841 err = cbor_value_advance(&repMap);
842 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advance repMap");
847 if (cbor_value_is_container(objMap))
849 err = cbor_value_leave_container(objMap, &repMap);
850 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to leave container");
857 OCRepPayloadDestroy(*outPayload);
862 static OCStackResult OCParseRepPayload(OCPayload **outPayload, CborValue *root)
864 OCStackResult ret = OC_STACK_INVALID_PARAM;
866 OCRepPayload *temp = NULL;
867 OCRepPayload *rootPayload = NULL;
868 OCRepPayload *curPayload = NULL;
869 CborValue rootMap = *root;
870 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
871 VERIFY_PARAM_NON_NULL(TAG, root, "Invalid Parameter root");
874 if (cbor_value_is_array(root))
876 err = cbor_value_enter_container(root, &rootMap);
877 VERIFY_CBOR_SUCCESS(TAG, err, "Failed entering repMap");
879 while (cbor_value_is_valid(&rootMap))
881 temp = OCRepPayloadCreate();
882 ret = OC_STACK_NO_MEMORY;
883 VERIFY_PARAM_NON_NULL(TAG, temp, "Failed allocating memory");
886 ret = OC_STACK_MALFORMED_RESPONSE;
888 // temporary fix to check for malformed cbor payload
889 if (!cbor_value_is_map(&rootMap) && !cbor_value_is_array(&rootMap)){
893 if (cbor_value_is_map(&rootMap))
895 err = cbor_value_map_find_value(&rootMap, OC_RSRVD_HREF, &curVal);
896 VERIFY_CBOR_SUCCESS(TAG, err, "to find href tag");
897 if (cbor_value_is_text_string(&curVal))
900 err = cbor_value_dup_text_string(&curVal, &temp->uri, &len, NULL);
901 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find uri");
906 if (cbor_value_is_map(&rootMap))
908 if (CborNoError == cbor_value_map_find_value(&rootMap, OC_RSRVD_RESOURCE_TYPE, &curVal))
910 err = OCParseStringLL(&rootMap, OC_RSRVD_RESOURCE_TYPE, &temp->types);
911 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find rt type tag/value");
916 if (cbor_value_is_map(&rootMap))
918 if (CborNoError == cbor_value_map_find_value(&rootMap, OC_RSRVD_INTERFACE, &curVal))
920 err = OCParseStringLL(&rootMap, OC_RSRVD_INTERFACE, &temp->interfaces);
921 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find interfaces tag/value");
925 if (cbor_value_is_map(&rootMap))
927 err = OCParseSingleRepPayload(&temp, &rootMap, true);
928 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to parse single rep payload");
931 if(rootPayload == NULL)
938 curPayload->next = temp;
939 curPayload = curPayload->next;
942 if (cbor_value_is_array(&rootMap))
944 err = cbor_value_advance(&rootMap);
945 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to advance single rep payload");
948 *outPayload = (OCPayload *)rootPayload;
952 OCRepPayloadDestroy(temp);
953 OCRepPayloadDestroy(rootPayload);
954 OIC_LOG(ERROR, TAG, "CBOR error in ParseRepPayload");
959 static OCStackResult OCParsePresencePayload(OCPayload **outPayload, CborValue *rootValue)
961 OCStackResult ret = OC_STACK_INVALID_PARAM;
962 OCPresencePayload *payload = NULL;
963 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
967 payload = (OCPresencePayload *)OICCalloc(1, sizeof(OCPresencePayload));
968 ret = OC_STACK_NO_MEMORY;
969 VERIFY_PARAM_NON_NULL(TAG, payload, "Failed allocating presence payload");
970 payload->base.type = PAYLOAD_TYPE_PRESENCE;
971 ret = OC_STACK_MALFORMED_RESPONSE;
973 if (cbor_value_is_map(rootValue))
980 CborError err = cbor_value_map_find_value(rootValue, OC_RSRVD_NONCE, &curVal);
981 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding nonce tag");
982 err = cbor_value_get_uint64(&curVal, &temp);
983 payload->sequenceNumber = (uint32_t)temp;
984 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding nonce value");
987 err = cbor_value_map_find_value(rootValue, OC_RSRVD_TTL, &curVal);
988 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding ttl tag");
990 err = cbor_value_get_uint64(&curVal, &temp);
991 payload->maxAge = (uint32_t)temp;
992 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding ttl value");
995 err = cbor_value_map_find_value(rootValue, OC_RSRVD_TRIGGER, &curVal);
996 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding trigger tag");
997 err = cbor_value_get_simple_type(&curVal, &trigger);
998 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding trigger value");
999 payload->trigger = (OCPresenceTrigger)trigger;
1001 // Resource type name
1002 err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &curVal);
1003 VERIFY_CBOR_SUCCESS(TAG, err, "to find res type tag");
1004 if (cbor_value_is_text_string(&curVal))
1007 err = cbor_value_dup_text_string(&curVal, &payload->resourceType, &len, NULL);
1008 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding resource type value");
1011 err = cbor_value_advance(rootValue);
1012 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing root value");
1014 *outPayload = (OCPayload *)payload;
1018 OIC_LOG(ERROR, TAG, "CBOR error Parse Presence Payload");
1019 OCPresencePayloadDestroy(payload);
1022 #endif // WITH_PRESENCE