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"
35 #if defined(__WITH_TLS__) || defined(__WITH_DTLS__)
36 #include "securevirtualresourcetypes.h"
39 #define TAG "OIC_RI_PAYLOAD"
40 #define CSV_SEPARATOR ','
42 static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val);
44 void OCPayloadDestroy(OCPayload* payload)
53 case PAYLOAD_TYPE_REPRESENTATION:
54 OCRepPayloadDestroy((OCRepPayload*)payload);
56 case PAYLOAD_TYPE_DISCOVERY:
57 OCDiscoveryPayloadDestroy((OCDiscoveryPayload*)payload);
60 case PAYLOAD_TYPE_PRESENCE:
61 OCPresencePayloadDestroy((OCPresencePayload*)payload);
64 case PAYLOAD_TYPE_SECURITY:
65 OCSecurityPayloadDestroy((OCSecurityPayload*)payload);
68 OIC_LOG_V(ERROR, TAG, "Unsupported payload type in destroy: %d", payload->type);
74 OCRepPayload* OCRepPayloadCreate()
76 OCRepPayload* payload = (OCRepPayload*)OICCalloc(1, sizeof(OCRepPayload));
83 payload->base.type = PAYLOAD_TYPE_REPRESENTATION;
88 void OCRepPayloadAppend(OCRepPayload* parent, OCRepPayload* child)
97 parent = parent->next;
104 static OCRepPayloadValue* OCRepPayloadFindValue(const OCRepPayload* payload, const char* name)
106 if (!payload || !name)
111 OCRepPayloadValue* val = payload->values;
114 if (0 == strcmp(val->name, name))
124 static void OCCopyPropertyValueArray(OCRepPayloadValue* dest, OCRepPayloadValue* source)
126 if (!dest || !source)
131 size_t dimTotal = calcDimTotal(source->arr.dimensions);
132 switch(source->arr.type)
135 dest->arr.iArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
136 VERIFY_PARAM_NON_NULL(TAG, dest->arr.iArray, "Failed allocating memory");
137 memcpy(dest->arr.iArray, source->arr.iArray, dimTotal * sizeof(int64_t));
139 case OCREP_PROP_DOUBLE:
140 dest->arr.dArray = (double*)OICMalloc(dimTotal * sizeof(double));
141 VERIFY_PARAM_NON_NULL(TAG, dest->arr.dArray, "Failed allocating memory");
142 memcpy(dest->arr.dArray, source->arr.dArray, dimTotal * sizeof(double));
144 case OCREP_PROP_BOOL:
145 dest->arr.bArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
146 VERIFY_PARAM_NON_NULL(TAG, dest->arr.bArray, "Failed allocating memory");
147 memcpy(dest->arr.bArray, source->arr.bArray, dimTotal * sizeof(bool));
149 case OCREP_PROP_STRING:
150 dest->arr.strArray = (char**)OICMalloc(dimTotal * sizeof(char*));
151 VERIFY_PARAM_NON_NULL(TAG, dest->arr.strArray, "Failed allocating memory");
152 for(size_t i = 0; i < dimTotal; ++i)
154 dest->arr.strArray[i] = OICStrdup(source->arr.strArray[i]);
157 case OCREP_PROP_OBJECT:
158 dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
159 VERIFY_PARAM_NON_NULL(TAG, dest->arr.objArray, "Failed allocating memory");
160 for(size_t i = 0; i < dimTotal; ++i)
162 dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
165 case OCREP_PROP_ARRAY:
166 dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
167 VERIFY_PARAM_NON_NULL(TAG, dest->arr.objArray, "Failed allocating memory");
168 for(size_t i = 0; i < dimTotal; ++i)
170 dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
173 case OCREP_PROP_BYTE_STRING:
174 dest->arr.ocByteStrArray = (OCByteString*)OICMalloc(dimTotal * sizeof(OCByteString));
175 VERIFY_PARAM_NON_NULL(TAG, dest->arr.ocByteStrArray, "Failed allocating memory");
176 for (size_t i = 0; i < dimTotal; ++i)
178 OCByteStringCopy(&dest->arr.ocByteStrArray[i], &source->arr.ocByteStrArray[i]);
179 VERIFY_PARAM_NON_NULL(TAG, dest->arr.ocByteStrArray[i].bytes, "Failed allocating memory");
183 OIC_LOG(ERROR, TAG, "CopyPropertyValueArray invalid type");
190 static void OCCopyPropertyValue (OCRepPayloadValue *dest, OCRepPayloadValue *source)
192 if (!source || !dest)
199 case OCREP_PROP_STRING:
200 dest->str = OICStrdup(source->str);
202 case OCREP_PROP_BYTE_STRING:
203 dest->ocByteStr.bytes = (uint8_t*)OICMalloc(source->ocByteStr.len * sizeof(uint8_t));
204 VERIFY_PARAM_NON_NULL(TAG, dest->ocByteStr.bytes, "Failed allocating memory");
205 dest->ocByteStr.len = source->ocByteStr.len;
206 memcpy(dest->ocByteStr.bytes, source->ocByteStr.bytes, dest->ocByteStr.len);
208 case OCREP_PROP_OBJECT:
209 dest->obj = OCRepPayloadClone(source->obj);
211 case OCREP_PROP_ARRAY:
212 OCCopyPropertyValueArray(dest, source);
215 // Nothing to do for the trivially copyable types.
222 static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val)
229 if (val->type == OCREP_PROP_STRING)
231 if (val->str != NULL)
236 else if (val->type == OCREP_PROP_BYTE_STRING)
238 OICFree(val->ocByteStr.bytes);
240 else if (val->type == OCREP_PROP_OBJECT)
242 OCRepPayloadDestroy(val->obj);
244 else if (val->type == OCREP_PROP_ARRAY)
246 size_t dimTotal = calcDimTotal(val->arr.dimensions);
247 switch(val->arr.type)
250 case OCREP_PROP_DOUBLE:
251 case OCREP_PROP_BOOL:
252 // Since this is a union, iArray will
253 // point to all of the above
254 OICFree(val->arr.iArray);
256 case OCREP_PROP_STRING:
257 if (val->arr.strArray != NULL)
259 for(size_t i = 0; i < dimTotal; ++i)
261 OICFree(val->arr.strArray[i]);
263 OICFree(val->arr.strArray);
266 case OCREP_PROP_BYTE_STRING:
267 if (val->arr.ocByteStrArray != NULL)
269 for (size_t i = 0; i < dimTotal; ++i)
271 if (val->arr.ocByteStrArray[i].bytes)
273 OICFree(val->arr.ocByteStrArray[i].bytes);
276 OICFree(val->arr.ocByteStrArray);
279 case OCREP_PROP_OBJECT: // This case is the temporary fix for string input
280 if (val->arr.objArray != NULL)
282 for(size_t i = 0; i< dimTotal; ++i)
284 OCRepPayloadDestroy(val->arr.objArray[i]);
286 OICFree(val->arr.objArray);
289 case OCREP_PROP_NULL:
290 case OCREP_PROP_ARRAY:
291 OIC_LOG_V(ERROR, TAG, "FreeRepPayloadValueContents: Illegal type\
292 inside an array: %d", val->arr.type);
298 static void OCFreeRepPayloadValue(OCRepPayloadValue* val)
306 OCFreeRepPayloadValueContents(val);
307 OCFreeRepPayloadValue(val->next);
310 static OCRepPayloadValue* OCRepPayloadValueClone (OCRepPayloadValue* source)
317 OCRepPayloadValue *sourceIter = source;
318 OCRepPayloadValue *destIter = (OCRepPayloadValue*) OICCalloc(1, sizeof(OCRepPayloadValue));
324 OCRepPayloadValue *headOfClone = destIter;
326 // Copy payload type and non pointer types in union.
327 *destIter = *sourceIter;
328 destIter->name = OICStrdup (sourceIter->name);
329 OCCopyPropertyValue (destIter, sourceIter);
331 sourceIter = sourceIter->next;
335 destIter->next = (OCRepPayloadValue*) OICCalloc(1, sizeof(OCRepPayloadValue));
338 OCFreeRepPayloadValue (headOfClone);
342 *(destIter->next) = *sourceIter;
343 destIter->next->name = OICStrdup (sourceIter->name);
344 OCCopyPropertyValue (destIter->next, sourceIter);
346 sourceIter = sourceIter->next;
347 destIter = destIter->next;
352 static OCRepPayloadValue* OCRepPayloadFindAndSetValue(OCRepPayload* payload, const char* name,
353 OCRepPayloadPropType type)
355 if (!payload || !name)
360 OCRepPayloadValue* val = payload->values;
363 payload->values = (OCRepPayloadValue*)OICCalloc(1, sizeof(OCRepPayloadValue));
364 if (!payload->values)
368 payload->values->name = OICStrdup(name);
369 if (!payload->values->name)
371 OICFree(payload->values);
372 payload->values = NULL;
375 payload->values->type =type;
376 return payload->values;
381 if (0 == strcmp(val->name, name))
383 OCFreeRepPayloadValueContents(val);
387 else if (val->next == NULL)
389 val->next = (OCRepPayloadValue*)OICCalloc(1, sizeof(OCRepPayloadValue));
394 val->next->name = OICStrdup(name);
395 if (!val->next->name)
401 val->next->type =type;
408 OIC_LOG(ERROR, TAG, "FindAndSetValue reached point after while loop, pointer corruption?");
412 bool OCRepPayloadAddResourceType(OCRepPayload* payload, const char* resourceType)
414 return OCRepPayloadAddResourceTypeAsOwner(payload, OICStrdup(resourceType));
417 bool OCRepPayloadAddResourceTypeAsOwner(OCRepPayload* payload, char* resourceType)
419 if (!payload || !resourceType)
426 OCStringLL* cur = payload->types;
431 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
438 cur->next->value = resourceType;
443 payload->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
448 payload->types->value = resourceType;
453 bool OCRepPayloadAddInterface(OCRepPayload* payload, const char* iface)
455 return OCRepPayloadAddInterfaceAsOwner(payload, OICStrdup(iface));
458 bool OCRepPayloadAddInterfaceAsOwner(OCRepPayload* payload, char* iface)
460 if (!payload || !iface)
465 if (payload->interfaces)
467 OCStringLL* cur = payload->interfaces;
472 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
478 cur->next->value = iface;
483 payload->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
484 if (!payload->interfaces)
488 payload->interfaces->value = iface;
493 bool OCRepPayloadSetUri(OCRepPayload* payload, const char* uri)
499 OICFree(payload->uri);
500 payload->uri = OICStrdup(uri);
501 return payload->uri != NULL;
504 bool OCRepPayloadIsNull(const OCRepPayload* payload, const char* name)
506 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
513 return val->type == OCREP_PROP_NULL;
516 static bool OCRepPayloadSetProp(OCRepPayload* payload, const char* name,
517 void* value, OCRepPayloadPropType type)
519 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, type);
527 val->i = *(int64_t*)value;
529 case OCREP_PROP_DOUBLE:
530 val->d = *(double*)value;
532 case OCREP_PROP_BOOL:
533 val->b = *(bool*)value;
535 case OCREP_PROP_OBJECT:
536 val->obj = (OCRepPayload*)value;
538 case OCREP_PROP_STRING:
539 val->str = (char*)value;
540 return val->str != NULL;
541 case OCREP_PROP_BYTE_STRING:
542 val->ocByteStr = *(OCByteString*)value;
543 return val->ocByteStr.bytes != NULL;
545 case OCREP_PROP_NULL:
547 case OCREP_PROP_ARRAY:
555 bool OCRepPayloadSetNull(OCRepPayload* payload, const char* name)
557 return OCRepPayloadSetProp(payload, name, NULL, OCREP_PROP_NULL);
560 bool OCRepPayloadSetPropInt(OCRepPayload* payload,
561 const char* name, int64_t value)
563 return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_INT);
566 bool OCRepPayloadGetPropInt(const OCRepPayload* payload, const char* name, int64_t* value)
568 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
570 if (!val || val->type != OCREP_PROP_INT)
579 bool OCRepPayloadSetPropDouble(OCRepPayload* payload,
580 const char* name, double value)
582 return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_DOUBLE);
585 bool OCRepPayloadGetPropDouble(const OCRepPayload* payload, const char* name, double* value)
587 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
591 if (val->type == OCREP_PROP_DOUBLE)
596 else if (val->type == OCREP_PROP_INT)
606 bool OCRepPayloadSetPropString(OCRepPayload* payload, const char* name, const char* value)
608 char* temp = OICStrdup(value);
609 bool b = OCRepPayloadSetPropStringAsOwner(payload, name, temp);
618 bool OCRepPayloadSetPropStringAsOwner(OCRepPayload* payload, const char* name, char* value)
620 return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_STRING);
623 bool OCRepPayloadGetPropString(const OCRepPayload* payload, const char* name, char** value)
625 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
627 if (!val || val->type != OCREP_PROP_STRING)
632 *value = OICStrdup(val->str);
633 return *value != NULL;
636 bool OCRepPayloadSetPropByteString(OCRepPayload* payload, const char* name, OCByteString value)
638 if (!value.bytes || !value.len)
643 OCByteString ocByteStr = {NULL, 0};
644 bool b = OCByteStringCopy(&ocByteStr, &value);
648 b = OCRepPayloadSetPropByteStringAsOwner(payload, name, &ocByteStr);
652 OICFree(ocByteStr.bytes);
657 bool OCRepPayloadSetPropByteStringAsOwner(OCRepPayload* payload, const char* name, OCByteString* value)
659 return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_BYTE_STRING);
662 bool OCRepPayloadGetPropByteString(const OCRepPayload* payload, const char* name, OCByteString* value)
664 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
666 if (!val || val->type != OCREP_PROP_BYTE_STRING)
676 value->bytes = (uint8_t*)OICMalloc(val->ocByteStr.len * sizeof(uint8_t));
681 value->len = val->ocByteStr.len;
682 memcpy(value->bytes, val->ocByteStr.bytes, value->len);
687 bool OCRepPayloadSetPropBool(OCRepPayload* payload,
688 const char* name, bool value)
690 return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_BOOL);
693 bool OCRepPayloadGetPropBool(const OCRepPayload* payload, const char* name, bool* value)
695 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
697 if (!val || val->type != OCREP_PROP_BOOL)
707 static char *getStringFromEncodingType(OicEncodingType_t type)
712 case OIC_ENCODING_BASE64: str = OC_RSRVD_BASE64; break;
713 case OIC_ENCODING_DER: str = OC_RSRVD_DER; break;
714 case OIC_ENCODING_PEM: str = OC_RSRVD_PEM; break;
715 case OIC_ENCODING_RAW: str = OC_RSRVD_RAW; break;
716 default: str = OC_RSRVD_UNKNOWN; break;
719 snprintf(encoding, sizeof(encoding), "%s.%s.%s", OC_OIC_SEC, OC_RSRVD_ENCODING, str);
721 return OICStrdup(encoding);
724 bool OCRepPayloadSetPropPubDataTypeAsOwner(OCRepPayload *payload, const char *name,
725 const OicSecKey_t *value)
727 if (!payload || !name || !value)
732 bool binary_field = false;
733 if (OIC_ENCODING_RAW == value->encoding || OIC_ENCODING_DER == value->encoding)
738 OCRepPayload *heplerPayload = OCRepPayloadCreate();
744 char *encoding = getStringFromEncodingType(value->encoding);
745 if (!OCRepPayloadSetPropString(heplerPayload, OC_RSRVD_ENCODING, encoding))
747 OIC_LOG_V(ERROR, TAG, "Can't set %s", OC_RSRVD_ENCODING);
750 OCByteString val = {.bytes = value->data, .len = value->len};
753 if (!OCRepPayloadSetPropByteString(heplerPayload, OC_RSRVD_DATA, val))
755 OIC_LOG_V(ERROR, TAG, "Can't set %s", OC_RSRVD_DATA);
760 if (!OCRepPayloadSetPropString(heplerPayload, OC_RSRVD_DATA, (char *)val.bytes))
762 OIC_LOG_V(ERROR, TAG, "Can't set %s", OC_RSRVD_DATA);
766 if (!OCRepPayloadSetPropObject(payload, name, (const OCRepPayload *)heplerPayload))
768 OIC_LOG_V(ERROR, TAG, "Can't set %s", name);
771 OCRepPayloadDestroy(heplerPayload);
777 bool OCRepPayloadSetPropPubDataType(OCRepPayload *payload, const char *name,
778 const OicSecKey_t *value)
780 return OCRepPayloadSetPropPubDataTypeAsOwner(payload, name, value);
783 static OicEncodingType_t getEncodingTypeFromString(char *encoding)
785 OicEncodingType_t type = OIC_ENCODING_UNKNOW;
787 char *str = strrchr(encoding, '.');
790 OIC_LOG_V(ERROR, TAG, "Can't find . in %s", encoding);
793 str++; //go to encoding itself
795 if (0 == strcmp(str, OC_RSRVD_BASE64)) type = OIC_ENCODING_BASE64;
796 else if (0 == strcmp(str, OC_RSRVD_DER)) type = OIC_ENCODING_DER;
797 else if (0 == strcmp(str, OC_RSRVD_PEM)) type = OIC_ENCODING_PEM;
798 else if (0 == strcmp(str, OC_RSRVD_RAW)) type = OIC_ENCODING_RAW;
803 bool OCRepPayloadGetPropPubDataType(const OCRepPayload *payload, const char *name, OicSecKey_t *value)
805 OCRepPayload *heplerPayload = NULL;
806 char *encoding = NULL;
809 if (!payload || !name || !value)
814 if (!OCRepPayloadGetPropObject(payload, name, &heplerPayload))
816 OIC_LOG_V(ERROR, TAG, "Can't get object with name %s", name);
820 if (!OCRepPayloadGetPropString(heplerPayload, OC_RSRVD_ENCODING, &encoding))
822 OIC_LOG_V(ERROR, TAG, "Can't get %s", OC_RSRVD_ENCODING);
826 value->encoding = getEncodingTypeFromString(encoding);
830 if (!OCRepPayloadGetPropByteString(heplerPayload, OC_RSRVD_DATA, &val))
832 if (!OCRepPayloadGetPropString(heplerPayload, OC_RSRVD_DATA, (char **)&val.bytes))
834 OIC_LOG_V(ERROR, TAG, "Can't get: %s", OC_RSRVD_DATA);
838 value->data = val.bytes;
839 value->len = strlen((char *)val.bytes);
844 value->data = val.bytes;
845 value->len = val.len;
848 OCRepPayloadDestroy(heplerPayload);
853 bool OCRepPayloadSetPropObject(OCRepPayload* payload, const char* name, const OCRepPayload* value)
855 OCRepPayload* temp = OCRepPayloadClone(value);
856 bool b = OCRepPayloadSetPropObjectAsOwner(payload, name, temp);
860 OCRepPayloadDestroy(temp);
865 bool OCRepPayloadSetPropObjectAsOwner(OCRepPayload* payload, const char* name, OCRepPayload* value)
867 return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_OBJECT);
870 bool OCRepPayloadGetPropObject(const OCRepPayload* payload, const char* name, OCRepPayload** value)
872 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
874 if (!val || val->type != OCREP_PROP_OBJECT)
879 *value = OCRepPayloadClone(val->obj);
880 return *value != NULL;
883 size_t calcDimTotal(const size_t dimensions[MAX_REP_ARRAY_DEPTH])
885 if (dimensions[0] == 0)
891 for(uint8_t i = 0; i < MAX_REP_ARRAY_DEPTH && dimensions[i] != 0; ++i)
893 total *= dimensions[i];
899 bool OCRepPayloadSetByteStringArrayAsOwner(OCRepPayload* payload, const char* name,
900 OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
902 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
909 val->arr.type = OCREP_PROP_BYTE_STRING;
910 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
911 val->arr.ocByteStrArray = array;
916 bool OCRepPayloadSetByteStringArray(OCRepPayload* payload, const char* name,
917 const OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
924 size_t dimTotal = calcDimTotal(dimensions);
930 OCByteString* newArray = (OCByteString*)OICCalloc(dimTotal, sizeof(OCByteString));
937 for (size_t i = 0; i < dimTotal; ++i)
939 newArray[i].bytes = (uint8_t*)OICMalloc(array[i].len * sizeof(uint8_t));
940 if (NULL == newArray[i].bytes)
942 for (size_t j = 0; j < i; ++j)
944 OICFree(newArray[j].bytes);
950 newArray[i].len = array[i].len;
951 memcpy(newArray[i].bytes, array[i].bytes, newArray[i].len);
954 bool b = OCRepPayloadSetByteStringArrayAsOwner(payload, name, newArray, dimensions);
957 for (size_t i = 0; i < dimTotal; ++i)
959 OICFree(newArray[i].bytes);
967 bool OCRepPayloadGetByteStringArray(const OCRepPayload* payload, const char* name,
968 OCByteString** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
970 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
972 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_BYTE_STRING
973 || !val->arr.ocByteStrArray)
978 size_t dimTotal = calcDimTotal(val->arr.dimensions);
984 *array = (OCByteString*)OICCalloc(dimTotal, sizeof(OCByteString));
990 for (size_t i = 0; i < dimTotal; ++i)
992 OCByteString* tmp = &(*array)[i];
993 tmp->bytes = (uint8_t*)OICMalloc(val->arr.ocByteStrArray[i].len * sizeof(uint8_t));
994 if (NULL == tmp->bytes)
996 for (size_t j = 0; j < i; ++j)
998 OCByteString* tmp = &(*array)[j];
1006 tmp->len = val->arr.ocByteStrArray[i].len;
1007 memcpy(tmp->bytes, val->arr.ocByteStrArray[i].bytes, tmp->len);
1010 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1015 bool OCRepPayloadSetIntArrayAsOwner(OCRepPayload* payload, const char* name,
1016 int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1018 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1025 val->arr.type = OCREP_PROP_INT;
1026 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1027 val->arr.iArray = array;
1032 bool OCRepPayloadSetIntArray(OCRepPayload* payload, const char* name,
1033 const int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1035 size_t dimTotal = calcDimTotal(dimensions);
1041 int64_t* newArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
1048 memcpy(newArray, array, dimTotal * sizeof(int64_t));
1051 bool b = OCRepPayloadSetIntArrayAsOwner(payload, name, newArray, dimensions);
1059 bool OCRepPayloadGetIntArray(const OCRepPayload* payload, const char* name,
1060 int64_t** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1062 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1064 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_INT
1065 || !val->arr.iArray)
1070 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1075 *array = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
1081 memcpy(*array, val->arr.iArray, dimTotal * sizeof(int64_t));
1082 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1086 bool OCRepPayloadSetDoubleArrayAsOwner(OCRepPayload* payload, const char* name,
1087 double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1089 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1096 val->arr.type = OCREP_PROP_DOUBLE;
1097 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1098 val->arr.dArray = array;
1102 bool OCRepPayloadSetDoubleArray(OCRepPayload* payload, const char* name,
1103 const double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1105 size_t dimTotal = calcDimTotal(dimensions);
1111 double* newArray = (double*)OICMalloc(dimTotal * sizeof(double));
1118 memcpy(newArray, array, dimTotal * sizeof(double));
1120 bool b = OCRepPayloadSetDoubleArrayAsOwner(payload, name, newArray, dimensions);
1128 bool OCRepPayloadGetDoubleArray(const OCRepPayload* payload, const char* name,
1129 double** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1131 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1133 if (!val || val->type != OCREP_PROP_ARRAY ||
1134 (val->arr.type != OCREP_PROP_DOUBLE && val->arr.type != OCREP_PROP_INT)
1135 || !val->arr.dArray)
1140 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1145 *array = (double*)OICMalloc(dimTotal * sizeof(double));
1151 if (val->arr.type == OCREP_PROP_DOUBLE)
1153 memcpy(*array, val->arr.dArray, dimTotal * sizeof(double));
1157 /* need to convert from integer */
1159 for ( ; n < dimTotal; ++n)
1161 (*array)[n] = val->arr.iArray[n];
1164 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1168 bool OCRepPayloadSetStringArrayAsOwner(OCRepPayload* payload, const char* name,
1169 char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1171 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1178 val->arr.type = OCREP_PROP_STRING;
1179 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1180 val->arr.strArray = array;
1184 bool OCRepPayloadSetStringArray(OCRepPayload* payload, const char* name,
1185 const char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1187 size_t dimTotal = calcDimTotal(dimensions);
1193 char** newArray = (char**)OICMalloc(dimTotal * sizeof(char*));
1200 for(size_t i = 0; i < dimTotal; ++i)
1202 newArray[i] = OICStrdup(array[i]);
1205 bool b = OCRepPayloadSetStringArrayAsOwner(payload, name, newArray, dimensions);
1209 for(size_t i = 0; i < dimTotal; ++i)
1211 OICFree(newArray[i]);
1218 bool OCRepPayloadGetStringArray(const OCRepPayload* payload, const char* name,
1219 char*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1221 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1223 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_STRING
1224 || !val->arr.strArray)
1229 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1234 *array = (char**)OICMalloc(dimTotal * sizeof(char*));
1240 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1242 for(size_t i = 0; i < dimTotal; ++i)
1244 (*array)[i] = OICStrdup(val->arr.strArray[i]);
1251 bool OCRepPayloadSetBoolArrayAsOwner(OCRepPayload* payload, const char* name,
1252 bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1255 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1262 val->arr.type = OCREP_PROP_BOOL;
1263 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1264 val->arr.bArray = array;
1268 bool OCRepPayloadSetBoolArray(OCRepPayload* payload, const char* name,
1269 const bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1271 size_t dimTotal = calcDimTotal(dimensions);
1277 bool* newArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
1284 memcpy(newArray, array, dimTotal * sizeof(bool));
1287 bool b = OCRepPayloadSetBoolArrayAsOwner(payload, name, newArray, dimensions);
1295 bool OCRepPayloadGetBoolArray(const OCRepPayload* payload, const char* name,
1296 bool** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1298 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1300 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_BOOL
1301 || !val->arr.bArray)
1306 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1311 *array = (bool*)OICMalloc(dimTotal * sizeof(bool));
1317 memcpy(*array, val->arr.bArray, dimTotal * sizeof(bool));
1318 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1322 bool OCRepPayloadSetPropObjectArrayAsOwner(OCRepPayload* payload, const char* name,
1323 OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1325 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1332 val->arr.type = OCREP_PROP_OBJECT;
1333 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1334 val->arr.objArray = array;
1339 bool OCRepPayloadSetPropObjectArray(OCRepPayload* payload, const char* name,
1340 const OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1342 size_t dimTotal = calcDimTotal(dimensions);
1348 OCRepPayload** newArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
1355 for(size_t i = 0; i < dimTotal; ++i)
1357 newArray[i] = OCRepPayloadClone(array[i]);
1360 bool b = OCRepPayloadSetPropObjectArrayAsOwner(payload, name, newArray, dimensions);
1364 for(size_t i = 0; i < dimTotal; ++i)
1366 OCRepPayloadDestroy(newArray[i]);
1373 bool OCRepPayloadGetPropObjectArray(const OCRepPayload* payload, const char* name,
1374 OCRepPayload*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1376 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1378 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_OBJECT
1379 || !val->arr.objArray)
1384 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1389 *array = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
1395 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1397 for(size_t i = 0; i < dimTotal; ++i)
1399 (*array)[i] = OCRepPayloadClone(val->arr.objArray[i]);
1405 void OCFreeOCStringLL(OCStringLL* ll)
1412 OCFreeOCStringLL(ll->next);
1417 OCStringLL* CloneOCStringLL (OCStringLL* ll)
1424 OCStringLL *sourceIter = ll;
1426 OCStringLL *destIter = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
1431 destIter->value = OICStrdup (sourceIter->value);
1433 OCStringLL *headOfClone = destIter;
1435 sourceIter = sourceIter->next;
1439 destIter->next = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
1440 if (!destIter->next)
1442 OCFreeOCStringLL (headOfClone);
1445 destIter->next->value = OICStrdup (sourceIter->value);
1447 destIter = destIter->next;
1448 sourceIter = sourceIter->next;
1453 OCStringLL* OCCreateOCStringLL(const char* text)
1458 char *backup = NULL;
1459 OCStringLL* result = NULL;
1460 OCStringLL* iter = NULL;
1461 OCStringLL* prev = NULL;
1462 static const char delim[] = { CSV_SEPARATOR, '\0' };
1464 VERIFY_PARAM_NON_NULL(TAG, text, "Invalid parameter");
1465 backup = OICStrdup(text);
1466 VERIFY_PARAM_NON_NULL(TAG, backup, "Failed allocating memory");
1468 for (head = backup; ; head = NULL)
1470 token = (char *) strtok_r(head, delim, &tail);
1475 iter = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
1476 VERIFY_PARAM_NON_NULL(TAG, iter, "Failed allocating memory");
1485 iter->value = OICStrdup(token);
1486 VERIFY_PARAM_NON_NULL(TAG, iter->value, "Failed allocating memory");
1494 OCFreeOCStringLL(result);
1498 char* OCCreateString(const OCStringLL* ll)
1511 for (const OCStringLL *it = ll; it; it = it->next)
1513 len += strlen(it->value) + 1;
1515 len--; // remove trailing separator (just added above)
1516 str = (char*) OICMalloc(len + 1);
1523 const OCStringLL *it = ll;
1526 sublen = strlen(it->value);
1527 count = snprintf(pos, len + 1, "%s", it->value);
1528 if ((size_t)count < sublen)
1539 *pos = CSV_SEPARATOR;
1548 bool OCByteStringCopy(OCByteString* dest, const OCByteString* source)
1550 VERIFY_PARAM_NON_NULL(TAG, source, "Bad input");
1554 dest = (OCByteString *)OICMalloc(sizeof(OCByteString));
1555 VERIFY_PARAM_NON_NULL(TAG, dest, "Failed allocating memory");
1559 OICFree(dest->bytes);
1561 dest->bytes = (uint8_t*)OICMalloc(source->len * sizeof(uint8_t));
1562 VERIFY_PARAM_NON_NULL(TAG, dest->bytes, "Failed allocating memory");
1563 memcpy(dest->bytes, source->bytes, source->len * sizeof(uint8_t));
1564 dest->len = source->len;
1571 OICFree(dest->bytes);
1578 OCRepPayload* OCRepPayloadClone (const OCRepPayload* payload)
1585 OCRepPayload *clone = OCRepPayloadCreate();
1592 clone->uri = OICStrdup (payload->uri);
1593 clone->types = CloneOCStringLL (payload->types);
1594 clone->interfaces = CloneOCStringLL (payload->interfaces);
1595 clone->values = OCRepPayloadValueClone (payload->values);
1600 OCRepPayload* OCRepPayloadBatchClone(const OCRepPayload* repPayload)
1602 OCRepPayload *newPayload = OCRepPayloadCreate();
1608 newPayload->uri = OICStrdup(repPayload->uri);
1609 OCRepPayload *clone = OCRepPayloadCreate();
1612 OCPayloadDestroy((OCPayload *)newPayload);
1616 clone->types = CloneOCStringLL(repPayload->types);
1617 clone->interfaces = CloneOCStringLL(repPayload->interfaces);
1618 clone->values = OCRepPayloadValueClone(repPayload->values);
1619 OCRepPayloadSetPropObjectAsOwner(newPayload, OC_RSRVD_REPRESENTATION, clone);
1624 void OCRepPayloadDestroy(OCRepPayload* payload)
1631 OICFree(payload->uri);
1632 OCFreeOCStringLL(payload->types);
1633 OCFreeOCStringLL(payload->interfaces);
1634 OCFreeRepPayloadValue(payload->values);
1635 OCRepPayloadDestroy(payload->next);
1639 OCDiscoveryPayload* OCDiscoveryPayloadCreate()
1641 OCDiscoveryPayload* payload = (OCDiscoveryPayload*)OICCalloc(1, sizeof(OCDiscoveryPayload));
1648 payload->base.type = PAYLOAD_TYPE_DISCOVERY;
1653 OCSecurityPayload* OCSecurityPayloadCreate(const uint8_t* securityData, size_t size)
1655 OCSecurityPayload* payload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1662 payload->base.type = PAYLOAD_TYPE_SECURITY;
1663 payload->securityData = (uint8_t *)OICCalloc(1, size);
1664 if (!payload->securityData)
1669 memcpy(payload->securityData, (uint8_t *)securityData, size);
1670 payload->payloadSize = size;
1675 void OCSecurityPayloadDestroy(OCSecurityPayload* payload)
1682 OICClearMemory(payload->securityData, payload->payloadSize);
1683 OICFree(payload->securityData);
1687 size_t OCDiscoveryPayloadGetResourceCount(OCDiscoveryPayload* payload)
1690 OCResourcePayload* p = payload->resources;
1699 OCResourcePayload* OCDiscoveryPayloadGetResource(OCDiscoveryPayload* payload, size_t index)
1702 OCResourcePayload* p = payload->resources;
1715 #if !defined(TCP_ADAPTER) || defined(DISABLE_TCP_SERVER)
1716 static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort)
1718 static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort,
1722 OCResourcePayload* pl = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1728 pl->uri = OICStrdup(res->uri);
1732 OCDiscoveryResourceDestroy(pl);
1737 OCResourceType* typePtr = res->rsrcType;
1739 if (typePtr != NULL)
1741 pl->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1744 OCDiscoveryResourceDestroy(pl);
1747 pl->types->value = OICStrdup(typePtr->resourcetypename);
1748 if (!pl->types->value)
1750 OCDiscoveryResourceDestroy(pl);
1754 OCStringLL* cur = pl->types;
1755 typePtr = typePtr->next;
1758 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1761 OCDiscoveryResourceDestroy(pl);
1764 cur->next->value = OICStrdup(typePtr->resourcetypename);
1765 if (!cur->next->value)
1767 OCDiscoveryResourceDestroy(pl);
1771 typePtr = typePtr->next;
1776 OCResourceInterface* ifPtr = res->rsrcInterface;
1779 pl->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1780 if (!pl->interfaces)
1782 OCDiscoveryResourceDestroy(pl);
1785 pl->interfaces->value = OICStrdup(ifPtr->name);
1786 if (!pl->interfaces->value)
1788 OCDiscoveryResourceDestroy(pl);
1792 OCStringLL* cur = pl->interfaces;
1793 ifPtr = ifPtr->next;
1796 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1799 OCDiscoveryResourceDestroy(pl);
1802 cur->next->value = OICStrdup(ifPtr->name);
1803 if (!cur->next->value)
1805 OCDiscoveryResourceDestroy(pl);
1809 ifPtr = ifPtr->next;
1813 pl->bitmap = res->resourceProperties & (OC_OBSERVABLE | OC_DISCOVERABLE
1818 pl->secure = (res->resourceProperties & OC_SECURE) != 0;
1819 pl->port = securePort;
1820 #if defined(TCP_ADAPTER) && !defined(DISABLE_TCP_SERVER)
1821 pl->tcpPort = tcpPort;
1826 #if !defined(TCP_ADAPTER) || defined(DISABLE_TCP_SERVER)
1827 void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
1828 uint16_t securePort)
1830 OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort));
1833 void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
1834 uint16_t securePort, uint16_t tcpPort)
1836 OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort, tcpPort));
1840 bool OCResourcePayloadAddStringLL(OCStringLL **stringLL, const char *value)
1843 VERIFY_PARAM_NON_NULL(TAG, value, "Invalid Parameters");
1844 dup = OICStrdup(value);
1845 VERIFY_PARAM_NON_NULL(TAG, dup, "Failed copying string");
1849 *stringLL = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
1850 VERIFY_PARAM_NON_NULL(TAG, *stringLL, "Failed allocating memory");
1851 (*stringLL)->value = dup;
1856 OCStringLL *temp = *stringLL;
1861 temp->next = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
1862 VERIFY_PARAM_NON_NULL(TAG, temp->next, "Failed allocating memory");
1863 temp->next->value = dup;
1871 void OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload, OCResourcePayload* res)
1878 if (!payload->resources)
1880 payload->resources = res;
1884 OCResourcePayload* p = payload->resources;
1893 void OCDiscoveryResourceDestroy(OCResourcePayload* payload)
1900 OICFree(payload->uri);
1901 OCFreeOCStringLL(payload->types);
1902 OCFreeOCStringLL(payload->interfaces);
1903 OCDiscoveryResourceDestroy(payload->next);
1907 void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload)
1913 OICFree(payload->sid);
1914 OICFree(payload->baseURI);
1915 OCFreeOCStringLL(payload->type);
1916 OICFree(payload->name);
1917 OCFreeOCStringLL(payload->iface);
1918 OCDiscoveryResourceDestroy(payload->resources);
1919 OCDiscoveryPayloadDestroy(payload->next);
1923 #ifdef WITH_PRESENCE
1924 OCPresencePayload* OCPresencePayloadCreate(uint32_t seqNum, uint32_t maxAge,
1925 OCPresenceTrigger trigger, const char* resourceType)
1927 OCPresencePayload* payload = (OCPresencePayload*)OICCalloc(1, sizeof(OCPresencePayload));
1933 payload->base.type = PAYLOAD_TYPE_PRESENCE;
1934 payload->sequenceNumber = seqNum;
1935 payload->maxAge = maxAge;
1936 payload->trigger = trigger;
1937 payload->resourceType = OICStrdup(resourceType);
1941 void OCPresencePayloadDestroy(OCPresencePayload* payload)
1947 OICFree(payload->resourceType);
1950 #endif // WITH_PRESENCE