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