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