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"
27 #include "occollection.h"
30 #include "oic_malloc.h"
31 #include "oic_string.h"
32 #include "ocstackinternal.h"
33 #include "ocresource.h"
35 #include "ocendpoint.h"
38 #define TAG "OIC_RI_PAYLOAD"
39 #define CSV_SEPARATOR ','
40 #define MASK_SECURE_FAMS (OC_FLAG_SECURE | OC_MASK_FAMS)
42 static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val);
44 void OC_CALL OCPayloadDestroy(OCPayload* payload)
53 case PAYLOAD_TYPE_REPRESENTATION:
54 OCRepPayloadDestroy((OCRepPayload*)payload);
56 case PAYLOAD_TYPE_DISCOVERY:
57 OCDiscoveryPayloadDestroy((OCDiscoveryPayload*)payload);
59 case PAYLOAD_TYPE_PRESENCE:
60 OCPresencePayloadDestroy((OCPresencePayload*)payload);
62 case PAYLOAD_TYPE_DIAGNOSTIC:
63 OCDiagnosticPayloadDestroy((OCDiagnosticPayload*)payload);
65 case PAYLOAD_TYPE_SECURITY:
66 OCSecurityPayloadDestroy((OCSecurityPayload*)payload);
68 case PAYLOAD_TYPE_INTROSPECTION:
69 OCIntrospectionPayloadDestroy((OCIntrospectionPayload*)payload);
72 OIC_LOG_V(ERROR, TAG, "Unsupported payload type in destroy: %d", payload->type);
78 OCRepPayload* OC_CALL OCRepPayloadCreate()
80 OCRepPayload* payload = (OCRepPayload*)OICCalloc(1, sizeof(OCRepPayload));
87 payload->base.type = PAYLOAD_TYPE_REPRESENTATION;
92 void OC_CALL OCRepPayloadAppend(OCRepPayload* parent, OCRepPayload* child)
101 parent = parent->next;
108 static OCRepPayloadValue* OC_CALL OCRepPayloadFindValue(const OCRepPayload* payload, const char* name)
110 if (!payload || !name)
115 OCRepPayloadValue* val = payload->values;
118 if (0 == strcmp(val->name, name))
128 static void OC_CALL OCCopyPropertyValueArray(OCRepPayloadValue* dest, OCRepPayloadValue* source)
130 if (!dest || !source)
135 size_t dimTotal = calcDimTotal(source->arr.dimensions);
136 switch(source->arr.type)
139 dest->arr.iArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
140 VERIFY_PARAM_NON_NULL(TAG, dest->arr.iArray, "Failed allocating memory");
141 memcpy(dest->arr.iArray, source->arr.iArray, dimTotal * sizeof(int64_t));
143 case OCREP_PROP_DOUBLE:
144 dest->arr.dArray = (double*)OICMalloc(dimTotal * sizeof(double));
145 VERIFY_PARAM_NON_NULL(TAG, dest->arr.dArray, "Failed allocating memory");
146 memcpy(dest->arr.dArray, source->arr.dArray, dimTotal * sizeof(double));
148 case OCREP_PROP_BOOL:
149 dest->arr.bArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
150 VERIFY_PARAM_NON_NULL(TAG, dest->arr.bArray, "Failed allocating memory");
151 memcpy(dest->arr.bArray, source->arr.bArray, dimTotal * sizeof(bool));
153 case OCREP_PROP_STRING:
154 dest->arr.strArray = (char**)OICMalloc(dimTotal * sizeof(char*));
155 VERIFY_PARAM_NON_NULL(TAG, dest->arr.strArray, "Failed allocating memory");
156 for(size_t i = 0; i < dimTotal; ++i)
158 dest->arr.strArray[i] = OICStrdup(source->arr.strArray[i]);
159 VERIFY_PARAM_NON_NULL(TAG, dest->arr.strArray[i], "Failed to duplicate string");
162 case OCREP_PROP_OBJECT:
163 dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
164 VERIFY_PARAM_NON_NULL(TAG, dest->arr.objArray, "Failed allocating memory");
165 for(size_t i = 0; i < dimTotal; ++i)
167 dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
170 case OCREP_PROP_ARRAY:
171 dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
172 VERIFY_PARAM_NON_NULL(TAG, dest->arr.objArray, "Failed allocating memory");
173 for(size_t i = 0; i < dimTotal; ++i)
175 dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
178 case OCREP_PROP_BYTE_STRING:
179 dest->arr.ocByteStrArray = (OCByteString*)OICCalloc(dimTotal, sizeof(OCByteString));
180 VERIFY_PARAM_NON_NULL(TAG, dest->arr.ocByteStrArray, "Failed allocating memory");
181 for (size_t i = 0; i < dimTotal; ++i)
183 OCByteStringCopy(&dest->arr.ocByteStrArray[i], &source->arr.ocByteStrArray[i]);
184 VERIFY_PARAM_NON_NULL(TAG, dest->arr.ocByteStrArray[i].bytes, "Failed allocating memory");
188 OIC_LOG(ERROR, TAG, "CopyPropertyValueArray invalid type");
195 static void OC_CALL OCCopyPropertyValue (OCRepPayloadValue *dest, OCRepPayloadValue *source)
197 if (!source || !dest)
204 case OCREP_PROP_STRING:
205 dest->str = OICStrdup(source->str);
207 case OCREP_PROP_BYTE_STRING:
208 dest->ocByteStr.bytes = (uint8_t*)OICMalloc(source->ocByteStr.len * sizeof(uint8_t));
209 VERIFY_PARAM_NON_NULL(TAG, dest->ocByteStr.bytes, "Failed allocating memory");
210 dest->ocByteStr.len = source->ocByteStr.len;
211 memcpy(dest->ocByteStr.bytes, source->ocByteStr.bytes, dest->ocByteStr.len);
213 case OCREP_PROP_OBJECT:
214 dest->obj = OCRepPayloadClone(source->obj);
216 case OCREP_PROP_ARRAY:
217 OCCopyPropertyValueArray(dest, source);
220 // Nothing to do for the trivially copyable types.
227 static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val)
234 if (val->type == OCREP_PROP_STRING)
238 else if (val->type == OCREP_PROP_BYTE_STRING)
240 OICFree(val->ocByteStr.bytes);
242 else if (val->type == OCREP_PROP_OBJECT)
244 OCRepPayloadDestroy(val->obj);
246 else if (val->type == OCREP_PROP_ARRAY)
248 size_t dimTotal = calcDimTotal(val->arr.dimensions);
249 switch(val->arr.type)
252 case OCREP_PROP_DOUBLE:
253 case OCREP_PROP_BOOL:
254 // Since this is a union, iArray will
255 // point to all of the above
256 OICFree(val->arr.iArray);
258 case OCREP_PROP_STRING:
259 for(size_t i = 0; i < dimTotal; ++i)
261 OICFree(val->arr.strArray[i]);
263 OICFree(val->arr.strArray);
265 case OCREP_PROP_BYTE_STRING:
266 for (size_t i = 0; i < dimTotal; ++i)
268 if (val->arr.ocByteStrArray[i].bytes)
270 OICFree(val->arr.ocByteStrArray[i].bytes);
273 OICFree(val->arr.ocByteStrArray);
275 case OCREP_PROP_OBJECT: // This case is the temporary fix for string input
276 for(size_t i = 0; i< dimTotal; ++i)
278 OCRepPayloadDestroy(val->arr.objArray[i]);
280 OICFree(val->arr.objArray);
282 case OCREP_PROP_NULL:
283 case OCREP_PROP_ARRAY:
284 OIC_LOG_V(ERROR, TAG, "FreeRepPayloadValueContents: Illegal type\
285 inside an array: %d", val->arr.type);
291 static void OC_CALL OCFreeRepPayloadValue(OCRepPayloadValue* val)
299 OCFreeRepPayloadValueContents(val);
300 OCFreeRepPayloadValue(val->next);
303 static OCRepPayloadValue* OC_CALL OCRepPayloadValueClone (OCRepPayloadValue* source)
310 OCRepPayloadValue *sourceIter = source;
311 OCRepPayloadValue *destIter = (OCRepPayloadValue*) OICCalloc(1, sizeof(OCRepPayloadValue));
317 OCRepPayloadValue *headOfClone = destIter;
319 // Copy payload type and non pointer types in union.
320 *destIter = *sourceIter;
321 destIter->name = OICStrdup (sourceIter->name);
322 OCCopyPropertyValue (destIter, sourceIter);
324 sourceIter = sourceIter->next;
328 destIter->next = (OCRepPayloadValue*) OICCalloc(1, sizeof(OCRepPayloadValue));
331 OCFreeRepPayloadValue (headOfClone);
335 *(destIter->next) = *sourceIter;
336 destIter->next->name = OICStrdup (sourceIter->name);
337 OCCopyPropertyValue (destIter->next, sourceIter);
339 sourceIter = sourceIter->next;
340 destIter = destIter->next;
345 static OCRepPayloadValue* OC_CALL OCRepPayloadFindAndSetValue(OCRepPayload* payload, const char* name,
346 OCRepPayloadPropType type)
348 if (!payload || !name)
353 OCRepPayloadValue* val = payload->values;
356 payload->values = (OCRepPayloadValue*)OICCalloc(1, sizeof(OCRepPayloadValue));
357 if (!payload->values)
361 payload->values->name = OICStrdup(name);
362 if (!payload->values->name)
364 OICFree(payload->values);
365 payload->values = NULL;
368 payload->values->type =type;
369 return payload->values;
374 if (0 == strcmp(val->name, name))
376 OCFreeRepPayloadValueContents(val);
380 else if (val->next == NULL)
382 val->next = (OCRepPayloadValue*)OICCalloc(1, sizeof(OCRepPayloadValue));
387 val->next->name = OICStrdup(name);
388 if (!val->next->name)
394 val->next->type =type;
401 OIC_LOG(ERROR, TAG, "FindAndSetValue reached point after while loop, pointer corruption?");
405 bool OC_CALL OCRepPayloadAddResourceType(OCRepPayload* payload, const char* resourceType)
407 return OCRepPayloadAddResourceTypeAsOwner(payload, OICStrdup(resourceType));
410 bool OC_CALL OCRepPayloadAddResourceTypeAsOwner(OCRepPayload* payload, char* resourceType)
412 if (!payload || !resourceType)
419 OCStringLL* cur = payload->types;
424 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
431 cur->next->value = resourceType;
436 payload->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
441 payload->types->value = resourceType;
446 bool OC_CALL OCRepPayloadAddInterface(OCRepPayload* payload, const char* iface)
448 return OCRepPayloadAddInterfaceAsOwner(payload, OICStrdup(iface));
451 bool OC_CALL OCRepPayloadAddInterfaceAsOwner(OCRepPayload* payload, char* iface)
453 if (!payload || !iface)
458 if (payload->interfaces)
460 OCStringLL* cur = payload->interfaces;
465 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
471 cur->next->value = iface;
476 payload->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
477 if (!payload->interfaces)
481 payload->interfaces->value = iface;
486 bool OC_CALL OCRepPayloadSetUri(OCRepPayload* payload, const char* uri)
492 OICFree(payload->uri);
493 payload->uri = OICStrdup(uri);
494 return payload->uri != NULL;
497 bool OC_CALL OCRepPayloadIsNull(const OCRepPayload* payload, const char* name)
499 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
506 return val->type == OCREP_PROP_NULL;
509 static bool OC_CALL OCRepPayloadSetProp(OCRepPayload* payload, const char* name,
510 void* value, OCRepPayloadPropType type)
512 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, type);
520 val->i = *(int64_t*)value;
522 case OCREP_PROP_DOUBLE:
523 val->d = *(double*)value;
525 case OCREP_PROP_BOOL:
526 val->b = *(bool*)value;
528 case OCREP_PROP_OBJECT:
529 val->obj = (OCRepPayload*)value;
531 case OCREP_PROP_STRING:
532 val->str = (char*)value;
533 return val->str != NULL;
534 case OCREP_PROP_BYTE_STRING:
535 val->ocByteStr = *(OCByteString*)value;
537 case OCREP_PROP_NULL:
539 case OCREP_PROP_ARRAY:
547 bool OC_CALL OCRepPayloadSetNull(OCRepPayload* payload, const char* name)
549 return OCRepPayloadSetProp(payload, name, NULL, OCREP_PROP_NULL);
552 bool OC_CALL OCRepPayloadSetPropInt(OCRepPayload* payload,
553 const char* name, int64_t value)
555 return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_INT);
558 bool OC_CALL OCRepPayloadGetPropInt(const OCRepPayload* payload, const char* name, int64_t* value)
560 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
562 if (!val || val->type != OCREP_PROP_INT)
571 bool OC_CALL OCRepPayloadSetPropDouble(OCRepPayload* payload,
572 const char* name, double value)
574 return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_DOUBLE);
577 bool OC_CALL OCRepPayloadGetPropDouble(const OCRepPayload* payload, const char* name, double* value)
579 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
583 if (val->type == OCREP_PROP_DOUBLE)
588 else if (val->type == OCREP_PROP_INT)
590 // Should be removed once IOT-1705 is fixed.
592 #pragma warning( suppress : 4244 )
604 bool OC_CALL OCRepPayloadSetPropString(OCRepPayload* payload, const char* name, const char* value)
606 char* temp = OICStrdup(value);
607 bool b = OCRepPayloadSetPropStringAsOwner(payload, name, temp);
616 bool OC_CALL OCRepPayloadSetPropStringAsOwner(OCRepPayload* payload, const char* name, char* value)
618 return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_STRING);
621 bool OC_CALL OCRepPayloadGetPropString(const OCRepPayload* payload, const char* name, char** value)
623 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
625 if (!val || val->type != OCREP_PROP_STRING)
630 *value = OICStrdup(val->str);
631 return *value != NULL;
634 bool OC_CALL OCRepPayloadSetPropByteString(OCRepPayload* payload, const char* name, OCByteString value)
636 OCByteString ocByteStr = {NULL, 0};
637 bool b = OCByteStringCopy(&ocByteStr, &value);
641 b = OCRepPayloadSetPropByteStringAsOwner(payload, name, &ocByteStr);
645 OICFree(ocByteStr.bytes);
650 bool OC_CALL OCRepPayloadSetPropByteStringAsOwner(OCRepPayload* payload, const char* name, OCByteString* value)
652 return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_BYTE_STRING);
655 bool OC_CALL OCRepPayloadGetPropByteString(const OCRepPayload* payload, const char* name, OCByteString* value)
657 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
659 if (!val || val->type != OCREP_PROP_BYTE_STRING)
669 if (val->ocByteStr.len)
671 value->bytes = (uint8_t*)OICMalloc(val->ocByteStr.len * sizeof(uint8_t));
681 value->len = val->ocByteStr.len;
682 memcpy(value->bytes, val->ocByteStr.bytes, value->len);
687 bool OC_CALL OCRepPayloadSetPropBool(OCRepPayload* payload,
688 const char* name, bool value)
690 return OCRepPayloadSetProp(payload, name, &value, OCREP_PROP_BOOL);
693 bool OC_CALL OCRepPayloadGetPropBool(const OCRepPayload* payload, const char* name, bool* value)
695 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
697 if (!val || val->type != OCREP_PROP_BOOL)
707 static char *getStringFromEncodingType(OicEncodingType_t type)
712 case OIC_ENCODING_BASE64: str = OC_RSRVD_BASE64; break;
713 case OIC_ENCODING_DER: str = OC_RSRVD_DER; break;
714 case OIC_ENCODING_PEM: str = OC_RSRVD_PEM; break;
715 case OIC_ENCODING_RAW: str = OC_RSRVD_RAW; break;
716 default: str = OC_RSRVD_UNKNOWN; break;
719 snprintf(encoding, sizeof(encoding), "%s.%s.%s", OC_OIC_SEC, OC_RSRVD_ENCODING, str);
721 return OICStrdup(encoding);
724 bool OC_CALL OCRepPayloadSetPropPubDataTypeAsOwner(OCRepPayload *payload, const char *name,
725 const OicSecKey_t *value)
727 if (!payload || !name || !value)
732 bool binary_field = false;
733 if (OIC_ENCODING_RAW == value->encoding || OIC_ENCODING_DER == value->encoding)
738 OCRepPayload *heplerPayload = OCRepPayloadCreate();
744 char *encoding = getStringFromEncodingType(value->encoding);
745 if (!OCRepPayloadSetPropString(heplerPayload, OC_RSRVD_ENCODING, encoding))
747 OIC_LOG_V(ERROR, TAG, "Can't set %s", OC_RSRVD_ENCODING);
750 OCByteString val = {.bytes = value->data, .len = value->len};
753 if (!OCRepPayloadSetPropByteString(heplerPayload, OC_RSRVD_DATA, val))
755 OIC_LOG_V(ERROR, TAG, "Can't set %s", OC_RSRVD_DATA);
760 if (!OCRepPayloadSetPropString(heplerPayload, OC_RSRVD_DATA, (char *)val.bytes))
762 OIC_LOG_V(ERROR, TAG, "Can't set %s", OC_RSRVD_DATA);
766 if (!OCRepPayloadSetPropObject(payload, name, (const OCRepPayload *)heplerPayload))
768 OIC_LOG_V(ERROR, TAG, "Can't set %s", name);
771 OCRepPayloadDestroy(heplerPayload);
777 bool OC_CALL OCRepPayloadSetPropPubDataType(OCRepPayload *payload, const char *name,
778 const OicSecKey_t *value)
780 return OCRepPayloadSetPropPubDataTypeAsOwner(payload, name, value);
783 static OicEncodingType_t getEncodingTypeFromString(char *encoding)
785 OicEncodingType_t type = OIC_ENCODING_UNKNOW;
787 char *str = strrchr(encoding, '.');
790 OIC_LOG_V(ERROR, TAG, "Can't find . in %s", encoding);
793 str++; //go to encoding itself
795 if (0 == strcmp(str, OC_RSRVD_BASE64)) type = OIC_ENCODING_BASE64;
796 else if (0 == strcmp(str, OC_RSRVD_DER)) type = OIC_ENCODING_DER;
797 else if (0 == strcmp(str, OC_RSRVD_PEM)) type = OIC_ENCODING_PEM;
798 else if (0 == strcmp(str, OC_RSRVD_RAW)) type = OIC_ENCODING_RAW;
803 bool OC_CALL OCRepPayloadGetPropPubDataType(const OCRepPayload *payload, const char *name, OicSecKey_t *value)
805 OCRepPayload *heplerPayload = NULL;
806 char *encoding = NULL;
809 if (!payload || !name || !value)
814 if (!OCRepPayloadGetPropObject(payload, name, &heplerPayload))
816 OIC_LOG_V(ERROR, TAG, "Can't get object with name %s", name);
820 if (!OCRepPayloadGetPropString(heplerPayload, OC_RSRVD_ENCODING, &encoding))
822 OIC_LOG_V(ERROR, TAG, "Can't get %s", OC_RSRVD_ENCODING);
826 value->encoding = getEncodingTypeFromString(encoding);
830 if (!OCRepPayloadGetPropByteString(heplerPayload, OC_RSRVD_DATA, &val))
832 if (!OCRepPayloadGetPropString(heplerPayload, OC_RSRVD_DATA, (char **)&val.bytes))
834 OIC_LOG_V(ERROR, TAG, "Can't get: %s", OC_RSRVD_DATA);
838 value->data = val.bytes;
839 value->len = strlen((const char*)val.bytes);
844 value->data = val.bytes;
845 value->len = val.len;
848 OCRepPayloadDestroy(heplerPayload);
853 bool OC_CALL OCRepPayloadSetPropObject(OCRepPayload* payload, const char* name, const OCRepPayload* value)
855 OCRepPayload* temp = OCRepPayloadClone(value);
856 bool b = OCRepPayloadSetPropObjectAsOwner(payload, name, temp);
860 OCRepPayloadDestroy(temp);
865 bool OC_CALL OCRepPayloadSetPropObjectAsOwner(OCRepPayload* payload, const char* name, OCRepPayload* value)
867 return OCRepPayloadSetProp(payload, name, value, OCREP_PROP_OBJECT);
870 bool OC_CALL OCRepPayloadGetPropObject(const OCRepPayload* payload, const char* name, OCRepPayload** value)
872 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
874 if (!val || val->type != OCREP_PROP_OBJECT)
879 *value = OCRepPayloadClone(val->obj);
880 return *value != NULL;
883 size_t OC_CALL calcDimTotal(const size_t dimensions[MAX_REP_ARRAY_DEPTH])
885 if (dimensions[0] == 0)
891 for(uint8_t i = 0; i < MAX_REP_ARRAY_DEPTH && dimensions[i] != 0; ++i)
893 total *= dimensions[i];
899 bool OC_CALL OCRepPayloadSetByteStringArrayAsOwner(OCRepPayload* payload, const char* name,
900 OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
902 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
909 val->arr.type = OCREP_PROP_BYTE_STRING;
910 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
911 val->arr.ocByteStrArray = array;
916 bool OC_CALL OCRepPayloadSetByteStringArray(OCRepPayload* payload, const char* name,
917 const OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
924 size_t dimTotal = calcDimTotal(dimensions);
930 OCByteString* newArray = (OCByteString*)OICCalloc(dimTotal, sizeof(OCByteString));
937 for (size_t i = 0; i < dimTotal; ++i)
941 newArray[i].bytes = (uint8_t*)OICMalloc(array[i].len * sizeof(uint8_t));
942 if (NULL == newArray[i].bytes)
944 for (size_t j = 0; j < i; ++j)
946 OICFree(newArray[j].bytes);
953 newArray[i].len = array[i].len;
954 memcpy(newArray[i].bytes, array[i].bytes, newArray[i].len);
957 bool b = OCRepPayloadSetByteStringArrayAsOwner(payload, name, newArray, dimensions);
960 for (size_t i = 0; i < dimTotal; ++i)
962 OICFree(newArray[i].bytes);
970 bool OC_CALL OCRepPayloadGetByteStringArray(const OCRepPayload* payload, const char* name,
971 OCByteString** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
973 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
975 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_BYTE_STRING
976 || !val->arr.ocByteStrArray)
981 size_t dimTotal = calcDimTotal(val->arr.dimensions);
987 *array = (OCByteString*)OICCalloc(dimTotal, sizeof(OCByteString));
993 for (size_t i = 0; i < dimTotal; ++i)
995 OCByteString* tmp = &(*array)[i];
996 if (val->arr.ocByteStrArray[i].len)
998 tmp->bytes = (uint8_t*)OICMalloc(val->arr.ocByteStrArray[i].len * sizeof(uint8_t));
999 if (NULL == tmp->bytes)
1001 for (size_t j = 0; j < i; ++j)
1003 OCByteString* temp = &(*array)[j];
1004 OICFree(temp->bytes);
1012 tmp->len = val->arr.ocByteStrArray[i].len;
1013 memcpy(tmp->bytes, val->arr.ocByteStrArray[i].bytes, tmp->len);
1016 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1021 bool OC_CALL OCRepPayloadSetIntArrayAsOwner(OCRepPayload* payload, const char* name,
1022 int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1024 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1031 val->arr.type = OCREP_PROP_INT;
1032 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1033 val->arr.iArray = array;
1038 bool OC_CALL OCRepPayloadSetIntArray(OCRepPayload* payload, const char* name,
1039 const int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1041 size_t dimTotal = calcDimTotal(dimensions);
1043 int64_t* newArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
1045 if (newArray && array)
1047 memcpy(newArray, array, dimTotal * sizeof(int64_t));
1050 bool b = OCRepPayloadSetIntArrayAsOwner(payload, name, newArray, dimensions);
1058 bool OC_CALL OCRepPayloadGetIntArray(const OCRepPayload* payload, const char* name,
1059 int64_t** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1061 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1063 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_INT
1064 || !val->arr.iArray)
1069 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1074 *array = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
1080 memcpy(*array, val->arr.iArray, dimTotal * sizeof(int64_t));
1081 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1085 bool OC_CALL OCRepPayloadSetDoubleArrayAsOwner(OCRepPayload* payload, const char* name,
1086 double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1088 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1095 val->arr.type = OCREP_PROP_DOUBLE;
1096 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1097 val->arr.dArray = array;
1101 bool OC_CALL OCRepPayloadSetDoubleArray(OCRepPayload* payload, const char* name,
1102 const double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1104 size_t dimTotal = calcDimTotal(dimensions);
1110 double* newArray = (double*)OICMalloc(dimTotal * sizeof(double));
1117 memcpy(newArray, array, dimTotal * sizeof(double));
1119 bool b = OCRepPayloadSetDoubleArrayAsOwner(payload, name, newArray, dimensions);
1127 bool OC_CALL OCRepPayloadGetDoubleArray(const OCRepPayload* payload, const char* name,
1128 double** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1130 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1133 (val->type != OCREP_PROP_ARRAY) ||
1134 ((val->arr.type != OCREP_PROP_DOUBLE) &&
1135 (val->arr.type != OCREP_PROP_INT)) ||
1141 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1146 *array = (double*)OICMalloc(dimTotal * sizeof(double));
1152 if (val->arr.type == OCREP_PROP_DOUBLE)
1154 memcpy(*array, val->arr.dArray, dimTotal * sizeof(double));
1158 /* need to convert from integer */
1160 for ( ; n < dimTotal; ++n)
1162 // Should be removed once IOT-1705 is fixed.
1164 #pragma warning( suppress : 4244 )
1165 (*array)[n] = val->arr.iArray[n];
1167 (*array)[n] = val->arr.iArray[n];
1171 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1175 bool OC_CALL OCRepPayloadSetStringArrayAsOwner(OCRepPayload* payload, const char* name,
1176 char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1178 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1185 val->arr.type = OCREP_PROP_STRING;
1186 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1187 val->arr.strArray = array;
1191 bool OC_CALL OCRepPayloadSetStringArray(OCRepPayload* payload, const char* name,
1192 const char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1194 size_t dimTotal = calcDimTotal(dimensions);
1200 char** newArray = (char**)OICMalloc(dimTotal * sizeof(char*));
1207 for(size_t i = 0; i < dimTotal; ++i)
1209 newArray[i] = OICStrdup(array[i]);
1212 bool b = OCRepPayloadSetStringArrayAsOwner(payload, name, newArray, dimensions);
1216 for(size_t i = 0; i < dimTotal; ++i)
1218 OICFree(newArray[i]);
1225 bool OC_CALL OCRepPayloadGetStringArray(const OCRepPayload* payload, const char* name,
1226 char*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1228 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1230 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_STRING
1231 || !val->arr.strArray)
1236 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1241 *array = (char**)OICMalloc(dimTotal * sizeof(char*));
1247 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1249 for(size_t i = 0; i < dimTotal; ++i)
1251 (*array)[i] = OICStrdup(val->arr.strArray[i]);
1258 bool OC_CALL OCRepPayloadSetBoolArrayAsOwner(OCRepPayload* payload, const char* name,
1259 bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1262 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1269 val->arr.type = OCREP_PROP_BOOL;
1270 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1271 val->arr.bArray = array;
1275 bool OC_CALL OCRepPayloadSetBoolArray(OCRepPayload* payload, const char* name,
1276 const bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1278 size_t dimTotal = calcDimTotal(dimensions);
1284 bool* newArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
1291 memcpy(newArray, array, dimTotal * sizeof(bool));
1294 bool b = OCRepPayloadSetBoolArrayAsOwner(payload, name, newArray, dimensions);
1302 bool OC_CALL OCRepPayloadGetBoolArray(const OCRepPayload* payload, const char* name,
1303 bool** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1305 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1307 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_BOOL
1308 || !val->arr.bArray)
1313 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1318 *array = (bool*)OICMalloc(dimTotal * sizeof(bool));
1324 memcpy(*array, val->arr.bArray, dimTotal * sizeof(bool));
1325 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1329 bool OC_CALL OCRepPayloadSetPropObjectArrayAsOwner(OCRepPayload* payload, const char* name,
1330 OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1332 OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
1339 val->arr.type = OCREP_PROP_OBJECT;
1340 memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1341 val->arr.objArray = array;
1346 bool OC_CALL OCRepPayloadSetPropObjectArray(OCRepPayload* payload, const char* name,
1347 const OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1349 size_t dimTotal = calcDimTotal(dimensions);
1355 OCRepPayload** newArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
1362 for(size_t i = 0; i < dimTotal; ++i)
1364 newArray[i] = OCRepPayloadClone(array[i]);
1367 bool b = OCRepPayloadSetPropObjectArrayAsOwner(payload, name, newArray, dimensions);
1371 for(size_t i = 0; i < dimTotal; ++i)
1373 OCRepPayloadDestroy(newArray[i]);
1380 bool OC_CALL OCRepPayloadGetPropObjectArray(const OCRepPayload* payload, const char* name,
1381 OCRepPayload*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
1383 OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
1385 if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_OBJECT
1386 || !val->arr.objArray)
1391 size_t dimTotal = calcDimTotal(val->arr.dimensions);
1396 *array = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
1402 memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
1404 for(size_t i = 0; i < dimTotal; ++i)
1406 (*array)[i] = OCRepPayloadClone(val->arr.objArray[i]);
1412 void OC_CALL OCFreeOCStringLL(OCStringLL* ll)
1419 OCFreeOCStringLL(ll->next);
1424 OCStringLL* OC_CALL CloneOCStringLL (OCStringLL* ll)
1431 OCStringLL *sourceIter = ll;
1433 OCStringLL *destIter = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
1438 destIter->value = OICStrdup (sourceIter->value);
1440 OCStringLL *headOfClone = destIter;
1442 sourceIter = sourceIter->next;
1446 destIter->next = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
1447 if (!destIter->next)
1449 OCFreeOCStringLL (headOfClone);
1452 destIter->next->value = OICStrdup (sourceIter->value);
1454 destIter = destIter->next;
1455 sourceIter = sourceIter->next;
1460 OCStringLL* OC_CALL OCCreateOCStringLL(const char* text)
1465 char *backup = NULL;
1466 OCStringLL* result = NULL;
1467 OCStringLL* iter = NULL;
1468 OCStringLL* prev = NULL;
1469 static const char delim[] = { CSV_SEPARATOR, '\0' };
1471 VERIFY_PARAM_NON_NULL(TAG, text, "Invalid parameter");
1472 backup = OICStrdup(text);
1473 VERIFY_PARAM_NON_NULL(TAG, backup, "Failed allocating memory");
1475 for (head = backup; ; head = NULL)
1477 token = (char *) strtok_r(head, delim, &tail);
1482 iter = (OCStringLL *)OICCalloc(1,sizeof(OCStringLL));
1483 VERIFY_PARAM_NON_NULL(TAG, iter, "Failed allocating memory");
1492 iter->value = OICStrdup(token);
1493 VERIFY_PARAM_NON_NULL(TAG, iter->value, "Failed allocating memory");
1502 OCFreeOCStringLL(result);
1506 char* OC_CALL OCCreateString(const OCStringLL* ll)
1519 for (const OCStringLL *it = ll; it; it = it->next)
1521 len += strlen(it->value) + 1;
1523 len--; // remove trailing separator (just added above)
1524 str = (char*) OICMalloc(len + 1);
1531 const OCStringLL *it = ll;
1534 sublen = strlen(it->value);
1535 count = snprintf(pos, len + 1, "%s", it->value);
1536 if ((size_t)count < sublen)
1547 *pos = CSV_SEPARATOR;
1556 bool OC_CALL OCByteStringCopy(OCByteString* dest, const OCByteString* source)
1558 VERIFY_PARAM_NON_NULL(TAG, dest, "Bad dest");
1559 VERIFY_PARAM_NON_NULL(TAG, source, "Bad source");
1563 OICFree(dest->bytes);
1567 dest->bytes = (uint8_t*)OICMalloc(source->len * sizeof(uint8_t));
1568 VERIFY_PARAM_NON_NULL(TAG, dest->bytes, "Failed allocating memory");
1569 memcpy(dest->bytes, source->bytes, source->len * sizeof(uint8_t));
1571 dest->len = source->len;
1578 OICFree(dest->bytes);
1585 OCRepPayload* OC_CALL OCRepPayloadClone (const OCRepPayload* payload)
1592 OCRepPayload *clone = OCRepPayloadCreate();
1599 clone->uri = OICStrdup (payload->uri);
1600 clone->types = CloneOCStringLL (payload->types);
1601 clone->interfaces = CloneOCStringLL (payload->interfaces);
1602 clone->values = OCRepPayloadValueClone (payload->values);
1607 OCRepPayload* OC_CALL OCRepPayloadBatchClone(const OCRepPayload* repPayload)
1609 OCRepPayload *newPayload = OCRepPayloadCreate();
1615 newPayload->uri = OICStrdup(repPayload->uri);
1616 OCRepPayload *clone = OCRepPayloadCreate();
1619 OCPayloadDestroy((OCPayload *)newPayload);
1623 clone->types = CloneOCStringLL(repPayload->types);
1624 clone->interfaces = CloneOCStringLL(repPayload->interfaces);
1625 clone->values = OCRepPayloadValueClone(repPayload->values);
1626 OCRepPayloadSetPropObjectAsOwner(newPayload, OC_RSRVD_REPRESENTATION, clone);
1631 void OC_CALL OCRepPayloadDestroy(OCRepPayload* payload)
1638 OICFree(payload->uri);
1639 OCFreeOCStringLL(payload->types);
1640 OCFreeOCStringLL(payload->interfaces);
1641 OCFreeRepPayloadValue(payload->values);
1642 OCRepPayloadDestroy(payload->next);
1646 OCDiscoveryPayload* OC_CALL OCDiscoveryPayloadCreate()
1648 OCDiscoveryPayload* payload = (OCDiscoveryPayload*)OICCalloc(1, sizeof(OCDiscoveryPayload));
1655 payload->base.type = PAYLOAD_TYPE_DISCOVERY;
1660 OCSecurityPayload* OC_CALL OCSecurityPayloadCreate(const uint8_t* securityData, size_t size)
1662 OCSecurityPayload* payload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
1669 payload->base.type = PAYLOAD_TYPE_SECURITY;
1670 payload->securityData = (uint8_t *)OICCalloc(1, size);
1671 if (!payload->securityData)
1676 memcpy(payload->securityData, (uint8_t *)securityData, size);
1677 payload->payloadSize = size;
1682 void OC_CALL OCSecurityPayloadDestroy(OCSecurityPayload* payload)
1689 OICClearMemory(payload->securityData, payload->payloadSize);
1690 OICFree(payload->securityData);
1694 OCIntrospectionPayload* OC_CALL OCIntrospectionPayloadCreateFromCbor(const uint8_t* cborData,
1697 OCIntrospectionPayload* payload = NULL;
1698 payload = (OCIntrospectionPayload*)OICCalloc(1, sizeof(OCIntrospectionPayload));
1704 payload->base.type = PAYLOAD_TYPE_INTROSPECTION;
1705 payload->cborPayload.bytes = (uint8_t*)OICCalloc(1, size);
1706 if (!payload->cborPayload.bytes)
1711 memcpy(payload->cborPayload.bytes, cborData, size);
1712 payload->cborPayload.len = size;
1717 void OC_CALL OCIntrospectionPayloadDestroy(OCIntrospectionPayload* payload)
1724 OICFree(payload->cborPayload.bytes);
1728 size_t OC_CALL OCDiscoveryPayloadGetResourceCount(OCDiscoveryPayload* payload)
1731 OCResourcePayload* p = payload->resources;
1740 OCResourcePayload* OC_CALL OCDiscoveryPayloadGetResource(OCDiscoveryPayload* payload, size_t index)
1743 OCResourcePayload* p = payload->resources;
1756 size_t OC_CALL OCEndpointPayloadGetEndpointCount(OCEndpointPayload* payload)
1759 OCEndpointPayload* ep = payload;
1768 OCEndpointPayload* OC_CALL OCEndpointPayloadGetEndpoint(OCEndpointPayload* payload, size_t index)
1771 OCEndpointPayload* ep = payload;
1784 void OC_CALL OCResourcePayloadAddNewEndpoint(OCResourcePayload* payload, OCEndpointPayload* endpoint)
1793 payload->eps = endpoint;
1797 OCEndpointPayload* ep = payload->eps;
1802 ep->next = endpoint;
1806 OCEndpointPayload* CreateEndpointPayloadList(const OCResource *resource, const OCDevAddr *devAddr,
1807 CAEndpoint_t *networkInfo, size_t infoSize,
1808 OCEndpointPayload **listHead, size_t* epSize, OCEndpointPayload** selfEp)
1810 OCEndpointPayload *headNode = NULL;
1811 OCEndpointPayload *lastNode = NULL;
1813 VERIFY_PARAM_NON_NULL(TAG, resource, "Invalid resource parameter");
1814 VERIFY_PARAM_NON_NULL(TAG, devAddr, "Invalid devAddr parameter");
1815 VERIFY_PARAM_NON_NULL(TAG, networkInfo, "Invalid networkInfo parameter");
1816 VERIFY_PARAM_NON_NULL(TAG, listHead, "Invalid listHead parameter");
1817 if (epSize != NULL) *epSize = 0;
1819 bool includeSecure = resource->resourceProperties & OC_SECURE;
1820 bool includeNonsecure = resource->resourceProperties & OC_NONSECURE;
1822 if ((OC_ADAPTER_IP | OC_ADAPTER_TCP) & (devAddr->adapter))
1824 for (size_t i = 0; i < infoSize; i++)
1826 CAEndpoint_t *info = networkInfo + i;
1828 if (((CA_ADAPTER_IP | CA_ADAPTER_TCP) & info->adapter &&
1829 info->ifindex == devAddr->ifindex) ||
1830 info->adapter == CA_ADAPTER_RFCOMM_BTEDR)
1832 OCTpsSchemeFlags matchedTps = OC_NO_TPS;
1833 if (OC_STACK_OK != OCGetMatchedTpsFlags(info->adapter,
1837 OIC_LOG_V(ERROR, TAG, "OCGetMatchedTpsFlags err");
1841 bool isSecure = (info->flags & OC_FLAG_SECURE);
1842 if (((resource->endpointType) & matchedTps) &&
1843 ((isSecure && includeSecure) || (!isSecure && includeNonsecure)))
1846 OCEndpointPayload* tmpNode = (OCEndpointPayload*)
1847 OICCalloc(1, sizeof(OCEndpointPayload));
1850 OIC_LOG_V(ERROR, TAG, "Fail creating tmpNode->addr");
1854 OCStackResult ret = OCConvertTpsToString(matchedTps, &(tmpNode->tps));
1855 if (ret != OC_STACK_OK)
1857 OIC_LOG_V(DEBUG, TAG, "OCConvertTpsToString(%s) is false", tmpNode->tps);
1858 OCDiscoveryEndpointDestroy(tmpNode);
1862 tmpNode->addr = (char*)OICCalloc(MAX_ADDR_STR_SIZE, sizeof(char));
1865 OIC_LOG_V(ERROR, TAG, "Fail creating tmpNode->addr");
1866 OCDiscoveryEndpointDestroy(tmpNode);
1870 memcpy(tmpNode->addr, info->addr, sizeof(info->addr));
1871 tmpNode->family = (OCTransportFlags)(info->flags);
1872 tmpNode->port = info->port;
1874 tmpNode->next = NULL;
1876 // remember endpoint that matches devAddr for use in anchor
1877 OCTransportFlags infoFlagsSecureFams = (OCTransportFlags)
1878 (info->flags & MASK_SECURE_FAMS);
1879 if ((selfEp != NULL) &&
1880 ((infoFlagsSecureFams & devAddr->flags) == infoFlagsSecureFams))
1893 lastNode->next = tmpNode;
1896 if (epSize != NULL) (*epSize)++;
1901 OIC_LOG_V(DEBUG, TAG, "CATransportAdapter_t value = %d", info->adapter);
1906 *listHead = headNode;
1909 OCDiscoveryEndpointDestroy(headNode);
1913 static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort,
1914 CAEndpoint_t *networkInfo, size_t infoSize,
1915 const OCDevAddr *devAddr
1922 OCResourcePayload* pl = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
1928 OCEndpointPayload *selfEp = NULL;
1929 if (networkInfo && infoSize && devAddr)
1931 CreateEndpointPayloadList(res, devAddr, networkInfo, infoSize,
1932 &(pl->eps), NULL, &selfEp);
1935 pl->uri = OICStrdup(res->uri);
1938 OCDiscoveryResourceDestroy(pl);
1942 // relation is always the default unless the resource is the well known URI
1943 if (0 == strcmp(res->uri, OC_RSRVD_WELL_KNOWN_URI))
1945 pl->rel = OICStrdup("self");
1948 OCDiscoveryResourceDestroy(pl);
1954 char *anchor = OCCreateEndpointString(selfEp);
1957 pl->anchor = anchor;
1961 OIC_LOG(ERROR, TAG, "Can't determine anchor");
1965 OCResourceType* typePtr = res->rsrcType;
1967 if (typePtr != NULL)
1969 pl->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1972 OCDiscoveryResourceDestroy(pl);
1975 pl->types->value = OICStrdup(typePtr->resourcetypename);
1976 if (!pl->types->value)
1978 OCDiscoveryResourceDestroy(pl);
1982 OCStringLL* cur = pl->types;
1983 typePtr = typePtr->next;
1986 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
1989 OCDiscoveryResourceDestroy(pl);
1992 cur->next->value = OICStrdup(typePtr->resourcetypename);
1993 if (!cur->next->value)
1995 OCDiscoveryResourceDestroy(pl);
1999 typePtr = typePtr->next;
2004 OCResourceInterface* ifPtr = res->rsrcInterface;
2007 pl->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
2008 if (!pl->interfaces)
2010 OCDiscoveryResourceDestroy(pl);
2013 pl->interfaces->value = OICStrdup(ifPtr->name);
2014 if (!pl->interfaces->value)
2016 OCDiscoveryResourceDestroy(pl);
2020 OCStringLL* cur = pl->interfaces;
2021 ifPtr = ifPtr->next;
2024 cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
2027 OCDiscoveryResourceDestroy(pl);
2030 cur->next->value = OICStrdup(ifPtr->name);
2031 if (!cur->next->value)
2033 OCDiscoveryResourceDestroy(pl);
2037 ifPtr = ifPtr->next;
2041 pl->bitmap = res->resourceProperties & (OC_OBSERVABLE | OC_DISCOVERABLE
2046 pl->secure = (res->resourceProperties & OC_SECURE) != 0;
2047 pl->port = securePort;
2049 pl->tcpPort = tcpPort;
2056 void OC_CALL OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
2057 uint16_t securePort)
2059 OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort, NULL, 0, NULL));
2062 void OC_CALL OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
2063 uint16_t securePort, uint16_t tcpPort)
2065 OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort, NULL, 0, NULL,
2071 void OCDiscoveryPayloadAddResourceWithEps(OCDiscoveryPayload* payload, const OCResource* res,
2072 uint16_t securePort, void *networkInfo, size_t infoSize,
2073 const OCDevAddr *devAddr)
2075 OCDiscoveryPayloadAddNewResource(payload,
2076 OCCopyResource(res, securePort, (CAEndpoint_t *)networkInfo,
2077 infoSize, devAddr));
2080 void OCDiscoveryPayloadAddResourceWithEps(OCDiscoveryPayload* payload, const OCResource* res,
2081 uint16_t securePort, void *networkInfo, size_t infoSize,
2082 const OCDevAddr *devAddr, uint16_t tcpPort)
2084 OCDiscoveryPayloadAddNewResource(payload,
2085 OCCopyResource(res, securePort, (CAEndpoint_t *)networkInfo,
2086 infoSize, devAddr, tcpPort));
2090 bool OC_CALL OCResourcePayloadAddStringLL(OCStringLL **stringLL, const char *value)
2093 VERIFY_PARAM_NON_NULL(TAG, value, "Invalid Parameters");
2094 dup = OICStrdup(value);
2095 VERIFY_PARAM_NON_NULL(TAG, dup, "Failed copying string");
2099 *stringLL = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
2100 VERIFY_PARAM_NON_NULL(TAG, *stringLL, "Failed allocating memory");
2101 (*stringLL)->value = dup;
2106 OCStringLL *temp = *stringLL;
2111 temp->next = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
2112 VERIFY_PARAM_NON_NULL(TAG, temp->next, "Failed allocating memory");
2113 temp->next->value = dup;
2121 void OC_CALL OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload, OCResourcePayload* res)
2128 if (!payload->resources)
2130 payload->resources = res;
2134 OCResourcePayload* p = payload->resources;
2143 void OC_CALL OCDiscoveryEndpointDestroy(OCEndpointPayload* payload)
2150 OICFree(payload->tps);
2151 OICFree(payload->addr);
2152 OCDiscoveryEndpointDestroy(payload->next);
2156 void OC_CALL OCDiscoveryResourceDestroy(OCResourcePayload* payload)
2163 OICFree(payload->uri);
2164 OICFree(payload->rel);
2165 OICFree(payload->anchor);
2166 OCFreeOCStringLL(payload->types);
2167 OCFreeOCStringLL(payload->interfaces);
2168 OCDiscoveryEndpointDestroy(payload->eps);
2169 OCDiscoveryResourceDestroy(payload->next);
2173 void OC_CALL OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload)
2179 OICFree(payload->sid);
2180 OCFreeOCStringLL(payload->type);
2181 OICFree(payload->name);
2182 OCFreeOCStringLL(payload->iface);
2183 OCDiscoveryResourceDestroy(payload->resources);
2184 OCDiscoveryPayloadDestroy(payload->next);
2188 OCPresencePayload* OC_CALL OCPresencePayloadCreate(uint32_t seqNum, uint32_t maxAge,
2189 OCPresenceTrigger trigger, const char* resourceType)
2191 OCPresencePayload* payload = (OCPresencePayload*)OICCalloc(1, sizeof(OCPresencePayload));
2197 payload->base.type = PAYLOAD_TYPE_PRESENCE;
2198 payload->sequenceNumber = seqNum;
2199 payload->maxAge = maxAge;
2200 payload->trigger = trigger;
2201 payload->resourceType = OICStrdup(resourceType);
2205 void OC_CALL OCPresencePayloadDestroy(OCPresencePayload* payload)
2211 OICFree(payload->resourceType);
2215 OCDiagnosticPayload* OC_CALL OCDiagnosticPayloadCreate(const char* message)
2222 OCDiagnosticPayload* payload = (OCDiagnosticPayload*)OICCalloc(1, sizeof(OCDiagnosticPayload));
2228 payload->base.type = PAYLOAD_TYPE_DIAGNOSTIC;
2229 payload->message = OICStrdup(message);
2233 void OC_CALL OCDiagnosticPayloadDestroy(OCDiagnosticPayload* payload)
2239 OICFree(payload->message);
2243 void OC_CALL OCEndpointPayloadDestroy(OCEndpointPayload* payload)
2249 OICFree(payload->tps);
2250 OICFree(payload->addr);
2251 OCEndpointPayloadDestroy(payload->next);
2255 OCRepPayload** OC_CALL OCLinksPayloadArrayCreate(const char* resourceUri,
2256 OCEntityHandlerRequest *ehRequest, size_t* createdArraySize)
2258 OIC_LOG(DEBUG, TAG, "OCLinksPayloadValueCreate");
2259 OCRepPayload** linksRepPayloadArray = NULL;
2260 if ((resourceUri != NULL) && (ehRequest != NULL))
2262 bool isOCFContentFormat = false;
2263 if (!OCRequestIsOCFContentFormat(ehRequest, &isOCFContentFormat))
2266 if (linksRepPayloadArray = BuildCollectionLinksPayloadArray(resourceUri,
2267 isOCFContentFormat, &ehRequest->devAddr, createdArraySize))
2269 OIC_LOG_V(DEBUG, TAG, "return value of BuildCollectionLinksPayloadArray() = %s",
2270 (linksRepPayloadArray != NULL) ? "true" : "false");
2272 return linksRepPayloadArray;
2275 // Check on Content Version option whether request has vnd.ocf+cbor format instead of cbor
2276 bool OCRequestIsOCFContentFormat(OCEntityHandlerRequest *ehRequest, bool* isOCFContentFormat)
2278 if ((ehRequest == NULL)||(isOCFContentFormat == NULL))
2281 OCServerRequest* serverRequest = (OCServerRequest*) ehRequest->requestHandle;
2283 if (OC_FORMAT_VND_OCF_CBOR == serverRequest->acceptFormat)
2285 *isOCFContentFormat = true;
2286 OIC_LOG_V(INFO, TAG, "Content format is application/vnd.ocf+cbor");
2288 else if (OC_FORMAT_CBOR == serverRequest->acceptFormat)
2290 *isOCFContentFormat = false;
2291 OIC_LOG_V(INFO, TAG, "Content format is application/cbor");
2295 OIC_LOG_V(ERROR, TAG, "Content format is neither application/vnd.ocf+cbor nor /cbor");