fix the problem when structures are destoried, repeatedly
[platform/core/iot/iotcon.git] / lib / icl-device.c
index 1ff6f8b..4a12c24 100644 (file)
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 #include <stdio.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
@@ -22,7 +23,7 @@
 #include "iotcon.h"
 #include "ic-utils.h"
 #include "icl.h"
-#include "icl-repr.h"
+#include "icl-representation.h"
 #include "icl-dbus.h"
 #include "icl-dbus-type.h"
 #include "icl-device.h"
@@ -46,97 +47,16 @@ typedef struct {
        iotcon_device_info_cb cb;
        void *user_data;
        unsigned int id;
+       int timeout_id;
 } icl_device_info_s;
 
 typedef struct {
        iotcon_platform_info_cb cb;
        void *user_data;
        unsigned int id;
+       int timeout_id;
 } icl_platform_info_s;
 
-typedef struct {
-       iotcon_tizen_info_cb cb;
-       void *user_data;
-} icl_tizen_info_s;
-
-
-API int iotcon_device_info_create(iotcon_device_info_h *device_info)
-{
-       iotcon_device_info_h info = NULL;
-
-       RETV_IF(NULL == device_info, IOTCON_ERROR_INVALID_PARAMETER);
-
-       info = calloc(1, sizeof(struct icl_device_info));
-       if (NULL == info) {
-               ERR("calloc() Fail(%d)", errno);
-               return IOTCON_ERROR_OUT_OF_MEMORY;
-       }
-
-       *device_info = info;
-
-       return IOTCON_ERROR_NONE;
-}
-
-
-API void iotcon_device_info_destroy(iotcon_device_info_h device_info)
-{
-       RET_IF(NULL == device_info);
-
-       free(device_info->device_name);
-       free(device_info->spec_ver);
-       free(device_info->device_id);
-       free(device_info->data_model_ver);
-       free(device_info);
-}
-
-
-API int iotcon_device_info_set_property(iotcon_device_info_h device_info,
-               iotcon_device_info_e property, const char *value)
-{
-       char *dup_value;
-
-       RETV_IF(NULL == device_info, IOTCON_ERROR_INVALID_PARAMETER);
-
-       if (value) {
-               dup_value = strdup(value);
-               if (NULL == dup_value) {
-                       ERR("strdup() Fail(%d)", errno);
-                       return IOTCON_ERROR_OUT_OF_MEMORY;
-               }
-       } else {
-               dup_value = NULL;
-       }
-
-       switch (property) {
-       case IOTCON_DEVICE_INFO_NAME:
-               if (device_info->device_name)
-                       free(device_info->device_name);
-               device_info->device_name = dup_value;
-               break;
-       case IOTCON_DEVICE_INFO_SPEC_VER:
-               if (device_info->spec_ver)
-                       free(device_info->spec_ver);
-               device_info->spec_ver = dup_value;
-               break;
-       case IOTCON_DEVICE_INFO_ID:
-               if (device_info->device_id)
-                       free(device_info->device_id);
-               device_info->device_id = dup_value;
-               break;
-       case IOTCON_DEVICE_INFO_DATA_MODEL_VER:
-               if (device_info->data_model_ver)
-                       free(device_info->data_model_ver);
-               device_info->data_model_ver = dup_value;
-               break;
-       default:
-               ERR("Invalid property(%d)", property);
-               free(dup_value);
-               return IOTCON_ERROR_INVALID_PARAMETER;
-       }
-
-       return IOTCON_ERROR_NONE;
-}
-
 
 API int iotcon_device_info_get_property(iotcon_device_info_h device_info,
                iotcon_device_info_e property, char **value)
@@ -165,37 +85,6 @@ API int iotcon_device_info_get_property(iotcon_device_info_h device_info,
        return IOTCON_ERROR_NONE;
 }
 
-
-API int iotcon_set_device_info(iotcon_device_info_h device_info)
-{
-       int ret;
-       GError *error = NULL;
-       GVariant *arg_info;
-
-       RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
-       RETV_IF(NULL == device_info, IOTCON_ERROR_INVALID_PARAMETER);
-       RETV_IF(NULL == device_info->device_name, IOTCON_ERROR_INVALID_PARAMETER);
-
-       arg_info = icl_dbus_device_info_to_gvariant(device_info);
-       ic_dbus_call_register_device_info_sync(icl_dbus_get_object(), arg_info, &ret,
-                       NULL, &error);
-       if (error) {
-               ERR("ic_dbus_call_register_device_info_sync() Fail(%s)", error->message);
-               ret = icl_dbus_convert_dbus_error(error->code);
-               g_error_free(error);
-               g_variant_unref(arg_info);
-               return ret;
-       }
-
-       if (IOTCON_ERROR_NONE != ret) {
-               ERR("iotcon-daemon Fail(%d)", ret);
-               return icl_dbus_convert_daemon_error(ret);
-       }
-
-       return ret;
-}
-
-
 static void _icl_device_info_cb(GDBusConnection *connection,
                const gchar *sender_name,
                const gchar *object_path,
@@ -209,33 +98,63 @@ static void _icl_device_info_cb(GDBusConnection *connection,
        icl_device_info_s *cb_container = user_data;
        iotcon_device_info_cb cb = cb_container->cb;
 
+       if (cb_container->timeout_id)
+               cb_container->timeout_id = 0;
+
        g_variant_get(parameters, "(&s&s&s&s&s)", &uri_path, &info.device_name,
                        &info.spec_ver, &info.device_id, &info.data_model_ver);
 
        /* From iotivity, we can get uri_path. But, the value is always "/oic/d". */
 
        if (cb)
-               cb(&info, cb_container->user_data);
+               cb(&info, IOTCON_ERROR_NONE, cb_container->user_data);
 }
 
+static gboolean _icl_timeout_get_device_info(gpointer p)
+{
+       FN_CALL;
+       icl_device_info_s *cb_container = p;
+       struct icl_device_info info = {0};
+
+       if (NULL == cb_container) {
+               ERR("cb_container is NULL");
+               return G_SOURCE_REMOVE;
+       }
+
+       if (cb_container->timeout_id && cb_container->cb)
+               cb_container->cb(&info, IOTCON_ERROR_TIMEOUT, cb_container->user_data);
 
-API int iotcon_get_device_info(const char *host_address, iotcon_device_info_cb cb,
+       icl_dbus_unsubscribe_signal(cb_container->id);
+       cb_container->id = 0;
+
+       return G_SOURCE_REMOVE;
+}
+
+API int iotcon_get_device_info(const char *host_address,
+               iotcon_connectivity_type_e connectivity_type,
+               iotcon_device_info_cb cb,
                void *user_data)
 {
-       GError *error = NULL;
+       int ret, timeout;
        unsigned int sub_id;
-       int ret, signal_number;
-       char signal_name[IC_DBUS_SIGNAL_LENGTH] = {0};
+       GError *error = NULL;
        icl_device_info_s *cb_container;
+       int64_t signal_number;
+       char signal_name[IC_DBUS_SIGNAL_LENGTH] = {0};
 
        RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
-       RETV_IF(NULL == host_address, IOTCON_ERROR_INVALID_PARAMETER);
        RETV_IF(NULL == cb, IOTCON_ERROR_INVALID_PARAMETER);
 
-       signal_number = icl_dbus_generate_signal_number();
+       timeout = icl_dbus_get_timeout();
 
-       ic_dbus_call_get_device_info_sync(icl_dbus_get_object(), host_address,
-                       signal_number, &ret, NULL, &error);
+       ic_dbus_call_get_device_info_sync(icl_dbus_get_object(),
+                       ic_utils_dbus_encode_str(host_address),
+                       connectivity_type,
+                       timeout,
+                       &signal_number,
+                       &ret,
+                       NULL,
+                       &error);
        if (error) {
                ERR("ic_dbus_call_get_device_info_sync() Fail(%s)", error->message);
                ret = icl_dbus_convert_dbus_error(error->code);
@@ -248,7 +167,7 @@ API int iotcon_get_device_info(const char *host_address, iotcon_device_info_cb c
                return icl_dbus_convert_daemon_error(ret);
        }
 
-       snprintf(signal_name, sizeof(signal_name), "%s_%u", IC_DBUS_SIGNAL_DEVICE,
+       snprintf(signal_name, sizeof(signal_name), "%s_%llx", IC_DBUS_SIGNAL_DEVICE,
                        signal_number);
 
        cb_container = calloc(1, sizeof(icl_device_info_s));
@@ -270,130 +189,12 @@ API int iotcon_get_device_info(const char *host_address, iotcon_device_info_cb c
 
        cb_container->id = sub_id;
 
-       return ret;
-}
-
-
-API int iotcon_platform_info_create(iotcon_platform_info_h *platform_info)
-{
-       iotcon_platform_info_h info = NULL;
-
-       RETV_IF(NULL == platform_info, IOTCON_ERROR_INVALID_PARAMETER);
-
-       info = calloc(1, sizeof(struct icl_platform_info));
-       if (NULL == info) {
-               ERR("calloc() Fail(%d)", errno);
-               return IOTCON_ERROR_OUT_OF_MEMORY;
-       }
-
-       *platform_info = info;
-
-       return IOTCON_ERROR_NONE;
-}
-
-
-API void iotcon_platform_info_destroy(iotcon_platform_info_h platform_info)
-{
-       RET_IF(NULL == platform_info);
-
-       free(platform_info->platform_id);
-       free(platform_info->manuf_name);
-       free(platform_info->manuf_url);
-       free(platform_info->model_number);
-       free(platform_info->date_of_manuf);
-       free(platform_info->platform_ver);
-       free(platform_info->os_ver);
-       free(platform_info->hardware_ver);
-       free(platform_info->firmware_ver);
-       free(platform_info->support_url);
-       free(platform_info->system_time);
-       free(platform_info);
-}
-
-
-API int iotcon_platform_info_set_property(iotcon_platform_info_h platform_info,
-               iotcon_platform_info_e property, const char *value)
-{
-       char *dup_value;
-
-       RETV_IF(NULL == platform_info, IOTCON_ERROR_INVALID_PARAMETER);
-
-       if (value) {
-               dup_value = strdup(value);
-               if (NULL == dup_value) {
-                       ERR("strdup() Fail(%d)", errno);
-                       return IOTCON_ERROR_OUT_OF_MEMORY;
-               }
-       } else {
-               dup_value = NULL;
-       }
-
-       switch (property) {
-       case IOTCON_PLATFORM_INFO_ID:
-               if (platform_info->platform_id)
-                       free(platform_info->platform_id);
-               platform_info->platform_id = dup_value;
-               break;
-       case IOTCON_PLATFORM_INFO_MANUF_NAME:
-               if (platform_info->manuf_name)
-                       free(platform_info->manuf_name);
-               platform_info->manuf_name = dup_value;
-               break;
-       case IOTCON_PLATFORM_INFO_MANUF_URL:
-               if (platform_info->manuf_url)
-                       free(platform_info->manuf_url);
-               platform_info->manuf_url = dup_value;
-               break;
-       case IOTCON_PLATFORM_INFO_MODEL_NUMBER:
-               if (platform_info->model_number)
-                       free(platform_info->model_number);
-               platform_info->model_number = dup_value;
-               break;
-       case IOTCON_PLATFORM_INFO_DATE_OF_MANUF:
-               if (platform_info->date_of_manuf)
-                       free(platform_info->date_of_manuf);
-               platform_info->date_of_manuf = dup_value;
-               break;
-       case IOTCON_PLATFORM_INFO_PLATFORM_VER:
-               if (platform_info->platform_ver)
-                       free(platform_info->platform_ver);
-               platform_info->platform_ver = dup_value;
-               break;
-       case IOTCON_PLATFORM_INFO_OS_VER:
-               if (platform_info->os_ver)
-                       free(platform_info->os_ver);
-               platform_info->os_ver = dup_value;
-               break;
-       case IOTCON_PLATFORM_INFO_HARDWARE_VER:
-               if (platform_info->hardware_ver)
-                       free(platform_info->hardware_ver);
-               platform_info->hardware_ver = dup_value;
-               break;
-       case IOTCON_PLATFORM_INFO_FIRMWARE_VER:
-               if (platform_info->firmware_ver)
-                       free(platform_info->firmware_ver);
-               platform_info->firmware_ver = dup_value;
-               break;
-       case IOTCON_PLATFORM_INFO_SUPPORT_URL:
-               if (platform_info->support_url)
-                       free(platform_info->support_url);
-               platform_info->support_url = dup_value;
-               break;
-       case IOTCON_PLATFORM_INFO_SYSTEM_TIME:
-               if (platform_info->system_time)
-                       free(platform_info->system_time);
-               platform_info->system_time = dup_value;
-               break;
-       default:
-               ERR("Invalid property(%d)", property);
-               free(dup_value);
-               return IOTCON_ERROR_INVALID_PARAMETER;
-       }
+       cb_container->timeout_id = g_timeout_add_seconds(timeout,
+                       _icl_timeout_get_device_info, cb_container);
 
-       return IOTCON_ERROR_NONE;
+       return ret;
 }
 
-
 API int iotcon_platform_info_get_property(iotcon_platform_info_h platform_info,
                iotcon_platform_info_e property, char **value)
 {
@@ -443,64 +244,6 @@ API int iotcon_platform_info_get_property(iotcon_platform_info_h platform_info,
 }
 
 
-/* The length of manufacturer_name should be less than and equal to 16.
- * The length of manufacturer_url should be less than and equal to 32. */
-API int iotcon_set_platform_info(iotcon_platform_info_h platform_info)
-{
-       int ret;
-       GError *error = NULL;
-       GVariant *arg_info;
-
-       RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
-       RETV_IF(NULL == platform_info, IOTCON_ERROR_INVALID_PARAMETER);
-
-       if (NULL == platform_info->platform_id
-                       || NULL == platform_info->manuf_name
-                       || NULL == platform_info->manuf_url
-                       || NULL == platform_info->model_number
-                       || NULL == platform_info->date_of_manuf
-                       || NULL == platform_info->platform_ver
-                       || NULL == platform_info->os_ver
-                       || NULL == platform_info->hardware_ver
-                       || NULL == platform_info->firmware_ver
-                       || NULL == platform_info->support_url
-                       || NULL == platform_info->system_time) {
-               ERR("one of parameter is NULL");
-               return IOTCON_ERROR_INVALID_PARAMETER;
-       }
-
-       if (platform_info->manuf_name
-                       && (ICL_MANUFACTURER_NAME_LENGTH_MAX < strlen(platform_info->manuf_name))) {
-               ERR("The length of manufacturer_name(%s) is invalid.", platform_info->manuf_name);
-               return IOTCON_ERROR_INVALID_PARAMETER;
-       }
-
-       if (platform_info->manuf_url
-                       && (ICL_MANUFACTURER_URL_LENGTH_MAX < strlen(platform_info->manuf_url))) {
-               ERR("The length of manufacturer_url(%s) is invalid.", platform_info->manuf_url);
-               return IOTCON_ERROR_INVALID_PARAMETER;
-       }
-
-       arg_info = icl_dbus_platform_info_to_gvariant(platform_info);
-       ic_dbus_call_register_platform_info_sync(icl_dbus_get_object(), arg_info, &ret,
-                       NULL, &error);
-       if (error) {
-               ERR("ic_dbus_call_register_platform_info_sync() Fail(%s)", error->message);
-               ret = icl_dbus_convert_dbus_error(error->code);
-               g_error_free(error);
-               g_variant_unref(arg_info);
-               return ret;
-       }
-
-       if (IOTCON_ERROR_NONE != ret) {
-               ERR("iotcon-daemon Fail(%d)", ret);
-               return icl_dbus_convert_daemon_error(ret);
-       }
-
-       return ret;
-}
-
-
 static void _icl_platform_info_cb(GDBusConnection *connection,
                const gchar *sender_name,
                const gchar *object_path,
@@ -514,6 +257,9 @@ static void _icl_platform_info_cb(GDBusConnection *connection,
        icl_platform_info_s *cb_container = user_data;
        iotcon_platform_info_cb cb = cb_container->cb;
 
+       if (cb_container->timeout_id)
+               cb_container->timeout_id = 0;
+
        g_variant_get(parameters, "(&s&s&s&s&s&s&s&s&s&s&s&s)",
                        &uri_path,
                        &info.platform_id,
@@ -528,30 +274,67 @@ static void _icl_platform_info_cb(GDBusConnection *connection,
                        &info.support_url,
                        &info.system_time);
 
+       info.manuf_url = ic_utils_dbus_decode_str(info.manuf_url);
+       info.model_number = ic_utils_dbus_decode_str(info.model_number);
+       info.date_of_manuf = ic_utils_dbus_decode_str(info.date_of_manuf);
+       info.platform_ver = ic_utils_dbus_decode_str(info.platform_ver);
+       info.os_ver = ic_utils_dbus_decode_str(info.os_ver);
+       info.hardware_ver = ic_utils_dbus_decode_str(info.hardware_ver);
+       info.firmware_ver = ic_utils_dbus_decode_str(info.firmware_ver);
+       info.support_url = ic_utils_dbus_decode_str(info.support_url);
+       info.system_time = ic_utils_dbus_decode_str(info.system_time);
+
        /* From iotivity, we can get uri_path. But, the value is always "/oic/p". */
 
        if (cb)
-               cb(&info, cb_container->user_data);
+               cb(&info, IOTCON_ERROR_NONE, cb_container->user_data);
 }
 
+static gboolean _icl_timeout_get_platform_info(gpointer p)
+{
+       FN_CALL;
+       icl_platform_info_s *cb_container = p;
+       struct icl_platform_info info = {0};
+
+       if (NULL == cb_container) {
+               ERR("cb_container is NULL");
+               return G_SOURCE_REMOVE;
+       }
+
+       if (cb_container->timeout_id && cb_container->cb)
+               cb_container->cb(&info, IOTCON_ERROR_TIMEOUT, cb_container->user_data);
 
-API int iotcon_get_platform_info(const char *host_address, iotcon_platform_info_cb cb,
+       icl_dbus_unsubscribe_signal(cb_container->id);
+       cb_container->id = 0;
+
+       return G_SOURCE_REMOVE;
+}
+
+API int iotcon_get_platform_info(const char *host_address,
+               iotcon_connectivity_type_e connectivity_type,
+               iotcon_platform_info_cb cb,
                void *user_data)
 {
-       GError *error = NULL;
+       int ret, timeout;
        unsigned int sub_id;
-       int ret, signal_number;
-       char signal_name[IC_DBUS_SIGNAL_LENGTH] = {0};
+       GError *error = NULL;
        icl_platform_info_s *cb_container;
+       int64_t signal_number;
+       char signal_name[IC_DBUS_SIGNAL_LENGTH] = {0};
 
        RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
-       RETV_IF(NULL == host_address, IOTCON_ERROR_INVALID_PARAMETER);
        RETV_IF(NULL == cb, IOTCON_ERROR_INVALID_PARAMETER);
 
-       signal_number = icl_dbus_generate_signal_number();
+       timeout = icl_dbus_get_timeout();
 
-       ic_dbus_call_get_platform_info_sync(icl_dbus_get_object(), host_address,
-                       signal_number, &ret, NULL, &error);
+       ic_dbus_call_get_platform_info_sync(icl_dbus_get_object(),
+                       ic_utils_dbus_encode_str(host_address),
+                       connectivity_type,
+                       timeout,
+                       &signal_number,
+                       &ret,
+                       NULL,
+                       &error);
        if (error) {
                ERR("ic_dbus_call_get_platform_info_sync() Fail(%s)", error->message);
                ret = icl_dbus_convert_dbus_error(error->code);
@@ -564,7 +347,7 @@ API int iotcon_get_platform_info(const char *host_address, iotcon_platform_info_
                return icl_dbus_convert_daemon_error(ret);
        }
 
-       snprintf(signal_name, sizeof(signal_name), "%s_%u", IC_DBUS_SIGNAL_PLATFORM,
+       snprintf(signal_name, sizeof(signal_name), "%s_%llx", IC_DBUS_SIGNAL_PLATFORM,
                        signal_number);
 
        cb_container = calloc(1, sizeof(icl_platform_info_s));
@@ -585,89 +368,8 @@ API int iotcon_get_platform_info(const char *host_address, iotcon_platform_info_
        }
 
        cb_container->id = sub_id;
+       cb_container->timeout_id = g_timeout_add_seconds(timeout,
+                       _icl_timeout_get_platform_info, cb_container);
 
        return ret;
 }
-
-
-static void _icl_tizen_info_cb(GObject *object, GAsyncResult *g_async_res,
-               gpointer user_data)
-{
-       int res;
-       GVariant *result;
-       char *device_name;
-       char *tizen_device_id;
-       GError *error = NULL;
-       struct icl_tizen_info info = {0};
-       icl_tizen_info_s *cb_container = user_data;
-       iotcon_tizen_info_cb cb = cb_container->cb;
-
-       ic_dbus_call_get_tizen_info_finish(IC_DBUS(object), &result, g_async_res, &error);
-       if (error) {
-               ERR("ic_dbus_call_get_tizen_info_finish() Fail(%s)", error->message);
-               g_error_free(error);
-               cb(&info, IOTCON_ERROR_DBUS, cb_container->user_data);
-               /* TODO contain time out error */
-               free(cb_container);
-               return;
-       }
-
-       g_variant_get(result, "(&s&si)", &device_name, &tizen_device_id, &res);
-
-       if (IOTCON_ERROR_NONE == res && NULL != ic_utils_dbus_decode_str(tizen_device_id)) {
-               info.device_name = ic_utils_dbus_decode_str(device_name);
-               info.tizen_device_id = tizen_device_id;
-       }
-
-       if (cb)
-               cb(&info, res, cb_container->user_data);
-
-       free(cb_container);
-}
-
-
-API int iotcon_get_tizen_info(const char *host_address, iotcon_tizen_info_cb cb,
-               void *user_data)
-{
-       icl_tizen_info_s *cb_container;
-
-       RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
-       RETV_IF(NULL == host_address, IOTCON_ERROR_INVALID_PARAMETER);
-       RETV_IF(NULL == cb, IOTCON_ERROR_INVALID_PARAMETER);
-
-       cb_container = calloc(1, sizeof(icl_tizen_info_s));
-       if (NULL == cb_container) {
-               ERR("calloc() Fail(%d)", errno);
-               return IOTCON_ERROR_OUT_OF_MEMORY;
-       }
-
-       cb_container->cb = cb;
-       cb_container->user_data = user_data;
-
-       ic_dbus_call_get_tizen_info(icl_dbus_get_object(), host_address, NULL,
-                       _icl_tizen_info_cb, cb_container);
-
-       return IOTCON_ERROR_NONE;
-}
-
-
-API int iotcon_tizen_info_get_property(iotcon_tizen_info_h tizen_info,
-               iotcon_tizen_info_e property, char **value)
-{
-       RETV_IF(NULL == tizen_info, IOTCON_ERROR_INVALID_PARAMETER);
-       RETV_IF(NULL == value, IOTCON_ERROR_INVALID_PARAMETER);
-
-       switch (property) {
-       case IOTCON_TIZEN_INFO_DEVICE_NAME:
-               *value = tizen_info->device_name;
-               break;
-       case IOTCON_TIZEN_INFO_TIZEN_DEVICE_ID:
-               *value = tizen_info->tizen_device_id;
-               break;
-       default:
-               ERR("Invalid property(%d)", property);
-               return IOTCON_ERROR_INVALID_PARAMETER;
-       }
-
-       return IOTCON_ERROR_NONE;
-}