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
24 #include "iotivity_config.h"
26 #include "ocpayload.h"
29 #include "oic_malloc.h"
30 #include "oic_string.h"
31 #include "ocstackinternal.h"
32 #include "ocresource.h"
34 #include "rdpayload.h"
36 #define TAG "OIC_RI_PAYLOAD"
37 #define CSV_SEPARATOR ','
39 static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val);
41 void OCPayloadDestroy(OCPayload* payload)
50 case PAYLOAD_TYPE_REPRESENTATION:
51 OCRepPayloadDestroy((OCRepPayload*)payload);
53 case PAYLOAD_TYPE_DISCOVERY:
54 OCDiscoveryPayloadDestroy((OCDiscoveryPayload*)payload);
56 case PAYLOAD_TYPE_DEVICE:
57 OCDevicePayloadDestroy((OCDevicePayload*)payload);
59 case PAYLOAD_TYPE_PLATFORM:
60 OCPlatformPayloadDestroy((OCPlatformPayload*)payload);
62 case PAYLOAD_TYPE_PRESENCE:
63 OCPresencePayloadDestroy((OCPresencePayload*)payload);
65 case PAYLOAD_TYPE_SECURITY:
66 OCSecurityPayloadDestroy((OCSecurityPayload*)payload);
68 #if defined(RD_CLIENT) || defined(RD_SERVER)
70 OCRDPayloadDestroy((OCRDPayload*)payload);
74 OIC_LOG_V(ERROR, TAG, "Unsupported payload type in destroy: %d", payload->type);
79 OCRepPayload* OCRepPayloadCreate()
81 OCRepPayload* payload = (OCRepPayload*)OICCalloc(1, sizeof(OCRepPayload));
88 payload->base.type = PAYLOAD_TYPE_REPRESENTATION;
93 void OCRepPayloadAppend(OCRepPayload* parent, OCRepPayload* child)
102 parent = parent->next;
109 static OCRepPayloadValue* OCRepPayloadFindValue(const OCRepPayload* payload, const char* name)
111 if (!payload || !name)
116 OCRepPayloadValue* val = payload->values;
119 if (0 == strcmp(val->name, name))
129 static void OCCopyPropertyValueArray(OCRepPayloadValue* dest, OCRepPayloadValue* source)
131 if (!dest || !source)
136 size_t dimTotal = calcDimTotal(source->arr.dimensions);
137 switch(source->arr.type)
140 dest->arr.iArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
141 VERIFY_PARAM_NON_NULL(TAG, dest->arr.iArray, "Failed allocating memory");
142 memcpy(dest->arr.iArray, source->arr.iArray, dimTotal * sizeof(int64_t));
144 case OCREP_PROP_DOUBLE:
145 dest->arr.dArray = (double*)OICMalloc(dimTotal * sizeof(double));
146 VERIFY_PARAM_NON_NULL(TAG, dest->arr.dArray, "Failed allocating memory");
147 memcpy(dest->arr.dArray, source->arr.dArray, dimTotal * sizeof(double));
149 case OCREP_PROP_BOOL:
150 dest->arr.bArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
151 VERIFY_PARAM_NON_NULL(TAG, dest->arr.bArray, "Failed allocating memory");
152 memcpy(dest->arr.bArray, source->arr.bArray, dimTotal * sizeof(bool));
154 case OCREP_PROP_STRING:
155 dest->arr.strArray = (char**)OICMalloc(dimTotal * sizeof(char*));
156 VERIFY_PARAM_NON_NULL(TAG, dest->arr.strArray, "Failed allocating memory");
157 for(size_t i = 0; i < dimTotal; ++i)
159 dest->arr.strArray[i] = OICStrdup(source->arr.strArray[i]);
162 case OCREP_PROP_OBJECT:
163 dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
164 VERIFY_PARAM_NON_NULL(TAG, dest->arr.objArray, "Failed allocating memory");
165 for(size_t i = 0; i < dimTotal; ++i)
167 dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
170 case OCREP_PROP_ARRAY:
171 dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
172 VERIFY_PARAM_NON_NULL(TAG, dest->arr.objArray, "Failed allocating memory");
173 for(size_t i = 0; i < dimTotal; ++i)
175 dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
179 OIC_LOG(ERROR, TAG, "CopyPropertyValueArray invalid type");
186 static void OCCopyPropertyValue (OCRepPayloadValue *dest, OCRepPayloadValue *source)
188 if (!source || !dest)
195 case OCREP_PROP_STRING:
196 dest->str = OICStrdup(source->str);
198 case OCREP_PROP_BYTE_STRING:
199 dest->ocByteStr.bytes = (uint8_t*)OICMalloc(source->ocByteStr.len * sizeof(uint8_t));
200 VERIFY_PARAM_NON_NULL(TAG, dest->ocByteStr.bytes, "Failed allocating memory");
201 dest->ocByteStr.len = source->ocByteStr.len;
202 memcpy(dest->ocByteStr.bytes, source->ocByteStr.bytes, dest->ocByteStr.len);
204 case OCREP_PROP_OBJECT:
205 dest->obj = OCRepPayloadClone(source->obj);
207 case OCREP_PROP_ARRAY:
208 OCCopyPropertyValueArray(dest, source);
211 // Nothing to do for the trivially copyable types.
218 static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val)
225 if (val->type == OCREP_PROP_STRING)
229 else if (val->type == OCREP_PROP_BYTE_STRING)
231 OICFree(val->ocByteStr.bytes);
233 else if (val->type == OCREP_PROP_OBJECT)
235 OCRepPayloadDestroy(val->obj);
237 else if (val->type == OCREP_PROP_ARRAY)
239 size_t dimTotal = calcDimTotal(val->arr.dimensions);
240 switch(val->arr.type)
243 case OCREP_PROP_DOUBLE:
244 case OCREP_PROP_BOOL:
245 // Since this is a union, iArray will
246 // point to all of the above
247 OICFree(val->arr.iArray);
249 case OCREP_PROP_STRING:
250 for(size_t i = 0; i< dimTotal; ++i)
252 OICFree(val->arr.strArray[i]);
254 OICFree(val->arr.strArray);
256 case OCREP_PROP_BYTE_STRING:
257 for (size_t i = 0; i< dimTotal; ++i)
259 OICFree(val->arr.ocByteStrArray[i].bytes);
261 OICFree(val->arr.ocByteStrArray);
263 case OCREP_PROP_OBJECT: // This case is the temporary fix for string input
264 for(size_t i = 0; i< dimTotal; ++i)
266 OCRepPayloadDestroy(val->arr.objArray[i]);
268 OICFree(val->arr.objArray);
270 case OCREP_PROP_NULL:
271 case OCREP_PROP_ARRAY:
272 OIC_LOG_V(ERROR, TAG, "FreeRepPayloadValueContents: Illegal type\
273 inside an array: %d", val->arr.type);
279 static void OCFreeRepPayloadValue(OCRepPayloadValue* val)
287 OCFreeRepPayloadValueContents(val);
288 OCFreeRepPayloadValue(val->next);
291 static OCRepPayloadValue* OCRepPayloadValueClone (OCRepPayloadValue* source)
298 OCRepPayloadValue *sourceIter = source;
299 OCRepPayloadValue *destIter = (OCRepPayloadValue*) OICCalloc(1, sizeof(OCRepPayloadValue));
305 OCRepPayloadValue *headOfClone = destIter;
307 // Copy payload type and non pointer types in union.
308 *destIter = *sourceIter;
309 destIter->name = OICStrdup (sourceIter->name);
310 OCCopyPropertyValue (destIter, sourceIter);
312 sourceIter = sourceIter->next;
316 destIter->next = (OCRepPayloadValue*) OICCalloc(1, sizeof(OCRepPayloadValue));
319 OCFreeRepPayloadValue (headOfClone);
323 *(destIter->next) = *sourceIter;
324 destIter->next->name = OICStrdup (sourceIter->name);
325 OCCopyPropertyValue (destIter->next, sourceIter);
327 sourceIter = sourceIter->next;
328 destIter = destIter->next;
333 static OCRepPayloadValue* OCRepPayloadFindAndSetValue(OCRepPayload* payload, const char* name,
334 OCRepPayloadPropType type)
336 if (!payload || !name)
341 OCRepPayloadValue* val = payload->values;
344 payload->values = (OCRepPayloadValue*)OICCalloc(1, sizeof(OCRepPayloadValue));
345 if (!payload->values)
349 payload->values->name = OICStrdup(name);
350 if (!payload->values->name)
352 OICFree(payload->values);
353 payload->values = NULL;
356 payload->values->type =type;
357 return payload->values;
362 if (0 == strcmp(val->name, name))
364 OCFreeRepPayloadValueContents(val);
368 else if (val->next == NULL)
370 val->next = (OCRepPayloadValue*)OICCalloc(1, sizeof(OCRepPayloadValue));
375 val->next->name = OICStrdup(name);
376 if (!val->next->name)
382 val->next->type =type;
389 OIC_LOG(ERROR, TAG, "FindAndSetValue reached point after while loop, pointer corruption?");
393 bool OCRepPayloadAddResourceType(OCRepPayload* payload, const char* resourceType)
395 return OCRepPayloadAddResourceTypeAsOwner(payload, OICStrdup(resourceType));
398 bool OCRepPayloadAddResourceTypeAsOwner(OCRepPayload* payload, char* resourceType)
400 if (!payload || !resourceType)
407 OCStringLL* cur = payload->types;
412 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
419 cur->next->value = resourceType;
424 payload->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
429 payload->types->value = resourceType;
434 bool OCRepPayloadAddInterface(OCRepPayload* payload, const char* iface)
436 return OCRepPayloadAddInterfaceAsOwner(payload, OICStrdup(iface));
439 bool OCRepPayloadAddInterfaceAsOwner(OCRepPayload* payload, char* iface)
441 if (!payload || !iface)
446 if (payload->interfaces)
448 OCStringLL* cur = payload->interfaces;
453 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
459 cur->next->value = iface;
464 payload->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
465 if (!payload->interfaces)
469 payload->interfaces->value = iface;
474 bool OCRepPayloadSetUri(OCRepPayload* payload, const char* uri)
480 OICFree(payload->uri);
481 payload->uri = OICStrdup(uri);
482 return payload->uri != NULL;
485 bool OCRepPayloadIsNull(const OCRepPayload* payload, const char* name)
487 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
494 return val->type == OCREP_PROP_NULL;
497 static bool OCRepPayloadSetProp(OCRepPayload* payload, const char* name,
498 void* value, OCRepPayloadPropType type)
500 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, type);
508 val->i = *(int64_t*)value;
510 case OCREP_PROP_DOUBLE:
511 val->d = *(double*)value;
513 case OCREP_PROP_BOOL:
514 val->b = *(bool*)value;
516 case OCREP_PROP_OBJECT:
517 val->obj = (OCRepPayload*)value;
519 case OCREP_PROP_STRING:
520 val->str = (char*)value;
521 return val->str != NULL;
522 case OCREP_PROP_BYTE_STRING:
523 val->ocByteStr = *(OCByteString*)value;
525 case OCREP_PROP_NULL:
527 case OCREP_PROP_ARRAY:
535 bool OCRepPayloadSetNull(OCRepPayload* payload, const char* name)
537 return OCRepPayloadSetProp(payload, name, NULL, OCREP_PROP_NULL);
540 bool OCRepPayloadSetPropInt(OCRepPayload* payload,
541 const char* name, int64_t value)
543 return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_INT);
546 bool OCRepPayloadGetPropInt(const OCRepPayload* payload, const char* name, int64_t* value)
548 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
550 if (!val || val->type != OCREP_PROP_INT)
559 bool OCRepPayloadSetPropDouble(OCRepPayload* payload,
560 const char* name, double value)
562 return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_DOUBLE);
565 bool OCRepPayloadGetPropDouble(const OCRepPayload* payload, const char* name, double* value)
567 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
571 if (val->type == OCREP_PROP_DOUBLE)
576 else if (val->type == OCREP_PROP_INT)
586 bool OCRepPayloadSetPropString(OCRepPayload* payload, const char* name, const char* value)
588 char* temp = OICStrdup(value);
589 bool b = OCRepPayloadSetPropStringAsOwner(payload, name, temp);
598 bool OCRepPayloadSetPropStringAsOwner(OCRepPayload* payload, const char* name, char* value)
600 return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_STRING);
603 bool OCRepPayloadGetPropString(const OCRepPayload* payload, const char* name, char** value)
605 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
607 if (!val || val->type != OCREP_PROP_STRING)
612 *value = OICStrdup(val->str);
613 return *value != NULL;
616 bool OCRepPayloadSetPropByteString(OCRepPayload* payload, const char* name, OCByteString value)
618 if (!value.bytes || !value.len)
623 OCByteString ocByteStr = {
624 .bytes = (uint8_t*)OICMalloc(value.len * sizeof(uint8_t)),
627 if (!ocByteStr.bytes)
631 memcpy(ocByteStr.bytes, value.bytes, ocByteStr.len);
633 bool b = OCRepPayloadSetPropByteStringAsOwner(payload, name, &ocByteStr);
637 OICFree(ocByteStr.bytes);
642 bool OCRepPayloadSetPropByteStringAsOwner(OCRepPayload* payload, const char* name, OCByteString* value)
644 return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_BYTE_STRING);
647 bool OCRepPayloadGetPropByteString(const OCRepPayload* payload, const char* name, OCByteString* value)
649 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
651 if (!val || val->type != OCREP_PROP_BYTE_STRING)
661 value->bytes = (uint8_t*)OICMalloc(val->ocByteStr.len * sizeof(uint8_t));
666 value->len = val->ocByteStr.len;
667 memcpy(value->bytes, val->ocByteStr.bytes, value->len);
672 bool OCRepPayloadSetPropBool(OCRepPayload* payload,
673 const char* name, bool value)
675 return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_BOOL);
678 bool OCRepPayloadGetPropBool(const OCRepPayload* payload, const char* name, bool* value)
680 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
682 if (!val || val->type != OCREP_PROP_BOOL)
691 bool OCRepPayloadSetPropObject(OCRepPayload* payload, const char* name, const OCRepPayload* value)
693 OCRepPayload* temp = OCRepPayloadClone(value);
694 bool b = OCRepPayloadSetPropObjectAsOwner(payload, name, temp);
698 OCRepPayloadDestroy(temp);
703 bool OCRepPayloadSetPropObjectAsOwner(OCRepPayload* payload, const char* name, OCRepPayload* value)
705 return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_OBJECT);
708 bool OCRepPayloadGetPropObject(const OCRepPayload* payload, const char* name, OCRepPayload** value)
710 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
712 if (!val || val->type != OCREP_PROP_OBJECT)
717 *value = OCRepPayloadClone(val->obj);
718 return *value != NULL;
721 size_t calcDimTotal(const size_t dimensions[MAX_REP_ARRAY_DEPTH])
723 if (dimensions[0] == 0)
729 for(uint8_t i = 0; i < MAX_REP_ARRAY_DEPTH && dimensions[i] != 0; ++i)
731 total *= dimensions[i];
737 bool OCRepPayloadSetByteStringArrayAsOwner(OCRepPayload* payload, const char* name,
738 OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
740 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
747 val->arr.type = OCREP_PROP_BYTE_STRING;
748 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
749 val->arr.ocByteStrArray = array;
754 bool OCRepPayloadSetByteStringArray(OCRepPayload* payload, const char* name,
755 const OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
762 size_t dimTotal = calcDimTotal(dimensions);
768 OCByteString* newArray = (OCByteString*)OICCalloc(dimTotal, sizeof(OCByteString));
775 for (size_t i = 0; i < dimTotal; ++i)
777 newArray[i].bytes = (uint8_t*)OICMalloc(array[i].len * sizeof(uint8_t));
778 if (NULL == newArray[i].bytes)
780 for (size_t j = 0; j < i; ++j)
782 OICFree(newArray[j].bytes);
788 newArray[i].len = array[i].len;
789 memcpy(newArray[i].bytes, array[i].bytes, newArray[i].len);
792 bool b = OCRepPayloadSetByteStringArrayAsOwner(payload, name, newArray, dimensions);
795 for (size_t i = 0; i < dimTotal; ++i)
797 OICFree(newArray[i].bytes);
805 bool OCRepPayloadGetByteStringArray(const OCRepPayload* payload, const char* name,
806 OCByteString** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
808 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
810 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_BYTE_STRING
811 || !val->arr.ocByteStrArray)
816 size_t dimTotal = calcDimTotal(val->arr.dimensions);
822 *array = (OCByteString*)OICCalloc(dimTotal, sizeof(OCByteString));
828 for (size_t i = 0; i < dimTotal; ++i)
830 OCByteString* tmp = &(*array)[i];
831 tmp->bytes = (uint8_t*)OICMalloc(val->arr.ocByteStrArray[i].len * sizeof(uint8_t));
832 if (NULL == tmp->bytes)
834 for (size_t j = 0; j < i; ++j)
836 OCByteString* tmp = &(*array)[j];
844 tmp->len = val->arr.ocByteStrArray[i].len;
845 memcpy(tmp->bytes, val->arr.ocByteStrArray[i].bytes, tmp->len);
848 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
853 bool OCRepPayloadSetIntArrayAsOwner(OCRepPayload* payload, const char* name,
854 int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
856 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
863 val->arr.type = OCREP_PROP_INT;
864 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
865 val->arr.iArray = array;
870 bool OCRepPayloadSetIntArray(OCRepPayload* payload, const char* name,
871 const int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
873 size_t dimTotal = calcDimTotal(dimensions);
879 int64_t* newArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
886 memcpy(newArray, array, dimTotal * sizeof(int64_t));
889 bool b = OCRepPayloadSetIntArrayAsOwner(payload, name, newArray, dimensions);
897 bool OCRepPayloadGetIntArray(const OCRepPayload* payload, const char* name,
898 int64_t** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
900 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
902 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_INT
908 size_t dimTotal = calcDimTotal(val->arr.dimensions);
913 *array = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
919 memcpy(*array, val->arr.iArray, dimTotal * sizeof(int64_t));
920 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
924 bool OCRepPayloadSetDoubleArrayAsOwner(OCRepPayload* payload, const char* name,
925 double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
927 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
934 val->arr.type = OCREP_PROP_DOUBLE;
935 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
936 val->arr.dArray = array;
940 bool OCRepPayloadSetDoubleArray(OCRepPayload* payload, const char* name,
941 const double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
943 size_t dimTotal = calcDimTotal(dimensions);
949 double* newArray = (double*)OICMalloc(dimTotal * sizeof(double));
956 memcpy(newArray, array, dimTotal * sizeof(double));
958 bool b = OCRepPayloadSetDoubleArrayAsOwner(payload, name, newArray, dimensions);
966 bool OCRepPayloadGetDoubleArray(const OCRepPayload* payload, const char* name,
967 double** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
969 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
971 if (!val || val->type != OCREP_PROP_ARRAY ||
972 (val->arr.type != OCREP_PROP_DOUBLE && val->arr.type != OCREP_PROP_INT)
978 size_t dimTotal = calcDimTotal(val->arr.dimensions);
983 *array = (double*)OICMalloc(dimTotal * sizeof(double));
989 if (val->arr.type == OCREP_PROP_DOUBLE)
991 memcpy(*array, val->arr.dArray, dimTotal * sizeof(double));
995 /* need to convert from integer */
997 for ( ; n < dimTotal; ++n)
999 (*array)[n] = val->arr.iArray[n];
1002 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1006 bool OCRepPayloadSetStringArrayAsOwner(OCRepPayload* payload, const char* name,
1007 char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1009 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1016 val->arr.type = OCREP_PROP_STRING;
1017 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1018 val->arr.strArray = array;
1022 bool OCRepPayloadSetStringArray(OCRepPayload* payload, const char* name,
1023 const char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1025 size_t dimTotal = calcDimTotal(dimensions);
1031 char** newArray = (char**)OICMalloc(dimTotal * sizeof(char*));
1038 for(size_t i = 0; i < dimTotal; ++i)
1040 newArray[i] = OICStrdup(array[i]);
1043 bool b = OCRepPayloadSetStringArrayAsOwner(payload, name, newArray, dimensions);
1047 for(size_t i = 0; i < dimTotal; ++i)
1049 OICFree(newArray[i]);
1056 bool OCRepPayloadGetStringArray(const OCRepPayload* payload, const char* name,
1057 char*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1059 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1061 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_STRING
1062 || !val->arr.strArray)
1067 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1072 *array = (char**)OICMalloc(dimTotal * sizeof(char*));
1078 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1080 for(size_t i = 0; i < dimTotal; ++i)
1082 (*array)[i] = OICStrdup(val->arr.strArray[i]);
1089 bool OCRepPayloadSetBoolArrayAsOwner(OCRepPayload* payload, const char* name,
1090 bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1093 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1100 val->arr.type = OCREP_PROP_BOOL;
1101 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1102 val->arr.bArray = array;
1106 bool OCRepPayloadSetBoolArray(OCRepPayload* payload, const char* name,
1107 const bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1109 size_t dimTotal = calcDimTotal(dimensions);
1115 bool* newArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
1122 memcpy(newArray, array, dimTotal * sizeof(bool));
1125 bool b = OCRepPayloadSetBoolArrayAsOwner(payload, name, newArray, dimensions);
1133 bool OCRepPayloadGetBoolArray(const OCRepPayload* payload, const char* name,
1134 bool** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1136 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1138 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_BOOL
1139 || !val->arr.bArray)
1144 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1149 *array = (bool*)OICMalloc(dimTotal * sizeof(bool));
1155 memcpy(*array, val->arr.bArray, dimTotal * sizeof(bool));
1156 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1160 bool OCRepPayloadSetPropObjectArrayAsOwner(OCRepPayload* payload, const char* name,
1161 OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1163 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1170 val->arr.type = OCREP_PROP_OBJECT;
1171 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1172 val->arr.objArray = array;
1177 bool OCRepPayloadSetPropObjectArray(OCRepPayload* payload, const char* name,
1178 const OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1180 size_t dimTotal = calcDimTotal(dimensions);
1186 OCRepPayload** newArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
1193 for(size_t i = 0; i < dimTotal; ++i)
1195 newArray[i] = OCRepPayloadClone(array[i]);
1198 bool b = OCRepPayloadSetPropObjectArrayAsOwner(payload, name, newArray, dimensions);
1202 for(size_t i = 0; i < dimTotal; ++i)
1204 OCRepPayloadDestroy(newArray[i]);
1211 bool OCRepPayloadGetPropObjectArray(const OCRepPayload* payload, const char* name,
1212 OCRepPayload*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1214 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1216 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_OBJECT
1217 || !val->arr.objArray)
1222 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1227 *array = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
1233 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1235 for(size_t i = 0; i < dimTotal; ++i)
1237 (*array)[i] = OCRepPayloadClone(val->arr.objArray[i]);
1243 void OCFreeOCStringLL(OCStringLL* ll)
1250 OCFreeOCStringLL(ll->next);
1255 OCStringLL* CloneOCStringLL (OCStringLL* ll)
1262 OCStringLL *sourceIter = ll;
1264 OCStringLL *destIter = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
1269 destIter->value = OICStrdup (sourceIter->value);
1271 OCStringLL *headOfClone = destIter;
1273 sourceIter = sourceIter->next;
1277 destIter->next = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
1278 if (!destIter->next)
1280 OCFreeOCStringLL (headOfClone);
1283 destIter->next->value = OICStrdup (sourceIter->value);
1285 destIter = destIter->next;
1286 sourceIter = sourceIter->next;
1291 OCStringLL* OCCreateOCStringLL(const char* text)
1296 char *backup = NULL;
1297 OCStringLL* result = NULL;
1298 OCStringLL* iter = NULL;
1299 OCStringLL* prev = NULL;
1300 static const char delim[] = { CSV_SEPARATOR, '\0' };
1302 VERIFY_PARAM_NON_NULL(TAG, text, "Invalid parameter");
1303 backup = OICStrdup(text);
1304 VERIFY_PARAM_NON_NULL(TAG, backup, "Failed allocating memory");
1306 for (head = backup; ; head = NULL)
1308 token = (char *) strtok_r(head, delim, &tail);
1310 iter = (OCStringLL *)OICCalloc(1,sizeof(OCStringLL));
1311 VERIFY_PARAM_NON_NULL(TAG, iter, "Failed allocating memory");
1320 iter->value = OICStrdup(token);
1321 VERIFY_PARAM_NON_NULL(TAG, iter->value, "Failed allocating memory");
1330 OCFreeOCStringLL(result);
1334 char* OCCreateString(const OCStringLL* ll)
1347 for (const OCStringLL *it = ll; it; it = it->next)
1349 len += strlen(it->value) + 1;
1351 len--; // renove trailing separator (just added above)
1352 str = (char*) malloc(len + 1);
1359 const OCStringLL *it = ll;
1362 sublen = strlen(it->value);
1363 count = snprintf(pos, len + 1, "%s", it->value);
1364 if ((size_t)count < sublen)
1375 *pos = CSV_SEPARATOR;
1384 OCRepPayload* OCRepPayloadClone (const OCRepPayload* payload)
1391 OCRepPayload *clone = OCRepPayloadCreate();
1398 clone->uri = OICStrdup (payload->uri);
1399 clone->types = CloneOCStringLL (payload->types);
1400 clone->interfaces = CloneOCStringLL (payload->interfaces);
1401 clone->values = OCRepPayloadValueClone (payload->values);
1407 void OCRepPayloadDestroy(OCRepPayload* payload)
1414 OICFree(payload->uri);
1415 OCFreeOCStringLL(payload->types);
1416 OCFreeOCStringLL(payload->interfaces);
1417 OCFreeRepPayloadValue(payload->values);
1418 OCRepPayloadDestroy(payload->next);
1422 OCDiscoveryPayload* OCDiscoveryPayloadCreate()
1424 OCDiscoveryPayload* payload = (OCDiscoveryPayload*)OICCalloc(1, sizeof(OCDiscoveryPayload));
1431 payload->base.type = PAYLOAD_TYPE_DISCOVERY;
1436 OCSecurityPayload* OCSecurityPayloadCreate(const uint8_t* securityData, size_t size)
1438 OCSecurityPayload* payload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1445 payload->base.type = PAYLOAD_TYPE_SECURITY;
1446 payload->securityData = (uint8_t *)OICCalloc(1, size);
1447 if (!payload->securityData)
1452 memcpy(payload->securityData, (uint8_t *)securityData, size);
1453 payload->payloadSize = size;
1458 void OCSecurityPayloadDestroy(OCSecurityPayload* payload)
1465 OICFree(payload->securityData);
1469 size_t OCDiscoveryPayloadGetResourceCount(OCDiscoveryPayload* payload)
1472 OCResourcePayload* p = payload->resources;
1481 OCResourcePayload* OCDiscoveryPayloadGetResource(OCDiscoveryPayload* payload, size_t index)
1484 OCResourcePayload* p = payload->resources;
1498 static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort)
1500 static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort,
1504 OCResourcePayload* pl = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1510 pl->uri = OICStrdup(res->uri);
1514 OCDiscoveryResourceDestroy(pl);
1519 OCResourceType* typePtr = res->rsrcType;
1521 if (typePtr != NULL)
1523 pl->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1526 OCDiscoveryResourceDestroy(pl);
1529 pl->types->value = OICStrdup(typePtr->resourcetypename);
1530 if (!pl->types->value)
1532 OCDiscoveryResourceDestroy(pl);
1536 OCStringLL* cur = pl->types;
1537 typePtr = typePtr->next;
1540 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1543 OCDiscoveryResourceDestroy(pl);
1546 cur->next->value = OICStrdup(typePtr->resourcetypename);
1547 if (!cur->next->value)
1549 OCDiscoveryResourceDestroy(pl);
1553 typePtr = typePtr->next;
1558 OCResourceInterface* ifPtr = res->rsrcInterface;
1561 pl->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1562 if (!pl->interfaces)
1564 OCDiscoveryResourceDestroy(pl);
1567 pl->interfaces->value = OICStrdup(ifPtr->name);
1568 if (!pl->interfaces->value)
1570 OCDiscoveryResourceDestroy(pl);
1574 OCStringLL* cur = pl->interfaces;
1575 ifPtr = ifPtr->next;
1578 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1581 OCDiscoveryResourceDestroy(pl);
1584 cur->next->value = OICStrdup(ifPtr->name);
1585 if (!cur->next->value)
1587 OCDiscoveryResourceDestroy(pl);
1591 ifPtr = ifPtr->next;
1595 pl->bitmap = res->resourceProperties & (OC_OBSERVABLE | OC_DISCOVERABLE
1600 pl->secure = (res->resourceProperties & OC_SECURE) != 0;
1601 pl->port = securePort;
1603 pl->tcpPort = tcpPort;
1609 void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
1610 uint16_t securePort)
1612 OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort));
1615 void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
1616 uint16_t securePort, uint16_t tcpPort)
1618 OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort, tcpPort));
1622 bool OCResourcePayloadAddStringLL(OCStringLL **stringLL, const char *value)
1624 char *dup = OICStrdup(value);
1625 VERIFY_PARAM_NON_NULL(TAG, dup, "Failed copying string");
1626 VERIFY_PARAM_NON_NULL(TAG, value, "Invalid Parameters");
1630 *stringLL = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
1631 VERIFY_PARAM_NON_NULL(TAG, *stringLL, "Failed allocating memory");
1632 (*stringLL)->value = dup;
1637 OCStringLL *temp = *stringLL;
1642 temp->next = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
1643 VERIFY_PARAM_NON_NULL(TAG, temp->next, "Failed allocating memory");
1644 temp->next->value = dup;
1652 void OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload, OCResourcePayload* res)
1659 if (!payload->resources)
1661 payload->resources = res;
1665 OCResourcePayload* p = payload->resources;
1674 void OCDiscoveryResourceDestroy(OCResourcePayload* payload)
1681 OICFree(payload->uri);
1682 OCFreeOCStringLL(payload->types);
1683 OCFreeOCStringLL(payload->interfaces);
1684 OCDiscoveryResourceDestroy(payload->next);
1688 void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload)
1694 OICFree(payload->sid);
1695 OICFree(payload->baseURI);
1696 OICFree(payload->uri);
1697 OCFreeOCStringLL(payload->type);
1698 OICFree(payload->name);
1699 OCFreeOCStringLL(payload->iface);
1700 OCDiscoveryResourceDestroy(payload->resources);
1701 OCDiscoveryPayloadDestroy(payload->next);
1705 OCDevicePayload* OCDevicePayloadCreate(const char* sid, const char* dname,
1706 const OCStringLL *types, const char* specVer, const char* dmVer)
1709 OCDevicePayload* payload = (OCDevicePayload*)OICCalloc(1, sizeof(OCDevicePayload));
1716 payload->base.type = PAYLOAD_TYPE_DEVICE;
1717 payload->sid = OICStrdup(sid);
1718 if (sid && !payload->sid)
1723 payload->deviceName = OICStrdup(dname);
1724 if (dname && !payload->deviceName)
1729 payload->specVersion = OICStrdup(specVer);
1730 if (specVer && !payload->specVersion)
1735 payload->dataModelVersions = OCCreateOCStringLL(dmVer);
1736 if (!payload->dataModelVersions || (dmVer && !payload->dataModelVersions->value))
1741 OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_DEFAULT);
1742 OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_READ);
1744 payload->types = CloneOCStringLL((OCStringLL *)types);
1745 if (types && !payload->types)
1753 OCDevicePayloadDestroy((OCDevicePayload*)payload);
1757 void OCDevicePayloadDestroy(OCDevicePayload* payload)
1764 OICFree(payload->sid);
1765 OICFree(payload->deviceName);
1766 OICFree(payload->specVersion);
1767 OCFreeOCStringLL(payload->dataModelVersions);
1768 OCFreeOCStringLL(payload->types);
1769 OCFreeOCStringLL(payload->interfaces);
1773 static void OCCopyPlatformInfo(const OCPlatformInfo* platformInfo, OCPlatformPayload* target)
1775 if (!platformInfo || !target)
1780 target->info.platformID = OICStrdup(platformInfo->platformID);
1781 target->info.manufacturerName = OICStrdup(platformInfo->manufacturerName);
1782 target->info.manufacturerUrl = OICStrdup(platformInfo->manufacturerUrl);
1783 target->info.modelNumber = OICStrdup(platformInfo->modelNumber);
1784 target->info.dateOfManufacture = OICStrdup(platformInfo->dateOfManufacture);
1785 target->info.platformVersion = OICStrdup(platformInfo->platformVersion);
1786 target->info.operatingSystemVersion = OICStrdup(platformInfo->operatingSystemVersion);
1787 target->info.hardwareVersion = OICStrdup(platformInfo->hardwareVersion);
1788 target->info.firmwareVersion = OICStrdup(platformInfo->firmwareVersion);
1789 target->info.supportUrl = OICStrdup(platformInfo->supportUrl);
1790 target->info.systemTime = OICStrdup(platformInfo->systemTime);
1793 OCPlatformPayload* OCPlatformPayloadCreateAsOwner(OCPlatformInfo* platformInfo)
1795 OCPlatformPayload* payload = (OCPlatformPayload*)OICCalloc(1, sizeof(OCPlatformPayload));
1801 payload->base.type = PAYLOAD_TYPE_PLATFORM;
1803 payload->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1804 if (!payload->interfaces)
1808 payload->interfaces->value = OICStrdup(OC_RSRVD_INTERFACE_READ);
1809 payload->rt = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1814 payload->rt->value = OICStrdup(OC_RSRVD_RESOURCE_TYPE_PLATFORM);
1815 payload->info = *platformInfo;
1820 OCPlatformPayload* OCPlatformPayloadCreate(const OCPlatformInfo* platformInfo)
1822 OCPlatformPayload* payload = (OCPlatformPayload*)OICCalloc(1, sizeof(OCPlatformPayload));
1829 payload->base.type = PAYLOAD_TYPE_PLATFORM;
1830 OCResourcePayloadAddStringLL(&payload->rt, OC_RSRVD_RESOURCE_TYPE_PLATFORM);
1832 OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_DEFAULT);
1833 OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_READ);
1835 OCCopyPlatformInfo(platformInfo, payload);
1840 void OCPlatformInfoDestroy(OCPlatformInfo *info)
1842 OICFree(info->platformID);
1843 OICFree(info->manufacturerName);
1844 OICFree(info->manufacturerUrl);
1845 OICFree(info->modelNumber);
1846 OICFree(info->dateOfManufacture);
1847 OICFree(info->platformVersion);
1848 OICFree(info->operatingSystemVersion);
1849 OICFree(info->hardwareVersion);
1850 OICFree(info->firmwareVersion);
1851 OICFree(info->supportUrl);
1852 OICFree(info->systemTime);
1855 void OCPlatformPayloadDestroy(OCPlatformPayload* payload)
1861 OICFree(payload->uri);
1862 OCPlatformInfoDestroy(&payload->info);
1863 OCFreeOCStringLL(payload->rt);
1864 OCFreeOCStringLL(payload->interfaces);
1868 OCPresencePayload* OCPresencePayloadCreate(uint32_t seqNum, uint32_t maxAge,
1869 OCPresenceTrigger trigger, const char* resourceType)
1871 OCPresencePayload* payload = (OCPresencePayload*)OICCalloc(1, sizeof(OCPresencePayload));
1877 payload->base.type = PAYLOAD_TYPE_PRESENCE;
1878 payload->sequenceNumber = seqNum;
1879 payload->maxAge = maxAge;
1880 payload->trigger = trigger;
1881 payload->resourceType = OICStrdup(resourceType);
1885 void OCPresencePayloadDestroy(OCPresencePayload* payload)
1891 OICFree(payload->resourceType);