2c8648eaef49cd1eac17909eda6e3516f0a7b1e1
[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 // Required for strok_r
22 #define _POSIX_C_SOURCE 200112L
23
24 #include "iotivity_config.h"
25 #include <stdio.h>
26 #include "ocpayload.h"
27 #include "octypes.h"
28 #include <string.h>
29 #include "oic_malloc.h"
30 #include "oic_string.h"
31 #include "ocstackinternal.h"
32 #include "ocresource.h"
33 #include "logger.h"
34 #include "ocendpoint.h"
35 #include "cacommon.h"
36
37 #define TAG "OIC_RI_PAYLOAD"
38 #define CSV_SEPARATOR ','
39
40 static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val);
41
42 void OCPayloadDestroy(OCPayload* payload)
43 {
44     if (!payload)
45     {
46         return;
47     }
48
49     switch(payload->type)
50     {
51         case PAYLOAD_TYPE_REPRESENTATION:
52             OCRepPayloadDestroy((OCRepPayload*)payload);
53             break;
54         case PAYLOAD_TYPE_DISCOVERY:
55             OCDiscoveryPayloadDestroy((OCDiscoveryPayload*)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         default:
64             OIC_LOG_V(ERROR, TAG, "Unsupported payload type in destroy: %d", payload->type);
65             OICFree(payload);
66             break;
67     }
68 }
69
70 OCRepPayload* OCRepPayloadCreate()
71 {
72     OCRepPayload* payload = (OCRepPayload*)OICCalloc(1, sizeof(OCRepPayload));
73
74     if (!payload)
75     {
76         return NULL;
77     }
78
79     payload->base.type = PAYLOAD_TYPE_REPRESENTATION;
80
81     return payload;
82 }
83
84 void OCRepPayloadAppend(OCRepPayload* parent, OCRepPayload* child)
85 {
86     if (!parent)
87     {
88         return;
89     }
90
91     while(parent->next)
92     {
93         parent = parent->next;
94     }
95
96     parent->next= child;
97     child->next = NULL;
98 }
99
100 static OCRepPayloadValue* OCRepPayloadFindValue(const OCRepPayload* payload, const char* name)
101 {
102     if (!payload || !name)
103     {
104         return NULL;
105     }
106
107     OCRepPayloadValue* val = payload->values;
108     while(val)
109     {
110         if (0 == strcmp(val->name, name))
111         {
112             return val;
113         }
114         val = val->next;
115     }
116
117     return NULL;
118 }
119
120 static void OCCopyPropertyValueArray(OCRepPayloadValue* dest, OCRepPayloadValue* source)
121 {
122     if (!dest || !source)
123     {
124         return;
125     }
126
127     size_t dimTotal = calcDimTotal(source->arr.dimensions);
128     switch(source->arr.type)
129     {
130         case OCREP_PROP_INT:
131             dest->arr.iArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
132             VERIFY_PARAM_NON_NULL(TAG, dest->arr.iArray, "Failed allocating memory");
133             memcpy(dest->arr.iArray, source->arr.iArray, dimTotal * sizeof(int64_t));
134             break;
135         case OCREP_PROP_DOUBLE:
136             dest->arr.dArray = (double*)OICMalloc(dimTotal * sizeof(double));
137             VERIFY_PARAM_NON_NULL(TAG, dest->arr.dArray, "Failed allocating memory");
138             memcpy(dest->arr.dArray, source->arr.dArray, dimTotal * sizeof(double));
139             break;
140         case OCREP_PROP_BOOL:
141             dest->arr.bArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
142             VERIFY_PARAM_NON_NULL(TAG, dest->arr.bArray, "Failed allocating memory");
143             memcpy(dest->arr.bArray, source->arr.bArray, dimTotal * sizeof(bool));
144             break;
145         case OCREP_PROP_STRING:
146             dest->arr.strArray = (char**)OICMalloc(dimTotal * sizeof(char*));
147             VERIFY_PARAM_NON_NULL(TAG, dest->arr.strArray, "Failed allocating memory");
148             for(size_t i = 0; i < dimTotal; ++i)
149             {
150                 dest->arr.strArray[i] = OICStrdup(source->arr.strArray[i]);
151             }
152             break;
153         case OCREP_PROP_OBJECT:
154             dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
155             VERIFY_PARAM_NON_NULL(TAG, dest->arr.objArray, "Failed allocating memory");
156             for(size_t i = 0; i < dimTotal; ++i)
157             {
158                 dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
159             }
160             break;
161         case OCREP_PROP_ARRAY:
162             dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
163             VERIFY_PARAM_NON_NULL(TAG, dest->arr.objArray, "Failed allocating memory");
164             for(size_t i = 0; i < dimTotal; ++i)
165             {
166                 dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
167             }
168             break;
169         case OCREP_PROP_BYTE_STRING:
170             dest->arr.ocByteStrArray = (OCByteString*)OICMalloc(dimTotal * sizeof(OCByteString));
171             VERIFY_PARAM_NON_NULL(TAG, dest->arr.ocByteStrArray, "Failed allocating memory");
172             for (size_t i = 0; i < dimTotal; ++i)
173             {
174                 OCByteStringCopy(&dest->arr.ocByteStrArray[i], &source->arr.ocByteStrArray[i]);
175                 VERIFY_PARAM_NON_NULL(TAG, dest->arr.ocByteStrArray[i].bytes, "Failed allocating memory");
176             }
177             break;
178         default:
179             OIC_LOG(ERROR, TAG, "CopyPropertyValueArray invalid type");
180             break;
181     }
182 exit:
183     return;
184 }
185
186 static void OCCopyPropertyValue (OCRepPayloadValue *dest, OCRepPayloadValue *source)
187 {
188     if (!source || !dest)
189     {
190         return;
191     }
192
193     switch(source->type)
194     {
195         case OCREP_PROP_STRING:
196             dest->str = OICStrdup(source->str);
197             break;
198         case OCREP_PROP_BYTE_STRING:
199             dest->ocByteStr.bytes = (uint8_t*)OICMalloc(source->ocByteStr.len * sizeof(uint8_t));
200             VERIFY_PARAM_NON_NULL(TAG, dest->ocByteStr.bytes, "Failed allocating memory");
201             dest->ocByteStr.len = source->ocByteStr.len;
202             memcpy(dest->ocByteStr.bytes, source->ocByteStr.bytes, dest->ocByteStr.len);
203             break;
204         case OCREP_PROP_OBJECT:
205             dest->obj = OCRepPayloadClone(source->obj);
206             break;
207         case OCREP_PROP_ARRAY:
208             OCCopyPropertyValueArray(dest, source);
209             break;
210         default:
211             // Nothing to do for the trivially copyable types.
212             break;
213     }
214 exit:
215     return;
216 }
217
218 static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val)
219 {
220     if (!val)
221     {
222         return;
223     }
224
225     if (val->type == OCREP_PROP_STRING)
226     {
227         OICFree(val->str);
228     }
229     else if (val->type == OCREP_PROP_BYTE_STRING)
230     {
231         OICFree(val->ocByteStr.bytes);
232     }
233     else if (val->type == OCREP_PROP_OBJECT)
234     {
235         OCRepPayloadDestroy(val->obj);
236     }
237     else if (val->type == OCREP_PROP_ARRAY)
238     {
239         size_t dimTotal = calcDimTotal(val->arr.dimensions);
240         switch(val->arr.type)
241         {
242             case OCREP_PROP_INT:
243             case OCREP_PROP_DOUBLE:
244             case OCREP_PROP_BOOL:
245                 // Since this is a union, iArray will
246                 // point to all of the above
247                 OICFree(val->arr.iArray);
248                 break;
249             case OCREP_PROP_STRING:
250                 for(size_t i = 0; i < dimTotal; ++i)
251                 {
252                     OICFree(val->arr.strArray[i]);
253                 }
254                 OICFree(val->arr.strArray);
255                 break;
256             case OCREP_PROP_BYTE_STRING:
257                 for (size_t i = 0; i < dimTotal; ++i)
258                 {
259                     if (val->arr.ocByteStrArray[i].bytes)
260                     {
261                         OICFree(val->arr.ocByteStrArray[i].bytes);
262                     }
263                 }
264                 OICFree(val->arr.ocByteStrArray);
265                 break;
266             case OCREP_PROP_OBJECT: // This case is the temporary fix for string input
267                 for(size_t i = 0; i< dimTotal; ++i)
268                 {
269                     OCRepPayloadDestroy(val->arr.objArray[i]);
270                 }
271                 OICFree(val->arr.objArray);
272                 break;
273             case OCREP_PROP_NULL:
274             case OCREP_PROP_ARRAY:
275                 OIC_LOG_V(ERROR, TAG, "FreeRepPayloadValueContents: Illegal type\
276                         inside an array: %d", val->arr.type);
277                 break;
278         }
279     }
280 }
281
282 static void OCFreeRepPayloadValue(OCRepPayloadValue* val)
283 {
284     if (!val)
285     {
286         return;
287     }
288
289     OICFree(val->name);
290     OCFreeRepPayloadValueContents(val);
291     OCFreeRepPayloadValue(val->next);
292     OICFree(val);
293 }
294 static OCRepPayloadValue* OCRepPayloadValueClone (OCRepPayloadValue* source)
295 {
296     if (!source)
297     {
298         return NULL;
299     }
300
301     OCRepPayloadValue *sourceIter = source;
302     OCRepPayloadValue *destIter = (OCRepPayloadValue*) OICCalloc(1, sizeof(OCRepPayloadValue));
303     if (!destIter)
304     {
305         return NULL;
306     }
307
308     OCRepPayloadValue *headOfClone = destIter;
309
310     // Copy payload type and non pointer types in union.
311     *destIter = *sourceIter;
312     destIter->name = OICStrdup (sourceIter->name);
313     OCCopyPropertyValue (destIter, sourceIter);
314
315     sourceIter = sourceIter->next;
316
317     while (sourceIter)
318     {
319         destIter->next = (OCRepPayloadValue*) OICCalloc(1, sizeof(OCRepPayloadValue));
320         if (!destIter->next)
321         {
322             OCFreeRepPayloadValue (headOfClone);
323             return NULL;
324         }
325
326         *(destIter->next) = *sourceIter;
327         destIter->next->name = OICStrdup (sourceIter->name);
328         OCCopyPropertyValue (destIter->next, sourceIter);
329
330         sourceIter = sourceIter->next;
331         destIter = destIter->next;
332     }
333     return headOfClone;
334 }
335
336 static OCRepPayloadValue* OCRepPayloadFindAndSetValue(OCRepPayload* payload, const char* name,
337         OCRepPayloadPropType type)
338 {
339     if (!payload || !name)
340     {
341         return NULL;
342     }
343
344     OCRepPayloadValue* val = payload->values;
345     if (val == NULL)
346     {
347         payload->values = (OCRepPayloadValue*)OICCalloc(1, sizeof(OCRepPayloadValue));
348         if (!payload->values)
349         {
350             return NULL;
351         }
352         payload->values->name = OICStrdup(name);
353         if (!payload->values->name)
354         {
355             OICFree(payload->values);
356             payload->values = NULL;
357             return NULL;
358         }
359         payload->values->type =type;
360         return payload->values;
361     }
362
363     while(val)
364     {
365         if (0 == strcmp(val->name, name))
366         {
367             OCFreeRepPayloadValueContents(val);
368             val->type = type;
369             return val;
370         }
371         else if (val->next == NULL)
372         {
373             val->next = (OCRepPayloadValue*)OICCalloc(1, sizeof(OCRepPayloadValue));
374             if (!val->next)
375             {
376                 return NULL;
377             }
378             val->next->name = OICStrdup(name);
379             if (!val->next->name)
380             {
381                 OICFree(val->next);
382                 val->next = NULL;
383                 return NULL;
384             }
385             val->next->type =type;
386             return val->next;
387         }
388
389         val = val->next;
390     }
391
392     OIC_LOG(ERROR, TAG, "FindAndSetValue reached point after while loop, pointer corruption?");
393     return NULL;
394 }
395
396 bool OCRepPayloadAddResourceType(OCRepPayload* payload, const char* resourceType)
397 {
398     return OCRepPayloadAddResourceTypeAsOwner(payload, OICStrdup(resourceType));
399 }
400
401 bool OCRepPayloadAddResourceTypeAsOwner(OCRepPayload* payload, char* resourceType)
402 {
403     if (!payload || !resourceType)
404     {
405         return false;
406     }
407
408     if (payload->types)
409     {
410         OCStringLL* cur = payload->types;
411         while(cur->next)
412         {
413             cur = cur->next;
414         }
415         cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
416
417         if (!cur->next)
418         {
419             return false;
420         }
421
422         cur->next->value = resourceType;
423         return true;
424     }
425     else
426     {
427         payload->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
428         if (!payload->types)
429         {
430             return false;
431         }
432         payload->types->value = resourceType;
433         return true;
434     }
435 }
436
437 bool OCRepPayloadAddInterface(OCRepPayload* payload, const char* iface)
438 {
439     return OCRepPayloadAddInterfaceAsOwner(payload, OICStrdup(iface));
440 }
441
442 bool OCRepPayloadAddInterfaceAsOwner(OCRepPayload* payload, char* iface)
443 {
444     if (!payload || !iface)
445     {
446         return false;
447     }
448
449     if (payload->interfaces)
450     {
451         OCStringLL* cur = payload->interfaces;
452         while(cur->next)
453         {
454             cur = cur->next;
455         }
456         cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
457
458         if (!cur->next)
459         {
460             return false;
461         }
462         cur->next->value = iface;
463         return true;
464     }
465     else
466     {
467         payload->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
468         if (!payload->interfaces)
469         {
470             return false;
471         }
472         payload->interfaces->value = iface;
473         return true;
474     }
475 }
476
477 bool OCRepPayloadSetUri(OCRepPayload* payload, const char*  uri)
478 {
479     if (!payload)
480     {
481         return false;
482     }
483     OICFree(payload->uri);
484     payload->uri = OICStrdup(uri);
485     return payload->uri != NULL;
486 }
487
488 bool OCRepPayloadIsNull(const OCRepPayload* payload, const char* name)
489 {
490     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
491
492     if (!val)
493     {
494         return true;
495     }
496
497     return val->type == OCREP_PROP_NULL;
498 }
499
500 static bool OCRepPayloadSetProp(OCRepPayload* payload, const char* name,
501         void* value, OCRepPayloadPropType type)
502 {
503     OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, type);
504     if (!val)
505     {
506         return false;
507     }
508     switch(type)
509     {
510         case OCREP_PROP_INT:
511                val->i = *(int64_t*)value;
512                break;
513         case OCREP_PROP_DOUBLE:
514                val->d = *(double*)value;
515                break;
516         case OCREP_PROP_BOOL:
517                val->b = *(bool*)value;
518                break;
519         case OCREP_PROP_OBJECT:
520                val->obj = (OCRepPayload*)value;
521                break;
522         case OCREP_PROP_STRING:
523                val->str = (char*)value;
524                return val->str != NULL;
525         case OCREP_PROP_BYTE_STRING:
526                val->ocByteStr = *(OCByteString*)value;
527                return val->ocByteStr.bytes != NULL;
528         case OCREP_PROP_NULL:
529                return val != NULL;
530         case OCREP_PROP_ARRAY:
531         default:
532                return false;
533     }
534
535     return true;
536 }
537
538 bool OCRepPayloadSetNull(OCRepPayload* payload, const char* name)
539 {
540     return OCRepPayloadSetProp(payload, name, NULL, OCREP_PROP_NULL);
541 }
542
543 bool OCRepPayloadSetPropInt(OCRepPayload* payload,
544         const char* name, int64_t value)
545 {
546     return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_INT);
547 }
548
549 bool OCRepPayloadGetPropInt(const OCRepPayload* payload, const char* name, int64_t* value)
550 {
551     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
552
553     if (!val || val->type != OCREP_PROP_INT)
554     {
555         return false;
556     }
557
558     *value = val->i;
559     return true;
560 }
561
562 bool OCRepPayloadSetPropDouble(OCRepPayload* payload,
563                                const char* name, double value)
564 {
565     return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_DOUBLE);
566 }
567
568 bool OCRepPayloadGetPropDouble(const OCRepPayload* payload, const char* name, double* value)
569 {
570     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
571
572     if (val)
573     {
574         if (val->type == OCREP_PROP_DOUBLE)
575         {
576             *value = val->d;
577             return true;
578         }
579         else if (val->type == OCREP_PROP_INT)
580         {
581 // Should be removed once IOT-1705 is fixed.
582 #ifdef _MSC_VER
583 #pragma warning( suppress : 4244 )
584             *value = val->i;
585 #else
586             *value = val->i;
587 #endif
588             return true;
589         }
590     }
591
592     return false;
593 }
594
595 bool OCRepPayloadSetPropString(OCRepPayload* payload, const char* name, const char* value)
596 {
597     char* temp = OICStrdup(value);
598     bool b = OCRepPayloadSetPropStringAsOwner(payload, name, temp);
599
600     if (!b)
601     {
602         OICFree(temp);
603     }
604     return b;
605 }
606
607 bool OCRepPayloadSetPropStringAsOwner(OCRepPayload* payload, const char* name, char* value)
608 {
609     return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_STRING);
610 }
611
612 bool OCRepPayloadGetPropString(const OCRepPayload* payload, const char* name, char** value)
613 {
614     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
615
616     if (!val || val->type != OCREP_PROP_STRING)
617     {
618         return false;
619     }
620
621     *value = OICStrdup(val->str);
622     return *value != NULL;
623 }
624
625 bool OCRepPayloadSetPropByteString(OCRepPayload* payload, const char* name, OCByteString value)
626 {
627     if (!value.bytes || !value.len)
628     {
629         return false;
630     }
631
632     OCByteString ocByteStr = {NULL, 0};
633     bool b = OCByteStringCopy(&ocByteStr, &value);
634
635     if (b)
636     {
637         b = OCRepPayloadSetPropByteStringAsOwner(payload, name, &ocByteStr);
638     }
639     if (!b)
640     {
641         OICFree(ocByteStr.bytes);
642     }
643     return b;
644 }
645
646 bool OCRepPayloadSetPropByteStringAsOwner(OCRepPayload* payload, const char* name, OCByteString* value)
647 {
648     return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_BYTE_STRING);
649 }
650
651 bool OCRepPayloadGetPropByteString(const OCRepPayload* payload, const char* name, OCByteString* value)
652 {
653     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
654
655     if (!val || val->type != OCREP_PROP_BYTE_STRING)
656     {
657         return false;
658     }
659
660     if (!value)
661     {
662         return false;
663     }
664
665     value->bytes = (uint8_t*)OICMalloc(val->ocByteStr.len * sizeof(uint8_t));
666     if (!value->bytes)
667     {
668         return false;
669     }
670     value->len = val->ocByteStr.len;
671     memcpy(value->bytes, val->ocByteStr.bytes, value->len);
672
673     return true;
674 }
675
676 bool OCRepPayloadSetPropBool(OCRepPayload* payload,
677                              const char* name, bool value)
678 {
679     return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_BOOL);
680 }
681
682 bool OCRepPayloadGetPropBool(const OCRepPayload* payload, const char* name, bool* value)
683 {
684     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
685
686     if (!val || val->type != OCREP_PROP_BOOL)
687     {
688         return false;
689     }
690
691     *value = val->b;
692     return true;
693 }
694
695 #ifdef __WITH_TLS__
696 static char *getStringFromEncodingType(OicEncodingType_t type)
697 {
698     char *str = NULL;
699     switch (type)
700     {
701         case OIC_ENCODING_BASE64: str = OC_RSRVD_BASE64; break;
702         case OIC_ENCODING_DER: str = OC_RSRVD_DER; break;
703         case OIC_ENCODING_PEM: str = OC_RSRVD_PEM; break;
704         case OIC_ENCODING_RAW: str = OC_RSRVD_RAW; break;
705         default: str = OC_RSRVD_UNKNOWN; break;
706     }
707     char encoding[32];
708     snprintf(encoding, sizeof(encoding), "%s.%s.%s", OC_OIC_SEC, OC_RSRVD_ENCODING, str);
709
710     return OICStrdup(encoding);
711 }
712
713 bool OCRepPayloadSetPropPubDataTypeAsOwner(OCRepPayload *payload, const char *name,
714                                            const OicSecKey_t *value)
715 {
716     if (!payload || !name || !value)
717     {
718         return false;
719     }
720
721     bool binary_field = false;
722     if (OIC_ENCODING_RAW == value->encoding || OIC_ENCODING_DER == value->encoding)
723     {
724         binary_field = true;
725     }
726
727     OCRepPayload *heplerPayload = OCRepPayloadCreate();
728     if (!heplerPayload)
729     {
730         return false;
731     }
732
733     char *encoding = getStringFromEncodingType(value->encoding);
734     if (!OCRepPayloadSetPropString(heplerPayload, OC_RSRVD_ENCODING, encoding))
735     {
736         OIC_LOG_V(ERROR, TAG, "Can't set %s", OC_RSRVD_ENCODING);
737     }
738
739     OCByteString val = {.bytes = value->data, .len = value->len};
740     if (binary_field)
741     {
742         if (!OCRepPayloadSetPropByteString(heplerPayload, OC_RSRVD_DATA, val))
743         {
744             OIC_LOG_V(ERROR, TAG, "Can't set %s", OC_RSRVD_DATA);
745         }
746     }
747     else
748     {
749         if (!OCRepPayloadSetPropString(heplerPayload, OC_RSRVD_DATA, (char *)val.bytes))
750         {
751             OIC_LOG_V(ERROR, TAG, "Can't set %s", OC_RSRVD_DATA);
752         }
753     }
754
755     if (!OCRepPayloadSetPropObject(payload, name, (const OCRepPayload *)heplerPayload))
756     {
757         OIC_LOG_V(ERROR, TAG, "Can't set %s", name);
758     }
759
760     OCRepPayloadDestroy(heplerPayload);
761     OICFree(encoding);
762
763     return true;
764 }
765
766 bool OCRepPayloadSetPropPubDataType(OCRepPayload *payload, const char *name,
767                                     const OicSecKey_t *value)
768 {
769     return OCRepPayloadSetPropPubDataTypeAsOwner(payload, name, value);
770 }
771
772 static OicEncodingType_t getEncodingTypeFromString(char *encoding)
773 {
774     OicEncodingType_t type = OIC_ENCODING_UNKNOW;
775
776     char *str = strrchr(encoding, '.');
777     if (NULL == str)
778     {
779         OIC_LOG_V(ERROR, TAG, "Can't find . in %s", encoding);
780         return type;
781     }
782     str++; //go to encoding itself
783
784     if (0 == strcmp(str, OC_RSRVD_BASE64)) type = OIC_ENCODING_BASE64;
785     else if (0 == strcmp(str, OC_RSRVD_DER)) type = OIC_ENCODING_DER;
786     else if (0 == strcmp(str, OC_RSRVD_PEM)) type = OIC_ENCODING_PEM;
787     else if (0 == strcmp(str, OC_RSRVD_RAW)) type = OIC_ENCODING_RAW;
788
789     return type;
790 }
791
792 bool OCRepPayloadGetPropPubDataType(const OCRepPayload *payload, const char *name, OicSecKey_t *value)
793 {
794     OCRepPayload *heplerPayload = NULL;
795     char *encoding = NULL;
796     OCByteString val;
797
798     if (!payload || !name || !value)
799     {
800         return false;
801     }
802
803     if (!OCRepPayloadGetPropObject(payload, name, &heplerPayload))
804     {
805         OIC_LOG_V(ERROR, TAG, "Can't get object with name %s", name);
806         return false;
807     }
808
809     if (!OCRepPayloadGetPropString(heplerPayload, OC_RSRVD_ENCODING, &encoding))
810     {
811         OIC_LOG_V(ERROR, TAG, "Can't get %s", OC_RSRVD_ENCODING);
812     }
813     else
814     {
815         value->encoding = getEncodingTypeFromString(encoding);
816         OICFree(encoding);
817     }
818
819     if (!OCRepPayloadGetPropByteString(heplerPayload, OC_RSRVD_DATA, &val))
820     {
821         if (!OCRepPayloadGetPropString(heplerPayload, OC_RSRVD_DATA, (char **)&val.bytes))
822         {
823             OIC_LOG_V(ERROR, TAG, "Can't get: %s", OC_RSRVD_DATA);
824         }
825         else
826         {
827             value->data = val.bytes;
828             value->len  = strlen(val.bytes);
829         }
830     }
831     else
832     {
833         value->data = val.bytes;
834         value->len  = val.len;
835     }
836
837     OCRepPayloadDestroy(heplerPayload);
838     return true;
839 }
840 #endif
841
842 bool OCRepPayloadSetPropObject(OCRepPayload* payload, const char* name, const OCRepPayload* value)
843 {
844     OCRepPayload* temp = OCRepPayloadClone(value);
845     bool b = OCRepPayloadSetPropObjectAsOwner(payload, name, temp);
846
847     if (!b)
848     {
849         OCRepPayloadDestroy(temp);
850     }
851     return b;
852 }
853
854 bool OCRepPayloadSetPropObjectAsOwner(OCRepPayload* payload, const char* name, OCRepPayload* value)
855 {
856     return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_OBJECT);
857 }
858
859 bool OCRepPayloadGetPropObject(const OCRepPayload* payload, const char* name, OCRepPayload** value)
860 {
861     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
862
863     if (!val || val->type != OCREP_PROP_OBJECT)
864     {
865         return false;
866     }
867
868     *value = OCRepPayloadClone(val->obj);
869     return *value != NULL;
870 }
871
872 size_t calcDimTotal(const size_t dimensions[MAX_REP_ARRAY_DEPTH])
873 {
874     if (dimensions[0] == 0)
875     {
876         return 0;
877     }
878
879     size_t total = 1;
880     for(uint8_t i = 0; i < MAX_REP_ARRAY_DEPTH && dimensions[i] != 0; ++i)
881     {
882         total *= dimensions[i];
883     }
884     return total;
885 }
886
887
888 bool OCRepPayloadSetByteStringArrayAsOwner(OCRepPayload* payload, const char* name,
889         OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
890 {
891     OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
892
893     if (!val)
894     {
895         return false;
896     }
897
898     val->arr.type = OCREP_PROP_BYTE_STRING;
899     memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
900     val->arr.ocByteStrArray = array;
901
902     return true;
903 }
904
905 bool OCRepPayloadSetByteStringArray(OCRepPayload* payload, const char* name,
906         const OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
907 {
908     if (!array)
909     {
910         return false;
911     }
912
913     size_t dimTotal = calcDimTotal(dimensions);
914     if (dimTotal == 0)
915     {
916         return false;
917     }
918
919     OCByteString* newArray = (OCByteString*)OICCalloc(dimTotal, sizeof(OCByteString));
920
921     if (!newArray)
922     {
923         return false;
924     }
925
926     for (size_t i = 0; i < dimTotal; ++i)
927     {
928         newArray[i].bytes = (uint8_t*)OICMalloc(array[i].len * sizeof(uint8_t));
929         if (NULL == newArray[i].bytes)
930         {
931             for (size_t j = 0; j < i; ++j)
932             {
933                 OICFree(newArray[j].bytes);
934             }
935
936             OICFree(newArray);
937             return false;
938         }
939         newArray[i].len = array[i].len;
940         memcpy(newArray[i].bytes, array[i].bytes, newArray[i].len);
941     }
942
943     bool b = OCRepPayloadSetByteStringArrayAsOwner(payload, name, newArray, dimensions);
944     if (!b)
945     {
946         for (size_t i = 0; i < dimTotal; ++i)
947         {
948             OICFree(newArray[i].bytes);
949         }
950
951         OICFree(newArray);
952     }
953     return b;
954 }
955
956 bool OCRepPayloadGetByteStringArray(const OCRepPayload* payload, const char* name,
957         OCByteString** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
958 {
959     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
960
961     if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_BYTE_STRING
962             || !val->arr.ocByteStrArray)
963     {
964         return false;
965     }
966
967     size_t dimTotal = calcDimTotal(val->arr.dimensions);
968     if (dimTotal == 0)
969     {
970         return false;
971     }
972
973     *array = (OCByteString*)OICCalloc(dimTotal, sizeof(OCByteString));
974     if (!*array)
975     {
976         return false;
977     }
978
979     for (size_t i = 0; i < dimTotal; ++i)
980     {
981         OCByteString* tmp = &(*array)[i];
982         tmp->bytes = (uint8_t*)OICMalloc(val->arr.ocByteStrArray[i].len * sizeof(uint8_t));
983         if (NULL == tmp->bytes)
984         {
985             for (size_t j = 0; j < i; ++j)
986             {
987                 OCByteString* tmp = &(*array)[j];
988                 OICFree(tmp->bytes);
989             }
990             OICFree(*array);
991             *array = NULL;
992
993             return false;
994         }
995         tmp->len = val->arr.ocByteStrArray[i].len;
996         memcpy(tmp->bytes, val->arr.ocByteStrArray[i].bytes, tmp->len);
997     }
998
999     memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1000     return true;
1001 }
1002
1003
1004 bool OCRepPayloadSetIntArrayAsOwner(OCRepPayload* payload, const char* name,
1005         int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1006 {
1007     OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1008
1009     if (!val)
1010     {
1011         return false;
1012     }
1013
1014     val->arr.type = OCREP_PROP_INT;
1015     memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1016     val->arr.iArray = array;
1017
1018     return true;
1019 }
1020
1021 bool OCRepPayloadSetIntArray(OCRepPayload* payload, const char* name,
1022         const int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1023 {
1024     size_t dimTotal = calcDimTotal(dimensions);
1025     if (dimTotal == 0)
1026     {
1027         return false;
1028     }
1029
1030     int64_t* newArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
1031
1032     if (!newArray)
1033     {
1034         return false;
1035     }
1036
1037     memcpy(newArray, array, dimTotal * sizeof(int64_t));
1038
1039
1040     bool b = OCRepPayloadSetIntArrayAsOwner(payload, name, newArray, dimensions);
1041     if (!b)
1042     {
1043         OICFree(newArray);
1044     }
1045     return b;
1046 }
1047
1048 bool OCRepPayloadGetIntArray(const OCRepPayload* payload, const char* name,
1049         int64_t** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1050 {
1051     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1052
1053     if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_INT
1054             || !val->arr.iArray)
1055     {
1056         return false;
1057     }
1058
1059     size_t dimTotal = calcDimTotal(val->arr.dimensions);
1060     if (dimTotal == 0)
1061     {
1062         return false;
1063     }
1064     *array = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
1065     if (!*array)
1066     {
1067         return false;
1068     }
1069
1070     memcpy(*array, val->arr.iArray, dimTotal * sizeof(int64_t));
1071     memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1072     return true;
1073 }
1074
1075 bool OCRepPayloadSetDoubleArrayAsOwner(OCRepPayload* payload, const char* name,
1076         double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
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_DOUBLE;
1086     memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1087     val->arr.dArray = array;
1088
1089     return true;
1090 }
1091 bool OCRepPayloadSetDoubleArray(OCRepPayload* payload, const char* name,
1092         const double* 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     double* newArray = (double*)OICMalloc(dimTotal * sizeof(double));
1101
1102     if (!newArray)
1103     {
1104         return false;
1105     }
1106
1107     memcpy(newArray, array, dimTotal * sizeof(double));
1108
1109     bool b = OCRepPayloadSetDoubleArrayAsOwner(payload, name, newArray, dimensions);
1110     if (!b)
1111     {
1112         OICFree(newArray);
1113     }
1114     return b;
1115 }
1116
1117 bool OCRepPayloadGetDoubleArray(const OCRepPayload* payload, const char* name,
1118         double** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1119 {
1120     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1121
1122     if (!val ||
1123         (val->type != OCREP_PROP_ARRAY) ||
1124         ((val->arr.type != OCREP_PROP_DOUBLE) &&
1125          (val->arr.type != OCREP_PROP_INT)) ||
1126         !val->arr.dArray)
1127     {
1128         return false;
1129     }
1130
1131     size_t dimTotal = calcDimTotal(val->arr.dimensions);
1132     if (dimTotal == 0)
1133     {
1134         return false;
1135     }
1136     *array = (double*)OICMalloc(dimTotal * sizeof(double));
1137     if (!*array)
1138     {
1139         return false;
1140     }
1141
1142     if (val->arr.type == OCREP_PROP_DOUBLE)
1143     {
1144         memcpy(*array, val->arr.dArray, dimTotal * sizeof(double));
1145     }
1146     else
1147     {
1148         /* need to convert from integer */
1149         size_t n = 0;
1150         for ( ; n < dimTotal; ++n)
1151         {
1152 // Should be removed once IOT-1705 is fixed.
1153 #ifdef _MSC_VER
1154 #pragma warning( suppress : 4244 )
1155             (*array)[n] = val->arr.iArray[n];
1156 #else
1157             (*array)[n] = val->arr.iArray[n];
1158 #endif
1159         }
1160     }
1161     memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1162     return true;
1163 }
1164
1165 bool OCRepPayloadSetStringArrayAsOwner(OCRepPayload* payload, const char* name,
1166         char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1167 {
1168     OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1169
1170     if (!val)
1171     {
1172         return false;
1173     }
1174
1175     val->arr.type = OCREP_PROP_STRING;
1176     memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1177     val->arr.strArray = array;
1178
1179     return true;
1180 }
1181 bool OCRepPayloadSetStringArray(OCRepPayload* payload, const char* name,
1182         const char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1183 {
1184     size_t dimTotal = calcDimTotal(dimensions);
1185     if (dimTotal == 0)
1186     {
1187         return false;
1188     }
1189
1190     char** newArray = (char**)OICMalloc(dimTotal * sizeof(char*));
1191
1192     if (!newArray)
1193     {
1194         return false;
1195     }
1196
1197     for(size_t i = 0; i < dimTotal; ++i)
1198     {
1199         newArray[i] = OICStrdup(array[i]);
1200     }
1201
1202     bool b = OCRepPayloadSetStringArrayAsOwner(payload, name, newArray, dimensions);
1203
1204     if (!b)
1205     {
1206         for(size_t i = 0; i < dimTotal; ++i)
1207         {
1208             OICFree(newArray[i]);
1209         }
1210         OICFree(newArray);
1211     }
1212     return b;
1213 }
1214
1215 bool OCRepPayloadGetStringArray(const OCRepPayload* payload, const char* name,
1216         char*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1217 {
1218     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1219
1220     if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_STRING
1221             || !val->arr.strArray)
1222     {
1223         return false;
1224     }
1225
1226     size_t dimTotal = calcDimTotal(val->arr.dimensions);
1227     if (dimTotal == 0)
1228     {
1229         return false;
1230     }
1231     *array = (char**)OICMalloc(dimTotal * sizeof(char*));
1232     if (!*array)
1233     {
1234         return false;
1235     }
1236
1237     memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1238
1239     for(size_t i = 0; i < dimTotal; ++i)
1240     {
1241         (*array)[i] = OICStrdup(val->arr.strArray[i]);
1242     }
1243
1244     return true;
1245
1246 }
1247
1248 bool OCRepPayloadSetBoolArrayAsOwner(OCRepPayload* payload, const char* name,
1249         bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1250 {
1251
1252     OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1253
1254     if (!val)
1255     {
1256         return false;
1257     }
1258
1259     val->arr.type = OCREP_PROP_BOOL;
1260     memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1261     val->arr.bArray = array;
1262
1263     return true;
1264 }
1265 bool OCRepPayloadSetBoolArray(OCRepPayload* payload, const char* name,
1266         const bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1267 {
1268     size_t dimTotal = calcDimTotal(dimensions);
1269     if (dimTotal == 0)
1270     {
1271         return false;
1272     }
1273
1274     bool* newArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
1275
1276     if (!newArray)
1277     {
1278         return false;
1279     }
1280
1281     memcpy(newArray, array, dimTotal * sizeof(bool));
1282
1283
1284     bool b = OCRepPayloadSetBoolArrayAsOwner(payload, name, newArray, dimensions);
1285     if (!b)
1286     {
1287         OICFree(newArray);
1288     }
1289     return b;
1290 }
1291
1292 bool OCRepPayloadGetBoolArray(const OCRepPayload* payload, const char* name,
1293         bool** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1294 {
1295     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1296
1297     if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_BOOL
1298             || !val->arr.bArray)
1299     {
1300         return false;
1301     }
1302
1303     size_t dimTotal = calcDimTotal(val->arr.dimensions);
1304     if (dimTotal == 0)
1305     {
1306         return false;
1307     }
1308     *array = (bool*)OICMalloc(dimTotal * sizeof(bool));
1309     if (!*array)
1310     {
1311         return false;
1312     }
1313
1314     memcpy(*array, val->arr.bArray, dimTotal * sizeof(bool));
1315     memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1316     return true;
1317 }
1318
1319 bool OCRepPayloadSetPropObjectArrayAsOwner(OCRepPayload* payload, const char* name,
1320         OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1321 {
1322     OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1323
1324     if (!val)
1325     {
1326         return false;
1327     }
1328
1329     val->arr.type = OCREP_PROP_OBJECT;
1330     memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1331     val->arr.objArray = array;
1332
1333     return true;
1334 }
1335
1336 bool OCRepPayloadSetPropObjectArray(OCRepPayload* payload, const char* name,
1337         const OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1338 {
1339     size_t dimTotal = calcDimTotal(dimensions);
1340     if (dimTotal == 0)
1341     {
1342         return false;
1343     }
1344
1345     OCRepPayload** newArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
1346
1347     if (!newArray)
1348     {
1349         return false;
1350     }
1351
1352     for(size_t i = 0; i < dimTotal; ++i)
1353     {
1354         newArray[i] = OCRepPayloadClone(array[i]);
1355     }
1356
1357     bool b = OCRepPayloadSetPropObjectArrayAsOwner(payload, name, newArray, dimensions);
1358
1359     if (!b)
1360     {
1361         for(size_t i = 0; i < dimTotal; ++i)
1362         {
1363            OCRepPayloadDestroy(newArray[i]);
1364         }
1365         OICFree(newArray);
1366     }
1367     return b;
1368 }
1369
1370 bool OCRepPayloadGetPropObjectArray(const OCRepPayload* payload, const char* name,
1371         OCRepPayload*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1372 {
1373     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1374
1375     if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_OBJECT
1376             || !val->arr.objArray)
1377     {
1378         return false;
1379     }
1380
1381     size_t dimTotal = calcDimTotal(val->arr.dimensions);
1382     if (dimTotal == 0)
1383     {
1384         return false;
1385     }
1386     *array = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
1387     if (!*array)
1388     {
1389         return false;
1390     }
1391
1392     memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1393
1394     for(size_t i = 0; i < dimTotal; ++i)
1395     {
1396         (*array)[i] = OCRepPayloadClone(val->arr.objArray[i]);
1397     }
1398
1399     return true;
1400 }
1401
1402 void OCFreeOCStringLL(OCStringLL* ll)
1403 {
1404     if (!ll)
1405     {
1406         return;
1407     }
1408
1409     OCFreeOCStringLL(ll->next);
1410     OICFree(ll->value);
1411     OICFree(ll);
1412 }
1413
1414 OCStringLL* CloneOCStringLL (OCStringLL* ll)
1415 {
1416     if (!ll)
1417     {
1418         return NULL;
1419     }
1420
1421     OCStringLL *sourceIter = ll;
1422
1423     OCStringLL *destIter = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
1424     if (!destIter)
1425     {
1426         return NULL;
1427     }
1428     destIter->value = OICStrdup (sourceIter->value);
1429
1430     OCStringLL *headOfClone = destIter;
1431
1432     sourceIter = sourceIter->next;
1433
1434     while (sourceIter)
1435     {
1436         destIter->next  = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
1437         if (!destIter->next)
1438         {
1439             OCFreeOCStringLL (headOfClone);
1440             return NULL;
1441         }
1442         destIter->next->value = OICStrdup (sourceIter->value);
1443
1444         destIter = destIter->next;
1445         sourceIter = sourceIter->next;
1446     }
1447     return headOfClone;
1448 }
1449
1450 OCStringLL* OCCreateOCStringLL(const char* text)
1451 {
1452     char *token = NULL;
1453     char *head = NULL;
1454     char *tail = NULL;
1455     char *backup  = NULL;
1456     OCStringLL* result = NULL;
1457     OCStringLL* iter = NULL;
1458     OCStringLL* prev = NULL;
1459     static const char delim[] = { CSV_SEPARATOR, '\0' };
1460
1461     VERIFY_PARAM_NON_NULL(TAG, text, "Invalid parameter");
1462     backup = OICStrdup(text);
1463     VERIFY_PARAM_NON_NULL(TAG, backup, "Failed allocating memory");
1464
1465     for (head = backup; ; head = NULL)
1466     {
1467         token = (char *) strtok_r(head, delim, &tail);
1468         if (!token)
1469         {
1470             break;
1471         }
1472         iter = (OCStringLL *)OICCalloc(1,sizeof(OCStringLL));
1473         VERIFY_PARAM_NON_NULL(TAG, iter, "Failed allocating memory");
1474         if (!result)
1475         {
1476             result = iter;
1477         }
1478         else
1479         {
1480             prev->next = iter;
1481         }
1482         iter->value = OICStrdup(token);
1483         VERIFY_PARAM_NON_NULL(TAG, iter->value, "Failed allocating memory");
1484         prev = iter;
1485         iter = iter->next;
1486     }
1487     OICFree(backup);
1488     return result;
1489
1490 exit:
1491     OICFree(backup);
1492     OCFreeOCStringLL(result);
1493     return NULL;
1494 }
1495
1496 char* OCCreateString(const OCStringLL* ll)
1497 {
1498     if (!ll)
1499     {
1500         return NULL;
1501     }
1502
1503     char *str = NULL;
1504     char *pos = NULL;
1505     size_t len = 0;
1506     size_t sublen = 0;
1507     int count = 0;
1508
1509     for (const OCStringLL *it = ll; it; it = it->next)
1510     {
1511         len += strlen(it->value) + 1;
1512     }
1513     len--; // remove trailing separator (just added above)
1514     str = (char*) OICMalloc(len + 1);
1515     if (!str)
1516     {
1517         return NULL;
1518     }
1519
1520     pos = str;
1521     const OCStringLL *it = ll;
1522     while (it)
1523     {
1524         sublen = strlen(it->value);
1525         count = snprintf(pos, len + 1, "%s", it->value);
1526         if ((size_t)count < sublen)
1527         {
1528             OICFree(str);
1529             return NULL;
1530         }
1531         len -= sublen;
1532         pos += count;
1533
1534         it = it->next;
1535         if (it)
1536         {
1537             *pos = CSV_SEPARATOR;
1538             len--;
1539             *(++pos) = '\0';
1540        }
1541     }
1542
1543     return str;
1544 }
1545
1546 bool OCByteStringCopy(OCByteString* dest, const OCByteString* source)
1547 {
1548     VERIFY_PARAM_NON_NULL(TAG, source, "Bad input");
1549
1550     if (!dest)
1551     {
1552         dest = (OCByteString *)OICMalloc(sizeof(OCByteString));
1553         VERIFY_PARAM_NON_NULL(TAG, dest, "Failed allocating memory");
1554     }
1555     if (dest->bytes)
1556     {
1557         OICFree(dest->bytes);
1558     }
1559     dest->bytes = (uint8_t*)OICMalloc(source->len * sizeof(uint8_t));
1560     VERIFY_PARAM_NON_NULL(TAG, dest->bytes, "Failed allocating memory");
1561     memcpy(dest->bytes, source->bytes, source->len * sizeof(uint8_t));
1562     dest->len = source->len;
1563     return true;
1564
1565 exit:
1566     if (dest)
1567     {
1568         dest->len = 0;
1569         OICFree(dest->bytes);
1570         dest->bytes = NULL;
1571     }
1572
1573     return false;
1574 }
1575
1576 OCRepPayload* OCRepPayloadClone (const OCRepPayload* payload)
1577 {
1578     if (!payload)
1579     {
1580         return NULL;
1581     }
1582
1583     OCRepPayload *clone = OCRepPayloadCreate();
1584
1585     if (!clone)
1586     {
1587         return NULL;
1588     }
1589
1590     clone->uri = OICStrdup (payload->uri);
1591     clone->types = CloneOCStringLL (payload->types);
1592     clone->interfaces = CloneOCStringLL (payload->interfaces);
1593     clone->values = OCRepPayloadValueClone (payload->values);
1594
1595     return clone;
1596 }
1597
1598 OCRepPayload* OCRepPayloadBatchClone(const OCRepPayload* repPayload)
1599 {
1600     OCRepPayload *newPayload = OCRepPayloadCreate();
1601     if (!newPayload)
1602     {
1603         return NULL;
1604     }
1605
1606     newPayload->uri = OICStrdup(repPayload->uri);
1607     OCRepPayload *clone = OCRepPayloadCreate();
1608     if (!clone)
1609     {
1610         OCPayloadDestroy((OCPayload *)newPayload);
1611         return NULL;
1612     }
1613
1614     clone->types  = CloneOCStringLL(repPayload->types);
1615     clone->interfaces  = CloneOCStringLL(repPayload->interfaces);
1616     clone->values = OCRepPayloadValueClone(repPayload->values);
1617     OCRepPayloadSetPropObjectAsOwner(newPayload, OC_RSRVD_REPRESENTATION, clone);
1618
1619     return newPayload;
1620 }
1621
1622 void OCRepPayloadDestroy(OCRepPayload* payload)
1623 {
1624     if (!payload)
1625     {
1626         return;
1627     }
1628
1629     OICFree(payload->uri);
1630     OCFreeOCStringLL(payload->types);
1631     OCFreeOCStringLL(payload->interfaces);
1632     OCFreeRepPayloadValue(payload->values);
1633     OCRepPayloadDestroy(payload->next);
1634     OICFree(payload);
1635 }
1636
1637 OCDiscoveryPayload* OCDiscoveryPayloadCreate()
1638 {
1639     OCDiscoveryPayload* payload = (OCDiscoveryPayload*)OICCalloc(1, sizeof(OCDiscoveryPayload));
1640
1641     if (!payload)
1642     {
1643         return NULL;
1644     }
1645
1646     payload->base.type = PAYLOAD_TYPE_DISCOVERY;
1647
1648     return payload;
1649 }
1650
1651 OCSecurityPayload* OCSecurityPayloadCreate(const uint8_t* securityData, size_t size)
1652 {
1653     OCSecurityPayload* payload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1654
1655     if (!payload)
1656     {
1657         return NULL;
1658     }
1659
1660     payload->base.type = PAYLOAD_TYPE_SECURITY;
1661     payload->securityData = (uint8_t *)OICCalloc(1, size);
1662     if (!payload->securityData)
1663     {
1664         OICFree(payload);
1665         return NULL;
1666     }
1667     memcpy(payload->securityData, (uint8_t *)securityData, size);
1668     payload->payloadSize = size;
1669
1670     return payload;
1671 }
1672
1673 void OCSecurityPayloadDestroy(OCSecurityPayload* payload)
1674 {
1675     if (!payload)
1676     {
1677         return;
1678     }
1679
1680     OICClearMemory(payload->securityData, payload->payloadSize);
1681     OICFree(payload->securityData);
1682     OICFree(payload);
1683 }
1684
1685 size_t OCDiscoveryPayloadGetResourceCount(OCDiscoveryPayload* payload)
1686 {
1687     size_t i = 0;
1688     OCResourcePayload* p = payload->resources;
1689     while(p)
1690     {
1691         ++i;
1692         p = p->next;
1693     }
1694     return i;
1695 }
1696
1697 OCResourcePayload* OCDiscoveryPayloadGetResource(OCDiscoveryPayload* payload, size_t index)
1698 {
1699     size_t i = 0;
1700     OCResourcePayload* p = payload->resources;
1701     while(p)
1702     {
1703         if (i == index)
1704         {
1705             return p;
1706         }
1707         ++i;
1708         p = p->next;
1709     }
1710     return NULL;
1711 }
1712
1713 size_t OCEndpointPayloadGetEndpointCount(OCEndpointPayload* payload)
1714 {
1715     size_t i = 0;
1716     OCEndpointPayload* ep = payload;
1717     while (ep)
1718     {
1719         ++i;
1720         ep = ep->next;
1721     }
1722     return i;
1723 }
1724
1725 OCEndpointPayload* OCEndpointPayloadGetEndpoint(OCEndpointPayload* payload, size_t index)
1726 {
1727     size_t i = 0;
1728     OCEndpointPayload* ep = payload;
1729     while (ep)
1730     {
1731         if (i == index)
1732         {
1733             return ep;
1734         }
1735         ++i;
1736         ep = ep->next;
1737     }
1738     return NULL;
1739 }
1740
1741 void OCResourcePayloadAddNewEndpoint(OCResourcePayload* payload, OCEndpointPayload* endpoint)
1742 {
1743     if (!payload)
1744     {
1745         return;
1746     }
1747
1748     if (!payload->eps)
1749     {
1750         payload->eps = endpoint;
1751     }
1752     else
1753     {
1754         OCEndpointPayload* ep = payload->eps;
1755         while (ep->next)
1756         {
1757             ep = ep->next;
1758         }
1759         ep->next = endpoint;
1760     }
1761 }
1762
1763 static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort,
1764                                          bool isVirtual, CAEndpoint_t *networkInfo,
1765                                          size_t infoSize, const OCDevAddr *devAddr
1766 #ifndef TCP_ADAPTER
1767                                                                                     )
1768 #else
1769                                          , uint16_t tcpPort)
1770 #endif
1771 {
1772     OCResourcePayload* pl = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1773     if (!pl)
1774     {
1775         return NULL;
1776     }
1777
1778     pl->uri = OICStrdup(res->uri);
1779
1780     if (!pl->uri)
1781     {
1782         OCDiscoveryResourceDestroy(pl);
1783         return NULL;
1784     }
1785
1786     // relation is always the default unless the resource is the well known URI
1787     if (0 == strcmp(res->uri, OC_RSRVD_WELL_KNOWN_URI))
1788     {
1789         pl->rel = OICStrdup("self");
1790
1791         if (!pl->rel)
1792         {
1793             OCDiscoveryResourceDestroy(pl);
1794             return NULL;
1795         }
1796     }
1797
1798     // types
1799     OCResourceType* typePtr = res->rsrcType;
1800
1801     if (typePtr != NULL)
1802     {
1803         pl->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1804         if (!pl->types)
1805         {
1806             OCDiscoveryResourceDestroy(pl);
1807             return NULL;
1808         }
1809         pl->types->value = OICStrdup(typePtr->resourcetypename);
1810         if (!pl->types->value)
1811         {
1812             OCDiscoveryResourceDestroy(pl);
1813             return NULL;
1814         }
1815
1816         OCStringLL* cur = pl->types;
1817         typePtr = typePtr->next;
1818         while(typePtr)
1819         {
1820             cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1821             if (!cur->next)
1822             {
1823                 OCDiscoveryResourceDestroy(pl);
1824                 return NULL;
1825             }
1826             cur->next->value = OICStrdup(typePtr->resourcetypename);
1827             if (!cur->next->value)
1828             {
1829                 OCDiscoveryResourceDestroy(pl);
1830                 return NULL;
1831             }
1832             cur = cur->next;
1833             typePtr = typePtr->next;
1834         }
1835     }
1836
1837     // interfaces
1838     OCResourceInterface* ifPtr = res->rsrcInterface;
1839     if (ifPtr != NULL)
1840     {
1841         pl->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1842         if (!pl->interfaces)
1843         {
1844             OCDiscoveryResourceDestroy(pl);
1845             return NULL;
1846         }
1847         pl->interfaces->value = OICStrdup(ifPtr->name);
1848         if (!pl->interfaces->value)
1849         {
1850             OCDiscoveryResourceDestroy(pl);
1851             return NULL;
1852         }
1853
1854         OCStringLL* cur = pl->interfaces;
1855         ifPtr = ifPtr->next;
1856         while(ifPtr && cur)
1857         {
1858             cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1859             if (!cur->next)
1860             {
1861                 OCDiscoveryResourceDestroy(pl);
1862                 return NULL;
1863             }
1864             cur->next->value = OICStrdup(ifPtr->name);
1865             if (!cur->next->value)
1866             {
1867                 OCDiscoveryResourceDestroy(pl);
1868                 return NULL;
1869             }
1870             cur = cur->next;
1871             ifPtr = ifPtr->next;
1872         }
1873     }
1874
1875     pl->bitmap = res->resourceProperties & (OC_OBSERVABLE | OC_DISCOVERABLE
1876 #ifdef MQ_PUBLISHER
1877                                             | OC_MQ_PUBLISHER
1878 #endif
1879                                             );
1880     pl->secure = (res->resourceProperties & OC_SECURE) != 0;
1881     pl->port = securePort;
1882 #ifdef TCP_ADAPTER
1883     pl->tcpPort = tcpPort;
1884 #endif
1885
1886     if (isVirtual || !networkInfo || infoSize == 0 || !devAddr)
1887     {
1888         pl->eps = NULL;
1889     }
1890     else
1891     {
1892         OCEndpointPayload *lastNode = pl->eps;
1893         if ((OC_ADAPTER_IP | OC_ADAPTER_TCP) & (devAddr->adapter))
1894         {
1895             for (size_t i = 0; i < infoSize; i++)
1896             {
1897                 CAEndpoint_t *info = networkInfo + i;
1898
1899                 if (info)
1900                 {
1901                     if (((CA_ADAPTER_IP | CA_ADAPTER_TCP) & info->adapter &&
1902                         info->ifindex == devAddr->ifindex) ||
1903                         info->adapter == CA_ADAPTER_RFCOMM_BTEDR)
1904                     {
1905                         OCTpsSchemeFlags matchedTps = OC_NO_TPS;
1906                         if (OC_STACK_OK != OCGetMatchedTpsFlags(info->adapter,
1907                                                                 info->flags,
1908                                                                 &matchedTps))
1909                         {
1910                             return NULL;
1911                         }
1912
1913                         if ((res->endpointType) & matchedTps)
1914                         {
1915                             // create payload
1916                             OCEndpointPayload* tmpNode = (OCEndpointPayload*)
1917                                                           OICCalloc(1, sizeof(OCEndpointPayload));
1918                             if (!tmpNode)
1919                             {
1920                                 return NULL;
1921                             }
1922
1923                             OCStackResult ret = OCConvertTpsToString(matchedTps, &(tmpNode->tps));
1924                             if (ret != OC_STACK_OK)
1925                             {
1926                                 OCDiscoveryEndpointDestroy(tmpNode);
1927                                 OCDiscoveryResourceDestroy(pl);
1928                                 return NULL;
1929                             }
1930
1931                             tmpNode->addr = (char*)OICCalloc(MAX_ADDR_STR_SIZE, sizeof(char));
1932                             if (!tmpNode->addr)
1933                             {
1934                                 OCDiscoveryEndpointDestroy(tmpNode);
1935                                 OCDiscoveryResourceDestroy(pl);
1936                                 return NULL;
1937                             }
1938
1939                             memcpy(tmpNode->addr, info->addr, sizeof(info->addr));
1940                             tmpNode->family = (OCTransportFlags)(info->flags);
1941                             tmpNode->port = info->port;
1942                             tmpNode->pri  = 1;
1943                             tmpNode->next = NULL;
1944
1945                             // store in list
1946                             if (!pl->eps)
1947                             {
1948                                 pl->eps = tmpNode;
1949                                 lastNode = tmpNode;
1950                             }
1951                             else
1952                             {
1953                                 lastNode->next = tmpNode;
1954                                 lastNode = tmpNode;
1955                             }
1956                         }
1957                     }
1958                 }
1959             }
1960         }
1961     }
1962
1963     return pl;
1964 }
1965
1966 #ifndef TCP_ADAPTER
1967 void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
1968                                    uint16_t securePort)
1969 {
1970     OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort, false, NULL, 0, NULL));
1971 }
1972 #else
1973 void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
1974                                    uint16_t securePort, uint16_t tcpPort)
1975 {
1976     OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort, false, NULL, 0, NULL, tcpPort));
1977 }
1978 #endif
1979
1980 #ifndef TCP_ADAPTER
1981 void OCDiscoveryPayloadAddResourceWithEps(OCDiscoveryPayload* payload, const OCResource* res,
1982                                           uint16_t securePort, bool isVirtual,
1983                                           void *networkInfo, size_t infoSize,
1984                                           const OCDevAddr *devAddr)
1985 {
1986     OCDiscoveryPayloadAddNewResource(payload,
1987                                      OCCopyResource(res, securePort, isVirtual,
1988                                                     (CAEndpoint_t *)networkInfo,
1989                                                     infoSize, devAddr));
1990 }
1991 #else
1992 void OCDiscoveryPayloadAddResourceWithEps(OCDiscoveryPayload* payload, const OCResource* res,
1993                                           uint16_t securePort, bool isVirtual,
1994                                           void *networkInfo, size_t infoSize,
1995                                           const OCDevAddr *devAddr, uint16_t tcpPort)
1996 {
1997     OCDiscoveryPayloadAddNewResource(payload,
1998                                      OCCopyResource(res, securePort, isVirtual,
1999                                                     (CAEndpoint_t *)networkInfo,
2000                                                     infoSize, devAddr, tcpPort));
2001 }
2002 #endif
2003
2004 bool OCResourcePayloadAddStringLL(OCStringLL **stringLL, const char *value)
2005 {
2006     char *dup = NULL;
2007     VERIFY_PARAM_NON_NULL(TAG, value, "Invalid Parameters");
2008     dup = OICStrdup(value);
2009     VERIFY_PARAM_NON_NULL(TAG, dup, "Failed copying string");
2010
2011     if (!*stringLL)
2012     {
2013         *stringLL = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
2014         VERIFY_PARAM_NON_NULL(TAG, *stringLL, "Failed allocating memory");
2015         (*stringLL)->value = dup;
2016         return true;
2017     }
2018     else
2019     {
2020         OCStringLL *temp = *stringLL;
2021         while(temp->next)
2022         {
2023             temp = temp->next;
2024         }
2025         temp->next = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
2026         VERIFY_PARAM_NON_NULL(TAG, temp->next, "Failed allocating memory");
2027         temp->next->value = dup;
2028         return true;
2029     }
2030 exit:
2031     OICFree(dup);
2032     return false;
2033 }
2034
2035 void OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload, OCResourcePayload* res)
2036 {
2037     if (!payload)
2038     {
2039         return;
2040     }
2041
2042     if (!payload->resources)
2043     {
2044         payload->resources = res;
2045     }
2046     else
2047     {
2048         OCResourcePayload* p = payload->resources;
2049         while(p->next)
2050         {
2051             p = p->next;
2052         }
2053         p->next = res;
2054     }
2055 }
2056
2057 void OCDiscoveryEndpointDestroy(OCEndpointPayload* payload)
2058 {
2059     if (!payload)
2060     {
2061         return;
2062     }
2063
2064     OICFree(payload->tps);
2065     OICFree(payload->addr);
2066     OCDiscoveryEndpointDestroy(payload->next);
2067     OICFree(payload);
2068 }
2069
2070 void OCDiscoveryResourceDestroy(OCResourcePayload* payload)
2071 {
2072     if (!payload)
2073     {
2074         return;
2075     }
2076
2077     OICFree(payload->uri);
2078     OICFree(payload->rel);
2079     OCFreeOCStringLL(payload->types);
2080     OCFreeOCStringLL(payload->interfaces);
2081     OCDiscoveryEndpointDestroy(payload->eps);
2082     OCDiscoveryResourceDestroy(payload->next);
2083     OICFree(payload);
2084 }
2085 void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload)
2086 {
2087     if (!payload)
2088     {
2089         return;
2090     }
2091     OICFree(payload->sid);
2092     OICFree(payload->baseURI);
2093     OCFreeOCStringLL(payload->type);
2094     OICFree(payload->name);
2095     OCFreeOCStringLL(payload->iface);
2096     OCDiscoveryResourceDestroy(payload->resources);
2097     OCDiscoveryPayloadDestroy(payload->next);
2098     OICFree(payload);
2099 }
2100
2101 OCPresencePayload* OCPresencePayloadCreate(uint32_t seqNum, uint32_t maxAge,
2102         OCPresenceTrigger trigger, const char* resourceType)
2103 {
2104     OCPresencePayload* payload = (OCPresencePayload*)OICCalloc(1, sizeof(OCPresencePayload));
2105     if (!payload)
2106     {
2107         return NULL;
2108     }
2109
2110     payload->base.type = PAYLOAD_TYPE_PRESENCE;
2111     payload->sequenceNumber = seqNum;
2112     payload->maxAge = maxAge;
2113     payload->trigger = trigger;
2114     payload->resourceType = OICStrdup(resourceType);
2115     return payload;
2116 }
2117
2118 void OCPresencePayloadDestroy(OCPresencePayload* payload)
2119 {
2120     if (!payload)
2121     {
2122         return;
2123     }
2124     OICFree(payload->resourceType);
2125     OICFree(payload);
2126 }