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