Parsing about a payload including resource information of multiple devices
[platform/upstream/iotivity.git] / resource / csdk / stack / src / ocpayload.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 // Required for strok_r
22 #define _POSIX_C_SOURCE 200112L
23
24 #include <stdio.h>
25 #include "ocpayload.h"
26 #include "octypes.h"
27 #include <string.h>
28 #include "oic_malloc.h"
29 #include "oic_string.h"
30 #include "ocstackinternal.h"
31 #include "ocresource.h"
32 #include "logger.h"
33 #include "rdpayload.h"
34
35 #define TAG "OIC_RI_PAYLOAD"
36 #define CSV_SEPARATOR ','
37
38 static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val);
39
40 void OCPayloadDestroy(OCPayload* payload)
41 {
42     if (!payload)
43     {
44         return;
45     }
46
47     switch(payload->type)
48     {
49         case PAYLOAD_TYPE_REPRESENTATION:
50             OCRepPayloadDestroy((OCRepPayload*)payload);
51             break;
52         case PAYLOAD_TYPE_DISCOVERY:
53             OCDiscoveryPayloadDestroy((OCDiscoveryPayload*)payload);
54             break;
55         case PAYLOAD_TYPE_DEVICE:
56             OCDevicePayloadDestroy((OCDevicePayload*)payload);
57             break;
58         case PAYLOAD_TYPE_PLATFORM:
59             OCPlatformPayloadDestroy((OCPlatformPayload*)payload);
60             break;
61         case PAYLOAD_TYPE_PRESENCE:
62             OCPresencePayloadDestroy((OCPresencePayload*)payload);
63             break;
64         case PAYLOAD_TYPE_SECURITY:
65             OCSecurityPayloadDestroy((OCSecurityPayload*)payload);
66             break;
67         case PAYLOAD_TYPE_RD:
68            OCRDPayloadDestroy((OCRDPayload*)payload);
69            break;
70         default:
71             OIC_LOG_V(ERROR, TAG, "Unsupported payload type in destroy: %d", payload->type);
72             OICFree(payload);
73             break;
74     }
75 }
76 OCRepPayload* OCRepPayloadCreate()
77 {
78     OCRepPayload* payload = (OCRepPayload*)OICCalloc(1, sizeof(OCRepPayload));
79
80     if (!payload)
81     {
82         return NULL;
83     }
84
85     payload->base.type = PAYLOAD_TYPE_REPRESENTATION;
86
87     return payload;
88 }
89
90 void OCRepPayloadAppend(OCRepPayload* parent, OCRepPayload* child)
91 {
92     if (!parent)
93     {
94         return;
95     }
96
97     while(parent->next)
98     {
99         parent = parent->next;
100     }
101
102     parent->next= child;
103     child->next = NULL;
104 }
105
106 static OCRepPayloadValue* OCRepPayloadFindValue(const OCRepPayload* payload, const char* name)
107 {
108     if (!payload || !name)
109     {
110         return NULL;
111     }
112
113     OCRepPayloadValue* val = payload->values;
114     while(val)
115     {
116         if (0 == strcmp(val->name, name))
117         {
118             return val;
119         }
120         val = val->next;
121     }
122
123     return NULL;
124 }
125
126 static void OCCopyPropertyValueArray(OCRepPayloadValue* dest, OCRepPayloadValue* source)
127 {
128     if (!dest || !source)
129     {
130         return;
131     }
132
133     size_t dimTotal = calcDimTotal(source->arr.dimensions);
134     switch(source->arr.type)
135     {
136         case OCREP_PROP_INT:
137             dest->arr.iArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
138             VERIFY_PARAM_NON_NULL(TAG, dest->arr.iArray, "Failed allocating memory");
139             memcpy(dest->arr.iArray, source->arr.iArray, dimTotal * sizeof(int64_t));
140             break;
141         case OCREP_PROP_DOUBLE:
142             dest->arr.dArray = (double*)OICMalloc(dimTotal * sizeof(double));
143             VERIFY_PARAM_NON_NULL(TAG, dest->arr.dArray, "Failed allocating memory");
144             memcpy(dest->arr.dArray, source->arr.dArray, dimTotal * sizeof(double));
145             break;
146         case OCREP_PROP_BOOL:
147             dest->arr.bArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
148             VERIFY_PARAM_NON_NULL(TAG, dest->arr.bArray, "Failed allocating memory");
149             memcpy(dest->arr.bArray, source->arr.bArray, dimTotal * sizeof(bool));
150             break;
151         case OCREP_PROP_STRING:
152             dest->arr.strArray = (char**)OICMalloc(dimTotal * sizeof(char*));
153             VERIFY_PARAM_NON_NULL(TAG, dest->arr.strArray, "Failed allocating memory");
154             for(size_t i = 0; i < dimTotal; ++i)
155             {
156                 dest->arr.strArray[i] = OICStrdup(source->arr.strArray[i]);
157             }
158             break;
159         case OCREP_PROP_OBJECT:
160             dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
161             VERIFY_PARAM_NON_NULL(TAG, dest->arr.objArray, "Failed allocating memory");
162             for(size_t i = 0; i < dimTotal; ++i)
163             {
164                 dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
165             }
166             break;
167         case OCREP_PROP_ARRAY:
168             dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
169             VERIFY_PARAM_NON_NULL(TAG, dest->arr.objArray, "Failed allocating memory");
170             for(size_t i = 0; i < dimTotal; ++i)
171             {
172                 dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
173             }
174             break;
175         default:
176             OIC_LOG(ERROR, TAG, "CopyPropertyValueArray invalid type");
177             break;
178     }
179 exit:
180     return;
181 }
182
183 static void OCCopyPropertyValue (OCRepPayloadValue *dest, OCRepPayloadValue *source)
184 {
185     if (!source || !dest)
186     {
187         return;
188     }
189
190     switch(source->type)
191     {
192         case OCREP_PROP_STRING:
193             dest->str = OICStrdup(source->str);
194             break;
195         case OCREP_PROP_BYTE_STRING:
196             dest->ocByteStr.bytes = (uint8_t*)OICMalloc(source->ocByteStr.len * sizeof(uint8_t));
197             VERIFY_PARAM_NON_NULL(TAG, dest->ocByteStr.bytes, "Failed allocating memory");
198             dest->ocByteStr.len = source->ocByteStr.len;
199             memcpy(dest->ocByteStr.bytes, source->ocByteStr.bytes, dest->ocByteStr.len);
200             break;
201         case OCREP_PROP_OBJECT:
202             dest->obj = OCRepPayloadClone(source->obj);
203             break;
204         case OCREP_PROP_ARRAY:
205             OCCopyPropertyValueArray(dest, source);
206             break;
207         default:
208             // Nothing to do for the trivially copyable types.
209             break;
210     }
211 exit:
212     return;
213 }
214
215 static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val)
216 {
217     if (!val)
218     {
219         return;
220     }
221
222     if (val->type == OCREP_PROP_STRING)
223     {
224         OICFree(val->str);
225     }
226     else if (val->type == OCREP_PROP_BYTE_STRING)
227     {
228         OICFree(val->ocByteStr.bytes);
229     }
230     else if (val->type == OCREP_PROP_OBJECT)
231     {
232         OCRepPayloadDestroy(val->obj);
233     }
234     else if (val->type == OCREP_PROP_ARRAY)
235     {
236         size_t dimTotal = calcDimTotal(val->arr.dimensions);
237         switch(val->arr.type)
238         {
239             case OCREP_PROP_INT:
240             case OCREP_PROP_DOUBLE:
241             case OCREP_PROP_BOOL:
242                 // Since this is a union, iArray will
243                 // point to all of the above
244                 OICFree(val->arr.iArray);
245                 break;
246             case OCREP_PROP_STRING:
247                 for(size_t i = 0; i< dimTotal; ++i)
248                 {
249                     OICFree(val->arr.strArray[i]);
250                 }
251                 OICFree(val->arr.strArray);
252                 break;
253             case OCREP_PROP_BYTE_STRING:
254                 for (size_t i = 0; i< dimTotal; ++i)
255                 {
256                     OICFree(val->arr.ocByteStrArray[i].bytes);
257                 }
258                 OICFree(val->arr.ocByteStrArray);
259                 break;
260             case OCREP_PROP_OBJECT: // This case is the temporary fix for string input
261                 for(size_t i = 0; i< dimTotal; ++i)
262                 {
263                     OCRepPayloadDestroy(val->arr.objArray[i]);
264                 }
265                 OICFree(val->arr.objArray);
266                 break;
267             case OCREP_PROP_NULL:
268             case OCREP_PROP_ARRAY:
269                 OIC_LOG_V(ERROR, TAG, "FreeRepPayloadValueContents: Illegal type\
270                         inside an array: %d", val->arr.type);
271                 break;
272         }
273     }
274 }
275
276 static void OCFreeRepPayloadValue(OCRepPayloadValue* val)
277 {
278     if (!val)
279     {
280         return;
281     }
282
283     OICFree(val->name);
284     OCFreeRepPayloadValueContents(val);
285     OCFreeRepPayloadValue(val->next);
286     OICFree(val);
287 }
288 static OCRepPayloadValue* OCRepPayloadValueClone (OCRepPayloadValue* source)
289 {
290     if (!source)
291     {
292         return NULL;
293     }
294
295     OCRepPayloadValue *sourceIter = source;
296     OCRepPayloadValue *destIter = (OCRepPayloadValue*) OICCalloc(1, sizeof(OCRepPayloadValue));
297     if (!destIter)
298     {
299         return NULL;
300     }
301
302     OCRepPayloadValue *headOfClone = destIter;
303
304     // Copy payload type and non pointer types in union.
305     *destIter = *sourceIter;
306     destIter->name = OICStrdup (sourceIter->name);
307     OCCopyPropertyValue (destIter, sourceIter);
308
309     sourceIter = sourceIter->next;
310
311     while (sourceIter)
312     {
313         destIter->next = (OCRepPayloadValue*) OICCalloc(1, sizeof(OCRepPayloadValue));
314         if (!destIter->next)
315         {
316             OCFreeRepPayloadValue (headOfClone);
317             return NULL;
318         }
319
320         *(destIter->next) = *sourceIter;
321         destIter->next->name = OICStrdup (sourceIter->name);
322         OCCopyPropertyValue (destIter->next, sourceIter);
323
324         sourceIter = sourceIter->next;
325         destIter = destIter->next;
326     }
327     return headOfClone;
328 }
329
330 static OCRepPayloadValue* OCRepPayloadFindAndSetValue(OCRepPayload* payload, const char* name,
331         OCRepPayloadPropType type)
332 {
333     if (!payload || !name)
334     {
335         return NULL;
336     }
337
338     OCRepPayloadValue* val = payload->values;
339     if (val == NULL)
340     {
341         payload->values = (OCRepPayloadValue*)OICCalloc(1, sizeof(OCRepPayloadValue));
342         if (!payload->values)
343         {
344             return NULL;
345         }
346         payload->values->name = OICStrdup(name);
347         if (!payload->values->name)
348         {
349             OICFree(payload->values);
350             payload->values = NULL;
351             return NULL;
352         }
353         payload->values->type =type;
354         return payload->values;
355     }
356
357     while(val)
358     {
359         if (0 == strcmp(val->name, name))
360         {
361             OCFreeRepPayloadValueContents(val);
362             val->type = type;
363             return val;
364         }
365         else if (val->next == NULL)
366         {
367             val->next = (OCRepPayloadValue*)OICCalloc(1, sizeof(OCRepPayloadValue));
368             if (!val->next)
369             {
370                 return NULL;
371             }
372             val->next->name = OICStrdup(name);
373             if (!val->next->name)
374             {
375                 OICFree(val->next);
376                 val->next = NULL;
377                 return NULL;
378             }
379             val->next->type =type;
380             return val->next;
381         }
382
383         val = val->next;
384     }
385
386     OIC_LOG(ERROR, TAG, "FindAndSetValue reached point after while loop, pointer corruption?");
387     return NULL;
388 }
389
390 bool OCRepPayloadAddResourceType(OCRepPayload* payload, const char* resourceType)
391 {
392     return OCRepPayloadAddResourceTypeAsOwner(payload, OICStrdup(resourceType));
393 }
394
395 bool OCRepPayloadAddResourceTypeAsOwner(OCRepPayload* payload, char* resourceType)
396 {
397     if (!payload || !resourceType)
398     {
399         return false;
400     }
401
402     if (payload->types)
403     {
404         OCStringLL* cur = payload->types;
405         while(cur->next)
406         {
407             cur = cur->next;
408         }
409         cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
410
411         if (!cur->next)
412         {
413             return false;
414         }
415
416         cur->next->value = resourceType;
417         return true;
418     }
419     else
420     {
421         payload->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
422         if (!payload->types)
423         {
424             return false;
425         }
426         payload->types->value = resourceType;
427         return true;
428     }
429 }
430
431 bool OCRepPayloadAddInterface(OCRepPayload* payload, const char* iface)
432 {
433     return OCRepPayloadAddInterfaceAsOwner(payload, OICStrdup(iface));
434 }
435
436 bool OCRepPayloadAddInterfaceAsOwner(OCRepPayload* payload, char* iface)
437 {
438     if (!payload || !iface)
439     {
440         return false;
441     }
442
443     if (payload->interfaces)
444     {
445         OCStringLL* cur = payload->interfaces;
446         while(cur->next)
447         {
448             cur = cur->next;
449         }
450         cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
451
452         if (!cur->next)
453         {
454             return false;
455         }
456         cur->next->value = iface;
457         return true;
458     }
459     else
460     {
461         payload->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
462         if (!payload->interfaces)
463         {
464             return false;
465         }
466         payload->interfaces->value = iface;
467         return true;
468     }
469 }
470
471 bool OCRepPayloadSetUri(OCRepPayload* payload, const char*  uri)
472 {
473     if (!payload)
474     {
475         return false;
476     }
477     OICFree(payload->uri);
478     payload->uri = OICStrdup(uri);
479     return payload->uri != NULL;
480 }
481
482 bool OCRepPayloadIsNull(const OCRepPayload* payload, const char* name)
483 {
484     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
485
486     if (!val)
487     {
488         return false;
489     }
490
491     return val->type == OCREP_PROP_NULL;
492 }
493
494 static bool OCRepPayloadSetProp(OCRepPayload* payload, const char* name,
495         void* value, OCRepPayloadPropType type)
496 {
497     OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, type);
498     if (!val)
499     {
500         return false;
501     }
502     switch(type)
503     {
504         case OCREP_PROP_INT:
505                val->i = *(int64_t*)value;
506                break;
507         case OCREP_PROP_DOUBLE:
508                val->d = *(double*)value;
509                break;
510         case OCREP_PROP_BOOL:
511                val->b = *(bool*)value;
512                break;
513         case OCREP_PROP_OBJECT:
514                val->obj = (OCRepPayload*)value;
515                break;
516         case OCREP_PROP_STRING:
517                val->str = (char*)value;
518                return val->str != NULL;
519         case OCREP_PROP_BYTE_STRING:
520                val->ocByteStr = *(OCByteString*)value;
521                break;
522         case OCREP_PROP_NULL:
523                return val != NULL;
524         case OCREP_PROP_ARRAY:
525         default:
526                return false;
527     }
528
529     return true;
530 }
531
532 bool OCRepPayloadSetNull(OCRepPayload* payload, const char* name)
533 {
534     return OCRepPayloadSetProp(payload, name, NULL, OCREP_PROP_NULL);
535 }
536
537 bool OCRepPayloadSetPropInt(OCRepPayload* payload,
538         const char* name, int64_t value)
539 {
540     return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_INT);
541 }
542
543 bool OCRepPayloadGetPropInt(const OCRepPayload* payload, const char* name, int64_t* value)
544 {
545     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
546
547     if (!val || val->type != OCREP_PROP_INT)
548     {
549         return false;
550     }
551
552     *value = val->i;
553     return true;
554 }
555
556 bool OCRepPayloadSetPropDouble(OCRepPayload* payload,
557                                const char* name, double value)
558 {
559     return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_DOUBLE);
560 }
561
562 bool OCRepPayloadGetPropDouble(const OCRepPayload* payload, const char* name, double* value)
563 {
564     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
565
566     if (val)
567     {
568         if (val->type == OCREP_PROP_DOUBLE)
569         {
570             *value = val->d;
571             return true;
572         }
573         else if (val->type == OCREP_PROP_INT)
574         {
575             *value = val->i;
576             return true;
577         }
578     }
579
580     return false;
581 }
582
583 bool OCRepPayloadSetPropString(OCRepPayload* payload, const char* name, const char* value)
584 {
585     char* temp = OICStrdup(value);
586     bool b = OCRepPayloadSetPropStringAsOwner(payload, name, temp);
587
588     if (!b)
589     {
590         OICFree(temp);
591     }
592     return b;
593 }
594
595 bool OCRepPayloadSetPropStringAsOwner(OCRepPayload* payload, const char* name, char* value)
596 {
597     return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_STRING);
598 }
599
600 bool OCRepPayloadGetPropString(const OCRepPayload* payload, const char* name, char** value)
601 {
602     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
603
604     if (!val || val->type != OCREP_PROP_STRING)
605     {
606         return false;
607     }
608
609     *value = OICStrdup(val->str);
610     return *value != NULL;
611 }
612
613 bool OCRepPayloadSetPropByteString(OCRepPayload* payload, const char* name, OCByteString value)
614 {
615     if (!value.bytes || !value.len)
616     {
617         return false;
618     }
619
620     OCByteString ocByteStr = {
621                     .bytes = (uint8_t*)OICMalloc(value.len * sizeof(uint8_t)),
622                     .len = value.len };
623
624     if (!ocByteStr.bytes)
625     {
626         return false;
627     }
628     memcpy(ocByteStr.bytes, value.bytes, ocByteStr.len);
629
630     bool b = OCRepPayloadSetPropByteStringAsOwner(payload, name, &ocByteStr);
631
632     if (!b)
633     {
634         OICFree(ocByteStr.bytes);
635     }
636     return b;
637 }
638
639 bool OCRepPayloadSetPropByteStringAsOwner(OCRepPayload* payload, const char* name, OCByteString* value)
640 {
641     return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_BYTE_STRING);
642 }
643
644 bool OCRepPayloadGetPropByteString(const OCRepPayload* payload, const char* name, OCByteString* value)
645 {
646     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
647
648     if (!val || val->type != OCREP_PROP_BYTE_STRING)
649     {
650         return false;
651     }
652
653     if (!value)
654     {
655         return false;
656     }
657
658     value->bytes = (uint8_t*)OICMalloc(val->ocByteStr.len * sizeof(uint8_t));
659     if (!value->bytes)
660     {
661         return false;
662     }
663     value->len = val->ocByteStr.len;
664     memcpy(value->bytes, val->ocByteStr.bytes, value->len);
665
666     return true;
667 }
668
669 bool OCRepPayloadSetPropBool(OCRepPayload* payload,
670                              const char* name, bool value)
671 {
672     return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_BOOL);
673 }
674
675 bool OCRepPayloadGetPropBool(const OCRepPayload* payload, const char* name, bool* value)
676 {
677     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
678
679     if (!val || val->type != OCREP_PROP_BOOL)
680     {
681         return false;
682     }
683
684     *value = val->b;
685     return true;
686 }
687
688 bool OCRepPayloadSetPropObject(OCRepPayload* payload, const char* name, const OCRepPayload* value)
689 {
690     OCRepPayload* temp = OCRepPayloadClone(value);
691     bool b = OCRepPayloadSetPropObjectAsOwner(payload, name, temp);
692
693     if (!b)
694     {
695         OCRepPayloadDestroy(temp);
696     }
697     return b;
698 }
699
700 bool OCRepPayloadSetPropObjectAsOwner(OCRepPayload* payload, const char* name, OCRepPayload* value)
701 {
702     return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_OBJECT);
703 }
704
705 bool OCRepPayloadGetPropObject(const OCRepPayload* payload, const char* name, OCRepPayload** value)
706 {
707     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
708
709     if (!val || val->type != OCREP_PROP_OBJECT)
710     {
711         return false;
712     }
713
714     *value = OCRepPayloadClone(val->obj);
715     return *value != NULL;
716 }
717
718 size_t calcDimTotal(const size_t dimensions[MAX_REP_ARRAY_DEPTH])
719 {
720     if (dimensions[0] == 0)
721     {
722         return 0;
723     }
724
725     size_t total = 1;
726     for(uint8_t i = 0; i < MAX_REP_ARRAY_DEPTH && dimensions[i] != 0; ++i)
727     {
728         total *= dimensions[i];
729     }
730     return total;
731 }
732
733
734 bool OCRepPayloadSetByteStringArrayAsOwner(OCRepPayload* payload, const char* name,
735         OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
736 {
737     OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
738
739     if (!val)
740     {
741         return false;
742     }
743
744     val->arr.type = OCREP_PROP_BYTE_STRING;
745     memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
746     val->arr.ocByteStrArray = array;
747
748     return true;
749 }
750
751 bool OCRepPayloadSetByteStringArray(OCRepPayload* payload, const char* name,
752         const OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
753 {
754     if (!array)
755     {
756         return false;
757     }
758
759     size_t dimTotal = calcDimTotal(dimensions);
760     if (dimTotal == 0)
761     {
762         return false;
763     }
764
765     OCByteString* newArray = (OCByteString*)OICCalloc(dimTotal, sizeof(OCByteString));
766
767     if (!newArray)
768     {
769         return false;
770     }
771
772     for (size_t i = 0; i < dimTotal; ++i)
773     {
774         newArray[i].bytes = (uint8_t*)OICMalloc(array[i].len * sizeof(uint8_t));
775         if (NULL == newArray[i].bytes)
776         {
777             for (size_t j = 0; j < i; ++j)
778             {
779                 OICFree(newArray[j].bytes);
780             }
781
782             OICFree(newArray);
783             return false;
784         }
785         newArray[i].len = array[i].len;
786         memcpy(newArray[i].bytes, array[i].bytes, newArray[i].len);
787     }
788
789     bool b = OCRepPayloadSetByteStringArrayAsOwner(payload, name, newArray, dimensions);
790     if (!b)
791     {
792         for (size_t i = 0; i < dimTotal; ++i)
793         {
794             OICFree(newArray[i].bytes);
795         }
796
797         OICFree(newArray);
798     }
799     return b;
800 }
801
802 bool OCRepPayloadGetByteStringArray(const OCRepPayload* payload, const char* name,
803         OCByteString** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
804 {
805     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
806
807     if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_BYTE_STRING
808             || !val->arr.ocByteStrArray)
809     {
810         return false;
811     }
812
813     size_t dimTotal = calcDimTotal(val->arr.dimensions);
814     if (dimTotal == 0)
815     {
816         return false;
817     }
818
819     *array = (OCByteString*)OICCalloc(dimTotal, sizeof(OCByteString));
820     if (!*array)
821     {
822         return false;
823     }
824
825     for (size_t i = 0; i < dimTotal; ++i)
826     {
827         OCByteString* tmp = &(*array)[i];
828         tmp->bytes = (uint8_t*)OICMalloc(val->arr.ocByteStrArray[i].len * sizeof(uint8_t));
829         if (NULL == tmp->bytes)
830         {
831             for (size_t j = 0; j < i; ++j)
832             {
833                 OCByteString* tmp = &(*array)[j];
834                 OICFree(tmp->bytes);
835             }
836             OICFree(*array);
837             *array = NULL;
838
839             return false;
840         }
841         tmp->len = val->arr.ocByteStrArray[i].len;
842         memcpy(tmp->bytes, val->arr.ocByteStrArray[i].bytes, tmp->len);
843     }
844
845     memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
846     return true;
847 }
848
849
850 bool OCRepPayloadSetIntArrayAsOwner(OCRepPayload* payload, const char* name,
851         int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
852 {
853     OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
854
855     if (!val)
856     {
857         return false;
858     }
859
860     val->arr.type = OCREP_PROP_INT;
861     memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
862     val->arr.iArray = array;
863
864     return true;
865 }
866
867 bool OCRepPayloadSetIntArray(OCRepPayload* payload, const char* name,
868         const int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
869 {
870     size_t dimTotal = calcDimTotal(dimensions);
871     if (dimTotal == 0)
872     {
873         return false;
874     }
875
876     int64_t* newArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
877
878     if (!newArray)
879     {
880         return false;
881     }
882
883     memcpy(newArray, array, dimTotal * sizeof(int64_t));
884
885
886     bool b = OCRepPayloadSetIntArrayAsOwner(payload, name, newArray, dimensions);
887     if (!b)
888     {
889         OICFree(newArray);
890     }
891     return b;
892 }
893
894 bool OCRepPayloadGetIntArray(const OCRepPayload* payload, const char* name,
895         int64_t** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
896 {
897     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
898
899     if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_INT
900             || !val->arr.iArray)
901     {
902         return false;
903     }
904
905     size_t dimTotal = calcDimTotal(val->arr.dimensions);
906     if (dimTotal == 0)
907     {
908         return false;
909     }
910     *array = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
911     if (!*array)
912     {
913         return false;
914     }
915
916     memcpy(*array, val->arr.iArray, dimTotal * sizeof(int64_t));
917     memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
918     return true;
919 }
920
921 bool OCRepPayloadSetDoubleArrayAsOwner(OCRepPayload* payload, const char* name,
922         double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
923 {
924     OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
925
926     if (!val)
927     {
928         return false;
929     }
930
931     val->arr.type = OCREP_PROP_DOUBLE;
932     memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
933     val->arr.dArray = array;
934
935     return true;
936 }
937 bool OCRepPayloadSetDoubleArray(OCRepPayload* payload, const char* name,
938         const double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
939 {
940     size_t dimTotal = calcDimTotal(dimensions);
941     if (dimTotal == 0)
942     {
943         return false;
944     }
945
946     double* newArray = (double*)OICMalloc(dimTotal * sizeof(double));
947
948     if (!newArray)
949     {
950         return false;
951     }
952
953     memcpy(newArray, array, dimTotal * sizeof(double));
954
955     bool b = OCRepPayloadSetDoubleArrayAsOwner(payload, name, newArray, dimensions);
956     if (!b)
957     {
958         OICFree(newArray);
959     }
960     return b;
961 }
962
963 bool OCRepPayloadGetDoubleArray(const OCRepPayload* payload, const char* name,
964         double** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
965 {
966     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
967
968     if (!val || val->type != OCREP_PROP_ARRAY ||
969         (val->arr.type != OCREP_PROP_DOUBLE && val->arr.type != OCREP_PROP_INT)
970             || !val->arr.dArray)
971     {
972         return false;
973     }
974
975     size_t dimTotal = calcDimTotal(val->arr.dimensions);
976     if (dimTotal == 0)
977     {
978         return false;
979     }
980     *array = (double*)OICMalloc(dimTotal * sizeof(double));
981     if (!*array)
982     {
983         return false;
984     }
985
986     if (val->arr.type == OCREP_PROP_DOUBLE)
987     {
988         memcpy(*array, val->arr.dArray, dimTotal * sizeof(double));
989     }
990     else
991     {
992         /* need to convert from integer */
993         size_t n = 0;
994         for ( ; n < dimTotal; ++n)
995         {
996             (*array)[n] = val->arr.iArray[n];
997         }
998     }
999     memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1000     return true;
1001 }
1002
1003 bool OCRepPayloadSetStringArrayAsOwner(OCRepPayload* payload, const char* name,
1004         char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1005 {
1006     OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1007
1008     if (!val)
1009     {
1010         return false;
1011     }
1012
1013     val->arr.type = OCREP_PROP_STRING;
1014     memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1015     val->arr.strArray = array;
1016
1017     return true;
1018 }
1019 bool OCRepPayloadSetStringArray(OCRepPayload* payload, const char* name,
1020         const char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1021 {
1022     size_t dimTotal = calcDimTotal(dimensions);
1023     if (dimTotal == 0)
1024     {
1025         return false;
1026     }
1027
1028     char** newArray = (char**)OICMalloc(dimTotal * sizeof(char*));
1029
1030     if (!newArray)
1031     {
1032         return false;
1033     }
1034
1035     for(size_t i = 0; i < dimTotal; ++i)
1036     {
1037         newArray[i] = OICStrdup(array[i]);
1038     }
1039
1040     bool b = OCRepPayloadSetStringArrayAsOwner(payload, name, newArray, dimensions);
1041
1042     if (!b)
1043     {
1044         for(size_t i = 0; i < dimTotal; ++i)
1045         {
1046             OICFree(newArray[i]);
1047         }
1048         OICFree(newArray);
1049     }
1050     return b;
1051 }
1052
1053 bool OCRepPayloadGetStringArray(const OCRepPayload* payload, const char* name,
1054         char*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1055 {
1056     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1057
1058     if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_STRING
1059             || !val->arr.strArray)
1060     {
1061         return false;
1062     }
1063
1064     size_t dimTotal = calcDimTotal(val->arr.dimensions);
1065     if (dimTotal == 0)
1066     {
1067         return false;
1068     }
1069     *array = (char**)OICMalloc(dimTotal * sizeof(char*));
1070     if (!*array)
1071     {
1072         return false;
1073     }
1074
1075     memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1076
1077     for(size_t i = 0; i < dimTotal; ++i)
1078     {
1079         (*array)[i] = OICStrdup(val->arr.strArray[i]);
1080     }
1081
1082     return true;
1083
1084 }
1085
1086 bool OCRepPayloadSetBoolArrayAsOwner(OCRepPayload* payload, const char* name,
1087         bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1088 {
1089
1090     OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1091
1092     if (!val)
1093     {
1094         return false;
1095     }
1096
1097     val->arr.type = OCREP_PROP_BOOL;
1098     memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1099     val->arr.bArray = array;
1100
1101     return true;
1102 }
1103 bool OCRepPayloadSetBoolArray(OCRepPayload* payload, const char* name,
1104         const bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1105 {
1106     size_t dimTotal = calcDimTotal(dimensions);
1107     if (dimTotal == 0)
1108     {
1109         return false;
1110     }
1111
1112     bool* newArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
1113
1114     if (!newArray)
1115     {
1116         return false;
1117     }
1118
1119     memcpy(newArray, array, dimTotal * sizeof(bool));
1120
1121
1122     bool b = OCRepPayloadSetBoolArrayAsOwner(payload, name, newArray, dimensions);
1123     if (!b)
1124     {
1125         OICFree(newArray);
1126     }
1127     return b;
1128 }
1129
1130 bool OCRepPayloadGetBoolArray(const OCRepPayload* payload, const char* name,
1131         bool** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1132 {
1133     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1134
1135     if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_BOOL
1136             || !val->arr.bArray)
1137     {
1138         return false;
1139     }
1140
1141     size_t dimTotal = calcDimTotal(val->arr.dimensions);
1142     if (dimTotal == 0)
1143     {
1144         return false;
1145     }
1146     *array = (bool*)OICMalloc(dimTotal * sizeof(bool));
1147     if (!*array)
1148     {
1149         return false;
1150     }
1151
1152     memcpy(*array, val->arr.bArray, dimTotal * sizeof(bool));
1153     memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1154     return true;
1155 }
1156
1157 bool OCRepPayloadSetPropObjectArrayAsOwner(OCRepPayload* payload, const char* name,
1158         OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1159 {
1160     OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1161
1162     if (!val)
1163     {
1164         return false;
1165     }
1166
1167     val->arr.type = OCREP_PROP_OBJECT;
1168     memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1169     val->arr.objArray = array;
1170
1171     return true;
1172 }
1173
1174 bool OCRepPayloadSetPropObjectArray(OCRepPayload* payload, const char* name,
1175         const OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1176 {
1177     size_t dimTotal = calcDimTotal(dimensions);
1178     if (dimTotal == 0)
1179     {
1180         return false;
1181     }
1182
1183     OCRepPayload** newArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
1184
1185     if (!newArray)
1186     {
1187         return false;
1188     }
1189
1190     for(size_t i = 0; i < dimTotal; ++i)
1191     {
1192         newArray[i] = OCRepPayloadClone(array[i]);
1193     }
1194
1195     bool b = OCRepPayloadSetPropObjectArrayAsOwner(payload, name, newArray, dimensions);
1196
1197     if (!b)
1198     {
1199         for(size_t i = 0; i < dimTotal; ++i)
1200         {
1201            OCRepPayloadDestroy(newArray[i]);
1202         }
1203         OICFree(newArray);
1204     }
1205     return b;
1206 }
1207
1208 bool OCRepPayloadGetPropObjectArray(const OCRepPayload* payload, const char* name,
1209         OCRepPayload*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1210 {
1211     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1212
1213     if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_OBJECT
1214             || !val->arr.objArray)
1215     {
1216         return false;
1217     }
1218
1219     size_t dimTotal = calcDimTotal(val->arr.dimensions);
1220     if (dimTotal == 0)
1221     {
1222         return false;
1223     }
1224     *array = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
1225     if (!*array)
1226     {
1227         return false;
1228     }
1229
1230     memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1231
1232     for(size_t i = 0; i < dimTotal; ++i)
1233     {
1234         (*array)[i] = OCRepPayloadClone(val->arr.objArray[i]);
1235     }
1236
1237     return true;
1238 }
1239
1240 void OCFreeOCStringLL(OCStringLL* ll)
1241 {
1242     if (!ll)
1243     {
1244         return;
1245     }
1246
1247     OCFreeOCStringLL(ll->next);
1248     OICFree(ll->value);
1249     OICFree(ll);
1250 }
1251
1252 OCStringLL* CloneOCStringLL (OCStringLL* ll)
1253 {
1254     if (!ll)
1255     {
1256         return NULL;
1257     }
1258
1259     OCStringLL *sourceIter = ll;
1260
1261     OCStringLL *destIter = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
1262     if (!destIter)
1263     {
1264         return NULL;
1265     }
1266     destIter->value = OICStrdup (sourceIter->value);
1267
1268     OCStringLL *headOfClone = destIter;
1269
1270     sourceIter = sourceIter->next;
1271
1272     while (sourceIter)
1273     {
1274         destIter->next  = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
1275         if (!destIter->next)
1276         {
1277             OCFreeOCStringLL (headOfClone);
1278             return NULL;
1279         }
1280         destIter->next->value = OICStrdup (sourceIter->value);
1281
1282         destIter = destIter->next;
1283         sourceIter = sourceIter->next;
1284     }
1285     return headOfClone;
1286 }
1287
1288 OCStringLL* OCCreateOCStringLL(const char* text)
1289 {
1290     char *token = NULL;
1291     char *head = NULL;
1292     char *tail = NULL;
1293     char *backup  = NULL;
1294     OCStringLL* result = NULL;
1295     OCStringLL* iter = NULL;
1296     OCStringLL* prev = NULL;
1297     static const char delim[] = { CSV_SEPARATOR, '\0' };
1298
1299     VERIFY_PARAM_NON_NULL(TAG, text, "Invalid parameter");
1300     backup = OICStrdup(text);
1301     VERIFY_PARAM_NON_NULL(TAG, backup, "Failed allocating memory");
1302
1303     for (head = backup; ; head = NULL)
1304     {
1305         token = (char *) strtok_r(head, delim, &tail);
1306         if (!token) break;
1307         iter = (OCStringLL *)OICCalloc(1,sizeof(OCStringLL));
1308         VERIFY_PARAM_NON_NULL(TAG, iter, "Failed allocating memory");
1309         if (!result)
1310         {
1311              result = iter;
1312         }
1313         else
1314         {
1315              prev->next = iter;
1316         }
1317         iter->value = OICStrdup(token);
1318         VERIFY_PARAM_NON_NULL(TAG, iter->value, "Failed allocating memory");
1319         prev = iter;
1320         iter = iter->next;
1321     }
1322     OICFree(backup);
1323     return result;
1324
1325 exit:
1326     OICFree(backup);
1327     OCFreeOCStringLL(result);
1328     return NULL;
1329 }
1330
1331 char* OCCreateString(const OCStringLL* ll)
1332 {
1333     char *str = NULL;
1334     char *pos = NULL;
1335     size_t len = 0;
1336     size_t sublen = 0;
1337     int count = 0;
1338
1339     if (!ll) return NULL;
1340
1341     for (const OCStringLL *it = ll; it ; it = it->next )
1342     {
1343         len += strlen(it->value) + 1;
1344     }
1345     len--; // renove trailing separator (just added above)
1346     str = (char*) malloc(len + 1);
1347     if (!str)
1348         return NULL;
1349
1350     pos = str;
1351     const OCStringLL *it = ll;
1352     while (it)
1353     {
1354         sublen = strlen(it->value);
1355         count = snprintf(pos, len + 1, "%s", it->value);
1356         if (count<sublen)
1357         {
1358             free(str);
1359             return NULL;
1360         }
1361         len-=sublen;
1362         pos+=count;
1363
1364         it = it->next;
1365         if (it)
1366         {
1367             *pos = CSV_SEPARATOR;
1368             len--;
1369             *(++pos) = '\0';
1370        }
1371     }
1372
1373     return str;
1374 }
1375
1376 OCRepPayload* OCRepPayloadClone (const OCRepPayload* payload)
1377 {
1378     if (!payload)
1379     {
1380         return NULL;
1381     }
1382
1383     OCRepPayload *clone = OCRepPayloadCreate();
1384
1385     if (!clone)
1386     {
1387         return NULL;
1388     }
1389
1390     clone->uri = OICStrdup (payload->uri);
1391     clone->types = CloneOCStringLL (payload->types);
1392     clone->interfaces = CloneOCStringLL (payload->interfaces);
1393     clone->values = OCRepPayloadValueClone (payload->values);
1394
1395     return clone;
1396 }
1397
1398
1399 void OCRepPayloadDestroy(OCRepPayload* payload)
1400 {
1401     if (!payload)
1402     {
1403         return;
1404     }
1405
1406     OICFree(payload->uri);
1407     OCFreeOCStringLL(payload->types);
1408     OCFreeOCStringLL(payload->interfaces);
1409     OCFreeRepPayloadValue(payload->values);
1410     OCRepPayloadDestroy(payload->next);
1411     OICFree(payload);
1412 }
1413
1414 OCDiscoveryPayload* OCDiscoveryPayloadCreate()
1415 {
1416     OCDiscoveryPayload* payload = (OCDiscoveryPayload*)OICCalloc(1, sizeof(OCDiscoveryPayload));
1417
1418     if (!payload)
1419     {
1420         return NULL;
1421     }
1422
1423     payload->base.type = PAYLOAD_TYPE_DISCOVERY;
1424
1425     return payload;
1426 }
1427
1428 OCSecurityPayload* OCSecurityPayloadCreate(const uint8_t* securityData, size_t size)
1429 {
1430     OCSecurityPayload* payload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1431
1432     if (!payload)
1433     {
1434         return NULL;
1435     }
1436
1437     payload->base.type = PAYLOAD_TYPE_SECURITY;
1438     payload->securityData = (uint8_t *)OICCalloc(1, size);
1439     if (!payload->securityData)
1440     {
1441         OICFree(payload);
1442         return NULL;
1443     }
1444     memcpy(payload->securityData, (uint8_t *)securityData, size);
1445     payload->payloadSize = size;
1446
1447     return payload;
1448 }
1449
1450 void OCSecurityPayloadDestroy(OCSecurityPayload* payload)
1451 {
1452     if (!payload)
1453     {
1454         return;
1455     }
1456
1457     OICFree(payload->securityData);
1458     OICFree(payload);
1459 }
1460
1461 size_t OCDiscoveryPayloadGetResourceCount(OCDiscoveryPayload* payload)
1462 {
1463     size_t i = 0;
1464     OCResourcePayload* p = payload->resources;
1465     while(p)
1466     {
1467         ++i;
1468         p = p->next;
1469     }
1470     return i;
1471 }
1472
1473 OCResourcePayload* OCDiscoveryPayloadGetResource(OCDiscoveryPayload* payload, size_t index)
1474 {
1475     size_t i = 0;
1476     OCResourcePayload* p = payload->resources;
1477     while(p)
1478     {
1479         if (i == index)
1480         {
1481             return p;
1482         }
1483         ++i;
1484         p = p->next;
1485     }
1486     return NULL;
1487 }
1488
1489 #ifndef TCP_ADAPTER
1490 static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort)
1491 #else
1492 static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort,
1493                                          uint16_t tcpPort)
1494 #endif
1495 {
1496     OCResourcePayload* pl = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1497     if (!pl)
1498     {
1499         return NULL;
1500     }
1501
1502     pl->uri = OICStrdup(res->uri);
1503
1504     if (!pl->uri)
1505     {
1506         OCDiscoveryResourceDestroy(pl);
1507         return NULL;
1508     }
1509
1510     // types
1511     OCResourceType* typePtr = res->rsrcType;
1512
1513     if (typePtr != NULL)
1514     {
1515         pl->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1516         if (!pl->types)
1517         {
1518             OCDiscoveryResourceDestroy(pl);
1519             return NULL;
1520         }
1521         pl->types->value = OICStrdup(typePtr->resourcetypename);
1522         if (!pl->types->value)
1523         {
1524             OCDiscoveryResourceDestroy(pl);
1525             return NULL;
1526         }
1527
1528         OCStringLL* cur = pl->types;
1529         typePtr = typePtr->next;
1530         while(typePtr)
1531         {
1532             cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1533             if (!cur->next)
1534             {
1535                 OCDiscoveryResourceDestroy(pl);
1536                 return NULL;
1537             }
1538             cur->next->value = OICStrdup(typePtr->resourcetypename);
1539             if (!cur->next->value)
1540             {
1541                 OCDiscoveryResourceDestroy(pl);
1542                 return NULL;
1543             }
1544             cur = cur->next;
1545             typePtr = typePtr->next;
1546         }
1547     }
1548
1549     // interfaces
1550     OCResourceInterface* ifPtr = res->rsrcInterface;
1551     if (ifPtr != NULL)
1552     {
1553         pl->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1554         if (!pl->interfaces)
1555         {
1556             OCDiscoveryResourceDestroy(pl);
1557             return NULL;
1558         }
1559         pl->interfaces->value = OICStrdup(ifPtr->name);
1560         if (!pl->interfaces->value)
1561         {
1562             OCDiscoveryResourceDestroy(pl);
1563             return NULL;
1564         }
1565
1566         OCStringLL* cur = pl->interfaces;
1567         ifPtr = ifPtr->next;
1568         while(ifPtr && cur)
1569         {
1570             cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1571             if (!cur->next)
1572             {
1573                 OCDiscoveryResourceDestroy(pl);
1574                 return NULL;
1575             }
1576             cur->next->value = OICStrdup(ifPtr->name);
1577             if (!cur->next->value)
1578             {
1579                 OCDiscoveryResourceDestroy(pl);
1580                 return NULL;
1581             }
1582             cur = cur->next;
1583             ifPtr = ifPtr->next;
1584         }
1585     }
1586
1587     pl->bitmap = res->resourceProperties & (OC_OBSERVABLE | OC_DISCOVERABLE);
1588     pl->secure = (res->resourceProperties & OC_SECURE) != 0;
1589     pl->port = securePort;
1590 #ifdef TCP_ADAPTER
1591     pl->tcpPort = tcpPort;
1592 #endif
1593     return pl;
1594 }
1595
1596 #ifndef TCP_ADAPTER
1597 void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
1598                                    uint16_t securePort)
1599 {
1600     OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort));
1601 }
1602 #else
1603 void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
1604                                    uint16_t securePort, uint16_t tcpPort)
1605 {
1606     OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort, tcpPort));
1607 }
1608 #endif
1609
1610 bool OCResourcePayloadAddStringLL(OCStringLL **stringLL, const char *value)
1611 {
1612     char *dup = OICStrdup(value);
1613     VERIFY_PARAM_NON_NULL(TAG, dup, "Failed copying string");
1614     VERIFY_PARAM_NON_NULL(TAG, value, "Invalid Parameters");
1615
1616     if (!*stringLL)
1617     {
1618         *stringLL = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
1619         VERIFY_PARAM_NON_NULL(TAG, *stringLL, "Failed allocating memory");
1620         (*stringLL)->value = dup;
1621         return true;
1622     }
1623     else
1624     {
1625         OCStringLL *temp = *stringLL;
1626         while(temp->next)
1627         {
1628             temp = temp->next;
1629         }
1630         temp->next = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
1631         VERIFY_PARAM_NON_NULL(TAG, temp->next, "Failed allocating memory");
1632         temp->next->value = dup;
1633         return true;
1634     }
1635 exit:
1636     OICFree(dup);
1637     return false;
1638 }
1639
1640 void OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload, OCResourcePayload* res)
1641 {
1642     if (!payload)
1643     {
1644         return;
1645     }
1646
1647     if (!payload->resources)
1648     {
1649         payload->resources = res;
1650     }
1651     else
1652     {
1653         OCResourcePayload* p = payload->resources;
1654         while(p->next)
1655         {
1656             p = p->next;
1657         }
1658         p->next = res;
1659     }
1660 }
1661
1662 void OCDiscoveryResourceDestroy(OCResourcePayload* payload)
1663 {
1664     if (!payload)
1665     {
1666         return;
1667     }
1668
1669     OICFree(payload->uri);
1670     OCFreeOCStringLL(payload->types);
1671     OCFreeOCStringLL(payload->interfaces);
1672     OCDiscoveryResourceDestroy(payload->next);
1673     OICFree(payload);
1674
1675 }
1676 void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload)
1677 {
1678     if (!payload)
1679     {
1680         return;
1681     }
1682     OICFree(payload->sid);
1683     OICFree(payload->baseURI);
1684     OICFree(payload->uri);
1685     OCFreeOCStringLL(payload->type);
1686     OICFree(payload->name);
1687     OCFreeOCStringLL(payload->iface);
1688     OCDiscoveryResourceDestroy(payload->resources);
1689     OCDiscoveryPayloadDestroy(payload->next);
1690     OICFree(payload);
1691 }
1692
1693 OCDevicePayload* OCDevicePayloadCreate(const char* sid, const char* dname,
1694         const OCStringLL *types, const char* specVer, const char* dmVer)
1695 {
1696
1697     OCDevicePayload* payload = (OCDevicePayload*)OICCalloc(1, sizeof(OCDevicePayload));
1698
1699     if (!payload)
1700     {
1701         return NULL;
1702     }
1703
1704     payload->base.type = PAYLOAD_TYPE_DEVICE;
1705     payload->sid = OICStrdup(sid);
1706     if (sid && !payload->sid)
1707     {
1708         goto exit;
1709     }
1710
1711     payload->deviceName = OICStrdup(dname);
1712     if (dname && !payload->deviceName)
1713     {
1714         goto exit;
1715     }
1716
1717     payload->specVersion = OICStrdup(specVer);
1718     if (specVer && !payload->specVersion)
1719     {
1720         goto exit;
1721     }
1722
1723     payload->dataModelVersions = OCCreateOCStringLL(dmVer);
1724     if (!payload->dataModelVersions || (dmVer && !payload->dataModelVersions->value))
1725     {
1726         goto exit;
1727     }
1728
1729     OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_DEFAULT);
1730     OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_READ);
1731
1732     payload->types = CloneOCStringLL((OCStringLL *)types);
1733     if (types && !payload->types)
1734     {
1735         goto exit;
1736     }
1737
1738     return payload;
1739
1740 exit:
1741     OCDevicePayloadDestroy((OCDevicePayload*)payload);
1742     return NULL;
1743 }
1744
1745 void OCDevicePayloadDestroy(OCDevicePayload* payload)
1746 {
1747     if (!payload)
1748     {
1749         return;
1750     }
1751
1752     OICFree(payload->sid);
1753     OICFree(payload->deviceName);
1754     OICFree(payload->specVersion);
1755     OCFreeOCStringLL(payload->dataModelVersions);
1756     OCFreeOCStringLL(payload->types);
1757     OCFreeOCStringLL(payload->interfaces);
1758     OICFree(payload);
1759 }
1760
1761 static void OCCopyPlatformInfo(const OCPlatformInfo* platformInfo, OCPlatformPayload* target)
1762 {
1763     if (!platformInfo || !target)
1764     {
1765         return;
1766     }
1767
1768     target->info.platformID = OICStrdup(platformInfo->platformID);
1769     target->info.manufacturerName = OICStrdup(platformInfo->manufacturerName);
1770     target->info.manufacturerUrl = OICStrdup(platformInfo->manufacturerUrl);
1771     target->info.modelNumber = OICStrdup(platformInfo->modelNumber);
1772     target->info.dateOfManufacture = OICStrdup(platformInfo->dateOfManufacture);
1773     target->info.platformVersion = OICStrdup(platformInfo->platformVersion);
1774     target->info.operatingSystemVersion = OICStrdup(platformInfo->operatingSystemVersion);
1775     target->info.hardwareVersion = OICStrdup(platformInfo->hardwareVersion);
1776     target->info.firmwareVersion = OICStrdup(platformInfo->firmwareVersion);
1777     target->info.supportUrl = OICStrdup(platformInfo->supportUrl);
1778     target->info.systemTime = OICStrdup(platformInfo->systemTime);
1779 }
1780
1781 OCPlatformPayload* OCPlatformPayloadCreateAsOwner(OCPlatformInfo* platformInfo)
1782 {
1783     OCPlatformPayload* payload = (OCPlatformPayload*)OICCalloc(1, sizeof(OCPlatformPayload));
1784     if (!payload)
1785     {
1786         return NULL;
1787     }
1788
1789     payload->base.type = PAYLOAD_TYPE_PLATFORM;
1790
1791     payload->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1792     if (!payload->interfaces)
1793     {
1794         return NULL;
1795     }
1796     payload->interfaces->value = OICStrdup(OC_RSRVD_INTERFACE_READ);
1797     payload->rt = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1798     if (!payload->rt)
1799     {
1800         return NULL;
1801     }
1802     payload->rt->value = OICStrdup(OC_RSRVD_RESOURCE_TYPE_PLATFORM);
1803     payload->info = *platformInfo;
1804
1805     return payload;
1806 }
1807
1808 OCPlatformPayload* OCPlatformPayloadCreate(const OCPlatformInfo* platformInfo)
1809 {
1810     OCPlatformPayload* payload = (OCPlatformPayload*)OICCalloc(1, sizeof(OCPlatformPayload));
1811
1812     if (!payload)
1813     {
1814         return NULL;
1815     }
1816
1817     payload->base.type = PAYLOAD_TYPE_PLATFORM;
1818     OCResourcePayloadAddStringLL(&payload->rt, OC_RSRVD_RESOURCE_TYPE_PLATFORM);
1819
1820     OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_DEFAULT);
1821     OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_READ);
1822
1823     OCCopyPlatformInfo(platformInfo, payload);
1824
1825     return payload;
1826 }
1827
1828 void OCPlatformInfoDestroy(OCPlatformInfo *info)
1829 {
1830     OICFree(info->platformID);
1831     OICFree(info->manufacturerName);
1832     OICFree(info->manufacturerUrl);
1833     OICFree(info->modelNumber);
1834     OICFree(info->dateOfManufacture);
1835     OICFree(info->platformVersion);
1836     OICFree(info->operatingSystemVersion);
1837     OICFree(info->hardwareVersion);
1838     OICFree(info->firmwareVersion);
1839     OICFree(info->supportUrl);
1840     OICFree(info->systemTime);
1841 }
1842
1843 void OCPlatformPayloadDestroy(OCPlatformPayload* payload)
1844 {
1845     if (!payload)
1846     {
1847         return;
1848     }
1849     OICFree(payload->uri);
1850     OCPlatformInfoDestroy(&payload->info);
1851     OCFreeOCStringLL(payload->rt);
1852     OCFreeOCStringLL(payload->interfaces);
1853     OICFree(payload);
1854 }
1855
1856 OCPresencePayload* OCPresencePayloadCreate(uint32_t seqNum, uint32_t maxAge,
1857         OCPresenceTrigger trigger, const char* resourceType)
1858 {
1859     OCPresencePayload* payload = (OCPresencePayload*)OICCalloc(1, sizeof(OCPresencePayload));
1860     if (!payload)
1861     {
1862         return NULL;
1863     }
1864
1865     payload->base.type = PAYLOAD_TYPE_PRESENCE;
1866     payload->sequenceNumber = seqNum;
1867     payload->maxAge = maxAge;
1868     payload->trigger = trigger;
1869     payload->resourceType = OICStrdup(resourceType);
1870     return payload;
1871 }
1872
1873 void OCPresencePayloadDestroy(OCPresencePayload* payload)
1874 {
1875     if (!payload)
1876     {
1877         return;
1878     }
1879     OICFree(payload->resourceType);
1880     OICFree(payload);
1881 }