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