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