8bb13b02846b01b26d8e682442033419c52ce693
[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* iface)
428 {
429     return OCRepPayloadAddInterfaceAsOwner(payload, OICStrdup(iface));
430 }
431
432 bool OCRepPayloadAddInterfaceAsOwner(OCRepPayload* payload, char* iface)
433 {
434     if (!payload || !iface)
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 = iface;
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 = iface;
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 false;
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 static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort)
1398 {
1399     OCResourcePayload* pl = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1400     if (!pl)
1401     {
1402         return NULL;
1403     }
1404
1405     pl->uri = OICStrdup(res->uri);
1406
1407     if (!pl->uri)
1408     {
1409         OCDiscoveryResourceDestroy(pl);
1410         return NULL;
1411     }
1412
1413     // types
1414     OCResourceType* typePtr = res->rsrcType;
1415
1416     if (typePtr != NULL)
1417     {
1418         pl->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1419         if (!pl->types)
1420         {
1421             OCDiscoveryResourceDestroy(pl);
1422             return NULL;
1423         }
1424         pl->types->value = OICStrdup(typePtr->resourcetypename);
1425         if (!pl->types->value)
1426         {
1427             OCDiscoveryResourceDestroy(pl);
1428             return NULL;
1429         }
1430
1431         OCStringLL* cur = pl->types;
1432         typePtr = typePtr->next;
1433         while(typePtr)
1434         {
1435             cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1436             if (!cur->next)
1437             {
1438                 OCDiscoveryResourceDestroy(pl);
1439                 return NULL;
1440             }
1441             cur->next->value = OICStrdup(typePtr->resourcetypename);
1442             if (!cur->next->value)
1443             {
1444                 OCDiscoveryResourceDestroy(pl);
1445                 return NULL;
1446             }
1447             cur = cur->next;
1448             typePtr = typePtr->next;
1449         }
1450     }
1451
1452     // interfaces
1453     OCResourceInterface* ifPtr = res->rsrcInterface;
1454     if (ifPtr != NULL)
1455     {
1456         pl->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1457         if (!pl->interfaces)
1458         {
1459             OCDiscoveryResourceDestroy(pl);
1460             return NULL;
1461         }
1462         pl->interfaces->value = OICStrdup(ifPtr->name);
1463         if (!pl->interfaces->value)
1464         {
1465             OCDiscoveryResourceDestroy(pl);
1466             return NULL;
1467         }
1468
1469         OCStringLL* cur = pl->interfaces;
1470         ifPtr = ifPtr->next;
1471         while(ifPtr && cur)
1472         {
1473             cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1474             if (!cur->next)
1475             {
1476                 OCDiscoveryResourceDestroy(pl);
1477                 return NULL;
1478             }
1479             cur->next->value = OICStrdup(ifPtr->name);
1480             if (!cur->next->value)
1481             {
1482                 OCDiscoveryResourceDestroy(pl);
1483                 return NULL;
1484             }
1485             cur = cur->next;
1486             ifPtr = ifPtr->next;
1487         }
1488     }
1489
1490     pl->bitmap = res->resourceProperties & (OC_OBSERVABLE | OC_DISCOVERABLE);
1491     pl->secure = (res->resourceProperties & OC_SECURE) != 0;
1492     pl->port = securePort;
1493 #ifdef TCP_ADAPTER
1494     pl->tcpPort = tcpPort;
1495 #endif
1496     return pl;
1497 }
1498
1499 void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
1500                                    uint16_t securePort, uint16_t tcpPort)
1501 {
1502     OC_UNUSED(tcpPort);
1503     OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort));
1504 }
1505
1506 bool OCResourcePayloadAddStringLL(OCStringLL **stringLL, const char *value)
1507 {
1508     char *dup = OICStrdup(value);
1509     VERIFY_PARAM_NON_NULL(TAG, dup, "Failed copying string");
1510     VERIFY_PARAM_NON_NULL(TAG, value, "Invalid Parameters");
1511
1512     if (!*stringLL)
1513     {
1514         *stringLL = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
1515         VERIFY_PARAM_NON_NULL(TAG, *stringLL, "Failed allocating memory");
1516         (*stringLL)->value = dup;
1517         return true;
1518     }
1519     else
1520     {
1521         OCStringLL *temp = *stringLL;
1522         while(temp->next)
1523         {
1524             temp = temp->next;
1525         }
1526         temp->next = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
1527         VERIFY_PARAM_NON_NULL(TAG, temp->next, "Failed allocating memory");
1528         temp->next->value = dup;
1529         return true;
1530     }
1531 exit:
1532     OICFree(dup);
1533     return false;
1534 }
1535
1536 void OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload, OCResourcePayload* res)
1537 {
1538     if (!payload)
1539     {
1540         return;
1541     }
1542
1543     if (!payload->resources)
1544     {
1545         payload->resources = res;
1546     }
1547     else
1548     {
1549         OCResourcePayload* p = payload->resources;
1550         while(p->next)
1551         {
1552             p = p->next;
1553         }
1554         p->next = res;
1555     }
1556 }
1557
1558 void OCDiscoveryResourceDestroy(OCResourcePayload* payload)
1559 {
1560     if (!payload)
1561     {
1562         return;
1563     }
1564
1565     OICFree(payload->uri);
1566     OCFreeOCStringLL(payload->types);
1567     OCFreeOCStringLL(payload->interfaces);
1568     OCDiscoveryResourceDestroy(payload->next);
1569     OICFree(payload);
1570
1571 }
1572 void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload)
1573 {
1574     if (!payload)
1575     {
1576         return;
1577     }
1578     OICFree(payload->sid);
1579     OICFree(payload->baseURI);
1580     OICFree(payload->uri);
1581     OICFree(payload->type);
1582     OICFree(payload->name);
1583     OCFreeOCStringLL(payload->iface);
1584     OCDiscoveryResourceDestroy(payload->resources);
1585     OICFree(payload);
1586 }
1587
1588 OCDevicePayload* OCDevicePayloadCreate(const char* sid, const char* dname,
1589         const OCStringLL *types, const char* specVer, const char* dmVer)
1590 {
1591
1592     OCDevicePayload* payload = (OCDevicePayload*)OICCalloc(1, sizeof(OCDevicePayload));
1593
1594     if (!payload)
1595     {
1596         return NULL;
1597     }
1598
1599     payload->base.type = PAYLOAD_TYPE_DEVICE;
1600     payload->sid = OICStrdup(sid);
1601     if (sid && !payload->sid)
1602     {
1603         goto exit;
1604     }
1605
1606     payload->deviceName = OICStrdup(dname);
1607     if (dname && !payload->deviceName)
1608     {
1609         goto exit;
1610     }
1611
1612     payload->specVersion = OICStrdup(specVer);
1613     if (specVer && !payload->specVersion)
1614     {
1615         goto exit;
1616     }
1617
1618     payload->dataModelVersion = OICStrdup(dmVer);
1619     if (dmVer && !payload->dataModelVersion)
1620     {
1621         goto exit;
1622     }
1623
1624     OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_DEFAULT);
1625     OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_READ);
1626
1627     payload->types = CloneOCStringLL((OCStringLL *)types);
1628     if (types && !payload->types)
1629     {
1630         goto exit;
1631     }
1632
1633     return payload;
1634
1635 exit:
1636     OCDevicePayloadDestroy((OCDevicePayload*)payload);
1637     return NULL;
1638 }
1639
1640 void OCDevicePayloadDestroy(OCDevicePayload* payload)
1641 {
1642     if (!payload)
1643     {
1644         return;
1645     }
1646
1647     OICFree(payload->sid);
1648     OICFree(payload->deviceName);
1649     OICFree(payload->specVersion);
1650     OICFree(payload->dataModelVersion);
1651     OCFreeOCStringLL(payload->types);
1652     OCFreeOCStringLL(payload->interfaces);
1653     OICFree(payload);
1654 }
1655
1656 static void OCCopyPlatformInfo(const OCPlatformInfo* platformInfo, OCPlatformPayload* target)
1657 {
1658     if (!platformInfo || !target)
1659     {
1660         return;
1661     }
1662
1663     target->info.platformID = OICStrdup(platformInfo->platformID);
1664     target->info.manufacturerName = OICStrdup(platformInfo->manufacturerName);
1665     target->info.manufacturerUrl = OICStrdup(platformInfo->manufacturerUrl);
1666     target->info.modelNumber = OICStrdup(platformInfo->modelNumber);
1667     target->info.dateOfManufacture = OICStrdup(platformInfo->dateOfManufacture);
1668     target->info.platformVersion = OICStrdup(platformInfo->platformVersion);
1669     target->info.operatingSystemVersion = OICStrdup(platformInfo->operatingSystemVersion);
1670     target->info.hardwareVersion = OICStrdup(platformInfo->hardwareVersion);
1671     target->info.firmwareVersion = OICStrdup(platformInfo->firmwareVersion);
1672     target->info.supportUrl = OICStrdup(platformInfo->supportUrl);
1673     target->info.systemTime = OICStrdup(platformInfo->systemTime);
1674 }
1675
1676 OCPlatformPayload* OCPlatformPayloadCreateAsOwner(OCPlatformInfo* platformInfo)
1677 {
1678     OCPlatformPayload* payload = (OCPlatformPayload*)OICCalloc(1, sizeof(OCPlatformPayload));
1679     if (!payload)
1680     {
1681         return NULL;
1682     }
1683
1684     payload->base.type = PAYLOAD_TYPE_PLATFORM;
1685
1686     payload->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1687     if (!payload->interfaces)
1688     {
1689         return NULL;
1690     }
1691     payload->interfaces->value = OICStrdup(OC_RSRVD_INTERFACE_READ);
1692     payload->rt = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1693     if (!payload->rt)
1694     {
1695         return NULL;
1696     }
1697     payload->rt->value = OICStrdup(OC_RSRVD_RESOURCE_TYPE_PLATFORM);
1698     payload->info = *platformInfo;
1699
1700     return payload;
1701 }
1702
1703 OCPlatformPayload* OCPlatformPayloadCreate(const OCPlatformInfo* platformInfo)
1704 {
1705     OCPlatformPayload* payload = (OCPlatformPayload*)OICCalloc(1, sizeof(OCPlatformPayload));
1706
1707     if (!payload)
1708     {
1709         return NULL;
1710     }
1711
1712     payload->base.type = PAYLOAD_TYPE_PLATFORM;
1713     OCResourcePayloadAddStringLL(&payload->rt, OC_RSRVD_RESOURCE_TYPE_PLATFORM);
1714
1715     OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_DEFAULT);
1716     OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_READ);
1717
1718     OCCopyPlatformInfo(platformInfo, payload);
1719
1720     return payload;
1721 }
1722
1723 void OCPlatformInfoDestroy(OCPlatformInfo *info)
1724 {
1725     OICFree(info->platformID);
1726     OICFree(info->manufacturerName);
1727     OICFree(info->manufacturerUrl);
1728     OICFree(info->modelNumber);
1729     OICFree(info->dateOfManufacture);
1730     OICFree(info->platformVersion);
1731     OICFree(info->operatingSystemVersion);
1732     OICFree(info->hardwareVersion);
1733     OICFree(info->firmwareVersion);
1734     OICFree(info->supportUrl);
1735     OICFree(info->systemTime);
1736 }
1737
1738 void OCPlatformPayloadDestroy(OCPlatformPayload* payload)
1739 {
1740     if (!payload)
1741     {
1742         return;
1743     }
1744     OICFree(payload->uri);
1745     OCPlatformInfoDestroy(&payload->info);
1746     OCFreeOCStringLL(payload->rt);
1747     OCFreeOCStringLL(payload->interfaces);
1748     OICFree(payload);
1749 }
1750
1751 OCPresencePayload* OCPresencePayloadCreate(uint32_t seqNum, uint32_t maxAge,
1752         OCPresenceTrigger trigger, const char* resourceType)
1753 {
1754     OCPresencePayload* payload = (OCPresencePayload*)OICCalloc(1, sizeof(OCPresencePayload));
1755     if (!payload)
1756     {
1757         return NULL;
1758     }
1759
1760     payload->base.type = PAYLOAD_TYPE_PRESENCE;
1761     payload->sequenceNumber = seqNum;
1762     payload->maxAge = maxAge;
1763     payload->trigger = trigger;
1764     payload->resourceType = OICStrdup(resourceType);
1765     return payload;
1766 }
1767
1768 void OCPresencePayloadDestroy(OCPresencePayload* payload)
1769 {
1770     if (!payload)
1771     {
1772         return;
1773     }
1774     OICFree(payload->resourceType);
1775     OICFree(payload);
1776 }