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