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