5e0d72757eabc16ce0638227abe7b0914f44d70f
[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)
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 *)securityData;
1320
1321     return payload;
1322 }
1323
1324 void OCSecurityPayloadDestroy(OCSecurityPayload* payload)
1325 {
1326     if (!payload)
1327     {
1328         return;
1329     }
1330     // Remove this once all cbor changes land.
1331     OICFree(payload->securityData);
1332     OICFree(payload->securityData1);
1333     OICFree(payload);
1334 }
1335
1336 size_t OCDiscoveryPayloadGetResourceCount(OCDiscoveryPayload* payload)
1337 {
1338     size_t i = 0;
1339     OCResourcePayload* p = payload->resources;
1340     while(p)
1341     {
1342         ++i;
1343         p = p->next;
1344     }
1345     return i;
1346 }
1347
1348 OCResourcePayload* OCDiscoveryPayloadGetResource(OCDiscoveryPayload* payload, size_t index)
1349 {
1350     size_t i = 0;
1351     OCResourcePayload* p = payload->resources;
1352     while(p)
1353     {
1354         if (i == index)
1355         {
1356             return p;
1357         }
1358         ++i;
1359         p = p->next;
1360     }
1361     return NULL;
1362 }
1363
1364 static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t port)
1365 {
1366     OCResourcePayload* pl = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1367     if (!pl)
1368     {
1369         return NULL;
1370     }
1371
1372     pl->uri = OICStrdup(res->uri);
1373
1374     if (!pl->uri)
1375     {
1376         OCDiscoveryResourceDestroy(pl);
1377         return NULL;
1378     }
1379
1380     // types
1381     OCResourceType* typePtr = res->rsrcType;
1382
1383     if (typePtr != NULL)
1384     {
1385         pl->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1386         if (!pl->types)
1387         {
1388             OCDiscoveryResourceDestroy(pl);
1389             return NULL;
1390         }
1391         pl->types->value = OICStrdup(typePtr->resourcetypename);
1392         if (!pl->types->value)
1393         {
1394             OCDiscoveryResourceDestroy(pl);
1395             return NULL;
1396         }
1397
1398         OCStringLL* cur = pl->types;
1399         typePtr = typePtr->next;
1400         while(typePtr)
1401         {
1402             cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1403             if (!cur->next)
1404             {
1405                 OCDiscoveryResourceDestroy(pl);
1406                 return NULL;
1407             }
1408             cur->next->value = OICStrdup(typePtr->resourcetypename);
1409             if (!cur->next->value)
1410             {
1411                 OCDiscoveryResourceDestroy(pl);
1412                 return NULL;
1413             }
1414             cur = cur->next;
1415             typePtr = typePtr->next;
1416         }
1417     }
1418
1419     // interfaces
1420     OCResourceInterface* ifPtr = res->rsrcInterface;
1421     if (ifPtr != NULL)
1422     {
1423         pl->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1424         if (!pl->interfaces)
1425         {
1426             OCDiscoveryResourceDestroy(pl);
1427             return NULL;
1428         }
1429         pl->interfaces->value = OICStrdup(ifPtr->name);
1430         if (!pl->interfaces->value)
1431         {
1432             OCDiscoveryResourceDestroy(pl);
1433             return NULL;
1434         }
1435
1436         OCStringLL* cur = pl->interfaces;
1437         ifPtr = ifPtr->next;
1438         while(ifPtr && cur)
1439         {
1440             cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1441             if (!cur->next)
1442             {
1443                 OCDiscoveryResourceDestroy(pl);
1444                 return NULL;
1445             }
1446             cur->next->value = OICStrdup(ifPtr->name);
1447             if (!cur->next->value)
1448             {
1449                 OCDiscoveryResourceDestroy(pl);
1450                 return NULL;
1451             }
1452             cur = cur->next;
1453             ifPtr = ifPtr->next;
1454         }
1455     }
1456
1457     pl->bitmap = res->resourceProperties & (OC_OBSERVABLE | OC_DISCOVERABLE);
1458     pl->secure = (res->resourceProperties & OC_SECURE) != 0;
1459     pl->port = port;
1460
1461     return pl;
1462 }
1463
1464 void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
1465         uint16_t port)
1466 {
1467     OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, port));
1468 }
1469
1470 bool OCResourcePayloadAddStringLL(OCStringLL **stringLL, const char *value)
1471 {
1472     char *dup = OICStrdup(value);
1473     VERIFY_PARAM_NON_NULL(TAG, dup, "Failed copying string");
1474     VERIFY_PARAM_NON_NULL(TAG, value, "Invalid Parameters");
1475
1476     if (!*stringLL)
1477     {
1478         *stringLL = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
1479         VERIFY_PARAM_NON_NULL(TAG, dup, "Failed allocating memory");
1480         (*stringLL)->value = dup;
1481         return true;
1482     }
1483     else
1484     {
1485         OCStringLL *temp = *stringLL;
1486         while(temp->next)
1487         {
1488             temp = temp->next;
1489         }
1490         temp->next = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
1491         VERIFY_PARAM_NON_NULL(TAG, temp->next, "Failed allocating memory");
1492         temp->next->value = dup;
1493         return true;
1494     }
1495 exit:
1496     OICFree(dup);
1497     return false;
1498 }
1499
1500 void OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload, OCResourcePayload* res)
1501 {
1502     if (!payload)
1503     {
1504         return;
1505     }
1506
1507     if (!payload->resources)
1508     {
1509         payload->resources = res;
1510     }
1511     else
1512     {
1513         OCResourcePayload* p = payload->resources;
1514         while(p->next)
1515         {
1516             p = p->next;
1517         }
1518         p->next = res;
1519     }
1520 }
1521
1522 void OCDiscoveryResourceDestroy(OCResourcePayload* payload)
1523 {
1524     if (!payload)
1525     {
1526         return;
1527     }
1528
1529     OICFree(payload->uri);
1530     OCFreeOCStringLL(payload->types);
1531     OCFreeOCStringLL(payload->interfaces);
1532     OCDiscoveryResourceDestroy(payload->next);
1533     OICFree(payload);
1534
1535 }
1536 void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload)
1537 {
1538     if (!payload)
1539     {
1540         return;
1541     }
1542     OICFree(payload->sid);
1543     OCDiscoveryResourceDestroy(payload->resources);
1544     OICFree(payload);
1545 }
1546
1547 OCDevicePayload* OCDevicePayloadCreate(const char* sid, const char* dname,
1548         const char* specVer, const char* dmVer)
1549 {
1550
1551     OCDevicePayload* payload = (OCDevicePayload*)OICCalloc(1, sizeof(OCDevicePayload));
1552
1553     if (!payload)
1554     {
1555         return NULL;
1556     }
1557
1558     payload->base.type = PAYLOAD_TYPE_DEVICE;
1559     payload->sid = OICStrdup(sid);
1560     if (sid && !payload->sid)
1561     {
1562         goto exit;
1563     }
1564
1565     payload->deviceName = OICStrdup(dname);
1566     if (dname && !payload->deviceName)
1567     {
1568         goto exit;
1569     }
1570
1571     payload->specVersion = OICStrdup(specVer);
1572     if (specVer && !payload->specVersion)
1573     {
1574         goto exit;
1575     }
1576
1577     payload->dataModelVersion = OICStrdup(dmVer);
1578     if (dmVer && !payload->dataModelVersion)
1579     {
1580         goto exit;
1581     }
1582
1583     return payload;
1584
1585 exit:
1586     OCDevicePayloadDestroy((OCDevicePayload*)payload);
1587     return NULL;
1588 }
1589
1590 void OCDevicePayloadDestroy(OCDevicePayload* payload)
1591 {
1592     if (!payload)
1593     {
1594         return;
1595     }
1596
1597     OICFree(payload->sid);
1598     OICFree(payload->deviceName);
1599     OICFree(payload->specVersion);
1600     OICFree(payload->dataModelVersion);
1601     OICFree(payload);
1602 }
1603
1604 static void OCCopyPlatformInfo(const OCPlatformInfo* platformInfo, OCPlatformPayload* target)
1605 {
1606     if (!platformInfo || !target)
1607     {
1608         return;
1609     }
1610
1611     target->info.platformID = OICStrdup(platformInfo->platformID);
1612     target->info.manufacturerName = OICStrdup(platformInfo->manufacturerName);
1613     target->info.manufacturerUrl = OICStrdup(platformInfo->manufacturerUrl);
1614     target->info.modelNumber = OICStrdup(platformInfo->modelNumber);
1615     target->info.dateOfManufacture = OICStrdup(platformInfo->dateOfManufacture);
1616     target->info.platformVersion = OICStrdup(platformInfo->platformVersion);
1617     target->info.operatingSystemVersion = OICStrdup(platformInfo->operatingSystemVersion);
1618     target->info.hardwareVersion = OICStrdup(platformInfo->hardwareVersion);
1619     target->info.firmwareVersion = OICStrdup(platformInfo->firmwareVersion);
1620     target->info.supportUrl = OICStrdup(platformInfo->supportUrl);
1621     target->info.systemTime = OICStrdup(platformInfo->systemTime);
1622 }
1623
1624 OCPlatformPayload* OCPlatformPayloadCreateAsOwner(OCPlatformInfo* platformInfo)
1625 {
1626     OCPlatformPayload* payload = (OCPlatformPayload*)OICCalloc(1, sizeof(OCPlatformPayload));
1627     if (!payload)
1628     {
1629         return NULL;
1630     }
1631
1632     payload->base.type = PAYLOAD_TYPE_PLATFORM;
1633
1634     payload->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1635     if (!payload->interfaces)
1636     {
1637         return NULL;
1638     }
1639     payload->interfaces->value = OICStrdup(OC_RSRVD_INTERFACE_READ);
1640     payload->rt = OICStrdup(OC_RSRVD_RESOURCE_TYPE_PLATFORM);
1641     payload->info = *platformInfo;
1642
1643     return payload;
1644 }
1645
1646 OCPlatformPayload* OCPlatformPayloadCreate(const OCPlatformInfo* platformInfo)
1647 {
1648     OCPlatformPayload* payload = (OCPlatformPayload*)OICCalloc(1, sizeof(OCPlatformPayload));
1649
1650     if (!payload)
1651     {
1652         return NULL;
1653     }
1654
1655     payload->base.type = PAYLOAD_TYPE_PLATFORM;
1656
1657     payload->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1658     if (!payload->interfaces)
1659     {
1660         return NULL;
1661     }
1662     payload->interfaces->value = OICStrdup(OC_RSRVD_INTERFACE_READ);
1663     payload->rt = OICStrdup(OC_RSRVD_RESOURCE_TYPE_PLATFORM);
1664     OCCopyPlatformInfo(platformInfo, payload);
1665
1666     return payload;
1667 }
1668
1669 void OCPlatformInfoDestroy(OCPlatformInfo *info)
1670 {
1671     OICFree(info->platformID);
1672     OICFree(info->manufacturerName);
1673     OICFree(info->manufacturerUrl);
1674     OICFree(info->modelNumber);
1675     OICFree(info->dateOfManufacture);
1676     OICFree(info->platformVersion);
1677     OICFree(info->operatingSystemVersion);
1678     OICFree(info->hardwareVersion);
1679     OICFree(info->firmwareVersion);
1680     OICFree(info->supportUrl);
1681     OICFree(info->systemTime);
1682 }
1683
1684 void OCPlatformPayloadDestroy(OCPlatformPayload* payload)
1685 {
1686     if (!payload)
1687     {
1688         return;
1689     }
1690     OICFree(payload->uri);
1691     OCPlatformInfoDestroy(&payload->info);
1692     OICFree(payload->rt);
1693     OCFreeOCStringLL(payload->interfaces);
1694     OICFree(payload);
1695 }
1696
1697 OCPresencePayload* OCPresencePayloadCreate(uint32_t seqNum, uint32_t maxAge,
1698         OCPresenceTrigger trigger, const char* resourceType)
1699 {
1700     OCPresencePayload* payload = (OCPresencePayload*)OICCalloc(1, sizeof(OCPresencePayload));
1701     if (!payload)
1702     {
1703         return NULL;
1704     }
1705
1706     payload->base.type = PAYLOAD_TYPE_PRESENCE;
1707     payload->sequenceNumber = seqNum;
1708     payload->maxAge = maxAge;
1709     payload->trigger = trigger;
1710     payload->resourceType = OICStrdup(resourceType);
1711     return payload;
1712 }
1713
1714 void OCPresencePayloadDestroy(OCPresencePayload* payload)
1715 {
1716     if (!payload)
1717     {
1718         return;
1719     }
1720     OICFree(payload->resourceType);
1721     OICFree(payload);
1722 }