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