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