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);
67 #if defined(RD_CLIENT) || defined(RD_SERVER)
69 OCRDPayloadDestroy((OCRDPayload*)payload);
73 OIC_LOG_V(ERROR, TAG, "Unsupported payload type in destroy: %d", payload->type);
78 OCRepPayload* OCRepPayloadCreate()
80 OCRepPayload* payload = (OCRepPayload*)OICCalloc(1, sizeof(OCRepPayload));
87 payload->base.type = PAYLOAD_TYPE_REPRESENTATION;
92 void OCRepPayloadAppend(OCRepPayload* parent, OCRepPayload* child)
101 parent = parent->next;
108 static OCRepPayloadValue* OCRepPayloadFindValue(const OCRepPayload* payload, const char* name)
110 if (!payload || !name)
115 OCRepPayloadValue* val = payload->values;
118 if (0 == strcmp(val->name, name))
128 static void OCCopyPropertyValueArray(OCRepPayloadValue* dest, OCRepPayloadValue* source)
130 if (!dest || !source)
135 size_t dimTotal = calcDimTotal(source->arr.dimensions);
136 switch(source->arr.type)
139 dest->arr.iArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
140 VERIFY_PARAM_NON_NULL(TAG, dest->arr.iArray, "Failed allocating memory");
141 memcpy(dest->arr.iArray, source->arr.iArray, dimTotal * sizeof(int64_t));
143 case OCREP_PROP_DOUBLE:
144 dest->arr.dArray = (double*)OICMalloc(dimTotal * sizeof(double));
145 VERIFY_PARAM_NON_NULL(TAG, dest->arr.dArray, "Failed allocating memory");
146 memcpy(dest->arr.dArray, source->arr.dArray, dimTotal * sizeof(double));
148 case OCREP_PROP_BOOL:
149 dest->arr.bArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
150 VERIFY_PARAM_NON_NULL(TAG, dest->arr.bArray, "Failed allocating memory");
151 memcpy(dest->arr.bArray, source->arr.bArray, dimTotal * sizeof(bool));
153 case OCREP_PROP_STRING:
154 dest->arr.strArray = (char**)OICMalloc(dimTotal * sizeof(char*));
155 VERIFY_PARAM_NON_NULL(TAG, dest->arr.strArray, "Failed allocating memory");
156 for(size_t i = 0; i < dimTotal; ++i)
158 dest->arr.strArray[i] = OICStrdup(source->arr.strArray[i]);
161 case OCREP_PROP_OBJECT:
162 dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
163 VERIFY_PARAM_NON_NULL(TAG, dest->arr.objArray, "Failed allocating memory");
164 for(size_t i = 0; i < dimTotal; ++i)
166 dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
169 case OCREP_PROP_ARRAY:
170 dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
171 VERIFY_PARAM_NON_NULL(TAG, dest->arr.objArray, "Failed allocating memory");
172 for(size_t i = 0; i < dimTotal; ++i)
174 dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
178 OIC_LOG(ERROR, TAG, "CopyPropertyValueArray invalid type");
185 static void OCCopyPropertyValue (OCRepPayloadValue *dest, OCRepPayloadValue *source)
187 if (!source || !dest)
194 case OCREP_PROP_STRING:
195 dest->str = OICStrdup(source->str);
197 case OCREP_PROP_BYTE_STRING:
198 dest->ocByteStr.bytes = (uint8_t*)OICMalloc(source->ocByteStr.len * sizeof(uint8_t));
199 VERIFY_PARAM_NON_NULL(TAG, dest->ocByteStr.bytes, "Failed allocating memory");
200 dest->ocByteStr.len = source->ocByteStr.len;
201 memcpy(dest->ocByteStr.bytes, source->ocByteStr.bytes, dest->ocByteStr.len);
203 case OCREP_PROP_OBJECT:
204 dest->obj = OCRepPayloadClone(source->obj);
206 case OCREP_PROP_ARRAY:
207 OCCopyPropertyValueArray(dest, source);
210 // Nothing to do for the trivially copyable types.
217 static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val)
224 if (val->type == OCREP_PROP_STRING)
228 else if (val->type == OCREP_PROP_BYTE_STRING)
230 OICFree(val->ocByteStr.bytes);
232 else if (val->type == OCREP_PROP_OBJECT)
234 OCRepPayloadDestroy(val->obj);
236 else if (val->type == OCREP_PROP_ARRAY)
238 size_t dimTotal = calcDimTotal(val->arr.dimensions);
239 switch(val->arr.type)
242 case OCREP_PROP_DOUBLE:
243 case OCREP_PROP_BOOL:
244 // Since this is a union, iArray will
245 // point to all of the above
246 OICFree(val->arr.iArray);
248 case OCREP_PROP_STRING:
249 for(size_t i = 0; i< dimTotal; ++i)
251 OICFree(val->arr.strArray[i]);
253 OICFree(val->arr.strArray);
255 case OCREP_PROP_BYTE_STRING:
256 for (size_t i = 0; i< dimTotal; ++i)
258 OICFree(val->arr.ocByteStrArray[i].bytes);
260 OICFree(val->arr.ocByteStrArray);
262 case OCREP_PROP_OBJECT: // This case is the temporary fix for string input
263 for(size_t i = 0; i< dimTotal; ++i)
265 OCRepPayloadDestroy(val->arr.objArray[i]);
267 OICFree(val->arr.objArray);
269 case OCREP_PROP_NULL:
270 case OCREP_PROP_ARRAY:
271 OIC_LOG_V(ERROR, TAG, "FreeRepPayloadValueContents: Illegal type\
272 inside an array: %d", val->arr.type);
278 static void OCFreeRepPayloadValue(OCRepPayloadValue* val)
286 OCFreeRepPayloadValueContents(val);
287 OCFreeRepPayloadValue(val->next);
290 static OCRepPayloadValue* OCRepPayloadValueClone (OCRepPayloadValue* source)
297 OCRepPayloadValue *sourceIter = source;
298 OCRepPayloadValue *destIter = (OCRepPayloadValue*) OICCalloc(1, sizeof(OCRepPayloadValue));
304 OCRepPayloadValue *headOfClone = destIter;
306 // Copy payload type and non pointer types in union.
307 *destIter = *sourceIter;
308 destIter->name = OICStrdup (sourceIter->name);
309 OCCopyPropertyValue (destIter, sourceIter);
311 sourceIter = sourceIter->next;
315 destIter->next = (OCRepPayloadValue*) OICCalloc(1, sizeof(OCRepPayloadValue));
318 OCFreeRepPayloadValue (headOfClone);
322 *(destIter->next) = *sourceIter;
323 destIter->next->name = OICStrdup (sourceIter->name);
324 OCCopyPropertyValue (destIter->next, sourceIter);
326 sourceIter = sourceIter->next;
327 destIter = destIter->next;
332 static OCRepPayloadValue* OCRepPayloadFindAndSetValue(OCRepPayload* payload, const char* name,
333 OCRepPayloadPropType type)
335 if (!payload || !name)
340 OCRepPayloadValue* val = payload->values;
343 payload->values = (OCRepPayloadValue*)OICCalloc(1, sizeof(OCRepPayloadValue));
344 if (!payload->values)
348 payload->values->name = OICStrdup(name);
349 if (!payload->values->name)
351 OICFree(payload->values);
352 payload->values = NULL;
355 payload->values->type =type;
356 return payload->values;
361 if (0 == strcmp(val->name, name))
363 OCFreeRepPayloadValueContents(val);
367 else if (val->next == NULL)
369 val->next = (OCRepPayloadValue*)OICCalloc(1, sizeof(OCRepPayloadValue));
374 val->next->name = OICStrdup(name);
375 if (!val->next->name)
381 val->next->type =type;
388 OIC_LOG(ERROR, TAG, "FindAndSetValue reached point after while loop, pointer corruption?");
392 bool OCRepPayloadAddResourceType(OCRepPayload* payload, const char* resourceType)
394 return OCRepPayloadAddResourceTypeAsOwner(payload, OICStrdup(resourceType));
397 bool OCRepPayloadAddResourceTypeAsOwner(OCRepPayload* payload, char* resourceType)
399 if (!payload || !resourceType)
406 OCStringLL* cur = payload->types;
411 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
418 cur->next->value = resourceType;
423 payload->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
428 payload->types->value = resourceType;
433 bool OCRepPayloadAddInterface(OCRepPayload* payload, const char* iface)
435 return OCRepPayloadAddInterfaceAsOwner(payload, OICStrdup(iface));
438 bool OCRepPayloadAddInterfaceAsOwner(OCRepPayload* payload, char* iface)
440 if (!payload || !iface)
445 if (payload->interfaces)
447 OCStringLL* cur = payload->interfaces;
452 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
458 cur->next->value = iface;
463 payload->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
464 if (!payload->interfaces)
468 payload->interfaces->value = iface;
473 bool OCRepPayloadSetUri(OCRepPayload* payload, const char* uri)
479 OICFree(payload->uri);
480 payload->uri = OICStrdup(uri);
481 return payload->uri != NULL;
484 bool OCRepPayloadIsNull(const OCRepPayload* payload, const char* name)
486 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
493 return val->type == OCREP_PROP_NULL;
496 static bool OCRepPayloadSetProp(OCRepPayload* payload, const char* name,
497 void* value, OCRepPayloadPropType type)
499 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, type);
507 val->i = *(int64_t*)value;
509 case OCREP_PROP_DOUBLE:
510 val->d = *(double*)value;
512 case OCREP_PROP_BOOL:
513 val->b = *(bool*)value;
515 case OCREP_PROP_OBJECT:
516 val->obj = (OCRepPayload*)value;
518 case OCREP_PROP_STRING:
519 val->str = (char*)value;
520 return val->str != NULL;
521 case OCREP_PROP_BYTE_STRING:
522 val->ocByteStr = *(OCByteString*)value;
524 case OCREP_PROP_NULL:
526 case OCREP_PROP_ARRAY:
534 bool OCRepPayloadSetNull(OCRepPayload* payload, const char* name)
536 return OCRepPayloadSetProp(payload, name, NULL, OCREP_PROP_NULL);
539 bool OCRepPayloadSetPropInt(OCRepPayload* payload,
540 const char* name, int64_t value)
542 return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_INT);
545 bool OCRepPayloadGetPropInt(const OCRepPayload* payload, const char* name, int64_t* value)
547 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
549 if (!val || val->type != OCREP_PROP_INT)
558 bool OCRepPayloadSetPropDouble(OCRepPayload* payload,
559 const char* name, double value)
561 return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_DOUBLE);
564 bool OCRepPayloadGetPropDouble(const OCRepPayload* payload, const char* name, double* value)
566 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
570 if (val->type == OCREP_PROP_DOUBLE)
575 else if (val->type == OCREP_PROP_INT)
585 bool OCRepPayloadSetPropString(OCRepPayload* payload, const char* name, const char* value)
587 char* temp = OICStrdup(value);
588 bool b = OCRepPayloadSetPropStringAsOwner(payload, name, temp);
597 bool OCRepPayloadSetPropStringAsOwner(OCRepPayload* payload, const char* name, char* value)
599 return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_STRING);
602 bool OCRepPayloadGetPropString(const OCRepPayload* payload, const char* name, char** value)
604 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
606 if (!val || val->type != OCREP_PROP_STRING)
611 *value = OICStrdup(val->str);
612 return *value != NULL;
615 bool OCRepPayloadSetPropByteString(OCRepPayload* payload, const char* name, OCByteString value)
617 if (!value.bytes || !value.len)
622 OCByteString ocByteStr = {
623 .bytes = (uint8_t*)OICMalloc(value.len * sizeof(uint8_t)),
626 if (!ocByteStr.bytes)
630 memcpy(ocByteStr.bytes, value.bytes, ocByteStr.len);
632 bool b = OCRepPayloadSetPropByteStringAsOwner(payload, name, &ocByteStr);
636 OICFree(ocByteStr.bytes);
641 bool OCRepPayloadSetPropByteStringAsOwner(OCRepPayload* payload, const char* name, OCByteString* value)
643 return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_BYTE_STRING);
646 bool OCRepPayloadGetPropByteString(const OCRepPayload* payload, const char* name, OCByteString* value)
648 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
650 if (!val || val->type != OCREP_PROP_BYTE_STRING)
660 value->bytes = (uint8_t*)OICMalloc(val->ocByteStr.len * sizeof(uint8_t));
665 value->len = val->ocByteStr.len;
666 memcpy(value->bytes, val->ocByteStr.bytes, value->len);
671 bool OCRepPayloadSetPropBool(OCRepPayload* payload,
672 const char* name, bool value)
674 return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_BOOL);
677 bool OCRepPayloadGetPropBool(const OCRepPayload* payload, const char* name, bool* value)
679 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
681 if (!val || val->type != OCREP_PROP_BOOL)
690 bool OCRepPayloadSetPropObject(OCRepPayload* payload, const char* name, const OCRepPayload* value)
692 OCRepPayload* temp = OCRepPayloadClone(value);
693 bool b = OCRepPayloadSetPropObjectAsOwner(payload, name, temp);
697 OCRepPayloadDestroy(temp);
702 bool OCRepPayloadSetPropObjectAsOwner(OCRepPayload* payload, const char* name, OCRepPayload* value)
704 return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_OBJECT);
707 bool OCRepPayloadGetPropObject(const OCRepPayload* payload, const char* name, OCRepPayload** value)
709 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
711 if (!val || val->type != OCREP_PROP_OBJECT)
716 *value = OCRepPayloadClone(val->obj);
717 return *value != NULL;
720 size_t calcDimTotal(const size_t dimensions[MAX_REP_ARRAY_DEPTH])
722 if (dimensions[0] == 0)
728 for(uint8_t i = 0; i < MAX_REP_ARRAY_DEPTH && dimensions[i] != 0; ++i)
730 total *= dimensions[i];
736 bool OCRepPayloadSetByteStringArrayAsOwner(OCRepPayload* payload, const char* name,
737 OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
739 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
746 val->arr.type = OCREP_PROP_BYTE_STRING;
747 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
748 val->arr.ocByteStrArray = array;
753 bool OCRepPayloadSetByteStringArray(OCRepPayload* payload, const char* name,
754 const OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
761 size_t dimTotal = calcDimTotal(dimensions);
767 OCByteString* newArray = (OCByteString*)OICCalloc(dimTotal, sizeof(OCByteString));
774 for (size_t i = 0; i < dimTotal; ++i)
776 newArray[i].bytes = (uint8_t*)OICMalloc(array[i].len * sizeof(uint8_t));
777 if (NULL == newArray[i].bytes)
779 for (size_t j = 0; j < i; ++j)
781 OICFree(newArray[j].bytes);
787 newArray[i].len = array[i].len;
788 memcpy(newArray[i].bytes, array[i].bytes, newArray[i].len);
791 bool b = OCRepPayloadSetByteStringArrayAsOwner(payload, name, newArray, dimensions);
794 for (size_t i = 0; i < dimTotal; ++i)
796 OICFree(newArray[i].bytes);
804 bool OCRepPayloadGetByteStringArray(const OCRepPayload* payload, const char* name,
805 OCByteString** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
807 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
809 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_BYTE_STRING
810 || !val->arr.ocByteStrArray)
815 size_t dimTotal = calcDimTotal(val->arr.dimensions);
821 *array = (OCByteString*)OICCalloc(dimTotal, sizeof(OCByteString));
827 for (size_t i = 0; i < dimTotal; ++i)
829 OCByteString* tmp = &(*array)[i];
830 tmp->bytes = (uint8_t*)OICMalloc(val->arr.ocByteStrArray[i].len * sizeof(uint8_t));
831 if (NULL == tmp->bytes)
833 for (size_t j = 0; j < i; ++j)
835 OCByteString* tmp = &(*array)[j];
843 tmp->len = val->arr.ocByteStrArray[i].len;
844 memcpy(tmp->bytes, val->arr.ocByteStrArray[i].bytes, tmp->len);
847 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
852 bool OCRepPayloadSetIntArrayAsOwner(OCRepPayload* payload, const char* name,
853 int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
855 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
862 val->arr.type = OCREP_PROP_INT;
863 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
864 val->arr.iArray = array;
869 bool OCRepPayloadSetIntArray(OCRepPayload* payload, const char* name,
870 const int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
872 size_t dimTotal = calcDimTotal(dimensions);
878 int64_t* newArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
885 memcpy(newArray, array, dimTotal * sizeof(int64_t));
888 bool b = OCRepPayloadSetIntArrayAsOwner(payload, name, newArray, dimensions);
896 bool OCRepPayloadGetIntArray(const OCRepPayload* payload, const char* name,
897 int64_t** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
899 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
901 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_INT
907 size_t dimTotal = calcDimTotal(val->arr.dimensions);
912 *array = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
918 memcpy(*array, val->arr.iArray, dimTotal * sizeof(int64_t));
919 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
923 bool OCRepPayloadSetDoubleArrayAsOwner(OCRepPayload* payload, const char* name,
924 double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
926 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
933 val->arr.type = OCREP_PROP_DOUBLE;
934 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
935 val->arr.dArray = array;
939 bool OCRepPayloadSetDoubleArray(OCRepPayload* payload, const char* name,
940 const double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
942 size_t dimTotal = calcDimTotal(dimensions);
948 double* newArray = (double*)OICMalloc(dimTotal * sizeof(double));
955 memcpy(newArray, array, dimTotal * sizeof(double));
957 bool b = OCRepPayloadSetDoubleArrayAsOwner(payload, name, newArray, dimensions);
965 bool OCRepPayloadGetDoubleArray(const OCRepPayload* payload, const char* name,
966 double** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
968 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
970 if (!val || val->type != OCREP_PROP_ARRAY ||
971 (val->arr.type != OCREP_PROP_DOUBLE && val->arr.type != OCREP_PROP_INT)
977 size_t dimTotal = calcDimTotal(val->arr.dimensions);
982 *array = (double*)OICMalloc(dimTotal * sizeof(double));
988 if (val->arr.type == OCREP_PROP_DOUBLE)
990 memcpy(*array, val->arr.dArray, dimTotal * sizeof(double));
994 /* need to convert from integer */
996 for ( ; n < dimTotal; ++n)
998 (*array)[n] = val->arr.iArray[n];
1001 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1005 bool OCRepPayloadSetStringArrayAsOwner(OCRepPayload* payload, const char* name,
1006 char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1008 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1015 val->arr.type = OCREP_PROP_STRING;
1016 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1017 val->arr.strArray = array;
1021 bool OCRepPayloadSetStringArray(OCRepPayload* payload, const char* name,
1022 const char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1024 size_t dimTotal = calcDimTotal(dimensions);
1030 char** newArray = (char**)OICMalloc(dimTotal * sizeof(char*));
1037 for(size_t i = 0; i < dimTotal; ++i)
1039 newArray[i] = OICStrdup(array[i]);
1042 bool b = OCRepPayloadSetStringArrayAsOwner(payload, name, newArray, dimensions);
1046 for(size_t i = 0; i < dimTotal; ++i)
1048 OICFree(newArray[i]);
1055 bool OCRepPayloadGetStringArray(const OCRepPayload* payload, const char* name,
1056 char*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1058 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1060 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_STRING
1061 || !val->arr.strArray)
1066 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1071 *array = (char**)OICMalloc(dimTotal * sizeof(char*));
1077 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1079 for(size_t i = 0; i < dimTotal; ++i)
1081 (*array)[i] = OICStrdup(val->arr.strArray[i]);
1088 bool OCRepPayloadSetBoolArrayAsOwner(OCRepPayload* payload, const char* name,
1089 bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1092 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1099 val->arr.type = OCREP_PROP_BOOL;
1100 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1101 val->arr.bArray = array;
1105 bool OCRepPayloadSetBoolArray(OCRepPayload* payload, const char* name,
1106 const bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1108 size_t dimTotal = calcDimTotal(dimensions);
1114 bool* newArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
1121 memcpy(newArray, array, dimTotal * sizeof(bool));
1124 bool b = OCRepPayloadSetBoolArrayAsOwner(payload, name, newArray, dimensions);
1132 bool OCRepPayloadGetBoolArray(const OCRepPayload* payload, const char* name,
1133 bool** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1135 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1137 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_BOOL
1138 || !val->arr.bArray)
1143 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1148 *array = (bool*)OICMalloc(dimTotal * sizeof(bool));
1154 memcpy(*array, val->arr.bArray, dimTotal * sizeof(bool));
1155 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1159 bool OCRepPayloadSetPropObjectArrayAsOwner(OCRepPayload* payload, const char* name,
1160 OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1162 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1169 val->arr.type = OCREP_PROP_OBJECT;
1170 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1171 val->arr.objArray = array;
1176 bool OCRepPayloadSetPropObjectArray(OCRepPayload* payload, const char* name,
1177 const OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1179 size_t dimTotal = calcDimTotal(dimensions);
1185 OCRepPayload** newArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
1192 for(size_t i = 0; i < dimTotal; ++i)
1194 newArray[i] = OCRepPayloadClone(array[i]);
1197 bool b = OCRepPayloadSetPropObjectArrayAsOwner(payload, name, newArray, dimensions);
1201 for(size_t i = 0; i < dimTotal; ++i)
1203 OCRepPayloadDestroy(newArray[i]);
1210 bool OCRepPayloadGetPropObjectArray(const OCRepPayload* payload, const char* name,
1211 OCRepPayload*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1213 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1215 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_OBJECT
1216 || !val->arr.objArray)
1221 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1226 *array = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
1232 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1234 for(size_t i = 0; i < dimTotal; ++i)
1236 (*array)[i] = OCRepPayloadClone(val->arr.objArray[i]);
1242 void OCFreeOCStringLL(OCStringLL* ll)
1249 OCFreeOCStringLL(ll->next);
1254 OCStringLL* CloneOCStringLL (OCStringLL* ll)
1261 OCStringLL *sourceIter = ll;
1263 OCStringLL *destIter = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
1268 destIter->value = OICStrdup (sourceIter->value);
1270 OCStringLL *headOfClone = destIter;
1272 sourceIter = sourceIter->next;
1276 destIter->next = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
1277 if (!destIter->next)
1279 OCFreeOCStringLL (headOfClone);
1282 destIter->next->value = OICStrdup (sourceIter->value);
1284 destIter = destIter->next;
1285 sourceIter = sourceIter->next;
1290 OCStringLL* OCCreateOCStringLL(const char* text)
1295 char *backup = NULL;
1296 OCStringLL* result = NULL;
1297 OCStringLL* iter = NULL;
1298 OCStringLL* prev = NULL;
1299 static const char delim[] = { CSV_SEPARATOR, '\0' };
1301 VERIFY_PARAM_NON_NULL(TAG, text, "Invalid parameter");
1302 backup = OICStrdup(text);
1303 VERIFY_PARAM_NON_NULL(TAG, backup, "Failed allocating memory");
1305 for (head = backup; ; head = NULL)
1307 token = (char *) strtok_r(head, delim, &tail);
1309 iter = (OCStringLL *)OICCalloc(1,sizeof(OCStringLL));
1310 VERIFY_PARAM_NON_NULL(TAG, iter, "Failed allocating memory");
1319 iter->value = OICStrdup(token);
1320 VERIFY_PARAM_NON_NULL(TAG, iter->value, "Failed allocating memory");
1329 OCFreeOCStringLL(result);
1333 char* OCCreateString(const OCStringLL* ll)
1341 if (!ll) return NULL;
1343 for (const OCStringLL *it = ll; it ; it = it->next )
1345 len += strlen(it->value) + 1;
1347 len--; // renove trailing separator (just added above)
1348 str = (char*) malloc(len + 1);
1353 const OCStringLL *it = ll;
1356 sublen = strlen(it->value);
1357 count = snprintf(pos, len + 1, "%s", it->value);
1369 *pos = CSV_SEPARATOR;
1378 OCRepPayload* OCRepPayloadClone (const OCRepPayload* payload)
1385 OCRepPayload *clone = OCRepPayloadCreate();
1392 clone->uri = OICStrdup (payload->uri);
1393 clone->types = CloneOCStringLL (payload->types);
1394 clone->interfaces = CloneOCStringLL (payload->interfaces);
1395 clone->values = OCRepPayloadValueClone (payload->values);
1401 void OCRepPayloadDestroy(OCRepPayload* payload)
1408 OICFree(payload->uri);
1409 OCFreeOCStringLL(payload->types);
1410 OCFreeOCStringLL(payload->interfaces);
1411 OCFreeRepPayloadValue(payload->values);
1412 OCRepPayloadDestroy(payload->next);
1416 OCDiscoveryPayload* OCDiscoveryPayloadCreate()
1418 OCDiscoveryPayload* payload = (OCDiscoveryPayload*)OICCalloc(1, sizeof(OCDiscoveryPayload));
1425 payload->base.type = PAYLOAD_TYPE_DISCOVERY;
1430 OCSecurityPayload* OCSecurityPayloadCreate(const uint8_t* securityData, size_t size)
1432 OCSecurityPayload* payload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1439 payload->base.type = PAYLOAD_TYPE_SECURITY;
1440 payload->securityData = (uint8_t *)OICCalloc(1, size);
1441 if (!payload->securityData)
1446 memcpy(payload->securityData, (uint8_t *)securityData, size);
1447 payload->payloadSize = size;
1452 void OCSecurityPayloadDestroy(OCSecurityPayload* payload)
1459 OICFree(payload->securityData);
1463 size_t OCDiscoveryPayloadGetResourceCount(OCDiscoveryPayload* payload)
1466 OCResourcePayload* p = payload->resources;
1475 OCResourcePayload* OCDiscoveryPayloadGetResource(OCDiscoveryPayload* payload, size_t index)
1478 OCResourcePayload* p = payload->resources;
1492 static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort)
1494 static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort,
1498 OCResourcePayload* pl = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1504 pl->uri = OICStrdup(res->uri);
1508 OCDiscoveryResourceDestroy(pl);
1513 OCResourceType* typePtr = res->rsrcType;
1515 if (typePtr != NULL)
1517 pl->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1520 OCDiscoveryResourceDestroy(pl);
1523 pl->types->value = OICStrdup(typePtr->resourcetypename);
1524 if (!pl->types->value)
1526 OCDiscoveryResourceDestroy(pl);
1530 OCStringLL* cur = pl->types;
1531 typePtr = typePtr->next;
1534 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1537 OCDiscoveryResourceDestroy(pl);
1540 cur->next->value = OICStrdup(typePtr->resourcetypename);
1541 if (!cur->next->value)
1543 OCDiscoveryResourceDestroy(pl);
1547 typePtr = typePtr->next;
1552 OCResourceInterface* ifPtr = res->rsrcInterface;
1555 pl->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1556 if (!pl->interfaces)
1558 OCDiscoveryResourceDestroy(pl);
1561 pl->interfaces->value = OICStrdup(ifPtr->name);
1562 if (!pl->interfaces->value)
1564 OCDiscoveryResourceDestroy(pl);
1568 OCStringLL* cur = pl->interfaces;
1569 ifPtr = ifPtr->next;
1572 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1575 OCDiscoveryResourceDestroy(pl);
1578 cur->next->value = OICStrdup(ifPtr->name);
1579 if (!cur->next->value)
1581 OCDiscoveryResourceDestroy(pl);
1585 ifPtr = ifPtr->next;
1589 pl->bitmap = res->resourceProperties & (OC_OBSERVABLE | OC_DISCOVERABLE
1594 pl->secure = (res->resourceProperties & OC_SECURE) != 0;
1595 pl->port = securePort;
1597 pl->tcpPort = tcpPort;
1603 void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
1604 uint16_t securePort)
1606 OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort));
1609 void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
1610 uint16_t securePort, uint16_t tcpPort)
1612 OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort, tcpPort));
1616 bool OCResourcePayloadAddStringLL(OCStringLL **stringLL, const char *value)
1618 char *dup = OICStrdup(value);
1619 VERIFY_PARAM_NON_NULL(TAG, dup, "Failed copying string");
1620 VERIFY_PARAM_NON_NULL(TAG, value, "Invalid Parameters");
1624 *stringLL = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
1625 VERIFY_PARAM_NON_NULL(TAG, *stringLL, "Failed allocating memory");
1626 (*stringLL)->value = dup;
1631 OCStringLL *temp = *stringLL;
1636 temp->next = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
1637 VERIFY_PARAM_NON_NULL(TAG, temp->next, "Failed allocating memory");
1638 temp->next->value = dup;
1646 void OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload, OCResourcePayload* res)
1653 if (!payload->resources)
1655 payload->resources = res;
1659 OCResourcePayload* p = payload->resources;
1668 void OCDiscoveryResourceDestroy(OCResourcePayload* payload)
1675 OICFree(payload->uri);
1676 OCFreeOCStringLL(payload->types);
1677 OCFreeOCStringLL(payload->interfaces);
1678 OCDiscoveryResourceDestroy(payload->next);
1682 void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload)
1688 OICFree(payload->sid);
1689 OICFree(payload->baseURI);
1690 OICFree(payload->uri);
1691 OCFreeOCStringLL(payload->type);
1692 OICFree(payload->name);
1693 OCFreeOCStringLL(payload->iface);
1694 OCDiscoveryResourceDestroy(payload->resources);
1695 OCDiscoveryPayloadDestroy(payload->next);
1699 OCDevicePayload* OCDevicePayloadCreate(const char* sid, const char* dname,
1700 const OCStringLL *types, const char* specVer, const char* dmVer)
1703 OCDevicePayload* payload = (OCDevicePayload*)OICCalloc(1, sizeof(OCDevicePayload));
1710 payload->base.type = PAYLOAD_TYPE_DEVICE;
1711 payload->sid = OICStrdup(sid);
1712 if (sid && !payload->sid)
1717 payload->deviceName = OICStrdup(dname);
1718 if (dname && !payload->deviceName)
1723 payload->specVersion = OICStrdup(specVer);
1724 if (specVer && !payload->specVersion)
1729 payload->dataModelVersions = OCCreateOCStringLL(dmVer);
1730 if (!payload->dataModelVersions || (dmVer && !payload->dataModelVersions->value))
1735 OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_DEFAULT);
1736 OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_READ);
1738 payload->types = CloneOCStringLL((OCStringLL *)types);
1739 if (types && !payload->types)
1747 OCDevicePayloadDestroy((OCDevicePayload*)payload);
1751 void OCDevicePayloadDestroy(OCDevicePayload* payload)
1758 OICFree(payload->sid);
1759 OICFree(payload->deviceName);
1760 OICFree(payload->specVersion);
1761 OCFreeOCStringLL(payload->dataModelVersions);
1762 OCFreeOCStringLL(payload->types);
1763 OCFreeOCStringLL(payload->interfaces);
1767 static void OCCopyPlatformInfo(const OCPlatformInfo* platformInfo, OCPlatformPayload* target)
1769 if (!platformInfo || !target)
1774 target->info.platformID = OICStrdup(platformInfo->platformID);
1775 target->info.manufacturerName = OICStrdup(platformInfo->manufacturerName);
1776 target->info.manufacturerUrl = OICStrdup(platformInfo->manufacturerUrl);
1777 target->info.modelNumber = OICStrdup(platformInfo->modelNumber);
1778 target->info.dateOfManufacture = OICStrdup(platformInfo->dateOfManufacture);
1779 target->info.platformVersion = OICStrdup(platformInfo->platformVersion);
1780 target->info.operatingSystemVersion = OICStrdup(platformInfo->operatingSystemVersion);
1781 target->info.hardwareVersion = OICStrdup(platformInfo->hardwareVersion);
1782 target->info.firmwareVersion = OICStrdup(platformInfo->firmwareVersion);
1783 target->info.supportUrl = OICStrdup(platformInfo->supportUrl);
1784 target->info.systemTime = OICStrdup(platformInfo->systemTime);
1787 OCPlatformPayload* OCPlatformPayloadCreateAsOwner(OCPlatformInfo* platformInfo)
1789 OCPlatformPayload* payload = (OCPlatformPayload*)OICCalloc(1, sizeof(OCPlatformPayload));
1795 payload->base.type = PAYLOAD_TYPE_PLATFORM;
1797 payload->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1798 if (!payload->interfaces)
1802 payload->interfaces->value = OICStrdup(OC_RSRVD_INTERFACE_READ);
1803 payload->rt = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1808 payload->rt->value = OICStrdup(OC_RSRVD_RESOURCE_TYPE_PLATFORM);
1809 payload->info = *platformInfo;
1814 OCPlatformPayload* OCPlatformPayloadCreate(const OCPlatformInfo* platformInfo)
1816 OCPlatformPayload* payload = (OCPlatformPayload*)OICCalloc(1, sizeof(OCPlatformPayload));
1823 payload->base.type = PAYLOAD_TYPE_PLATFORM;
1824 OCResourcePayloadAddStringLL(&payload->rt, OC_RSRVD_RESOURCE_TYPE_PLATFORM);
1826 OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_DEFAULT);
1827 OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_READ);
1829 OCCopyPlatformInfo(platformInfo, payload);
1834 void OCPlatformInfoDestroy(OCPlatformInfo *info)
1836 OICFree(info->platformID);
1837 OICFree(info->manufacturerName);
1838 OICFree(info->manufacturerUrl);
1839 OICFree(info->modelNumber);
1840 OICFree(info->dateOfManufacture);
1841 OICFree(info->platformVersion);
1842 OICFree(info->operatingSystemVersion);
1843 OICFree(info->hardwareVersion);
1844 OICFree(info->firmwareVersion);
1845 OICFree(info->supportUrl);
1846 OICFree(info->systemTime);
1849 void OCPlatformPayloadDestroy(OCPlatformPayload* payload)
1855 OICFree(payload->uri);
1856 OCPlatformInfoDestroy(&payload->info);
1857 OCFreeOCStringLL(payload->rt);
1858 OCFreeOCStringLL(payload->interfaces);
1862 OCPresencePayload* OCPresencePayloadCreate(uint32_t seqNum, uint32_t maxAge,
1863 OCPresenceTrigger trigger, const char* resourceType)
1865 OCPresencePayload* payload = (OCPresencePayload*)OICCalloc(1, sizeof(OCPresencePayload));
1871 payload->base.type = PAYLOAD_TYPE_PRESENCE;
1872 payload->sequenceNumber = seqNum;
1873 payload->maxAge = maxAge;
1874 payload->trigger = trigger;
1875 payload->resourceType = OICStrdup(resourceType);
1879 void OCPresencePayloadDestroy(OCPresencePayload* payload)
1885 OICFree(payload->resourceType);