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