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