RDServer discovery functionality
[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 #include "ocpayloadcbor.h"
22 #include <stdlib.h>
23 #include "logger.h"
24 #include "oic_malloc.h"
25 #include "ocstackinternal.h"
26 #include "ocpayload.h"
27 #include "cbor.h"
28
29 #define TAG PCF("OCPayloadParse")
30
31 static OCStackResult OCParseDiscoveryPayload(OCPayload** outPayload, CborValue* arrayVal);
32 static OCStackResult OCParseDevicePayload(OCPayload** outPayload, CborValue* arrayVal);
33 static OCStackResult OCParsePlatformPayload(OCPayload** outPayload, CborValue* arrayVal);
34 static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue* repParent);
35 static OCStackResult OCParseRepPayload(OCPayload** outPayload, CborValue* arrayVal);
36 static OCStackResult OCParsePresencePayload(OCPayload** outPayload, CborValue* arrayVal);
37 static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* arrayVal);
38
39 OCStackResult OCParsePayload(OCPayload** outPayload, const uint8_t* payload, size_t payloadSize)
40 {
41     CborParser parser;
42     CborValue rootValue;
43     bool err = false;
44
45     OC_LOG_V(INFO, TAG, "CBOR Parsing size: %d", payloadSize);
46     if((err = cbor_parser_init(payload, payloadSize, 0, &parser, &rootValue)) != false)
47     {
48         OC_LOG_V(ERROR, TAG, "CBOR Parser init failed: %d", err);
49         return OC_STACK_ERROR;
50     }
51
52     if(!cbor_value_is_array(&rootValue))
53     {
54         OC_LOG_V(ERROR, TAG, "CBOR payload root object is not an array :%x", rootValue.type);
55         return OC_STACK_MALFORMED_RESPONSE;
56     }
57
58     CborValue arrayValue;
59     // enter the array
60     err = err || cbor_value_enter_container(&rootValue, &arrayValue);
61
62     int payloadType = 0;
63     err = err || cbor_value_get_int(&arrayValue, &payloadType);
64     err = err || cbor_value_advance_fixed(&arrayValue);
65
66     if(err)
67     {
68         OC_LOG_V(ERROR, TAG, "CBOR payload parse failed :%d", err);
69         return OC_STACK_MALFORMED_RESPONSE;
70     }
71
72     OCStackResult result = OC_STACK_ERROR;
73     switch(payloadType)
74     {
75         case PAYLOAD_TYPE_DISCOVERY:
76             result = OCParseDiscoveryPayload(outPayload, &arrayValue);
77             break;
78         case PAYLOAD_TYPE_DEVICE:
79             result = OCParseDevicePayload(outPayload, &arrayValue);
80             break;
81         case PAYLOAD_TYPE_PLATFORM:
82             result = OCParsePlatformPayload(outPayload, &arrayValue);
83             break;
84         case PAYLOAD_TYPE_REPRESENTATION:
85             result = OCParseRepPayload(outPayload, &arrayValue);
86             break;
87         case PAYLOAD_TYPE_PRESENCE:
88             result = OCParsePresencePayload(outPayload, &arrayValue);
89             break;
90         case PAYLOAD_TYPE_SECURITY:
91             result = OCParseSecurityPayload(outPayload, &arrayValue);
92             break;
93 #ifdef WITH_RD
94         case PAYLOAD_TYPE_RD:
95             result = OCRDCborToPayload(&arrayValue, outPayload);
96             break;
97 #endif
98         default:
99             OC_LOG_V(ERROR, TAG, "ParsePayload Type default: %d", payloadType);
100             result = OC_STACK_ERROR;
101             break;
102     }
103
104     if(result == OC_STACK_OK)
105     {
106         err = err || cbor_value_leave_container(&rootValue, &arrayValue);
107         if(err != CborNoError)
108         {
109             return OC_STACK_MALFORMED_RESPONSE;
110         }
111     }
112     else
113     {
114         OC_LOG_V(INFO, TAG, "Finished parse payload, result is %d", result);
115     }
116
117     return result;
118 }
119
120 void OCFreeOCStringLL(OCStringLL* ll);
121
122 static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* arrayVal)
123 {
124     bool err = false;
125     char * securityData = NULL;
126
127     if(cbor_value_is_map(arrayVal))
128     {
129         CborValue curVal;
130         err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
131
132         if(cbor_value_is_valid(&curVal))
133         {
134             size_t len;
135             err = err || cbor_value_dup_text_string(&curVal, &securityData, &len, NULL);
136         }
137     }
138     else
139     {
140         OC_LOG_V(ERROR, TAG, PCF("Cbor main value not a map"));
141         return OC_STACK_MALFORMED_RESPONSE;
142     }
143
144     err = err || cbor_value_advance(arrayVal);
145
146     if(err)
147     {
148         OC_LOG_V(ERROR, TAG, "Cbor in error condition");
149         OICFree(securityData);
150         return OC_STACK_MALFORMED_RESPONSE;
151     }
152
153     *outPayload = (OCPayload*)OCSecurityPayloadCreate(securityData);
154     OICFree(securityData);
155
156     return OC_STACK_OK;
157
158 }
159
160 static OCStackResult OCParseDiscoveryPayload(OCPayload** outPayload, CborValue* arrayVal)
161 {
162     bool err = false;
163
164     OCDiscoveryPayload* out = OCDiscoveryPayloadCreate();
165
166     if(!out)
167     {
168         return OC_STACK_NO_MEMORY;
169     }
170
171     size_t resourceCount = 0;
172     while(!err &&
173             cbor_value_is_map(arrayVal))
174     {
175         OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
176         if(!resource)
177         {
178             OC_LOG_V(ERROR, TAG, "Memory allocation failed");
179             OCDiscoveryPayloadDestroy(out);
180             return OC_STACK_NO_MEMORY;
181         }
182         CborValue curVal;
183
184         // Uri
185         err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
186         size_t len;
187         err = err || cbor_value_dup_text_string(&curVal, &(resource->uri), &len, NULL);
188
189         // SID
190         err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_SERVER_INSTANCE_ID, &curVal);
191         err = err || cbor_value_dup_byte_string(&curVal, &(resource->sid), &len, NULL);
192
193         // Prop Tag
194         {
195              err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_PROPERTY, &curVal);
196             // ResourceTypes
197             CborValue rtArray;
198              err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_RESOURCE_TYPE, &rtArray);
199
200             CborValue rtVal;
201              err = err || cbor_value_enter_container(&rtArray, &rtVal);
202
203             OCStringLL* llPtr = NULL;
204             while(!err && cbor_value_is_text_string(&rtVal))
205             {
206                 if(resource->types == NULL)
207                 {
208                     resource->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
209                     llPtr = resource->types;
210                     if(!llPtr)
211                     {
212                         OC_LOG(ERROR, TAG, PCF("Memory allocation failed"));
213                         OICFree(resource->uri);
214                         OICFree(resource->sid);
215                         OICFree(resource);
216                         OCDiscoveryPayloadDestroy(out);
217                         return OC_STACK_NO_MEMORY;
218                     }
219                 }
220                 else if(llPtr)
221                 {
222                     llPtr->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
223                     llPtr = llPtr->next;
224                     if(!llPtr)
225                     {
226                         OC_LOG(ERROR, TAG, PCF("Memory allocation failed"));
227                         OICFree(resource->uri);
228                         OICFree(resource->sid);
229                         OCFreeOCStringLL(resource->types);
230                         OICFree(resource);
231                         OCDiscoveryPayloadDestroy(out);
232                         return OC_STACK_NO_MEMORY;
233                     }
234                 }
235                 else
236                 {
237                         OC_LOG(ERROR, TAG, PCF("Unknown state in resource type copying"));
238                         OICFree(resource->uri);
239                         OICFree(resource->sid);
240                         OCFreeOCStringLL(resource->types);
241                         OICFree(resource);
242                         OCDiscoveryPayloadDestroy(out);
243                         return OC_STACK_NO_MEMORY;
244                 }
245
246                  err = err || cbor_value_dup_text_string(&rtVal, &(llPtr->value), &len, NULL);
247                  err = err || cbor_value_advance(&rtVal);
248             }
249
250              err = err || cbor_value_leave_container(&rtArray, &rtVal);
251             //
252             // Interface Types
253             CborValue ifArray;
254              err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_INTERFACE, &ifArray);
255             CborValue ifVal;
256              err = err || cbor_value_enter_container(&ifArray, &ifVal);
257
258             llPtr = NULL;
259             while(!err && cbor_value_is_text_string(&ifVal))
260             {
261                 if(resource->interfaces == NULL)
262                 {
263                     resource->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
264                     llPtr = resource->interfaces;
265                     if(!llPtr)
266                     {
267                         OC_LOG_V(ERROR, TAG, "Memory allocation failed");
268                         OICFree(resource->uri);
269                         OICFree(resource->sid);
270                         OCFreeOCStringLL(resource->types);
271                         OICFree(resource);
272                         OCDiscoveryPayloadDestroy(out);
273                         return OC_STACK_NO_MEMORY;
274                     }
275                 }
276                 else if (llPtr)
277                 {
278                     llPtr->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
279                     llPtr = llPtr->next;
280                     if(!llPtr)
281                     {
282                         OC_LOG_V(ERROR, TAG, "Memory allocation failed");
283                         OICFree(resource->uri);
284                         OICFree(resource->sid);
285                         OCFreeOCStringLL(resource->types);
286                         OCFreeOCStringLL(resource->interfaces);
287                         OICFree(resource);
288                         OCDiscoveryPayloadDestroy(out);
289                         return OC_STACK_NO_MEMORY;
290                     }
291                 }
292                 else
293                 {
294                         OC_LOG(ERROR, TAG, PCF("Unknown state in resource interfaces copying"));
295                         OICFree(resource->uri);
296                         OICFree(resource->sid);
297                         OCFreeOCStringLL(resource->types);
298                         OICFree(resource);
299                         OCDiscoveryPayloadDestroy(out);
300                         return OC_STACK_NO_MEMORY;
301                 }
302
303                  err = err || cbor_value_dup_text_string(&ifVal, &(llPtr->value), &len, NULL);
304                  err = err || cbor_value_advance(&ifVal);
305             }
306              err = err || cbor_value_leave_container(&ifArray, &ifVal);
307
308             // Policy
309             {
310                 CborValue policyMap;
311                 err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_POLICY, &policyMap);
312
313                 // Bitmap
314                 CborValue val;
315                 err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &val);
316                 uint64_t temp = 0;
317                 err = err || cbor_value_get_uint64(&val, &temp);
318                 resource->bitmap = (uint8_t)temp;
319                 // Secure Flag
320                 err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &val);
321                 if(cbor_value_is_valid(&val))
322                 {
323                     err = err || cbor_value_get_boolean(&val, &(resource->secure));
324                     // Port
325                     CborValue port;
326                     err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT,
327                                     &port);
328                     if(cbor_value_is_valid(&port))
329                     {
330                         err = err || cbor_value_get_uint64(&port, &temp);
331                         resource->port = (uint16_t)temp;
332                     }
333                 }
334             }
335         }
336
337         err = err || cbor_value_advance(arrayVal);
338         if(err)
339         {
340             OICFree(resource->uri);
341             OICFree(resource->sid);
342             OCFreeOCStringLL(resource->types);
343             OCFreeOCStringLL(resource->interfaces);
344             OICFree(resource);
345             OCDiscoveryPayloadDestroy(out);
346             OC_LOG_V(ERROR, TAG, "CBOR in error condition", err);
347             return OC_STACK_MALFORMED_RESPONSE;
348         }
349         ++resourceCount;
350         OCDiscoveryPayloadAddNewResource(out, resource);
351     }
352
353     if(err)
354     {
355         OCDiscoveryPayloadDestroy(out);
356         return OC_STACK_MALFORMED_RESPONSE;
357     }
358     else
359     {
360         *outPayload = (OCPayload*)out;
361         return OC_STACK_OK;
362     }
363 }
364
365 static OCStackResult OCParseDevicePayload(OCPayload** outPayload, CborValue* arrayVal)
366 {
367     bool err = false;
368
369     if(cbor_value_is_map(arrayVal))
370     {
371         char* uri = NULL;
372         uint8_t* sid = NULL;
373         char* dname = NULL;
374         char* specVer = NULL;
375         char* dmVer = NULL;
376         CborValue curVal;
377          err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
378         size_t len;
379          err = err || cbor_value_dup_text_string(&curVal, &uri, &len, NULL);
380
381         // Representation
382         {
383              err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
384
385             CborValue repVal;
386             // Device ID
387              err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DEVICE_ID, &repVal);
388              err = err || cbor_value_dup_byte_string(&repVal, &sid, &len, NULL);
389             // Device Name
390              err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DEVICE_NAME, &repVal);
391              err = err || cbor_value_dup_text_string(&repVal, &dname, &len, NULL);
392             // Device Spec Version
393              err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SPEC_VERSION, &repVal);
394              err = err || cbor_value_dup_text_string(&repVal, &specVer, &len, NULL);
395             // Data Model Version
396              err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DATA_MODEL_VERSION, &repVal);
397              err = err || cbor_value_dup_text_string(&repVal, &dmVer, &len, NULL);
398
399         }
400
401          err = err || cbor_value_advance(arrayVal);
402
403         if(err)
404         {
405             OICFree(uri);
406             OICFree(sid);
407             OICFree(dname);
408             OICFree(specVer);
409             OICFree(dmVer);
410             OC_LOG_V(ERROR, TAG, "CBOR in error condition %d", err);
411             return OC_STACK_MALFORMED_RESPONSE;
412         }
413
414         *outPayload = (OCPayload*)OCDevicePayloadCreate(uri, sid, dname, specVer, dmVer);
415
416         OICFree(uri);
417         OICFree(sid);
418         OICFree(dname);
419         OICFree(specVer);
420         OICFree(dmVer);
421         if(!*outPayload)
422         {
423             return OC_STACK_NO_MEMORY;
424         }
425
426         return OC_STACK_OK;
427     }
428     else
429     {
430         OC_LOG(ERROR, TAG, PCF("Root device node was not a map"));
431         return OC_STACK_MALFORMED_RESPONSE;
432     }
433
434 }
435
436 static OCStackResult OCParsePlatformPayload(OCPayload** outPayload, CborValue* arrayVal)
437 {
438     bool err = false;
439
440     if(cbor_value_is_map(arrayVal))
441     {
442         char* uri = NULL;
443         OCPlatformInfo info = {0};
444         CborValue curVal;
445          err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
446         size_t len;
447          err = err || cbor_value_dup_text_string(&curVal, &uri, &len, NULL);
448
449         // Representation
450         {
451              err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
452
453             CborValue repVal;
454             // Platform ID
455              err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_PLATFORM_ID, &repVal);
456              err = err || cbor_value_dup_text_string(&repVal, &(info.platformID), &len, NULL);
457
458             // MFG Name
459              err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_NAME, &repVal);
460              err = err || cbor_value_dup_text_string(&repVal, &(info.manufacturerName), &len, NULL);
461
462             // MFG URL
463              err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_URL, &repVal);
464             if(cbor_value_is_valid(&repVal))
465             {
466                  err = err || cbor_value_dup_text_string(&repVal, &(info.manufacturerUrl), &len, NULL);
467             }
468
469             // Model Num
470              err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MODEL_NUM, &repVal);
471             if(cbor_value_is_valid(&repVal))
472             {
473                  err = err || cbor_value_dup_text_string(&repVal, &(info.modelNumber), &len, NULL);
474             }
475
476             // Date of Mfg
477              err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_DATE, &repVal);
478             if(cbor_value_is_valid(&repVal))
479             {
480                  err = err || cbor_value_dup_text_string(&repVal, &(info.dateOfManufacture), &len,
481                         NULL);
482             }
483
484             // Platform Version
485              err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_PLATFORM_VERSION, &repVal);
486             if(cbor_value_is_valid(&repVal))
487             {
488                  err = err || cbor_value_dup_text_string(&repVal, &(info.platformVersion), &len,
489                         NULL);
490             }
491
492             // OS Version
493              err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_OS_VERSION, &repVal);
494             if(cbor_value_is_valid(&repVal))
495             {
496                  err = err || cbor_value_dup_text_string(&repVal, &(info.operatingSystemVersion),
497                         &len, NULL);
498             }
499
500             // Hardware Version
501              err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_HARDWARE_VERSION, &repVal);
502             if(cbor_value_is_valid(&repVal))
503             {
504                  err = err || cbor_value_dup_text_string(&repVal, &(info.hardwareVersion), &len,
505                         NULL);
506             }
507
508             // Firmware Version
509              err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_FIRMWARE_VERSION, &repVal);
510             if(cbor_value_is_valid(&repVal))
511             {
512                  err = err || cbor_value_dup_text_string(&repVal, &(info.firmwareVersion), &len,
513                         NULL);
514             }
515
516             // Support URL
517              err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SUPPORT_URL, &repVal);
518             if(cbor_value_is_valid(&repVal))
519             {
520                  err = err || cbor_value_dup_text_string(&repVal, &(info.supportUrl), &len, NULL);
521             }
522
523             // System Time
524              err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SYSTEM_TIME, &repVal);
525             if(cbor_value_is_valid(&repVal))
526             {
527                  err = err || cbor_value_dup_text_string(&repVal, &(info.systemTime), &len, NULL);
528             }
529         }
530
531          err = err || cbor_value_advance(arrayVal);
532
533         if(err)
534         {
535             OICFree(info.dateOfManufacture);
536             OICFree(info.firmwareVersion);
537             OICFree(info.hardwareVersion);
538             OICFree(info.manufacturerName);
539             OICFree(info.manufacturerUrl);
540             OICFree(info.modelNumber);
541             OICFree(info.operatingSystemVersion);
542             OICFree(info.platformID);
543             OICFree(info.platformVersion);
544             OICFree(info.supportUrl);
545             OICFree(info.systemTime);
546             OC_LOG(ERROR, TAG, PCF("CBOR error In ParsePlatformPayload"));
547             return OC_STACK_MALFORMED_RESPONSE;
548         }
549
550         *outPayload = (OCPayload*)OCPlatformPayloadCreateAsOwner(uri, &info);
551
552         if(!*outPayload)
553         {
554             return OC_STACK_NO_MEMORY;
555         }
556
557         return OC_STACK_OK;
558     }
559     else
560     {
561         OC_LOG(ERROR, TAG, PCF("Root device node was not a map"));
562         return OC_STACK_MALFORMED_RESPONSE;
563     }
564 }
565
566 static bool OCParseArray(OCRepPayload* out, const char* name, CborValue* container)
567 {
568     CborValue insideArray;
569     bool err = false;
570     uint64_t tempInt = 0;
571     OCRepPayloadPropType type;
572     size_t dimensions[MAX_REP_ARRAY_DEPTH];
573     err = err || cbor_value_enter_container(container, &insideArray);
574
575     err = err || cbor_value_get_uint64(&insideArray, &tempInt);
576     err = err || cbor_value_advance_fixed(&insideArray);
577     type = (OCRepPayloadPropType)tempInt;
578
579     for(int i = 0; i < MAX_REP_ARRAY_DEPTH; ++ i)
580     {
581          err = err || cbor_value_get_uint64(&insideArray, &tempInt);
582          err = err || cbor_value_advance_fixed(&insideArray);
583         dimensions[i] = tempInt;
584     }
585
586     size_t dimTotal = calcDimTotal(dimensions);
587
588     void* arr = NULL;
589     char* tempStr;
590     size_t len;
591     OCRepPayload* pl;
592     switch(type)
593     {
594         case OCREP_PROP_INT:
595             arr = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
596             if (arr)
597             {
598                 for(size_t i = 0; i < dimTotal && !err; ++i)
599                 {
600                      err = err || cbor_value_get_int64(&insideArray, &(((int64_t*)arr)[i]));
601                      err = err || cbor_value_advance_fixed(&insideArray);
602                 }
603                 if(err || !OCRepPayloadSetIntArrayAsOwner(out, name, (int64_t*)arr, dimensions))
604                 {
605                     OICFree(arr);
606                     err = true;
607                 }
608             }
609             else
610             {
611                 err = true;
612             }
613             break;
614         case OCREP_PROP_DOUBLE:
615             arr = (double*)OICMalloc(dimTotal * sizeof(double));
616             if(arr)
617             {
618                 for(size_t i = 0; i < dimTotal && !err; ++i)
619                 {
620                      err = err || cbor_value_get_double(&insideArray, &(((double*)arr)[i]));
621                      err = err || cbor_value_advance_fixed(&insideArray);
622                 }
623                 if(err || !OCRepPayloadSetDoubleArrayAsOwner(out, name, (double*)arr, dimensions))
624                 {
625                     OICFree(arr);
626                     err = true;
627                 }
628             }
629             else
630             {
631                 err = true;
632             }
633             break;
634         case OCREP_PROP_BOOL:
635             arr = (bool*)OICMalloc(dimTotal * sizeof(bool));
636             if(arr)
637             {
638                 for(size_t i = 0; i < dimTotal && !err; ++i)
639                 {
640                      err = err || cbor_value_get_boolean(&insideArray, &(((bool*)arr)[i]));
641                      err = err || cbor_value_advance_fixed(&insideArray);
642                 }
643                 if(err && !OCRepPayloadSetBoolArrayAsOwner(out, name, (bool*)arr, dimensions))
644                 {
645                     OICFree(arr);
646                     err = true;
647                 }
648             }
649             else
650             {
651                 err = true;
652             }
653             break;
654         case OCREP_PROP_STRING:
655             arr = (char**)OICMalloc(dimTotal * sizeof(char*));
656             if(arr)
657             {
658                 for(size_t i = 0; i < dimTotal && !err; ++i)
659                 {
660                     err = err || cbor_value_dup_text_string(&insideArray, &tempStr,
661                             &len, NULL);
662                     err = err || cbor_value_advance(&insideArray);
663                     ((char**)arr)[i] = tempStr;
664                 }
665                 if(err || !OCRepPayloadSetStringArrayAsOwner(out, name, (char**)arr, dimensions))
666                 {
667                     OICFree(arr);
668                     err = true;
669                 }
670             }
671             else
672             {
673                 err = true;
674             }
675             break;
676         case OCREP_PROP_OBJECT:
677             arr = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
678             if(arr)
679             {
680                 for(size_t i = 0; i < dimTotal && !err; ++i)
681                 {
682                     pl = NULL;
683                     err = err || OCParseSingleRepPayload(&pl, &insideArray);
684                     err = err || cbor_value_advance(&insideArray);
685                     ((OCRepPayload**)arr)[i] = pl;
686                 }
687                 if(err || !OCRepPayloadSetPropObjectArrayAsOwner(out, name,
688                         (OCRepPayload**)arr, dimensions))
689                 {
690                     OICFree(arr);
691                     err = true;
692                 }
693             }
694             else
695             {
696                 err = true;
697             }
698             break;
699         default:
700             OC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
701             err = true;
702             break;
703     }
704
705     return err;
706 }
707
708 static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue* repParent)
709 {
710     *outPayload = OCRepPayloadCreate();
711     OCRepPayload* curPayload = *outPayload;
712     bool err = false;
713     if(!*outPayload)
714     {
715         return CborErrorOutOfMemory;
716     }
717
718     size_t len;
719     CborValue curVal;
720     err = err || cbor_value_map_find_value(repParent, OC_RSRVD_HREF, &curVal);
721     if(cbor_value_is_valid(&curVal))
722     {
723         err = err || cbor_value_dup_text_string(&curVal, &curPayload->uri, &len,
724             NULL);
725     }
726
727     err = err || cbor_value_map_find_value(repParent, OC_RSRVD_PROPERTY, &curVal);
728     if(cbor_value_is_valid(&curVal))
729     {
730         CborValue insidePropArray = {0};
731         err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_RESOURCE_TYPE,
732                 &insidePropArray);
733
734         if(cbor_value_is_array(&insidePropArray))
735         {
736             CborValue rtArray;
737             err = err || cbor_value_enter_container(&insidePropArray, &rtArray);
738
739             while(!err && cbor_value_is_valid(&rtArray))
740             {
741                 char* curRt;
742                 err = err || cbor_value_dup_text_string(&rtArray, &curRt, &len, NULL);
743                 err = err || cbor_value_advance(&rtArray);
744                 OCRepPayloadAddResourceTypeAsOwner(curPayload, curRt);
745             }
746
747             err = err || cbor_value_leave_container(&insidePropArray, &rtArray);
748         }
749
750         err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_INTERFACE, &insidePropArray);
751
752         if(cbor_value_is_array(&insidePropArray))
753         {
754             CborValue ifArray;
755             err = err || cbor_value_enter_container(&insidePropArray, &ifArray);
756
757             while(!err && cbor_value_is_valid(&ifArray))
758             {
759                 char* curIf;
760                 err = err || cbor_value_dup_text_string(&ifArray, &curIf, &len, NULL);
761                 err = err || cbor_value_advance(&ifArray);
762                 OCRepPayloadAddInterfaceAsOwner(curPayload, curIf);
763             }
764
765             err = err || cbor_value_leave_container(&insidePropArray, &ifArray);
766         }
767     }
768     err = err || cbor_value_map_find_value(repParent, OC_RSRVD_REPRESENTATION, &curVal);
769     if(cbor_value_is_map(&curVal))
770     {
771         CborValue repMap;
772         err = err || cbor_value_enter_container(&curVal, &repMap);
773
774         while(!err && cbor_value_is_valid(&repMap))
775         {
776             char* name;
777              err = err || cbor_value_dup_text_string(&repMap, &name, &len, NULL);
778
779              err = err || cbor_value_advance(&repMap);
780
781             int64_t intval = 0;
782             bool boolval = false;
783             char* strval = NULL;
784             double doubleval = 0;
785             OCRepPayload* pl;
786
787             switch(cbor_value_get_type(&repMap))
788             {
789                 case CborNullType:
790                     err = !OCRepPayloadSetNull(curPayload, name);
791                     break;
792                 case CborIntegerType:
793                     err = err || cbor_value_get_int64(&repMap, &intval);
794                     if (!err)
795                     {
796                         err = !OCRepPayloadSetPropInt(curPayload, name, intval);
797                     }
798                     break;
799                 case CborDoubleType:
800                     err = err || cbor_value_get_double(&repMap, &doubleval);
801                     if (!err)
802                     {
803                         err = !OCRepPayloadSetPropDouble(curPayload, name, doubleval);
804                     }
805                     break;
806                 case CborBooleanType:
807                     err = err || cbor_value_get_boolean(&repMap, &boolval);
808                     if (!err)
809                     {
810                         err = !OCRepPayloadSetPropBool(curPayload, name, boolval);
811                     }
812                     break;
813                 case CborTextStringType:
814                     err = err || cbor_value_dup_text_string(&repMap, &strval, &len, NULL);
815                     if (!err)
816                     {
817                         err = !OCRepPayloadSetPropStringAsOwner(curPayload, name, strval);
818                     }
819                     break;
820                 case CborMapType:
821                     err = err || OCParseSingleRepPayload(&pl, &repMap);
822                     if (!err)
823                     {
824                         err = !OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl);
825                     }
826                     break;
827                 case CborArrayType:
828                     err = err || OCParseArray(curPayload, name, &repMap);
829                     break;
830                 default:
831                     OC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type);
832                     err = true;
833             }
834
835              err = err || cbor_value_advance(&repMap);
836             OICFree(name);
837         }
838         err = err || cbor_value_leave_container(&curVal, &repMap);
839     }
840
841     if(err)
842     {
843         OCRepPayloadDestroy(*outPayload);
844         *outPayload = NULL;
845     }
846
847     return err;
848 }
849 static OCStackResult OCParseRepPayload(OCPayload** outPayload, CborValue* arrayVal)
850 {
851     bool err = false;
852
853     OCRepPayload* rootPayload = NULL;
854     OCRepPayload* curPayload = NULL;
855     OCRepPayload* temp = NULL;
856     while(!err && cbor_value_is_map(arrayVal))
857     {
858          err = err || OCParseSingleRepPayload(&temp, arrayVal);
859
860         if(rootPayload == NULL)
861         {
862             rootPayload = temp;
863             curPayload = temp;
864         }
865         else
866         {
867             curPayload->next = temp;
868             curPayload = curPayload->next;
869         }
870
871
872          err = err || cbor_value_advance(arrayVal);
873         if(err)
874         {
875             OCRepPayloadDestroy(rootPayload);
876             OC_LOG_V(ERROR, TAG, PCF("CBOR error in ParseRepPayload"));
877             return OC_STACK_MALFORMED_RESPONSE;
878         }
879     }
880
881     *outPayload = (OCPayload*)rootPayload;
882
883     return OC_STACK_OK;
884 }
885
886 static OCStackResult OCParsePresencePayload(OCPayload** outPayload, CborValue* arrayVal)
887 {
888     bool err = false;
889     if(cbor_value_is_map(arrayVal))
890     {
891         uint64_t seqNum = 0;
892         uint64_t maxAge = 0;
893         OCPresenceTrigger trigger = OC_PRESENCE_TRIGGER_CREATE;
894         char* tempStr = NULL;
895         size_t len = 0;
896
897         CborValue curVal;
898         // Sequence Number
899         err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_NONCE, &curVal);
900         err = err || cbor_value_get_uint64(&curVal, &seqNum);
901
902         // Max Age
903         err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_TTL, &curVal);
904         err = err || cbor_value_get_uint64(&curVal, &maxAge);
905
906         // Trigger
907         err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_TRIGGER, &curVal);
908         err = err || cbor_value_dup_text_string(&curVal, &tempStr, &len, NULL);
909         trigger = convertTriggerStringToEnum(tempStr);
910         OICFree(tempStr);
911         tempStr = NULL;
912
913         // Resource type name
914          err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_RESOURCE_TYPE, &curVal);
915         if(cbor_value_is_valid(&curVal))
916         {
917              err = err || cbor_value_dup_text_string(&curVal, &tempStr, &len, NULL);
918         }
919
920         err = err || cbor_value_advance(arrayVal);
921
922         if(!err)
923         {
924             *outPayload = (OCPayload*)OCPresencePayloadCreate(seqNum, maxAge, trigger, tempStr);
925         }
926         OICFree(tempStr);
927
928         if(err)
929         {
930             OCPayloadDestroy(*outPayload);
931             OC_LOG_V(ERROR, TAG, PCF("CBOR error Parse Presence Payload"));
932             return OC_STACK_MALFORMED_RESPONSE;
933         }
934
935         if(!*outPayload)
936         {
937             return OC_STACK_NO_MEMORY;
938         }
939
940         return OC_STACK_OK;
941     }
942     else
943     {
944         OC_LOG(ERROR, TAG, PCF("Root presence node was not a map"));
945         return OC_STACK_MALFORMED_RESPONSE;
946     }
947 }