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