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