#define IC_DBUS_SIGNAL_DEVICE "DEVICE"
#define IC_DBUS_SIGNAL_PLATFORM "PLATFORM"
#define IC_DBUS_SIGNAL_PRESENCE "PRESENCE"
+#define IC_DBUS_SIGNAL_MONITORING "MONITORING"
+#define IC_DBUS_SIGNAL_CACHING "CACHING"
#define IC_INTERFACE_DEFAULT "oic.if.baseline"
#define IC_INTERFACE_LINK "oic.if.ll"
<arg type="as" name="resource_types" direction="in"/>
<arg type="i" name="ifaces" direction="in"/>
<arg type="i" name="properties" direction="in"/>
- <arg type="x" name="signal_number" direction="in"/>
+ <arg type="x" name="signal_number" direction="out"/>
<arg type="x" name="resource" direction="out"/>
</method>
<method name="unregisterResource">
<arg type="s" name="host_address" direction="in"/>
<arg type="i" name="connectivity" direction="in"/>
<arg type="s" name="type" direction="in"/>
- <arg type="x" name="signal_number" direction="in"/>
+ <arg type="x" name="signal_number" direction="out"/>
<arg type="i" name="ret" direction="out"/>
</method>
<method name="get">
<arg type="(ssba(qs)i)" name="remote_resource" direction="in"/>
<arg type="i" name="observe_type" direction="in"/>
<arg type="a(ss)" name="query" direction="in"/>
- <arg type="x" name="signal_number" direction="in"/>
+ <arg type="x" name="signal_number" direction="out"/>
<arg type="x" name="observe_h" direction="out"/>
</method>
<method name="observerStop">
<method name="getDeviceInfo">
<arg type="s" name="host_address" direction="in"/>
<arg type="i" name="connectivity" direction="in"/>
- <arg type="x" name="signal_number" direction="in"/>
+ <arg type="x" name="signal_number" direction="out"/>
<arg type="i" name="ret" direction="out"/>
</method>
<method name="getPlatformInfo">
<arg type="s" name="host_address" direction="in"/>
<arg type="i" name="connectivity" direction="in"/>
- <arg type="x" name="signal_number" direction="in"/>
+ <arg type="x" name="signal_number" direction="out"/>
<arg type="i" name="ret" direction="out"/>
</method>
<method name="getTizenInfo">
<method name="stopPresence">
<arg type="i" name="ret" direction="out"/>
</method>
+ <method name="startMonitoring">
+ <arg type="s" name="uri_path" direction="in"/>
+ <arg type="s" name="host_address" direction="in"/>
+ <arg type="i" name="connectivity" direction="in"/>
+ <arg type="x" name="signal_number" direction="out"/>
+ <arg type="i" name="ret" direction="out"/>
+ </method>
+ <method name="stopMonitoring">
+ <arg type="s" name="uri_path" direction="in"/>
+ <arg type="s" name="host_address" direction="in"/>
+ <arg type="i" name="ret" direction="out"/>
+ </method>
+ <method name="startCaching">
+ <arg type="s" name="uri_path" direction="in"/>
+ <arg type="s" name="host_address" direction="in"/>
+ <arg type="i" name="connectivity" direction="in"/>
+ <arg type="x" name="signal_number" direction="out"/>
+ <arg type="i" name="ret" direction="out"/>
+ </method>
+ <method name="stopCaching">
+ <arg type="s" name="uri_path" direction="in"/>
+ <arg type="s" name="host_address" direction="in"/>
+ <arg type="i" name="ret" direction="out"/>
+ </method>
+ <method name="encapGetTimeInterval">
+ <arg type="i" name="time_interval" direction="out"/>
+ </method>
+ <method name="encapSetTimeInterval">
+ <arg type="i" name="time_interval" direction="in"/>
+ </method>
</interface>
</node>
}
+int64_t icd_dbus_generate_signal_number()
+{
+ static int64_t i = 0;
+
+ return i++;
+}
+
+
static void _icd_dbus_resource_handle_free(OCResourceHandle handle)
{
icd_dbus_client_s *client;
const gchar *uri_path,
const gchar* const *resource_types,
gint ifaces,
- gint properties,
- gint64 signal_number)
+ gint properties)
{
FN_CALL;
int ret;
const gchar *sender;
OCResourceHandle handle;
+ int64_t signal_number = 0;
handle = icd_ioty_register_resource(uri_path, resource_types, ifaces, properties);
if (handle) {
sender = g_dbus_method_invocation_get_sender(invocation);
+ signal_number = icd_dbus_generate_signal_number();
ret = _icd_dbus_resource_list_append_handle(sender, handle, signal_number);
if (IOTCON_ERROR_NONE != ret) {
ERR("_icd_dbus_resource_list_append_handle() Fail(%d)", ret);
}
}
- ic_dbus_complete_register_resource(object, invocation, ICD_POINTER_TO_INT64(handle));
+ ic_dbus_complete_register_resource(object, invocation, signal_number,
+ ICD_POINTER_TO_INT64(handle));
return TRUE;
}
GDBusMethodInvocation *invocation,
const gchar *host_address,
gint connectivity,
- const gchar *type,
- gint64 signal_number)
+ const gchar *type)
{
int ret;
const gchar *sender;
+ int64_t signal_number;
sender = g_dbus_method_invocation_get_sender(invocation);
+
+ signal_number = icd_dbus_generate_signal_number();
ret = icd_ioty_find_resource(host_address, connectivity, type, signal_number, sender);
if (IOTCON_ERROR_NONE != ret)
ERR("icd_ioty_find_resource() Fail(%d)", ret);
- ic_dbus_complete_find_resource(object, invocation, ret);
+ ic_dbus_complete_find_resource(object, invocation, signal_number, ret);
return TRUE;
}
GDBusMethodInvocation *invocation,
GVariant *resource,
gint observe_policy,
- GVariant *query,
- gint64 signal_number)
+ GVariant *query)
{
OCDoHandle observe_h;
const gchar *sender;
+ int64_t signal_number;
+ signal_number = icd_dbus_generate_signal_number();
sender = g_dbus_method_invocation_get_sender(invocation);
+
observe_h = icd_ioty_observer_start(resource, observe_policy, query,
signal_number, sender);
if (NULL == observe_h)
ERR("icd_ioty_observer_start() Fail");
- ic_dbus_complete_observer_start(object, invocation, ICD_POINTER_TO_INT64(observe_h));
+ ic_dbus_complete_observer_start(object, invocation, signal_number,
+ ICD_POINTER_TO_INT64(observe_h));
/* observe_h will be freed in _dbus_handle_observer_stop() */
return TRUE;
static gboolean _dbus_handle_get_device_info(icDbus *object,
GDBusMethodInvocation *invocation,
const gchar *host_address,
- gint connectivity,
- gint64 signal_number)
+ gint connectivity)
{
int ret;
const gchar *sender;
+ int64_t signal_number;
+ signal_number = icd_dbus_generate_signal_number();
sender = g_dbus_method_invocation_get_sender(invocation);
+
ret = icd_ioty_get_info(ICD_DEVICE_INFO, host_address, connectivity, signal_number,
sender);
if (IOTCON_ERROR_NONE != ret)
ERR("icd_ioty_get_info(device info) Fail(%d)", ret);
- ic_dbus_complete_get_device_info(object, invocation, ret);
+ ic_dbus_complete_get_device_info(object, invocation, signal_number, ret);
return TRUE;
}
static gboolean _dbus_handle_get_platform_info(icDbus *object,
GDBusMethodInvocation *invocation,
const gchar *host_address,
- gint connectivity,
- gint64 signal_number)
+ gint connectivity)
{
int ret;
const gchar *sender;
+ int64_t signal_number;
+ signal_number = icd_dbus_generate_signal_number();
sender = g_dbus_method_invocation_get_sender(invocation);
+
ret = icd_ioty_get_info(ICD_PLATFORM_INFO, host_address, connectivity, signal_number,
sender);
if (IOTCON_ERROR_NONE != ret)
ERR("icd_ioty_get_info(platform info) Fail(%d)", ret);
- ic_dbus_complete_get_platform_info(object, invocation, ret);
+ ic_dbus_complete_get_platform_info(object, invocation, signal_number, ret);
return TRUE;
}
{
OCDoHandle presence_h;
- presence_h = icd_ioty_subscribe_presence(host_address, connectivity, type);
+ presence_h = icd_ioty_subscribe_presence(ICD_PRESENCE, host_address, connectivity,
+ type, NULL);
if (NULL == presence_h)
ERR("icd_ioty_subscribe_presence() Fail");
}
+static gboolean _dbus_handle_encap_get_time_interval(icDbus *object,
+ GDBusMethodInvocation *invocation)
+{
+ int time_interval;
+
+ time_interval = icd_ioty_encap_get_time_interval();
+
+ ic_dbus_complete_encap_get_time_interval(object, invocation, time_interval);
+
+ return TRUE;
+}
+
+
+static gboolean _dbus_handle_encap_set_time_interval(icDbus *object,
+ GDBusMethodInvocation *invocation,
+ gint time_interval)
+{
+ icd_ioty_encap_set_time_interval(time_interval);
+
+ ic_dbus_complete_encap_set_time_interval(object, invocation);
+
+ return TRUE;
+}
+
+
+static gboolean _dbus_handle_start_monitoring(icDbus *object,
+ GDBusMethodInvocation *invocation,
+ const gchar *uri_path,
+ const gchar *host_address,
+ gint connectivity)
+{
+ int ret;
+ int64_t signal_number;
+
+ ret = icd_ioty_start_encap(ICD_ENCAP_MONITORING, uri_path, host_address,
+ connectivity, &signal_number);
+ if (IOTCON_ERROR_NONE != ret)
+ ERR("icd_ioty_start_encap() Fail(%d)", ret);
+
+ ic_dbus_complete_start_monitoring(object, invocation, signal_number, ret);
+
+ return TRUE;
+}
+
+
+static gboolean _dbus_handle_stop_monitoring(icDbus *object,
+ GDBusMethodInvocation *invocation,
+ const gchar *uri_path,
+ const gchar *host_address)
+{
+ int ret;
+
+ ret = icd_ioty_stop_encap(ICD_ENCAP_MONITORING, uri_path, host_address);
+ if (IOTCON_ERROR_NONE != ret)
+ ERR("icd_ioty_stop_encap() Fail(%d)", ret);
+
+ ic_dbus_complete_stop_monitoring(object, invocation, ret);
+
+ return TRUE;
+}
+
+
+static gboolean _dbus_handle_start_caching(icDbus *object,
+ GDBusMethodInvocation *invocation,
+ const gchar *uri_path,
+ const gchar *host_address,
+ gint connectivity)
+{
+ int ret;
+ int64_t signal_number;
+
+ ret = icd_ioty_start_encap(ICD_ENCAP_CACHING, uri_path, host_address,
+ connectivity, &signal_number);
+ if (IOTCON_ERROR_NONE != ret)
+ ERR("icd_ioty_start_encap() Fail(%d)", ret);
+
+ ic_dbus_complete_start_monitoring(object, invocation, signal_number, ret);
+
+ return TRUE;
+}
+
+
+static gboolean _dbus_handle_stop_caching(icDbus *object,
+ GDBusMethodInvocation *invocation,
+ const gchar *uri_path,
+ const gchar *host_address)
+{
+ int ret;
+
+ ret = icd_ioty_stop_encap(ICD_ENCAP_CACHING, uri_path, host_address);
+ if (IOTCON_ERROR_NONE != ret)
+ ERR("icd_ioty_stop_encap() Fail(%d)", ret);
+
+ ic_dbus_complete_stop_monitoring(object, invocation, ret);
+
+ return TRUE;
+}
+
+
static void _dbus_on_bus_acquired(GDBusConnection *conn, const gchar *name,
gpointer user_data)
{
G_CALLBACK(_dbus_handle_subscribe_presence), NULL);
g_signal_connect(icd_dbus_object, "handle-unsubscribe-presence",
G_CALLBACK(_dbus_handle_unsubscribe_presence), NULL);
+ g_signal_connect(icd_dbus_object, "handle-encap-get-time-interval",
+ G_CALLBACK(_dbus_handle_encap_get_time_interval), NULL);
+ g_signal_connect(icd_dbus_object, "handle-encap-set-time-interval",
+ G_CALLBACK(_dbus_handle_encap_set_time_interval), NULL);
+ g_signal_connect(icd_dbus_object, "handle-start-monitoring",
+ G_CALLBACK(_dbus_handle_start_monitoring), NULL);
+ g_signal_connect(icd_dbus_object, "handle-stop-monitoring",
+ G_CALLBACK(_dbus_handle_stop_monitoring), NULL);
+ g_signal_connect(icd_dbus_object, "handle-start-caching",
+ G_CALLBACK(_dbus_handle_start_caching), NULL);
+ g_signal_connect(icd_dbus_object, "handle-stop-caching",
+ G_CALLBACK(_dbus_handle_stop_caching), NULL);
ret = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(icd_dbus_object),
conn, IOTCON_DBUS_OBJPATH, &error);
#define ICD_POINTER_TO_INT64(p) ((int64_t)(intptr_t)(p))
icDbus* icd_dbus_get_object();
+int64_t icd_dbus_generate_signal_number();
int icd_dbus_client_list_get_info(void *handle, int64_t *signal_number,
gchar **bus_name);
int icd_dbus_emit_signal(const char *dest, const char *signal_name,
};
+struct icd_encap_context {
+ int64_t signal_number;
+ OCRepPayload *oic_payload;
+ OCStackResult ret;
+ icd_encap_info_s *encap_info;
+};
+
+
void icd_ioty_ocprocess_stop()
{
icd_ioty_alive = 0;
return OC_STACK_DELETE_TRANSACTION;
}
+
+
+static int _worker_encap_get_cb(void *context)
+{
+ int ret;
+ struct icd_encap_context *ctx = context;
+ iotcon_remote_resource_state_e resource_state;
+ GVariant *monitoring_value, *caching_value;
+
+ RETV_IF(NULL == ctx, IOTCON_ERROR_INVALID_PARAMETER);
+
+ /* MONITORING */
+ if (0 < ctx->encap_info->monitoring_count) {
+ switch (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 != ctx->encap_info->resource_state) {
+ ctx->encap_info->resource_state = resource_state;
+ monitoring_value = g_variant_new("(i)", resource_state);
+ ret = _ocprocess_response_signal(NULL, IC_DBUS_SIGNAL_MONITORING,
+ ctx->encap_info->signal_number, monitoring_value);
+ if (IOTCON_ERROR_NONE != ret) {
+ ERR("_ocprocess_response_signal() Fail(%d)", ret);
+ OCRepPayloadDestroy(ctx->oic_payload);
+ free(ctx);
+ return ret;
+ }
+ }
+ }
+
+ /* CACHING */
+ if (0 < ctx->encap_info->caching_count) {
+ if (OC_STACK_OK != ctx->ret) {
+ OCRepPayloadDestroy(ctx->oic_payload);
+ free(ctx);
+ return IOTCON_ERROR_NONE;
+ }
+
+ ret = icd_payload_representation_compare(ctx->encap_info->oic_payload,
+ ctx->oic_payload);
+ if (IC_EQUAL == ret) {
+ OCRepPayloadDestroy(ctx->oic_payload);
+ free(ctx);
+ return IOTCON_ERROR_NONE;
+ }
+
+ ctx->encap_info->oic_payload = ctx->oic_payload;
+ caching_value = icd_payload_to_gvariant((OCPayload*)ctx->oic_payload);
+
+ ret = _ocprocess_response_signal(NULL, IC_DBUS_SIGNAL_CACHING,
+ ctx->encap_info->signal_number, caching_value);
+ if (IOTCON_ERROR_NONE != ret) {
+ ERR("_ocprocess_response_signal() Fail(%d)", ret);
+ OCRepPayloadDestroy(ctx->oic_payload);
+ free(ctx);
+ return ret;
+ }
+ }
+
+ OCRepPayloadDestroy(ctx->oic_payload);
+ free(ctx);
+
+ return IOTCON_ERROR_NONE;
+}
+
+
+OCStackApplicationResult icd_ioty_ocprocess_encap_get_cb(void *ctx, OCDoHandle handle,
+ OCClientResponse *resp)
+{
+ FN_CALL;
+ int ret;
+ icd_encap_info_s *encap_info = ctx;
+ struct icd_encap_context *encap_ctx;
+
+ RETV_IF(NULL == ctx, OC_STACK_DELETE_TRANSACTION);
+
+ encap_ctx = calloc(1, sizeof(struct icd_encap_context));
+ if (NULL == encap_ctx) {
+ ERR("calloc() Fail(%d)", errno);
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+
+ encap_ctx->ret = resp->result;
+ encap_ctx->oic_payload = OCRepPayloadClone((OCRepPayload*)resp->payload);
+ encap_ctx->encap_info = encap_info;
+
+ ret = _ocprocess_worker_start(_worker_encap_get_cb, encap_ctx);
+ if (IOTCON_ERROR_NONE != ret) {
+ ERR("_ocprocess_worker_start() Fail(%d)", ret);
+ OCRepPayloadDestroy((OCRepPayload*)encap_ctx->oic_payload);
+ free(encap_ctx);
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+
+ return OC_STACK_DELETE_TRANSACTION;
+}
+
+
+static int _worker_encap_get(void *context)
+{
+ icd_encap_info_s *encap_info = context;
+
+ 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;
+
+ RETV_IF(NULL == resp, OC_STACK_KEEP_TRANSACTION);
+
+ ret = _ocprocess_worker_start(_worker_encap_get, ctx);
+ 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;
+ 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;
+
+ ret = _ocprocess_worker_start(_worker_encap_get, ctx);
+ 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_get_tizen_info_cb(void *ctx,
OCDoHandle handle, OCClientResponse* resp);
+OCStackApplicationResult icd_ioty_ocprocess_encap_get_cb(void *ctx, OCDoHandle handle,
+ OCClientResponse* resp);
+
+OCStackApplicationResult icd_ioty_ocprocess_encap_observe_cb(void *ctx, OCDoHandle handle,
+ OCClientResponse* resp);
+
+OCStackApplicationResult icd_ioty_ocprocess_encap_presence_cb(void *ctx,
+ OCDoHandle handle, OCClientResponse* resp);
+
#endif /*__IOT_CONNECTIVITY_MANAGER_DAEMON_IOTIVITY_OCPROCESS_H__*/
#include "icd-ioty-ocprocess.h"
#define ICD_UUID_LENGTH 37
+#define ICD_REMOTE_RESOURCE_DEFAULT_TIME_INTERVAL 10 /* 10 sec */
+
+static int icd_remote_resource_time_interval = ICD_REMOTE_RESOURCE_DEFAULT_TIME_INTERVAL;
static const char *ICD_SYSTEM_INFO_TIZEN_ID = "http://tizen.org/system/tizenid";
static const char *ICD_SYSTEM_INFO_PLATFORM_NAME = "http://tizen.org/system/platform.name";
static icd_tizen_info_s icd_tizen_info = {0};
+static GHashTable *icd_ioty_encap_table;
static GHashTable *icd_ioty_presence_table;
static GMutex icd_csdk_mutex;
}
+static OCDoHandle _icd_ioty_observe_register(const char *uri_path,
+ OCDevAddr *dev_addr,
+ GVariantIter *options,
+ OCMethod method,
+ OCConnectivityType oic_conn_type,
+ OCCallbackData *cbdata)
+{
+ OCDoHandle handle;
+ int options_size = 0;
+ OCStackResult result;
+ OCHeaderOption *oic_options_ptr = NULL;
+ OCHeaderOption oic_options[MAX_HEADER_OPTIONS];
+
+ if (options) {
+ options_size = g_variant_iter_n_children(options);
+ if (0 != options_size) {
+ int ret = _ioty_get_header_options(options, options_size, oic_options,
+ sizeof(oic_options) / sizeof(oic_options[0]));
+ if (IOTCON_ERROR_NONE != ret) {
+ ERR("_ioty_get_header_options() Fail(%d)", ret);
+ if (cbdata->cd)
+ cbdata->cd(cbdata->context);
+ return NULL;
+ }
+ oic_options_ptr = oic_options;
+ }
+ }
+
+ icd_ioty_csdk_lock();
+ /* TODO : QoS is come from lib. And user can set QoS to client structure. */
+ result = OCDoResource(&handle, method, uri_path, dev_addr, NULL, oic_conn_type,
+ OC_LOW_QOS, cbdata, oic_options_ptr, options_size);
+ icd_ioty_csdk_unlock();
+
+ if (OC_STACK_OK != result) {
+ ERR("OCDoResource() Fail(%d)", result);
+ if (cbdata->cd)
+ cbdata->cd(cbdata->context);
+ return NULL;
+ }
+
+ return handle;
+}
+
+
OCDoHandle icd_ioty_observer_start(GVariant *resource, int observe_policy,
GVariant *query, int64_t signal_number, const char *bus_name)
{
bool is_secure;
OCMethod method;
OCDoHandle handle;
- OCStackResult result;
GVariantIter *options;
+ int ret, conn_type;
icd_sig_ctx_s *context;
- OCCallbackData cbdata = {0};
- int ret, conn_type, options_size;
char *uri_path, *host, *uri;
- OCHeaderOption oic_options[MAX_HEADER_OPTIONS];
- OCHeaderOption *oic_options_ptr = NULL;
- OCConnectivityType oic_conn_type;
OCDevAddr dev_addr = {0};
+ OCCallbackData cbdata = {0};
+ OCConnectivityType oic_conn_type;
g_variant_get(resource, "(&s&sba(qs)i)", &uri_path, &host, &is_secure, &options,
&conn_type);
else
method = OC_REST_OBSERVE_ALL;
+ oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
+
+ ret = icd_ioty_get_dev_addr(host, conn_type, &dev_addr);
+ if (IOTCON_ERROR_NONE != ret) {
+ ERR("icd_ioty_get_dev_addr() Fail(%d)", ret);
+ free(uri);
+ g_variant_iter_free(options);
+ return NULL;
+ }
+
context = calloc(1, sizeof(icd_sig_ctx_s));
if (NULL == context) {
ERR("calloc() Fail(%d)", errno);
free(uri);
+ g_variant_iter_free(options);
return NULL;
}
- context->bus_name = ic_utils_strdup(bus_name);
+
context->signal_number = signal_number;
+ context->bus_name = ic_utils_strdup(bus_name);
cbdata.context = context;
cbdata.cb = icd_ioty_ocprocess_observe_cb;
cbdata.cd = _ioty_free_signal_context;
- options_size = g_variant_iter_n_children(options);
- if (0 != options_size) {
- int ret = _ioty_get_header_options(options, options_size, oic_options,
- sizeof(oic_options) / sizeof(oic_options[0]));
- if (IOTCON_ERROR_NONE != ret) {
- ERR("_ioty_get_header_options() Fail(%d)", ret);
- free(context->bus_name);
- free(context);
- free(uri);
- g_variant_iter_free(options);
- return NULL;
- }
- oic_options_ptr = oic_options;
- }
- g_variant_iter_free(options);
-
- oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
-
- ret = icd_ioty_get_dev_addr(host, conn_type, &dev_addr);
- if (IOTCON_ERROR_NONE != ret) {
- ERR("icd_ioty_get_dev_addr() Fail(%d)", ret);
- free(context->bus_name);
- free(context);
- free(uri);
- return NULL;
- }
+ handle = _icd_ioty_observe_register(uri, &dev_addr, options, method, oic_conn_type,
+ &cbdata);
+ if (NULL == handle)
+ ERR("_icd_ioty_observe_register() Fail");
- icd_ioty_csdk_lock();
- /* TODO : QoS is come from lib. And user can set QoS to client structure. */
- result = OCDoResource(&handle, method, uri, &dev_addr, NULL, oic_conn_type,
- OC_LOW_QOS, &cbdata, oic_options_ptr, options_size);
- icd_ioty_csdk_unlock();
free(uri);
- if (OC_STACK_OK != result) {
- ERR("OCDoResource() Fail(%d)", result);
- free(context->bus_name);
- free(context);
- return NULL;
- }
+ g_variant_iter_free(options);
return handle;
}
int icd_ioty_observer_stop(OCDoHandle handle, GVariant *options)
{
- int options_size;
OCStackResult ret;
+ int options_size = 0;
GVariantIter options_iter;
OCHeaderOption oic_options[MAX_HEADER_OPTIONS];
OCHeaderOption *oic_options_ptr = NULL;
- g_variant_iter_init(&options_iter, options);
-
- options_size = g_variant_iter_n_children(&options_iter);
- if (0 != options_size) {
- int ret = _ioty_get_header_options(&options_iter, options_size, oic_options,
- sizeof(oic_options) / sizeof(oic_options[0]));
- if (IOTCON_ERROR_NONE != ret) {
- ERR("_ioty_get_header_options() Fail(%d)", ret);
- return ret;
+ if (options) {
+ g_variant_iter_init(&options_iter, options);
+
+ options_size = g_variant_iter_n_children(&options_iter);
+ if (0 != options_size) {
+ int ret = _ioty_get_header_options(&options_iter, options_size, oic_options,
+ sizeof(oic_options) / sizeof(oic_options[0]));
+ if (IOTCON_ERROR_NONE != ret) {
+ ERR("_ioty_get_header_options() Fail(%d)", ret);
+ return ret;
+ }
+ oic_options_ptr = oic_options;
}
- oic_options_ptr = oic_options;
}
icd_ioty_csdk_lock();
}
-static icd_presence_handle_info* _icd_ioty_presence_table_add(const char *host_address)
+static icd_presence_handle_info_s* _icd_ioty_presence_table_add(const char *host_address)
{
- icd_presence_handle_info *handle_info;
+ icd_presence_handle_info_s *handle_info;
- handle_info = calloc(1, sizeof(icd_presence_handle_info));
+ handle_info = calloc(1, sizeof(icd_presence_handle_info_s));
if (NULL == handle_info) {
ERR("calloc() Fail(%d)", errno);
return NULL;
static void _icd_ioty_presence_table_remove(const char *host_address)
{
- icd_presence_handle_info *handle_info;
+ icd_presence_handle_info_s *handle_info;
handle_info = g_hash_table_lookup(icd_ioty_presence_table, host_address);
if (NULL == handle_info)
}
-static icd_presence_handle_info* _icd_ioty_presence_table_get_handle_info(
+static icd_presence_handle_info_s* _icd_ioty_presence_table_get_handle_info(
const char *host_address)
{
return g_hash_table_lookup(icd_ioty_presence_table, host_address);
OCDoHandle icd_ioty_presence_table_get_handle(const char *host_address)
{
- icd_presence_handle_info *handle_info;
+ icd_presence_handle_info_s *handle_info;
handle_info = g_hash_table_lookup(icd_ioty_presence_table, host_address);
if (NULL == handle_info)
}
-OCDoHandle icd_ioty_subscribe_presence(const char *host_address, int conn_type,
- const char *resource_type)
+OCDoHandle icd_ioty_subscribe_presence(int type, const char *host_address, int conn_type,
+ const char *resource_type, void *context)
{
OCDoHandle handle;
const char *address;
char uri[PATH_MAX] = {0};
OCCallbackData cbdata = {0};
OCConnectivityType oic_conn_type;
- icd_presence_handle_info *handle_info;
+ icd_presence_handle_info_s *handle_info;
_icd_ioty_presence_table_create();
snprintf(uri, sizeof(uri), "%s%s", address, OC_RSRVD_PRESENCE_URI);
- cbdata.cb = icd_ioty_ocprocess_presence_cb;
- cbdata.cd = _ioty_free_signal_context;
+ switch (type) {
+ case ICD_ENCAP_MONITORING:
+ cbdata.context = context;
+ cbdata.cb = icd_ioty_ocprocess_encap_presence_cb;
+ break;
+ case ICD_PRESENCE:
+ default:
+ cbdata.cb = icd_ioty_ocprocess_presence_cb;
+ }
oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
return IOTCON_ERROR_NONE;
}
+
+
+int icd_ioty_encap_get_time_interval()
+{
+ return icd_remote_resource_time_interval;
+}
+
+
+static void _encap_set_time_interval(gpointer key, gpointer value, gpointer user_data)
+{
+ icd_encap_info_s *encap_info = value;
+
+ g_source_remove(encap_info->get_timer_id);
+
+ encap_info->get_timer_id = g_timeout_add_seconds(icd_remote_resource_time_interval,
+ icd_ioty_encap_get, encap_info);
+}
+
+
+void icd_ioty_encap_set_time_interval(int time_interval)
+{
+ icd_remote_resource_time_interval = time_interval;
+
+ g_hash_table_foreach(icd_ioty_encap_table, _encap_set_time_interval, NULL);
+}
+
+
+static void _free_encap_info(void *user_data)
+{
+ icd_encap_info_s *encap_info = user_data;
+
+ OCRepPayloadDestroy(encap_info->oic_payload);
+ free(encap_info->uri_path);
+ free(encap_info->dev_addr);
+ free(encap_info);
+}
+
+
+static icd_encap_info_s* _icd_ioty_encap_table_add(const char *uri_path,
+ const char *host_address, int conn_type)
+{
+ int ret;
+ char key_str[PATH_MAX];
+ icd_encap_info_s *encap_info;
+
+ if (NULL == icd_ioty_encap_table) {
+ icd_ioty_encap_table = g_hash_table_new_full(g_str_hash, g_str_equal, free,
+ _free_encap_info);
+ }
+
+ encap_info = calloc(1, sizeof(icd_encap_info_s));
+ if (NULL == encap_info) {
+ ERR("calloc() Fail(%d)", errno);
+ return NULL;
+ }
+
+ encap_info->dev_addr = calloc(1, sizeof(OCDevAddr));
+ if (NULL == encap_info->dev_addr) {
+ ERR("calloc() Fail(%d)", errno);
+ free(encap_info);
+ return NULL;
+ }
+
+ ret = icd_ioty_get_dev_addr(host_address, conn_type, encap_info->dev_addr);
+ if (IOTCON_ERROR_NONE != ret) {
+ ERR("icd_ioty_get_dev_addr() Fail(%d)", ret);
+ free(encap_info->dev_addr);
+ free(encap_info);
+ return NULL;
+ }
+
+ encap_info->uri_path = ic_utils_strdup(uri_path);
+ encap_info->oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
+ snprintf(key_str, sizeof(key_str), "%s%s", uri_path, host_address);
+ encap_info->signal_number = icd_dbus_generate_signal_number();
+
+ g_hash_table_insert(icd_ioty_encap_table, ic_utils_strdup(key_str),
+ encap_info);
+
+ return encap_info;
+}
+
+
+static void _icd_ioty_encap_table_remove(icd_encap_info_s *encap_info,
+ const char *host_address)
+{
+ char key_str[PATH_MAX];
+
+ snprintf(key_str, sizeof(key_str), "%s%s", encap_info->uri_path, host_address);
+
+ g_hash_table_remove(icd_ioty_encap_table, key_str);
+
+ if (0 == g_hash_table_size(icd_ioty_encap_table)) {
+ g_hash_table_destroy(icd_ioty_encap_table);
+ icd_ioty_encap_table = NULL;
+ }
+}
+
+
+static icd_encap_info_s* _icd_ioty_encap_table_get_info(const char *uri_path,
+ const char *host_address)
+{
+ char key_str[PATH_MAX];
+ icd_encap_info_s *encap_info;
+
+ if (NULL == icd_ioty_encap_table)
+ return NULL;
+
+ snprintf(key_str, sizeof(key_str), "%s%s", uri_path, host_address);
+
+ encap_info = g_hash_table_lookup(icd_ioty_encap_table, key_str);
+ if (NULL == encap_info)
+ return NULL;
+
+ return encap_info;
+}
+
+
+gboolean icd_ioty_encap_get(gpointer user_data)
+{
+ FN_CALL;
+ OCStackResult result;
+ OCCallbackData cbdata = {0};
+ icd_encap_info_s *encap_info = user_data;
+
+ cbdata.context = encap_info;
+ cbdata.cb = icd_ioty_ocprocess_encap_get_cb;
+
+ icd_ioty_csdk_lock();
+ result = OCDoResource(NULL, OC_REST_GET, encap_info->uri_path, encap_info->dev_addr,
+ NULL, encap_info->oic_conn_type, OC_LOW_QOS, &cbdata, NULL, 0);
+ icd_ioty_csdk_unlock();
+
+ if (OC_STACK_OK != result)
+ ERR("OCDoResource() Fail(%d)", result);
+
+ return G_SOURCE_CONTINUE;
+}
+
+
+int icd_ioty_start_encap(int type, const char *uri_path, const char *host_address,
+ int conn_type, int64_t *signal_number)
+{
+ OCCallbackData cbdata = {0};
+ icd_encap_info_s *encap_info;
+
+ encap_info = _icd_ioty_encap_table_get_info(uri_path, host_address);
+ if (NULL == encap_info) {
+ encap_info = _icd_ioty_encap_table_add(uri_path, host_address, conn_type);
+ if (NULL == encap_info) {
+ ERR("_icd_ioty_encap_table_add() Fail");
+ return IOTCON_ERROR_OUT_OF_MEMORY;
+ }
+ }
+
+ if (0 == encap_info->monitoring_count + encap_info->caching_count) {
+ /* GET METHOD */
+ icd_ioty_encap_get(encap_info);
+ encap_info->get_timer_id = g_timeout_add_seconds(
+ icd_remote_resource_time_interval, icd_ioty_encap_get, encap_info);
+ }
+
+ switch (type) {
+ case ICD_ENCAP_MONITORING:
+ if (0 != encap_info->monitoring_count) {
+ *signal_number = encap_info->signal_number;
+ encap_info->monitoring_count++;
+ return IOTCON_ERROR_NONE;
+ }
+ /* DEVICE PRESENCE */
+ encap_info->presence_handle = icd_ioty_subscribe_presence(ICD_ENCAP_MONITORING,
+ host_address, conn_type, NULL, encap_info);
+ if (NULL == encap_info->presence_handle) {
+ ERR("icd_ioty_subscribe_presence() Fail");
+ if (0 == encap_info->monitoring_count + encap_info->caching_count) {
+ g_source_remove(encap_info->get_timer_id);
+ encap_info->get_timer_id = 0;
+ _icd_ioty_encap_table_remove(encap_info, host_address);
+ }
+ return IOTCON_ERROR_IOTIVITY;
+ }
+ encap_info->monitoring_count++;
+ break;
+ case ICD_ENCAP_CACHING:
+ if (0 != encap_info->caching_count) {
+ *signal_number = encap_info->signal_number;
+ encap_info->caching_count++;
+ return IOTCON_ERROR_NONE;
+ }
+ /* OBSERVE METHOD */
+ cbdata.context = encap_info;
+ cbdata.cb = icd_ioty_ocprocess_encap_observe_cb;
+
+ encap_info->observe_handle = _icd_ioty_observe_register(uri_path,
+ encap_info->dev_addr,
+ NULL,
+ OC_REST_OBSERVE,
+ encap_info->oic_conn_type,
+ &cbdata);
+ if (NULL == encap_info->observe_handle) {
+ ERR("_icd_ioty_observe_register() Fail");
+ if (0 == encap_info->monitoring_count + encap_info->caching_count) {
+ g_source_remove(encap_info->get_timer_id);
+ encap_info->get_timer_id = 0;
+ _icd_ioty_encap_table_remove(encap_info, host_address);
+ }
+ return IOTCON_ERROR_IOTIVITY;
+ }
+ encap_info->caching_count++;
+ break;
+ default:
+ ERR("Invalid Type(%d)", type);
+ if (0 == encap_info->monitoring_count + encap_info->caching_count) {
+ g_source_remove(encap_info->get_timer_id);
+ encap_info->get_timer_id = 0;
+ _icd_ioty_encap_table_remove(encap_info, host_address);
+ }
+ return IOTCON_ERROR_INVALID_TYPE;
+ }
+ *signal_number = encap_info->signal_number;
+
+ return IOTCON_ERROR_NONE;
+}
+
+
+int icd_ioty_stop_encap(int type, const char *uri_path, const char *host_address)
+{
+ int ret;
+ icd_encap_info_s *encap_info;
+
+ encap_info = _icd_ioty_encap_table_get_info(uri_path, host_address);
+ if (NULL == encap_info) {
+ ERR("_icd_ioty_encap_table_get_info() Fail");
+ return IOTCON_ERROR_INVALID_PARAMETER;
+ }
+
+ switch (type) {
+ case ICD_ENCAP_MONITORING:
+ if (0 == encap_info->monitoring_count) {
+ ERR("Not Monitoring(%s%s)", host_address, uri_path);
+ return IOTCON_ERROR_INVALID_PARAMETER;
+ }
+
+ encap_info->monitoring_count--;
+ if (0 != encap_info->monitoring_count)
+ return IOTCON_ERROR_NONE;
+
+ /* DEVICE PRESENCE */
+ ret = icd_ioty_unsubscribe_presence(encap_info->presence_handle, host_address);
+ if (IOTCON_ERROR_NONE != ret) {
+ ERR("icd_ioty_unsubscribe_presence() Fail(%d)", ret);
+ return ret;
+ }
+ break;
+ case ICD_ENCAP_CACHING:
+ if (0 == encap_info->caching_count) {
+ ERR("Not Caching(%s%s)", host_address, uri_path);
+ return IOTCON_ERROR_INVALID_PARAMETER;
+ }
+
+ encap_info->caching_count--;
+ if (0 != encap_info->caching_count)
+ return IOTCON_ERROR_NONE;
+
+ /* OBSERVE METHOD */
+ ret = icd_ioty_observer_stop(encap_info->observe_handle, NULL);
+ if (IOTCON_ERROR_NONE != ret) {
+ ERR("icd_ioty_observer_stop() Fail(%d)", ret);
+ return ret;
+ }
+ break;
+ default:
+ ERR("Invalid Type(%d)", type);
+ return IOTCON_ERROR_INVALID_TYPE;
+ }
+
+ if (0 != encap_info->monitoring_count + encap_info->caching_count)
+ return IOTCON_ERROR_NONE;
+
+ /* GET METHOD */
+ g_source_remove(encap_info->get_timer_id);
+
+ _icd_ioty_encap_table_remove(encap_info, host_address);
+
+ return IOTCON_ERROR_NONE;
+}
+
typedef struct {
OCDoHandle handle;
int client_count;
-} icd_presence_handle_info;
+} icd_presence_handle_info_s;
+
+typedef struct {
+ char *uri_path;
+ OCDevAddr* dev_addr;
+ OCConnectivityType oic_conn_type;
+ int64_t signal_number;
+ int get_timer_id;
+ int monitoring_count;
+ int caching_count;
+ OCDoHandle presence_handle;
+ OCDoHandle observe_handle;
+ iotcon_remote_resource_state_e resource_state;
+ OCRepPayload *oic_payload;
+} icd_encap_info_s;
enum {
ICD_CRUD_GET,
ICD_DEVICE_INFO,
ICD_PLATFORM_INFO,
ICD_TIZEN_INFO,
+ ICD_ENCAP_MONITORING,
+ ICD_ENCAP_CACHING,
+ ICD_PRESENCE,
};
void icd_ioty_csdk_lock();
OCDoHandle icd_ioty_presence_table_get_handle(const char *host_address);
-OCDoHandle icd_ioty_subscribe_presence(const char *host_address, int conn_type,
- const char *resource_type);
+OCDoHandle icd_ioty_subscribe_presence(int type, const char *host_address, int conn_type,
+ const char *resource_type, void *context);
int icd_ioty_unsubscribe_presence(OCDoHandle handle, const char *host_address);
int icd_ioty_stop_presence();
+int icd_ioty_encap_get_time_interval();
+
+void icd_ioty_encap_set_time_interval(int time_interval);
+
+gboolean icd_ioty_encap_get(gpointer user_data);
+
+int icd_ioty_start_encap(int type, const char *uri_path, const char *host_address,
+ int conn_type, int64_t *signal_number);
+
+int icd_ioty_stop_encap(int type, const char *uri_path, const char *host_address);
+
static inline int icd_ioty_convert_error(int ret)
{
switch (ret) {
return repr;
}
+
+static int _oic_string_list_length(OCStringLL *str_list)
+{
+ int len = 0;
+
+ while (str_list) {
+ len++;
+ str_list = str_list->next;
+ }
+
+ return len;
+}
+
+
+static bool _oic_string_list_contain(OCStringLL *str_list, char *str_value)
+{
+ OCStringLL *c;
+
+ for (c = str_list; c; c = c->next) {
+ if (IC_STR_EQUAL == g_strcmp0(str_value, str_list->value))
+ return true;
+ }
+
+ return false;
+}
+
+
+static int _representation_compare_string_list(OCStringLL *list1, OCStringLL *list2)
+{
+ OCStringLL *c;
+
+ if (NULL == list1 || NULL == list2)
+ return !!(list1 - list2);
+
+ if (_oic_string_list_length(list1) != _oic_string_list_length(list2))
+ return 1;
+
+ for (c = list1; c; c = c->next) {
+ if (false == _oic_string_list_contain(list2, c->value))
+ return 1;
+ }
+
+ return IC_EQUAL;
+}
+
+
+static int _representation_compare_array(OCRepPayloadValueArray arr1,
+ OCRepPayloadValueArray arr2)
+{
+ int i, len1, len2;
+
+ len1 = calcDimTotal(arr1.dimensions);
+ len2 = calcDimTotal(arr2.dimensions);
+
+ if (len1 != len2)
+ return 1;
+
+ switch (arr1.type) {
+ case OCREP_PROP_INT:
+ for (i = 0; i < len1; i++) {
+ if (arr1.iArray[i] != arr2.iArray[i])
+ return 1;
+ }
+ break;
+ case OCREP_PROP_BOOL:
+ for (i = 0; i < len1; i++) {
+ if (arr1.bArray[i] != arr2.bArray[i])
+ return 1;
+ }
+ break;
+ case OCREP_PROP_DOUBLE:
+ for (i = 0; i < len1; i++) {
+ if (arr1.dArray[i] != arr2.dArray[i])
+ return 1;
+ }
+ break;
+ case OCREP_PROP_STRING:
+ for (i = 0; i < len1; i++) {
+ if (IC_STR_EQUAL != g_strcmp0(arr1.strArray[i], arr2.strArray[i]))
+ return 1;
+ }
+ break;
+ case OCREP_PROP_OBJECT:
+ for (i = 0; i < len1; i++) {
+ if (IC_EQUAL != icd_payload_representation_compare(arr1.objArray[i],
+ arr2.objArray[i]))
+ return 1;
+ }
+ break;
+ default:
+ ERR("Invalid Type (%d)", arr1.type);
+ return 1;
+ }
+
+ return IC_EQUAL;
+}
+
+
+static int _representation_compare_value(OCRepPayloadValue *value1,
+ OCRepPayloadValue *value2)
+{
+ int ret = 1;
+
+ if (NULL == value1 || NULL == value2)
+ return !!(value1 - value2);
+
+ /* compare key */
+ if (IC_STR_EQUAL != g_strcmp0(value1->name, value2->name))
+ return 1;
+
+ /* compare value */
+ if (value1->type != value2->type)
+ return 1;
+
+ switch (value1->type) {
+ case OCREP_PROP_NULL:
+ ret = IC_EQUAL;
+ break;
+ case OCREP_PROP_INT:
+ ret = (value1->i == value2->i)? IC_EQUAL : 1;
+ break;
+ case OCREP_PROP_DOUBLE:
+ ret = (value1->d == value2->d)? IC_EQUAL : 1;
+ break;
+ case OCREP_PROP_BOOL:
+ ret = (value1->b == value2->b)? IC_EQUAL : 1;
+ break;
+ case OCREP_PROP_STRING:
+ ret = (IC_STR_EQUAL == g_strcmp0(value1->str, value2->str))? IC_EQUAL : 1;
+ break;
+ case OCREP_PROP_OBJECT:
+ ret = icd_payload_representation_compare(value1->obj, value2->obj);
+ break;
+ case OCREP_PROP_ARRAY:
+ ret = _representation_compare_array(value1->arr, value2->arr);
+ break;
+ default:
+ ERR("Invalid Type (%d)", value1->type);
+ }
+
+ return ret;
+}
+
+
+static int _representation_values_list_length(OCRepPayloadValue *value_list)
+{
+ int len = 0;
+
+ while (value_list) {
+ len++;
+ value_list = value_list->next;
+ }
+
+ return len;
+}
+
+
+static bool _representation_values_list_contain(OCRepPayloadValue *value_list,
+ OCRepPayloadValue *value)
+{
+ OCRepPayloadValue *c;
+
+ for (c = value_list; c; c = c->next) {
+ if (IC_EQUAL == _representation_compare_value(c, value))
+ return true;
+ }
+
+ return false;
+}
+
+
+static int _representation_compare_values_list(OCRepPayloadValue *value1,
+ OCRepPayloadValue *value2)
+{
+ OCRepPayloadValue *c;
+
+ if (NULL == value1 || NULL == value2)
+ return !!(value1 - value2);
+
+ if (_representation_values_list_length(value1)
+ != _representation_values_list_length(value2))
+ return 1;
+
+ for (c = value1; c; c = c->next) {
+ if (false == _representation_values_list_contain(value2, c))
+ return 1;
+ }
+
+ return IC_EQUAL;
+}
+
+
+static int _representation_compare_without_children(OCRepPayload *repr1,
+ OCRepPayload *repr2)
+{
+ int ret;
+
+ if (NULL == repr1 || NULL == repr2)
+ return !!(repr1 - repr2);
+
+ /* compare uri */
+ if (IC_STR_EQUAL != g_strcmp0(repr1->uri, repr2->uri))
+ return 1;
+
+ /* compare resource types */
+ ret = _representation_compare_string_list(repr1->types, repr2->types);
+ if (IC_EQUAL != ret)
+ return ret;
+
+ /* compare resource interfaces */
+ ret = _representation_compare_string_list(repr1->interfaces, repr2->interfaces);
+ if (IC_EQUAL != ret)
+ return ret;
+
+ /* compare values */
+ ret = _representation_compare_values_list(repr1->values, repr2->values);
+ if (IC_EQUAL != ret)
+ return ret;
+
+ return IC_EQUAL;
+}
+
+
+static int _representation_list_length(OCRepPayload *repr_list)
+{
+ int len = 0;
+
+ while (repr_list) {
+ len++;
+ repr_list = repr_list->next;
+ }
+
+ return len;
+}
+
+
+static bool _representation_list_contain(OCRepPayload *repr_list, OCRepPayload *repr)
+{
+ OCRepPayload *c;
+
+ for (c = repr_list; c; c = c->next) {
+ if (IC_EQUAL == _representation_compare_without_children(c, repr))
+ return true;
+ }
+
+ return false;
+}
+
+
+static int _representation_compare_children(OCRepPayload *repr1, OCRepPayload *repr2)
+{
+ OCRepPayload *c;
+
+ if (NULL == repr1 || NULL == repr2)
+ return !!(repr1 - repr2);
+
+ if (_representation_list_length(repr1) != _representation_list_length(repr2))
+ return 1;
+
+ for (c = repr1; c; c = c->next) {
+ if (false == _representation_list_contain(repr2, c))
+ return 1;
+ }
+
+ return IC_EQUAL;
+}
+
+
+int icd_payload_representation_compare(OCRepPayload *repr1, OCRepPayload *repr2)
+{
+ int ret;
+
+ ret = _representation_compare_without_children(repr1, repr2);
+ if (IC_EQUAL != ret)
+ return ret;
+
+ /* compare childrean */
+ ret = _representation_compare_children(repr1->next, repr2->next);
+ if (IC_EQUAL != ret)
+ return ret;
+
+ return IC_EQUAL;
+}
GVariant* icd_payload_to_gvariant(OCPayload *payload);
GVariant** icd_payload_res_to_gvariant(OCPayload *payload, OCDevAddr *dev_addr);
OCRepPayload* icd_payload_representation_from_gvariant(GVariant *var);
+int icd_payload_representation_compare(OCRepPayload *repr1, OCRepPayload *repr2);
#endif /*__IOT_CONNECTIVITY_MANAGER_DAEMON_PAYLOAD_H__*/
}
-int64_t icl_dbus_generate_signal_number()
-{
- static int64_t i = 0;
-
- return i++;
-}
-
-
unsigned int icl_dbus_subscribe_signal(char *signal_name, void *cb_container,
void *cb_free, GDBusSignalCallback sig_handler)
{
icDbus* icl_dbus_get_object();
-int64_t icl_dbus_generate_signal_number();
unsigned int icl_dbus_subscribe_signal(char *signal_name, void *cb_container,
void *cb_free, GDBusSignalCallback sig_handler);
RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
RETV_IF(NULL == cb, IOTCON_ERROR_INVALID_PARAMETER);
- signal_number = icl_dbus_generate_signal_number();
-
ic_dbus_call_get_device_info_sync(icl_dbus_get_object(),
ic_utils_dbus_encode_str(host_address),
connectivity_type,
- signal_number,
+ &signal_number,
&ret,
NULL,
&error);
RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
RETV_IF(NULL == cb, IOTCON_ERROR_INVALID_PARAMETER);
- signal_number = icl_dbus_generate_signal_number();
-
ic_dbus_call_get_platform_info_sync(icl_dbus_get_object(),
ic_utils_dbus_encode_str(host_address),
connectivity_type,
- signal_number,
+ &signal_number,
&ret,
NULL,
&error);
return IOTCON_ERROR_INVALID_PARAMETER;
}
- signal_number = icl_dbus_generate_signal_number();
-
ic_dbus_call_register_resource_sync(icl_dbus_get_object(), uri_path, types, iface,
- properties, signal_number, &(resource->handle), NULL, &error);
+ properties, &signal_number, &(resource->handle), NULL, &error);
if (error) {
ERR("ic_dbus_call_register_resource_sync() Fail(%s)", error->message);
ret = icl_dbus_convert_dbus_error(error->code);
#include "icl-representation.h"
#include "icl-list.h"
#include "icl-value.h"
+#include "icl-payload.h"
#include "icl-remote-resource.h"
-static int _caching_compare_state(iotcon_state_h state1, iotcon_state_h state2);
-static int _caching_compare_value(iotcon_value_h val1, iotcon_value_h val2);
-static int _caching_compare_repr(iotcon_representation_h repr1,
- iotcon_representation_h repr2);
+typedef struct {
+ iotcon_remote_resource_cached_representation_changed_cb cb;
+ void *user_data;
+ iotcon_remote_resource_h resource;
+} icl_caching_s;
-static int _caching_compare_glist(GList *list1, GList *list2, GCompareFunc func)
-{
- GList *c;
-
- if (NULL == list1 || NULL == list2)
- return !!(list1 - list2);
-
- if (g_list_length(list1) != g_list_length(list2))
- return 1;
-
- for (c = list1; c; c = c->next) {
- if (NULL == g_list_find_custom(list2, c->data, func))
- return 1;
- }
-
- return IC_EQUAL;
-}
-
-static gint _caching_find_value_custom(gconstpointer a, gconstpointer b)
-{
- return _caching_compare_value((iotcon_value_h)a, (iotcon_value_h)b);
-}
-
-static int _caching_compare_list(iotcon_list_h list1, iotcon_list_h list2)
-{
- if (NULL == list1 || NULL == list2)
- return !!(list1 - list2);
-
- if (list1->type != list2->type)
- return 1;
-
- return _caching_compare_glist(list1->list, list2->list, _caching_find_value_custom);
-}
-
-static int _caching_compare_value(iotcon_value_h val1, iotcon_value_h val2)
-{
- if (NULL == val1 || NULL == val2)
- return !!(val1 - val2);
-
- if (val1->type != val2->type)
- return 1;
-
- switch (val1->type) {
- case IOTCON_TYPE_INT:
- return (((icl_basic_s *)val1)->val.i == ((icl_basic_s *)val2)->val.i)? 0: 1;
- case IOTCON_TYPE_BOOL:
- return (((icl_basic_s *)val1)->val.b == ((icl_basic_s *)val2)->val.b)? 0: 1;
- case IOTCON_TYPE_DOUBLE:
- return (((icl_basic_s *)val1)->val.d == ((icl_basic_s *)val2)->val.d)? 0: 1;
- case IOTCON_TYPE_STR:
- return g_strcmp0(((icl_basic_s *)val1)->val.s, ((icl_basic_s *)val2)->val.s);
- case IOTCON_TYPE_NULL:
- return IC_EQUAL;
- case IOTCON_TYPE_LIST:
- return _caching_compare_list(((icl_val_list_s *)val1)->list,
- ((icl_val_list_s *)val2)->list);
- case IOTCON_TYPE_STATE:
- return _caching_compare_state(((icl_val_state_s *)val1)->state,
- ((icl_val_state_s *)val2)->state);
- case IOTCON_TYPE_NONE:
- default:
- ERR("Invalid type (%d)", val1->type);
- }
- return IC_EQUAL;
-}
-
-static int _caching_compare_state(iotcon_state_h state1, iotcon_state_h state2)
-{
- int ret;
- GHashTableIter iter;
- gpointer key, value;
-
- if (NULL == state1 || NULL == state2)
- return !!(state1 - state2);
-
- /* compare state */
- if (g_hash_table_size(state1->hash_table) != g_hash_table_size(state2->hash_table))
- return 1;
-
- g_hash_table_iter_init(&iter, state1->hash_table);
- while (g_hash_table_iter_next(&iter, &key, &value)) {
- iotcon_value_h val1 = value;
- iotcon_value_h val2 = g_hash_table_lookup(state2->hash_table, key);
- ret = _caching_compare_value(val1, val2);
- if (IC_EQUAL != ret)
- return 1;
- }
- return IC_EQUAL;
-}
-
-static gint _caching_find_repr_custom(gconstpointer a, gconstpointer b)
-{
- iotcon_representation_h repr1 = (iotcon_representation_h)a;
- iotcon_representation_h repr2 = (iotcon_representation_h)b;
- return _caching_compare_repr(repr1, repr2);
-}
-
-static gint _caching_find_resource_types_custom(gconstpointer a, gconstpointer b)
-{
- return g_strcmp0(a, b);
-}
-
-static int _caching_compare_resource_types(iotcon_resource_types_h types1,
- iotcon_resource_types_h types2)
-{
- int ret;
-
- if (NULL == types1 || NULL == types2)
- return !!(types1 - types2);
-
- ret = _caching_compare_glist(types1->type_list, types2->type_list,
- _caching_find_resource_types_custom);
- if (IC_EQUAL != ret)
- return 1;
-
- return IC_EQUAL;
-}
-
-/* return 0 on same */
-static int _caching_compare_repr(iotcon_representation_h repr1,
- iotcon_representation_h repr2)
-{
- int ret;
-
- if (NULL == repr1 || NULL == repr2)
- return !!(repr1 - repr2);
-
- /* compare interface */
- if (repr1->interfaces != repr2->interfaces)
- return 1;
-
- /* compare visibility */
- if (repr1->visibility != repr2->visibility)
- return 1;
-
- /* compare uri_path */
- if (IC_STR_EQUAL != g_strcmp0(repr1->uri_path, repr2->uri_path))
- return 1;
-
- ret = _caching_compare_resource_types(repr1->res_types, repr2->res_types);
- if (IC_EQUAL != ret)
- return 1;
-
- /* compare state */
- ret = _caching_compare_state(repr1->state, repr2->state);
- if (IC_EQUAL != ret)
- return 1;
-
- /* compare children */
- ret = _caching_compare_glist(repr1->children, repr2->children,
- _caching_find_repr_custom);
- if (IC_EQUAL != ret)
- return 1;
-
- return IC_EQUAL;
-}
-
-static void _caching_get_cb(iotcon_remote_resource_h resource,
- iotcon_error_e err,
- iotcon_request_type_e request_type,
- iotcon_response_h resp,
- void *user_data)
-{
- int ret;
- iotcon_response_result_e result;
- iotcon_representation_h repr = NULL;
- iotcon_representation_h cloned_repr;
-
- RET_IF(NULL == resource);
- RET_IF(NULL == resource->caching_handle);
- RETM_IF(IOTCON_ERROR_NONE != err, "_caching_get() Fail(%d)", err);
-
- ret = iotcon_response_get_result(resp, &result);
- if (IOTCON_ERROR_NONE != ret || IOTCON_RESPONSE_OK != result) {
- ERR("Invalid result (%d)", result);
- return;
- }
- ret = iotcon_response_get_representation(resp, &repr);
- if (IOTCON_ERROR_NONE != ret) {
- ERR("iotcon_response_get_representation() Fail(%d)", ret);
- return;
- }
-
- ret = _caching_compare_repr(resource->caching_handle->repr, repr);
- if (IC_EQUAL == ret) { /* same */
- DBG("Not changed");
- return;
- }
-
- ret = iotcon_representation_clone(repr, &cloned_repr);
- if (IOTCON_ERROR_NONE != ret) {
- ERR("iotcon_representation_clone() Fail(%d)", ret);
- return;
- }
-
- if (resource->caching_handle->repr)
- iotcon_representation_destroy(resource->caching_handle->repr);
-
- resource->caching_handle->repr = cloned_repr;
-
- if (resource->caching_handle->cb)
- resource->caching_handle->cb(resource, repr, resource->caching_handle->user_data);
-}
-
-
-static void _caching_observe_cb(GDBusConnection *connection,
+static void _icl_caching_cb(GDBusConnection *connection,
const gchar *sender_name,
const gchar *object_path,
const gchar *interface_name,
GVariant *parameters,
gpointer user_data)
{
+ FN_CALL;
int ret;
- iotcon_remote_resource_h resource = user_data;
-
- RET_IF(NULL == resource);
- RET_IF(NULL == resource->caching_handle);
-
- ret = iotcon_remote_resource_get(resource, NULL, _caching_get_cb, NULL);
- if (IOTCON_ERROR_NONE != ret)
- ERR("iotcon_remote_resource_get() for caching Fail(%d)", ret);
-}
-
-
-static void _caching_observe_cleanup(iotcon_remote_resource_h resource)
-{
- resource->caching_handle->observe_handle = 0;
- resource->caching_handle->observe_sub_id = 0;
-}
-
-
-static int _caching_observer_start(iotcon_remote_resource_h resource)
-{
- int ret;
- int64_t handle = 0;
- unsigned int sub_id = 0;
+ iotcon_representation_h repr, cached_repr;
+ icl_caching_s *cb_container = user_data;
+ iotcon_remote_resource_cached_representation_changed_cb cb = cb_container->cb;
- RETV_IF(NULL == resource, IOTCON_ERROR_INVALID_PARAMETER);
+ repr = icl_representation_from_gvariant(parameters);
- ret = icl_remote_resource_observer_start(resource, IOTCON_OBSERVE_IGNORE_OUT_OF_ORDER, NULL,
- _caching_observe_cb, resource, _caching_observe_cleanup, &sub_id, &handle);
+ ret = iotcon_representation_clone(repr, &cached_repr);
if (IOTCON_ERROR_NONE != ret) {
- ERR("icl_remote_resource_observer_start() Fail(%d)", ret);
- return ret;
+ ERR("iotcon_representation_clone() Fail(%d)", ret);
+ return;
}
- resource->caching_handle->observe_sub_id = sub_id;
- resource->caching_handle->observe_handle = handle;
+ if (cb_container->resource->cached_repr)
+ iotcon_representation_destroy(cb_container->resource->cached_repr);
+ cb_container->resource->cached_repr = cached_repr;
- return IOTCON_ERROR_NONE;
-}
-
-
-static int _caching_observer_stop(iotcon_remote_resource_h resource)
-{
- int ret;
-
- RETV_IF(NULL == resource, IOTCON_ERROR_INVALID_PARAMETER);
- if (0 == resource->caching_handle->observe_handle) {
- ERR("It doesn't have a caching observe handle");
- return IOTCON_ERROR_INVALID_PARAMETER;
- }
-
- ret = icl_remote_resource_stop_observing(resource,
- NULL,
- resource->caching_handle->observe_handle,
- resource->caching_handle->observe_sub_id);
- if (IOTCON_ERROR_NONE != ret) {
- ERR("icl_remote_resource_stop_observing() Fail(%d)", ret);
- return ret;
+ if (cb) {
+ cb(cb_container->resource, cb_container->resource->cached_repr,
+ cb_container->user_data);
}
-
- return IOTCON_ERROR_NONE;
}
-static gboolean _caching_get_timer(gpointer user_data)
+static void _icl_caching_conn_cleanup(icl_caching_s *cb_container)
{
- int ret;
- iotcon_remote_resource_h resource = user_data;
-
- RETV_IF(NULL == resource, G_SOURCE_REMOVE);
-
- ret = iotcon_remote_resource_get(resource, NULL, _caching_get_cb, NULL);
- if (IOTCON_ERROR_NONE != ret)
- ERR("iotcon_remote_resource_get() for caching Fail(%d)", ret);
-
- return G_SOURCE_CONTINUE;
+ if (cb_container->resource->cached_repr) {
+ iotcon_representation_destroy(cb_container->resource->cached_repr);
+ cb_container->resource->cached_repr = NULL;
+ }
+ cb_container->resource->caching_sub_id = 0;
+ free(cb_container);
}
API int iotcon_remote_resource_start_caching(iotcon_remote_resource_h resource,
iotcon_remote_resource_cached_representation_changed_cb cb, void *user_data)
{
- int ret, time_interval;
- unsigned int get_timer_id;
+ int ret, sub_id;
+ GError *error = NULL;
+ int64_t signal_number;
+ icl_caching_s *cb_container;
+ char signal_name[IC_DBUS_SIGNAL_LENGTH] = {0};
+ RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
RETV_IF(NULL == resource, IOTCON_ERROR_INVALID_PARAMETER);
- if (resource->caching_handle) {
+ if (0 != resource->caching_sub_id) {
ERR("Already Start Caching");
return IOTCON_ERROR_ALREADY;
}
INFO("Start Caching");
- resource->caching_handle = calloc(1, sizeof(struct icl_remote_resource_caching));
- if (NULL == resource->caching_handle) {
- ERR("calloc() Fail(%d)", errno);
- return IOTCON_ERROR_OUT_OF_MEMORY;
+ ic_dbus_call_start_caching_sync(icl_dbus_get_object(),
+ resource->uri_path,
+ resource->host_address,
+ resource->connectivity_type,
+ &signal_number,
+ &ret,
+ NULL,
+ &error);
+ if (error) {
+ ERR("ic_dbus_call_start_caching_sync() Fail(%s)", error->message);
+ ret = icl_dbus_convert_dbus_error(error->code);
+ g_error_free(error);
+ return IOTCON_ERROR_DBUS;
}
-
- _caching_get_timer(resource);
-
- /* OBSERVE METHOD */
- ret = _caching_observer_start(resource);
if (IOTCON_ERROR_NONE != ret) {
- ERR("_caching_observer_start() Fail(%d)", ret);
- free(resource->caching_handle);
- resource->caching_handle = NULL;
- return ret;
+ ERR("iotcon-daemon Fail(%d)", ret);
+ return icl_dbus_convert_daemon_error(ret);
}
- /* GET METHOD */
- resource->caching_handle->cb = cb;
- resource->caching_handle->user_data = user_data;
+ snprintf(signal_name, sizeof(signal_name), "%s_%llx", IC_DBUS_SIGNAL_CACHING,
+ signal_number);
- ret = iotcon_remote_resource_get_time_interval(&time_interval);
- if (IOTCON_ERROR_NONE != ret) {
- ERR("iotcon_remote_resource_get_time_interval() Fail(%d)", ret);
- return ret;
+ cb_container = calloc(1, sizeof(icl_caching_s));
+ if (NULL == cb_container) {
+ ERR("calloc() Fail(%d)", errno);
+ return IOTCON_ERROR_OUT_OF_MEMORY;
}
- get_timer_id = g_timeout_add_seconds(time_interval, _caching_get_timer, resource);
- resource->caching_handle->get_timer_id = get_timer_id;
+ cb_container->cb = cb;
+ cb_container->user_data = user_data;
+
+ sub_id = icl_dbus_subscribe_signal(signal_name, cb_container,
+ _icl_caching_conn_cleanup, _icl_caching_cb);
+ if (0 == sub_id) {
+ ERR("icl_dbus_subscribe_signal() Fail");
+ free(cb_container);
+ return IOTCON_ERROR_DBUS;
+ }
+ resource->caching_sub_id = sub_id;
+ cb_container->resource = resource;
return IOTCON_ERROR_NONE;
}
API int iotcon_remote_resource_stop_caching(iotcon_remote_resource_h resource)
{
int ret;
+ GError *error = NULL;
+ RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
RETV_IF(NULL == resource, IOTCON_ERROR_INVALID_PARAMETER);
- if (NULL == resource->caching_handle) {
+ if (0 == resource->caching_sub_id) {
ERR("Not Cached");
return IOTCON_ERROR_INVALID_PARAMETER;
}
INFO("Stop Caching");
- /* GET METHOD */
- g_source_remove(resource->caching_handle->get_timer_id);
-
- if (resource->caching_handle->repr) {
- iotcon_representation_destroy(resource->caching_handle->repr);
- resource->caching_handle->repr = NULL;
- }
-
- /* OBSERVE METHOD */
- ret = _caching_observer_stop(resource);
- if (IOTCON_ERROR_NONE == ret) {
- ERR("_caching_observer_stop() Fail(%d)", ret);
+ ic_dbus_call_stop_caching_sync(icl_dbus_get_object(),
+ resource->uri_path,
+ resource->host_address,
+ &ret,
+ NULL,
+ &error);
+ if (error) {
+ ERR("ic_dbus_call_stop_caching_sync() Fail(%s)", error->message);
+ ret = icl_dbus_convert_dbus_error(error->code);
+ g_error_free(error);
return ret;
}
+ if (IOTCON_ERROR_NONE != ret) {
+ ERR("iotcon-daemon Fail(%d)", ret);
+ return icl_dbus_convert_dbus_error(ret);
+ }
- free(resource->caching_handle);
- resource->caching_handle = NULL;
+ icl_dbus_unsubscribe_signal(resource->caching_sub_id);
return IOTCON_ERROR_NONE;
}
RETV_IF(NULL == resource, IOTCON_ERROR_INVALID_PARAMETER);
RETV_IF(NULL == representation, IOTCON_ERROR_INVALID_PARAMETER);
- if (NULL == resource->caching_handle->repr) {
+ if (NULL == resource->cached_repr) {
ERR("No Caching Representation");
return IOTCON_ERROR_NO_DATA;
}
- *representation = resource->caching_handle->repr;
+ *representation = resource->cached_repr;
return IOTCON_ERROR_NONE;
}
}
-int icl_remote_resource_observer_start(iotcon_remote_resource_h resource,
+API int iotcon_remote_resource_observe_register(iotcon_remote_resource_h resource,
iotcon_observe_policy_e observe_policy,
iotcon_query_h query,
- GDBusSignalCallback sig_handler,
- void *cb_container,
- void *cb_free,
- unsigned int *sub_id,
- int64_t *observe_handle)
+ iotcon_remote_resource_observe_cb cb,
+ void *user_data)
{
int ret;
+ unsigned int sub_id;
GError *error = NULL;
int64_t signal_number;
+ int64_t observe_handle;
+ icl_on_observe_s *cb_container;
GVariant *arg_query, *arg_remote_resource;
char signal_name[IC_DBUS_SIGNAL_LENGTH] = {0};
RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
-
- signal_number = icl_dbus_generate_signal_number();
+ RETV_IF(NULL == resource, IOTCON_ERROR_INVALID_PARAMETER);
+ RETV_IF(NULL == cb, IOTCON_ERROR_INVALID_PARAMETER);
+ RETV_IF(resource->observe_handle || resource->observe_sub_id, IOTCON_ERROR_ALREADY);
arg_remote_resource = icl_dbus_remote_resource_to_gvariant(resource);
arg_query = icl_dbus_query_to_gvariant(query);
+ cb_container = calloc(1, sizeof(icl_on_observe_s));
+ if (NULL == cb_container) {
+ ERR("calloc() Fail(%d)", errno);
+ g_variant_unref(arg_query);
+ g_variant_unref(arg_remote_resource);
+ return IOTCON_ERROR_OUT_OF_MEMORY;
+ }
+
+ cb_container->resource = resource;
+ cb_container->cb = cb;
+ cb_container->user_data = user_data;
+
ic_dbus_call_observer_start_sync(icl_dbus_get_object(), arg_remote_resource,
- observe_policy, arg_query, signal_number, observe_handle, NULL, &error);
+ observe_policy, arg_query, &signal_number, &observe_handle, NULL, &error);
if (error) {
ERR("ic_dbus_call_observer_start_sync() Fail(%s)", error->message);
ret = icl_dbus_convert_dbus_error(error->code);
g_error_free(error);
g_variant_unref(arg_query);
g_variant_unref(arg_remote_resource);
+ free(cb_container);
return ret;
}
-
- if (0 == *observe_handle) {
+ if (0 == observe_handle) {
ERR("iotcon-daemon Fail");
+ free(cb_container);
return IOTCON_ERROR_IOTIVITY;
}
snprintf(signal_name, sizeof(signal_name), "%s_%llx", IC_DBUS_SIGNAL_OBSERVE,
signal_number);
- *sub_id = icl_dbus_subscribe_signal(signal_name, cb_container, cb_free, sig_handler);
- if (0 == *sub_id) {
+ sub_id = icl_dbus_subscribe_signal(signal_name, cb_container,
+ _icl_observe_conn_cleanup, _icl_on_observe_cb);
+ if (0 == sub_id) {
ERR("icl_dbus_subscribe_signal() Fail");
- return IOTCON_ERROR_DBUS;
- }
-
- return IOTCON_ERROR_NONE;
-}
-
-
-API int iotcon_remote_resource_observe_register(iotcon_remote_resource_h resource,
- iotcon_observe_policy_e observe_policy,
- iotcon_query_h query,
- iotcon_remote_resource_observe_cb cb,
- void *user_data)
-{
- int ret;
- unsigned int sub_id;
- int64_t observe_handle;
- icl_on_observe_s *cb_container;
-
- RETV_IF(NULL == resource, IOTCON_ERROR_INVALID_PARAMETER);
- RETV_IF(NULL == cb, IOTCON_ERROR_INVALID_PARAMETER);
- RETV_IF(resource->observe_handle || resource->observe_sub_id, IOTCON_ERROR_ALREADY);
-
- cb_container = calloc(1, sizeof(icl_on_observe_s));
- if (NULL == cb_container) {
- ERR("calloc() Fail(%d)", errno);
- return IOTCON_ERROR_OUT_OF_MEMORY;
- }
-
- cb_container->resource = resource;
- cb_container->cb = cb;
- cb_container->user_data = user_data;
-
- ret = icl_remote_resource_observer_start(resource,
- observe_policy,
- query,
- _icl_on_observe_cb,
- cb_container,
- _icl_observe_conn_cleanup,
- &sub_id,
- &observe_handle);
- if (IOTCON_ERROR_NONE != ret) {
- ERR("icl_remote_resource_observer_start() Fail(%d)", ret);
free(cb_container);
- return ret;
+ return IOTCON_ERROR_DBUS;
}
resource->observe_sub_id = sub_id;
}
-int icl_remote_resource_stop_observing(iotcon_remote_resource_h resource,
- iotcon_options_h options, int64_t handle, unsigned int sub_id)
+API int iotcon_remote_resource_observe_deregister(iotcon_remote_resource_h resource)
{
int ret;
GError *error = NULL;
GVariant *arg_options;
RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
+ RETV_IF(NULL == resource, IOTCON_ERROR_INVALID_PARAMETER);
+ if (0 == resource->observe_handle) {
+ ERR("It doesn't have a observe_handle");
+ return IOTCON_ERROR_INVALID_PARAMETER;
+ }
- arg_options = icl_dbus_options_to_gvariant(options);
+ arg_options = icl_dbus_options_to_gvariant(resource->header_options);
- ic_dbus_call_observer_stop_sync(icl_dbus_get_object(), handle, arg_options,
- &ret, NULL, &error);
+ ic_dbus_call_observer_stop_sync(icl_dbus_get_object(), resource->observe_handle,
+ arg_options, &ret, NULL, &error);
if (error) {
ERR("ic_dbus_call_observer_stop_sync() Fail(%s)", error->message);
ret = icl_dbus_convert_dbus_error(error->code);
return IOTCON_ERROR_NONE;
}
-
-API int iotcon_remote_resource_observe_deregister(iotcon_remote_resource_h resource)
-{
- int ret;
-
- RETV_IF(NULL == resource, IOTCON_ERROR_INVALID_PARAMETER);
- if (0 == resource->observe_handle) {
- ERR("It doesn't have a observe_handle");
- return IOTCON_ERROR_INVALID_PARAMETER;
- }
-
- ret = icl_remote_resource_stop_observing(resource, resource->header_options,
- resource->observe_handle, resource->observe_sub_id);
- if (IOTCON_ERROR_NONE != ret) {
- ERR("icl_remote_resource_stop_observing() Fail(%d)", ret);
- return ret;
- }
-
- return IOTCON_ERROR_NONE;
-}
-
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <glib.h>
#include "iotcon.h"
#include "iotcon-internal.h"
#include "icl.h"
+#include "icl-dbus.h"
#include "icl-remote-resource.h"
-static void _monitoring_get_cb(iotcon_remote_resource_h resource,
- iotcon_error_e err,
- iotcon_request_type_e request_type,
- iotcon_response_h response,
- void *user_data)
+typedef struct {
+ iotcon_remote_resource_state_changed_cb cb;
+ void *user_data;
+ iotcon_remote_resource_h resource;
+} icl_monitoring_s;
+
+static void _icl_monitoring_cb(GDBusConnection *connection,
+ const gchar *sender_name,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
{
- int ret;
- iotcon_response_result_e response_result;
+ FN_CALL;
+ icl_monitoring_s *cb_container = user_data;
iotcon_remote_resource_state_e resource_state;
+ iotcon_remote_resource_state_changed_cb cb = cb_container->cb;
- RET_IF(NULL == resource);
- RET_IF(NULL == resource->monitoring_handle);
- RETM_IF(IOTCON_ERROR_NONE != err, "_monitoring_get() Fail(%d)", err);
-
- ret = iotcon_response_get_result(response, &response_result);
- if (IOTCON_ERROR_NONE != ret) {
- ERR("iotcon_response_get_result() Fail(%d)", ret);
- return;
- }
-
- if (IOTCON_RESPONSE_OK <= response_result)
- resource_state = IOTCON_REMOTE_RESOURCE_ALIVE;
- else
- resource_state = IOTCON_REMOTE_RESOURCE_LOST_SIGNAL;
-
- if (resource_state == resource->monitoring_handle->resource_state)
- return;
+ g_variant_get(parameters, "(i)", &resource_state);
- resource->monitoring_handle->resource_state = resource_state;
+ if (cb)
+ cb(cb_container->resource, resource_state, cb_container->user_data);
- if (resource->monitoring_handle->cb)
- resource->monitoring_handle->cb(resource, resource_state,
- resource->monitoring_handle->user_data);
}
-static gboolean _monitoring_get_timer(gpointer user_data)
+static void _icl_monitoring_conn_cleanup(icl_monitoring_s *cb_container)
{
- int ret;
- iotcon_remote_resource_h resource = user_data;
-
- RETV_IF(NULL == resource, G_SOURCE_REMOVE);
-
- ret = iotcon_remote_resource_get(resource, NULL, _monitoring_get_cb, NULL);
- if (IOTCON_ERROR_NONE != ret)
- ERR("iotcon_remote_resource_get() for caching Fail(%d)", ret);
-
- return G_SOURCE_CONTINUE;
-}
-
-
-static void _monitoring_presence_cb(iotcon_presence_h presence, iotcon_error_e err,
- iotcon_presence_response_h response, void *user_data)
-{
- int ret, time_interval;
- unsigned int get_timer_id;
- iotcon_presence_result_e result;
- iotcon_presence_trigger_e trigger;
- iotcon_remote_resource_h resource = user_data;
-
- RET_IF(NULL == resource);
- RET_IF(NULL == resource->monitoring_handle);
- RETM_IF(IOTCON_ERROR_NONE != err, "_monitoring_presence() Fail(%d)", err);
-
- ret = iotcon_presence_response_get_result(response, &result);
- if (IOTCON_ERROR_NONE != ret) {
- ERR("iotcon_presence_response_get_result() Fail(%d)", ret);
- return;
- }
-
- if (IOTCON_PRESENCE_OK == result) {
- ret = iotcon_presence_response_get_trigger(response, &trigger);
- if (IOTCON_ERROR_NONE != ret) {
- ERR("iotcon_presence_response_get_trigger() Fail(%d)", ret);
- return;
- }
-
- if (IOTCON_PRESENCE_RESOURCE_DESTROYED != trigger)
- return;
- }
-
- ret = iotcon_remote_resource_get_time_interval(&time_interval);
- if (IOTCON_ERROR_NONE != ret) {
- ERR("iotcon_remote_resource_get_time_interval() Fail(%d)", ret);
- return;
- }
-
- g_source_remove(resource->monitoring_handle->get_timer_id);
-
- _monitoring_get_timer(resource);
- get_timer_id = g_timeout_add_seconds(time_interval, _monitoring_get_timer, resource);
- resource->monitoring_handle->get_timer_id = get_timer_id;
+ cb_container->resource->monitoring_sub_id = 0;
+ free(cb_container);
}
API int iotcon_remote_resource_start_monitoring(iotcon_remote_resource_h resource,
iotcon_remote_resource_state_changed_cb cb, void *user_data)
{
- char *host_address;
- int ret, time_interval;
- unsigned int get_timer_id;
- iotcon_connectivity_type_e connectivity_type;
+ int ret, sub_id;
+ GError *error = NULL;
+ int64_t signal_number;
+ icl_monitoring_s *cb_container;
+ char signal_name[IC_DBUS_SIGNAL_LENGTH] = {0};
+ RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
RETV_IF(NULL == resource, IOTCON_ERROR_INVALID_PARAMETER);
RETV_IF(NULL == cb, IOTCON_ERROR_INVALID_PARAMETER);
- if (resource->monitoring_handle) {
+ if (0 != resource->monitoring_sub_id) {
ERR("Already Start Monitoring");
return IOTCON_ERROR_ALREADY;
}
INFO("Start Monitoring");
- resource->monitoring_handle = calloc(1, sizeof(struct icl_remote_resource_monitoring));
- if (NULL == resource->monitoring_handle) {
- ERR("calloc() Fail(%d)", errno);
- return IOTCON_ERROR_OUT_OF_MEMORY;
+ ic_dbus_call_start_monitoring_sync(icl_dbus_get_object(),
+ resource->uri_path,
+ resource->host_address,
+ resource->connectivity_type,
+ &signal_number,
+ &ret,
+ NULL,
+ &error);
+ if (error) {
+ ERR("ic_dbus_call_start_monitoring_sync() Fail(%s)", error->message);
+ ret = icl_dbus_convert_dbus_error(error->code);
+ g_error_free(error);
+ return IOTCON_ERROR_DBUS;
}
-
- _monitoring_get_timer(resource);
-
- /* GET METHOD (Resource Presence) */
- resource->monitoring_handle->cb = cb;
- resource->monitoring_handle->user_data = user_data;
-
- ret = iotcon_remote_resource_get_time_interval(&time_interval);
if (IOTCON_ERROR_NONE != ret) {
- ERR("iotcon_remote_resource_get_time_interval() Fail(%d)", ret);
- free(resource->monitoring_handle);
- resource->monitoring_handle = NULL;
- return ret;
+ ERR("iotcon-daemon Fail(%d)", ret);
+ return icl_dbus_convert_daemon_error(ret);
}
- get_timer_id = g_timeout_add_seconds(time_interval, _monitoring_get_timer, resource);
- resource->monitoring_handle->get_timer_id = get_timer_id;
+ snprintf(signal_name, sizeof(signal_name), "%s_%llx", IC_DBUS_SIGNAL_MONITORING,
+ signal_number);
- /* Device Presence */
- ret = iotcon_remote_resource_get_host_address(resource, &host_address);
- if (IOTCON_ERROR_NONE != ret) {
- ERR("iotcon_remote_resource_get_host_address() Fail(%d)", ret);
- g_source_remove(resource->monitoring_handle->get_timer_id);
- free(resource->monitoring_handle);
- resource->monitoring_handle = NULL;
- return ret;
+ cb_container = calloc(1, sizeof(icl_monitoring_s));
+ if (NULL == cb_container) {
+ ERR("calloc() Fail(%d)", errno);
+ return IOTCON_ERROR_OUT_OF_MEMORY;
}
- ret = iotcon_remote_resource_get_connectivity_type(resource, &connectivity_type);
- if (IOTCON_ERROR_NONE != ret) {
- ERR("iotcon_remote_resource_get_connectivity_type() Fail(%d)", ret);
- g_source_remove(resource->monitoring_handle->get_timer_id);
- free(resource->monitoring_handle);
- resource->monitoring_handle = NULL;
- return ret;
- }
+ cb_container->cb = cb;
+ cb_container->user_data = user_data;
- ret = iotcon_add_presence_cb(host_address, connectivity_type, NULL,
- _monitoring_presence_cb, resource, &resource->monitoring_handle->presence);
- if (IOTCON_ERROR_NONE != ret) {
- ERR("iotcon_add_presence_cb() Fail(%d)", ret);
- g_source_remove(resource->monitoring_handle->get_timer_id);
- free(resource->monitoring_handle);
- resource->monitoring_handle = NULL;
- return ret;
+ sub_id = icl_dbus_subscribe_signal(signal_name, cb_container,
+ _icl_monitoring_conn_cleanup, _icl_monitoring_cb);
+ if (0 == sub_id) {
+ ERR("icl_dbus_subscribe_signal() Fail");
+ free(cb_container);
+ return IOTCON_ERROR_DBUS;
}
+ resource->monitoring_sub_id = sub_id;
+ cb_container->resource = resource;
return IOTCON_ERROR_NONE;
}
API int iotcon_remote_resource_stop_monitoring(iotcon_remote_resource_h resource)
{
int ret;
+ GError *error = NULL;
+ RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
RETV_IF(NULL == resource, IOTCON_ERROR_INVALID_PARAMETER);
- if (NULL == resource->monitoring_handle) {
+ if (0 == resource->monitoring_sub_id) {
ERR("Not Monitoring");
return IOTCON_ERROR_INVALID_PARAMETER;
}
INFO("Stop Monitoring");
- /* Device Presence */
- ret = iotcon_remove_presence_cb(resource->monitoring_handle->presence);
- if (IOTCON_ERROR_NONE != ret) {
- ERR("iotcon_remove_presence_cb() Fail(%d)", ret);
+ ic_dbus_call_stop_monitoring_sync(icl_dbus_get_object(),
+ resource->uri_path,
+ resource->host_address,
+ &ret,
+ NULL,
+ &error);
+ if (error) {
+ ERR("ic_dbus_call_stop_monitoring_sync() Fail(%s)", error->message);
+ ret = icl_dbus_convert_dbus_error(error->code);
+ g_error_free(error);
return ret;
}
+ if (IOTCON_ERROR_NONE != ret) {
+ ERR("iotcon-daemon Fail(%d)", ret);
+ return icl_dbus_convert_daemon_error(ret);
+ }
- /* GET METHOD */
- g_source_remove(resource->monitoring_handle->get_timer_id);
-
- free(resource->monitoring_handle);
- resource->monitoring_handle = NULL;
+ icl_dbus_unsubscribe_signal(resource->monitoring_sub_id);
return IOTCON_ERROR_NONE;
}
#include "icl-resource-types.h"
#include "icl-payload.h"
-#define ICL_REMOTE_RESOURCE_DEFAULT_TIME_INTERVAL 10 /* 10 sec */
#define ICL_REMOTE_RESOURCE_MAX_TIME_INTERVAL 3600 /* 60 min */
typedef struct {
int timeout_id;
} icl_found_resource_s;
-static int icl_remote_resource_time_interval;
-
-
static iotcon_remote_resource_h _icl_remote_resource_from_gvariant(GVariant *payload,
iotcon_connectivity_type_e connectivity_type);
return IOTCON_ERROR_INVALID_PARAMETER;
}
- signal_number = icl_dbus_generate_signal_number();
-
ic_dbus_call_find_resource_sync(icl_dbus_get_object(),
ic_utils_dbus_encode_str(host_address),
connectivity_type,
ic_utils_dbus_encode_str(resource_type),
- signal_number,
+ &signal_number,
&ret,
NULL,
&error);
icl_remote_resource_crud_stop(resource);
- if (resource->caching_handle)
+ if (0 != resource->caching_sub_id)
iotcon_remote_resource_stop_caching(resource);
- if (resource->monitoring_handle)
+ if (0 != resource->monitoring_sub_id)
iotcon_remote_resource_stop_monitoring(resource);
free(resource->uri_path);
API int iotcon_remote_resource_get_time_interval(int *time_interval)
{
+ GError *error = NULL;
+ int ret, arg_time_interval;
+
RETV_IF(NULL == time_interval, IOTCON_ERROR_INVALID_PARAMETER);
- if (0 == icl_remote_resource_time_interval)
- *time_interval = ICL_REMOTE_RESOURCE_DEFAULT_TIME_INTERVAL;
- else
- *time_interval = icl_remote_resource_time_interval;
+ ic_dbus_call_encap_get_time_interval_sync(icl_dbus_get_object(), &arg_time_interval,
+ NULL, &error);
+ if (error) {
+ ERR("ic_dbus_call_encap_get_time_interval_sync() Fail(%s)", error->message);
+ ret = icl_dbus_convert_dbus_error(error->code);
+ g_error_free(error);
+ return ret;
+ }
+
+ *time_interval = arg_time_interval;
return IOTCON_ERROR_NONE;
}
API int iotcon_remote_resource_set_time_interval(int time_interval)
{
+ int ret;
+ GError *error = NULL;
+
RETV_IF(ICL_REMOTE_RESOURCE_MAX_TIME_INTERVAL < time_interval || time_interval <= 0,
IOTCON_ERROR_INVALID_PARAMETER);
- icl_remote_resource_time_interval = time_interval;
+ ic_dbus_call_encap_set_time_interval_sync(icl_dbus_get_object(), time_interval,
+ NULL, &error);
+ if (error) {
+ ERR("ic_dbus_call_encap_set_time_interval_sync() Fail(%s)", error->message);
+ ret = icl_dbus_convert_dbus_error(error->code);
+ g_error_free(error);
+ return ret;
+ }
return IOTCON_ERROR_NONE;
}
ICL_DEVICE_STATE_LOST_SIGNAL,
} icl_remote_resource_device_state_e;
-struct icl_remote_resource_caching {
- unsigned int get_timer_id;
- iotcon_representation_h repr;
- iotcon_remote_resource_cached_representation_changed_cb cb;
- void *user_data;
- unsigned int observe_sub_id;
- int64_t observe_handle;
-};
-
-struct icl_remote_resource_monitoring {
- unsigned int get_timer_id;
- iotcon_remote_resource_state_e resource_state;
- iotcon_remote_resource_state_changed_cb cb;
- void *user_data;
- iotcon_presence_h presence;
- icl_remote_resource_device_state_e device_state;
-};
-
-typedef struct icl_remote_resource_caching* icl_remote_resource_caching_h;
-typedef struct icl_remote_resource_monitoring* icl_remote_resource_monitoring_h;
-
struct icl_remote_resource {
char *uri_path;
char *host_address;
iotcon_connectivity_type_e connectivity_type;
int64_t observe_handle;
unsigned int observe_sub_id;
- icl_remote_resource_caching_h caching_handle;
- icl_remote_resource_monitoring_h monitoring_handle;
+ unsigned int monitoring_sub_id;
+ unsigned int caching_sub_id;
+ iotcon_representation_h cached_repr;
};
void icl_remote_resource_crud_stop(iotcon_remote_resource_h resource);
-int icl_remote_resource_observer_start(iotcon_remote_resource_h resource,
- iotcon_observe_policy_e observe_policy,
- iotcon_query_h query,
- GDBusSignalCallback sig_handler,
- void *cb_container,
- void *cb_free,
- unsigned int *sub_id,
- int64_t *observe_handle);
-
-int icl_remote_resource_stop_observing(iotcon_remote_resource_h resource,
- iotcon_options_h options, int64_t handle, unsigned int sub_id);
-
#endif /* __IOT_CONNECTIVITY_MANAGER_LIBRARY_CLIENT_H__ */
return IOTCON_ERROR_OUT_OF_MEMORY;
}
- signal_number = icl_dbus_generate_signal_number();
-
ic_dbus_call_register_resource_sync(icl_dbus_get_object(), uri_path, types, ifaces,
- properties, signal_number, &(resource->handle), NULL, &error);
+ properties, &signal_number, &(resource->handle), NULL, &error);
if (error) {
ERR("ic_dbus_call_register_resource_sync() Fail(%s)", error->message);
ret = icl_dbus_convert_dbus_error(error->code);
* @brief Starts caching of a remote resource.
* @details Use this function to start caching the resource's attribute.\n
* Although, remote resource is not observable, it keeps the representation up-to-date.
- * Because It checks whether representation is changed, periodically.
- * The default checking interval is 10 seconds, But it may be changed by a administrator.
+ * Because It checks whether representation is changed, periodically.\n
+ * The default checking interval is 10 seconds, but it may be changed by an administrator.
*
* @since_tizen 3.0
* @privlevel public
/**
* @brief Starts monitoring of a remote resource.
* @details When remote resource's state are changed, registered callbacks will be called
- * in turn. Internally, it checks the state of resource, periodically. Thus, it may not
- * receive the state, immediately.
+ * in turn. Although, remote resource does not call iotcon_start_presence(), it knows
+ * the state of resource. Because it checks the state of resource, periodically.\n
+ * The default checking interval is 10 seconds, but it may be changed by an administrator.
*
* @since_tizen 3.0
* @privlevel public