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