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