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