apply observe,presence functions
authoryoungman <yman.jung@samsung.com>
Mon, 10 Aug 2015 05:55:16 +0000 (14:55 +0900)
committeryoungman <yman.jung@samsung.com>
Tue, 3 Nov 2015 11:08:20 +0000 (20:08 +0900)
Change-Id: I31b910bd0c51fb3416dbe747163e32b3cbcb30a5
Signed-off-by: youngman <yman.jung@samsung.com>
common/ic-dbus.xml
daemon/icd-dbus.c
daemon/icd-ioty-ocprocess.c
daemon/icd-ioty-ocprocess.h
daemon/icd-ioty.c
daemon/icd-ioty.h
lib/icl-client-crud.c
lib/icl-dbus-type.c
lib/icl-dbus-type.h
lib/icl-presence.c

index 82334a6..061089d 100644 (file)
                        <arg type="(a(qs)i)" name="ret" direction="out"/>
                </method>
                <method name="observerStart">
-                       <arg type="(ssba(qs)asii)" name="client" direction="in"/>
+                       <arg type="(ssa(qs)i)" name="client" direction="in"/>
                        <arg type="i" name="observe_type" direction="in"/>
                        <arg type="a(ss)" name="query" direction="in"/>
                        <arg type="u" name="signal_number" direction="in"/>
                        <arg type="i" name="observe_h" direction="out"/>
-                       <arg type="i" name="ret" direction="out"/>
                </method>
                <method name="observerStop">
                        <arg type="i" name="observe_h" direction="in"/>
+                       <arg type="a(qs)" name="options" direction="in"/>
                        <arg type="i" name="ret" direction="out"/>
                </method>
                <method name="registerDeviceInfo">
index e1de746..0bc5792 100644 (file)
@@ -217,7 +217,7 @@ static int _icd_dbus_client_list_find_client(const gchar *owner, GList **ret_lis
                client_list = client_list->next;
        }
 
-       return IOTCON_ERROR_NO_DATA;
+       return IOTCON_ERROR_NONE;
 }
 
 static void _icd_dbus_name_owner_changed_cb(GDBusConnection *conn,
@@ -511,17 +511,16 @@ static gboolean _dbus_handle_observer_start(icDbus *object,
                GVariant *query,
                guint signal_number)
 {
-       int ret;
-       int observe_h;
+       void *observe_h;
        const gchar *sender;
 
        sender = g_dbus_method_invocation_get_sender(invocation);
-       ret = icd_ioty_observer_start(client, observe_type, query, signal_number, sender,
-                       &observe_h);
-       if (IOTCON_ERROR_NONE != ret)
-               ERR("icd_ioty_observer_start() Fail(%d)", ret);
+       observe_h = icd_ioty_observer_start(client, observe_type, query, signal_number,
+                       sender);
+       if (NULL == observe_h)
+               ERR("icd_ioty_observer_start() Fail");
 
-       ic_dbus_complete_observer_start(object, invocation, observe_h, ret);
+       ic_dbus_complete_observer_start(object, invocation, GPOINTER_TO_INT(observe_h));
 
        /* observe_h will be freed in _dbus_handle_observer_stop() */
        return TRUE;
@@ -530,11 +529,12 @@ static gboolean _dbus_handle_observer_start(icDbus *object,
 
 static gboolean _dbus_handle_observer_stop(icDbus *object,
                GDBusMethodInvocation *invocation,
-               gint observe_h)
+               gint observe_h,
+               GVariant *options)
 {
        int ret;
 
-       ret = icd_ioty_observer_stop(GINT_TO_POINTER(observe_h));
+       ret = icd_ioty_observer_stop(GINT_TO_POINTER(observe_h), options);
        if (IOTCON_ERROR_NONE != ret)
                ERR("icd_ioty_observer_stop() Fail(%d)", ret);
 
@@ -706,8 +706,7 @@ static gboolean _dbus_handle_subscribe_presence(icDbus *object,
        if (NULL == presence_h)
                ERR("icd_ioty_subscribe_presence() Fail");
 
-       ic_dbus_complete_subscribe_presence(object, invocation,
-                       GPOINTER_TO_INT(presence_h));
+       ic_dbus_complete_subscribe_presence(object, invocation, GPOINTER_TO_INT(presence_h));
 
        return TRUE;
 }
index e403a44..1416ee6 100644 (file)
@@ -20,6 +20,7 @@
 #include <json-glib/json-glib.h>
 
 #include <ocstack.h>
+#include <octypes.h>
 
 #include "iotcon.h"
 #include "ic-utils.h"
@@ -78,6 +79,24 @@ struct icd_crud_context {
 };
 
 
+struct icd_observe_context {
+       unsigned int signum;
+       int res;
+       int seqnum;
+       char *bus_name;
+       char *payload;
+       GVariantBuilder *options;
+};
+
+
+struct icd_presence_context {
+       unsigned int signum;
+       char *bus_name;
+       int result;
+       unsigned int nonce;
+       OCDevAddr *dev_addr;
+};
+
 void icd_ioty_ocprocess_stop()
 {
        icd_ioty_alive = 0;
@@ -651,7 +670,7 @@ OCStackApplicationResult icd_ioty_ocprocess_get_cb(void *ctx, OCDoHandle handle,
        }
 
        result = resp->result;
-       if (result == OC_STACK_OK) {
+       if (OC_STACK_OK == result) {
                res = IOTCON_RESPONSE_RESULT_OK;
                options = _ocprocess_parse_header_options(resp->rcvdVendorSpecificHeaderOptions,
                                resp->numRcvdVendorSpecificHeaderOptions);
@@ -697,9 +716,6 @@ OCStackApplicationResult icd_ioty_ocprocess_put_cb(void *ctx, OCDoHandle handle,
        case OC_STACK_RESOURCE_CREATED:
                res = IOTCON_RESPONSE_RESULT_RESOURCE_CREATED;
                break;
-       case OC_STACK_RESOURCE_DELETED:
-               res = IOTCON_RESPONSE_RESULT_RESOURCE_DELETED;
-               break;
        default:
                WARN("resp error(%d)", result);
                res = IOTCON_RESPONSE_RESULT_ERROR;
@@ -755,9 +771,6 @@ OCStackApplicationResult icd_ioty_ocprocess_post_cb(void *ctx, OCDoHandle handle
        case OC_STACK_RESOURCE_CREATED:
                res = IOTCON_RESPONSE_RESULT_RESOURCE_CREATED;
                break;
-       case OC_STACK_RESOURCE_DELETED:
-               res = IOTCON_RESPONSE_RESULT_RESOURCE_DELETED;
-               break;
        default:
                WARN("resp error(%d)", result);
                res = IOTCON_RESPONSE_RESULT_ERROR;
@@ -836,3 +849,236 @@ OCStackApplicationResult icd_ioty_ocprocess_delete_cb(void *ctx, OCDoHandle hand
        return OC_STACK_DELETE_TRANSACTION;
 }
 
+
+static int _worker_observe_cb(void *context)
+{
+       int ret;
+       GVariant *value;
+       struct icd_observe_context *ctx = context;
+
+       RETV_IF(NULL == ctx, IOTCON_ERROR_INVALID_PARAMETER);
+
+       value = g_variant_new("(a(qs)sii)", ctx->options, ctx->payload, ctx->res,
+                       ctx->seqnum);
+
+       ret = _ocprocess_response_signal(ctx->bus_name, IC_DBUS_SIGNAL_OBSERVE, ctx->signum,
+                       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);
+       free(ctx->payload);
+       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)
+{
+       int ret;
+       GVariant *value;
+
+       value = g_variant_new("(a(qs)sii)", NULL, IC_STR_NULL, ret_val, 0);
+
+       ret = _ocprocess_response_signal(dest, IC_DBUS_SIGNAL_OBSERVE, signum, 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)
+{
+       int ret, res;
+       OCStackResult result;
+       GVariantBuilder *options;
+       struct icd_observe_context *observe_ctx;
+       icd_sig_ctx_s *sig_context = ctx;
+
+       RETV_IF(NULL == ctx, OC_STACK_KEEP_TRANSACTION);
+
+       if (NULL == resp->resJSONPayload || '\0' == resp->resJSONPayload[0]) {
+               ERR("json payload is empty");
+               _observe_cb_response_error(sig_context->bus_name, sig_context->signum,
+                               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,
+                               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;
+       }
+
+       observe_ctx->payload = strdup(resp->resJSONPayload);
+       observe_ctx->signum = sig_context->signum;
+       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);
+       if (IOTCON_ERROR_NONE != ret) {
+               ERR("_ocprocess_worker_start() Fail(%d)", ret);
+               _observe_cb_response_error(sig_context->bus_name, sig_context->signum, ret);
+               free(observe_ctx->bus_name);
+               free(observe_ctx->payload);
+               g_variant_builder_unref(observe_ctx->options);
+               free(observe_ctx);
+               return OC_STACK_KEEP_TRANSACTION;
+       }
+
+       /* DO NOT FREE sig_context. It MUST be freed in the ocstack */
+       /* DO NOT FREE observe_ctx. It MUST be freed in the _worker_observe_cb func */
+
+       return OC_STACK_KEEP_TRANSACTION;
+}
+
+
+
+static int _worker_presence_cb(void *context)
+{
+       FN_CALL;
+       int ret;
+       uint16_t port;
+       uint8_t a, b, c, d;
+       GVariant *value;
+       char addr[PATH_MAX] = {0};
+       struct icd_presence_context *ctx = context;
+
+       RETV_IF(NULL == ctx, IOTCON_ERROR_INVALID_PARAMETER);
+
+       ret = OCDevAddrToIPv4Addr(ctx->dev_addr, &a, &b, &c, &d);
+       if (OC_STACK_OK != ret) {
+               ERR("OCDevAddrToIPv4Addr() Fail(%d)", ret);
+               free(ctx->bus_name);
+               free(ctx->dev_addr);
+               free(ctx);
+               return ret;
+       }
+
+       ret = OCDevAddrToPort(ctx->dev_addr, &port);
+       if (OC_STACK_OK != ret) {
+               ERR("OCDevAddrToPort() Fail(%d)", ret);
+               free(ctx->bus_name);
+               free(ctx->dev_addr);
+               free(ctx);
+               return ret;
+       }
+
+       /* TODO coap:// ? */
+       snprintf(addr, sizeof(addr), ICD_IOTY_COAP"%d.%d.%d.%d:%d", a, b, c, d, port);
+
+       value = g_variant_new("(ius)", ctx->result, ctx->nonce, addr);
+
+       ret = _ocprocess_response_signal(ctx->bus_name, IC_DBUS_SIGNAL_PRESENCE, ctx->signum,
+                       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);
+
+       return ret;
+}
+
+
+static void _presence_cb_response_error(const char *dest, unsigned int signum,
+               int ret_val)
+{
+       FN_CALL;
+       int ret;
+       GVariant *value;
+
+       value = g_variant_new("(ius)", ret_val, 0, IC_STR_NULL);
+
+       ret = _ocprocess_response_signal(dest, IC_DBUS_SIGNAL_PRESENCE, signum, value);
+       if (IOTCON_ERROR_NONE != ret)
+               ERR("_ocprocess_response_signal() Fail(%d)", ret);
+}
+
+
+OCStackApplicationResult icd_ioty_ocprocess_presence_cb(void *ctx, OCDoHandle handle,
+               OCClientResponse *resp)
+{
+       FN_CALL;
+       int ret;
+       OCDevAddr *dev_addr;
+       icd_sig_ctx_s *sig_context = ctx;
+       struct icd_presence_context *presence_ctx;
+
+       RETV_IF(NULL == ctx, 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);
+               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->addr, sizeof(OCDevAddr));
+
+       switch (resp->result) {
+       case OC_STACK_OK:
+               presence_ctx->result = IOTCON_PRESENCE_OK;
+               break;
+       case OC_STACK_PRESENCE_STOPPED:
+               presence_ctx->result = IOTCON_PRESENCE_STOPPED;
+               break;
+       case OC_STACK_PRESENCE_TIMEOUT:
+               presence_ctx->result = IOTCON_PRESENCE_TIMEOUT;
+               break;
+       case OC_STACK_ERROR:
+       default:
+               DBG("Presence error(%d)", resp->result);
+               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->nonce = resp->sequenceNumber;
+       presence_ctx->dev_addr = dev_addr;
+
+       ret = _ocprocess_worker_start(_worker_presence_cb, presence_ctx);
+       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);
+               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;
+}
+
+
index 65b31eb..a9d94e7 100644 (file)
@@ -41,4 +41,10 @@ OCStackApplicationResult icd_ioty_ocprocess_post_cb(void *ctx, OCDoHandle handle
 OCStackApplicationResult icd_ioty_ocprocess_delete_cb(void *ctx, OCDoHandle handle,
                OCClientResponse *resp);
 
+OCStackApplicationResult icd_ioty_ocprocess_observe_cb(void *ctx, OCDoHandle handle,
+               OCClientResponse* resp);
+
+OCStackApplicationResult icd_ioty_ocprocess_presence_cb(void *ctx, OCDoHandle handle,
+               OCClientResponse* resp);
+
 #endif /*__IOT_CONNECTIVITY_MANAGER_DAEMON_IOTIVITY_THREAD_H__*/
index 814cf80..c0c2e94 100644 (file)
@@ -137,12 +137,12 @@ OCResourceHandle icd_ioty_register_resource(const char *uri_path,
 }
 
 
-int icd_ioty_unregister_resource(OCResourceHandle resource_handle)
+int icd_ioty_unregister_resource(OCResourceHandle handle)
 {
        OCStackResult ret;
 
        icd_ioty_csdk_lock();
-       ret = OCDeleteResource(resource_handle);
+       ret = OCDeleteResource(handle);
        icd_ioty_csdk_unlock();
        if (OC_STACK_OK != ret) {
                ERR("OCDeleteResource() Fail(%d)", ret);
@@ -153,7 +153,7 @@ int icd_ioty_unregister_resource(OCResourceHandle resource_handle)
 }
 
 
-int icd_ioty_bind_interface(OCResourceHandle resourceHandle, iotcon_interface_e iface)
+int icd_ioty_bind_interface(OCResourceHandle handle, iotcon_interface_e iface)
 {
        int ret;
        OCStackResult result;
@@ -166,7 +166,7 @@ int icd_ioty_bind_interface(OCResourceHandle resourceHandle, iotcon_interface_e
        }
 
        icd_ioty_csdk_lock();
-       result = OCBindResourceInterfaceToResource(resourceHandle, resource_interface);
+       result = OCBindResourceInterfaceToResource(handle, resource_interface);
        icd_ioty_csdk_unlock();
        if (OC_STACK_OK != result) {
                ERR("OCBindResourceInterfaceToResource() Fail(%d)", result);
@@ -177,12 +177,12 @@ int icd_ioty_bind_interface(OCResourceHandle resourceHandle, iotcon_interface_e
 }
 
 
-int icd_ioty_bind_type(OCResourceHandle resource_handle, const char *resource_type)
+int icd_ioty_bind_type(OCResourceHandle handle, const char *resource_type)
 {
        OCStackResult ret;
 
        icd_ioty_csdk_lock();
-       ret = OCBindResourceTypeToResource(resource_handle, resource_type);
+       ret = OCBindResourceTypeToResource(handle, resource_type);
        icd_ioty_csdk_unlock();
        if (OC_STACK_OK != ret) {
                ERR("OCBindResourceTypeToResource() Fail(%d)", ret);
@@ -225,7 +225,8 @@ int icd_ioty_unbind_resource(OCResourceHandle parent, OCResourceHandle child)
 }
 
 
-int icd_ioty_notify_list_of_observers(void *handle, GVariant *msg, GVariant *observers)
+int icd_ioty_notify_list_of_observers(OCResourceHandle handle, GVariant *msg,
+               GVariant *observers)
 {
        int i, error_code, obs_length;
        char *repr_json = NULL;
@@ -262,7 +263,7 @@ int icd_ioty_notify_list_of_observers(void *handle, GVariant *msg, GVariant *obs
 }
 
 
-int icd_ioty_notify_all(void *handle)
+int icd_ioty_notify_all(OCResourceHandle handle)
 {
        OCStackResult ret;
 
@@ -634,17 +635,110 @@ gboolean icd_ioty_delete(icDbus *object, GDBusMethodInvocation *invocation,
 }
 
 
-int icd_ioty_observer_start(GVariant *resource, int observe_type,
-               GVariant *query, unsigned int signal_number, const char *bus_name, int *observe_h)
+OCDoHandle icd_ioty_observer_start(GVariant *resource, int observe_type, GVariant *query,
+               unsigned int signal_number, const char *bus_name)
 {
-       // TODO : To be implemented
-       return IOTCON_ERROR_NONE;
+       OCMethod method;
+       OCDoHandle handle;
+       OCStackResult result;
+       GVariantIter *options;
+       icd_sig_ctx_s *context;
+       OCCallbackData cbdata = {0};
+       int conn_type, options_size;
+       char *uri_path, *host, *uri;
+       OCHeaderOption oic_options[MAX_HEADER_OPTIONS];
+       OCHeaderOption *oic_options_ptr = NULL;
+
+       g_variant_get(resource, "(&s&sa(qs)i)", &uri_path, &host, &options, &conn_type);
+
+       uri = _icd_ioty_resource_generate_uri(host, uri_path, query);
+       if (NULL == uri) {
+               ERR("_icd_ioty_resource_generate_uri() Fail");
+               g_variant_iter_free(options);
+               return NULL;
+       }
+
+       if (IOTCON_OBSERVE == observe_type)
+               method = OC_REST_OBSERVE;
+       else if (IOTCON_OBSERVE_ALL == observe_type)
+               method = OC_REST_OBSERVE_ALL;
+       else
+               method = OC_REST_OBSERVE_ALL;
+
+       context = calloc(1, sizeof(icd_sig_ctx_s));
+       if (NULL == context) {
+               ERR("calloc() Fail(%d)", errno);
+               return NULL;
+       }
+       context->bus_name = ic_utils_strdup(bus_name);
+       context->signum = signal_number;
+
+       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);
+
+       icd_ioty_csdk_lock();
+       /* TODO : QoS is come from lib. And user can set QoS to client structure.  */
+       result = OCDoResource(&handle, method, uri, NULL, NULL, conn_type, OC_HIGH_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;
+       }
+
+       return handle;
 }
 
 
-int icd_ioty_observer_stop(void *observe_h)
+int icd_ioty_observer_stop(OCDoHandle handle, GVariant *options)
 {
-       // TODO : To be implemented
+       int options_size;
+       OCStackResult ret;
+       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;
+               }
+               oic_options_ptr = oic_options;
+       }
+
+       icd_ioty_csdk_lock();
+       ret = OCCancel(handle, OC_HIGH_QOS, oic_options_ptr, options_size);
+       icd_ioty_csdk_unlock();
+       if (OC_STACK_OK != ret) {
+               ERR("OCCancel() Fail(%d)", ret);
+               return IOTCON_ERROR_IOTIVITY;
+       }
+
        return IOTCON_ERROR_NONE;
 }
 
@@ -684,27 +778,96 @@ int icd_ioty_get_platform_info(const char *host_address, unsigned int signal_num
 OCDoHandle icd_ioty_subscribe_presence(const char *host_address,
                const char *resource_type, unsigned int signal_number, const char *bus_name)
 {
-       // TODO : To be implemented
-       return NULL;
+       int len;
+       OCDoHandle handle;
+       OCStackResult result;
+       char uri[PATH_MAX] = {0};
+       OCCallbackData cbdata = {0};
+       icd_sig_ctx_s *context;
+       iotcon_connectivity_type_e conn_type = IOTCON_CONNECTIVITY_IPV4;
+
+       len = snprintf(uri, sizeof(uri), "%s%s", host_address, OC_PRESENCE_URI);
+       if (len <= 0 || sizeof(uri) <= len) {
+               ERR("snprintf() Fail(%d)", len);
+               return NULL;
+       }
+
+       if (IC_STR_EQUAL != strcmp(IC_STR_NULL, resource_type))
+               snprintf(uri + len, sizeof(uri), "?rt=%s", resource_type);
+
+       context = calloc(1, sizeof(icd_sig_ctx_s));
+       if (NULL == context) {
+               ERR("calloc() Fail(%d)", errno);
+               return NULL;
+       }
+       context->bus_name = ic_utils_strdup(bus_name);
+       context->signum = signal_number;
+
+       cbdata.context = context;
+       cbdata.cb = icd_ioty_ocprocess_presence_cb;
+       cbdata.cd = _ioty_free_signal_context;
+
+       /* TODO : OC_ALL has wrong behaviour in iotivity version 0.9.1.
+        * Therefore, OC_IPV4 SHOULD be changed to OC_ALL later.
+        */
+       icd_ioty_csdk_lock();
+       result = OCDoResource(&handle, OC_REST_PRESENCE, uri, NULL, NULL, conn_type,
+                       OC_LOW_QOS, &cbdata, NULL, 0);
+       icd_ioty_csdk_unlock();
+
+       if (OC_STACK_OK != result) {
+               ERR("OCDoResource() Fail(%d)", result);
+               free(context->bus_name);
+               free(context);
+               return NULL;
+       }
+       return handle;
 }
 
 
-int icd_ioty_unsubscribe_presence(OCDoHandle presence_handle)
+int icd_ioty_unsubscribe_presence(OCDoHandle handle)
 {
-       // TODO : To be implemented
+       OCStackResult ret;
+
+       icd_ioty_csdk_lock();
+       ret = OCCancel(handle, OC_LOW_QOS, NULL, 0);
+       icd_ioty_csdk_unlock();
+       if (OC_STACK_OK != ret) {
+               ERR("OCCancel() Fail(%d)", ret);
+               return IOTCON_ERROR_IOTIVITY;
+       }
+
        return IOTCON_ERROR_NONE;
 }
 
 
 int icd_ioty_start_presence(unsigned int time_to_live)
 {
-       // TODO : To be implemented
+       OCStackResult ret;
+
+       icd_ioty_csdk_lock();
+       ret = OCStartPresence(time_to_live);
+       icd_ioty_csdk_unlock();
+       if (OC_STACK_OK != ret) {
+               ERR("OCStartPresence() Fail(%d)", ret);
+               return IOTCON_ERROR_IOTIVITY;
+       }
+
        return IOTCON_ERROR_NONE;
 }
 
 
 int icd_ioty_stop_presence()
 {
-       // TODO : To be implemented
+       OCStackResult ret;
+
+       icd_ioty_csdk_lock();
+       ret = OCStopPresence();
+       icd_ioty_csdk_unlock();
+       if (OC_STACK_OK != ret) {
+               ERR("OCStopPresence() Fail(%d)", ret);
+               return IOTCON_ERROR_IOTIVITY;
+       }
+
        return IOTCON_ERROR_NONE;
 }
index 54bb7f1..7fbc758 100644 (file)
@@ -20,6 +20,8 @@
 #include <stdint.h>
 #include <glib.h>
 
+#include <octypes.h>
+
 #include "iotcon.h"
 
 #define ICD_IOTY_COAP "coap://"
@@ -45,22 +47,23 @@ GThread* icd_ioty_init(const char *addr, unsigned short port);
 
 void icd_ioty_deinit();
 
-void* icd_ioty_register_resource(const char *uri_path, const char* const* res_types,
-               int ifaces, uint8_t properties);
+OCResourceHandle icd_ioty_register_resource(const char *uri_path,
+               const char* const* res_types, int ifaces, uint8_t properties);
 
-int icd_ioty_unregister_resource(void *resource_handle);
+int icd_ioty_unregister_resource(OCResourceHandle handle);
 
-int icd_ioty_bind_interface(void *resource_handle, iotcon_interface_e iface);
+int icd_ioty_bind_interface(OCResourceHandle handle, iotcon_interface_e iface);
 
-int icd_ioty_bind_type(void *resource_handle, const char *resource_type);
+int icd_ioty_bind_type(OCResourceHandle handle, const char *resource_type);
 
-int icd_ioty_bind_resource(void *parent, void *child);
+int icd_ioty_bind_resource(OCResourceHandle parent, OCResourceHandle child);
 
-int icd_ioty_unbind_resource(void *parent, void *child);
+int icd_ioty_unbind_resource(OCResourceHandle parent, OCResourceHandle child);
 
-int icd_ioty_notify_list_of_observers(void *handle, GVariant *msg, GVariant *observers);
+int icd_ioty_notify_list_of_observers(OCResourceHandle handle, GVariant *msg,
+               GVariant *observers);
 
-int icd_ioty_notify_all(void *handle);
+int icd_ioty_notify_all(OCResourceHandle handle);
 
 int icd_ioty_send_response(GVariant *resp);
 
@@ -82,10 +85,10 @@ gboolean icd_ioty_post(icDbus *object, GDBusMethodInvocation *invocation,
 gboolean icd_ioty_delete(icDbus *object, GDBusMethodInvocation *invocation,
                GVariant *resource);
 
-int icd_ioty_observer_start(GVariant *resource, int observe_type, GVariant *query,
-               unsigned int signal_number, const char *bus_name, int *observe_h);
+OCDoHandle icd_ioty_observer_start(GVariant *resource, int observe_type, GVariant *query,
+               unsigned int signal_number, const char *bus_name);
 
-int icd_ioty_observer_stop(void *observe_h);
+int icd_ioty_observer_stop(OCDoHandle handle, GVariant *options);
 
 #ifdef DEVICE_INFO_IMPL /* not implemented in iotivity 0.9.1 */
 int icd_ioty_register_device_info(GVariant *value);
@@ -99,10 +102,10 @@ int icd_ioty_register_platform_info(GVariant *value);
 int icd_ioty_get_platform_info(const char *host_address, unsigned int signal_number,
                const char *bus_name);
 
-void* icd_ioty_subscribe_presence(const char *host_address, const char *resource_type,
-               unsigned int signal_number, const char *bus_name);
+OCDoHandle icd_ioty_subscribe_presence(const char *host_address,
+               const char *resource_type, unsigned int signal_number, const char *bus_name);
 
-int icd_ioty_unsubscribe_presence(void *presence_handle);
+int icd_ioty_unsubscribe_presence(OCDoHandle handle);
 
 int icd_ioty_start_presence(unsigned int time_to_live);
 
index 96a3566..e93100a 100644 (file)
@@ -380,50 +380,42 @@ static void _icl_on_observe_cb(GDBusConnection *connection,
                gpointer user_data)
 {
        FN_CALL;
-       int index;
+       int res;
+       int seq_num;
+       iotcon_repr_h repr;
        GVariantIter *options;
        unsigned short option_id;
-       char *option_data;
+       char *option_data, *repr_json;
        iotcon_options_h header_options = NULL;
-       iotcon_repr_h repr = NULL;
-       GVariantIter *repr_iter;
-       char *repr_json;
-       char *repr_uri_path;
-       int res;
-       int seq_num;
 
        icl_on_observe_s *cb_container = user_data;
        iotcon_on_observe_cb cb = cb_container->cb;
 
-       g_variant_get(parameters, "(a(qs)asii)", &options, &repr_iter, &res, &seq_num);
+       g_variant_get(parameters, "(a(qs)sii)", &options, &repr_json, &res, &seq_num);
 
-       if (g_variant_iter_n_children(options)) {
+       if (IOTCON_ERROR_NONE == res && g_variant_iter_n_children(options)) {
                header_options = iotcon_options_new();
                while (g_variant_iter_loop(options, "(q&s)", &option_id, &option_data))
                        iotcon_options_insert(header_options, option_id, option_data);
        }
        g_variant_iter_free(options);
 
-       for (index = 0; g_variant_iter_loop(repr_iter, "&s", &repr_json); index++) {
-               iotcon_repr_h cur_repr = icl_repr_parse_json(repr_json);
-               if (NULL == cur_repr) {
-                       ERR("icl_repr_parse_json() Fail");
-                       iotcon_options_free(header_options);
-                       if (repr)
-                               iotcon_repr_free(repr);
-                       g_variant_iter_free(repr_iter);
+       if (IC_STR_EQUAL == strcmp(IC_STR_NULL, repr_json)) {
+               repr = iotcon_repr_new();
+       } else {
+               repr = icl_repr_create_repr(repr_json);
+               if (NULL == repr) {
+                       ERR("icl_repr_create_repr() Fail");
+                       if (header_options)
+                               iotcon_options_free(header_options);
+
+                       iotcon_client_free(cb_container->resource);
+                       free(cb_container);
                        return;
                }
-               repr_uri_path = icl_repr_json_get_uri_path(repr_json);
-               iotcon_repr_set_uri_path(cur_repr, repr_uri_path);
-               free(repr_uri_path);
-
-               if (0 == index)
-                       repr = cur_repr;
-               else
-                       repr->children = g_list_append(repr->children, cur_repr);
        }
-       g_variant_iter_free(repr_iter);
+
+       res = icl_dbus_convert_daemon_error(res);
 
        if (cb)
                cb(cb_container->resource, repr, header_options, res, seq_num,
@@ -451,7 +443,6 @@ API int iotcon_observer_start(iotcon_client_h resource,
                iotcon_on_observe_cb cb,
                void *user_data)
 {
-       int ret;
        int observe_handle;
        GError *error = NULL;
        unsigned int sub_id;
@@ -471,7 +462,7 @@ API int iotcon_observer_start(iotcon_client_h resource,
        arg_query = icl_dbus_query_to_gvariant(query);
 
        ic_dbus_call_observer_start_sync(icl_dbus_get_object(), arg_client, observe_type,
-                       arg_query, signal_number, &observe_handle, &ret, NULL, &error);
+                       arg_query, signal_number, &observe_handle, NULL, &error);
        if (error) {
                ERR("ic_dbus_call_observer_start_sync() Fail(%s)", error->message);
                g_error_free(error);
@@ -480,9 +471,9 @@ API int iotcon_observer_start(iotcon_client_h resource,
                return IOTCON_ERROR_DBUS;
        }
 
-       if (IOTCON_ERROR_NONE != ret) {
-               ERR("iotcon-daemon Fail(%d)", ret);
-               return icl_dbus_convert_daemon_error(ret);
+       if (0 == observe_handle) {
+               ERR("iotcon-daemon Fail");
+               return IOTCON_ERROR_IOTIVITY;
        }
 
        snprintf(signal_name, sizeof(signal_name), "%s_%u", IC_DBUS_SIGNAL_OBSERVE,
@@ -504,8 +495,8 @@ API int iotcon_observer_start(iotcon_client_h resource,
        cb_container->cb = cb;
        cb_container->user_data = user_data;
 
-       sub_id = icl_dbus_subscribe_signal(signal_name, cb_container, _icl_observe_conn_cleanup,
-                       _icl_on_observe_cb);
+       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;
@@ -513,7 +504,7 @@ API int iotcon_observer_start(iotcon_client_h resource,
        resource->observe_sub_id = sub_id;
        resource->observe_handle = observe_handle;
 
-       return ret;
+       return IOTCON_ERROR_NONE;
 }
 
 
@@ -521,6 +512,7 @@ API int iotcon_observer_stop(iotcon_client_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);
@@ -529,8 +521,10 @@ API int iotcon_observer_stop(iotcon_client_h resource)
                return IOTCON_ERROR_INVALID_PARAMETER;
        }
 
-       ic_dbus_call_observer_stop_sync(icl_dbus_get_object(),
-                       resource->observe_handle, &ret, NULL, &error);
+       arg_options = icl_dbus_options_to_gvariant(resource->header_options);
+
+       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);
                g_error_free(error);
index 2395e31..eebdbaf 100644 (file)
@@ -59,7 +59,7 @@ GVariant* icl_dbus_notimsg_to_gvariant(struct icl_notify_msg *msg)
        g_variant_builder_init(&builder, G_VARIANT_TYPE("a(is)"));
 
        if (msg) {
-               repr_json = icl_repr_generate_json(msg->repr, false, true);
+               repr_json = icl_repr_generate_json(msg->repr, false, false);
                if (NULL == repr_json) {
                        ERR("icl_repr_generate_json() Fail");
                        g_variant_builder_clear(&builder);
@@ -195,6 +195,25 @@ GVariant* icl_dbus_query_to_gvariant(iotcon_query_h query)
 }
 
 
+GVariant* icl_dbus_options_to_gvariant(iotcon_options_h options)
+{
+       GHashTableIter iter;
+       GVariantBuilder builder;
+       gpointer option_id, option_data;
+
+       g_variant_builder_init(&builder, G_VARIANT_TYPE("a(qs)"));
+       if (options) {
+               g_hash_table_iter_init(&iter, options->hash);
+               while (g_hash_table_iter_next(&iter, &option_id, &option_data)) {
+                       g_variant_builder_add(&builder, "(qs)", GPOINTER_TO_INT(option_id),
+                                       option_data);
+               }
+       }
+
+       return g_variant_new("a(qs)", builder);
+}
+
+
 GVariant* icl_dbus_observers_to_gvariant(iotcon_observers_h observers)
 {
        GList *node;
index 47c747b..18bf5cb 100644 (file)
@@ -29,6 +29,7 @@ GVariant* icl_dbus_device_info_to_gvariant(iotcon_device_info_s *device_info);
 #endif
 GVariant* icl_dbus_platform_info_to_gvariant(iotcon_platform_info_s *platform_info);
 GVariant* icl_dbus_query_to_gvariant(iotcon_query_h query);
+GVariant* icl_dbus_options_to_gvariant(iotcon_options_h options);
 GVariant* icl_dbus_observers_to_gvariant(iotcon_observers_h observers);
 
 #endif /* __IOT_CONNECTIVITY_MANAGER_LIBRARY_UTILITY_H__ */
index 061f45d..5fe798c 100644 (file)
@@ -20,6 +20,7 @@
 #include <glib.h>
 
 #include "iotcon.h"
+#include "ic-utils.h"
 #include "icl.h"
 #include "icl-dbus.h"
 
@@ -96,6 +97,8 @@ static void _icl_presence_cb(GDBusConnection *connection,
 
        g_variant_get(parameters, "(iu&s)", &res, &nonce, &host_address);
 
+       res = icl_dbus_convert_daemon_error(res);
+
        if (cb)
                cb(res, nonce, host_address, presence_container->user_data);
 }
@@ -134,8 +137,7 @@ API iotcon_presence_h iotcon_subscribe_presence(const char *host_address,
                return NULL;
        }
 
-       if (NULL == resource_type)
-               resource_type = "";
+       resource_type = ic_utils_dbus_encode_str(resource_type);
 
        ic_dbus_call_subscribe_presence_sync(icl_dbus_get_object(), host_address,
                        resource_type, signal_number, &(presence_container->handle), NULL, &error);