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