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