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);
56 case PAYLOAD_TYPE_PRESENCE:
57 OCPresencePayloadDestroy((OCPresencePayload*)payload);
60 case PAYLOAD_TYPE_SECURITY:
61 OCSecurityPayloadDestroy((OCSecurityPayload*)payload);
64 OIC_LOG_V(ERROR, TAG, "Unsupported payload type in destroy: %d", payload->type);
70 OCRepPayload* OCRepPayloadCreate()
72 OCRepPayload* payload = (OCRepPayload*)OICCalloc(1, sizeof(OCRepPayload));
79 payload->base.type = PAYLOAD_TYPE_REPRESENTATION;
84 void OCRepPayloadAppend(OCRepPayload* parent, OCRepPayload* child)
93 parent = parent->next;
100 static OCRepPayloadValue* OCRepPayloadFindValue(const OCRepPayload* payload, const char* name)
102 if (!payload || !name)
107 OCRepPayloadValue* val = payload->values;
110 if (0 == strcmp(val->name, name))
120 static void OCCopyPropertyValueArray(OCRepPayloadValue* dest, OCRepPayloadValue* source)
122 if (!dest || !source)
127 size_t dimTotal = calcDimTotal(source->arr.dimensions);
128 switch(source->arr.type)
131 dest->arr.iArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
132 VERIFY_PARAM_NON_NULL(TAG, dest->arr.iArray, "Failed allocating memory");
133 memcpy(dest->arr.iArray, source->arr.iArray, dimTotal * sizeof(int64_t));
135 case OCREP_PROP_DOUBLE:
136 dest->arr.dArray = (double*)OICMalloc(dimTotal * sizeof(double));
137 VERIFY_PARAM_NON_NULL(TAG, dest->arr.dArray, "Failed allocating memory");
138 memcpy(dest->arr.dArray, source->arr.dArray, dimTotal * sizeof(double));
140 case OCREP_PROP_BOOL:
141 dest->arr.bArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
142 VERIFY_PARAM_NON_NULL(TAG, dest->arr.bArray, "Failed allocating memory");
143 memcpy(dest->arr.bArray, source->arr.bArray, dimTotal * sizeof(bool));
145 case OCREP_PROP_STRING:
146 dest->arr.strArray = (char**)OICMalloc(dimTotal * sizeof(char*));
147 VERIFY_PARAM_NON_NULL(TAG, dest->arr.strArray, "Failed allocating memory");
148 for(size_t i = 0; i < dimTotal; ++i)
150 dest->arr.strArray[i] = OICStrdup(source->arr.strArray[i]);
153 case OCREP_PROP_OBJECT:
154 dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
155 VERIFY_PARAM_NON_NULL(TAG, dest->arr.objArray, "Failed allocating memory");
156 for(size_t i = 0; i < dimTotal; ++i)
158 dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
161 case OCREP_PROP_ARRAY:
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_BYTE_STRING:
170 dest->arr.ocByteStrArray = (OCByteString*)OICMalloc(dimTotal * sizeof(OCByteString));
171 VERIFY_PARAM_NON_NULL(TAG, dest->arr.ocByteStrArray, "Failed allocating memory");
172 for (size_t i = 0; i < dimTotal; ++i)
174 OCByteStringCopy(&dest->arr.ocByteStrArray[i], &source->arr.ocByteStrArray[i]);
175 VERIFY_PARAM_NON_NULL(TAG, dest->arr.ocByteStrArray[i].bytes, "Failed allocating memory");
179 OIC_LOG(ERROR, TAG, "CopyPropertyValueArray invalid type");
186 static void OCCopyPropertyValue (OCRepPayloadValue *dest, OCRepPayloadValue *source)
188 if (!source || !dest)
195 case OCREP_PROP_STRING:
196 dest->str = OICStrdup(source->str);
198 case OCREP_PROP_BYTE_STRING:
199 dest->ocByteStr.bytes = (uint8_t*)OICMalloc(source->ocByteStr.len * sizeof(uint8_t));
200 VERIFY_PARAM_NON_NULL(TAG, dest->ocByteStr.bytes, "Failed allocating memory");
201 dest->ocByteStr.len = source->ocByteStr.len;
202 memcpy(dest->ocByteStr.bytes, source->ocByteStr.bytes, dest->ocByteStr.len);
204 case OCREP_PROP_OBJECT:
205 dest->obj = OCRepPayloadClone(source->obj);
207 case OCREP_PROP_ARRAY:
208 OCCopyPropertyValueArray(dest, source);
211 // Nothing to do for the trivially copyable types.
218 static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val)
225 if (val->type == OCREP_PROP_STRING)
227 if (val->str != NULL)
232 else if (val->type == OCREP_PROP_BYTE_STRING)
234 OICFree(val->ocByteStr.bytes);
236 else if (val->type == OCREP_PROP_OBJECT)
238 OCRepPayloadDestroy(val->obj);
240 else if (val->type == OCREP_PROP_ARRAY)
242 size_t dimTotal = calcDimTotal(val->arr.dimensions);
243 switch(val->arr.type)
246 case OCREP_PROP_DOUBLE:
247 case OCREP_PROP_BOOL:
248 // Since this is a union, iArray will
249 // point to all of the above
250 OICFree(val->arr.iArray);
252 case OCREP_PROP_STRING:
253 if (val->arr.strArray != NULL)
255 for(size_t i = 0; i < dimTotal; ++i)
257 OICFree(val->arr.strArray[i]);
259 OICFree(val->arr.strArray);
262 case OCREP_PROP_BYTE_STRING:
263 if (val->arr.ocByteStrArray != NULL)
265 for (size_t i = 0; i < dimTotal; ++i)
267 if (val->arr.ocByteStrArray[i].bytes)
269 OICFree(val->arr.ocByteStrArray[i].bytes);
272 OICFree(val->arr.ocByteStrArray);
275 case OCREP_PROP_OBJECT: // This case is the temporary fix for string input
276 if (val->arr.objArray != NULL)
278 for(size_t i = 0; i< dimTotal; ++i)
280 OCRepPayloadDestroy(val->arr.objArray[i]);
282 OICFree(val->arr.objArray);
285 case OCREP_PROP_NULL:
286 case OCREP_PROP_ARRAY:
287 OIC_LOG_V(ERROR, TAG, "FreeRepPayloadValueContents: Illegal type\
288 inside an array: %d", val->arr.type);
294 static void OCFreeRepPayloadValue(OCRepPayloadValue* val)
302 OCFreeRepPayloadValueContents(val);
303 OCFreeRepPayloadValue(val->next);
306 static OCRepPayloadValue* OCRepPayloadValueClone (OCRepPayloadValue* source)
313 OCRepPayloadValue *sourceIter = source;
314 OCRepPayloadValue *destIter = (OCRepPayloadValue*) OICCalloc(1, sizeof(OCRepPayloadValue));
320 OCRepPayloadValue *headOfClone = destIter;
322 // Copy payload type and non pointer types in union.
323 *destIter = *sourceIter;
324 destIter->name = OICStrdup (sourceIter->name);
325 OCCopyPropertyValue (destIter, sourceIter);
327 sourceIter = sourceIter->next;
331 destIter->next = (OCRepPayloadValue*) OICCalloc(1, sizeof(OCRepPayloadValue));
334 OCFreeRepPayloadValue (headOfClone);
338 *(destIter->next) = *sourceIter;
339 destIter->next->name = OICStrdup (sourceIter->name);
340 OCCopyPropertyValue (destIter->next, sourceIter);
342 sourceIter = sourceIter->next;
343 destIter = destIter->next;
348 static OCRepPayloadValue* OCRepPayloadFindAndSetValue(OCRepPayload* payload, const char* name,
349 OCRepPayloadPropType type)
351 if (!payload || !name)
356 OCRepPayloadValue* val = payload->values;
359 payload->values = (OCRepPayloadValue*)OICCalloc(1, sizeof(OCRepPayloadValue));
360 if (!payload->values)
364 payload->values->name = OICStrdup(name);
365 if (!payload->values->name)
367 OICFree(payload->values);
368 payload->values = NULL;
371 payload->values->type =type;
372 return payload->values;
377 if (0 == strcmp(val->name, name))
379 OCFreeRepPayloadValueContents(val);
383 else if (val->next == NULL)
385 val->next = (OCRepPayloadValue*)OICCalloc(1, sizeof(OCRepPayloadValue));
390 val->next->name = OICStrdup(name);
391 if (!val->next->name)
397 val->next->type =type;
404 OIC_LOG(ERROR, TAG, "FindAndSetValue reached point after while loop, pointer corruption?");
408 bool OCRepPayloadAddResourceType(OCRepPayload* payload, const char* resourceType)
410 return OCRepPayloadAddResourceTypeAsOwner(payload, OICStrdup(resourceType));
413 bool OCRepPayloadAddResourceTypeAsOwner(OCRepPayload* payload, char* resourceType)
415 if (!payload || !resourceType)
422 OCStringLL* cur = payload->types;
427 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
434 cur->next->value = resourceType;
439 payload->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
444 payload->types->value = resourceType;
449 bool OCRepPayloadAddInterface(OCRepPayload* payload, const char* iface)
451 return OCRepPayloadAddInterfaceAsOwner(payload, OICStrdup(iface));
454 bool OCRepPayloadAddInterfaceAsOwner(OCRepPayload* payload, char* iface)
456 if (!payload || !iface)
461 if (payload->interfaces)
463 OCStringLL* cur = payload->interfaces;
468 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
474 cur->next->value = iface;
479 payload->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
480 if (!payload->interfaces)
484 payload->interfaces->value = iface;
489 bool OCRepPayloadSetUri(OCRepPayload* payload, const char* uri)
495 OICFree(payload->uri);
496 payload->uri = OICStrdup(uri);
497 return payload->uri != NULL;
500 bool OCRepPayloadIsNull(const OCRepPayload* payload, const char* name)
502 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
509 return val->type == OCREP_PROP_NULL;
512 static bool OCRepPayloadSetProp(OCRepPayload* payload, const char* name,
513 void* value, OCRepPayloadPropType type)
515 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, type);
523 val->i = *(int64_t*)value;
525 case OCREP_PROP_DOUBLE:
526 val->d = *(double*)value;
528 case OCREP_PROP_BOOL:
529 val->b = *(bool*)value;
531 case OCREP_PROP_OBJECT:
532 val->obj = (OCRepPayload*)value;
534 case OCREP_PROP_STRING:
535 val->str = (char*)value;
536 return val->str != NULL;
537 case OCREP_PROP_BYTE_STRING:
538 val->ocByteStr = *(OCByteString*)value;
539 return val->ocByteStr.bytes != NULL;
541 case OCREP_PROP_NULL:
543 case OCREP_PROP_ARRAY:
551 bool OCRepPayloadSetNull(OCRepPayload* payload, const char* name)
553 return OCRepPayloadSetProp(payload, name, NULL, OCREP_PROP_NULL);
556 bool OCRepPayloadSetPropInt(OCRepPayload* payload,
557 const char* name, int64_t value)
559 return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_INT);
562 bool OCRepPayloadGetPropInt(const OCRepPayload* payload, const char* name, int64_t* value)
564 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
566 if (!val || val->type != OCREP_PROP_INT)
575 bool OCRepPayloadSetPropDouble(OCRepPayload* payload,
576 const char* name, double value)
578 return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_DOUBLE);
581 bool OCRepPayloadGetPropDouble(const OCRepPayload* payload, const char* name, double* value)
583 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
587 if (val->type == OCREP_PROP_DOUBLE)
592 else if (val->type == OCREP_PROP_INT)
602 bool OCRepPayloadSetPropString(OCRepPayload* payload, const char* name, const char* value)
604 char* temp = OICStrdup(value);
605 bool b = OCRepPayloadSetPropStringAsOwner(payload, name, temp);
614 bool OCRepPayloadSetPropStringAsOwner(OCRepPayload* payload, const char* name, char* value)
616 return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_STRING);
619 bool OCRepPayloadGetPropString(const OCRepPayload* payload, const char* name, char** value)
621 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
623 if (!val || val->type != OCREP_PROP_STRING)
628 *value = OICStrdup(val->str);
629 return *value != NULL;
632 bool OCRepPayloadSetPropByteString(OCRepPayload* payload, const char* name, OCByteString value)
634 if (!value.bytes || !value.len)
639 OCByteString ocByteStr = {NULL, 0};
640 bool b = OCByteStringCopy(&ocByteStr, &value);
644 b = OCRepPayloadSetPropByteStringAsOwner(payload, name, &ocByteStr);
648 OICFree(ocByteStr.bytes);
653 bool OCRepPayloadSetPropByteStringAsOwner(OCRepPayload* payload, const char* name, OCByteString* value)
655 return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_BYTE_STRING);
658 bool OCRepPayloadGetPropByteString(const OCRepPayload* payload, const char* name, OCByteString* value)
660 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
662 if (!val || val->type != OCREP_PROP_BYTE_STRING)
672 value->bytes = (uint8_t*)OICMalloc(val->ocByteStr.len * sizeof(uint8_t));
677 value->len = val->ocByteStr.len;
678 memcpy(value->bytes, val->ocByteStr.bytes, value->len);
683 bool OCRepPayloadSetPropBool(OCRepPayload* payload,
684 const char* name, bool value)
686 return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_BOOL);
689 bool OCRepPayloadGetPropBool(const OCRepPayload* payload, const char* name, bool* value)
691 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
693 if (!val || val->type != OCREP_PROP_BOOL)
703 static char *getStringFromEncodingType(OicEncodingType_t type)
708 case OIC_ENCODING_BASE64: str = OC_RSRVD_BASE64; break;
709 case OIC_ENCODING_DER: str = OC_RSRVD_DER; break;
710 case OIC_ENCODING_PEM: str = OC_RSRVD_PEM; break;
711 case OIC_ENCODING_RAW: str = OC_RSRVD_RAW; break;
712 default: str = OC_RSRVD_UNKNOWN; break;
715 snprintf(encoding, sizeof(encoding), "%s.%s.%s", OC_OIC_SEC, OC_RSRVD_ENCODING, str);
717 return OICStrdup(encoding);
720 bool OCRepPayloadSetPropPubDataTypeAsOwner(OCRepPayload *payload, const char *name,
721 const OicSecKey_t *value)
723 if (!payload || !name || !value)
728 bool binary_field = false;
729 if (OIC_ENCODING_RAW == value->encoding || OIC_ENCODING_DER == value->encoding)
734 OCRepPayload *heplerPayload = OCRepPayloadCreate();
740 char *encoding = getStringFromEncodingType(value->encoding);
741 if (!OCRepPayloadSetPropString(heplerPayload, OC_RSRVD_ENCODING, encoding))
743 OIC_LOG_V(ERROR, TAG, "Can't set %s", OC_RSRVD_ENCODING);
746 OCByteString val = {.bytes = value->data, .len = value->len};
749 if (!OCRepPayloadSetPropByteString(heplerPayload, OC_RSRVD_DATA, val))
751 OIC_LOG_V(ERROR, TAG, "Can't set %s", OC_RSRVD_DATA);
756 if (!OCRepPayloadSetPropString(heplerPayload, OC_RSRVD_DATA, (char *)val.bytes))
758 OIC_LOG_V(ERROR, TAG, "Can't set %s", OC_RSRVD_DATA);
762 if (!OCRepPayloadSetPropObject(payload, name, (const OCRepPayload *)heplerPayload))
764 OIC_LOG_V(ERROR, TAG, "Can't set %s", name);
767 OCRepPayloadDestroy(heplerPayload);
773 bool OCRepPayloadSetPropPubDataType(OCRepPayload *payload, const char *name,
774 const OicSecKey_t *value)
776 return OCRepPayloadSetPropPubDataTypeAsOwner(payload, name, value);
779 static OicEncodingType_t getEncodingTypeFromString(char *encoding)
781 OicEncodingType_t type = OIC_ENCODING_UNKNOW;
783 char *str = strrchr(encoding, '.');
786 OIC_LOG_V(ERROR, TAG, "Can't find . in %s", encoding);
789 str++; //go to encoding itself
791 if (0 == strcmp(str, OC_RSRVD_BASE64)) type = OIC_ENCODING_BASE64;
792 else if (0 == strcmp(str, OC_RSRVD_DER)) type = OIC_ENCODING_DER;
793 else if (0 == strcmp(str, OC_RSRVD_PEM)) type = OIC_ENCODING_PEM;
794 else if (0 == strcmp(str, OC_RSRVD_RAW)) type = OIC_ENCODING_RAW;
799 bool OCRepPayloadGetPropPubDataType(const OCRepPayload *payload, const char *name, OicSecKey_t *value)
801 OCRepPayload *heplerPayload = NULL;
802 char *encoding = NULL;
805 if (!payload || !name || !value)
810 if (!OCRepPayloadGetPropObject(payload, name, &heplerPayload))
812 OIC_LOG_V(ERROR, TAG, "Can't get object with name %s", name);
816 if (!OCRepPayloadGetPropString(heplerPayload, OC_RSRVD_ENCODING, &encoding))
818 OIC_LOG_V(ERROR, TAG, "Can't get %s", OC_RSRVD_ENCODING);
822 value->encoding = getEncodingTypeFromString(encoding);
826 if (!OCRepPayloadGetPropByteString(heplerPayload, OC_RSRVD_DATA, &val))
828 if (!OCRepPayloadGetPropString(heplerPayload, OC_RSRVD_DATA, (char **)&val.bytes))
830 OIC_LOG_V(ERROR, TAG, "Can't get: %s", OC_RSRVD_DATA);
834 value->data = val.bytes;
835 value->len = strlen((char *)val.bytes);
840 value->data = val.bytes;
841 value->len = val.len;
844 OCRepPayloadDestroy(heplerPayload);
849 bool OCRepPayloadSetPropObject(OCRepPayload* payload, const char* name, const OCRepPayload* value)
851 OCRepPayload* temp = OCRepPayloadClone(value);
852 bool b = OCRepPayloadSetPropObjectAsOwner(payload, name, temp);
856 OCRepPayloadDestroy(temp);
861 bool OCRepPayloadSetPropObjectAsOwner(OCRepPayload* payload, const char* name, OCRepPayload* value)
863 return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_OBJECT);
866 bool OCRepPayloadGetPropObject(const OCRepPayload* payload, const char* name, OCRepPayload** value)
868 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
870 if (!val || val->type != OCREP_PROP_OBJECT)
875 *value = OCRepPayloadClone(val->obj);
876 return *value != NULL;
879 size_t calcDimTotal(const size_t dimensions[MAX_REP_ARRAY_DEPTH])
881 if (dimensions[0] == 0)
887 for(uint8_t i = 0; i < MAX_REP_ARRAY_DEPTH && dimensions[i] != 0; ++i)
889 total *= dimensions[i];
895 bool OCRepPayloadSetByteStringArrayAsOwner(OCRepPayload* payload, const char* name,
896 OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
898 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
905 val->arr.type = OCREP_PROP_BYTE_STRING;
906 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
907 val->arr.ocByteStrArray = array;
912 bool OCRepPayloadSetByteStringArray(OCRepPayload* payload, const char* name,
913 const OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
920 size_t dimTotal = calcDimTotal(dimensions);
926 OCByteString* newArray = (OCByteString*)OICCalloc(dimTotal, sizeof(OCByteString));
933 for (size_t i = 0; i < dimTotal; ++i)
935 newArray[i].bytes = (uint8_t*)OICMalloc(array[i].len * sizeof(uint8_t));
936 if (NULL == newArray[i].bytes)
938 for (size_t j = 0; j < i; ++j)
940 OICFree(newArray[j].bytes);
946 newArray[i].len = array[i].len;
947 memcpy(newArray[i].bytes, array[i].bytes, newArray[i].len);
950 bool b = OCRepPayloadSetByteStringArrayAsOwner(payload, name, newArray, dimensions);
953 for (size_t i = 0; i < dimTotal; ++i)
955 OICFree(newArray[i].bytes);
963 bool OCRepPayloadGetByteStringArray(const OCRepPayload* payload, const char* name,
964 OCByteString** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
966 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
968 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_BYTE_STRING
969 || !val->arr.ocByteStrArray)
974 size_t dimTotal = calcDimTotal(val->arr.dimensions);
980 *array = (OCByteString*)OICCalloc(dimTotal, sizeof(OCByteString));
986 for (size_t i = 0; i < dimTotal; ++i)
988 OCByteString* tmp = &(*array)[i];
989 tmp->bytes = (uint8_t*)OICMalloc(val->arr.ocByteStrArray[i].len * sizeof(uint8_t));
990 if (NULL == tmp->bytes)
992 for (size_t j = 0; j < i; ++j)
994 OCByteString* tmp = &(*array)[j];
1002 tmp->len = val->arr.ocByteStrArray[i].len;
1003 memcpy(tmp->bytes, val->arr.ocByteStrArray[i].bytes, tmp->len);
1006 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1011 bool OCRepPayloadSetIntArrayAsOwner(OCRepPayload* payload, const char* name,
1012 int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1014 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1021 val->arr.type = OCREP_PROP_INT;
1022 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1023 val->arr.iArray = array;
1028 bool OCRepPayloadSetIntArray(OCRepPayload* payload, const char* name,
1029 const int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1031 size_t dimTotal = calcDimTotal(dimensions);
1037 int64_t* newArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
1044 memcpy(newArray, array, dimTotal * sizeof(int64_t));
1047 bool b = OCRepPayloadSetIntArrayAsOwner(payload, name, newArray, dimensions);
1055 bool OCRepPayloadGetIntArray(const OCRepPayload* payload, const char* name,
1056 int64_t** 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_INT
1061 || !val->arr.iArray)
1066 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1071 *array = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
1077 memcpy(*array, val->arr.iArray, dimTotal * sizeof(int64_t));
1078 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1082 bool OCRepPayloadSetDoubleArrayAsOwner(OCRepPayload* payload, const char* name,
1083 double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1085 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1092 val->arr.type = OCREP_PROP_DOUBLE;
1093 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1094 val->arr.dArray = array;
1098 bool OCRepPayloadSetDoubleArray(OCRepPayload* payload, const char* name,
1099 const double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1101 size_t dimTotal = calcDimTotal(dimensions);
1107 double* newArray = (double*)OICMalloc(dimTotal * sizeof(double));
1114 memcpy(newArray, array, dimTotal * sizeof(double));
1116 bool b = OCRepPayloadSetDoubleArrayAsOwner(payload, name, newArray, dimensions);
1124 bool OCRepPayloadGetDoubleArray(const OCRepPayload* payload, const char* name,
1125 double** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1127 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1129 if (!val || val->type != OCREP_PROP_ARRAY ||
1130 (val->arr.type != OCREP_PROP_DOUBLE && val->arr.type != OCREP_PROP_INT)
1131 || !val->arr.dArray)
1136 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1141 *array = (double*)OICMalloc(dimTotal * sizeof(double));
1147 if (val->arr.type == OCREP_PROP_DOUBLE)
1149 memcpy(*array, val->arr.dArray, dimTotal * sizeof(double));
1153 /* need to convert from integer */
1155 for ( ; n < dimTotal; ++n)
1157 (*array)[n] = val->arr.iArray[n];
1160 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1164 bool OCRepPayloadSetStringArrayAsOwner(OCRepPayload* payload, const char* name,
1165 char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1167 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1174 val->arr.type = OCREP_PROP_STRING;
1175 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1176 val->arr.strArray = array;
1180 bool OCRepPayloadSetStringArray(OCRepPayload* payload, const char* name,
1181 const char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1183 size_t dimTotal = calcDimTotal(dimensions);
1189 char** newArray = (char**)OICMalloc(dimTotal * sizeof(char*));
1196 for(size_t i = 0; i < dimTotal; ++i)
1198 newArray[i] = OICStrdup(array[i]);
1201 bool b = OCRepPayloadSetStringArrayAsOwner(payload, name, newArray, dimensions);
1205 for(size_t i = 0; i < dimTotal; ++i)
1207 OICFree(newArray[i]);
1214 bool OCRepPayloadGetStringArray(const OCRepPayload* payload, const char* name,
1215 char*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1217 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1219 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_STRING
1220 || !val->arr.strArray)
1225 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1230 *array = (char**)OICMalloc(dimTotal * sizeof(char*));
1236 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1238 for(size_t i = 0; i < dimTotal; ++i)
1240 (*array)[i] = OICStrdup(val->arr.strArray[i]);
1247 bool OCRepPayloadSetBoolArrayAsOwner(OCRepPayload* payload, const char* name,
1248 bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1251 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1258 val->arr.type = OCREP_PROP_BOOL;
1259 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1260 val->arr.bArray = array;
1264 bool OCRepPayloadSetBoolArray(OCRepPayload* payload, const char* name,
1265 const bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1267 size_t dimTotal = calcDimTotal(dimensions);
1273 bool* newArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
1280 memcpy(newArray, array, dimTotal * sizeof(bool));
1283 bool b = OCRepPayloadSetBoolArrayAsOwner(payload, name, newArray, dimensions);
1291 bool OCRepPayloadGetBoolArray(const OCRepPayload* payload, const char* name,
1292 bool** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1294 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1296 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_BOOL
1297 || !val->arr.bArray)
1302 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1307 *array = (bool*)OICMalloc(dimTotal * sizeof(bool));
1313 memcpy(*array, val->arr.bArray, dimTotal * sizeof(bool));
1314 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1318 bool OCRepPayloadSetPropObjectArrayAsOwner(OCRepPayload* payload, const char* name,
1319 OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1321 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1328 val->arr.type = OCREP_PROP_OBJECT;
1329 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1330 val->arr.objArray = array;
1335 bool OCRepPayloadSetPropObjectArray(OCRepPayload* payload, const char* name,
1336 const OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1338 size_t dimTotal = calcDimTotal(dimensions);
1344 OCRepPayload** newArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
1351 for(size_t i = 0; i < dimTotal; ++i)
1353 newArray[i] = OCRepPayloadClone(array[i]);
1356 bool b = OCRepPayloadSetPropObjectArrayAsOwner(payload, name, newArray, dimensions);
1360 for(size_t i = 0; i < dimTotal; ++i)
1362 OCRepPayloadDestroy(newArray[i]);
1369 bool OCRepPayloadGetPropObjectArray(const OCRepPayload* payload, const char* name,
1370 OCRepPayload*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1372 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1374 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_OBJECT
1375 || !val->arr.objArray)
1380 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1385 *array = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
1391 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1393 for(size_t i = 0; i < dimTotal; ++i)
1395 (*array)[i] = OCRepPayloadClone(val->arr.objArray[i]);
1401 void OCFreeOCStringLL(OCStringLL* ll)
1408 OCFreeOCStringLL(ll->next);
1413 OCStringLL* CloneOCStringLL (OCStringLL* ll)
1420 OCStringLL *sourceIter = ll;
1422 OCStringLL *destIter = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
1427 destIter->value = OICStrdup (sourceIter->value);
1429 OCStringLL *headOfClone = destIter;
1431 sourceIter = sourceIter->next;
1435 destIter->next = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
1436 if (!destIter->next)
1438 OCFreeOCStringLL (headOfClone);
1441 destIter->next->value = OICStrdup (sourceIter->value);
1443 destIter = destIter->next;
1444 sourceIter = sourceIter->next;
1449 OCStringLL* OCCreateOCStringLL(const char* text)
1454 char *backup = NULL;
1455 OCStringLL* result = NULL;
1456 OCStringLL* iter = NULL;
1457 OCStringLL* prev = NULL;
1458 static const char delim[] = { CSV_SEPARATOR, '\0' };
1460 VERIFY_PARAM_NON_NULL(TAG, text, "Invalid parameter");
1461 backup = OICStrdup(text);
1462 VERIFY_PARAM_NON_NULL(TAG, backup, "Failed allocating memory");
1464 for (head = backup; ; head = NULL)
1466 token = (char *) strtok_r(head, delim, &tail);
1471 iter = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
1472 VERIFY_PARAM_NON_NULL(TAG, iter, "Failed allocating memory");
1481 iter->value = OICStrdup(token);
1482 VERIFY_PARAM_NON_NULL(TAG, iter->value, "Failed allocating memory");
1490 OCFreeOCStringLL(result);
1494 char* OCCreateString(const OCStringLL* ll)
1507 for (const OCStringLL *it = ll; it; it = it->next)
1509 len += strlen(it->value) + 1;
1511 len--; // remove trailing separator (just added above)
1512 str = (char*) OICMalloc(len + 1);
1519 const OCStringLL *it = ll;
1522 sublen = strlen(it->value);
1523 count = snprintf(pos, len + 1, "%s", it->value);
1524 if ((size_t)count < sublen)
1535 *pos = CSV_SEPARATOR;
1544 bool OCByteStringCopy(OCByteString* dest, const OCByteString* source)
1546 VERIFY_PARAM_NON_NULL(TAG, source, "Bad input");
1550 dest = (OCByteString *)OICMalloc(sizeof(OCByteString));
1551 VERIFY_PARAM_NON_NULL(TAG, dest, "Failed allocating memory");
1555 OICFree(dest->bytes);
1557 dest->bytes = (uint8_t*)OICMalloc(source->len * sizeof(uint8_t));
1558 VERIFY_PARAM_NON_NULL(TAG, dest->bytes, "Failed allocating memory");
1559 memcpy(dest->bytes, source->bytes, source->len * sizeof(uint8_t));
1560 dest->len = source->len;
1567 OICFree(dest->bytes);
1574 OCRepPayload* OCRepPayloadClone (const OCRepPayload* payload)
1581 OCRepPayload *clone = OCRepPayloadCreate();
1588 clone->uri = OICStrdup (payload->uri);
1589 clone->types = CloneOCStringLL (payload->types);
1590 clone->interfaces = CloneOCStringLL (payload->interfaces);
1591 clone->values = OCRepPayloadValueClone (payload->values);
1596 OCRepPayload* OCRepPayloadBatchClone(const OCRepPayload* repPayload)
1598 OCRepPayload *newPayload = OCRepPayloadCreate();
1604 newPayload->uri = OICStrdup(repPayload->uri);
1605 OCRepPayload *clone = OCRepPayloadCreate();
1608 OCPayloadDestroy((OCPayload *)newPayload);
1612 clone->types = CloneOCStringLL(repPayload->types);
1613 clone->interfaces = CloneOCStringLL(repPayload->interfaces);
1614 clone->values = OCRepPayloadValueClone(repPayload->values);
1615 OCRepPayloadSetPropObjectAsOwner(newPayload, OC_RSRVD_REPRESENTATION, clone);
1620 void OCRepPayloadDestroy(OCRepPayload* payload)
1627 OICFree(payload->uri);
1628 OCFreeOCStringLL(payload->types);
1629 OCFreeOCStringLL(payload->interfaces);
1630 OCFreeRepPayloadValue(payload->values);
1631 OCRepPayloadDestroy(payload->next);
1635 OCDiscoveryPayload* OCDiscoveryPayloadCreate()
1637 OCDiscoveryPayload* payload = (OCDiscoveryPayload*)OICCalloc(1, sizeof(OCDiscoveryPayload));
1644 payload->base.type = PAYLOAD_TYPE_DISCOVERY;
1649 OCSecurityPayload* OCSecurityPayloadCreate(const uint8_t* securityData, size_t size)
1651 OCSecurityPayload* payload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1658 payload->base.type = PAYLOAD_TYPE_SECURITY;
1659 payload->securityData = (uint8_t *)OICCalloc(1, size);
1660 if (!payload->securityData)
1665 memcpy(payload->securityData, (uint8_t *)securityData, size);
1666 payload->payloadSize = size;
1671 void OCSecurityPayloadDestroy(OCSecurityPayload* payload)
1678 OICClearMemory(payload->securityData, payload->payloadSize);
1679 OICFree(payload->securityData);
1683 size_t OCDiscoveryPayloadGetResourceCount(OCDiscoveryPayload* payload)
1686 OCResourcePayload* p = payload->resources;
1695 OCResourcePayload* OCDiscoveryPayloadGetResource(OCDiscoveryPayload* payload, size_t index)
1698 OCResourcePayload* p = payload->resources;
1712 static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort)
1714 static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort,
1718 OCResourcePayload* pl = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1724 pl->uri = OICStrdup(res->uri);
1728 OCDiscoveryResourceDestroy(pl);
1733 OCResourceType* typePtr = res->rsrcType;
1735 if (typePtr != NULL)
1737 pl->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1740 OCDiscoveryResourceDestroy(pl);
1743 pl->types->value = OICStrdup(typePtr->resourcetypename);
1744 if (!pl->types->value)
1746 OCDiscoveryResourceDestroy(pl);
1750 OCStringLL* cur = pl->types;
1751 typePtr = typePtr->next;
1754 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1757 OCDiscoveryResourceDestroy(pl);
1760 cur->next->value = OICStrdup(typePtr->resourcetypename);
1761 if (!cur->next->value)
1763 OCDiscoveryResourceDestroy(pl);
1767 typePtr = typePtr->next;
1772 OCResourceInterface* ifPtr = res->rsrcInterface;
1775 pl->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1776 if (!pl->interfaces)
1778 OCDiscoveryResourceDestroy(pl);
1781 pl->interfaces->value = OICStrdup(ifPtr->name);
1782 if (!pl->interfaces->value)
1784 OCDiscoveryResourceDestroy(pl);
1788 OCStringLL* cur = pl->interfaces;
1789 ifPtr = ifPtr->next;
1792 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1795 OCDiscoveryResourceDestroy(pl);
1798 cur->next->value = OICStrdup(ifPtr->name);
1799 if (!cur->next->value)
1801 OCDiscoveryResourceDestroy(pl);
1805 ifPtr = ifPtr->next;
1809 pl->bitmap = res->resourceProperties & (OC_OBSERVABLE | OC_DISCOVERABLE
1814 pl->secure = (res->resourceProperties & OC_SECURE) != 0;
1815 pl->port = securePort;
1817 pl->tcpPort = tcpPort;
1823 void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
1824 uint16_t securePort)
1826 OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort));
1829 void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
1830 uint16_t securePort, uint16_t tcpPort)
1832 OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort, tcpPort));
1836 bool OCResourcePayloadAddStringLL(OCStringLL **stringLL, const char *value)
1839 VERIFY_PARAM_NON_NULL(TAG, value, "Invalid Parameters");
1840 dup = OICStrdup(value);
1841 VERIFY_PARAM_NON_NULL(TAG, dup, "Failed copying string");
1845 *stringLL = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
1846 VERIFY_PARAM_NON_NULL(TAG, *stringLL, "Failed allocating memory");
1847 (*stringLL)->value = dup;
1852 OCStringLL *temp = *stringLL;
1857 temp->next = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
1858 VERIFY_PARAM_NON_NULL(TAG, temp->next, "Failed allocating memory");
1859 temp->next->value = dup;
1867 void OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload, OCResourcePayload* res)
1874 if (!payload->resources)
1876 payload->resources = res;
1880 OCResourcePayload* p = payload->resources;
1889 void OCDiscoveryResourceDestroy(OCResourcePayload* payload)
1896 OICFree(payload->uri);
1897 OCFreeOCStringLL(payload->types);
1898 OCFreeOCStringLL(payload->interfaces);
1899 OCDiscoveryResourceDestroy(payload->next);
1903 void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload)
1909 OICFree(payload->sid);
1910 OICFree(payload->baseURI);
1911 OCFreeOCStringLL(payload->type);
1912 OICFree(payload->name);
1913 OCFreeOCStringLL(payload->iface);
1914 OCDiscoveryResourceDestroy(payload->resources);
1915 OCDiscoveryPayloadDestroy(payload->next);
1919 #ifdef WITH_PRESENCE
1920 OCPresencePayload* OCPresencePayloadCreate(uint32_t seqNum, uint32_t maxAge,
1921 OCPresenceTrigger trigger, const char* resourceType)
1923 OCPresencePayload* payload = (OCPresencePayload*)OICCalloc(1, sizeof(OCPresencePayload));
1929 payload->base.type = PAYLOAD_TYPE_PRESENCE;
1930 payload->sequenceNumber = seqNum;
1931 payload->maxAge = maxAge;
1932 payload->trigger = trigger;
1933 payload->resourceType = OICStrdup(resourceType);
1937 void OCPresencePayloadDestroy(OCPresencePayload* payload)
1943 OICFree(payload->resourceType);
1946 #endif // WITH_PRESENCE