1 //******************************************************************
3 // Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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
11 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 // Required for strok_r
22 #define _POSIX_C_SOURCE 200112L
25 #include "ocpayload.h"
28 #include "oic_malloc.h"
29 #include "oic_string.h"
30 #include "ocstackinternal.h"
31 #include "ocresource.h"
33 #include "rdpayload.h"
35 #define TAG "OIC_RI_PAYLOAD"
36 #define CSV_SEPARATOR ','
38 static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val);
40 void OCPayloadDestroy(OCPayload* payload)
49 case PAYLOAD_TYPE_REPRESENTATION:
50 OCRepPayloadDestroy((OCRepPayload*)payload);
52 case PAYLOAD_TYPE_DISCOVERY:
53 OCDiscoveryPayloadDestroy((OCDiscoveryPayload*)payload);
55 case PAYLOAD_TYPE_DEVICE:
56 OCDevicePayloadDestroy((OCDevicePayload*)payload);
58 case PAYLOAD_TYPE_PLATFORM:
59 OCPlatformPayloadDestroy((OCPlatformPayload*)payload);
61 case PAYLOAD_TYPE_PRESENCE:
62 OCPresencePayloadDestroy((OCPresencePayload*)payload);
64 case PAYLOAD_TYPE_SECURITY:
65 OCSecurityPayloadDestroy((OCSecurityPayload*)payload);
68 OCRDPayloadDestroy((OCRDPayload*)payload);
71 OIC_LOG_V(ERROR, TAG, "Unsupported payload type in destroy: %d", payload->type);
76 OCRepPayload* OCRepPayloadCreate()
78 OCRepPayload* payload = (OCRepPayload*)OICCalloc(1, sizeof(OCRepPayload));
85 payload->base.type = PAYLOAD_TYPE_REPRESENTATION;
90 void OCRepPayloadAppend(OCRepPayload* parent, OCRepPayload* child)
99 parent = parent->next;
106 static OCRepPayloadValue* OCRepPayloadFindValue(const OCRepPayload* payload, const char* name)
108 if (!payload || !name)
113 OCRepPayloadValue* val = payload->values;
116 if (0 == strcmp(val->name, name))
126 static void OCCopyPropertyValueArray(OCRepPayloadValue* dest, OCRepPayloadValue* source)
128 if (!dest || !source)
133 size_t dimTotal = calcDimTotal(source->arr.dimensions);
134 switch(source->arr.type)
137 dest->arr.iArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
138 VERIFY_PARAM_NON_NULL(TAG, dest->arr.iArray, "Failed allocating memory");
139 memcpy(dest->arr.iArray, source->arr.iArray, dimTotal * sizeof(int64_t));
141 case OCREP_PROP_DOUBLE:
142 dest->arr.dArray = (double*)OICMalloc(dimTotal * sizeof(double));
143 VERIFY_PARAM_NON_NULL(TAG, dest->arr.dArray, "Failed allocating memory");
144 memcpy(dest->arr.dArray, source->arr.dArray, dimTotal * sizeof(double));
146 case OCREP_PROP_BOOL:
147 dest->arr.bArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
148 VERIFY_PARAM_NON_NULL(TAG, dest->arr.bArray, "Failed allocating memory");
149 memcpy(dest->arr.bArray, source->arr.bArray, dimTotal * sizeof(bool));
151 case OCREP_PROP_STRING:
152 dest->arr.strArray = (char**)OICMalloc(dimTotal * sizeof(char*));
153 VERIFY_PARAM_NON_NULL(TAG, dest->arr.strArray, "Failed allocating memory");
154 for(size_t i = 0; i < dimTotal; ++i)
156 dest->arr.strArray[i] = OICStrdup(source->arr.strArray[i]);
159 case OCREP_PROP_OBJECT:
160 dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
161 VERIFY_PARAM_NON_NULL(TAG, dest->arr.objArray, "Failed allocating memory");
162 for(size_t i = 0; i < dimTotal; ++i)
164 dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
167 case OCREP_PROP_ARRAY:
168 dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
169 VERIFY_PARAM_NON_NULL(TAG, dest->arr.objArray, "Failed allocating memory");
170 for(size_t i = 0; i < dimTotal; ++i)
172 dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
176 OIC_LOG(ERROR, TAG, "CopyPropertyValueArray invalid type");
183 static void OCCopyPropertyValue (OCRepPayloadValue *dest, OCRepPayloadValue *source)
185 if (!source || !dest)
192 case OCREP_PROP_STRING:
193 dest->str = OICStrdup(source->str);
195 case OCREP_PROP_OBJECT:
196 dest->obj = OCRepPayloadClone(source->obj);
198 case OCREP_PROP_ARRAY:
199 OCCopyPropertyValueArray(dest, source);
202 // Nothing to do for the trivially copyable types.
207 static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val)
214 if (val->type == OCREP_PROP_STRING)
218 else if (val->type == OCREP_PROP_BYTE_STRING)
220 OICFree(val->ocByteStr.bytes);
222 else if (val->type == OCREP_PROP_OBJECT)
224 OCRepPayloadDestroy(val->obj);
226 else if (val->type == OCREP_PROP_ARRAY)
228 size_t dimTotal = calcDimTotal(val->arr.dimensions);
229 switch(val->arr.type)
232 case OCREP_PROP_DOUBLE:
233 case OCREP_PROP_BOOL:
234 // Since this is a union, iArray will
235 // point to all of the above
236 OICFree(val->arr.iArray);
238 case OCREP_PROP_STRING:
239 for(size_t i = 0; i< dimTotal; ++i)
241 OICFree(val->arr.strArray[i]);
243 OICFree(val->arr.strArray);
245 case OCREP_PROP_BYTE_STRING:
246 for (size_t i = 0; i< dimTotal; ++i)
248 OICFree(val->arr.ocByteStrArray[i].bytes);
250 OICFree(val->arr.ocByteStrArray);
252 case OCREP_PROP_OBJECT: // This case is the temporary fix for string input
253 for(size_t i = 0; i< dimTotal; ++i)
255 OCRepPayloadDestroy(val->arr.objArray[i]);
257 OICFree(val->arr.objArray);
259 case OCREP_PROP_NULL:
260 case OCREP_PROP_ARRAY:
261 OIC_LOG_V(ERROR, TAG, "FreeRepPayloadValueContents: Illegal type\
262 inside an array: %d", val->arr.type);
268 static void OCFreeRepPayloadValue(OCRepPayloadValue* val)
276 OCFreeRepPayloadValueContents(val);
277 OCFreeRepPayloadValue(val->next);
280 static OCRepPayloadValue* OCRepPayloadValueClone (OCRepPayloadValue* source)
287 OCRepPayloadValue *sourceIter = source;
288 OCRepPayloadValue *destIter = (OCRepPayloadValue*) OICCalloc(1, sizeof(OCRepPayloadValue));
294 OCRepPayloadValue *headOfClone = destIter;
296 // Copy payload type and non pointer types in union.
297 *destIter = *sourceIter;
298 destIter->name = OICStrdup (sourceIter->name);
299 OCCopyPropertyValue (destIter, sourceIter);
301 sourceIter = sourceIter->next;
305 destIter->next = (OCRepPayloadValue*) OICCalloc(1, sizeof(OCRepPayloadValue));
308 OCFreeRepPayloadValue (headOfClone);
312 *(destIter->next) = *sourceIter;
313 destIter->next->name = OICStrdup (sourceIter->name);
314 OCCopyPropertyValue (destIter->next, sourceIter);
316 sourceIter = sourceIter->next;
317 destIter = destIter->next;
322 static OCRepPayloadValue* OCRepPayloadFindAndSetValue(OCRepPayload* payload, const char* name,
323 OCRepPayloadPropType type)
325 if (!payload || !name)
330 OCRepPayloadValue* val = payload->values;
333 payload->values = (OCRepPayloadValue*)OICCalloc(1, sizeof(OCRepPayloadValue));
334 if (!payload->values)
338 payload->values->name = OICStrdup(name);
339 if (!payload->values->name)
341 OICFree(payload->values);
342 payload->values = NULL;
345 payload->values->type =type;
346 return payload->values;
351 if (0 == strcmp(val->name, name))
353 OCFreeRepPayloadValueContents(val);
357 else if (val->next == NULL)
359 val->next = (OCRepPayloadValue*)OICCalloc(1, sizeof(OCRepPayloadValue));
364 val->next->name = OICStrdup(name);
365 if (!val->next->name)
371 val->next->type =type;
378 OIC_LOG(ERROR, TAG, "FindAndSetValue reached point after while loop, pointer corruption?");
382 bool OCRepPayloadAddResourceType(OCRepPayload* payload, const char* resourceType)
384 return OCRepPayloadAddResourceTypeAsOwner(payload, OICStrdup(resourceType));
387 bool OCRepPayloadAddResourceTypeAsOwner(OCRepPayload* payload, char* resourceType)
389 if (!payload || !resourceType)
396 OCStringLL* cur = payload->types;
401 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
408 cur->next->value = resourceType;
413 payload->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
418 payload->types->value = resourceType;
423 bool OCRepPayloadAddInterface(OCRepPayload* payload, const char* interface)
425 return OCRepPayloadAddInterfaceAsOwner(payload, OICStrdup(interface));
428 bool OCRepPayloadAddInterfaceAsOwner(OCRepPayload* payload, char* interface)
430 if (!payload || !interface)
435 if (payload->interfaces)
437 OCStringLL* cur = payload->interfaces;
442 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
448 cur->next->value = interface;
453 payload->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
454 if (!payload->interfaces)
458 payload->interfaces->value = interface;
463 bool OCRepPayloadSetUri(OCRepPayload* payload, const char* uri)
469 OICFree(payload->uri);
470 payload->uri = OICStrdup(uri);
471 return payload->uri != NULL;
474 bool OCRepPayloadIsNull(const OCRepPayload* payload, const char* name)
476 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
483 return val->type == OCREP_PROP_NULL;
486 static bool OCRepPayloadSetProp(OCRepPayload* payload, const char* name,
487 void* value, OCRepPayloadPropType type)
489 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, type);
497 val->i = *(int64_t*)value;
499 case OCREP_PROP_DOUBLE:
500 val->d = *(double*)value;
502 case OCREP_PROP_BOOL:
503 val->b = *(bool*)value;
505 case OCREP_PROP_OBJECT:
506 val->obj = (OCRepPayload*)value;
508 case OCREP_PROP_STRING:
509 val->str = (char*)value;
510 return val->str != NULL;
511 case OCREP_PROP_BYTE_STRING:
512 val->ocByteStr = *(OCByteString*)value;
514 case OCREP_PROP_NULL:
516 case OCREP_PROP_ARRAY:
524 bool OCRepPayloadSetNull(OCRepPayload* payload, const char* name)
526 return OCRepPayloadSetProp(payload, name, NULL, OCREP_PROP_NULL);
529 bool OCRepPayloadSetPropInt(OCRepPayload* payload,
530 const char* name, int64_t value)
532 return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_INT);
535 bool OCRepPayloadGetPropInt(const OCRepPayload* payload, const char* name, int64_t* value)
537 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
539 if (!val || val->type != OCREP_PROP_INT)
548 bool OCRepPayloadSetPropDouble(OCRepPayload* payload,
549 const char* name, double value)
551 return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_DOUBLE);
554 bool OCRepPayloadGetPropDouble(const OCRepPayload* payload, const char* name, double* value)
556 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
560 if (val->type == OCREP_PROP_DOUBLE)
565 else if (val->type == OCREP_PROP_INT)
575 bool OCRepPayloadSetPropString(OCRepPayload* payload, const char* name, const char* value)
577 char* temp = OICStrdup(value);
578 bool b = OCRepPayloadSetPropStringAsOwner(payload, name, temp);
587 bool OCRepPayloadSetPropStringAsOwner(OCRepPayload* payload, const char* name, char* value)
589 return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_STRING);
592 bool OCRepPayloadGetPropString(const OCRepPayload* payload, const char* name, char** value)
594 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
596 if (!val || val->type != OCREP_PROP_STRING)
601 *value = OICStrdup(val->str);
602 return *value != NULL;
605 bool OCRepPayloadSetPropByteString(OCRepPayload* payload, const char* name, OCByteString value)
607 if (!value.bytes || !value.len)
612 OCByteString ocByteStr = {
613 .bytes = (uint8_t*)OICMalloc(value.len * sizeof(uint8_t)),
616 if (!ocByteStr.bytes)
620 memcpy(ocByteStr.bytes, value.bytes, ocByteStr.len);
622 bool b = OCRepPayloadSetPropByteStringAsOwner(payload, name, &ocByteStr);
626 OICFree(ocByteStr.bytes);
631 bool OCRepPayloadSetPropByteStringAsOwner(OCRepPayload* payload, const char* name, OCByteString* value)
633 return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_BYTE_STRING);
636 bool OCRepPayloadGetPropByteString(const OCRepPayload* payload, const char* name, OCByteString* value)
638 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
640 if (!val || val->type != OCREP_PROP_BYTE_STRING)
650 value->bytes = (uint8_t*)OICMalloc(val->ocByteStr.len * sizeof(uint8_t));
655 value->len = val->ocByteStr.len;
656 memcpy(value->bytes, val->ocByteStr.bytes, value->len);
661 bool OCRepPayloadSetPropBool(OCRepPayload* payload,
662 const char* name, bool value)
664 return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_BOOL);
667 bool OCRepPayloadGetPropBool(const OCRepPayload* payload, const char* name, bool* value)
669 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
671 if (!val || val->type != OCREP_PROP_BOOL)
680 bool OCRepPayloadSetPropObject(OCRepPayload* payload, const char* name, const OCRepPayload* value)
682 OCRepPayload* temp = OCRepPayloadClone(value);
683 bool b = OCRepPayloadSetPropObjectAsOwner(payload, name, temp);
687 OCRepPayloadDestroy(temp);
692 bool OCRepPayloadSetPropObjectAsOwner(OCRepPayload* payload, const char* name, OCRepPayload* value)
694 return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_OBJECT);
697 bool OCRepPayloadGetPropObject(const OCRepPayload* payload, const char* name, OCRepPayload** value)
699 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
701 if (!val || val->type != OCREP_PROP_OBJECT)
706 *value = OCRepPayloadClone(val->obj);
707 return *value != NULL;
710 size_t calcDimTotal(const size_t dimensions[MAX_REP_ARRAY_DEPTH])
712 if (dimensions[0] == 0)
718 for(uint8_t i = 0; i < MAX_REP_ARRAY_DEPTH && dimensions[i] != 0; ++i)
720 total *= dimensions[i];
726 bool OCRepPayloadSetByteStringArrayAsOwner(OCRepPayload* payload, const char* name,
727 OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
729 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
736 val->arr.type = OCREP_PROP_BYTE_STRING;
737 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
738 val->arr.ocByteStrArray = array;
743 bool OCRepPayloadSetByteStringArray(OCRepPayload* payload, const char* name,
744 const OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
751 size_t dimTotal = calcDimTotal(dimensions);
757 OCByteString* newArray = (OCByteString*)OICCalloc(dimTotal, sizeof(OCByteString));
764 for (size_t i = 0; i < dimTotal; ++i)
766 newArray[i].bytes = (uint8_t*)OICMalloc(array[i].len * sizeof(uint8_t));
767 if (NULL == newArray[i].bytes)
769 for (size_t j = 0; j < i; ++j)
771 OICFree(newArray[j].bytes);
777 newArray[i].len = array[i].len;
778 memcpy(newArray[i].bytes, array[i].bytes, newArray[i].len);
781 bool b = OCRepPayloadSetByteStringArrayAsOwner(payload, name, newArray, dimensions);
784 for (size_t i = 0; i < dimTotal; ++i)
786 OICFree(newArray[i].bytes);
794 bool OCRepPayloadGetByteStringArray(const OCRepPayload* payload, const char* name,
795 OCByteString** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
797 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
799 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_BYTE_STRING
800 || !val->arr.ocByteStrArray)
805 size_t dimTotal = calcDimTotal(val->arr.dimensions);
811 *array = (OCByteString*)OICCalloc(dimTotal, sizeof(OCByteString));
817 for (size_t i = 0; i < dimTotal; ++i)
819 OCByteString* tmp = &(*array)[i];
820 tmp->bytes = (uint8_t*)OICMalloc(val->arr.ocByteStrArray[i].len * sizeof(uint8_t));
821 if (NULL == tmp->bytes)
823 for (size_t j = 0; j < i; ++j)
825 OCByteString* tmp = &(*array)[j];
833 tmp->len = val->arr.ocByteStrArray[i].len;
834 memcpy(tmp->bytes, val->arr.ocByteStrArray[i].bytes, tmp->len);
837 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
842 bool OCRepPayloadSetIntArrayAsOwner(OCRepPayload* payload, const char* name,
843 int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
845 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
852 val->arr.type = OCREP_PROP_INT;
853 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
854 val->arr.iArray = array;
859 bool OCRepPayloadSetIntArray(OCRepPayload* payload, const char* name,
860 const int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
862 size_t dimTotal = calcDimTotal(dimensions);
868 int64_t* newArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
875 memcpy(newArray, array, dimTotal * sizeof(int64_t));
878 bool b = OCRepPayloadSetIntArrayAsOwner(payload, name, newArray, dimensions);
886 bool OCRepPayloadGetIntArray(const OCRepPayload* payload, const char* name,
887 int64_t** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
889 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
891 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_INT
897 size_t dimTotal = calcDimTotal(val->arr.dimensions);
902 *array = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
908 memcpy(*array, val->arr.iArray, dimTotal * sizeof(int64_t));
909 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
913 bool OCRepPayloadSetDoubleArrayAsOwner(OCRepPayload* payload, const char* name,
914 double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
916 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
923 val->arr.type = OCREP_PROP_DOUBLE;
924 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
925 val->arr.dArray = array;
929 bool OCRepPayloadSetDoubleArray(OCRepPayload* payload, const char* name,
930 const double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
932 size_t dimTotal = calcDimTotal(dimensions);
938 double* newArray = (double*)OICMalloc(dimTotal * sizeof(double));
945 memcpy(newArray, array, dimTotal * sizeof(double));
947 bool b = OCRepPayloadSetDoubleArrayAsOwner(payload, name, newArray, dimensions);
955 bool OCRepPayloadGetDoubleArray(const OCRepPayload* payload, const char* name,
956 double** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
958 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
960 if (!val || val->type != OCREP_PROP_ARRAY ||
961 (val->arr.type != OCREP_PROP_DOUBLE && val->arr.type != OCREP_PROP_INT)
967 size_t dimTotal = calcDimTotal(val->arr.dimensions);
972 *array = (double*)OICMalloc(dimTotal * sizeof(double));
978 if (val->arr.type == OCREP_PROP_DOUBLE)
980 memcpy(*array, val->arr.dArray, dimTotal * sizeof(double));
984 /* need to convert from integer */
986 for ( ; n < dimTotal; ++n)
988 (*array)[n] = val->arr.iArray[n];
991 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
995 bool OCRepPayloadSetStringArrayAsOwner(OCRepPayload* payload, const char* name,
996 char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
998 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1005 val->arr.type = OCREP_PROP_STRING;
1006 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1007 val->arr.strArray = array;
1011 bool OCRepPayloadSetStringArray(OCRepPayload* payload, const char* name,
1012 const char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1014 size_t dimTotal = calcDimTotal(dimensions);
1020 char** newArray = (char**)OICMalloc(dimTotal * sizeof(char*));
1027 for(size_t i = 0; i < dimTotal; ++i)
1029 newArray[i] = OICStrdup(array[i]);
1032 bool b = OCRepPayloadSetStringArrayAsOwner(payload, name, newArray, dimensions);
1036 for(size_t i = 0; i < dimTotal; ++i)
1038 OICFree(newArray[i]);
1045 bool OCRepPayloadGetStringArray(const OCRepPayload* payload, const char* name,
1046 char*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1048 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1050 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_STRING
1051 || !val->arr.strArray)
1056 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1061 *array = (char**)OICMalloc(dimTotal * sizeof(char*));
1067 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1069 for(size_t i = 0; i < dimTotal; ++i)
1071 (*array)[i] = OICStrdup(val->arr.strArray[i]);
1078 bool OCRepPayloadSetBoolArrayAsOwner(OCRepPayload* payload, const char* name,
1079 bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1082 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1089 val->arr.type = OCREP_PROP_BOOL;
1090 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1091 val->arr.bArray = array;
1095 bool OCRepPayloadSetBoolArray(OCRepPayload* payload, const char* name,
1096 const bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1098 size_t dimTotal = calcDimTotal(dimensions);
1104 bool* newArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
1111 memcpy(newArray, array, dimTotal * sizeof(bool));
1114 bool b = OCRepPayloadSetBoolArrayAsOwner(payload, name, newArray, dimensions);
1122 bool OCRepPayloadGetBoolArray(const OCRepPayload* payload, const char* name,
1123 bool** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1125 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1127 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_BOOL
1128 || !val->arr.bArray)
1133 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1138 *array = (bool*)OICMalloc(dimTotal * sizeof(bool));
1144 memcpy(*array, val->arr.bArray, dimTotal * sizeof(bool));
1145 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1149 bool OCRepPayloadSetPropObjectArrayAsOwner(OCRepPayload* payload, const char* name,
1150 OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1152 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1159 val->arr.type = OCREP_PROP_OBJECT;
1160 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1161 val->arr.objArray = array;
1166 bool OCRepPayloadSetPropObjectArray(OCRepPayload* payload, const char* name,
1167 const OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1169 size_t dimTotal = calcDimTotal(dimensions);
1175 OCRepPayload** newArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
1182 for(size_t i = 0; i < dimTotal; ++i)
1184 newArray[i] = OCRepPayloadClone(array[i]);
1187 bool b = OCRepPayloadSetPropObjectArrayAsOwner(payload, name, newArray, dimensions);
1191 for(size_t i = 0; i < dimTotal; ++i)
1193 OCRepPayloadDestroy(newArray[i]);
1200 bool OCRepPayloadGetPropObjectArray(const OCRepPayload* payload, const char* name,
1201 OCRepPayload*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1203 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1205 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_OBJECT
1206 || !val->arr.objArray)
1211 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1216 *array = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
1222 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1224 for(size_t i = 0; i < dimTotal; ++i)
1226 (*array)[i] = OCRepPayloadClone(val->arr.objArray[i]);
1232 void OCFreeOCStringLL(OCStringLL* ll)
1239 OCFreeOCStringLL(ll->next);
1244 OCStringLL* CloneOCStringLL (OCStringLL* ll)
1251 OCStringLL *sourceIter = ll;
1253 OCStringLL *destIter = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
1258 destIter->value = OICStrdup (sourceIter->value);
1260 OCStringLL *headOfClone = destIter;
1262 sourceIter = sourceIter->next;
1266 destIter->next = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
1267 if (!destIter->next)
1269 OCFreeOCStringLL (headOfClone);
1272 destIter->next->value = OICStrdup (sourceIter->value);
1274 destIter = destIter->next;
1275 sourceIter = sourceIter->next;
1280 OCStringLL* OCCreateOCStringLL(const char* text)
1285 char *backup = NULL;
1286 OCStringLL* result = NULL;
1287 OCStringLL* iter = NULL;
1288 OCStringLL* prev = NULL;
1289 static const char delim[] = { CSV_SEPARATOR, '\0' };
1291 VERIFY_PARAM_NON_NULL(TAG, text, "Invalid parameter");
1292 backup = OICStrdup(text);
1293 VERIFY_PARAM_NON_NULL(TAG, backup, "Failed allocating memory");
1295 for (head = backup; ; head = NULL)
1297 token = (char *) strtok_r(head, delim, &tail);
1299 iter = (OCStringLL *)OICCalloc(1,sizeof(OCStringLL));
1300 VERIFY_PARAM_NON_NULL(TAG, iter, "Failed allocating memory");
1309 iter->value = OICStrdup(token);
1310 VERIFY_PARAM_NON_NULL(TAG, iter->value, "Failed allocating memory");
1319 OCFreeOCStringLL(result);
1323 char* OCCreateString(const OCStringLL* ll)
1331 if (!ll) return NULL;
1333 for (const OCStringLL *it = ll; it ; it = it->next )
1335 len += strlen(it->value) + 1;
1337 len--; // renove trailing separator (just added above)
1338 str = (char*) malloc(len + 1);
1343 const OCStringLL *it = ll;
1346 sublen = strlen(it->value);
1347 count = snprintf(pos, len + 1, "%s", it->value);
1359 *pos = CSV_SEPARATOR;
1368 OCRepPayload* OCRepPayloadClone (const OCRepPayload* payload)
1375 OCRepPayload *clone = OCRepPayloadCreate();
1382 clone->uri = OICStrdup (payload->uri);
1383 clone->types = CloneOCStringLL (payload->types);
1384 clone->interfaces = CloneOCStringLL (payload->interfaces);
1385 clone->values = OCRepPayloadValueClone (payload->values);
1391 void OCRepPayloadDestroy(OCRepPayload* payload)
1398 OICFree(payload->uri);
1399 OCFreeOCStringLL(payload->types);
1400 OCFreeOCStringLL(payload->interfaces);
1401 OCFreeRepPayloadValue(payload->values);
1402 OCRepPayloadDestroy(payload->next);
1406 OCDiscoveryPayload* OCDiscoveryPayloadCreate()
1408 OCDiscoveryPayload* payload = (OCDiscoveryPayload*)OICCalloc(1, sizeof(OCDiscoveryPayload));
1415 payload->base.type = PAYLOAD_TYPE_DISCOVERY;
1420 OCSecurityPayload* OCSecurityPayloadCreate(const uint8_t* securityData, size_t size)
1422 OCSecurityPayload* payload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1429 payload->base.type = PAYLOAD_TYPE_SECURITY;
1430 payload->securityData = (uint8_t *)OICCalloc(1, size);
1431 if (!payload->securityData)
1436 memcpy(payload->securityData, (uint8_t *)securityData, size);
1437 payload->payloadSize = size;
1442 void OCSecurityPayloadDestroy(OCSecurityPayload* payload)
1449 OICFree(payload->securityData);
1453 size_t OCDiscoveryPayloadGetResourceCount(OCDiscoveryPayload* payload)
1456 OCResourcePayload* p = payload->resources;
1465 OCResourcePayload* OCDiscoveryPayloadGetResource(OCDiscoveryPayload* payload, size_t index)
1468 OCResourcePayload* p = payload->resources;
1481 static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort,
1484 OCResourcePayload* pl = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1490 pl->uri = OICStrdup(res->uri);
1494 OCDiscoveryResourceDestroy(pl);
1499 OCResourceType* typePtr = res->rsrcType;
1501 if (typePtr != NULL)
1503 pl->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1506 OCDiscoveryResourceDestroy(pl);
1509 pl->types->value = OICStrdup(typePtr->resourcetypename);
1510 if (!pl->types->value)
1512 OCDiscoveryResourceDestroy(pl);
1516 OCStringLL* cur = pl->types;
1517 typePtr = typePtr->next;
1520 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1523 OCDiscoveryResourceDestroy(pl);
1526 cur->next->value = OICStrdup(typePtr->resourcetypename);
1527 if (!cur->next->value)
1529 OCDiscoveryResourceDestroy(pl);
1533 typePtr = typePtr->next;
1538 OCResourceInterface* ifPtr = res->rsrcInterface;
1541 pl->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1542 if (!pl->interfaces)
1544 OCDiscoveryResourceDestroy(pl);
1547 pl->interfaces->value = OICStrdup(ifPtr->name);
1548 if (!pl->interfaces->value)
1550 OCDiscoveryResourceDestroy(pl);
1554 OCStringLL* cur = pl->interfaces;
1555 ifPtr = ifPtr->next;
1558 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1561 OCDiscoveryResourceDestroy(pl);
1564 cur->next->value = OICStrdup(ifPtr->name);
1565 if (!cur->next->value)
1567 OCDiscoveryResourceDestroy(pl);
1571 ifPtr = ifPtr->next;
1575 pl->bitmap = res->resourceProperties & (OC_OBSERVABLE | OC_DISCOVERABLE);
1576 pl->secure = (res->resourceProperties & OC_SECURE) != 0;
1577 pl->port = securePort;
1579 pl->tcpPort = tcpPort;
1584 void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
1585 uint16_t securePort, uint16_t tcpPort)
1587 OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort, tcpPort));
1590 bool OCResourcePayloadAddStringLL(OCStringLL **stringLL, const char *value)
1592 char *dup = OICStrdup(value);
1593 VERIFY_PARAM_NON_NULL(TAG, dup, "Failed copying string");
1594 VERIFY_PARAM_NON_NULL(TAG, value, "Invalid Parameters");
1598 *stringLL = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
1599 VERIFY_PARAM_NON_NULL(TAG, *stringLL, "Failed allocating memory");
1600 (*stringLL)->value = dup;
1605 OCStringLL *temp = *stringLL;
1610 temp->next = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
1611 VERIFY_PARAM_NON_NULL(TAG, temp->next, "Failed allocating memory");
1612 temp->next->value = dup;
1620 void OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload, OCResourcePayload* res)
1627 if (!payload->resources)
1629 payload->resources = res;
1633 OCResourcePayload* p = payload->resources;
1642 void OCDiscoveryResourceDestroy(OCResourcePayload* payload)
1649 OICFree(payload->uri);
1650 OCFreeOCStringLL(payload->types);
1651 OCFreeOCStringLL(payload->interfaces);
1652 OCDiscoveryResourceDestroy(payload->next);
1656 void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload)
1662 OICFree(payload->sid);
1663 OICFree(payload->baseURI);
1664 OICFree(payload->uri);
1665 OCFreeOCStringLL(payload->type);
1666 OICFree(payload->name);
1667 OCFreeOCStringLL(payload->interface);
1668 OCDiscoveryResourceDestroy(payload->resources);
1672 OCDevicePayload* OCDevicePayloadCreate(const char* sid, const char* dname,
1673 const OCStringLL *types, const char* specVer, const char* dmVer)
1676 OCDevicePayload* payload = (OCDevicePayload*)OICCalloc(1, sizeof(OCDevicePayload));
1683 payload->base.type = PAYLOAD_TYPE_DEVICE;
1684 payload->sid = OICStrdup(sid);
1685 if (sid && !payload->sid)
1690 payload->deviceName = OICStrdup(dname);
1691 if (dname && !payload->deviceName)
1696 payload->specVersion = OICStrdup(specVer);
1697 if (specVer && !payload->specVersion)
1702 payload->dataModelVersions = OCCreateOCStringLL(dmVer);
1703 if (!payload->dataModelVersions || (dmVer && !payload->dataModelVersions->value))
1708 OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_DEFAULT);
1709 OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_READ);
1711 payload->types = CloneOCStringLL((OCStringLL *)types);
1712 if (types && !payload->types)
1720 OCDevicePayloadDestroy((OCDevicePayload*)payload);
1724 void OCDevicePayloadDestroy(OCDevicePayload* payload)
1731 OICFree(payload->sid);
1732 OICFree(payload->deviceName);
1733 OICFree(payload->specVersion);
1734 OCFreeOCStringLL(payload->dataModelVersions);
1735 OCFreeOCStringLL(payload->types);
1736 OCFreeOCStringLL(payload->interfaces);
1740 static void OCCopyPlatformInfo(const OCPlatformInfo* platformInfo, OCPlatformPayload* target)
1742 if (!platformInfo || !target)
1747 target->info.platformID = OICStrdup(platformInfo->platformID);
1748 target->info.manufacturerName = OICStrdup(platformInfo->manufacturerName);
1749 target->info.manufacturerUrl = OICStrdup(platformInfo->manufacturerUrl);
1750 target->info.modelNumber = OICStrdup(platformInfo->modelNumber);
1751 target->info.dateOfManufacture = OICStrdup(platformInfo->dateOfManufacture);
1752 target->info.platformVersion = OICStrdup(platformInfo->platformVersion);
1753 target->info.operatingSystemVersion = OICStrdup(platformInfo->operatingSystemVersion);
1754 target->info.hardwareVersion = OICStrdup(platformInfo->hardwareVersion);
1755 target->info.firmwareVersion = OICStrdup(platformInfo->firmwareVersion);
1756 target->info.supportUrl = OICStrdup(platformInfo->supportUrl);
1757 target->info.systemTime = OICStrdup(platformInfo->systemTime);
1760 OCPlatformPayload* OCPlatformPayloadCreateAsOwner(OCPlatformInfo* platformInfo)
1762 OCPlatformPayload* payload = (OCPlatformPayload*)OICCalloc(1, sizeof(OCPlatformPayload));
1768 payload->base.type = PAYLOAD_TYPE_PLATFORM;
1770 payload->info = *platformInfo;
1775 OCPlatformPayload* OCPlatformPayloadCreate(const OCPlatformInfo* platformInfo)
1777 OCPlatformPayload* payload = (OCPlatformPayload*)OICCalloc(1, sizeof(OCPlatformPayload));
1784 payload->base.type = PAYLOAD_TYPE_PLATFORM;
1786 OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_DEFAULT);
1787 OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_READ);
1789 OCResourcePayloadAddStringLL(&payload->rt, OC_RSRVD_RESOURCE_TYPE_PLATFORM);
1790 OCCopyPlatformInfo(platformInfo, payload);
1795 void OCPlatformInfoDestroy(OCPlatformInfo *info)
1797 OICFree(info->platformID);
1798 OICFree(info->manufacturerName);
1799 OICFree(info->manufacturerUrl);
1800 OICFree(info->modelNumber);
1801 OICFree(info->dateOfManufacture);
1802 OICFree(info->platformVersion);
1803 OICFree(info->operatingSystemVersion);
1804 OICFree(info->hardwareVersion);
1805 OICFree(info->firmwareVersion);
1806 OICFree(info->supportUrl);
1807 OICFree(info->systemTime);
1810 void OCPlatformPayloadDestroy(OCPlatformPayload* payload)
1816 OICFree(payload->uri);
1817 OCPlatformInfoDestroy(&payload->info);
1818 OCFreeOCStringLL(payload->rt);
1819 OCFreeOCStringLL(payload->interfaces);
1823 OCPresencePayload* OCPresencePayloadCreate(uint32_t seqNum, uint32_t maxAge,
1824 OCPresenceTrigger trigger, const char* resourceType)
1826 OCPresencePayload* payload = (OCPresencePayload*)OICCalloc(1, sizeof(OCPresencePayload));
1832 payload->base.type = PAYLOAD_TYPE_PRESENCE;
1833 payload->sequenceNumber = seqNum;
1834 payload->maxAge = maxAge;
1835 payload->trigger = trigger;
1836 payload->resourceType = OICStrdup(resourceType);
1840 void OCPresencePayloadDestroy(OCPresencePayload* payload)
1846 OICFree(payload->resourceType);