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