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 #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_PRESENCE:
56 OCPresencePayloadDestroy((OCPresencePayload*)payload);
58 case PAYLOAD_TYPE_SECURITY:
59 OCSecurityPayloadDestroy((OCSecurityPayload*)payload);
62 OIC_LOG_V(ERROR, TAG, "Unsupported payload type in destroy: %d", payload->type);
68 OCRepPayload* OCRepPayloadCreate()
70 OCRepPayload* payload = (OCRepPayload*)OICCalloc(1, sizeof(OCRepPayload));
77 payload->base.type = PAYLOAD_TYPE_REPRESENTATION;
82 void OCRepPayloadAppend(OCRepPayload* parent, OCRepPayload* child)
91 parent = parent->next;
98 static OCRepPayloadValue* OCRepPayloadFindValue(const OCRepPayload* payload, const char* name)
100 if (!payload || !name)
105 OCRepPayloadValue* val = payload->values;
108 if (0 == strcmp(val->name, name))
118 static void OCCopyPropertyValueArray(OCRepPayloadValue* dest, OCRepPayloadValue* source)
120 if (!dest || !source)
125 size_t dimTotal = calcDimTotal(source->arr.dimensions);
126 switch(source->arr.type)
129 dest->arr.iArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
130 VERIFY_PARAM_NON_NULL(TAG, dest->arr.iArray, "Failed allocating memory");
131 memcpy(dest->arr.iArray, source->arr.iArray, dimTotal * sizeof(int64_t));
133 case OCREP_PROP_DOUBLE:
134 dest->arr.dArray = (double*)OICMalloc(dimTotal * sizeof(double));
135 VERIFY_PARAM_NON_NULL(TAG, dest->arr.dArray, "Failed allocating memory");
136 memcpy(dest->arr.dArray, source->arr.dArray, dimTotal * sizeof(double));
138 case OCREP_PROP_BOOL:
139 dest->arr.bArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
140 VERIFY_PARAM_NON_NULL(TAG, dest->arr.bArray, "Failed allocating memory");
141 memcpy(dest->arr.bArray, source->arr.bArray, dimTotal * sizeof(bool));
143 case OCREP_PROP_STRING:
144 dest->arr.strArray = (char**)OICMalloc(dimTotal * sizeof(char*));
145 VERIFY_PARAM_NON_NULL(TAG, dest->arr.strArray, "Failed allocating memory");
146 for(size_t i = 0; i < dimTotal; ++i)
148 dest->arr.strArray[i] = OICStrdup(source->arr.strArray[i]);
151 case OCREP_PROP_OBJECT:
152 dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
153 VERIFY_PARAM_NON_NULL(TAG, dest->arr.objArray, "Failed allocating memory");
154 for(size_t i = 0; i < dimTotal; ++i)
156 dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
159 case OCREP_PROP_ARRAY:
160 dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
161 VERIFY_PARAM_NON_NULL(TAG, dest->arr.objArray, "Failed allocating memory");
162 for(size_t i = 0; i < dimTotal; ++i)
164 dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
167 case OCREP_PROP_BYTE_STRING:
168 dest->arr.ocByteStrArray = (OCByteString*)OICMalloc(dimTotal * sizeof(OCByteString));
169 VERIFY_PARAM_NON_NULL(TAG, dest->arr.ocByteStrArray, "Failed allocating memory");
170 for (size_t i = 0; i < dimTotal; ++i)
172 OCByteStringCopy(&dest->arr.ocByteStrArray[i], &source->arr.ocByteStrArray[i]);
173 VERIFY_PARAM_NON_NULL(TAG, dest->arr.ocByteStrArray[i].bytes, "Failed allocating memory");
177 OIC_LOG(ERROR, TAG, "CopyPropertyValueArray invalid type");
184 static void OCCopyPropertyValue (OCRepPayloadValue *dest, OCRepPayloadValue *source)
186 if (!source || !dest)
193 case OCREP_PROP_STRING:
194 dest->str = OICStrdup(source->str);
196 case OCREP_PROP_BYTE_STRING:
197 dest->ocByteStr.bytes = (uint8_t*)OICMalloc(source->ocByteStr.len * sizeof(uint8_t));
198 VERIFY_PARAM_NON_NULL(TAG, dest->ocByteStr.bytes, "Failed allocating memory");
199 dest->ocByteStr.len = source->ocByteStr.len;
200 memcpy(dest->ocByteStr.bytes, source->ocByteStr.bytes, dest->ocByteStr.len);
202 case OCREP_PROP_OBJECT:
203 dest->obj = OCRepPayloadClone(source->obj);
205 case OCREP_PROP_ARRAY:
206 OCCopyPropertyValueArray(dest, source);
209 // Nothing to do for the trivially copyable types.
216 static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val)
223 if (val->type == OCREP_PROP_STRING)
227 else if (val->type == OCREP_PROP_BYTE_STRING)
229 OICFree(val->ocByteStr.bytes);
231 else if (val->type == OCREP_PROP_OBJECT)
233 OCRepPayloadDestroy(val->obj);
235 else if (val->type == OCREP_PROP_ARRAY)
237 size_t dimTotal = calcDimTotal(val->arr.dimensions);
238 switch(val->arr.type)
241 case OCREP_PROP_DOUBLE:
242 case OCREP_PROP_BOOL:
243 // Since this is a union, iArray will
244 // point to all of the above
245 OICFree(val->arr.iArray);
247 case OCREP_PROP_STRING:
248 for(size_t i = 0; i < dimTotal; ++i)
250 OICFree(val->arr.strArray[i]);
252 OICFree(val->arr.strArray);
254 case OCREP_PROP_BYTE_STRING:
255 for (size_t i = 0; i < dimTotal; ++i)
257 if (val->arr.ocByteStrArray[i].bytes)
259 OICFree(val->arr.ocByteStrArray[i].bytes);
262 OICFree(val->arr.ocByteStrArray);
264 case OCREP_PROP_OBJECT: // This case is the temporary fix for string input
265 for(size_t i = 0; i< dimTotal; ++i)
267 OCRepPayloadDestroy(val->arr.objArray[i]);
269 OICFree(val->arr.objArray);
271 case OCREP_PROP_NULL:
272 case OCREP_PROP_ARRAY:
273 OIC_LOG_V(ERROR, TAG, "FreeRepPayloadValueContents: Illegal type\
274 inside an array: %d", val->arr.type);
280 static void OCFreeRepPayloadValue(OCRepPayloadValue* val)
288 OCFreeRepPayloadValueContents(val);
289 OCFreeRepPayloadValue(val->next);
292 static OCRepPayloadValue* OCRepPayloadValueClone (OCRepPayloadValue* source)
299 OCRepPayloadValue *sourceIter = source;
300 OCRepPayloadValue *destIter = (OCRepPayloadValue*) OICCalloc(1, sizeof(OCRepPayloadValue));
306 OCRepPayloadValue *headOfClone = destIter;
308 // Copy payload type and non pointer types in union.
309 *destIter = *sourceIter;
310 destIter->name = OICStrdup (sourceIter->name);
311 OCCopyPropertyValue (destIter, sourceIter);
313 sourceIter = sourceIter->next;
317 destIter->next = (OCRepPayloadValue*) OICCalloc(1, sizeof(OCRepPayloadValue));
320 OCFreeRepPayloadValue (headOfClone);
324 *(destIter->next) = *sourceIter;
325 destIter->next->name = OICStrdup (sourceIter->name);
326 OCCopyPropertyValue (destIter->next, sourceIter);
328 sourceIter = sourceIter->next;
329 destIter = destIter->next;
334 static OCRepPayloadValue* OCRepPayloadFindAndSetValue(OCRepPayload* payload, const char* name,
335 OCRepPayloadPropType type)
337 if (!payload || !name)
342 OCRepPayloadValue* val = payload->values;
345 payload->values = (OCRepPayloadValue*)OICCalloc(1, sizeof(OCRepPayloadValue));
346 if (!payload->values)
350 payload->values->name = OICStrdup(name);
351 if (!payload->values->name)
353 OICFree(payload->values);
354 payload->values = NULL;
357 payload->values->type =type;
358 return payload->values;
363 if (0 == strcmp(val->name, name))
365 OCFreeRepPayloadValueContents(val);
369 else if (val->next == NULL)
371 val->next = (OCRepPayloadValue*)OICCalloc(1, sizeof(OCRepPayloadValue));
376 val->next->name = OICStrdup(name);
377 if (!val->next->name)
383 val->next->type =type;
390 OIC_LOG(ERROR, TAG, "FindAndSetValue reached point after while loop, pointer corruption?");
394 bool OCRepPayloadAddResourceType(OCRepPayload* payload, const char* resourceType)
396 return OCRepPayloadAddResourceTypeAsOwner(payload, OICStrdup(resourceType));
399 bool OCRepPayloadAddResourceTypeAsOwner(OCRepPayload* payload, char* resourceType)
401 if (!payload || !resourceType)
408 OCStringLL* cur = payload->types;
413 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
420 cur->next->value = resourceType;
425 payload->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
430 payload->types->value = resourceType;
435 bool OCRepPayloadAddInterface(OCRepPayload* payload, const char* iface)
437 return OCRepPayloadAddInterfaceAsOwner(payload, OICStrdup(iface));
440 bool OCRepPayloadAddInterfaceAsOwner(OCRepPayload* payload, char* iface)
442 if (!payload || !iface)
447 if (payload->interfaces)
449 OCStringLL* cur = payload->interfaces;
454 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
460 cur->next->value = iface;
465 payload->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
466 if (!payload->interfaces)
470 payload->interfaces->value = iface;
475 bool OCRepPayloadSetUri(OCRepPayload* payload, const char* uri)
481 OICFree(payload->uri);
482 payload->uri = OICStrdup(uri);
483 return payload->uri != NULL;
486 bool OCRepPayloadIsNull(const OCRepPayload* payload, const char* name)
488 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
495 return val->type == OCREP_PROP_NULL;
498 static bool OCRepPayloadSetProp(OCRepPayload* payload, const char* name,
499 void* value, OCRepPayloadPropType type)
501 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, type);
509 val->i = *(int64_t*)value;
511 case OCREP_PROP_DOUBLE:
512 val->d = *(double*)value;
514 case OCREP_PROP_BOOL:
515 val->b = *(bool*)value;
517 case OCREP_PROP_OBJECT:
518 val->obj = (OCRepPayload*)value;
520 case OCREP_PROP_STRING:
521 val->str = (char*)value;
522 return val->str != NULL;
523 case OCREP_PROP_BYTE_STRING:
524 val->ocByteStr = *(OCByteString*)value;
525 return val->ocByteStr.bytes != NULL;
527 case OCREP_PROP_NULL:
529 case OCREP_PROP_ARRAY:
537 bool OCRepPayloadSetNull(OCRepPayload* payload, const char* name)
539 return OCRepPayloadSetProp(payload, name, NULL, OCREP_PROP_NULL);
542 bool OCRepPayloadSetPropInt(OCRepPayload* payload,
543 const char* name, int64_t value)
545 return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_INT);
548 bool OCRepPayloadGetPropInt(const OCRepPayload* payload, const char* name, int64_t* value)
550 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
552 if (!val || val->type != OCREP_PROP_INT)
561 bool OCRepPayloadSetPropDouble(OCRepPayload* payload,
562 const char* name, double value)
564 return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_DOUBLE);
567 bool OCRepPayloadGetPropDouble(const OCRepPayload* payload, const char* name, double* value)
569 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
573 if (val->type == OCREP_PROP_DOUBLE)
578 else if (val->type == OCREP_PROP_INT)
588 bool OCRepPayloadSetPropString(OCRepPayload* payload, const char* name, const char* value)
590 char* temp = OICStrdup(value);
591 bool b = OCRepPayloadSetPropStringAsOwner(payload, name, temp);
600 bool OCRepPayloadSetPropStringAsOwner(OCRepPayload* payload, const char* name, char* value)
602 return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_STRING);
605 bool OCRepPayloadGetPropString(const OCRepPayload* payload, const char* name, char** value)
607 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
609 if (!val || val->type != OCREP_PROP_STRING)
614 *value = OICStrdup(val->str);
615 return *value != NULL;
618 bool OCRepPayloadSetPropByteString(OCRepPayload* payload, const char* name, OCByteString value)
620 if (!value.bytes || !value.len)
625 OCByteString ocByteStr = {NULL, 0};
626 bool b = OCByteStringCopy(&ocByteStr, &value);
630 b = OCRepPayloadSetPropByteStringAsOwner(payload, name, &ocByteStr);
634 OICFree(ocByteStr.bytes);
639 bool OCRepPayloadSetPropByteStringAsOwner(OCRepPayload* payload, const char* name, OCByteString* value)
641 return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_BYTE_STRING);
644 bool OCRepPayloadGetPropByteString(const OCRepPayload* payload, const char* name, OCByteString* value)
646 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
648 if (!val || val->type != OCREP_PROP_BYTE_STRING)
658 value->bytes = (uint8_t*)OICMalloc(val->ocByteStr.len * sizeof(uint8_t));
663 value->len = val->ocByteStr.len;
664 memcpy(value->bytes, val->ocByteStr.bytes, value->len);
669 bool OCRepPayloadSetPropBool(OCRepPayload* payload,
670 const char* name, bool value)
672 return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_BOOL);
675 bool OCRepPayloadGetPropBool(const OCRepPayload* payload, const char* name, bool* value)
677 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
679 if (!val || val->type != OCREP_PROP_BOOL)
689 static char *getStringFromEncodingType(OicEncodingType_t type)
694 case OIC_ENCODING_BASE64: str = OC_RSRVD_BASE64; break;
695 case OIC_ENCODING_DER: str = OC_RSRVD_DER; break;
696 case OIC_ENCODING_PEM: str = OC_RSRVD_PEM; break;
697 case OIC_ENCODING_RAW: str = OC_RSRVD_RAW; break;
698 default: str = OC_RSRVD_UNKNOWN; break;
701 snprintf(encoding, sizeof(encoding), "%s.%s.%s", OC_OIC_SEC, OC_RSRVD_ENCODING, str);
703 return OICStrdup(encoding);
706 bool OCRepPayloadSetPropPubDataTypeAsOwner(OCRepPayload *payload, const char *name,
707 const OicSecKey_t *value)
709 if (!payload || !name || !value)
714 bool binary_field = false;
715 if (OIC_ENCODING_RAW == value->encoding || OIC_ENCODING_DER == value->encoding)
720 OCRepPayload *heplerPayload = OCRepPayloadCreate();
726 char *encoding = getStringFromEncodingType(value->encoding);
727 if (!OCRepPayloadSetPropString(heplerPayload, OC_RSRVD_ENCODING, encoding))
729 OIC_LOG_V(ERROR, TAG, "Can't set %s", OC_RSRVD_ENCODING);
732 OCByteString val = {.bytes = value->data, .len = value->len};
735 if (!OCRepPayloadSetPropByteString(heplerPayload, OC_RSRVD_DATA, val))
737 OIC_LOG_V(ERROR, TAG, "Can't set %s", OC_RSRVD_DATA);
742 if (!OCRepPayloadSetPropString(heplerPayload, OC_RSRVD_DATA, (char *)val.bytes))
744 OIC_LOG_V(ERROR, TAG, "Can't set %s", OC_RSRVD_DATA);
748 if (!OCRepPayloadSetPropObject(payload, name, (const OCRepPayload *)heplerPayload))
750 OIC_LOG_V(ERROR, TAG, "Can't set %s", name);
753 OCRepPayloadDestroy(heplerPayload);
759 bool OCRepPayloadSetPropPubDataType(OCRepPayload *payload, const char *name,
760 const OicSecKey_t *value)
762 return OCRepPayloadSetPropPubDataTypeAsOwner(payload, name, value);
765 static OicEncodingType_t getEncodingTypeFromString(char *encoding)
767 OicEncodingType_t type = OIC_ENCODING_UNKNOW;
769 char *str = strrchr(encoding, '.');
772 OIC_LOG_V(ERROR, TAG, "Can't find . in %s", encoding);
775 str++; //go to encoding itself
777 if (0 == strcmp(str, OC_RSRVD_BASE64)) type = OIC_ENCODING_BASE64;
778 else if (0 == strcmp(str, OC_RSRVD_DER)) type = OIC_ENCODING_DER;
779 else if (0 == strcmp(str, OC_RSRVD_PEM)) type = OIC_ENCODING_PEM;
780 else if (0 == strcmp(str, OC_RSRVD_RAW)) type = OIC_ENCODING_RAW;
785 bool OCRepPayloadGetPropPubDataType(const OCRepPayload *payload, const char *name, OicSecKey_t *value)
787 OCRepPayload *heplerPayload = NULL;
788 char *encoding = NULL;
791 if (!payload || !name || !value)
796 if (!OCRepPayloadGetPropObject(payload, name, &heplerPayload))
798 OIC_LOG_V(ERROR, TAG, "Can't get object with name %s", name);
802 if (!OCRepPayloadGetPropString(heplerPayload, OC_RSRVD_ENCODING, &encoding))
804 OIC_LOG_V(ERROR, TAG, "Can't get %s", OC_RSRVD_ENCODING);
808 value->encoding = getEncodingTypeFromString(encoding);
812 if (!OCRepPayloadGetPropByteString(heplerPayload, OC_RSRVD_DATA, &val))
814 if (!OCRepPayloadGetPropString(heplerPayload, OC_RSRVD_DATA, (char **)&val.bytes))
816 OIC_LOG_V(ERROR, TAG, "Can't get: %s", OC_RSRVD_DATA);
820 value->data = val.bytes;
821 value->len = strlen(val.bytes);
826 value->data = val.bytes;
827 value->len = val.len;
830 OCRepPayloadDestroy(heplerPayload);
835 bool OCRepPayloadSetPropObject(OCRepPayload* payload, const char* name, const OCRepPayload* value)
837 OCRepPayload* temp = OCRepPayloadClone(value);
838 bool b = OCRepPayloadSetPropObjectAsOwner(payload, name, temp);
842 OCRepPayloadDestroy(temp);
847 bool OCRepPayloadSetPropObjectAsOwner(OCRepPayload* payload, const char* name, OCRepPayload* value)
849 return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_OBJECT);
852 bool OCRepPayloadGetPropObject(const OCRepPayload* payload, const char* name, OCRepPayload** value)
854 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
856 if (!val || val->type != OCREP_PROP_OBJECT)
861 *value = OCRepPayloadClone(val->obj);
862 return *value != NULL;
865 size_t calcDimTotal(const size_t dimensions[MAX_REP_ARRAY_DEPTH])
867 if (dimensions[0] == 0)
873 for(uint8_t i = 0; i < MAX_REP_ARRAY_DEPTH && dimensions[i] != 0; ++i)
875 total *= dimensions[i];
881 bool OCRepPayloadSetByteStringArrayAsOwner(OCRepPayload* payload, const char* name,
882 OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
884 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
891 val->arr.type = OCREP_PROP_BYTE_STRING;
892 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
893 val->arr.ocByteStrArray = array;
898 bool OCRepPayloadSetByteStringArray(OCRepPayload* payload, const char* name,
899 const OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
906 size_t dimTotal = calcDimTotal(dimensions);
912 OCByteString* newArray = (OCByteString*)OICCalloc(dimTotal, sizeof(OCByteString));
919 for (size_t i = 0; i < dimTotal; ++i)
921 newArray[i].bytes = (uint8_t*)OICMalloc(array[i].len * sizeof(uint8_t));
922 if (NULL == newArray[i].bytes)
924 for (size_t j = 0; j < i; ++j)
926 OICFree(newArray[j].bytes);
932 newArray[i].len = array[i].len;
933 memcpy(newArray[i].bytes, array[i].bytes, newArray[i].len);
936 bool b = OCRepPayloadSetByteStringArrayAsOwner(payload, name, newArray, dimensions);
939 for (size_t i = 0; i < dimTotal; ++i)
941 OICFree(newArray[i].bytes);
949 bool OCRepPayloadGetByteStringArray(const OCRepPayload* payload, const char* name,
950 OCByteString** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
952 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
954 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_BYTE_STRING
955 || !val->arr.ocByteStrArray)
960 size_t dimTotal = calcDimTotal(val->arr.dimensions);
966 *array = (OCByteString*)OICCalloc(dimTotal, sizeof(OCByteString));
972 for (size_t i = 0; i < dimTotal; ++i)
974 OCByteString* tmp = &(*array)[i];
975 tmp->bytes = (uint8_t*)OICMalloc(val->arr.ocByteStrArray[i].len * sizeof(uint8_t));
976 if (NULL == tmp->bytes)
978 for (size_t j = 0; j < i; ++j)
980 OCByteString* tmp = &(*array)[j];
988 tmp->len = val->arr.ocByteStrArray[i].len;
989 memcpy(tmp->bytes, val->arr.ocByteStrArray[i].bytes, tmp->len);
992 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
997 bool OCRepPayloadSetIntArrayAsOwner(OCRepPayload* payload, const char* name,
998 int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1000 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1007 val->arr.type = OCREP_PROP_INT;
1008 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1009 val->arr.iArray = array;
1014 bool OCRepPayloadSetIntArray(OCRepPayload* payload, const char* name,
1015 const int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1017 size_t dimTotal = calcDimTotal(dimensions);
1023 int64_t* newArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
1030 memcpy(newArray, array, dimTotal * sizeof(int64_t));
1033 bool b = OCRepPayloadSetIntArrayAsOwner(payload, name, newArray, dimensions);
1041 bool OCRepPayloadGetIntArray(const OCRepPayload* payload, const char* name,
1042 int64_t** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1044 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1046 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_INT
1047 || !val->arr.iArray)
1052 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1057 *array = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
1063 memcpy(*array, val->arr.iArray, dimTotal * sizeof(int64_t));
1064 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1068 bool OCRepPayloadSetDoubleArrayAsOwner(OCRepPayload* payload, const char* name,
1069 double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1071 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1078 val->arr.type = OCREP_PROP_DOUBLE;
1079 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1080 val->arr.dArray = array;
1084 bool OCRepPayloadSetDoubleArray(OCRepPayload* payload, const char* name,
1085 const double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1087 size_t dimTotal = calcDimTotal(dimensions);
1093 double* newArray = (double*)OICMalloc(dimTotal * sizeof(double));
1100 memcpy(newArray, array, dimTotal * sizeof(double));
1102 bool b = OCRepPayloadSetDoubleArrayAsOwner(payload, name, newArray, dimensions);
1110 bool OCRepPayloadGetDoubleArray(const OCRepPayload* payload, const char* name,
1111 double** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1113 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1115 if (!val || val->type != OCREP_PROP_ARRAY ||
1116 (val->arr.type != OCREP_PROP_DOUBLE && val->arr.type != OCREP_PROP_INT)
1117 || !val->arr.dArray)
1122 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1127 *array = (double*)OICMalloc(dimTotal * sizeof(double));
1133 if (val->arr.type == OCREP_PROP_DOUBLE)
1135 memcpy(*array, val->arr.dArray, dimTotal * sizeof(double));
1139 /* need to convert from integer */
1141 for ( ; n < dimTotal; ++n)
1143 (*array)[n] = val->arr.iArray[n];
1146 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1150 bool OCRepPayloadSetStringArrayAsOwner(OCRepPayload* payload, const char* name,
1151 char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1153 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1160 val->arr.type = OCREP_PROP_STRING;
1161 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1162 val->arr.strArray = array;
1166 bool OCRepPayloadSetStringArray(OCRepPayload* payload, const char* name,
1167 const char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1169 size_t dimTotal = calcDimTotal(dimensions);
1175 char** newArray = (char**)OICMalloc(dimTotal * sizeof(char*));
1182 for(size_t i = 0; i < dimTotal; ++i)
1184 newArray[i] = OICStrdup(array[i]);
1187 bool b = OCRepPayloadSetStringArrayAsOwner(payload, name, newArray, dimensions);
1191 for(size_t i = 0; i < dimTotal; ++i)
1193 OICFree(newArray[i]);
1200 bool OCRepPayloadGetStringArray(const OCRepPayload* payload, const char* name,
1201 char*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1203 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1205 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_STRING
1206 || !val->arr.strArray)
1211 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1216 *array = (char**)OICMalloc(dimTotal * sizeof(char*));
1222 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1224 for(size_t i = 0; i < dimTotal; ++i)
1226 (*array)[i] = OICStrdup(val->arr.strArray[i]);
1233 bool OCRepPayloadSetBoolArrayAsOwner(OCRepPayload* payload, const char* name,
1234 bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1237 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1244 val->arr.type = OCREP_PROP_BOOL;
1245 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1246 val->arr.bArray = array;
1250 bool OCRepPayloadSetBoolArray(OCRepPayload* payload, const char* name,
1251 const bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1253 size_t dimTotal = calcDimTotal(dimensions);
1259 bool* newArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
1266 memcpy(newArray, array, dimTotal * sizeof(bool));
1269 bool b = OCRepPayloadSetBoolArrayAsOwner(payload, name, newArray, dimensions);
1277 bool OCRepPayloadGetBoolArray(const OCRepPayload* payload, const char* name,
1278 bool** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1280 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1282 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_BOOL
1283 || !val->arr.bArray)
1288 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1293 *array = (bool*)OICMalloc(dimTotal * sizeof(bool));
1299 memcpy(*array, val->arr.bArray, dimTotal * sizeof(bool));
1300 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1304 bool OCRepPayloadSetPropObjectArrayAsOwner(OCRepPayload* payload, const char* name,
1305 OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1307 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1314 val->arr.type = OCREP_PROP_OBJECT;
1315 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1316 val->arr.objArray = array;
1321 bool OCRepPayloadSetPropObjectArray(OCRepPayload* payload, const char* name,
1322 const OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1324 size_t dimTotal = calcDimTotal(dimensions);
1330 OCRepPayload** newArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
1337 for(size_t i = 0; i < dimTotal; ++i)
1339 newArray[i] = OCRepPayloadClone(array[i]);
1342 bool b = OCRepPayloadSetPropObjectArrayAsOwner(payload, name, newArray, dimensions);
1346 for(size_t i = 0; i < dimTotal; ++i)
1348 OCRepPayloadDestroy(newArray[i]);
1355 bool OCRepPayloadGetPropObjectArray(const OCRepPayload* payload, const char* name,
1356 OCRepPayload*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1358 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1360 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_OBJECT
1361 || !val->arr.objArray)
1366 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1371 *array = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
1377 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1379 for(size_t i = 0; i < dimTotal; ++i)
1381 (*array)[i] = OCRepPayloadClone(val->arr.objArray[i]);
1387 void OCFreeOCStringLL(OCStringLL* ll)
1394 OCFreeOCStringLL(ll->next);
1399 OCStringLL* CloneOCStringLL (OCStringLL* ll)
1406 OCStringLL *sourceIter = ll;
1408 OCStringLL *destIter = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
1413 destIter->value = OICStrdup (sourceIter->value);
1415 OCStringLL *headOfClone = destIter;
1417 sourceIter = sourceIter->next;
1421 destIter->next = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
1422 if (!destIter->next)
1424 OCFreeOCStringLL (headOfClone);
1427 destIter->next->value = OICStrdup (sourceIter->value);
1429 destIter = destIter->next;
1430 sourceIter = sourceIter->next;
1435 OCStringLL* OCCreateOCStringLL(const char* text)
1440 char *backup = NULL;
1441 OCStringLL* result = NULL;
1442 OCStringLL* iter = NULL;
1443 OCStringLL* prev = NULL;
1444 static const char delim[] = { CSV_SEPARATOR, '\0' };
1446 VERIFY_PARAM_NON_NULL(TAG, text, "Invalid parameter");
1447 backup = OICStrdup(text);
1448 VERIFY_PARAM_NON_NULL(TAG, backup, "Failed allocating memory");
1450 for (head = backup; ; head = NULL)
1452 token = (char *) strtok_r(head, delim, &tail);
1457 iter = (OCStringLL *)OICCalloc(1,sizeof(OCStringLL));
1458 VERIFY_PARAM_NON_NULL(TAG, iter, "Failed allocating memory");
1467 iter->value = OICStrdup(token);
1468 VERIFY_PARAM_NON_NULL(TAG, iter->value, "Failed allocating memory");
1477 OCFreeOCStringLL(result);
1481 char* OCCreateString(const OCStringLL* ll)
1494 for (const OCStringLL *it = ll; it; it = it->next)
1496 len += strlen(it->value) + 1;
1498 len--; // remove trailing separator (just added above)
1499 str = (char*) OICMalloc(len + 1);
1506 const OCStringLL *it = ll;
1509 sublen = strlen(it->value);
1510 count = snprintf(pos, len + 1, "%s", it->value);
1511 if ((size_t)count < sublen)
1522 *pos = CSV_SEPARATOR;
1531 bool OCByteStringCopy(OCByteString* dest, const OCByteString* source)
1533 VERIFY_PARAM_NON_NULL(TAG, source, "Bad input");
1537 dest = (OCByteString *)OICMalloc(sizeof(OCByteString));
1538 VERIFY_PARAM_NON_NULL(TAG, dest, "Failed allocating memory");
1542 OICFree(dest->bytes);
1544 dest->bytes = (uint8_t*)OICMalloc(source->len * sizeof(uint8_t));
1545 VERIFY_PARAM_NON_NULL(TAG, dest->bytes, "Failed allocating memory");
1546 memcpy(dest->bytes, source->bytes, source->len * sizeof(uint8_t));
1547 dest->len = source->len;
1554 OICFree(dest->bytes);
1561 OCRepPayload* OCRepPayloadClone (const OCRepPayload* payload)
1568 OCRepPayload *clone = OCRepPayloadCreate();
1575 clone->uri = OICStrdup (payload->uri);
1576 clone->types = CloneOCStringLL (payload->types);
1577 clone->interfaces = CloneOCStringLL (payload->interfaces);
1578 clone->values = OCRepPayloadValueClone (payload->values);
1583 OCRepPayload* OCRepPayloadBatchClone(const OCRepPayload* repPayload)
1585 OCRepPayload *newPayload = OCRepPayloadCreate();
1591 newPayload->uri = OICStrdup(repPayload->uri);
1592 OCRepPayload *clone = OCRepPayloadCreate();
1595 OCPayloadDestroy((OCPayload *)newPayload);
1599 clone->types = CloneOCStringLL(repPayload->types);
1600 clone->interfaces = CloneOCStringLL(repPayload->interfaces);
1601 clone->values = OCRepPayloadValueClone(repPayload->values);
1602 OCRepPayloadSetPropObjectAsOwner(newPayload, OC_RSRVD_REPRESENTATION, clone);
1607 void OCRepPayloadDestroy(OCRepPayload* payload)
1614 OICFree(payload->uri);
1615 OCFreeOCStringLL(payload->types);
1616 OCFreeOCStringLL(payload->interfaces);
1617 OCFreeRepPayloadValue(payload->values);
1618 OCRepPayloadDestroy(payload->next);
1622 OCDiscoveryPayload* OCDiscoveryPayloadCreate()
1624 OCDiscoveryPayload* payload = (OCDiscoveryPayload*)OICCalloc(1, sizeof(OCDiscoveryPayload));
1631 payload->base.type = PAYLOAD_TYPE_DISCOVERY;
1636 OCSecurityPayload* OCSecurityPayloadCreate(const uint8_t* securityData, size_t size)
1638 OCSecurityPayload* payload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1645 payload->base.type = PAYLOAD_TYPE_SECURITY;
1646 payload->securityData = (uint8_t *)OICCalloc(1, size);
1647 if (!payload->securityData)
1652 memcpy(payload->securityData, (uint8_t *)securityData, size);
1653 payload->payloadSize = size;
1658 void OCSecurityPayloadDestroy(OCSecurityPayload* payload)
1665 OICClearMemory(payload->securityData, payload->payloadSize);
1666 OICFree(payload->securityData);
1670 size_t OCDiscoveryPayloadGetResourceCount(OCDiscoveryPayload* payload)
1673 OCResourcePayload* p = payload->resources;
1682 OCResourcePayload* OCDiscoveryPayloadGetResource(OCDiscoveryPayload* payload, size_t index)
1685 OCResourcePayload* p = payload->resources;
1699 static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort)
1701 static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort,
1705 OCResourcePayload* pl = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1711 pl->uri = OICStrdup(res->uri);
1715 OCDiscoveryResourceDestroy(pl);
1720 OCResourceType* typePtr = res->rsrcType;
1722 if (typePtr != NULL)
1724 pl->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1727 OCDiscoveryResourceDestroy(pl);
1730 pl->types->value = OICStrdup(typePtr->resourcetypename);
1731 if (!pl->types->value)
1733 OCDiscoveryResourceDestroy(pl);
1737 OCStringLL* cur = pl->types;
1738 typePtr = typePtr->next;
1741 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1744 OCDiscoveryResourceDestroy(pl);
1747 cur->next->value = OICStrdup(typePtr->resourcetypename);
1748 if (!cur->next->value)
1750 OCDiscoveryResourceDestroy(pl);
1754 typePtr = typePtr->next;
1759 OCResourceInterface* ifPtr = res->rsrcInterface;
1762 pl->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1763 if (!pl->interfaces)
1765 OCDiscoveryResourceDestroy(pl);
1768 pl->interfaces->value = OICStrdup(ifPtr->name);
1769 if (!pl->interfaces->value)
1771 OCDiscoveryResourceDestroy(pl);
1775 OCStringLL* cur = pl->interfaces;
1776 ifPtr = ifPtr->next;
1779 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1782 OCDiscoveryResourceDestroy(pl);
1785 cur->next->value = OICStrdup(ifPtr->name);
1786 if (!cur->next->value)
1788 OCDiscoveryResourceDestroy(pl);
1792 ifPtr = ifPtr->next;
1796 pl->bitmap = res->resourceProperties & (OC_OBSERVABLE | OC_DISCOVERABLE
1801 pl->secure = (res->resourceProperties & OC_SECURE) != 0;
1802 pl->port = securePort;
1804 pl->tcpPort = tcpPort;
1810 void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
1811 uint16_t securePort)
1813 OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort));
1816 void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
1817 uint16_t securePort, uint16_t tcpPort)
1819 OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort, tcpPort));
1823 bool OCResourcePayloadAddStringLL(OCStringLL **stringLL, const char *value)
1826 VERIFY_PARAM_NON_NULL(TAG, value, "Invalid Parameters");
1827 dup = OICStrdup(value);
1828 VERIFY_PARAM_NON_NULL(TAG, dup, "Failed copying string");
1832 *stringLL = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
1833 VERIFY_PARAM_NON_NULL(TAG, *stringLL, "Failed allocating memory");
1834 (*stringLL)->value = dup;
1839 OCStringLL *temp = *stringLL;
1844 temp->next = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
1845 VERIFY_PARAM_NON_NULL(TAG, temp->next, "Failed allocating memory");
1846 temp->next->value = dup;
1854 void OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload, OCResourcePayload* res)
1861 if (!payload->resources)
1863 payload->resources = res;
1867 OCResourcePayload* p = payload->resources;
1876 void OCDiscoveryResourceDestroy(OCResourcePayload* payload)
1883 OICFree(payload->uri);
1884 OCFreeOCStringLL(payload->types);
1885 OCFreeOCStringLL(payload->interfaces);
1886 OCDiscoveryResourceDestroy(payload->next);
1890 void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload)
1896 OICFree(payload->sid);
1897 OICFree(payload->baseURI);
1898 OICFree(payload->uri);
1899 OCFreeOCStringLL(payload->type);
1900 OICFree(payload->name);
1901 OCFreeOCStringLL(payload->iface);
1902 OCDiscoveryResourceDestroy(payload->resources);
1903 OCDiscoveryPayloadDestroy(payload->next);
1907 OCPresencePayload* OCPresencePayloadCreate(uint32_t seqNum, uint32_t maxAge,
1908 OCPresenceTrigger trigger, const char* resourceType)
1910 OCPresencePayload* payload = (OCPresencePayload*)OICCalloc(1, sizeof(OCPresencePayload));
1916 payload->base.type = PAYLOAD_TYPE_PRESENCE;
1917 payload->sequenceNumber = seqNum;
1918 payload->maxAge = maxAge;
1919 payload->trigger = trigger;
1920 payload->resourceType = OICStrdup(resourceType);
1924 void OCPresencePayloadDestroy(OCPresencePayload* payload)
1930 OICFree(payload->resourceType);