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