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