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