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