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