2ad55b223c3b76c3109237ff10eeceebe64edd06
[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 securePort,
1390                                          uint16_t tcpPort)
1391 {
1392     OCResourcePayload* pl = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1393     if (!pl)
1394     {
1395         return NULL;
1396     }
1397
1398     pl->uri = OICStrdup(res->uri);
1399
1400     if (!pl->uri)
1401     {
1402         OCDiscoveryResourceDestroy(pl);
1403         return NULL;
1404     }
1405
1406     // types
1407     OCResourceType* typePtr = res->rsrcType;
1408
1409     if (typePtr != NULL)
1410     {
1411         pl->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1412         if (!pl->types)
1413         {
1414             OCDiscoveryResourceDestroy(pl);
1415             return NULL;
1416         }
1417         pl->types->value = OICStrdup(typePtr->resourcetypename);
1418         if (!pl->types->value)
1419         {
1420             OCDiscoveryResourceDestroy(pl);
1421             return NULL;
1422         }
1423
1424         OCStringLL* cur = pl->types;
1425         typePtr = typePtr->next;
1426         while(typePtr)
1427         {
1428             cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1429             if (!cur->next)
1430             {
1431                 OCDiscoveryResourceDestroy(pl);
1432                 return NULL;
1433             }
1434             cur->next->value = OICStrdup(typePtr->resourcetypename);
1435             if (!cur->next->value)
1436             {
1437                 OCDiscoveryResourceDestroy(pl);
1438                 return NULL;
1439             }
1440             cur = cur->next;
1441             typePtr = typePtr->next;
1442         }
1443     }
1444
1445     // interfaces
1446     OCResourceInterface* ifPtr = res->rsrcInterface;
1447     if (ifPtr != NULL)
1448     {
1449         pl->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1450         if (!pl->interfaces)
1451         {
1452             OCDiscoveryResourceDestroy(pl);
1453             return NULL;
1454         }
1455         pl->interfaces->value = OICStrdup(ifPtr->name);
1456         if (!pl->interfaces->value)
1457         {
1458             OCDiscoveryResourceDestroy(pl);
1459             return NULL;
1460         }
1461
1462         OCStringLL* cur = pl->interfaces;
1463         ifPtr = ifPtr->next;
1464         while(ifPtr && cur)
1465         {
1466             cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1467             if (!cur->next)
1468             {
1469                 OCDiscoveryResourceDestroy(pl);
1470                 return NULL;
1471             }
1472             cur->next->value = OICStrdup(ifPtr->name);
1473             if (!cur->next->value)
1474             {
1475                 OCDiscoveryResourceDestroy(pl);
1476                 return NULL;
1477             }
1478             cur = cur->next;
1479             ifPtr = ifPtr->next;
1480         }
1481     }
1482
1483     pl->bitmap = res->resourceProperties & (OC_OBSERVABLE | OC_DISCOVERABLE);
1484     pl->secure = (res->resourceProperties & OC_SECURE) != 0;
1485     pl->port = securePort;
1486 #ifdef TCP_ADAPTER
1487     pl->tcpPort = tcpPort;
1488 #endif
1489     return pl;
1490 }
1491
1492 void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
1493                                    uint16_t securePort, uint16_t tcpPort)
1494 {
1495     OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort, tcpPort));
1496 }
1497
1498 bool OCResourcePayloadAddStringLL(OCStringLL **stringLL, const char *value)
1499 {
1500     char *dup = OICStrdup(value);
1501     VERIFY_PARAM_NON_NULL(TAG, dup, "Failed copying string");
1502     VERIFY_PARAM_NON_NULL(TAG, value, "Invalid Parameters");
1503
1504     if (!*stringLL)
1505     {
1506         *stringLL = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
1507         VERIFY_PARAM_NON_NULL(TAG, *stringLL, "Failed allocating memory");
1508         (*stringLL)->value = dup;
1509         return true;
1510     }
1511     else
1512     {
1513         OCStringLL *temp = *stringLL;
1514         while(temp->next)
1515         {
1516             temp = temp->next;
1517         }
1518         temp->next = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
1519         VERIFY_PARAM_NON_NULL(TAG, temp->next, "Failed allocating memory");
1520         temp->next->value = dup;
1521         return true;
1522     }
1523 exit:
1524     OICFree(dup);
1525     return false;
1526 }
1527
1528 void OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload, OCResourcePayload* res)
1529 {
1530     if (!payload)
1531     {
1532         return;
1533     }
1534
1535     if (!payload->resources)
1536     {
1537         payload->resources = res;
1538     }
1539     else
1540     {
1541         OCResourcePayload* p = payload->resources;
1542         while(p->next)
1543         {
1544             p = p->next;
1545         }
1546         p->next = res;
1547     }
1548 }
1549
1550 void OCDiscoveryResourceDestroy(OCResourcePayload* payload)
1551 {
1552     if (!payload)
1553     {
1554         return;
1555     }
1556
1557     OICFree(payload->uri);
1558     OCFreeOCStringLL(payload->types);
1559     OCFreeOCStringLL(payload->interfaces);
1560     OCDiscoveryResourceDestroy(payload->next);
1561     OICFree(payload);
1562
1563 }
1564 void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload)
1565 {
1566     if (!payload)
1567     {
1568         return;
1569     }
1570     OICFree(payload->sid);
1571     OICFree(payload->baseURI);
1572     OICFree(payload->uri);
1573     OICFree(payload->type);
1574     OICFree(payload->name);
1575     OCFreeOCStringLL(payload->interface);
1576     OCDiscoveryResourceDestroy(payload->resources);
1577     OICFree(payload);
1578 }
1579
1580 OCDevicePayload* OCDevicePayloadCreate(const char* sid, const char* dname,
1581         const OCStringLL *types, const char* specVer, const char* dmVer)
1582 {
1583
1584     OCDevicePayload* payload = (OCDevicePayload*)OICCalloc(1, sizeof(OCDevicePayload));
1585
1586     if (!payload)
1587     {
1588         return NULL;
1589     }
1590
1591     payload->base.type = PAYLOAD_TYPE_DEVICE;
1592     payload->sid = OICStrdup(sid);
1593     if (sid && !payload->sid)
1594     {
1595         goto exit;
1596     }
1597
1598     payload->deviceName = OICStrdup(dname);
1599     if (dname && !payload->deviceName)
1600     {
1601         goto exit;
1602     }
1603
1604     payload->specVersion = OICStrdup(specVer);
1605     if (specVer && !payload->specVersion)
1606     {
1607         goto exit;
1608     }
1609
1610     payload->dataModelVersion = OICStrdup(dmVer);
1611     if (dmVer && !payload->dataModelVersion)
1612     {
1613         goto exit;
1614     }
1615
1616     OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_DEFAULT);
1617     OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_READ);
1618
1619     payload->types = CloneOCStringLL((OCStringLL *)types);
1620     if (types && !payload->types)
1621     {
1622         goto exit;
1623     }
1624
1625     return payload;
1626
1627 exit:
1628     OCDevicePayloadDestroy((OCDevicePayload*)payload);
1629     return NULL;
1630 }
1631
1632 void OCDevicePayloadDestroy(OCDevicePayload* payload)
1633 {
1634     if (!payload)
1635     {
1636         return;
1637     }
1638
1639     OICFree(payload->sid);
1640     OICFree(payload->deviceName);
1641     OICFree(payload->specVersion);
1642     OICFree(payload->dataModelVersion);
1643     OCFreeOCStringLL(payload->types);
1644     OCFreeOCStringLL(payload->interfaces);
1645     OICFree(payload);
1646 }
1647
1648 static void OCCopyPlatformInfo(const OCPlatformInfo* platformInfo, OCPlatformPayload* target)
1649 {
1650     if (!platformInfo || !target)
1651     {
1652         return;
1653     }
1654
1655     target->info.platformID = OICStrdup(platformInfo->platformID);
1656     target->info.manufacturerName = OICStrdup(platformInfo->manufacturerName);
1657     target->info.manufacturerUrl = OICStrdup(platformInfo->manufacturerUrl);
1658     target->info.modelNumber = OICStrdup(platformInfo->modelNumber);
1659     target->info.dateOfManufacture = OICStrdup(platformInfo->dateOfManufacture);
1660     target->info.platformVersion = OICStrdup(platformInfo->platformVersion);
1661     target->info.operatingSystemVersion = OICStrdup(platformInfo->operatingSystemVersion);
1662     target->info.hardwareVersion = OICStrdup(platformInfo->hardwareVersion);
1663     target->info.firmwareVersion = OICStrdup(platformInfo->firmwareVersion);
1664     target->info.supportUrl = OICStrdup(platformInfo->supportUrl);
1665     target->info.systemTime = OICStrdup(platformInfo->systemTime);
1666 }
1667
1668 OCPlatformPayload* OCPlatformPayloadCreateAsOwner(OCPlatformInfo* platformInfo)
1669 {
1670     OCPlatformPayload* payload = (OCPlatformPayload*)OICCalloc(1, sizeof(OCPlatformPayload));
1671     if (!payload)
1672     {
1673         return NULL;
1674     }
1675
1676     payload->base.type = PAYLOAD_TYPE_PLATFORM;
1677
1678     payload->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1679     if (!payload->interfaces)
1680     {
1681         return NULL;
1682     }
1683     payload->interfaces->value = OICStrdup(OC_RSRVD_INTERFACE_READ);
1684     payload->rt = OICStrdup(OC_RSRVD_RESOURCE_TYPE_PLATFORM);
1685     payload->info = *platformInfo;
1686
1687     return payload;
1688 }
1689
1690 OCPlatformPayload* OCPlatformPayloadCreate(const OCPlatformInfo* platformInfo)
1691 {
1692     OCPlatformPayload* payload = (OCPlatformPayload*)OICCalloc(1, sizeof(OCPlatformPayload));
1693
1694     if (!payload)
1695     {
1696         return NULL;
1697     }
1698
1699     payload->base.type = PAYLOAD_TYPE_PLATFORM;
1700     payload->rt = OICStrdup(OC_RSRVD_RESOURCE_TYPE_PLATFORM);
1701
1702     OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_DEFAULT);
1703     OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_READ);
1704
1705     OCCopyPlatformInfo(platformInfo, payload);
1706
1707     return payload;
1708 }
1709
1710 void OCPlatformInfoDestroy(OCPlatformInfo *info)
1711 {
1712     OICFree(info->platformID);
1713     OICFree(info->manufacturerName);
1714     OICFree(info->manufacturerUrl);
1715     OICFree(info->modelNumber);
1716     OICFree(info->dateOfManufacture);
1717     OICFree(info->platformVersion);
1718     OICFree(info->operatingSystemVersion);
1719     OICFree(info->hardwareVersion);
1720     OICFree(info->firmwareVersion);
1721     OICFree(info->supportUrl);
1722     OICFree(info->systemTime);
1723 }
1724
1725 void OCPlatformPayloadDestroy(OCPlatformPayload* payload)
1726 {
1727     if (!payload)
1728     {
1729         return;
1730     }
1731     OICFree(payload->uri);
1732     OCPlatformInfoDestroy(&payload->info);
1733     OICFree(payload->rt);
1734     OCFreeOCStringLL(payload->interfaces);
1735     OICFree(payload);
1736 }
1737
1738 OCPresencePayload* OCPresencePayloadCreate(uint32_t seqNum, uint32_t maxAge,
1739         OCPresenceTrigger trigger, const char* resourceType)
1740 {
1741     OCPresencePayload* payload = (OCPresencePayload*)OICCalloc(1, sizeof(OCPresencePayload));
1742     if (!payload)
1743     {
1744         return NULL;
1745     }
1746
1747     payload->base.type = PAYLOAD_TYPE_PRESENCE;
1748     payload->sequenceNumber = seqNum;
1749     payload->maxAge = maxAge;
1750     payload->trigger = trigger;
1751     payload->resourceType = OICStrdup(resourceType);
1752     return payload;
1753 }
1754
1755 void OCPresencePayloadDestroy(OCPresencePayload* payload)
1756 {
1757     if (!payload)
1758     {
1759         return;
1760     }
1761     OICFree(payload->resourceType);
1762     OICFree(payload);
1763 }