Merge branch 'windows-port'
[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     str = (char*) malloc(len + 1);
1346     if (!str)
1347         return NULL;
1348
1349     pos = str;
1350     for (const OCStringLL *it = ll; it ; it = it->next )
1351     {
1352         sublen = strlen(it->value) + 1;
1353         count = snprintf(pos, len + 1, "%s%c", it->value, CSV_SEPARATOR);
1354         if (count<sublen)
1355         {
1356             free(str);
1357             return NULL;
1358         }
1359         len-=sublen;
1360         pos+=count;
1361     }
1362
1363     return str;
1364 }
1365
1366 OCRepPayload* OCRepPayloadClone (const OCRepPayload* payload)
1367 {
1368     if (!payload)
1369     {
1370         return NULL;
1371     }
1372
1373     OCRepPayload *clone = OCRepPayloadCreate();
1374
1375     if (!clone)
1376     {
1377         return NULL;
1378     }
1379
1380     clone->uri = OICStrdup (payload->uri);
1381     clone->types = CloneOCStringLL (payload->types);
1382     clone->interfaces = CloneOCStringLL (payload->interfaces);
1383     clone->values = OCRepPayloadValueClone (payload->values);
1384
1385     return clone;
1386 }
1387
1388
1389 void OCRepPayloadDestroy(OCRepPayload* payload)
1390 {
1391     if (!payload)
1392     {
1393         return;
1394     }
1395
1396     OICFree(payload->uri);
1397     OCFreeOCStringLL(payload->types);
1398     OCFreeOCStringLL(payload->interfaces);
1399     OCFreeRepPayloadValue(payload->values);
1400     OCRepPayloadDestroy(payload->next);
1401     OICFree(payload);
1402 }
1403
1404 OCDiscoveryPayload* OCDiscoveryPayloadCreate()
1405 {
1406     OCDiscoveryPayload* payload = (OCDiscoveryPayload*)OICCalloc(1, sizeof(OCDiscoveryPayload));
1407
1408     if (!payload)
1409     {
1410         return NULL;
1411     }
1412
1413     payload->base.type = PAYLOAD_TYPE_DISCOVERY;
1414
1415     return payload;
1416 }
1417
1418 OCSecurityPayload* OCSecurityPayloadCreate(const uint8_t* securityData, size_t size)
1419 {
1420     OCSecurityPayload* payload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1421
1422     if (!payload)
1423     {
1424         return NULL;
1425     }
1426
1427     payload->base.type = PAYLOAD_TYPE_SECURITY;
1428     payload->securityData = (uint8_t *)OICCalloc(1, size);
1429     if (!payload->securityData)
1430     {
1431         OICFree(payload);
1432         return NULL;
1433     }
1434     memcpy(payload->securityData, (uint8_t *)securityData, size);
1435     payload->payloadSize = size;
1436
1437     return payload;
1438 }
1439
1440 void OCSecurityPayloadDestroy(OCSecurityPayload* payload)
1441 {
1442     if (!payload)
1443     {
1444         return;
1445     }
1446
1447     OICFree(payload->securityData);
1448     OICFree(payload);
1449 }
1450
1451 size_t OCDiscoveryPayloadGetResourceCount(OCDiscoveryPayload* payload)
1452 {
1453     size_t i = 0;
1454     OCResourcePayload* p = payload->resources;
1455     while(p)
1456     {
1457         ++i;
1458         p = p->next;
1459     }
1460     return i;
1461 }
1462
1463 OCResourcePayload* OCDiscoveryPayloadGetResource(OCDiscoveryPayload* payload, size_t index)
1464 {
1465     size_t i = 0;
1466     OCResourcePayload* p = payload->resources;
1467     while(p)
1468     {
1469         if (i == index)
1470         {
1471             return p;
1472         }
1473         ++i;
1474         p = p->next;
1475     }
1476     return NULL;
1477 }
1478
1479 #ifndef TCP_ADAPTER
1480 static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort)
1481 #else
1482 static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort,
1483                                          uint16_t tcpPort)
1484 #endif
1485 {
1486     OCResourcePayload* pl = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1487     if (!pl)
1488     {
1489         return NULL;
1490     }
1491
1492     pl->uri = OICStrdup(res->uri);
1493
1494     if (!pl->uri)
1495     {
1496         OCDiscoveryResourceDestroy(pl);
1497         return NULL;
1498     }
1499
1500     // types
1501     OCResourceType* typePtr = res->rsrcType;
1502
1503     if (typePtr != NULL)
1504     {
1505         pl->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1506         if (!pl->types)
1507         {
1508             OCDiscoveryResourceDestroy(pl);
1509             return NULL;
1510         }
1511         pl->types->value = OICStrdup(typePtr->resourcetypename);
1512         if (!pl->types->value)
1513         {
1514             OCDiscoveryResourceDestroy(pl);
1515             return NULL;
1516         }
1517
1518         OCStringLL* cur = pl->types;
1519         typePtr = typePtr->next;
1520         while(typePtr)
1521         {
1522             cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1523             if (!cur->next)
1524             {
1525                 OCDiscoveryResourceDestroy(pl);
1526                 return NULL;
1527             }
1528             cur->next->value = OICStrdup(typePtr->resourcetypename);
1529             if (!cur->next->value)
1530             {
1531                 OCDiscoveryResourceDestroy(pl);
1532                 return NULL;
1533             }
1534             cur = cur->next;
1535             typePtr = typePtr->next;
1536         }
1537     }
1538
1539     // interfaces
1540     OCResourceInterface* ifPtr = res->rsrcInterface;
1541     if (ifPtr != NULL)
1542     {
1543         pl->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1544         if (!pl->interfaces)
1545         {
1546             OCDiscoveryResourceDestroy(pl);
1547             return NULL;
1548         }
1549         pl->interfaces->value = OICStrdup(ifPtr->name);
1550         if (!pl->interfaces->value)
1551         {
1552             OCDiscoveryResourceDestroy(pl);
1553             return NULL;
1554         }
1555
1556         OCStringLL* cur = pl->interfaces;
1557         ifPtr = ifPtr->next;
1558         while(ifPtr && cur)
1559         {
1560             cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1561             if (!cur->next)
1562             {
1563                 OCDiscoveryResourceDestroy(pl);
1564                 return NULL;
1565             }
1566             cur->next->value = OICStrdup(ifPtr->name);
1567             if (!cur->next->value)
1568             {
1569                 OCDiscoveryResourceDestroy(pl);
1570                 return NULL;
1571             }
1572             cur = cur->next;
1573             ifPtr = ifPtr->next;
1574         }
1575     }
1576
1577     pl->bitmap = res->resourceProperties & (OC_OBSERVABLE | OC_DISCOVERABLE);
1578     pl->secure = (res->resourceProperties & OC_SECURE) != 0;
1579     pl->port = securePort;
1580 #ifdef TCP_ADAPTER
1581     pl->tcpPort = tcpPort;
1582 #endif
1583     return pl;
1584 }
1585
1586 #ifndef TCP_ADAPTER
1587 void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
1588                                    uint16_t securePort)
1589 {
1590     OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort));
1591 }
1592 #else
1593 void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
1594                                    uint16_t securePort, uint16_t tcpPort)
1595 {
1596     OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort, tcpPort));
1597 }
1598 #endif
1599
1600 bool OCResourcePayloadAddStringLL(OCStringLL **stringLL, const char *value)
1601 {
1602     char *dup = OICStrdup(value);
1603     VERIFY_PARAM_NON_NULL(TAG, dup, "Failed copying string");
1604     VERIFY_PARAM_NON_NULL(TAG, value, "Invalid Parameters");
1605
1606     if (!*stringLL)
1607     {
1608         *stringLL = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
1609         VERIFY_PARAM_NON_NULL(TAG, *stringLL, "Failed allocating memory");
1610         (*stringLL)->value = dup;
1611         return true;
1612     }
1613     else
1614     {
1615         OCStringLL *temp = *stringLL;
1616         while(temp->next)
1617         {
1618             temp = temp->next;
1619         }
1620         temp->next = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
1621         VERIFY_PARAM_NON_NULL(TAG, temp->next, "Failed allocating memory");
1622         temp->next->value = dup;
1623         return true;
1624     }
1625 exit:
1626     OICFree(dup);
1627     return false;
1628 }
1629
1630 void OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload, OCResourcePayload* res)
1631 {
1632     if (!payload)
1633     {
1634         return;
1635     }
1636
1637     if (!payload->resources)
1638     {
1639         payload->resources = res;
1640     }
1641     else
1642     {
1643         OCResourcePayload* p = payload->resources;
1644         while(p->next)
1645         {
1646             p = p->next;
1647         }
1648         p->next = res;
1649     }
1650 }
1651
1652 void OCDiscoveryResourceDestroy(OCResourcePayload* payload)
1653 {
1654     if (!payload)
1655     {
1656         return;
1657     }
1658
1659     OICFree(payload->uri);
1660     OCFreeOCStringLL(payload->types);
1661     OCFreeOCStringLL(payload->interfaces);
1662     OCDiscoveryResourceDestroy(payload->next);
1663     OICFree(payload);
1664
1665 }
1666 void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload)
1667 {
1668     if (!payload)
1669     {
1670         return;
1671     }
1672     OICFree(payload->sid);
1673     OICFree(payload->baseURI);
1674     OICFree(payload->uri);
1675     OCFreeOCStringLL(payload->type);
1676     OICFree(payload->name);
1677     OCFreeOCStringLL(payload->iface);
1678     OCDiscoveryResourceDestroy(payload->resources);
1679     OICFree(payload);
1680 }
1681
1682 OCDevicePayload* OCDevicePayloadCreate(const char* sid, const char* dname,
1683         const OCStringLL *types, const char* specVer, const char* dmVer)
1684 {
1685
1686     OCDevicePayload* payload = (OCDevicePayload*)OICCalloc(1, sizeof(OCDevicePayload));
1687
1688     if (!payload)
1689     {
1690         return NULL;
1691     }
1692
1693     payload->base.type = PAYLOAD_TYPE_DEVICE;
1694     payload->sid = OICStrdup(sid);
1695     if (sid && !payload->sid)
1696     {
1697         goto exit;
1698     }
1699
1700     payload->deviceName = OICStrdup(dname);
1701     if (dname && !payload->deviceName)
1702     {
1703         goto exit;
1704     }
1705
1706     payload->specVersion = OICStrdup(specVer);
1707     if (specVer && !payload->specVersion)
1708     {
1709         goto exit;
1710     }
1711
1712     payload->dataModelVersions = OCCreateOCStringLL(dmVer);
1713     if (!payload->dataModelVersions || (dmVer && !payload->dataModelVersions->value))
1714     {
1715         goto exit;
1716     }
1717
1718     OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_DEFAULT);
1719     OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_READ);
1720
1721     payload->types = CloneOCStringLL((OCStringLL *)types);
1722     if (types && !payload->types)
1723     {
1724         goto exit;
1725     }
1726
1727     return payload;
1728
1729 exit:
1730     OCDevicePayloadDestroy((OCDevicePayload*)payload);
1731     return NULL;
1732 }
1733
1734 void OCDevicePayloadDestroy(OCDevicePayload* payload)
1735 {
1736     if (!payload)
1737     {
1738         return;
1739     }
1740
1741     OICFree(payload->sid);
1742     OICFree(payload->deviceName);
1743     OICFree(payload->specVersion);
1744     OCFreeOCStringLL(payload->dataModelVersions);
1745     OCFreeOCStringLL(payload->types);
1746     OCFreeOCStringLL(payload->interfaces);
1747     OICFree(payload);
1748 }
1749
1750 static void OCCopyPlatformInfo(const OCPlatformInfo* platformInfo, OCPlatformPayload* target)
1751 {
1752     if (!platformInfo || !target)
1753     {
1754         return;
1755     }
1756
1757     target->info.platformID = OICStrdup(platformInfo->platformID);
1758     target->info.manufacturerName = OICStrdup(platformInfo->manufacturerName);
1759     target->info.manufacturerUrl = OICStrdup(platformInfo->manufacturerUrl);
1760     target->info.modelNumber = OICStrdup(platformInfo->modelNumber);
1761     target->info.dateOfManufacture = OICStrdup(platformInfo->dateOfManufacture);
1762     target->info.platformVersion = OICStrdup(platformInfo->platformVersion);
1763     target->info.operatingSystemVersion = OICStrdup(platformInfo->operatingSystemVersion);
1764     target->info.hardwareVersion = OICStrdup(platformInfo->hardwareVersion);
1765     target->info.firmwareVersion = OICStrdup(platformInfo->firmwareVersion);
1766     target->info.supportUrl = OICStrdup(platformInfo->supportUrl);
1767     target->info.systemTime = OICStrdup(platformInfo->systemTime);
1768 }
1769
1770 OCPlatformPayload* OCPlatformPayloadCreateAsOwner(OCPlatformInfo* platformInfo)
1771 {
1772     OCPlatformPayload* payload = (OCPlatformPayload*)OICCalloc(1, sizeof(OCPlatformPayload));
1773     if (!payload)
1774     {
1775         return NULL;
1776     }
1777
1778     payload->base.type = PAYLOAD_TYPE_PLATFORM;
1779
1780     payload->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1781     if (!payload->interfaces)
1782     {
1783         return NULL;
1784     }
1785     payload->interfaces->value = OICStrdup(OC_RSRVD_INTERFACE_READ);
1786     payload->rt = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1787     if (!payload->rt)
1788     {
1789         return NULL;
1790     }
1791     payload->rt->value = OICStrdup(OC_RSRVD_RESOURCE_TYPE_PLATFORM);
1792     payload->info = *platformInfo;
1793
1794     return payload;
1795 }
1796
1797 OCPlatformPayload* OCPlatformPayloadCreate(const OCPlatformInfo* platformInfo)
1798 {
1799     OCPlatformPayload* payload = (OCPlatformPayload*)OICCalloc(1, sizeof(OCPlatformPayload));
1800
1801     if (!payload)
1802     {
1803         return NULL;
1804     }
1805
1806     payload->base.type = PAYLOAD_TYPE_PLATFORM;
1807     OCResourcePayloadAddStringLL(&payload->rt, OC_RSRVD_RESOURCE_TYPE_PLATFORM);
1808
1809     OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_DEFAULT);
1810     OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_READ);
1811
1812     OCCopyPlatformInfo(platformInfo, payload);
1813
1814     return payload;
1815 }
1816
1817 void OCPlatformInfoDestroy(OCPlatformInfo *info)
1818 {
1819     OICFree(info->platformID);
1820     OICFree(info->manufacturerName);
1821     OICFree(info->manufacturerUrl);
1822     OICFree(info->modelNumber);
1823     OICFree(info->dateOfManufacture);
1824     OICFree(info->platformVersion);
1825     OICFree(info->operatingSystemVersion);
1826     OICFree(info->hardwareVersion);
1827     OICFree(info->firmwareVersion);
1828     OICFree(info->supportUrl);
1829     OICFree(info->systemTime);
1830 }
1831
1832 void OCPlatformPayloadDestroy(OCPlatformPayload* payload)
1833 {
1834     if (!payload)
1835     {
1836         return;
1837     }
1838     OICFree(payload->uri);
1839     OCPlatformInfoDestroy(&payload->info);
1840     OCFreeOCStringLL(payload->rt);
1841     OCFreeOCStringLL(payload->interfaces);
1842     OICFree(payload);
1843 }
1844
1845 OCPresencePayload* OCPresencePayloadCreate(uint32_t seqNum, uint32_t maxAge,
1846         OCPresenceTrigger trigger, const char* resourceType)
1847 {
1848     OCPresencePayload* payload = (OCPresencePayload*)OICCalloc(1, sizeof(OCPresencePayload));
1849     if (!payload)
1850     {
1851         return NULL;
1852     }
1853
1854     payload->base.type = PAYLOAD_TYPE_PRESENCE;
1855     payload->sequenceNumber = seqNum;
1856     payload->maxAge = maxAge;
1857     payload->trigger = trigger;
1858     payload->resourceType = OICStrdup(resourceType);
1859     return payload;
1860 }
1861
1862 void OCPresencePayloadDestroy(OCPresencePayload* payload)
1863 {
1864     if (!payload)
1865     {
1866         return;
1867     }
1868     OICFree(payload->resourceType);
1869     OICFree(payload);
1870 }