fix the problem when structures are destoried, repeatedly
[platform/core/iot/iotcon.git] / lib / icl-resource.c
index 49dc550..b077a6c 100644 (file)
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
 #include <glib.h>
+#include <tizen_type.h>
 
 #include "iotcon.h"
 #include "ic-utils.h"
 #include "icl.h"
-#include "icl-repr.h"
+#include "icl-representation.h"
 #include "icl-dbus.h"
 #include "icl-request.h"
 #include "icl-dbus-type.h"
 #include "icl-resource.h"
 #include "icl-payload.h"
 
-/**
- * @brief The maximum length of uri_path path which can be held in a resource.
- *
- * @since_tizen 3.0
- */
-#define ICL_URI_PATH_LENGTH_MAX 36
-
-
 static void _icl_request_handler(GDBusConnection *connection,
                const gchar *sender_name,
                const gchar *object_path,
@@ -62,12 +54,14 @@ static void _icl_request_handler(GDBusConnection *connection,
        iotcon_resource_h resource = user_data;
        iotcon_request_handler_cb cb = resource->cb;
 
-       g_variant_get(parameters, "(ia(qs)a(ss)iiavxx)",
-                       &request.types,
+       g_variant_get(parameters, "(siia(qs)a(ss)iiavxx)",
+                       &request.host_address,
+                       &request.connectivity_type,
+                       &request.type,
                        &options,
                        &query,
                        &request.observation_info.action,
-                       &request.observation_info.observer_id,
+                       &request.observation_info.observe_id,
                        &repr_iter,
                        &request.oic_request_h,
                        &request.oic_resource_h);
@@ -83,7 +77,7 @@ static void _icl_request_handler(GDBusConnection *connection,
                }
 
                while (g_variant_iter_loop(options, "(q&s)", &option_id, &option_data))
-                       iotcon_options_insert(request.header_options, option_id, option_data);
+                       iotcon_options_add(request.header_options, option_id, option_data);
        }
        g_variant_iter_free(options);
 
@@ -99,7 +93,7 @@ static void _icl_request_handler(GDBusConnection *connection,
                }
 
                while (g_variant_iter_loop(query, "(&s&s)", &key, &value))
-                       iotcon_query_insert(request.query, key, value);
+                       iotcon_query_add(request.query, key, value);
        }
        g_variant_iter_free(query);
 
@@ -117,15 +111,12 @@ static void _icl_request_handler(GDBusConnection *connection,
        g_variant_iter_free(repr_iter);
 
        /* for iotcon_resource_notify */
-       if (IOTCON_REQUEST_OBSERVE & request.types) {
-               int observer_id = request.observation_info.observer_id;
-               if (IOTCON_OBSERVE_REGISTER == request.observation_info.action) {
-                       if (NULL == resource->observers)
-                               iotcon_observers_create(&resource->observers);
-                       iotcon_observers_insert(resource->observers, observer_id);
-               } else if (IOTCON_OBSERVE_DEREGISTER == request.observation_info.action) {
-                       iotcon_observers_delete(resource->observers, observer_id);
-               }
+       if (IOTCON_OBSERVE_REGISTER == request.observation_info.action) {
+               if (NULL == resource->observers)
+                       iotcon_observers_create(&resource->observers);
+               iotcon_observers_add(resource->observers, request.observation_info.observe_id);
+       } else if (IOTCON_OBSERVE_DEREGISTER == request.observation_info.action) {
+               iotcon_observers_remove(resource->observers, request.observation_info.observe_id);
        }
 
        if (cb)
@@ -167,12 +158,13 @@ API int iotcon_resource_create(const char *uri_path,
                void *user_data,
                iotcon_resource_h *resource_handle)
 {
+       int ret;
        unsigned int sub_id;
-       GError *error = NULL;
        const gchar **types;
+       GError *error = NULL;
        iotcon_resource_h resource;
-       int signal_number, ret;
-       char sig_name[IC_DBUS_SIGNAL_LENGTH];
+       int64_t signal_number;
+       char signal_name[IC_DBUS_SIGNAL_LENGTH];
 
        RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
        RETV_IF(NULL == uri_path, IOTCON_ERROR_INVALID_PARAMETER);
@@ -191,13 +183,11 @@ API int iotcon_resource_create(const char *uri_path,
        if (NULL == types) {
                ERR("icl_dbus_resource_types_to_array() Fail");
                free(resource);
-               return IOTCON_ERROR_INVALID_PARAMETER;
+               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);
@@ -220,12 +210,12 @@ API int iotcon_resource_create(const char *uri_path,
        resource->types = icl_resource_types_ref(res_types);
        resource->uri_path = ic_utils_strdup(uri_path);
        resource->ifaces = ifaces;
-       resource->is_observable = properties & IOTCON_OBSERVABLE;
+       resource->properties = properties;
 
-       snprintf(sig_name, sizeof(sig_name), "%s_%u", IC_DBUS_SIGNAL_REQUEST_HANDLER,
+       snprintf(signal_name, sizeof(signal_name), "%s_%llx", IC_DBUS_SIGNAL_REQUEST_HANDLER,
                        signal_number);
 
-       sub_id = icl_dbus_subscribe_signal(sig_name, resource, _icl_resource_conn_cleanup,
+       sub_id = icl_dbus_subscribe_signal(signal_name, resource, _icl_resource_conn_cleanup,
                        _icl_request_handler);
        if (0 == sub_id) {
                ERR("icl_dbus_subscribe_signal() Fail");
@@ -249,10 +239,9 @@ API int iotcon_resource_destroy(iotcon_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 (0 == resource->sub_id) {
+       if (0 == resource->handle) { /* iotcon dbus disconnected */
                WARN("Invalid Resource handle");
                iotcon_resource_types_destroy(resource->types);
                if (resource->observers)
@@ -262,6 +251,11 @@ API int iotcon_resource_destroy(iotcon_resource_h resource)
                return IOTCON_ERROR_NONE;
        }
 
+       if (NULL == icl_dbus_get_object()) {
+               ERR("icl_dbus_get_object() return NULL");
+               return IOTCON_ERROR_DBUS;
+       }
+
        ic_dbus_call_unregister_resource_sync(icl_dbus_get_object(), resource->handle, NULL,
                        &error);
        if (error) {
@@ -270,10 +264,10 @@ API int iotcon_resource_destroy(iotcon_resource_h resource)
                g_error_free(error);
                return ret;
        }
-
        resource->handle = 0;
 
        icl_dbus_unsubscribe_signal(resource->sub_id);
+       resource->sub_id = 0;
 
        return IOTCON_ERROR_NONE;
 }
@@ -347,15 +341,15 @@ API int iotcon_resource_bind_type(iotcon_resource_h resource, const char *resour
        return ret;
 }
 
-
 API int iotcon_resource_set_request_handler(iotcon_resource_h resource,
-               iotcon_request_handler_cb cb)
+               iotcon_request_handler_cb cb, void *user_data)
 {
        RETV_IF(NULL == resource, IOTCON_ERROR_INVALID_PARAMETER);
        RETV_IF(NULL == cb, IOTCON_ERROR_INVALID_PARAMETER);
 
-       WARN("Request handler is changed");
+       DBG("Request handler is changed");
        resource->cb = cb;
+       resource->user_data = user_data;
 
        return IOTCON_ERROR_NONE;
 }
@@ -526,57 +520,23 @@ API int iotcon_resource_get_interfaces(iotcon_resource_h resource, int *ifaces)
 }
 
 
-API int iotcon_resource_is_observable(iotcon_resource_h resource, bool *observable)
+API int iotcon_resource_get_properties(iotcon_resource_h resource, int *properties)
 {
        RETV_IF(NULL == resource, IOTCON_ERROR_INVALID_PARAMETER);
-       RETV_IF(NULL == observable, IOTCON_ERROR_INVALID_PARAMETER);
+       RETV_IF(NULL == properties, IOTCON_ERROR_INVALID_PARAMETER);
 
-       *observable = resource->is_observable;
+       *properties = resource->properties;
 
        return IOTCON_ERROR_NONE;
 }
 
-
-API int iotcon_notimsg_create(iotcon_representation_h repr, iotcon_interface_e iface,
-               iotcon_notimsg_h *notimsg_handle)
-{
-       iotcon_notimsg_h msg;
-
-       RETV_IF(NULL == repr, IOTCON_ERROR_INVALID_PARAMETER);
-       RETV_IF(NULL == notimsg_handle, IOTCON_ERROR_INVALID_PARAMETER);
-
-       msg = calloc(1, sizeof(struct icl_notify_msg));
-       if (NULL == msg) {
-               ERR("calloc() Fail(%d)", errno);
-               return IOTCON_ERROR_OUT_OF_MEMORY;
-       }
-
-       msg->repr = repr;
-       icl_representation_inc_ref_count(msg->repr);
-       msg->iface = iface;
-       msg->error_code = 200;
-
-       *notimsg_handle = msg;
-
-       return IOTCON_ERROR_NONE;
-}
-
-
-API void iotcon_notimsg_destroy(iotcon_notimsg_h msg)
-{
-       RET_IF(NULL == msg);
-
-       iotcon_representation_destroy(msg->repr);
-       free(msg);
-}
-
-API int iotcon_resource_notify(iotcon_resource_h resource, iotcon_notimsg_h msg,
-               iotcon_observers_h observers)
+API int iotcon_resource_notify(iotcon_resource_h resource,
+               iotcon_representation_h repr, iotcon_observers_h observers)
 {
        int ret;
        GError *error = NULL;
-       GVariant *noti_msg;
        GVariant *obs;
+       GVariant *repr_gvar;
 
        RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
        RETV_IF(NULL == resource, IOTCON_ERROR_INVALID_PARAMETER);
@@ -586,11 +546,10 @@ API int iotcon_resource_notify(iotcon_resource_h resource, iotcon_notimsg_h msg,
                return IOTCON_ERROR_INVALID_PARAMETER;
        }
 
-       /* TODO: Get default message if msg parameter is NULL */
-       noti_msg = icl_dbus_notimsg_to_gvariant(msg);
-       if (NULL == noti_msg) {
-               ERR("icl_dbus_notimsg_to_gvariant() Fail");
-               return IOTCON_ERROR_REPRESENTATION;
+       repr_gvar = icl_dbus_representation_to_gvariant(repr);
+       if (NULL == repr_gvar) {
+               ERR("icl_representation_to_gvariant() Fail");
+               return IOTCON_ERROR_SYSTEM;
        }
 
        if (observers)
@@ -598,14 +557,14 @@ API int iotcon_resource_notify(iotcon_resource_h resource, iotcon_notimsg_h msg,
        else
                obs = icl_dbus_observers_to_gvariant(resource->observers);
 
-       ic_dbus_call_notify_sync(icl_dbus_get_object(), resource->handle, noti_msg, obs, &ret,
-                       NULL, &error);
+       ic_dbus_call_notify_sync(icl_dbus_get_object(), resource->handle, repr_gvar, obs,
+                       &ret, NULL, &error);
        if (error) {
                ERR("ic_dbus_call_notify_sync() Fail(%s)", error->message);
                ret = icl_dbus_convert_dbus_error(error->code);
                g_error_free(error);
                g_variant_unref(obs);
-               g_variant_unref(noti_msg);
+               g_variant_unref(repr_gvar);
                return ret;
        }