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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
22 #include "ocpayload.h"
25 #include "oic_malloc.h"
26 #include "oic_string.h"
27 #include "ocstackinternal.h"
28 #include "ocresource.h"
30 #include "rdpayload.h"
32 #define TAG "OIC_RI_PAYLOAD"
34 static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val);
35 static void FreeOCDiscoveryResource(OCResourcePayload* payload);
37 void OCPayloadDestroy(OCPayload* payload)
46 case PAYLOAD_TYPE_REPRESENTATION:
47 OCRepPayloadDestroy((OCRepPayload*)payload);
49 case PAYLOAD_TYPE_DISCOVERY:
50 OCDiscoveryPayloadDestroy((OCDiscoveryPayload*)payload);
52 case PAYLOAD_TYPE_DEVICE:
53 OCDevicePayloadDestroy((OCDevicePayload*)payload);
55 case PAYLOAD_TYPE_PLATFORM:
56 OCPlatformPayloadDestroy((OCPlatformPayload*)payload);
58 case PAYLOAD_TYPE_PRESENCE:
59 OCPresencePayloadDestroy((OCPresencePayload*)payload);
61 case PAYLOAD_TYPE_SECURITY:
62 OCSecurityPayloadDestroy((OCSecurityPayload*)payload);
65 OCRDPayloadDestroy((OCRDPayload*)payload);
68 OIC_LOG_V(ERROR, TAG, "Unsupported payload type in destroy: %d", payload->type);
73 OCRepPayload* OCRepPayloadCreate()
75 OCRepPayload* payload = (OCRepPayload*)OICCalloc(1, sizeof(OCRepPayload));
82 payload->base.type = PAYLOAD_TYPE_REPRESENTATION;
87 void OCRepPayloadAppend(OCRepPayload* parent, OCRepPayload* child)
96 parent = parent->next;
103 static OCRepPayloadValue* OCRepPayloadFindValue(const OCRepPayload* payload, const char* name)
105 if (!payload || !name)
110 OCRepPayloadValue* val = payload->values;
113 if (0 == strcmp(val->name, name))
123 static void OCCopyPropertyValueArray(OCRepPayloadValue* dest, OCRepPayloadValue* source)
125 if (!dest || !source)
130 size_t dimTotal = calcDimTotal(source->arr.dimensions);
131 switch(source->arr.type)
134 dest->arr.iArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
135 memcpy(dest->arr.iArray, source->arr.iArray, dimTotal * sizeof(int64_t));
137 case OCREP_PROP_DOUBLE:
138 dest->arr.dArray = (double*)OICMalloc(dimTotal * sizeof(double));
139 memcpy(dest->arr.dArray, source->arr.dArray, dimTotal * sizeof(double));
141 case OCREP_PROP_BOOL:
142 dest->arr.bArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
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 for(size_t i = 0; i < dimTotal; ++i)
149 dest->arr.strArray[i] = OICStrdup(source->arr.strArray[i]);
152 case OCREP_PROP_ARRAY:
153 dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
154 for(size_t i = 0; i < dimTotal; ++i)
156 dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
160 OIC_LOG(ERROR, TAG, "CopyPropertyValueArray invalid type");
165 static void OCCopyPropertyValue (OCRepPayloadValue *dest, OCRepPayloadValue *source)
167 if (!source || !dest)
174 case OCREP_PROP_STRING:
175 dest->str = OICStrdup(source->str);
177 case OCREP_PROP_OBJECT:
178 dest->obj = OCRepPayloadClone(source->obj);
180 case OCREP_PROP_ARRAY:
181 OCCopyPropertyValueArray(dest, source);
184 // Nothing to do for the trivially copyable types.
189 static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val)
196 if (val->type == OCREP_PROP_STRING)
200 else if (val->type == OCREP_PROP_BYTE_STRING)
202 OICFree(val->ocByteStr.bytes);
204 else if (val->type == OCREP_PROP_OBJECT)
206 OCRepPayloadDestroy(val->obj);
208 else if (val->type == OCREP_PROP_ARRAY)
210 size_t dimTotal = calcDimTotal(val->arr.dimensions);
211 switch(val->arr.type)
214 case OCREP_PROP_DOUBLE:
215 case OCREP_PROP_BOOL:
216 // Since this is a union, iArray will
217 // point to all of the above
218 OICFree(val->arr.iArray);
220 case OCREP_PROP_STRING:
221 for(size_t i = 0; i< dimTotal; ++i)
223 OICFree(val->arr.strArray[i]);
225 OICFree(val->arr.strArray);
227 case OCREP_PROP_BYTE_STRING:
228 for (size_t i = 0; i< dimTotal; ++i)
230 OICFree(val->arr.ocByteStrArray[i].bytes);
232 OICFree(val->arr.ocByteStrArray);
234 case OCREP_PROP_OBJECT:
235 for(size_t i = 0; i< dimTotal; ++i)
237 OCRepPayloadDestroy(val->arr.objArray[i]);
239 OICFree(val->arr.objArray);
241 case OCREP_PROP_NULL:
242 case OCREP_PROP_ARRAY:
243 OIC_LOG_V(ERROR, TAG, "FreeRepPayloadValueContents: Illegal type\
244 inside an array: %d", val->arr.type);
250 static void OCFreeRepPayloadValue(OCRepPayloadValue* val)
258 OCFreeRepPayloadValueContents(val);
259 OCFreeRepPayloadValue(val->next);
262 static OCRepPayloadValue* OCRepPayloadValueClone (OCRepPayloadValue* source)
269 OCRepPayloadValue *sourceIter = source;
270 OCRepPayloadValue *destIter = (OCRepPayloadValue*) OICCalloc(1, sizeof(OCRepPayloadValue));
276 OCRepPayloadValue *headOfClone = destIter;
278 // Copy payload type and non pointer types in union.
279 *destIter = *sourceIter;
280 destIter->name = OICStrdup (sourceIter->name);
281 OCCopyPropertyValue (destIter, sourceIter);
283 sourceIter = sourceIter->next;
287 destIter->next = (OCRepPayloadValue*) OICCalloc(1, sizeof(OCRepPayloadValue));
290 OCFreeRepPayloadValue (headOfClone);
294 *(destIter->next) = *sourceIter;
295 destIter->next->name = OICStrdup (sourceIter->name);
296 OCCopyPropertyValue (destIter->next, sourceIter);
298 sourceIter = sourceIter->next;
299 destIter = destIter->next;
304 static OCRepPayloadValue* OCRepPayloadFindAndSetValue(OCRepPayload* payload, const char* name,
305 OCRepPayloadPropType type)
307 if (!payload || !name)
312 OCRepPayloadValue* val = payload->values;
315 payload->values = (OCRepPayloadValue*)OICCalloc(1, sizeof(OCRepPayloadValue));
316 if (!payload->values)
320 payload->values->name = OICStrdup(name);
321 if (!payload->values->name)
323 OICFree(payload->values);
324 payload->values = NULL;
327 payload->values->type =type;
328 return payload->values;
333 if (0 == strcmp(val->name, name))
335 OCFreeRepPayloadValueContents(val);
339 else if (val->next == NULL)
341 val->next = (OCRepPayloadValue*)OICCalloc(1, sizeof(OCRepPayloadValue));
346 val->next->name = OICStrdup(name);
347 if (!val->next->name)
353 val->next->type =type;
360 OIC_LOG(ERROR, TAG, "FindAndSetValue reached point after while loop, pointer corruption?");
364 bool OCRepPayloadAddResourceType(OCRepPayload* payload, const char* resourceType)
366 return OCRepPayloadAddResourceTypeAsOwner(payload, OICStrdup(resourceType));
369 bool OCRepPayloadAddResourceTypeAsOwner(OCRepPayload* payload, char* resourceType)
371 if (!payload || !resourceType)
378 OCStringLL* cur = payload->types;
383 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
390 cur->next->value = resourceType;
395 payload->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
400 payload->types->value = resourceType;
405 bool OCRepPayloadAddInterface(OCRepPayload* payload, const char* interface)
407 return OCRepPayloadAddInterfaceAsOwner(payload, OICStrdup(interface));
410 bool OCRepPayloadAddInterfaceAsOwner(OCRepPayload* payload, char* interface)
412 if (!payload || !interface)
417 if (payload->interfaces)
419 OCStringLL* cur = payload->interfaces;
424 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
430 cur->next->value = interface;
435 payload->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
436 if (!payload->interfaces)
440 payload->interfaces->value = interface;
445 bool OCRepPayloadSetUri(OCRepPayload* payload, const char* uri)
451 OICFree(payload->uri);
452 payload->uri = OICStrdup(uri);
453 return payload->uri != NULL;
456 bool OCRepPayloadIsNull(const OCRepPayload* payload, const char* name)
458 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
465 return val->type == OCREP_PROP_NULL;
468 static bool OCRepPayloadSetProp(OCRepPayload* payload, const char* name,
469 void* value, OCRepPayloadPropType type)
471 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, type);
479 val->i = *(int64_t*)value;
481 case OCREP_PROP_DOUBLE:
482 val->d = *(double*)value;
484 case OCREP_PROP_BOOL:
485 val->b = *(bool*)value;
487 case OCREP_PROP_OBJECT:
488 val->obj = (OCRepPayload*)value;
490 case OCREP_PROP_STRING:
491 val->str = (char*)value;
492 return val->str != NULL;
493 case OCREP_PROP_BYTE_STRING:
494 val->ocByteStr = *(OCByteString*)value;
496 case OCREP_PROP_NULL:
498 case OCREP_PROP_ARRAY:
506 bool OCRepPayloadSetNull(OCRepPayload* payload, const char* name)
508 return OCRepPayloadSetProp(payload, name, NULL, OCREP_PROP_NULL);
511 bool OCRepPayloadSetPropInt(OCRepPayload* payload,
512 const char* name, int64_t value)
514 return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_INT);
517 bool OCRepPayloadGetPropInt(const OCRepPayload* payload, const char* name, int64_t* value)
519 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
521 if (!val || val->type != OCREP_PROP_INT)
530 bool OCRepPayloadSetPropDouble(OCRepPayload* payload,
531 const char* name, double value)
533 return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_DOUBLE);
536 bool OCRepPayloadGetPropDouble(const OCRepPayload* payload, const char* name, double* value)
538 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
540 if (!val || val->type != OCREP_PROP_DOUBLE)
549 bool OCRepPayloadSetPropString(OCRepPayload* payload, const char* name, const char* value)
551 char* temp = OICStrdup(value);
552 bool b = OCRepPayloadSetPropStringAsOwner(payload, name, temp);
561 bool OCRepPayloadSetPropStringAsOwner(OCRepPayload* payload, const char* name, char* value)
563 return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_STRING);
566 bool OCRepPayloadGetPropString(const OCRepPayload* payload, const char* name, char** value)
568 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
570 if (!val || val->type != OCREP_PROP_STRING)
575 *value = OICStrdup(val->str);
576 return *value != NULL;
579 bool OCRepPayloadSetPropByteString(OCRepPayload* payload, const char* name, OCByteString value)
581 if (!value.bytes || !value.len)
586 OCByteString ocByteStr = {
587 .bytes = (uint8_t*)OICMalloc(value.len * sizeof(uint8_t)),
590 if (!ocByteStr.bytes)
594 memcpy(ocByteStr.bytes, value.bytes, ocByteStr.len);
596 bool b = OCRepPayloadSetPropByteStringAsOwner(payload, name, &ocByteStr);
600 OICFree(ocByteStr.bytes);
605 bool OCRepPayloadSetPropByteStringAsOwner(OCRepPayload* payload, const char* name, OCByteString* value)
607 return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_BYTE_STRING);
610 bool OCRepPayloadGetPropByteString(const OCRepPayload* payload, const char* name, OCByteString* value)
612 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
614 if (!val || val->type != OCREP_PROP_BYTE_STRING)
624 value->bytes = (uint8_t*)OICMalloc(val->ocByteStr.len * sizeof(uint8_t));
629 value->len = val->ocByteStr.len;
630 memcpy(value->bytes, val->ocByteStr.bytes, value->len);
635 bool OCRepPayloadSetPropBool(OCRepPayload* payload,
636 const char* name, bool value)
638 return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_BOOL);
641 bool OCRepPayloadGetPropBool(const OCRepPayload* payload, const char* name, bool* value)
643 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
645 if (!val || val->type != OCREP_PROP_BOOL)
654 bool OCRepPayloadSetPropObject(OCRepPayload* payload, const char* name, const OCRepPayload* value)
656 OCRepPayload* temp = OCRepPayloadClone(value);
657 bool b = OCRepPayloadSetPropObjectAsOwner(payload, name, temp);
661 OCRepPayloadDestroy(temp);
666 bool OCRepPayloadSetPropObjectAsOwner(OCRepPayload* payload, const char* name, OCRepPayload* value)
668 return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_OBJECT);
671 bool OCRepPayloadGetPropObject(const OCRepPayload* payload, const char* name, OCRepPayload** value)
673 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
675 if (!val || val->type != OCREP_PROP_OBJECT)
680 *value = OCRepPayloadClone(val->obj);
681 return *value != NULL;
684 size_t calcDimTotal(const size_t dimensions[MAX_REP_ARRAY_DEPTH])
686 if (dimensions[0] == 0)
692 for(uint8_t i = 0; i < MAX_REP_ARRAY_DEPTH && dimensions[i] != 0; ++i)
694 total *= dimensions[i];
700 bool OCRepPayloadSetByteStringArrayAsOwner(OCRepPayload* payload, const char* name,
701 OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
703 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
710 val->arr.type = OCREP_PROP_BYTE_STRING;
711 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
712 val->arr.ocByteStrArray = array;
717 bool OCRepPayloadSetByteStringArray(OCRepPayload* payload, const char* name,
718 const OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
725 size_t dimTotal = calcDimTotal(dimensions);
731 OCByteString* newArray = (OCByteString*)OICCalloc(dimTotal, sizeof(OCByteString));
738 for (size_t i = 0; i < dimTotal; ++i)
740 newArray[i].bytes = (uint8_t*)OICMalloc(array[i].len * sizeof(uint8_t));
741 if (NULL == newArray[i].bytes)
743 for (size_t j = 0; j < i; ++j)
745 OICFree(newArray[j].bytes);
751 newArray[i].len = array[i].len;
752 memcpy(newArray[i].bytes, array[i].bytes, newArray[i].len);
755 bool b = OCRepPayloadSetByteStringArrayAsOwner(payload, name, newArray, dimensions);
758 for (size_t i = 0; i < dimTotal; ++i)
760 OICFree(newArray[i].bytes);
768 bool OCRepPayloadGetByteStringArray(const OCRepPayload* payload, const char* name,
769 OCByteString** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
771 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
773 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_BYTE_STRING
774 || !val->arr.ocByteStrArray)
779 size_t dimTotal = calcDimTotal(val->arr.dimensions);
785 *array = (OCByteString*)OICCalloc(dimTotal, sizeof(OCByteString));
791 for (size_t i = 0; i < dimTotal; ++i)
793 OCByteString* tmp = &(*array)[i];
794 tmp->bytes = (uint8_t*)OICMalloc(val->arr.ocByteStrArray[i].len * sizeof(uint8_t));
795 if (NULL == tmp->bytes)
797 for (size_t j = 0; j < i; ++j)
799 OCByteString* tmp = &(*array)[j];
807 tmp->len = val->arr.ocByteStrArray[i].len;
808 memcpy(tmp->bytes, val->arr.ocByteStrArray[i].bytes, tmp->len);
811 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
816 bool OCRepPayloadSetIntArrayAsOwner(OCRepPayload* payload, const char* name,
817 int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
819 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
826 val->arr.type = OCREP_PROP_INT;
827 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
828 val->arr.iArray = array;
833 bool OCRepPayloadSetIntArray(OCRepPayload* payload, const char* name,
834 const int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
836 size_t dimTotal = calcDimTotal(dimensions);
842 int64_t* newArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
849 memcpy(newArray, array, dimTotal * sizeof(int64_t));
852 bool b = OCRepPayloadSetIntArrayAsOwner(payload, name, newArray, dimensions);
860 bool OCRepPayloadGetIntArray(const OCRepPayload* payload, const char* name,
861 int64_t** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
863 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
865 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_INT
871 size_t dimTotal = calcDimTotal(val->arr.dimensions);
876 *array = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
882 memcpy(*array, val->arr.iArray, dimTotal * sizeof(int64_t));
883 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
887 bool OCRepPayloadSetDoubleArrayAsOwner(OCRepPayload* payload, const char* name,
888 double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
890 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
897 val->arr.type = OCREP_PROP_DOUBLE;
898 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
899 val->arr.dArray = array;
903 bool OCRepPayloadSetDoubleArray(OCRepPayload* payload, const char* name,
904 const double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
906 size_t dimTotal = calcDimTotal(dimensions);
912 double* newArray = (double*)OICMalloc(dimTotal * sizeof(double));
919 memcpy(newArray, array, dimTotal * sizeof(double));
921 bool b = OCRepPayloadSetDoubleArrayAsOwner(payload, name, newArray, dimensions);
929 bool OCRepPayloadGetDoubleArray(const OCRepPayload* payload, const char* name,
930 double** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
932 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
934 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_DOUBLE
940 size_t dimTotal = calcDimTotal(val->arr.dimensions);
945 *array = (double*)OICMalloc(dimTotal * sizeof(double));
951 memcpy(*array, val->arr.dArray, dimTotal * sizeof(double));
952 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
956 bool OCRepPayloadSetStringArrayAsOwner(OCRepPayload* payload, const char* name,
957 char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
959 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
966 val->arr.type = OCREP_PROP_STRING;
967 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
968 val->arr.strArray = array;
972 bool OCRepPayloadSetStringArray(OCRepPayload* payload, const char* name,
973 const char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
975 size_t dimTotal = calcDimTotal(dimensions);
981 char** newArray = (char**)OICMalloc(dimTotal * sizeof(char*));
988 for(size_t i = 0; i < dimTotal; ++i)
990 newArray[i] = OICStrdup(array[i]);
993 bool b = OCRepPayloadSetStringArrayAsOwner(payload, name, newArray, dimensions);
997 for(size_t i = 0; i < dimTotal; ++i)
999 OICFree(newArray[i]);
1006 bool OCRepPayloadGetStringArray(const OCRepPayload* payload, const char* name,
1007 char*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1009 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1011 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_STRING
1012 || !val->arr.strArray)
1017 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1022 *array = (char**)OICMalloc(dimTotal * sizeof(char*));
1028 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1030 for(size_t i = 0; i < dimTotal; ++i)
1032 (*array)[i] = OICStrdup(val->arr.strArray[i]);
1039 bool OCRepPayloadSetBoolArrayAsOwner(OCRepPayload* payload, const char* name,
1040 bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1043 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1050 val->arr.type = OCREP_PROP_BOOL;
1051 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1052 val->arr.bArray = array;
1056 bool OCRepPayloadSetBoolArray(OCRepPayload* payload, const char* name,
1057 const bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1059 size_t dimTotal = calcDimTotal(dimensions);
1065 bool* newArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
1072 memcpy(newArray, array, dimTotal * sizeof(bool));
1075 bool b = OCRepPayloadSetBoolArrayAsOwner(payload, name, newArray, dimensions);
1083 bool OCRepPayloadGetBoolArray(const OCRepPayload* payload, const char* name,
1084 bool** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1086 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1088 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_BOOL
1089 || !val->arr.bArray)
1094 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1099 *array = (bool*)OICMalloc(dimTotal * sizeof(bool));
1105 memcpy(*array, val->arr.bArray, dimTotal * sizeof(bool));
1106 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1110 bool OCRepPayloadSetPropObjectArrayAsOwner(OCRepPayload* payload, const char* name,
1111 OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1113 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1120 val->arr.type = OCREP_PROP_OBJECT;
1121 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1122 val->arr.objArray = array;
1127 bool OCRepPayloadSetPropObjectArray(OCRepPayload* payload, const char* name,
1128 const OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1130 size_t dimTotal = calcDimTotal(dimensions);
1136 OCRepPayload** newArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
1143 for(size_t i = 0; i < dimTotal; ++i)
1145 newArray[i] = OCRepPayloadClone(array[i]);
1148 bool b = OCRepPayloadSetPropObjectArrayAsOwner(payload, name, newArray, dimensions);
1152 for(size_t i = 0; i < dimTotal; ++i)
1154 OCRepPayloadDestroy(newArray[i]);
1161 bool OCRepPayloadGetPropObjectArray(const OCRepPayload* payload, const char* name,
1162 OCRepPayload*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1164 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1166 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_OBJECT
1167 || !val->arr.objArray)
1172 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1177 *array = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
1183 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1185 for(size_t i = 0; i < dimTotal; ++i)
1187 (*array)[i] = OCRepPayloadClone(val->arr.objArray[i]);
1193 void OCFreeOCStringLL(OCStringLL* ll)
1200 OCFreeOCStringLL(ll->next);
1205 OCStringLL* CloneOCStringLL (OCStringLL* ll)
1212 OCStringLL *sourceIter = ll;
1214 OCStringLL *destIter = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
1219 destIter->value = OICStrdup (sourceIter->value);
1221 OCStringLL *headOfClone = destIter;
1223 sourceIter = sourceIter->next;
1227 destIter->next = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
1228 if (!destIter->next)
1230 OCFreeOCStringLL (headOfClone);
1233 destIter->next->value = OICStrdup (sourceIter->value);
1235 destIter = destIter->next;
1236 sourceIter = sourceIter->next;
1241 OCRepPayload* OCRepPayloadClone (const OCRepPayload* payload)
1248 OCRepPayload *clone = OCRepPayloadCreate();
1255 clone->uri = OICStrdup (payload->uri);
1256 clone->types = CloneOCStringLL (payload->types);
1257 clone->interfaces = CloneOCStringLL (payload->interfaces);
1258 clone->values = OCRepPayloadValueClone (payload->values);
1264 void OCRepPayloadDestroy(OCRepPayload* payload)
1271 OICFree(payload->uri);
1272 OCFreeOCStringLL(payload->types);
1273 OCFreeOCStringLL(payload->interfaces);
1274 OCFreeRepPayloadValue(payload->values);
1275 OCRepPayloadDestroy(payload->next);
1279 OCDiscoveryPayload* OCDiscoveryPayloadCreate()
1281 OCDiscoveryPayload* payload = (OCDiscoveryPayload*)OICCalloc(1, sizeof(OCDiscoveryPayload));
1288 payload->base.type = PAYLOAD_TYPE_DISCOVERY;
1293 OCSecurityPayload* OCSecurityPayloadCreate(const char* securityData)
1295 OCSecurityPayload* payload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1302 payload->base.type = PAYLOAD_TYPE_SECURITY;
1303 payload->securityData = OICStrdup(securityData);
1308 void OCSecurityPayloadDestroy(OCSecurityPayload* payload)
1315 OICFree(payload->securityData);
1319 size_t OCDiscoveryPayloadGetResourceCount(OCDiscoveryPayload* payload)
1322 OCResourcePayload* p = payload->resources;
1331 OCResourcePayload* OCDiscoveryPayloadGetResource(OCDiscoveryPayload* payload, size_t index)
1334 OCResourcePayload* p = payload->resources;
1347 static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t port)
1349 OCResourcePayload* pl = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1355 pl->uri = OICStrdup(res->uri);
1359 FreeOCDiscoveryResource(pl);
1364 OCResourceType* typePtr = res->rsrcType;
1366 if (typePtr != NULL)
1368 pl->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1371 FreeOCDiscoveryResource(pl);
1374 pl->types->value = OICStrdup(typePtr->resourcetypename);
1375 if (!pl->types->value)
1377 FreeOCDiscoveryResource(pl);
1381 OCStringLL* cur = pl->types;
1382 typePtr = typePtr->next;
1385 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1388 FreeOCDiscoveryResource(pl);
1391 cur->next->value = OICStrdup(typePtr->resourcetypename);
1392 if (!cur->next->value)
1394 FreeOCDiscoveryResource(pl);
1398 typePtr = typePtr->next;
1403 OCResourceInterface* ifPtr = res->rsrcInterface;
1406 pl->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1407 if (!pl->interfaces)
1409 FreeOCDiscoveryResource(pl);
1412 pl->interfaces->value = OICStrdup(ifPtr->name);
1413 if (!pl->interfaces->value)
1415 FreeOCDiscoveryResource(pl);
1419 OCStringLL* cur = pl->interfaces;
1420 ifPtr = ifPtr->next;
1423 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1426 FreeOCDiscoveryResource(pl);
1429 cur->next->value = OICStrdup(ifPtr->name);
1430 if (!cur->next->value)
1432 FreeOCDiscoveryResource(pl);
1436 ifPtr = ifPtr->next;
1440 pl->bitmap = res->resourceProperties & (OC_OBSERVABLE | OC_DISCOVERABLE);
1441 pl->secure = (res->resourceProperties & OC_SECURE) != 0;
1447 void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
1450 OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, port));
1453 bool OCResourcePayloadAddResourceType(OCResourcePayload* payload, const char* resourceType)
1455 if (!resourceType || !payload)
1460 char* dup = OICStrdup(resourceType);
1467 if (!payload->types)
1469 payload->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1471 if (!payload->types)
1477 payload->types->value = dup;
1483 OCStringLL* temp = payload->types;
1490 temp->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1497 temp->next->value = dup;
1502 bool OCResourcePayloadAddInterface(OCResourcePayload* payload, const char* interface)
1504 if (!interface || !payload)
1509 char* dup = OICStrdup(interface);
1516 if (!payload->interfaces)
1518 payload->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1520 if (!payload->interfaces)
1526 payload->interfaces->value = dup;
1532 OCStringLL* temp = payload->interfaces;
1539 temp->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1546 temp->next->value = dup;
1551 void OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload, OCResourcePayload* res)
1558 if (!payload->resources)
1560 payload->resources = res;
1564 OCResourcePayload* p = payload->resources;
1573 static void FreeOCDiscoveryResource(OCResourcePayload* payload)
1580 OICFree(payload->uri);
1581 OCFreeOCStringLL(payload->types);
1582 OCFreeOCStringLL(payload->interfaces);
1583 FreeOCDiscoveryResource(payload->next);
1587 void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload)
1593 OICFree(payload->sid);
1594 FreeOCDiscoveryResource(payload->resources);
1598 OCDevicePayload* OCDevicePayloadCreate(const uint8_t* sid, const char* dname,
1599 const char* specVer, const char* dmVer)
1602 OCDevicePayload* payload = (OCDevicePayload*)OICCalloc(1, sizeof(OCDevicePayload));
1609 payload->base.type = PAYLOAD_TYPE_DEVICE;
1613 payload->sid = (uint8_t*)OICMalloc(UUID_SIZE);
1618 memcpy(payload->sid, sid, UUID_SIZE);
1621 payload->deviceName = OICStrdup(dname);
1622 if (dname && !payload->deviceName)
1627 payload->specVersion = OICStrdup(specVer);
1628 if (specVer && !payload->specVersion)
1633 payload->dataModelVersion = OICStrdup(dmVer);
1634 if (dmVer && !payload->dataModelVersion)
1642 OCDevicePayloadDestroy((OCDevicePayload*)payload);
1646 void OCDevicePayloadDestroy(OCDevicePayload* payload)
1653 OICFree(payload->sid);
1654 OICFree(payload->deviceName);
1655 OICFree(payload->specVersion);
1656 OICFree(payload->dataModelVersion);
1660 static void OCCopyPlatformInfo(const OCPlatformInfo* platformInfo, OCPlatformPayload* target)
1662 if (!platformInfo || !target)
1667 target->info.platformID = OICStrdup(platformInfo->platformID);
1668 target->info.manufacturerName = OICStrdup(platformInfo->manufacturerName);
1669 target->info.manufacturerUrl = OICStrdup(platformInfo->manufacturerUrl);
1670 target->info.modelNumber = OICStrdup(platformInfo->modelNumber);
1671 target->info.dateOfManufacture = OICStrdup(platformInfo->dateOfManufacture);
1672 target->info.platformVersion = OICStrdup(platformInfo->platformVersion);
1673 target->info.operatingSystemVersion = OICStrdup(platformInfo->operatingSystemVersion);
1674 target->info.hardwareVersion = OICStrdup(platformInfo->hardwareVersion);
1675 target->info.firmwareVersion = OICStrdup(platformInfo->firmwareVersion);
1676 target->info.supportUrl = OICStrdup(platformInfo->supportUrl);
1677 target->info.systemTime = OICStrdup(platformInfo->systemTime);
1680 OCPlatformPayload* OCPlatformPayloadCreateAsOwner(OCPlatformInfo* platformInfo)
1682 OCPlatformPayload* payload = (OCPlatformPayload*)OICCalloc(1, sizeof(OCPlatformPayload));
1688 payload->base.type = PAYLOAD_TYPE_PLATFORM;
1689 payload->info = *platformInfo;
1694 OCPlatformPayload* OCPlatformPayloadCreate(const OCPlatformInfo* platformInfo)
1696 OCPlatformPayload* payload = (OCPlatformPayload*)OICCalloc(1, sizeof(OCPlatformPayload));
1703 payload->base.type = PAYLOAD_TYPE_PLATFORM;
1704 OCCopyPlatformInfo(platformInfo, payload);
1709 void OCPlatformPayloadDestroy(OCPlatformPayload* payload)
1715 OICFree(payload->uri);
1716 OICFree(payload->info.platformID);
1717 OICFree(payload->info.manufacturerName);
1718 OICFree(payload->info.manufacturerUrl);
1719 OICFree(payload->info.modelNumber);
1720 OICFree(payload->info.dateOfManufacture);
1721 OICFree(payload->info.platformVersion);
1722 OICFree(payload->info.operatingSystemVersion);
1723 OICFree(payload->info.hardwareVersion);
1724 OICFree(payload->info.firmwareVersion);
1725 OICFree(payload->info.supportUrl);
1726 OICFree(payload->info.systemTime);
1730 OCPresencePayload* OCPresencePayloadCreate(uint32_t seqNum, uint32_t maxAge,
1731 OCPresenceTrigger trigger, const char* resourceType)
1733 OCPresencePayload* payload = (OCPresencePayload*)OICCalloc(1, sizeof(OCPresencePayload));
1739 payload->base.type = PAYLOAD_TYPE_PRESENCE;
1740 payload->sequenceNumber = seqNum;
1741 payload->maxAge = maxAge;
1742 payload->trigger = trigger;
1743 payload->resourceType = OICStrdup(resourceType);
1747 void OCPresencePayloadDestroy(OCPresencePayload* payload)
1753 OICFree(payload->resourceType);