//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// Required for strok_r
+#define _POSIX_C_SOURCE 200112L
+#include "iotivity_config.h"
+#include <stdio.h>
#include "ocpayload.h"
#include "octypes.h"
#include <string.h>
#include "rdpayload.h"
#define TAG "OIC_RI_PAYLOAD"
+#define CSV_SEPARATOR ','
static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val);
case PAYLOAD_TYPE_SECURITY:
OCSecurityPayloadDestroy((OCSecurityPayload*)payload);
break;
+#if defined(RD_CLIENT) || defined(RD_SERVER)
case PAYLOAD_TYPE_RD:
OCRDPayloadDestroy((OCRDPayload*)payload);
break;
+#endif
default:
OIC_LOG_V(ERROR, TAG, "Unsupported payload type in destroy: %d", payload->type);
OICFree(payload);
{
case OCREP_PROP_INT:
dest->arr.iArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
+ VERIFY_PARAM_NON_NULL(TAG, dest->arr.iArray, "Failed allocating memory");
memcpy(dest->arr.iArray, source->arr.iArray, dimTotal * sizeof(int64_t));
break;
case OCREP_PROP_DOUBLE:
dest->arr.dArray = (double*)OICMalloc(dimTotal * sizeof(double));
+ VERIFY_PARAM_NON_NULL(TAG, dest->arr.dArray, "Failed allocating memory");
memcpy(dest->arr.dArray, source->arr.dArray, dimTotal * sizeof(double));
break;
case OCREP_PROP_BOOL:
dest->arr.bArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
+ VERIFY_PARAM_NON_NULL(TAG, dest->arr.bArray, "Failed allocating memory");
memcpy(dest->arr.bArray, source->arr.bArray, dimTotal * sizeof(bool));
break;
case OCREP_PROP_STRING:
dest->arr.strArray = (char**)OICMalloc(dimTotal * sizeof(char*));
+ VERIFY_PARAM_NON_NULL(TAG, dest->arr.strArray, "Failed allocating memory");
for(size_t i = 0; i < dimTotal; ++i)
{
dest->arr.strArray[i] = OICStrdup(source->arr.strArray[i]);
break;
case OCREP_PROP_OBJECT:
dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
+ VERIFY_PARAM_NON_NULL(TAG, dest->arr.objArray, "Failed allocating memory");
for(size_t i = 0; i < dimTotal; ++i)
{
dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
break;
case OCREP_PROP_ARRAY:
dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
+ VERIFY_PARAM_NON_NULL(TAG, dest->arr.objArray, "Failed allocating memory");
for(size_t i = 0; i < dimTotal; ++i)
{
dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
OIC_LOG(ERROR, TAG, "CopyPropertyValueArray invalid type");
break;
}
+exit:
+ return;
}
static void OCCopyPropertyValue (OCRepPayloadValue *dest, OCRepPayloadValue *source)
case OCREP_PROP_STRING:
dest->str = OICStrdup(source->str);
break;
+ case OCREP_PROP_BYTE_STRING:
+ dest->ocByteStr.bytes = (uint8_t*)OICMalloc(source->ocByteStr.len * sizeof(uint8_t));
+ VERIFY_PARAM_NON_NULL(TAG, dest->ocByteStr.bytes, "Failed allocating memory");
+ dest->ocByteStr.len = source->ocByteStr.len;
+ memcpy(dest->ocByteStr.bytes, source->ocByteStr.bytes, dest->ocByteStr.len);
+ break;
case OCREP_PROP_OBJECT:
dest->obj = OCRepPayloadClone(source->obj);
break;
// Nothing to do for the trivially copyable types.
break;
}
+exit:
+ return;
}
static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val)
}
}
-bool OCRepPayloadAddInterface(OCRepPayload* payload, const char* interface)
+bool OCRepPayloadAddInterface(OCRepPayload* payload, const char* iface)
{
- return OCRepPayloadAddInterfaceAsOwner(payload, OICStrdup(interface));
+ return OCRepPayloadAddInterfaceAsOwner(payload, OICStrdup(iface));
}
-bool OCRepPayloadAddInterfaceAsOwner(OCRepPayload* payload, char* interface)
+bool OCRepPayloadAddInterfaceAsOwner(OCRepPayload* payload, char* iface)
{
- if (!payload || !interface)
+ if (!payload || !iface)
{
return false;
}
{
return false;
}
- cur->next->value = interface;
+ cur->next->value = iface;
return true;
}
else
{
return false;
}
- payload->interfaces->value = interface;
+ payload->interfaces->value = iface;
return true;
}
}
if (!val)
{
- return false;
+ return true;
}
return val->type == OCREP_PROP_NULL;
{
OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
- if (!val || val->type != OCREP_PROP_DOUBLE)
+ if (val)
{
- return false;
+ if (val->type == OCREP_PROP_DOUBLE)
+ {
+ *value = val->d;
+ return true;
+ }
+ else if (val->type == OCREP_PROP_INT)
+ {
+ *value = val->i;
+ return true;
+ }
}
- *value = val->d;
- return true;
+ return false;
}
bool OCRepPayloadSetPropString(OCRepPayload* payload, const char* name, const char* value)
{
if (!array)
{
- return NULL;
+ return false;
}
size_t dimTotal = calcDimTotal(dimensions);
{
OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
- if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_DOUBLE
+ if (!val || val->type != OCREP_PROP_ARRAY ||
+ (val->arr.type != OCREP_PROP_DOUBLE && val->arr.type != OCREP_PROP_INT)
|| !val->arr.dArray)
{
return false;
return false;
}
- memcpy(*array, val->arr.dArray, dimTotal * sizeof(double));
+ if (val->arr.type == OCREP_PROP_DOUBLE)
+ {
+ memcpy(*array, val->arr.dArray, dimTotal * sizeof(double));
+ }
+ else
+ {
+ /* need to convert from integer */
+ size_t n = 0;
+ for ( ; n < dimTotal; ++n)
+ {
+ (*array)[n] = val->arr.iArray[n];
+ }
+ }
memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
return true;
}
return headOfClone;
}
+OCStringLL* OCCreateOCStringLL(const char* text)
+{
+ char *token = NULL;
+ char *head = NULL;
+ char *tail = NULL;
+ char *backup = NULL;
+ OCStringLL* result = NULL;
+ OCStringLL* iter = NULL;
+ OCStringLL* prev = NULL;
+ static const char delim[] = { CSV_SEPARATOR, '\0' };
+
+ VERIFY_PARAM_NON_NULL(TAG, text, "Invalid parameter");
+ backup = OICStrdup(text);
+ VERIFY_PARAM_NON_NULL(TAG, backup, "Failed allocating memory");
+
+ for (head = backup; ; head = NULL)
+ {
+ token = (char *) strtok_r(head, delim, &tail);
+ if (!token) break;
+ iter = (OCStringLL *)OICCalloc(1,sizeof(OCStringLL));
+ VERIFY_PARAM_NON_NULL(TAG, iter, "Failed allocating memory");
+ if (!result)
+ {
+ result = iter;
+ }
+ else
+ {
+ prev->next = iter;
+ }
+ iter->value = OICStrdup(token);
+ VERIFY_PARAM_NON_NULL(TAG, iter->value, "Failed allocating memory");
+ prev = iter;
+ iter = iter->next;
+ }
+ OICFree(backup);
+ return result;
+
+exit:
+ OICFree(backup);
+ OCFreeOCStringLL(result);
+ return NULL;
+}
+
+char* OCCreateString(const OCStringLL* ll)
+{
+ if (!ll)
+ {
+ return NULL;
+ }
+
+ char *str = NULL;
+ char *pos = NULL;
+ size_t len = 0;
+ size_t sublen = 0;
+ int count = 0;
+
+ for (const OCStringLL *it = ll; it; it = it->next)
+ {
+ len += strlen(it->value) + 1;
+ }
+ len--; // renove trailing separator (just added above)
+ str = (char*) malloc(len + 1);
+ if (!str)
+ {
+ return NULL;
+ }
+
+ pos = str;
+ const OCStringLL *it = ll;
+ while (it)
+ {
+ sublen = strlen(it->value);
+ count = snprintf(pos, len + 1, "%s", it->value);
+ if ((size_t)count < sublen)
+ {
+ free(str);
+ return NULL;
+ }
+ len -= sublen;
+ pos += count;
+
+ it = it->next;
+ if (it)
+ {
+ *pos = CSV_SEPARATOR;
+ len--;
+ *(++pos) = '\0';
+ }
+ }
+
+ return str;
+}
+
OCRepPayload* OCRepPayloadClone (const OCRepPayload* payload)
{
if (!payload)
return payload;
}
-OCSecurityPayload* OCSecurityPayloadCreate(const char* securityData)
+OCSecurityPayload* OCSecurityPayloadCreate(const uint8_t* securityData, size_t size)
{
OCSecurityPayload* payload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
}
payload->base.type = PAYLOAD_TYPE_SECURITY;
- payload->securityData = OICStrdup(securityData);
+ payload->securityData = (uint8_t *)OICCalloc(1, size);
+ if (!payload->securityData)
+ {
+ OICFree(payload);
+ return NULL;
+ }
+ memcpy(payload->securityData, (uint8_t *)securityData, size);
+ payload->payloadSize = size;
return payload;
}
return NULL;
}
-static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t port)
+#ifndef TCP_ADAPTER
+static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort)
+#else
+static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort,
+ uint16_t tcpPort)
+#endif
{
OCResourcePayload* pl = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
if (!pl)
}
}
- pl->bitmap = res->resourceProperties & (OC_OBSERVABLE | OC_DISCOVERABLE);
+ pl->bitmap = res->resourceProperties & (OC_OBSERVABLE | OC_DISCOVERABLE
+#ifdef MQ_PUBLISHER
+ | OC_MQ_PUBLISHER
+#endif
+ );
pl->secure = (res->resourceProperties & OC_SECURE) != 0;
- pl->port = port;
-
+ pl->port = securePort;
+#ifdef TCP_ADAPTER
+ pl->tcpPort = tcpPort;
+#endif
return pl;
}
+#ifndef TCP_ADAPTER
+void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
+ uint16_t securePort)
+{
+ OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort));
+}
+#else
void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
- uint16_t port)
+ uint16_t securePort, uint16_t tcpPort)
{
- OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, port));
+ OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort, tcpPort));
}
+#endif
bool OCResourcePayloadAddStringLL(OCStringLL **stringLL, const char *value)
{
if (!*stringLL)
{
*stringLL = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
- VERIFY_PARAM_NON_NULL(TAG, dup, "Failed allocating memory");
+ VERIFY_PARAM_NON_NULL(TAG, *stringLL, "Failed allocating memory");
(*stringLL)->value = dup;
return true;
}
OICFree(payload->sid);
OICFree(payload->baseURI);
OICFree(payload->uri);
- OICFree(payload->type);
+ OCFreeOCStringLL(payload->type);
OICFree(payload->name);
- OCFreeOCStringLL(payload->interface);
+ OCFreeOCStringLL(payload->iface);
OCDiscoveryResourceDestroy(payload->resources);
+ OCDiscoveryPayloadDestroy(payload->next);
OICFree(payload);
}
goto exit;
}
- payload->dataModelVersion = OICStrdup(dmVer);
- if (dmVer && !payload->dataModelVersion)
+ payload->dataModelVersions = OCCreateOCStringLL(dmVer);
+ if (!payload->dataModelVersions || (dmVer && !payload->dataModelVersions->value))
{
goto exit;
}
OICFree(payload->sid);
OICFree(payload->deviceName);
OICFree(payload->specVersion);
- OICFree(payload->dataModelVersion);
+ OCFreeOCStringLL(payload->dataModelVersions);
OCFreeOCStringLL(payload->types);
OCFreeOCStringLL(payload->interfaces);
OICFree(payload);
return NULL;
}
payload->interfaces->value = OICStrdup(OC_RSRVD_INTERFACE_READ);
- payload->rt = OICStrdup(OC_RSRVD_RESOURCE_TYPE_PLATFORM);
+ payload->rt = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+ if (!payload->rt)
+ {
+ return NULL;
+ }
+ payload->rt->value = OICStrdup(OC_RSRVD_RESOURCE_TYPE_PLATFORM);
payload->info = *platformInfo;
return payload;
}
payload->base.type = PAYLOAD_TYPE_PLATFORM;
- payload->rt = OICStrdup(OC_RSRVD_RESOURCE_TYPE_PLATFORM);
+ OCResourcePayloadAddStringLL(&payload->rt, OC_RSRVD_RESOURCE_TYPE_PLATFORM);
OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_DEFAULT);
OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_READ);
}
OICFree(payload->uri);
OCPlatformInfoDestroy(&payload->info);
- OICFree(payload->rt);
+ OCFreeOCStringLL(payload->rt);
OCFreeOCStringLL(payload->interfaces);
OICFree(payload);
}