* limitations under the License.
*/
+#include <stdint.h>
#include <stdlib.h>
-#include <unistd.h> /* for usleep() */
+#include <unistd.h>
#include <glib.h>
#include <ocstack.h>
static int icd_ioty_alive;
-typedef int (*_ocprocess_fn)(void *user_data);
+typedef int (*_ocprocess_cb)(void *user_data);
+typedef void (*_free_context)(void *context);
struct icd_ioty_worker
{
void *ctx;
- _ocprocess_fn fn;
+ _ocprocess_cb cb;
+ _free_context free_ctx;
+};
+
+
+struct icd_worker_context {
+ GMutex icd_worker_mutex;
};
struct icd_req_context {
- unsigned int signum;
+ GMutex icd_worker_mutex;
+ int64_t signal_number;
char *bus_name;
- int types;
- int observer_id;
- int observe_action;
+ int request_type;
+ int observe_id;
+ int observe_type;
OCRequestHandle request_h;
OCResourceHandle resource_h;
GVariant *payload;
GVariantBuilder *options;
GVariantBuilder *query;
+ OCDevAddr dev_addr;
};
struct icd_find_context {
- unsigned int signum;
+ GMutex icd_worker_mutex;
+ int64_t signal_number;
char *bus_name;
int conn_type;
GVariant **payload;
struct icd_crud_context {
+ GMutex icd_worker_mutex;
int res;
int crud_type;
GVariant *payload;
struct icd_info_context {
- unsigned int signum;
+ GMutex icd_worker_mutex;
+ int64_t signal_number;
int info_type;
char *bus_name;
GVariant *payload;
struct icd_observe_context {
- unsigned int signum;
+ GMutex icd_worker_mutex;
+ int64_t signal_number;
int res;
int seqnum;
char *bus_name;
struct icd_presence_context {
- unsigned int signum;
- char *bus_name;
+ GMutex icd_worker_mutex;
+ OCDoHandle handle;
int result;
unsigned int nonce;
- OCDevAddr *dev_addr;
+ OCDevAddr dev_addr;
+ iotcon_presence_trigger_e trigger;
+ char *resource_type;
+};
+
+
+struct icd_encap_get_context {
+ GMutex icd_worker_mutex;
+ OCRepPayload *oic_payload;
+ OCStackResult ret;
+ OCDevAddr dev_addr;
+ char *uri_path;
};
{
int ret;
struct icd_ioty_worker *worker = data;
+ struct icd_worker_context *ctx = worker->ctx;
if (NULL == data) {
ERR("worker is NULL");
return NULL;
}
- ret = worker->fn(worker->ctx);
+ g_mutex_lock(&ctx->icd_worker_mutex);
+ ret = worker->cb(worker->ctx);
if (IOTCON_ERROR_NONE != ret)
- ERR("fn() Fail(%d)", ret);
+ ERR("cb() Fail(%d)", ret);
+ g_mutex_unlock(&ctx->icd_worker_mutex);
+
+ if (worker->free_ctx)
+ worker->free_ctx(worker->ctx);
/* worker was allocated from _ocprocess_worker_start() */
free(worker);
}
-static int _ocprocess_worker_start(_ocprocess_fn fn, void *ctx)
+static int _ocprocess_worker_start(_ocprocess_cb cb, void *ctx, _free_context free_ctx)
{
GError *error;
GThread *thread;
struct icd_ioty_worker *worker;
- RETV_IF(NULL == fn, IOTCON_ERROR_INVALID_PARAMETER);
+ RETV_IF(NULL == cb, IOTCON_ERROR_INVALID_PARAMETER);
worker = calloc(1, sizeof(struct icd_ioty_worker));
if (NULL == worker) {
return IOTCON_ERROR_OUT_OF_MEMORY;
}
- worker->fn = fn;
+ worker->cb = cb;
worker->ctx = ctx;
+ worker->free_ctx = free_ctx;
/* TODO : consider thread pool mechanism */
thread = g_thread_try_new("worker_thread", _ocprocess_worker_thread, worker, &error);
}
-static int _ocprocess_response_signal(const char *dest, const char *signal,
- unsigned int signum, GVariant *value)
+static int _ocprocess_response_signal(const char *dest, const char *signal_prefix,
+ int64_t signal_number, GVariant *value)
{
int ret;
- char sig_name[IC_DBUS_SIGNAL_LENGTH] = {0};
+ char signal_name[IC_DBUS_SIGNAL_LENGTH] = {0};
- ret = snprintf(sig_name, sizeof(sig_name), "%s_%u", signal, signum);
- if (ret <= 0 || sizeof(sig_name) <= ret) {
+ ret = snprintf(signal_name, sizeof(signal_name), "%s_%llx", signal_prefix, signal_number);
+ if (ret <= 0 || sizeof(signal_name) <= ret) {
ERR("snprintf() Fail(%d)", ret);
- return IOTCON_ERROR_UNKNOWN;
+ g_variant_unref(value);
+ return IOTCON_ERROR_IO_ERROR;
}
- ret = icd_dbus_emit_signal(dest, sig_name, value);
+ ret = icd_dbus_emit_signal(dest, signal_name, value);
if (IOTCON_ERROR_NONE != ret) {
ERR("icd_dbus_emit_signal() Fail(%d)", ret);
return ret;
return options;
}
+static int _ioty_oic_action_to_ioty_action(int oic_action)
+{
+ int action;
+
+ switch (oic_action) {
+ case OC_OBSERVE_REGISTER:
+ action = IOTCON_OBSERVE_REGISTER;
+ break;
+ case OC_OBSERVE_DEREGISTER:
+ action = IOTCON_OBSERVE_DEREGISTER;
+ break;
+ case OC_OBSERVE_NO_OPTION:
+ default:
+ ERR("Invalid action (%d)", oic_action);
+ action = IOTCON_OBSERVE_NO_TYPE;
+ }
+ return action;
+}
+
+
+static void _icd_req_context_free(void *ctx)
+{
+ struct icd_req_context *req_ctx = ctx;
+
+ free(req_ctx->bus_name);
+ if (req_ctx->payload)
+ g_variant_unref(req_ctx->payload);
+ g_variant_builder_unref(req_ctx->options);
+ g_variant_builder_unref(req_ctx->query);
+ free(req_ctx);
+}
+
static int _worker_req_handler(void *context)
{
- int ret;
GVariant *value;
- struct icd_req_context *ctx = context;
+ char *host_address;
+ int ret, conn_type;
GVariantBuilder payload_builder;
+ struct icd_req_context *ctx = context;
RETV_IF(NULL == ctx, IOTCON_ERROR_INVALID_PARAMETER);
g_variant_builder_init(&payload_builder, G_VARIANT_TYPE("av"));
- if (ctx->payload)
+ if (ctx->payload) {
g_variant_builder_add(&payload_builder, "v", ctx->payload);
+ ctx->payload = NULL;
+ }
- value = g_variant_new("(ia(qs)a(ss)iiavii)",
- ctx->types,
+ ret = icd_ioty_get_host_address(&ctx->dev_addr, &host_address, &conn_type);
+ if (IOTCON_ERROR_NONE != ret) {
+ ERR("icd_ioty_get_host_address() Fail(%d)", ret);
+ g_variant_builder_clear(&payload_builder);
+ return ret;
+ }
+
+ value = g_variant_new("(siia(qs)a(ss)iiavxx)",
+ host_address,
+ conn_type,
+ ctx->request_type,
ctx->options,
ctx->query,
- ctx->observe_action,
- ctx->observer_id,
+ ctx->observe_type,
+ ctx->observe_id,
&payload_builder,
- GPOINTER_TO_INT(ctx->request_h),
- GPOINTER_TO_INT(ctx->resource_h));
+ ICD_POINTER_TO_INT64(ctx->request_h),
+ ICD_POINTER_TO_INT64(ctx->resource_h));
+
+ free(host_address);
ret = _ocprocess_response_signal(ctx->bus_name, IC_DBUS_SIGNAL_REQUEST_HANDLER,
- ctx->signum, value);
+ ctx->signal_number, value);
if (IOTCON_ERROR_NONE != ret)
ERR("_ocprocess_response_signal() Fail(%d)", ret);
- free(ctx->bus_name);
- g_variant_builder_unref(ctx->options);
- g_variant_builder_unref(ctx->query);
- free(ctx);
-
return ret;
}
{
FN_CALL;
int ret;
- unsigned int signal_number;
+ int64_t signal_number;
char *query_str, *query_key, *query_value;
char *token, *save_ptr1, *save_ptr2;
char *bus_name = NULL;
}
/* signal number & bus_name */
- req_ctx->signum = signal_number;
+ req_ctx->signal_number = signal_number;
req_ctx->bus_name = bus_name;
+ memcpy(&req_ctx->dev_addr, &request->devAddr, sizeof(OCDevAddr));
+
/* request type */
if (OC_REQUEST_FLAG & flag) {
switch (request->method) {
case OC_REST_GET:
- req_ctx->types = IOTCON_REQUEST_GET;
+ req_ctx->request_type = IOTCON_REQUEST_GET;
req_ctx->payload = NULL;
-
- if (OC_OBSERVE_FLAG & flag) {
- req_ctx->types |= IOTCON_REQUEST_OBSERVE;
- /* observation info*/
- req_ctx->observer_id = request->obsInfo.obsId;
- req_ctx->observe_action = request->obsInfo.action;
- }
break;
case OC_REST_PUT:
- req_ctx->types = IOTCON_REQUEST_PUT;
+ req_ctx->request_type = IOTCON_REQUEST_PUT;
req_ctx->payload = icd_payload_to_gvariant(request->payload);
break;
case OC_REST_POST:
- req_ctx->types = IOTCON_REQUEST_POST;
+ req_ctx->request_type = IOTCON_REQUEST_POST;
req_ctx->payload = icd_payload_to_gvariant(request->payload);
break;
case OC_REST_DELETE:
- req_ctx->types = IOTCON_REQUEST_DELETE;
+ req_ctx->request_type = IOTCON_REQUEST_DELETE;
req_ctx->payload = NULL;
break;
default:
}
}
+ if (OC_OBSERVE_FLAG & flag) {
+ /* observation info*/
+ req_ctx->observe_id = request->obsInfo.obsId;
+ req_ctx->observe_type = _ioty_oic_action_to_ioty_action(request->obsInfo.action);
+ } else {
+ req_ctx->observe_type = IOTCON_OBSERVE_NO_TYPE;
+ }
+
/* header options */
req_ctx->options = _ocprocess_parse_header_options(
request->rcvdVendorSpecificHeaderOptions,
query_str = NULL;
}
- ret = _ocprocess_worker_start(_worker_req_handler, req_ctx);
+ ret = _ocprocess_worker_start(_worker_req_handler, req_ctx, _icd_req_context_free);
if (IOTCON_ERROR_NONE != ret) {
ERR("_ocprocess_worker_start() Fail(%d)", ret);
- free(req_ctx->bus_name);
- if (req_ctx->payload)
- g_variant_unref(req_ctx->payload);
- g_variant_builder_unref(req_ctx->options);
- g_variant_builder_unref(req_ctx->query);
- free(req_ctx);
+ _icd_req_context_free(req_ctx);
return OC_EH_ERROR;
}
{
FN_CALL;
OCStackResult result;
+ const struct timespec delay = {0, 10 * 1000 * 1000}; /* 10 ms */
icd_ioty_alive = 1;
while (icd_ioty_alive) {
break;
}
- /* TODO : SHOULD revise time or usleep */
- usleep(10);
+ /* TODO : Current '10ms' is not proven sleep time. Revise the time after test.
+ * Or recommend changes to event driven architecture */
+ nanosleep(&delay, NULL);
}
return NULL;
}
+static void _icd_find_context_free(void *ctx)
+{
+ struct icd_find_context *find_ctx = ctx;
+
+ free(find_ctx->bus_name);
+ free(find_ctx);
+}
+
+
static int _worker_find_cb(void *context)
{
GVariant *value;
* To reduce the number of emit_signal, let's send signal only one time for one device.
* for ex, client list. */
ret = _ocprocess_response_signal(ctx->bus_name, IC_DBUS_SIGNAL_FOUND_RESOURCE,
- ctx->signum, value);
+ ctx->signal_number, value);
if (IOTCON_ERROR_NONE != ret) {
ERR("_ocprocess_response_signal() Fail(%d)", ret);
g_variant_unref(value);
}
}
- /* ctx was allocated from icd_ioty_ocprocess_find_cb() */
- free(ctx->bus_name);
- free(ctx);
-
return ret;
}
if (NULL == resp->payload)
/* normal case : payload COULD be NULL */
return OC_STACK_KEEP_TRANSACTION;
- RETV_IF(PAYLOAD_TYPE_DISCOVERY != resp->payload->type,
- OC_STACK_KEEP_TRANSACTION);
+ RETVM_IF(PAYLOAD_TYPE_DISCOVERY != resp->payload->type,
+ OC_STACK_KEEP_TRANSACTION, "Invalid payload type(%d)", resp->payload->type);
find_ctx = calloc(1, sizeof(struct icd_find_context));
if (NULL == find_ctx) {
return OC_STACK_KEEP_TRANSACTION;
}
- find_ctx->signum = sig_context->signum;
+ find_ctx->signal_number = sig_context->signal_number;
find_ctx->bus_name = ic_utils_strdup(sig_context->bus_name);
find_ctx->payload = icd_payload_res_to_gvariant(resp->payload, &resp->devAddr);
find_ctx->conn_type = icd_ioty_transport_flag_to_conn_type(resp->devAddr.adapter,
resp->devAddr.flags);
- ret = _ocprocess_worker_start(_worker_find_cb, find_ctx);
+ ret = _ocprocess_worker_start(_worker_find_cb, find_ctx, _icd_find_context_free);
if (IOTCON_ERROR_NONE != ret) {
ERR("_ocprocess_worker_start() Fail(%d)", ret);
- free(find_ctx->bus_name);
ic_utils_gvariant_array_free(find_ctx->payload);
- free(find_ctx);
+ _icd_find_context_free(find_ctx);
return OC_STACK_KEEP_TRANSACTION;
}
}
+static void _icd_crud_context_free(void *ctx)
+{
+ struct icd_crud_context *crud_ctx = ctx;
+
+ g_variant_builder_unref(crud_ctx->options);
+ free(crud_ctx);
+}
+
+
static int _worker_crud_cb(void *context)
{
GVariant *value;
value = g_variant_new("(a(qs)vi)", ctx->options, ctx->payload, ctx->res);
icd_ioty_complete(ctx->crud_type, ctx->invocation, value);
- /* ctx was allocated from icd_ioty_ocprocess_xxx_cb() */
- g_variant_builder_unref(ctx->options);
- free(ctx);
-
return IOTCON_ERROR_NONE;
}
-static int _worker_info_cb(void *context)
-{
- int ret;
- const char *sig_name = NULL;
- struct icd_info_context *ctx = context;
-
- RETV_IF(NULL == ctx, IOTCON_ERROR_INVALID_PARAMETER);
-
- if (ICD_DEVICE_INFO == ctx->info_type)
- sig_name = IC_DBUS_SIGNAL_DEVICE;
- else if (ICD_PLATFORM_INFO == ctx->info_type)
- sig_name = IC_DBUS_SIGNAL_PLATFORM;
-
- ret = _ocprocess_response_signal(ctx->bus_name, sig_name, ctx->signum, ctx->payload);
- if (IOTCON_ERROR_NONE != ret)
- ERR("_ocprocess_response_signal() Fail(%d)", ret);
-
- /* ctx was allocated from icd_ioty_ocprocess_info_cb() */
- free(ctx->bus_name);
- free(ctx);
-
- return ret;
-}
-
-
-static int _ocprocess_worker(_ocprocess_fn fn, int type, OCPayload *payload, int res,
+static int _ocprocess_worker(_ocprocess_cb cb, int type, OCPayload *payload, int res,
GVariantBuilder *options, void *ctx)
{
int ret;
crud_ctx->options = options;
crud_ctx->invocation = ctx;
- ret = _ocprocess_worker_start(fn, crud_ctx);
+ ret = _ocprocess_worker_start(cb, crud_ctx, _icd_crud_context_free);
if (IOTCON_ERROR_NONE != ret) {
ERR("_ocprocess_worker_start() Fail(%d)", ret);
if (crud_ctx->payload)
return ret;
}
+static int _ocprocess_parse_oic_result(OCStackResult result)
+{
+ int res;
+
+ switch (result) {
+ case OC_STACK_OK:
+ res = IOTCON_RESPONSE_OK;
+ break;
+ case OC_STACK_RESOURCE_CREATED:
+ res = IOTCON_RESPONSE_RESOURCE_CREATED;
+ break;
+ case OC_STACK_RESOURCE_DELETED:
+ res = IOTCON_RESPONSE_RESULT_DELETED;
+ break;
+ case OC_STACK_UNAUTHORIZED_REQ:
+ res = IOTCON_RESPONSE_FORBIDDEN;
+ break;
+ default:
+ WARN("response error(%d)", result);
+ res = IOTCON_RESPONSE_ERROR;
+ break;
+ }
+
+ return res;
+}
+
OCStackApplicationResult icd_ioty_ocprocess_get_cb(void *ctx, OCDoHandle handle,
OCClientResponse *resp)
{
FN_CALL;
int ret, res;
- OCStackResult result;
GVariantBuilder *options;
RETV_IF(NULL == ctx, OC_STACK_DELETE_TRANSACTION);
return OC_STACK_DELETE_TRANSACTION;
}
- result = resp->result;
- if (OC_STACK_OK == result) {
- res = IOTCON_RESPONSE_RESULT_OK;
- options = _ocprocess_parse_header_options(resp->rcvdVendorSpecificHeaderOptions,
- resp->numRcvdVendorSpecificHeaderOptions);
- } else {
- WARN("resp error(%d)", result);
- res = IOTCON_RESPONSE_RESULT_ERROR;
- options = NULL;
- }
+ res = _ocprocess_parse_oic_result(resp->result);
+
+ options = _ocprocess_parse_header_options(resp->rcvdVendorSpecificHeaderOptions,
+ resp->numRcvdVendorSpecificHeaderOptions);
ret = _ocprocess_worker(_worker_crud_cb, ICD_CRUD_GET, resp->payload, res,
options, ctx);
{
FN_CALL;
int ret, res;
- OCStackResult result;
GVariantBuilder *options;
RETV_IF(NULL == ctx, OC_STACK_DELETE_TRANSACTION);
return OC_STACK_DELETE_TRANSACTION;
}
- result = resp->result;
- switch (result) {
- case OC_STACK_OK:
- res = IOTCON_RESPONSE_RESULT_OK;
- break;
- case OC_STACK_RESOURCE_CREATED:
- res = IOTCON_RESPONSE_RESULT_RESOURCE_CREATED;
- break;
- default:
- WARN("resp error(%d)", result);
- res = IOTCON_RESPONSE_RESULT_ERROR;
- options = NULL;
- }
+ res = _ocprocess_parse_oic_result(resp->result);
- if (IOTCON_RESPONSE_RESULT_ERROR != res) {
- options = _ocprocess_parse_header_options(resp->rcvdVendorSpecificHeaderOptions,
- resp->numRcvdVendorSpecificHeaderOptions);
- }
+ options = _ocprocess_parse_header_options(resp->rcvdVendorSpecificHeaderOptions,
+ resp->numRcvdVendorSpecificHeaderOptions);
ret = _ocprocess_worker(_worker_crud_cb, ICD_CRUD_PUT, resp->payload, res,
options, ctx);
{
FN_CALL;
int ret, res;
- OCStackResult result;
GVariantBuilder *options;
RETV_IF(NULL == ctx, OC_STACK_DELETE_TRANSACTION);
return OC_STACK_DELETE_TRANSACTION;
}
- result = resp->result;
- switch (result) {
- case OC_STACK_OK:
- res = IOTCON_RESPONSE_RESULT_OK;
- break;
- case OC_STACK_RESOURCE_CREATED:
- res = IOTCON_RESPONSE_RESULT_RESOURCE_CREATED;
- break;
- default:
- WARN("resp error(%d)", result);
- res = IOTCON_RESPONSE_RESULT_ERROR;
- options = NULL;
- }
+ res = _ocprocess_parse_oic_result(resp->result);
- if (IOTCON_RESPONSE_RESULT_ERROR != res) {
- options = _ocprocess_parse_header_options(resp->rcvdVendorSpecificHeaderOptions,
- resp->numRcvdVendorSpecificHeaderOptions);
- }
+ options = _ocprocess_parse_header_options(resp->rcvdVendorSpecificHeaderOptions,
+ resp->numRcvdVendorSpecificHeaderOptions);
ret = _ocprocess_worker(_worker_crud_cb, ICD_CRUD_POST, resp->payload, res,
options, ctx);
{
FN_CALL;
int ret, res;
- OCStackResult result;
GVariantBuilder *options;
RETV_IF(NULL == ctx, OC_STACK_DELETE_TRANSACTION);
return OC_STACK_DELETE_TRANSACTION;
}
- result = resp->result;
- switch (result) {
- case OC_STACK_OK:
- res = IOTCON_RESPONSE_RESULT_OK;
- break;
- case OC_STACK_RESOURCE_DELETED:
- res = IOTCON_RESPONSE_RESULT_RESOURCE_DELETED;
- break;
- default:
- WARN("resp error(%d)", result);
- res = IOTCON_RESPONSE_RESULT_ERROR;
- options = NULL;
- }
+ res = _ocprocess_parse_oic_result(resp->result);
- if (IOTCON_RESPONSE_RESULT_ERROR != res) {
- options = _ocprocess_parse_header_options(resp->rcvdVendorSpecificHeaderOptions,
- resp->numRcvdVendorSpecificHeaderOptions);
- }
+ options = _ocprocess_parse_header_options(resp->rcvdVendorSpecificHeaderOptions,
+ resp->numRcvdVendorSpecificHeaderOptions);
ret = _ocprocess_worker(_worker_crud_cb, ICD_CRUD_DELETE, NULL, res, options, ctx);
if (IOTCON_ERROR_NONE != ret) {
}
+static void _icd_observe_context_free(void *ctx)
+{
+ struct icd_observe_context *observe_ctx = ctx;
+
+ g_variant_builder_unref(observe_ctx->options);
+ free(observe_ctx->bus_name);
+ free(observe_ctx);
+}
+
+
static int _worker_observe_cb(void *context)
{
int ret;
value = g_variant_new("(a(qs)vii)", ctx->options, ctx->payload, ctx->res,
ctx->seqnum);
- ret = _ocprocess_response_signal(ctx->bus_name, IC_DBUS_SIGNAL_OBSERVE, ctx->signum,
- value);
+ ret = _ocprocess_response_signal(ctx->bus_name, IC_DBUS_SIGNAL_OBSERVE,
+ ctx->signal_number, value);
if (IOTCON_ERROR_NONE != ret)
ERR("_ocprocess_response_signal() Fail(%d)", ret);
- /* ctx was allocated from icd_ioty_ocprocess_observe_cb() */
- free(ctx->bus_name);
- g_variant_builder_unref(ctx->options);
- free(ctx);
-
return ret;
}
-static void _observe_cb_response_error(const char *dest, unsigned int signum, int ret_val)
+static void _observe_cb_response_error(const char *dest,
+ int64_t signal_number, int ret_val)
{
int ret;
GVariant *value;
+ GVariant *payload;
+ GVariantBuilder options;
+
+ g_variant_builder_init(&options, G_VARIANT_TYPE("a(qs)"));
+ payload = icd_payload_representation_empty_gvariant();
- value = g_variant_new("(a(qs)vii)", NULL, NULL, ret_val, 0);
+ value = g_variant_new("(a(qs)vii)", &options, payload, ret_val, 0);
- ret = _ocprocess_response_signal(dest, IC_DBUS_SIGNAL_OBSERVE, signum, value);
+ ret = _ocprocess_response_signal(dest, IC_DBUS_SIGNAL_OBSERVE, signal_number, value);
if (IOTCON_ERROR_NONE != ret)
ERR("_ocprocess_response_signal() Fail(%d)", ret);
}
-OCStackApplicationResult icd_ioty_ocprocess_observe_cb(void *ctx, OCDoHandle handle,
- OCClientResponse *resp)
+OCStackApplicationResult icd_ioty_ocprocess_observe_cb(void *ctx,
+ OCDoHandle handle, OCClientResponse *resp)
{
int ret, res;
- OCStackResult result;
GVariantBuilder *options;
struct icd_observe_context *observe_ctx;
icd_sig_ctx_s *sig_context = ctx;
if (NULL == resp->payload) {
ERR("payload is empty");
- _observe_cb_response_error(sig_context->bus_name, sig_context->signum,
+ _observe_cb_response_error(sig_context->bus_name, sig_context->signal_number,
IOTCON_ERROR_IOTIVITY);
return OC_STACK_KEEP_TRANSACTION;
}
observe_ctx = calloc(1, sizeof(struct icd_observe_context));
if (NULL == observe_ctx) {
ERR("calloc() Fail(%d)", errno);
- _observe_cb_response_error(sig_context->bus_name, sig_context->signum,
+ _observe_cb_response_error(sig_context->bus_name, sig_context->signal_number,
IOTCON_ERROR_OUT_OF_MEMORY);
return OC_STACK_KEEP_TRANSACTION;
}
- result = resp->result;
- if (OC_STACK_OK == result) {
- res = IOTCON_RESPONSE_RESULT_OK;
- options = _ocprocess_parse_header_options(resp->rcvdVendorSpecificHeaderOptions,
- resp->numRcvdVendorSpecificHeaderOptions);
- } else {
- WARN("resp error(%d)", result);
- res = IOTCON_RESPONSE_RESULT_ERROR;
- options = NULL;
- }
+ res = _ocprocess_parse_oic_result(resp->result);
+
+ options = _ocprocess_parse_header_options(resp->rcvdVendorSpecificHeaderOptions,
+ resp->numRcvdVendorSpecificHeaderOptions);
observe_ctx->payload = icd_payload_to_gvariant(resp->payload);
- observe_ctx->signum = sig_context->signum;
+ observe_ctx->signal_number = sig_context->signal_number;
observe_ctx->res = res;
observe_ctx->bus_name = ic_utils_strdup(sig_context->bus_name);
observe_ctx->options = options;
- ret = _ocprocess_worker_start(_worker_observe_cb, observe_ctx);
+ ret = _ocprocess_worker_start(_worker_observe_cb, observe_ctx,
+ _icd_observe_context_free);
if (IOTCON_ERROR_NONE != ret) {
ERR("_ocprocess_worker_start() Fail(%d)", ret);
- _observe_cb_response_error(sig_context->bus_name, sig_context->signum, ret);
+ _observe_cb_response_error(sig_context->bus_name, sig_context->signal_number, ret);
free(observe_ctx->bus_name);
if (observe_ctx->payload)
g_variant_unref(observe_ctx->payload);
}
+static void _icd_presence_context_free(void *ctx)
+{
+ struct icd_presence_context *presence_ctx = ctx;
+
+ free(presence_ctx->resource_type);
+ free(presence_ctx);
+}
+
+
static int _worker_presence_cb(void *context)
{
- FN_CALL;
- int ret;
- GVariant *value;
- char addr[PATH_MAX] = {0};
+ int conn_type;
+ OCDoHandle handle;
+ char *host_address;
+ GVariant *value, *value2;
+ int ret = IOTCON_ERROR_NONE;
struct icd_presence_context *ctx = context;
RETV_IF(NULL == ctx, IOTCON_ERROR_INVALID_PARAMETER);
- snprintf(addr, sizeof(addr), "%s:%d", ctx->dev_addr->addr, ctx->dev_addr->port);
+ ret = icd_ioty_get_host_address(&ctx->dev_addr, &host_address, &conn_type);
+ if (IOTCON_ERROR_NONE != ret) {
+ ERR("icd_ioty_get_host_address() Fail(%d)", ret);
+ return ret;
+ }
+
+ value = g_variant_new("(iusiis)", ctx->result, ctx->nonce, host_address, conn_type,
+ ctx->trigger, ic_utils_dbus_encode_str(ctx->resource_type));
+ value2 = g_variant_ref(value);
- value = g_variant_new("(ius)", ctx->result, ctx->nonce, addr);
+ free(host_address);
- ret = _ocprocess_response_signal(ctx->bus_name, IC_DBUS_SIGNAL_PRESENCE, ctx->signum,
- value);
+ ret = _ocprocess_response_signal(NULL, IC_DBUS_SIGNAL_PRESENCE,
+ ICD_POINTER_TO_INT64(ctx->handle), value);
if (IOTCON_ERROR_NONE != ret)
ERR("_ocprocess_response_signal() Fail(%d)", ret);
- /* ctx was allocated from icd_ioty_ocprocess_presence_cb() */
- free(ctx->bus_name);
- free(ctx->dev_addr);
- free(ctx);
+ handle = icd_ioty_presence_table_get_handle(ICD_MULTICAST_ADDRESS);
+ if (handle && (handle != ctx->handle)) {
+ ret = _ocprocess_response_signal(NULL, IC_DBUS_SIGNAL_PRESENCE,
+ ICD_POINTER_TO_INT64(handle), value2);
+ if (IOTCON_ERROR_NONE != ret)
+ ERR("_ocprocess_response_signal() Fail(%d)", ret);
+ } else {
+ g_variant_unref(value2);
+ }
return ret;
}
-static void _presence_cb_response_error(const char *dest, unsigned int signum,
- int ret_val)
+static void _presence_cb_response_error(OCDoHandle handle, int ret_val)
{
FN_CALL;
int ret;
- GVariant *value;
+ OCDoHandle handle2;
+ GVariant *value, *value2;
- value = g_variant_new("(ius)", ret_val, 0, IC_STR_NULL);
+ value = g_variant_new("(iusiis)", ret_val, 0, IC_STR_NULL, IOTCON_CONNECTIVITY_ALL,
+ IOTCON_PRESENCE_RESOURCE_CREATED, IC_STR_NULL);
+ value2 = g_variant_ref(value);
- ret = _ocprocess_response_signal(dest, IC_DBUS_SIGNAL_PRESENCE, signum, value);
+ ret = _ocprocess_response_signal(NULL, IC_DBUS_SIGNAL_PRESENCE,
+ ICD_POINTER_TO_INT64(handle), value);
if (IOTCON_ERROR_NONE != ret)
ERR("_ocprocess_response_signal() Fail(%d)", ret);
+
+ handle2 = icd_ioty_presence_table_get_handle(ICD_MULTICAST_ADDRESS);
+ if (handle2 && (handle2 != handle)) {
+ ret = _ocprocess_response_signal(NULL, IC_DBUS_SIGNAL_PRESENCE,
+ ICD_POINTER_TO_INT64(handle), value2);
+ if (IOTCON_ERROR_NONE != ret)
+ ERR("_ocprocess_response_signal() Fail(%d)", ret);
+ } else {
+ g_variant_unref(value2);
+ }
+}
+
+
+static int _presence_trigger_to_ioty_trigger(OCPresenceTrigger src,
+ iotcon_presence_trigger_e *dest)
+{
+ RETV_IF(NULL == dest, IOTCON_ERROR_INVALID_PARAMETER);
+
+ switch (src) {
+ case OC_PRESENCE_TRIGGER_CREATE:
+ *dest = IOTCON_PRESENCE_RESOURCE_CREATED;
+ break;
+ case OC_PRESENCE_TRIGGER_CHANGE:
+ *dest = IOTCON_PRESENCE_RESOURCE_UPDATED;
+ break;
+ case OC_PRESENCE_TRIGGER_DELETE:
+ *dest = IOTCON_PRESENCE_RESOURCE_DESTROYED;
+ break;
+ default:
+ ERR("Invalid trigger(%d)", src);
+ return IOTCON_ERROR_INVALID_PARAMETER;
+ }
+
+ return IOTCON_ERROR_NONE;
}
{
FN_CALL;
int ret;
- OCDevAddr *dev_addr;
- icd_sig_ctx_s *sig_context = ctx;
+ OCPresencePayload *payload;
struct icd_presence_context *presence_ctx;
- RETV_IF(NULL == ctx, OC_STACK_KEEP_TRANSACTION);
RETV_IF(NULL == resp, OC_STACK_KEEP_TRANSACTION);
presence_ctx = calloc(1, sizeof(struct icd_presence_context));
if (NULL == presence_ctx) {
ERR("calloc() Fail(%d)", errno);
- _presence_cb_response_error(sig_context->bus_name, sig_context->signum,
- IOTCON_ERROR_OUT_OF_MEMORY);
+ _presence_cb_response_error(handle, IOTCON_ERROR_OUT_OF_MEMORY);
return OC_STACK_KEEP_TRANSACTION;
}
- dev_addr = calloc(1, sizeof(OCDevAddr));
- if (NULL == dev_addr) {
- ERR("calloc() Fail(%d)", errno);
- _presence_cb_response_error(sig_context->bus_name, sig_context->signum,
- IOTCON_ERROR_OUT_OF_MEMORY);
- free(presence_ctx);
- return OC_STACK_KEEP_TRANSACTION;
- }
- memcpy(dev_addr, &resp->devAddr, sizeof(OCDevAddr));
+ memcpy(&presence_ctx->dev_addr, &resp->devAddr, sizeof(OCDevAddr));
+
+ payload = (OCPresencePayload*)resp->payload;
switch (resp->result) {
case OC_STACK_OK:
presence_ctx->result = IOTCON_PRESENCE_OK;
+ ret = _presence_trigger_to_ioty_trigger(payload->trigger, &presence_ctx->trigger);
+ if (IOTCON_ERROR_NONE != ret) {
+ ERR("_presence_trigger_to_ioty_trigger() Fail(%d)", ret);
+ _presence_cb_response_error(handle, ret);
+ free(presence_ctx);
+ return OC_STACK_KEEP_TRANSACTION;
+ }
break;
case OC_STACK_PRESENCE_STOPPED:
presence_ctx->result = IOTCON_PRESENCE_STOPPED;
presence_ctx->result = IOTCON_ERROR_IOTIVITY;
}
- presence_ctx->signum = sig_context->signum;
- presence_ctx->bus_name = ic_utils_strdup(sig_context->bus_name);
+ presence_ctx->handle = handle;
presence_ctx->nonce = resp->sequenceNumber;
- presence_ctx->dev_addr = dev_addr;
- ret = _ocprocess_worker_start(_worker_presence_cb, presence_ctx);
+ if (payload->resourceType)
+ presence_ctx->resource_type = strdup(payload->resourceType);
+
+ ret = _ocprocess_worker_start(_worker_presence_cb, presence_ctx,
+ _icd_presence_context_free);
if (IOTCON_ERROR_NONE != ret) {
ERR("_ocprocess_worker_start() Fail(%d)", ret);
- _presence_cb_response_error(sig_context->bus_name, sig_context->signum, ret);
- free(presence_ctx->bus_name);
- free(presence_ctx->dev_addr);
- free(presence_ctx);
+ _presence_cb_response_error(handle, ret);
+ _icd_presence_context_free(presence_ctx);
return OC_STACK_KEEP_TRANSACTION;
}
- /* DO NOT FREE sig_context. It MUST be freed in the ocstack */
/* DO NOT FREE presence_ctx. It MUST be freed in the _worker_presence_cb func */
return OC_STACK_KEEP_TRANSACTION;
}
+static void _icd_info_context_free(void *ctx)
+{
+ struct icd_info_context *info_ctx = ctx;
+
+ free(info_ctx->bus_name);
+ free(info_ctx);
+}
+
+
+static int _worker_info_cb(void *context)
+{
+ int ret;
+ const char *signal_prefix = NULL;
+ struct icd_info_context *ctx = context;
+
+ RETV_IF(NULL == ctx, IOTCON_ERROR_INVALID_PARAMETER);
+
+ if (ICD_DEVICE_INFO == ctx->info_type)
+ signal_prefix = IC_DBUS_SIGNAL_DEVICE;
+ else if (ICD_PLATFORM_INFO == ctx->info_type)
+ signal_prefix = IC_DBUS_SIGNAL_PLATFORM;
+
+ ret = _ocprocess_response_signal(ctx->bus_name, signal_prefix, ctx->signal_number,
+ ctx->payload);
+ if (IOTCON_ERROR_NONE != ret)
+ ERR("_ocprocess_response_signal() Fail(%d)", ret);
+
+ return ret;
+}
+
+
OCStackApplicationResult icd_ioty_ocprocess_info_cb(void *ctx, OCDoHandle handle,
OCClientResponse *resp)
{
info_ctx->info_type = info_type;
info_ctx->payload = icd_payload_to_gvariant(resp->payload);
- info_ctx->signum = sig_context->signum;
+ info_ctx->signal_number = sig_context->signal_number;
info_ctx->bus_name = ic_utils_strdup(sig_context->bus_name);
- ret = _ocprocess_worker_start(_worker_info_cb, info_ctx);
+ ret = _ocprocess_worker_start(_worker_info_cb, info_ctx, _icd_info_context_free);
if (IOTCON_ERROR_NONE != ret) {
ERR("_ocprocess_worker_start() Fail(%d)", ret);
- free(info_ctx->bus_name);
if (info_ctx->payload)
g_variant_unref(info_ctx->payload);
- free(info_ctx);
+ _icd_info_context_free(info_ctx);
return OC_STACK_KEEP_TRANSACTION;
}
}
+static void _icd_encap_get_context_free(void *ctx)
+{
+ struct icd_encap_get_context *encap_ctx = ctx;
+
+ free(encap_ctx->uri_path);
+ free(encap_ctx);
+}
+
+
+static int _worker_encap_get_cb(void *context)
+{
+ int ret, conn_type;
+ char *host_address;
+ icd_encap_info_s *encap_info;
+ GVariant *monitoring_value, *caching_value;
+ iotcon_remote_resource_state_e resource_state;
+ struct icd_encap_get_context *encap_get_ctx = context;
+
+ /* GET ENCAP INFO */
+ ret = icd_ioty_get_host_address(&encap_get_ctx->dev_addr, &host_address, &conn_type);
+ if (IOTCON_ERROR_NONE != ret) {
+ ERR("icd_ioty_get_host_address() Fail");
+ return ret;
+ }
+
+ encap_info = _icd_ioty_encap_table_get_info(encap_get_ctx->uri_path, host_address);
+ if (NULL == encap_info) {
+ ERR("_icd_ioty_encap_table_get_info() Fail");
+ free(host_address);
+ return IOTCON_ERROR_NO_DATA;
+ }
+ free(host_address);
+
+ /* MONITORING */
+ if (0 < encap_info->monitoring_count) {
+ switch (encap_get_ctx->ret) {
+ case OC_STACK_OK:
+ resource_state = IOTCON_REMOTE_RESOURCE_ALIVE;
+ break;
+ case OC_STACK_ERROR:
+ default:
+ resource_state = IOTCON_REMOTE_RESOURCE_LOST_SIGNAL;
+ }
+ if (resource_state != encap_info->resource_state) {
+ encap_info->resource_state = resource_state;
+ monitoring_value = g_variant_new("(i)", resource_state);
+ ret = _ocprocess_response_signal(NULL, IC_DBUS_SIGNAL_MONITORING,
+ encap_info->signal_number, monitoring_value);
+ if (IOTCON_ERROR_NONE != ret) {
+ ERR("_ocprocess_response_signal() Fail(%d)", ret);
+ OCRepPayloadDestroy(encap_get_ctx->oic_payload);
+ return ret;
+ }
+ }
+ }
+
+ /* CACHING */
+ if (0 < encap_info->caching_count) {
+ if (OC_STACK_OK != encap_get_ctx->ret) {
+ OCRepPayloadDestroy(encap_get_ctx->oic_payload);
+ return IOTCON_ERROR_NONE;
+ }
+
+ ret = icd_payload_representation_compare(encap_info->oic_payload,
+ encap_get_ctx->oic_payload);
+ if (IC_EQUAL == ret) {
+ OCRepPayloadDestroy(encap_get_ctx->oic_payload);
+ return IOTCON_ERROR_NONE;
+ }
+
+ encap_info->oic_payload = encap_get_ctx->oic_payload;
+ caching_value = icd_payload_to_gvariant((OCPayload*)encap_get_ctx->oic_payload);
+
+ ret = _ocprocess_response_signal(NULL, IC_DBUS_SIGNAL_CACHING,
+ encap_info->signal_number, caching_value);
+ if (IOTCON_ERROR_NONE != ret) {
+ ERR("_ocprocess_response_signal() Fail(%d)", ret);
+ return ret;
+ }
+ }
+
+ return IOTCON_ERROR_NONE;
+}
+
+
+OCStackApplicationResult icd_ioty_ocprocess_encap_get_cb(void *ctx, OCDoHandle handle,
+ OCClientResponse *resp)
+{
+ int ret;
+ struct icd_encap_get_context *encap_get_ctx;
+
+ RETV_IF(NULL == resp, OC_STACK_DELETE_TRANSACTION);
+
+ encap_get_ctx = calloc(1, sizeof(struct icd_encap_get_context));
+ if (NULL == encap_get_ctx) {
+ ERR("calloc() Fail(%d)", errno);
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+
+ encap_get_ctx->ret = resp->result;
+ encap_get_ctx->oic_payload = OCRepPayloadClone((OCRepPayload*)resp->payload);
+ encap_get_ctx->uri_path = ic_utils_strdup(resp->resourceUri);
+ memcpy(&encap_get_ctx->dev_addr, &resp->devAddr, sizeof(OCDevAddr));
+
+ ret = _ocprocess_worker_start(_worker_encap_get_cb, encap_get_ctx,
+ _icd_encap_get_context_free);
+ if (IOTCON_ERROR_NONE != ret) {
+ ERR("_ocprocess_worker_start() Fail(%d)", ret);
+ OCRepPayloadDestroy((OCRepPayload*)encap_get_ctx->oic_payload);
+ _icd_encap_get_context_free(encap_get_ctx);
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+
+ return OC_STACK_DELETE_TRANSACTION;
+}
+
+
+static int _worker_encap_get(void *context)
+{
+ int ret, conn_type;
+ char *host_address;
+ icd_encap_info_s *encap_info;
+ icd_encap_worker_ctx_s *encap_ctx = context;
+
+ if (false == encap_ctx->is_valid)
+ return IOTCON_ERROR_NONE;
+
+ ret = icd_ioty_get_host_address(&encap_ctx->dev_addr, &host_address, &conn_type);
+ if (IOTCON_ERROR_NONE != ret) {
+ ERR("icd_ioty_get_host_address() Fail");
+ return ret;
+ }
+
+ encap_info = _icd_ioty_encap_table_get_info(encap_ctx->uri_path, host_address);
+ if (NULL == encap_info) {
+ ERR("_icd_ioty_encap_table_get_info() Fail");
+ free(host_address);
+ return IOTCON_ERROR_NO_DATA;
+ }
+ free(host_address);
+
+ g_source_remove(encap_info->get_timer_id);
+ icd_ioty_encap_get(encap_info);
+ encap_info->get_timer_id = g_timeout_add_seconds(icd_ioty_encap_get_time_interval(),
+ icd_ioty_encap_get, encap_info);
+
+ return IOTCON_ERROR_NONE;
+}
+
+
+OCStackApplicationResult icd_ioty_ocprocess_encap_observe_cb(void *ctx, OCDoHandle handle,
+ OCClientResponse *resp)
+{
+ FN_CALL;
+ int ret;
+ icd_encap_worker_ctx_s *encap_ctx = ctx;
+
+ RETV_IF(NULL == resp, OC_STACK_KEEP_TRANSACTION);
+
+ if (OC_OBSERVE_DEREGISTER == resp->sequenceNumber)
+ return OC_STACK_DELETE_TRANSACTION;
+
+ if (OC_STACK_OK != resp->result)
+ return OC_STACK_KEEP_TRANSACTION;
+
+ memcpy(&encap_ctx->dev_addr, &resp->devAddr, sizeof(OCDevAddr));
+
+ ret = _ocprocess_worker_start(_worker_encap_get, encap_ctx, NULL);
+ if (IOTCON_ERROR_NONE != ret) {
+ ERR("_ocprocess_worker_start() Fail(%d)", ret);
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+
+ return OC_STACK_KEEP_TRANSACTION;
+}
+
+
+OCStackApplicationResult icd_ioty_ocprocess_encap_presence_cb(void *ctx,
+ OCDoHandle handle, OCClientResponse *resp)
+{
+ FN_CALL;
+ int ret;
+ icd_encap_worker_ctx_s *encap_ctx = ctx;
+ OCPresencePayload *payload = (OCPresencePayload*)resp->payload;
+
+ RETV_IF(NULL == resp, OC_STACK_KEEP_TRANSACTION);
+
+ if ((OC_STACK_OK == resp->result) && (OC_PRESENCE_TRIGGER_DELETE != payload->trigger))
+ return OC_STACK_KEEP_TRANSACTION;
+
+ memcpy(&encap_ctx->dev_addr, &resp->devAddr, sizeof(OCDevAddr));
+
+ ret = _ocprocess_worker_start(_worker_encap_get, encap_ctx, NULL);
+ if (IOTCON_ERROR_NONE != ret) {
+ ERR("_ocprocess_worker_start() Fail(%d)", ret);
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+
+ return OC_STACK_KEEP_TRANSACTION;
+}