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