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_BYTE_STRING:
196 dest->ocByteStr.bytes = (uint8_t*)OICMalloc(source->ocByteStr.len * sizeof(uint8_t));
197 VERIFY_PARAM_NON_NULL(TAG, dest->ocByteStr.bytes, "Failed allocating memory");
198 dest->ocByteStr.len = source->ocByteStr.len;
199 memcpy(dest->ocByteStr.bytes, source->ocByteStr.bytes, dest->ocByteStr.len);
201 case OCREP_PROP_OBJECT:
202 dest->obj = OCRepPayloadClone(source->obj);
204 case OCREP_PROP_ARRAY:
205 OCCopyPropertyValueArray(dest, source);
208 // Nothing to do for the trivially copyable types.
215 static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val)
222 if (val->type == OCREP_PROP_STRING)
226 else if (val->type == OCREP_PROP_BYTE_STRING)
228 OICFree(val->ocByteStr.bytes);
230 else if (val->type == OCREP_PROP_OBJECT)
232 OCRepPayloadDestroy(val->obj);
234 else if (val->type == OCREP_PROP_ARRAY)
236 size_t dimTotal = calcDimTotal(val->arr.dimensions);
237 switch(val->arr.type)
240 case OCREP_PROP_DOUBLE:
241 case OCREP_PROP_BOOL:
242 // Since this is a union, iArray will
243 // point to all of the above
244 OICFree(val->arr.iArray);
246 case OCREP_PROP_STRING:
247 for(size_t i = 0; i< dimTotal; ++i)
249 OICFree(val->arr.strArray[i]);
251 OICFree(val->arr.strArray);
253 case OCREP_PROP_BYTE_STRING:
254 for (size_t i = 0; i< dimTotal; ++i)
256 OICFree(val->arr.ocByteStrArray[i].bytes);
258 OICFree(val->arr.ocByteStrArray);
260 case OCREP_PROP_OBJECT: // This case is the temporary fix for string input
261 for(size_t i = 0; i< dimTotal; ++i)
263 OCRepPayloadDestroy(val->arr.objArray[i]);
265 OICFree(val->arr.objArray);
267 case OCREP_PROP_NULL:
268 case OCREP_PROP_ARRAY:
269 OIC_LOG_V(ERROR, TAG, "FreeRepPayloadValueContents: Illegal type\
270 inside an array: %d", val->arr.type);
276 static void OCFreeRepPayloadValue(OCRepPayloadValue* val)
284 OCFreeRepPayloadValueContents(val);
285 OCFreeRepPayloadValue(val->next);
288 static OCRepPayloadValue* OCRepPayloadValueClone (OCRepPayloadValue* source)
295 OCRepPayloadValue *sourceIter = source;
296 OCRepPayloadValue *destIter = (OCRepPayloadValue*) OICCalloc(1, sizeof(OCRepPayloadValue));
302 OCRepPayloadValue *headOfClone = destIter;
304 // Copy payload type and non pointer types in union.
305 *destIter = *sourceIter;
306 destIter->name = OICStrdup (sourceIter->name);
307 OCCopyPropertyValue (destIter, sourceIter);
309 sourceIter = sourceIter->next;
313 destIter->next = (OCRepPayloadValue*) OICCalloc(1, sizeof(OCRepPayloadValue));
316 OCFreeRepPayloadValue (headOfClone);
320 *(destIter->next) = *sourceIter;
321 destIter->next->name = OICStrdup (sourceIter->name);
322 OCCopyPropertyValue (destIter->next, sourceIter);
324 sourceIter = sourceIter->next;
325 destIter = destIter->next;
330 static OCRepPayloadValue* OCRepPayloadFindAndSetValue(OCRepPayload* payload, const char* name,
331 OCRepPayloadPropType type)
333 if (!payload || !name)
338 OCRepPayloadValue* val = payload->values;
341 payload->values = (OCRepPayloadValue*)OICCalloc(1, sizeof(OCRepPayloadValue));
342 if (!payload->values)
346 payload->values->name = OICStrdup(name);
347 if (!payload->values->name)
349 OICFree(payload->values);
350 payload->values = NULL;
353 payload->values->type =type;
354 return payload->values;
359 if (0 == strcmp(val->name, name))
361 OCFreeRepPayloadValueContents(val);
365 else if (val->next == NULL)
367 val->next = (OCRepPayloadValue*)OICCalloc(1, sizeof(OCRepPayloadValue));
372 val->next->name = OICStrdup(name);
373 if (!val->next->name)
379 val->next->type =type;
386 OIC_LOG(ERROR, TAG, "FindAndSetValue reached point after while loop, pointer corruption?");
390 bool OCRepPayloadAddResourceType(OCRepPayload* payload, const char* resourceType)
392 return OCRepPayloadAddResourceTypeAsOwner(payload, OICStrdup(resourceType));
395 bool OCRepPayloadAddResourceTypeAsOwner(OCRepPayload* payload, char* resourceType)
397 if (!payload || !resourceType)
404 OCStringLL* cur = payload->types;
409 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
416 cur->next->value = resourceType;
421 payload->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
426 payload->types->value = resourceType;
431 bool OCRepPayloadAddInterface(OCRepPayload* payload, const char* iface)
433 return OCRepPayloadAddInterfaceAsOwner(payload, OICStrdup(iface));
436 bool OCRepPayloadAddInterfaceAsOwner(OCRepPayload* payload, char* iface)
438 if (!payload || !iface)
443 if (payload->interfaces)
445 OCStringLL* cur = payload->interfaces;
450 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
456 cur->next->value = iface;
461 payload->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
462 if (!payload->interfaces)
466 payload->interfaces->value = iface;
471 bool OCRepPayloadSetUri(OCRepPayload* payload, const char* uri)
477 OICFree(payload->uri);
478 payload->uri = OICStrdup(uri);
479 return payload->uri != NULL;
482 bool OCRepPayloadIsNull(const OCRepPayload* payload, const char* name)
484 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
491 return val->type == OCREP_PROP_NULL;
494 static bool OCRepPayloadSetProp(OCRepPayload* payload, const char* name,
495 void* value, OCRepPayloadPropType type)
497 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, type);
505 val->i = *(int64_t*)value;
507 case OCREP_PROP_DOUBLE:
508 val->d = *(double*)value;
510 case OCREP_PROP_BOOL:
511 val->b = *(bool*)value;
513 case OCREP_PROP_OBJECT:
514 val->obj = (OCRepPayload*)value;
516 case OCREP_PROP_STRING:
517 val->str = (char*)value;
518 return val->str != NULL;
519 case OCREP_PROP_BYTE_STRING:
520 val->ocByteStr = *(OCByteString*)value;
522 case OCREP_PROP_NULL:
524 case OCREP_PROP_ARRAY:
532 bool OCRepPayloadSetNull(OCRepPayload* payload, const char* name)
534 return OCRepPayloadSetProp(payload, name, NULL, OCREP_PROP_NULL);
537 bool OCRepPayloadSetPropInt(OCRepPayload* payload,
538 const char* name, int64_t value)
540 return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_INT);
543 bool OCRepPayloadGetPropInt(const OCRepPayload* payload, const char* name, int64_t* value)
545 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
547 if (!val || val->type != OCREP_PROP_INT)
556 bool OCRepPayloadSetPropDouble(OCRepPayload* payload,
557 const char* name, double value)
559 return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_DOUBLE);
562 bool OCRepPayloadGetPropDouble(const OCRepPayload* payload, const char* name, double* value)
564 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
568 if (val->type == OCREP_PROP_DOUBLE)
573 else if (val->type == OCREP_PROP_INT)
583 bool OCRepPayloadSetPropString(OCRepPayload* payload, const char* name, const char* value)
585 char* temp = OICStrdup(value);
586 bool b = OCRepPayloadSetPropStringAsOwner(payload, name, temp);
595 bool OCRepPayloadSetPropStringAsOwner(OCRepPayload* payload, const char* name, char* value)
597 return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_STRING);
600 bool OCRepPayloadGetPropString(const OCRepPayload* payload, const char* name, char** value)
602 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
604 if (!val || val->type != OCREP_PROP_STRING)
609 *value = OICStrdup(val->str);
610 return *value != NULL;
613 bool OCRepPayloadSetPropByteString(OCRepPayload* payload, const char* name, OCByteString value)
615 if (!value.bytes || !value.len)
620 OCByteString ocByteStr = {
621 .bytes = (uint8_t*)OICMalloc(value.len * sizeof(uint8_t)),
624 if (!ocByteStr.bytes)
628 memcpy(ocByteStr.bytes, value.bytes, ocByteStr.len);
630 bool b = OCRepPayloadSetPropByteStringAsOwner(payload, name, &ocByteStr);
634 OICFree(ocByteStr.bytes);
639 bool OCRepPayloadSetPropByteStringAsOwner(OCRepPayload* payload, const char* name, OCByteString* value)
641 return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_BYTE_STRING);
644 bool OCRepPayloadGetPropByteString(const OCRepPayload* payload, const char* name, OCByteString* value)
646 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
648 if (!val || val->type != OCREP_PROP_BYTE_STRING)
658 value->bytes = (uint8_t*)OICMalloc(val->ocByteStr.len * sizeof(uint8_t));
663 value->len = val->ocByteStr.len;
664 memcpy(value->bytes, val->ocByteStr.bytes, value->len);
669 bool OCRepPayloadSetPropBool(OCRepPayload* payload,
670 const char* name, bool value)
672 return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_BOOL);
675 bool OCRepPayloadGetPropBool(const OCRepPayload* payload, const char* name, bool* value)
677 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
679 if (!val || val->type != OCREP_PROP_BOOL)
688 bool OCRepPayloadSetPropObject(OCRepPayload* payload, const char* name, const OCRepPayload* value)
690 OCRepPayload* temp = OCRepPayloadClone(value);
691 bool b = OCRepPayloadSetPropObjectAsOwner(payload, name, temp);
695 OCRepPayloadDestroy(temp);
700 bool OCRepPayloadSetPropObjectAsOwner(OCRepPayload* payload, const char* name, OCRepPayload* value)
702 return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_OBJECT);
705 bool OCRepPayloadGetPropObject(const OCRepPayload* payload, const char* name, OCRepPayload** value)
707 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
709 if (!val || val->type != OCREP_PROP_OBJECT)
714 *value = OCRepPayloadClone(val->obj);
715 return *value != NULL;
718 size_t calcDimTotal(const size_t dimensions[MAX_REP_ARRAY_DEPTH])
720 if (dimensions[0] == 0)
726 for(uint8_t i = 0; i < MAX_REP_ARRAY_DEPTH && dimensions[i] != 0; ++i)
728 total *= dimensions[i];
734 bool OCRepPayloadSetByteStringArrayAsOwner(OCRepPayload* payload, const char* name,
735 OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
737 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
744 val->arr.type = OCREP_PROP_BYTE_STRING;
745 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
746 val->arr.ocByteStrArray = array;
751 bool OCRepPayloadSetByteStringArray(OCRepPayload* payload, const char* name,
752 const OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
759 size_t dimTotal = calcDimTotal(dimensions);
765 OCByteString* newArray = (OCByteString*)OICCalloc(dimTotal, sizeof(OCByteString));
772 for (size_t i = 0; i < dimTotal; ++i)
774 newArray[i].bytes = (uint8_t*)OICMalloc(array[i].len * sizeof(uint8_t));
775 if (NULL == newArray[i].bytes)
777 for (size_t j = 0; j < i; ++j)
779 OICFree(newArray[j].bytes);
785 newArray[i].len = array[i].len;
786 memcpy(newArray[i].bytes, array[i].bytes, newArray[i].len);
789 bool b = OCRepPayloadSetByteStringArrayAsOwner(payload, name, newArray, dimensions);
792 for (size_t i = 0; i < dimTotal; ++i)
794 OICFree(newArray[i].bytes);
802 bool OCRepPayloadGetByteStringArray(const OCRepPayload* payload, const char* name,
803 OCByteString** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
805 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
807 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_BYTE_STRING
808 || !val->arr.ocByteStrArray)
813 size_t dimTotal = calcDimTotal(val->arr.dimensions);
819 *array = (OCByteString*)OICCalloc(dimTotal, sizeof(OCByteString));
825 for (size_t i = 0; i < dimTotal; ++i)
827 OCByteString* tmp = &(*array)[i];
828 tmp->bytes = (uint8_t*)OICMalloc(val->arr.ocByteStrArray[i].len * sizeof(uint8_t));
829 if (NULL == tmp->bytes)
831 for (size_t j = 0; j < i; ++j)
833 OCByteString* tmp = &(*array)[j];
841 tmp->len = val->arr.ocByteStrArray[i].len;
842 memcpy(tmp->bytes, val->arr.ocByteStrArray[i].bytes, tmp->len);
845 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
850 bool OCRepPayloadSetIntArrayAsOwner(OCRepPayload* payload, const char* name,
851 int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
853 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
860 val->arr.type = OCREP_PROP_INT;
861 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
862 val->arr.iArray = array;
867 bool OCRepPayloadSetIntArray(OCRepPayload* payload, const char* name,
868 const int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
870 size_t dimTotal = calcDimTotal(dimensions);
876 int64_t* newArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
883 memcpy(newArray, array, dimTotal * sizeof(int64_t));
886 bool b = OCRepPayloadSetIntArrayAsOwner(payload, name, newArray, dimensions);
894 bool OCRepPayloadGetIntArray(const OCRepPayload* payload, const char* name,
895 int64_t** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
897 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
899 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_INT
905 size_t dimTotal = calcDimTotal(val->arr.dimensions);
910 *array = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
916 memcpy(*array, val->arr.iArray, dimTotal * sizeof(int64_t));
917 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
921 bool OCRepPayloadSetDoubleArrayAsOwner(OCRepPayload* payload, const char* name,
922 double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
924 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
931 val->arr.type = OCREP_PROP_DOUBLE;
932 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
933 val->arr.dArray = array;
937 bool OCRepPayloadSetDoubleArray(OCRepPayload* payload, const char* name,
938 const double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
940 size_t dimTotal = calcDimTotal(dimensions);
946 double* newArray = (double*)OICMalloc(dimTotal * sizeof(double));
953 memcpy(newArray, array, dimTotal * sizeof(double));
955 bool b = OCRepPayloadSetDoubleArrayAsOwner(payload, name, newArray, dimensions);
963 bool OCRepPayloadGetDoubleArray(const OCRepPayload* payload, const char* name,
964 double** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
966 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
968 if (!val || val->type != OCREP_PROP_ARRAY ||
969 (val->arr.type != OCREP_PROP_DOUBLE && val->arr.type != OCREP_PROP_INT)
975 size_t dimTotal = calcDimTotal(val->arr.dimensions);
980 *array = (double*)OICMalloc(dimTotal * sizeof(double));
986 if (val->arr.type == OCREP_PROP_DOUBLE)
988 memcpy(*array, val->arr.dArray, dimTotal * sizeof(double));
992 /* need to convert from integer */
994 for ( ; n < dimTotal; ++n)
996 (*array)[n] = val->arr.iArray[n];
999 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1003 bool OCRepPayloadSetStringArrayAsOwner(OCRepPayload* payload, const char* name,
1004 char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1006 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1013 val->arr.type = OCREP_PROP_STRING;
1014 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1015 val->arr.strArray = array;
1019 bool OCRepPayloadSetStringArray(OCRepPayload* payload, const char* name,
1020 const char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1022 size_t dimTotal = calcDimTotal(dimensions);
1028 char** newArray = (char**)OICMalloc(dimTotal * sizeof(char*));
1035 for(size_t i = 0; i < dimTotal; ++i)
1037 newArray[i] = OICStrdup(array[i]);
1040 bool b = OCRepPayloadSetStringArrayAsOwner(payload, name, newArray, dimensions);
1044 for(size_t i = 0; i < dimTotal; ++i)
1046 OICFree(newArray[i]);
1053 bool OCRepPayloadGetStringArray(const OCRepPayload* payload, const char* name,
1054 char*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1056 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1058 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_STRING
1059 || !val->arr.strArray)
1064 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1069 *array = (char**)OICMalloc(dimTotal * sizeof(char*));
1075 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1077 for(size_t i = 0; i < dimTotal; ++i)
1079 (*array)[i] = OICStrdup(val->arr.strArray[i]);
1086 bool OCRepPayloadSetBoolArrayAsOwner(OCRepPayload* payload, const char* name,
1087 bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1090 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1097 val->arr.type = OCREP_PROP_BOOL;
1098 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1099 val->arr.bArray = array;
1103 bool OCRepPayloadSetBoolArray(OCRepPayload* payload, const char* name,
1104 const bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1106 size_t dimTotal = calcDimTotal(dimensions);
1112 bool* newArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
1119 memcpy(newArray, array, dimTotal * sizeof(bool));
1122 bool b = OCRepPayloadSetBoolArrayAsOwner(payload, name, newArray, dimensions);
1130 bool OCRepPayloadGetBoolArray(const OCRepPayload* payload, const char* name,
1131 bool** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1133 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1135 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_BOOL
1136 || !val->arr.bArray)
1141 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1146 *array = (bool*)OICMalloc(dimTotal * sizeof(bool));
1152 memcpy(*array, val->arr.bArray, dimTotal * sizeof(bool));
1153 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1157 bool OCRepPayloadSetPropObjectArrayAsOwner(OCRepPayload* payload, const char* name,
1158 OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1160 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1167 val->arr.type = OCREP_PROP_OBJECT;
1168 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1169 val->arr.objArray = array;
1174 bool OCRepPayloadSetPropObjectArray(OCRepPayload* payload, const char* name,
1175 const OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1177 size_t dimTotal = calcDimTotal(dimensions);
1183 OCRepPayload** newArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
1190 for(size_t i = 0; i < dimTotal; ++i)
1192 newArray[i] = OCRepPayloadClone(array[i]);
1195 bool b = OCRepPayloadSetPropObjectArrayAsOwner(payload, name, newArray, dimensions);
1199 for(size_t i = 0; i < dimTotal; ++i)
1201 OCRepPayloadDestroy(newArray[i]);
1208 bool OCRepPayloadGetPropObjectArray(const OCRepPayload* payload, const char* name,
1209 OCRepPayload*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1211 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1213 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_OBJECT
1214 || !val->arr.objArray)
1219 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1224 *array = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
1230 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1232 for(size_t i = 0; i < dimTotal; ++i)
1234 (*array)[i] = OCRepPayloadClone(val->arr.objArray[i]);
1240 void OCFreeOCStringLL(OCStringLL* ll)
1247 OCFreeOCStringLL(ll->next);
1252 OCStringLL* CloneOCStringLL (OCStringLL* ll)
1259 OCStringLL *sourceIter = ll;
1261 OCStringLL *destIter = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
1266 destIter->value = OICStrdup (sourceIter->value);
1268 OCStringLL *headOfClone = destIter;
1270 sourceIter = sourceIter->next;
1274 destIter->next = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
1275 if (!destIter->next)
1277 OCFreeOCStringLL (headOfClone);
1280 destIter->next->value = OICStrdup (sourceIter->value);
1282 destIter = destIter->next;
1283 sourceIter = sourceIter->next;
1288 OCStringLL* OCCreateOCStringLL(const char* text)
1293 char *backup = NULL;
1294 OCStringLL* result = NULL;
1295 OCStringLL* iter = NULL;
1296 OCStringLL* prev = NULL;
1297 static const char delim[] = { CSV_SEPARATOR, '\0' };
1299 VERIFY_PARAM_NON_NULL(TAG, text, "Invalid parameter");
1300 backup = OICStrdup(text);
1301 VERIFY_PARAM_NON_NULL(TAG, backup, "Failed allocating memory");
1303 for (head = backup; ; head = NULL)
1305 token = (char *) strtok_r(head, delim, &tail);
1307 iter = (OCStringLL *)OICCalloc(1,sizeof(OCStringLL));
1308 VERIFY_PARAM_NON_NULL(TAG, iter, "Failed allocating memory");
1317 iter->value = OICStrdup(token);
1318 VERIFY_PARAM_NON_NULL(TAG, iter->value, "Failed allocating memory");
1327 OCFreeOCStringLL(result);
1331 char* OCCreateString(const OCStringLL* ll)
1339 if (!ll) return NULL;
1341 for (const OCStringLL *it = ll; it ; it = it->next )
1343 len += strlen(it->value) + 1;
1345 len--; // renove trailing separator (just added above)
1346 str = (char*) malloc(len + 1);
1351 const OCStringLL *it = ll;
1354 sublen = strlen(it->value);
1355 count = snprintf(pos, len + 1, "%s", it->value);
1367 *pos = CSV_SEPARATOR;
1376 OCRepPayload* OCRepPayloadClone (const OCRepPayload* payload)
1383 OCRepPayload *clone = OCRepPayloadCreate();
1390 clone->uri = OICStrdup (payload->uri);
1391 clone->types = CloneOCStringLL (payload->types);
1392 clone->interfaces = CloneOCStringLL (payload->interfaces);
1393 clone->values = OCRepPayloadValueClone (payload->values);
1399 void OCRepPayloadDestroy(OCRepPayload* payload)
1406 OICFree(payload->uri);
1407 OCFreeOCStringLL(payload->types);
1408 OCFreeOCStringLL(payload->interfaces);
1409 OCFreeRepPayloadValue(payload->values);
1410 OCRepPayloadDestroy(payload->next);
1414 OCDiscoveryPayload* OCDiscoveryPayloadCreate()
1416 OCDiscoveryPayload* payload = (OCDiscoveryPayload*)OICCalloc(1, sizeof(OCDiscoveryPayload));
1423 payload->base.type = PAYLOAD_TYPE_DISCOVERY;
1428 OCSecurityPayload* OCSecurityPayloadCreate(const uint8_t* securityData, size_t size)
1430 OCSecurityPayload* payload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1437 payload->base.type = PAYLOAD_TYPE_SECURITY;
1438 payload->securityData = (uint8_t *)OICCalloc(1, size);
1439 if (!payload->securityData)
1444 memcpy(payload->securityData, (uint8_t *)securityData, size);
1445 payload->payloadSize = size;
1450 void OCSecurityPayloadDestroy(OCSecurityPayload* payload)
1457 OICFree(payload->securityData);
1461 size_t OCDiscoveryPayloadGetResourceCount(OCDiscoveryPayload* payload)
1464 OCResourcePayload* p = payload->resources;
1473 OCResourcePayload* OCDiscoveryPayloadGetResource(OCDiscoveryPayload* payload, size_t index)
1476 OCResourcePayload* p = payload->resources;
1490 static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort)
1492 static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort,
1496 OCResourcePayload* pl = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1502 pl->uri = OICStrdup(res->uri);
1506 OCDiscoveryResourceDestroy(pl);
1511 OCResourceType* typePtr = res->rsrcType;
1513 if (typePtr != NULL)
1515 pl->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1518 OCDiscoveryResourceDestroy(pl);
1521 pl->types->value = OICStrdup(typePtr->resourcetypename);
1522 if (!pl->types->value)
1524 OCDiscoveryResourceDestroy(pl);
1528 OCStringLL* cur = pl->types;
1529 typePtr = typePtr->next;
1532 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1535 OCDiscoveryResourceDestroy(pl);
1538 cur->next->value = OICStrdup(typePtr->resourcetypename);
1539 if (!cur->next->value)
1541 OCDiscoveryResourceDestroy(pl);
1545 typePtr = typePtr->next;
1550 OCResourceInterface* ifPtr = res->rsrcInterface;
1553 pl->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1554 if (!pl->interfaces)
1556 OCDiscoveryResourceDestroy(pl);
1559 pl->interfaces->value = OICStrdup(ifPtr->name);
1560 if (!pl->interfaces->value)
1562 OCDiscoveryResourceDestroy(pl);
1566 OCStringLL* cur = pl->interfaces;
1567 ifPtr = ifPtr->next;
1570 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1573 OCDiscoveryResourceDestroy(pl);
1576 cur->next->value = OICStrdup(ifPtr->name);
1577 if (!cur->next->value)
1579 OCDiscoveryResourceDestroy(pl);
1583 ifPtr = ifPtr->next;
1587 pl->bitmap = res->resourceProperties & (OC_OBSERVABLE | OC_DISCOVERABLE);
1588 pl->secure = (res->resourceProperties & OC_SECURE) != 0;
1589 pl->port = securePort;
1591 pl->tcpPort = tcpPort;
1597 void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
1598 uint16_t securePort)
1600 OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort));
1603 void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
1604 uint16_t securePort, uint16_t tcpPort)
1606 OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort, tcpPort));
1610 bool OCResourcePayloadAddStringLL(OCStringLL **stringLL, const char *value)
1612 char *dup = OICStrdup(value);
1613 VERIFY_PARAM_NON_NULL(TAG, dup, "Failed copying string");
1614 VERIFY_PARAM_NON_NULL(TAG, value, "Invalid Parameters");
1618 *stringLL = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
1619 VERIFY_PARAM_NON_NULL(TAG, *stringLL, "Failed allocating memory");
1620 (*stringLL)->value = dup;
1625 OCStringLL *temp = *stringLL;
1630 temp->next = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
1631 VERIFY_PARAM_NON_NULL(TAG, temp->next, "Failed allocating memory");
1632 temp->next->value = dup;
1640 void OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload, OCResourcePayload* res)
1647 if (!payload->resources)
1649 payload->resources = res;
1653 OCResourcePayload* p = payload->resources;
1662 void OCDiscoveryResourceDestroy(OCResourcePayload* payload)
1669 OICFree(payload->uri);
1670 OCFreeOCStringLL(payload->types);
1671 OCFreeOCStringLL(payload->interfaces);
1672 OCDiscoveryResourceDestroy(payload->next);
1676 void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload)
1682 OICFree(payload->sid);
1683 OICFree(payload->baseURI);
1684 OICFree(payload->uri);
1685 OCFreeOCStringLL(payload->type);
1686 OICFree(payload->name);
1687 OCFreeOCStringLL(payload->iface);
1688 OCDiscoveryResourceDestroy(payload->resources);
1689 OCDiscoveryPayloadDestroy(payload->next);
1693 OCDevicePayload* OCDevicePayloadCreate(const char* sid, const char* dname,
1694 const OCStringLL *types, const char* specVer, const char* dmVer)
1697 OCDevicePayload* payload = (OCDevicePayload*)OICCalloc(1, sizeof(OCDevicePayload));
1704 payload->base.type = PAYLOAD_TYPE_DEVICE;
1705 payload->sid = OICStrdup(sid);
1706 if (sid && !payload->sid)
1711 payload->deviceName = OICStrdup(dname);
1712 if (dname && !payload->deviceName)
1717 payload->specVersion = OICStrdup(specVer);
1718 if (specVer && !payload->specVersion)
1723 payload->dataModelVersions = OCCreateOCStringLL(dmVer);
1724 if (!payload->dataModelVersions || (dmVer && !payload->dataModelVersions->value))
1729 OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_DEFAULT);
1730 OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_READ);
1732 payload->types = CloneOCStringLL((OCStringLL *)types);
1733 if (types && !payload->types)
1741 OCDevicePayloadDestroy((OCDevicePayload*)payload);
1745 void OCDevicePayloadDestroy(OCDevicePayload* payload)
1752 OICFree(payload->sid);
1753 OICFree(payload->deviceName);
1754 OICFree(payload->specVersion);
1755 OCFreeOCStringLL(payload->dataModelVersions);
1756 OCFreeOCStringLL(payload->types);
1757 OCFreeOCStringLL(payload->interfaces);
1761 static void OCCopyPlatformInfo(const OCPlatformInfo* platformInfo, OCPlatformPayload* target)
1763 if (!platformInfo || !target)
1768 target->info.platformID = OICStrdup(platformInfo->platformID);
1769 target->info.manufacturerName = OICStrdup(platformInfo->manufacturerName);
1770 target->info.manufacturerUrl = OICStrdup(platformInfo->manufacturerUrl);
1771 target->info.modelNumber = OICStrdup(platformInfo->modelNumber);
1772 target->info.dateOfManufacture = OICStrdup(platformInfo->dateOfManufacture);
1773 target->info.platformVersion = OICStrdup(platformInfo->platformVersion);
1774 target->info.operatingSystemVersion = OICStrdup(platformInfo->operatingSystemVersion);
1775 target->info.hardwareVersion = OICStrdup(platformInfo->hardwareVersion);
1776 target->info.firmwareVersion = OICStrdup(platformInfo->firmwareVersion);
1777 target->info.supportUrl = OICStrdup(platformInfo->supportUrl);
1778 target->info.systemTime = OICStrdup(platformInfo->systemTime);
1781 OCPlatformPayload* OCPlatformPayloadCreateAsOwner(OCPlatformInfo* platformInfo)
1783 OCPlatformPayload* payload = (OCPlatformPayload*)OICCalloc(1, sizeof(OCPlatformPayload));
1789 payload->base.type = PAYLOAD_TYPE_PLATFORM;
1791 payload->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1792 if (!payload->interfaces)
1796 payload->interfaces->value = OICStrdup(OC_RSRVD_INTERFACE_READ);
1797 payload->rt = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1802 payload->rt->value = OICStrdup(OC_RSRVD_RESOURCE_TYPE_PLATFORM);
1803 payload->info = *platformInfo;
1808 OCPlatformPayload* OCPlatformPayloadCreate(const OCPlatformInfo* platformInfo)
1810 OCPlatformPayload* payload = (OCPlatformPayload*)OICCalloc(1, sizeof(OCPlatformPayload));
1817 payload->base.type = PAYLOAD_TYPE_PLATFORM;
1818 OCResourcePayloadAddStringLL(&payload->rt, OC_RSRVD_RESOURCE_TYPE_PLATFORM);
1820 OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_DEFAULT);
1821 OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_READ);
1823 OCCopyPlatformInfo(platformInfo, payload);
1828 void OCPlatformInfoDestroy(OCPlatformInfo *info)
1830 OICFree(info->platformID);
1831 OICFree(info->manufacturerName);
1832 OICFree(info->manufacturerUrl);
1833 OICFree(info->modelNumber);
1834 OICFree(info->dateOfManufacture);
1835 OICFree(info->platformVersion);
1836 OICFree(info->operatingSystemVersion);
1837 OICFree(info->hardwareVersion);
1838 OICFree(info->firmwareVersion);
1839 OICFree(info->supportUrl);
1840 OICFree(info->systemTime);
1843 void OCPlatformPayloadDestroy(OCPlatformPayload* payload)
1849 OICFree(payload->uri);
1850 OCPlatformInfoDestroy(&payload->info);
1851 OCFreeOCStringLL(payload->rt);
1852 OCFreeOCStringLL(payload->interfaces);
1856 OCPresencePayload* OCPresencePayloadCreate(uint32_t seqNum, uint32_t maxAge,
1857 OCPresenceTrigger trigger, const char* resourceType)
1859 OCPresencePayload* payload = (OCPresencePayload*)OICCalloc(1, sizeof(OCPresencePayload));
1865 payload->base.type = PAYLOAD_TYPE_PRESENCE;
1866 payload->sequenceNumber = seqNum;
1867 payload->maxAge = maxAge;
1868 payload->trigger = trigger;
1869 payload->resourceType = OICStrdup(resourceType);
1873 void OCPresencePayloadDestroy(OCPresencePayload* payload)
1879 OICFree(payload->resourceType);