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