[IOT-972] add type and interface to platform representation
[platform/upstream/iotivity.git] / resource / csdk / stack / src / ocpayloadparse.c
1 //******************************************************************
2 //
3 // Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
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
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
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.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
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
29 #include <string.h>
30 #include <stdlib.h>
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
39 #define TAG "OIC_RI_PAYLOADPARSE"
40
41 static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *arrayVal);
42 static OCStackResult OCParseDevicePayload(OCPayload **outPayload, CborValue *arrayVal);
43 static OCStackResult OCParsePlatformPayload(OCPayload **outPayload, CborValue *arrayVal);
44 static CborError OCParseSingleRepPayload(OCRepPayload **outPayload, CborValue *repParent, bool isRoot);
45 static OCStackResult OCParseRepPayload(OCPayload **outPayload, CborValue *arrayVal);
46 static OCStackResult OCParsePresencePayload(OCPayload **outPayload, CborValue *arrayVal);
47 static OCStackResult OCParseSecurityPayload(OCPayload **outPayload, CborValue * rrayVal);
48
49 OCStackResult OCParsePayload(OCPayload **outPayload, OCPayloadType payloadType,
50         const uint8_t *payload, size_t payloadSize)
51 {
52     OCStackResult result = OC_STACK_MALFORMED_RESPONSE;
53     CborError err;
54
55     VERIFY_PARAM_NON_NULL(TAG, outPayload, "Conversion of outPayload failed");
56     VERIFY_PARAM_NON_NULL(TAG, payload, "Invalid cbor payload value");
57
58     OIC_LOG_V(INFO, TAG, "CBOR Parsing size: %zu", payloadSize);
59
60     CborParser parser;
61     CborValue rootValue;
62
63     err = cbor_parser_init(payload, payloadSize, 0, &parser, &rootValue);
64     VERIFY_CBOR_SUCCESS(TAG, err, "Failed initializing init value")
65
66     switch(payloadType)
67     {
68         case PAYLOAD_TYPE_DISCOVERY:
69             result = OCParseDiscoveryPayload(outPayload, &rootValue);
70             break;
71         case PAYLOAD_TYPE_DEVICE:
72             result = OCParseDevicePayload(outPayload, &rootValue);
73             break;
74         case PAYLOAD_TYPE_PLATFORM:
75             result = OCParsePlatformPayload(outPayload, &rootValue);
76             break;
77         case PAYLOAD_TYPE_REPRESENTATION:
78             result = OCParseRepPayload(outPayload, &rootValue);
79             break;
80         case PAYLOAD_TYPE_PRESENCE:
81             result = OCParsePresencePayload(outPayload, &rootValue);
82             break;
83         case PAYLOAD_TYPE_SECURITY:
84             result = OCParseSecurityPayload(outPayload, &rootValue);
85             break;
86         case PAYLOAD_TYPE_RD:
87             result = OCRDCborToPayload(&rootValue, outPayload);
88             break;
89         default:
90             OIC_LOG_V(ERROR, TAG, "ParsePayload Type default: %d", payloadType);
91             result = OC_STACK_INVALID_PARAM;
92             break;
93     }
94
95     OIC_LOG_V(INFO, TAG, "Finished parse payload, result is %d", result);
96
97 exit:
98     return result;
99 }
100
101 void OCFreeOCStringLL(OCStringLL* ll);
102
103 static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* rootValue)
104 {
105     OCStackResult ret = OC_STACK_MALFORMED_RESPONSE;
106     CborError err;
107     char *securityData = NULL;
108
109     VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid parameter");
110     VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid cbor");
111
112     CborValue strVal;
113
114     err = cbor_value_enter_container(rootValue, &strVal);
115     VERIFY_CBOR_SUCCESS(TAG, err, "Failed entering container");
116     if (cbor_value_is_text_string(&strVal))
117     {
118         size_t len = 0;
119         err = cbor_value_dup_text_string(&strVal, &securityData, &len, NULL);
120         VERIFY_CBOR_SUCCESS(TAG, err, "Failed reading security data");
121         *outPayload = (OCPayload *)OCSecurityPayloadCreate(securityData);
122         VERIFY_PARAM_NON_NULL(TAG, *outPayload, "Invalid cbor");
123         ret = OC_STACK_OK;
124     }
125
126 exit:
127     OICFree(securityData);
128     return ret;
129
130 }
131
132 static char* InPlaceStringTrim(char* str)
133 {
134     while (str[0] == ' ')
135     {
136         ++str;
137     }
138
139     size_t lastchar = strlen(str);
140
141     while (str[lastchar] == ' ')
142     {
143         str[lastchar] = '\0';
144         --lastchar;
145     }
146
147     return str;
148 }
149
150 static CborError OCParseStringLL(CborValue *map, char *type, OCStringLL **resource)
151 {
152     CborValue val;
153     CborError err = cbor_value_map_find_value(map, type, &val);
154     VERIFY_CBOR_SUCCESS(TAG, err, "to find StringLL TAG");
155
156     if (cbor_value_is_text_string(&val))
157     {
158         char *input = NULL;
159         char *savePtr = NULL;
160         size_t len = 0;
161
162         err = cbor_value_dup_text_string(&val, &input, &len, NULL);
163         VERIFY_CBOR_SUCCESS(TAG, err, "to find StringLL value");
164
165         if (input)
166         {
167             char *curPtr = strtok_r(input, " ", &savePtr);
168             while (curPtr)
169             {
170                 char *trimmed = InPlaceStringTrim(curPtr);
171                 if (trimmed[0] !='\0')
172                 {
173                     if (!OCResourcePayloadAddStringLL(resource, trimmed))
174                     {
175                         return CborErrorOutOfMemory;
176                     }
177                 }
178                 curPtr = strtok_r(NULL, " ", &savePtr);
179             }
180             OICFree(input);
181         }
182     }
183 exit:
184     return err;
185 }
186
187 static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *rootValue)
188 {
189     OCStackResult ret = OC_STACK_INVALID_PARAM;
190     OCResourcePayload *resource = NULL;
191     OCDiscoveryPayload *out = NULL;
192     size_t len = 0;
193     CborError err = CborNoError;
194     *outPayload = NULL;
195
196     VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
197     VERIFY_PARAM_NON_NULL(TAG, rootValue, "Invalid Parameter rootValue");
198
199     // Root value is already inside the main root array
200     CborValue rootMap;
201     ret = OC_STACK_NO_MEMORY;
202     out = OCDiscoveryPayloadCreate();
203     VERIFY_PARAM_NON_NULL(TAG, out, "Failed error initializing discovery payload");
204
205     // Enter the main root map
206     ret = OC_STACK_MALFORMED_RESPONSE;
207     err = cbor_value_enter_container(rootValue, &rootMap);
208     VERIFY_CBOR_SUCCESS(TAG, err, "to enter root map container");
209
210     // Look for DI
211     CborValue curVal;
212     err = cbor_value_map_find_value(&rootMap, OC_RSRVD_DEVICE_ID, &curVal);
213     VERIFY_CBOR_SUCCESS(TAG, err, "to find device id tag");
214     if (cbor_value_is_valid(&curVal))
215     {
216         if (cbor_value_is_byte_string(&curVal))
217         {
218             err = cbor_value_dup_byte_string(&curVal, (uint8_t **)&(out->sid), &len, NULL);
219             VERIFY_CBOR_SUCCESS(TAG, err, "to copy device id value");
220         }
221         else if (cbor_value_is_text_string(&curVal))
222         {
223             err = cbor_value_dup_text_string(&curVal, &(out->sid), &len, NULL);
224             VERIFY_CBOR_SUCCESS(TAG, err, "to copy device id value");
225         }
226     }
227
228     // BaseURI - Not a mandatory field
229     err = cbor_value_map_find_value(&rootMap, OC_RSRVD_BASE_URI, &curVal);
230     if (cbor_value_is_valid(&curVal))
231     {
232         err = cbor_value_dup_text_string(&curVal, &(out->baseURI), &len, NULL);
233         VERIFY_CBOR_SUCCESS(TAG, err, "to find base uri value");
234     }
235
236     // HREF - Not a mandatory field
237     err = cbor_value_map_find_value(&rootMap, OC_RSRVD_HREF, &curVal);
238     if (cbor_value_is_valid(&curVal))
239     {
240         err = cbor_value_dup_text_string(&curVal, &(out->uri), &len, NULL);
241         VERIFY_CBOR_SUCCESS(TAG, err, "to find uri value");
242     }
243
244     // RT - Not a mandatory field
245     err = cbor_value_map_find_value(&rootMap, OC_RSRVD_RESOURCE_TYPE, &curVal);
246     if (cbor_value_is_valid(&curVal))
247     {
248         err = cbor_value_dup_text_string(&curVal, &(out->type), &len, NULL);
249         VERIFY_CBOR_SUCCESS(TAG, err, "to find base uri value");
250     }
251
252     // IF - Not a mandatory field
253     err = cbor_value_map_find_value(&rootMap, OC_RSRVD_INTERFACE, &curVal);
254     if (cbor_value_is_valid(&curVal))
255     {
256         err =  OCParseStringLL(&rootMap, OC_RSRVD_INTERFACE, &out->interface);
257     }
258     if (!out->interface)
259     {
260         if (!OCResourcePayloadAddStringLL(&out->interface, OC_RSRVD_INTERFACE_LL))
261         {
262             err = CborErrorOutOfMemory;
263         }
264     }
265
266     // Name - Not a mandatory field
267     err = cbor_value_map_find_value(&rootMap, OC_RSRVD_DEVICE_NAME, &curVal);
268     if (cbor_value_is_valid(&curVal))
269     {
270         err = cbor_value_dup_text_string(&curVal, &out->name, &len, NULL);
271         VERIFY_CBOR_SUCCESS(TAG, err, "to find device name");
272     }
273
274     // Look for Links which will have an array as the value
275     CborValue linkMap;
276     err = cbor_value_map_find_value(&rootMap, OC_RSRVD_LINKS, &linkMap);
277     VERIFY_CBOR_SUCCESS(TAG, err, "to find links tag");
278
279     // Enter the links array and start iterating through the array processing
280     // each resource which shows up as a map.
281     CborValue resourceMap;
282     err = cbor_value_enter_container(&linkMap, &resourceMap);
283     VERIFY_CBOR_SUCCESS(TAG, err, "to enter link map");
284
285     while (cbor_value_is_map(&resourceMap))
286     {
287         resource = (OCResourcePayload *)OICCalloc(1, sizeof(OCResourcePayload));
288         VERIFY_PARAM_NON_NULL(TAG, resource, "Failed allocating resource payload");
289
290         // Uri
291         err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_HREF, &curVal);
292         VERIFY_CBOR_SUCCESS(TAG, err, "to find href tag");
293         err = cbor_value_dup_text_string(&curVal, &(resource->uri), &len, NULL);
294         VERIFY_CBOR_SUCCESS(TAG, err, "to find href value");
295
296         // ResourceTypes
297         err =  OCParseStringLL(&resourceMap, OC_RSRVD_RESOURCE_TYPE, &resource->types);
298         VERIFY_CBOR_SUCCESS(TAG, err, "to find resource type tag/value");
299
300         // Interface Types
301         err =  OCParseStringLL(&resourceMap, OC_RSRVD_INTERFACE, &resource->interfaces);
302         if (CborNoError != err)
303         {
304             if (!OCResourcePayloadAddStringLL(&resource->interfaces, OC_RSRVD_INTERFACE_LL))
305             {
306                 err = CborErrorOutOfMemory;
307             }
308         }
309
310         // Policy
311         CborValue policyMap;
312         err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_POLICY, &policyMap);
313         VERIFY_CBOR_SUCCESS(TAG, err, "to find policy tag");
314
315         // Bitmap
316         err = cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &curVal);
317         VERIFY_CBOR_SUCCESS(TAG, err, "to find bitmap tag");
318         err = cbor_value_get_int(&curVal, (int *)&resource->bitmap);
319         VERIFY_CBOR_SUCCESS(TAG, err, "to find bitmap value");
320
321         // Secure Flag
322         err = cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &curVal);
323         if (cbor_value_is_valid(&curVal))
324         {
325             err = cbor_value_get_boolean(&curVal, &(resource->secure));
326             VERIFY_CBOR_SUCCESS(TAG, err, "to find secure value");
327         }
328
329         // Port
330         err = cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT, &curVal);
331         if (cbor_value_is_valid(&curVal))
332         {
333             err = cbor_value_get_int(&curVal, (int *)&resource->port);
334             VERIFY_CBOR_SUCCESS(TAG, err, "to find port value");
335         }
336
337         err = cbor_value_advance(&resourceMap);
338         VERIFY_CBOR_SUCCESS(TAG, err, "to advance resource map");
339
340         OCDiscoveryPayloadAddNewResource(out, resource);
341     }
342
343     err = cbor_value_leave_container(rootValue, &resourceMap);
344     VERIFY_CBOR_SUCCESS(TAG, err, "to advance resource map");
345
346     *outPayload = (OCPayload *)out;
347     OIC_LOG_PAYLOAD(DEBUG, *outPayload);
348
349     return OC_STACK_OK;
350
351 exit:
352     OCDiscoveryResourceDestroy(resource);
353     OCDiscoveryPayloadDestroy(out);
354     return ret;
355 }
356
357 static OCStackResult OCParseDevicePayload(OCPayload **outPayload, CborValue *rootValue)
358 {
359     OCStackResult ret = OC_STACK_INVALID_PARAM;
360     CborError err = CborNoError;
361     OCDevicePayload *out = NULL;
362     VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid param outPayload");
363     VERIFY_PARAM_NON_NULL(TAG, rootValue, "Invalid param rootValue");
364
365     *outPayload = NULL;
366
367     out = (OCDevicePayload *)OICCalloc(1, sizeof(OCDevicePayload));
368     VERIFY_PARAM_NON_NULL(TAG, out, "Failed allocating device payload")
369     out->base.type = PAYLOAD_TYPE_DEVICE;
370     ret = OC_STACK_MALFORMED_RESPONSE;
371
372     if (cbor_value_is_map(rootValue))
373     {
374         CborValue curVal;
375         // Resource Type
376         err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &curVal);
377         if (cbor_value_is_valid(&curVal))
378         {
379             err =  OCParseStringLL(rootValue, OC_RSRVD_RESOURCE_TYPE, &out->types);
380             VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find rt type tag/value");
381         }
382         // Device ID
383         size_t len = 0;
384         err = cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_ID, &curVal);
385         if (cbor_value_is_valid(&curVal))
386         {
387             if (cbor_value_is_byte_string(&curVal))
388             {
389                 err = cbor_value_dup_byte_string(&curVal, (uint8_t **)&out->sid, &len, NULL);
390                 VERIFY_CBOR_SUCCESS(TAG, err, "to find device id in device payload");
391             }
392             else if (cbor_value_is_text_string(&curVal))
393             {
394                 err = cbor_value_dup_text_string(&curVal, &out->sid, &len, NULL);
395                 VERIFY_CBOR_SUCCESS(TAG, err, "to find device id in device payload");
396             }
397         }
398         // Device Name
399         err = cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_NAME, &curVal);
400         if (cbor_value_is_valid(&curVal))
401         {
402             err = cbor_value_dup_text_string(&curVal, &out->deviceName, &len, NULL);
403             VERIFY_CBOR_SUCCESS(TAG, err, "to find device name in device payload");
404         }
405         // Device Spec Version
406         err = cbor_value_map_find_value(rootValue, OC_RSRVD_SPEC_VERSION, &curVal);
407         if (cbor_value_is_valid(&curVal))
408         {
409             err = cbor_value_dup_text_string(&curVal, &out->specVersion, &len, NULL);
410             VERIFY_CBOR_SUCCESS(TAG, err, "to find spec version in device payload");
411         }
412         // Data Model Version
413         err = cbor_value_map_find_value(rootValue, OC_RSRVD_DATA_MODEL_VERSION, &curVal);
414         if (cbor_value_is_valid(&curVal))
415         {
416             err = cbor_value_dup_text_string(&curVal, &out->dataModelVersion, &len, NULL);
417             VERIFY_CBOR_SUCCESS(TAG, err, "to find data model version in device payload");
418         }
419         err = cbor_value_advance(rootValue);
420         VERIFY_CBOR_SUCCESS(TAG, err, "to advance device payload");
421
422         *outPayload = (OCPayload *)out;
423         return OC_STACK_OK;
424     }
425
426 exit:
427     OCDevicePayloadDestroy(out);
428     return ret;
429 }
430
431 static OCStackResult OCParsePlatformPayload(OCPayload **outPayload, CborValue *rootValue)
432 {
433     OCStackResult ret = OC_STACK_INVALID_PARAM;
434     CborError err = CborNoError;
435     OCPlatformInfo info = {0};
436     char* rt = NULL;
437     OCStringLL* interfaces = NULL;
438     OCPlatformPayload* out = NULL;
439
440     VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
441
442     if (cbor_value_is_map(rootValue))
443     {
444         CborValue repVal;
445         size_t len = 0;
446         ret = OC_STACK_MALFORMED_RESPONSE;
447
448         // Platform ID
449         err = cbor_value_map_find_value(rootValue, OC_RSRVD_PLATFORM_ID, &repVal);
450         if (cbor_value_is_valid(&repVal))
451         {
452             err = cbor_value_dup_text_string(&repVal, &(info.platformID), &len, NULL);
453             VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find platformID in the platform payload");
454         }
455          // MFG Name
456         err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_NAME, &repVal);
457         if (cbor_value_is_valid(&repVal))
458         {
459             err = cbor_value_dup_text_string(&repVal, &(info.manufacturerName), &len, NULL);
460             VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find manufactureName in the platform payload");
461         }
462         // MFG URL
463         err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_URL, &repVal);
464         if (cbor_value_is_valid(&repVal))
465         {
466             err = cbor_value_dup_text_string(&repVal, &(info.manufacturerUrl), &len, NULL);
467             VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find manufactureUrl in the platform payload");
468         }
469         // Model Num
470         err = cbor_value_map_find_value(rootValue, OC_RSRVD_MODEL_NUM, &repVal);
471         if (cbor_value_is_valid(&repVal))
472         {
473             err = cbor_value_dup_text_string(&repVal, &(info.modelNumber), &len, NULL);
474             VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find modelNumber in the platform payload");
475         }
476         // Date of Mfg
477         err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_DATE, &repVal);
478         if (cbor_value_is_valid(&repVal))
479         {
480             err = cbor_value_dup_text_string(&repVal, &(info.dateOfManufacture), &len, NULL);
481             VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find dateOfManufacture in the platform payload");
482         }
483         // Platform Version
484         err = cbor_value_map_find_value(rootValue, OC_RSRVD_PLATFORM_VERSION, &repVal);
485         if (cbor_value_is_valid(&repVal))
486         {
487             err = cbor_value_dup_text_string(&repVal, &(info.platformVersion), &len, NULL);
488             VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find platformVersion in the platform payload");
489         }
490         // OS Version
491         err = cbor_value_map_find_value(rootValue, OC_RSRVD_OS_VERSION, &repVal);
492         if (cbor_value_is_valid(&repVal))
493         {
494             err = cbor_value_dup_text_string(&repVal, &(info.operatingSystemVersion), &len, NULL);
495             VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find OSVersion in the platform payload");
496         }
497         // Hardware Version
498         err = cbor_value_map_find_value(rootValue, OC_RSRVD_HARDWARE_VERSION, &repVal);
499         if(cbor_value_is_valid(&repVal))
500         {
501             err = cbor_value_dup_text_string(&repVal, &(info.hardwareVersion), &len, NULL);
502             VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find HWVersion in the platform payload");
503         }
504         // Firmware Version
505         err = cbor_value_map_find_value(rootValue, OC_RSRVD_FIRMWARE_VERSION, &repVal);
506         if(cbor_value_is_valid(&repVal))
507         {
508             err = cbor_value_dup_text_string(&repVal, &(info.firmwareVersion), &len, NULL);
509             VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find firmwareVersion in the platform payload");
510         }
511         // Support URL
512         err = cbor_value_map_find_value(rootValue, OC_RSRVD_SUPPORT_URL, &repVal);
513         if(cbor_value_is_valid(&repVal))
514         {
515             err = cbor_value_dup_text_string(&repVal, &(info.supportUrl), &len, NULL);
516             VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find supportUrl in the platform payload");
517         }
518         // System Time
519         err = cbor_value_map_find_value(rootValue, OC_RSRVD_SYSTEM_TIME, &repVal);
520         if(cbor_value_is_valid(&repVal))
521         {
522             err = cbor_value_dup_text_string(&repVal, &(info.systemTime), &len, NULL);
523             VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find systemTume in the platform payload");
524         }
525
526         // Resource type
527         err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &repVal);
528         if(cbor_value_is_valid(&repVal))
529         {
530             err = cbor_value_dup_text_string(&repVal, &rt, &len, NULL);
531             VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find resource type in the platform payload");
532         }
533
534         // Interface Types
535         err = cbor_value_map_find_value(rootValue, OC_RSRVD_INTERFACE, &repVal);
536         if(cbor_value_is_valid(&repVal))
537         {
538             err =  OCParseStringLL(rootValue, OC_RSRVD_INTERFACE, &interfaces);
539             VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find interfaces tag/value");
540         }
541
542         err = cbor_value_advance(rootValue);
543         VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find supportUrl in the platform payload");
544
545        out = (OCPlatformPayload *)OCPlatformPayloadCreateAsOwner(&info);
546        out->rt = rt;
547        out->interfaces = interfaces;
548        *outPayload = (OCPayload *)out;
549        return OC_STACK_OK;
550     }
551
552 exit:
553     OCPlatformInfoDestroy(&info);
554     OIC_LOG(ERROR, TAG, "CBOR error In ParsePlatformPayload");
555     return ret;
556 }
557
558 static OCRepPayloadPropType DecodeCborType(CborType type)
559 {
560     switch (type)
561     {
562         case CborNullType:
563             return OCREP_PROP_NULL;
564         case CborIntegerType:
565             return OCREP_PROP_INT;
566         case CborDoubleType:
567             return OCREP_PROP_DOUBLE;
568         case CborBooleanType:
569             return OCREP_PROP_BOOL;
570         case CborTextStringType:
571             return OCREP_PROP_STRING;
572         case CborByteStringType:
573             return OCREP_PROP_BYTE_STRING;
574         case CborMapType:
575             return OCREP_PROP_OBJECT;
576         case CborArrayType:
577             return OCREP_PROP_ARRAY;
578         default:
579             return OCREP_PROP_NULL;
580     }
581 }
582 static CborError OCParseArrayFindDimensionsAndType(const CborValue *parent,
583         size_t dimensions[MAX_REP_ARRAY_DEPTH], OCRepPayloadPropType *type)
584 {
585     CborValue insideArray;
586     *type = OCREP_PROP_NULL;
587     dimensions[0] = dimensions[1] = dimensions[2] = 0;
588
589     CborError err = cbor_value_enter_container(parent, &insideArray);
590     VERIFY_CBOR_SUCCESS(TAG, err, "Failed to enter container");
591
592     while (cbor_value_is_valid(&insideArray))
593     {
594         OCRepPayloadPropType tempType = DecodeCborType(cbor_value_get_type(&insideArray));
595
596         if (tempType == OCREP_PROP_ARRAY)
597         {
598             size_t subdim[MAX_REP_ARRAY_DEPTH];
599             tempType = OCREP_PROP_NULL;
600             err = OCParseArrayFindDimensionsAndType(&insideArray, subdim, &tempType);
601             VERIFY_CBOR_SUCCESS(TAG, err, "Failed to parse array");
602
603             if (subdim[2] != 0)
604             {
605                 OIC_LOG(ERROR, TAG, "Parse array helper, sub-array too deep");
606             }
607
608             dimensions[1] = dimensions[1] >= subdim[0] ? dimensions[1] : subdim[0];
609             dimensions[2] = dimensions[2] >= subdim[1] ? dimensions[2] : subdim[1];
610
611             if (*type != OCREP_PROP_NULL && tempType != OCREP_PROP_NULL && *type != tempType)
612             {
613                 OIC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed (subtype)");
614                 return CborUnknownError;
615             }
616             else if (*type == OCREP_PROP_NULL)
617             {
618                 // We don't know the type of this array yet, so the assignment is OK
619                 *type = tempType;
620             }
621         }
622         else if (*type == OCREP_PROP_NULL)
623         {
624             // We don't know the type of this array yet, so the assignment is OK
625             *type = tempType;
626         }
627         // tempType is allowed to be NULL, since it might now know the answer yet
628         else if (tempType != OCREP_PROP_NULL && *type != tempType)
629         {
630             // this is an invalid situation!
631             OIC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed");
632             return CborUnknownError;
633         }
634
635         ++dimensions[0];
636         err = cbor_value_advance(&insideArray);
637         VERIFY_CBOR_SUCCESS(TAG, err, "Failed to advance array");
638     }
639
640 exit:
641     return err;
642 }
643
644 static size_t getAllocSize(OCRepPayloadPropType type)
645 {
646     switch (type)
647     {
648         case OCREP_PROP_INT:
649             return sizeof (int64_t);
650         case OCREP_PROP_DOUBLE:
651             return sizeof (double);
652         case OCREP_PROP_BOOL:
653             return sizeof (bool);
654         case OCREP_PROP_STRING:
655             return sizeof (char*);
656         case OCREP_PROP_BYTE_STRING:
657             return sizeof (OCByteString);
658         case OCREP_PROP_OBJECT:
659             return sizeof (OCRepPayload*);
660         default:
661             return 0;
662     }
663 }
664
665 static size_t arrayStep(size_t dimensions[MAX_REP_ARRAY_DEPTH], size_t elementNum)
666 {
667     return
668         (dimensions[1] == 0 ? 1 : dimensions[1]) *
669         (dimensions[2] == 0 ? 1 : dimensions[2]) *
670         elementNum;
671 }
672
673 static CborError OCParseArrayFillArray(const CborValue *parent,
674         size_t dimensions[MAX_REP_ARRAY_DEPTH], OCRepPayloadPropType type, void *targetArray)
675 {
676     CborValue insideArray;
677
678     size_t i = 0;
679     char *tempStr = NULL;
680     OCByteString ocByteStr = { .bytes = NULL, .len = 0};
681     size_t tempLen = 0;
682     OCRepPayload *tempPl = NULL;
683
684     size_t newdim[MAX_REP_ARRAY_DEPTH];
685     newdim[0] = dimensions[1];
686     newdim[1] = dimensions[2];
687     newdim[2] = 0;
688
689     CborError err = cbor_value_enter_container(parent, &insideArray);
690     VERIFY_CBOR_SUCCESS(TAG, err, "Failed to enter container");
691
692     while (!err && i < dimensions[0] && cbor_value_is_valid(&insideArray))
693     {
694         bool noAdvance = false;
695         if (cbor_value_get_type(&insideArray) != CborNullType)
696         {
697             switch (type)
698             {
699                 case OCREP_PROP_INT:
700                     if (dimensions[1] == 0)
701                     {
702                         err = cbor_value_get_int64(&insideArray, &(((int64_t*)targetArray)[i]));
703                     }
704                     else
705                     {
706                         err = OCParseArrayFillArray(&insideArray, newdim, type,
707                             &(((int64_t*)targetArray)[arrayStep(dimensions, i)]));
708                     }
709                     break;
710                 case OCREP_PROP_DOUBLE:
711                     if (dimensions[1] == 0)
712                     {
713                         err = cbor_value_get_double(&insideArray, &(((double*)targetArray)[i]));
714                     }
715                     else
716                     {
717                         err = OCParseArrayFillArray(&insideArray, newdim, type,
718                             &(((double*)targetArray)[arrayStep(dimensions, i)]));
719                     }
720                     break;
721                 case OCREP_PROP_BOOL:
722                     if (dimensions[1] == 0)
723                     {
724                         err = cbor_value_get_boolean(&insideArray, &(((bool*)targetArray)[i]));
725                     }
726                     else
727                     {
728                         err = OCParseArrayFillArray(&insideArray, newdim, type,
729                             &(((bool*)targetArray)[arrayStep(dimensions, i)]));
730                     }
731                     break;
732                 case OCREP_PROP_STRING:
733                     if (dimensions[1] == 0)
734                     {
735                         err = cbor_value_dup_text_string(&insideArray, &tempStr, &tempLen, NULL);
736                         ((char**)targetArray)[i] = tempStr;
737                         tempStr = NULL;
738                     }
739                     else
740                     {
741                         err = OCParseArrayFillArray(&insideArray, newdim, type,
742                             &(((char**)targetArray)[arrayStep(dimensions, i)]));
743                     }
744                     break;
745                 case OCREP_PROP_BYTE_STRING:
746                     if (dimensions[1] == 0)
747                     {
748                         err = cbor_value_dup_byte_string(&insideArray, &(ocByteStr.bytes),
749                                 &(ocByteStr.len), NULL);
750                         ((OCByteString*)targetArray)[i] = ocByteStr;
751                     }
752                     else
753                     {
754                         err = OCParseArrayFillArray(&insideArray, newdim, type,
755                                 &(((OCByteString*)targetArray)[arrayStep(dimensions, i)]));
756                     }
757                     break;
758                 case OCREP_PROP_OBJECT:
759                     if (dimensions[1] == 0)
760                     {
761                         err = OCParseSingleRepPayload(&tempPl, &insideArray, false);
762                         ((OCRepPayload**)targetArray)[i] = tempPl;
763                         tempPl = NULL;
764                         noAdvance = true;
765                     }
766                     else
767                     {
768                         err = OCParseArrayFillArray(&insideArray, newdim, type,
769                             &(((OCRepPayload**)targetArray)[arrayStep(dimensions, i)]));
770                     }
771                     break;
772                 default:
773                     OIC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
774                     err = CborErrorUnknownType;
775                     break;
776             }
777             VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting repPayload");
778         }
779         ++i;
780         if (!noAdvance && cbor_value_is_valid(&insideArray))
781         {
782             err = cbor_value_advance(&insideArray);
783             VERIFY_CBOR_SUCCESS(TAG, err, "Failed advnce insideArray");
784         }
785     }
786
787 exit:
788     return err;
789 }
790
791 static CborError OCParseArray(OCRepPayload *out, const char *name, CborValue *container)
792 {
793     void *arr = NULL;
794     OCRepPayloadPropType type = OCREP_PROP_NULL;
795     size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
796     size_t dimTotal = 0;
797     size_t allocSize = 0;
798     bool res = true;
799     CborError err = OCParseArrayFindDimensionsAndType(container, dimensions, &type);
800     VERIFY_CBOR_SUCCESS(TAG, err, "Array details weren't clear");
801
802     if (type == OCREP_PROP_NULL)
803     {
804         res = OCRepPayloadSetNull(out, name);
805         err = (CborError) !res;
806         VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting value");
807         err = cbor_value_advance(container);
808         VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing container");
809         return err;
810     }
811
812     dimTotal = calcDimTotal(dimensions);
813     allocSize = getAllocSize(type);
814     arr = OICCalloc(dimTotal, allocSize);
815     VERIFY_PARAM_NON_NULL(TAG, arr, "Array Parse allocation failed");
816
817     res = OCParseArrayFillArray(container, dimensions, type, arr);
818     VERIFY_CBOR_SUCCESS(TAG, err, "Failed parse array");
819
820     switch (type)
821     {
822         case OCREP_PROP_INT:
823             res = OCRepPayloadSetIntArrayAsOwner(out, name, (int64_t *)arr, dimensions);
824             break;
825         case OCREP_PROP_DOUBLE:
826             res = OCRepPayloadSetDoubleArrayAsOwner(out, name, (double *)arr, dimensions);
827             break;
828         case OCREP_PROP_BOOL:
829             res = OCRepPayloadSetBoolArrayAsOwner(out, name, (bool *)arr, dimensions);
830             break;
831         case OCREP_PROP_STRING:
832             res = OCRepPayloadSetStringArrayAsOwner(out, name, (char **)arr, dimensions);
833             break;
834         case OCREP_PROP_BYTE_STRING:
835             res = OCRepPayloadSetByteStringArrayAsOwner(out, name, (OCByteString *)arr, dimensions);
836             break;
837         case OCREP_PROP_OBJECT:
838             res = OCRepPayloadSetPropObjectArrayAsOwner(out, name, (OCRepPayload**)arr, dimensions);
839             break;
840         default:
841             OIC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
842             break;
843     }
844     err = (CborError) !res;
845     VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting array parameter");
846     return CborNoError;
847 exit:
848     if (type == OCREP_PROP_STRING)
849     {
850         for(size_t i = 0; i < dimTotal; ++i)
851         {
852             OICFree(((char**)arr)[i]);
853         }
854     }
855     if (type == OCREP_PROP_BYTE_STRING)
856     {
857         for(size_t i = 0; i < dimTotal; ++i)
858         {
859             OICFree(((OCByteString*)arr)[i].bytes);
860         }
861     }
862     if (type == OCREP_PROP_OBJECT)
863     {
864         for(size_t i = 0; i < dimTotal; ++i)
865         {
866             OCRepPayloadDestroy(((OCRepPayload**)arr)[i]);
867         }
868     }
869     OICFree(arr);
870     return err;
871 }
872
873 static CborError OCParseSingleRepPayload(OCRepPayload **outPayload, CborValue *objMap, bool isRoot)
874 {
875     CborError err = CborUnknownError;
876     char *name = NULL;
877     bool res = false;
878     VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
879     VERIFY_PARAM_NON_NULL(TAG, objMap, "Invalid Parameter objMap");
880
881     if (cbor_value_is_map(objMap))
882     {
883         if (!*outPayload)
884         {
885             *outPayload = OCRepPayloadCreate();
886             if (!*outPayload)
887             {
888                 return CborErrorOutOfMemory;
889             }
890         }
891
892         OCRepPayload *curPayload = *outPayload;
893
894         size_t len = 0;
895         CborValue repMap;
896         err = cbor_value_enter_container(objMap, &repMap);
897         VERIFY_CBOR_SUCCESS(TAG, err, "Failed entering repMap");
898
899         while (!err && cbor_value_is_valid(&repMap))
900         {
901             if (cbor_value_is_text_string(&repMap))
902             {
903                 err = cbor_value_dup_text_string(&repMap, &name, &len, NULL);
904                 VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding tag name in the map");
905                 err = cbor_value_advance(&repMap);
906                 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing rootMap");
907                 if (name &&
908                     isRoot &&
909                     ((0 == strcmp(OC_RSRVD_HREF, name)) ||
910                      (0 == strcmp(OC_RSRVD_RESOURCE_TYPE, name)) ||
911                     (0 == strcmp(OC_RSRVD_INTERFACE, name))))
912                 {
913                     err = cbor_value_advance(&repMap);
914                     OICFree(name);
915                     continue;
916                 }
917             }
918             CborType type = cbor_value_get_type(&repMap);
919             switch (type)
920             {
921                 case CborNullType:
922                     res = OCRepPayloadSetNull(curPayload, name);
923                     break;
924                 case CborIntegerType:
925                     {
926                         int64_t intval = 0;
927                         err = cbor_value_get_int64(&repMap, &intval);
928                         VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting int value");
929                         res = OCRepPayloadSetPropInt(curPayload, name, intval);
930                     }
931                     break;
932                 case CborDoubleType:
933                     {
934                         double doubleval = 0;
935                         err = cbor_value_get_double(&repMap, &doubleval);
936                         VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting double value");
937                         res = OCRepPayloadSetPropDouble(curPayload, name, doubleval);
938                     }
939                     break;
940                 case CborBooleanType:
941                     {
942                         bool boolval = false;
943                         err = cbor_value_get_boolean(&repMap, &boolval);
944                         VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting boolean value");
945                         res = OCRepPayloadSetPropBool(curPayload, name, boolval);
946                     }
947                     break;
948                 case CborTextStringType:
949                     {
950                         char *strval = NULL;
951                         err = cbor_value_dup_text_string(&repMap, &strval, &len, NULL);
952                         VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting string value");
953                         res = OCRepPayloadSetPropStringAsOwner(curPayload, name, strval);
954                     }
955                     break;
956                 case CborByteStringType:
957                     {
958                         uint8_t* bytestrval = NULL;
959                         err = cbor_value_dup_byte_string(&repMap, &bytestrval, &len, NULL);
960                         VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting byte string value");
961                         OCByteString tmp = {.bytes = bytestrval, .len = len};
962                         res = OCRepPayloadSetPropByteStringAsOwner(curPayload, name, &tmp);
963                     }
964                     break;
965                 case CborMapType:
966                     {
967                         OCRepPayload *pl = NULL;
968                         err = OCParseSingleRepPayload(&pl, &repMap, false);
969                         VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting parse single rep");
970                         res = OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl);
971                     }
972                     break;
973                 case CborArrayType:
974                     err = OCParseArray(curPayload, name, &repMap);
975                     break;
976                 default:
977                     OIC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type);
978                     res = false;
979             }
980             if (type != CborArrayType)
981             {
982                 err = (CborError) !res;
983             }
984             VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting value");
985
986             if (type != CborMapType && cbor_value_is_valid(&repMap))
987             {
988                 err = cbor_value_advance(&repMap);
989                 VERIFY_CBOR_SUCCESS(TAG, err, "Failed advance repMap");
990             }
991             OICFree(name);
992             name = NULL;
993         }
994         if (cbor_value_is_container(objMap))
995         {
996             err = cbor_value_leave_container(objMap, &repMap);
997             VERIFY_CBOR_SUCCESS(TAG, err, "Failed to leave container");
998         }
999         return err;
1000     }
1001
1002 exit:
1003     OICFree(name);
1004     OCRepPayloadDestroy(*outPayload);
1005     *outPayload = NULL;
1006     return err;
1007 }
1008
1009 static OCStackResult OCParseRepPayload(OCPayload **outPayload, CborValue *root)
1010 {
1011     OCStackResult ret = OC_STACK_INVALID_PARAM;
1012     CborError err;
1013     OCRepPayload *temp = NULL;
1014     OCRepPayload *rootPayload = NULL;
1015     OCRepPayload *curPayload = NULL;
1016     CborValue rootMap = *root;
1017     VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
1018     VERIFY_PARAM_NON_NULL(TAG, root, "Invalid Parameter root");
1019
1020     *outPayload = NULL;
1021     if (cbor_value_is_array(root))
1022     {
1023         err = cbor_value_enter_container(root, &rootMap);
1024     }
1025     while (cbor_value_is_valid(&rootMap))
1026     {
1027         temp = OCRepPayloadCreate();
1028         ret = OC_STACK_NO_MEMORY;
1029         VERIFY_PARAM_NON_NULL(TAG, temp, "Failed allocating memory");
1030
1031         CborValue curVal;
1032         ret = OC_STACK_MALFORMED_RESPONSE;
1033
1034         // temporary fix to check for malformed cbor payload
1035         if (!cbor_value_is_map(&rootMap) && !cbor_value_is_array(&rootMap)){
1036             goto exit;
1037         }
1038
1039         if (cbor_value_is_map(&rootMap))
1040         {
1041             err = cbor_value_map_find_value(&rootMap, OC_RSRVD_HREF, &curVal);
1042             if (cbor_value_is_valid(&curVal))
1043             {
1044                 size_t len = 0;
1045                 err = cbor_value_dup_text_string(&curVal, &temp->uri, &len, NULL);
1046                 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find uri");
1047             }
1048         }
1049
1050         // Resource types
1051         if (cbor_value_is_map(&rootMap))
1052         {
1053             if (CborNoError == cbor_value_map_find_value(&rootMap, OC_RSRVD_RESOURCE_TYPE, &curVal))
1054             {
1055                 err =  OCParseStringLL(&rootMap, OC_RSRVD_RESOURCE_TYPE, &temp->types);
1056                 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find rt type tag/value");
1057             }
1058         }
1059
1060         // Interface Types
1061         if (cbor_value_is_map(&rootMap))
1062         {
1063             if (CborNoError == cbor_value_map_find_value(&rootMap, OC_RSRVD_INTERFACE, &curVal))
1064             {
1065                 err =  OCParseStringLL(&rootMap, OC_RSRVD_INTERFACE, &temp->interfaces);
1066                 VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find interfaces tag/value");
1067             }
1068         }
1069
1070         if (cbor_value_is_map(&rootMap))
1071         {
1072             err = OCParseSingleRepPayload(&temp, &rootMap, true);
1073             VERIFY_CBOR_SUCCESS(TAG, err, "Failed to parse single rep payload");
1074         }
1075
1076         if(rootPayload == NULL)
1077         {
1078             rootPayload = temp;
1079             curPayload = temp;
1080         }
1081         else
1082         {
1083             curPayload->next = temp;
1084             curPayload = curPayload->next;
1085         }
1086
1087         if (cbor_value_is_array(&rootMap))
1088         {
1089             err = cbor_value_advance(&rootMap);
1090             VERIFY_CBOR_SUCCESS(TAG, err, "Failed to advance single rep payload");
1091         }
1092     }
1093     *outPayload = (OCPayload *)rootPayload;
1094     return OC_STACK_OK;
1095
1096 exit:
1097     OCRepPayloadDestroy(temp);
1098     OCRepPayloadDestroy(rootPayload);
1099     OIC_LOG(ERROR, TAG, "CBOR error in ParseRepPayload");
1100     return ret;
1101 }
1102
1103 static OCStackResult OCParsePresencePayload(OCPayload **outPayload, CborValue *rootValue)
1104 {
1105     OCStackResult ret = OC_STACK_INVALID_PARAM;
1106     OCPresencePayload *payload = NULL;
1107     VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
1108
1109     *outPayload = NULL;
1110
1111     payload = (OCPresencePayload *)OICCalloc(1, sizeof(OCPresencePayload));
1112     ret = OC_STACK_NO_MEMORY;
1113     VERIFY_PARAM_NON_NULL(TAG, payload, "Failed allocating presence payload");
1114     payload->base.type = PAYLOAD_TYPE_PRESENCE;
1115     ret = OC_STACK_MALFORMED_RESPONSE;
1116
1117     if (cbor_value_is_map(rootValue))
1118     {
1119         CborValue curVal;
1120
1121         // Sequence Number
1122         CborError err = cbor_value_map_find_value(rootValue, OC_RSRVD_NONCE, &curVal);
1123         VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding nonce tag");
1124         err = cbor_value_get_uint64(&curVal, (uint64_t *)&payload->sequenceNumber);
1125         VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding nonce value");
1126
1127         // Max Age
1128         err = cbor_value_map_find_value(rootValue, OC_RSRVD_TTL, &curVal);
1129         VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding ttl tag");
1130         err = cbor_value_get_uint64(&curVal, (uint64_t *)&payload->maxAge);
1131         VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding ttl value");
1132
1133         // Trigger
1134         err = cbor_value_map_find_value(rootValue, OC_RSRVD_TRIGGER, &curVal);
1135         VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding trigger tag");
1136         err = cbor_value_get_simple_type(&curVal, (uint8_t *)&payload->trigger);
1137         VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding trigger value");
1138
1139         // Resource type name
1140         err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &curVal);
1141         if (cbor_value_is_valid(&curVal))
1142         {
1143             size_t len = 0;
1144             err = cbor_value_dup_text_string(&curVal, &payload->resourceType, &len, NULL);
1145             VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding resource type value");
1146         }
1147
1148         err = cbor_value_advance(rootValue);
1149         VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing root value");
1150
1151         *outPayload = (OCPayload *)payload;
1152         return OC_STACK_OK;
1153     }
1154 exit:
1155     OIC_LOG(ERROR, TAG, "CBOR error Parse Presence Payload");
1156     OCPresencePayloadDestroy(payload);
1157     return ret;
1158 }