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