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