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