Add timeout & finish cb in find method and remove bind method
authorJihoon Jung <jh8801.jung@samsung.com>
Wed, 10 Jan 2018 09:58:10 +0000 (18:58 +0900)
committersaerome.kim <saerome.kim@samsung.com>
Mon, 2 Jul 2018 10:38:38 +0000 (19:38 +0900)
Signed-off-by: Jihoon Jung <jh8801.jung@samsung.com>
capi/include/familynet.h
capi/src/familynet.c
capi/src/familynet_gdbus.xml
capi/unittest/familynet_unit_test.cpp
src/fn-manager/include/fn_gdbus_group.h [changed mode: 0644->0755]
src/fn-manager/include/fn_group.h [changed mode: 0644->0755]
src/fn-manager/include/fn_iot.h [changed mode: 0644->0755]
src/fn-manager/src/familynet_gdbus.xml [changed mode: 0644->0755]
src/fn-manager/src/fn_gdbus_group.c [changed mode: 0644->0755]
src/fn-manager/src/fn_group.c [changed mode: 0644->0755]
src/fn-manager/src/fn_iot.c [changed mode: 0644->0755]

index 99511c1..f52e140 100755 (executable)
@@ -15,7 +15,8 @@ typedef enum {
 typedef void *familynet_group_h;
 typedef void *familynet_group_device_h;
 
-typedef bool (*familynet_group_find_cb)(familynet_group_type_e type, familynet_group_h target, void *user_data);
+typedef bool (*familynet_group_found_cb)(familynet_group_type_e type, familynet_group_h target, void *user_data);
+typedef void (*familynet_group_finish_cb)(int result, void *user_data);
 
 
 /* Management Module APIs*/
@@ -24,15 +25,18 @@ int familynet_deinitialize(); /* deinitialize gdbus connection with manager daem
 
 /* Group Module APIs*/
 /* familynet_group_create : craete group in my daemon */
-int familynet_group_create(char *group_name, familynet_group_h *group_handle);
+int familynet_group_create(char *group_name);
 /* familynet_group_find : find groups in my daemon + remote groups in network */
-int familynet_group_find(familynet_group_find_cb callback, void *user_data);
+int familynet_group_find(int timeout, familynet_group_found_cb find_cb, familynet_group_finish_cb finish_cb, void *user_data);
+/* familynet_group_find : find groups in my daemon + remote groups in network */
+int familynet_group_get_found_group(familynet_group_h **groups, int *count);
 /* familynet_group_join : join to remote group. if group handle is my daemon's, then the api return fail error */
-int familynet_group_join(familynet_group_h group_handle, familynet_group_find_cb callback, void *user_data);
+int familynet_group_join(familynet_group_h group_handle, familynet_group_found_cb callback, void *user_data);
 /* familynet_group_join : leave from remote group. if group handle is my daemon's, then the api return fail error */
 int familynet_group_leave(familynet_group_h group_handle, void *user_data);
 /* familynet_group_delete : remove group. if group handle is remote group, then the api return fail error */
 int familynet_group_delete(char *group_name, familynet_group_h *group_handle);
+int familynet_group_merge(familynet_group_h dest_group, familynet_group_h src_group);
 
 /* Group Device Module */
 /* The "Group Device" is element of group. Only one group device per target.
@@ -41,19 +45,17 @@ int familynet_group_delete(char *group_name, familynet_group_h *group_handle);
 
 /* familynet_group_device_find : Find the group devices on the network. (exclude myself) */
 int familynet_group_device_find(familynet_group_h group_handle,
-       familynet_group_device_h group_device_handle, familynet_group_find_cb callback, void *user_data);
+       familynet_group_device_h group_device_handle, familynet_group_found_cb callback, void *user_data);
 
 /* familynet_group_device_invite : Invite a remote group device to my group. */
 int familynet_group_device_invite(familynet_group_h group_handle,
-       familynet_group_device_h group_device_handle, familynet_group_find_cb callback, void *user_data); //Join to device in group (async)
+       familynet_group_device_h group_device_handle, familynet_group_found_cb callback, void *user_data); //Join to device in group (async)
 
 /* familynet_group_device_eject : Eject a remote group device from my group. */
 int familynet_group_device_eject(familynet_group_h group_handle,
-       familynet_group_device_h group_device_handle, familynet_group_find_cb callback, void *user_data); //dismiss from group (async)
+       familynet_group_device_h group_device_handle, familynet_group_found_cb callback, void *user_data); //dismiss from group (async)
 
 /* Group Information Module */
-int familynet_group_information_get_name(familynet_group_h group_handle, char **name);
-int familynet_group_information_get_device_count(familynet_group_h group_handle, int *device_count);
 int familynet_group_information_get_type(familynet_group_h group_handle, familynet_group_type_e *type);
 
 /* Group Device Information Module */
index a3f1b08..b8d0101 100755 (executable)
@@ -31,11 +31,87 @@ do { \
 
 typedef struct _familynet_group_t
 {
-       char *name;
+       char *uri_path;
+       char *device_id;
+       char *group_name;
+       char *host_addr;
+       char *resource_type;
        familynet_group_type_e type;
-       int device_count;
 } familynet_group_t;
 
+typedef struct _event_cb_t {
+        familynet_group_found_cb found_cb;
+                 familynet_group_finish_cb finish_cb;
+        void *user_data;
+} event_cb_t;
+
+static __thread GSList *event_cb_list = NULL;
+
+static familynet_group_t *_create_group_handle(char *uri_path, char *device_id,
+       char *group_name, char *host_addr, char *resource_type, familynet_group_type_e type)
+{
+       familynet_group_t *group_handle = g_new0(familynet_group_t, 1);
+
+       group_handle->uri_path = g_strdup(uri_path);
+       group_handle->device_id = g_strdup(device_id);
+       group_handle->group_name = g_strdup(group_name);
+       group_handle->host_addr = g_strdup(host_addr);
+       group_handle->resource_type = g_strdup(resource_type);
+       group_handle->type = type;
+
+       return group_handle;
+}
+
+static void _group_found_cb(Group *object,
+        GVariant *va, gpointer user_data)
+{
+       GVariantIter *iter = NULL;
+       const gchar *key;
+       GVariant *key_value;
+       familynet_group_t *group = NULL;
+       char *uri_path;
+       char *device_id;
+       char *group_name;
+       char *host_addr;
+       char *resource_type;
+       familynet_group_type_e type;
+
+       g_variant_get(va, "a{sv}", &iter);
+       while (g_variant_iter_loop(iter, "{sv}", &key, &key_value)) {
+               if (g_strcmp0(key, "URI") == 0) {
+                       uri_path = g_variant_get_string(key_value, NULL);
+               } else if (g_strcmp0(key, "DeviceID") == 0) {
+                       device_id = g_variant_get_string(key_value, NULL);
+               } else if (g_strcmp0(key, "GroupName") == 0) {
+                       group_name = g_variant_get_string(key_value, NULL);
+               } else if (g_strcmp0(key, "HostAddress") == 0) {
+                       host_addr = g_variant_get_string(key_value, NULL);
+               } else if (g_strcmp0(key, "GroupDeviceType") == 0) {
+                       resource_type = g_variant_get_string(key_value, NULL);
+               } else if (g_strcmp0(key, "GroupType") == 0) {
+                       type = g_variant_get_int32(key_value);
+               }
+       }
+
+       g_variant_iter_free(iter);
+
+       group = _create_group_handle(uri_path, device_id, group_name, host_addr, resource_type, type);
+
+       for (GSList *l = event_cb_list; l != NULL; l = l->next) {
+               event_cb_t *event_s = (event_cb_t *)l->data;
+               event_s->found_cb(type, group, event_s->user_data);
+       }
+}
+
+static void _finish_cb(Group *object,
+        gint ret, gpointer user_data)
+{
+       for (GSList *l = event_cb_list; l != NULL; l = l->next) {
+               event_cb_t *event_s = (event_cb_t *)l->data;
+               event_s->finish_cb(ret, event_s->user_data);
+       }
+}
+
 static void _group_proxy_init(void)
 {
        GError *error = NULL;
@@ -47,6 +123,9 @@ static void _group_proxy_init(void)
                 FN_DBUS_GROUP_PATH,
                 NULL,
                 &error);
+
+       g_signal_connect(group_proxy, "group-found", G_CALLBACK(_group_found_cb), NULL);
+       g_signal_connect(group_proxy, "finish", G_CALLBACK(_finish_cb), NULL);
 }
 
 static void _group_proxy_deinit(void)
@@ -75,18 +154,6 @@ static int _gdbus_deinitialize(void)
        return ret;
 }
 
-static familynet_group_t *_create_group_handle(familynet_group_type_e type,
-       char *name, int device_count)
-{
-       familynet_group_t *group_handle = g_new0(familynet_group_t, 1);
-
-       group_handle->type = type;
-       group_handle->device_count = device_count;
-       group_handle->name = g_strdup(name);
-
-       return group_handle;
-}
-
 int familynet_initialize()
 {
        int ret = 0;
@@ -132,7 +199,7 @@ int familynet_deinitialize()
 
 }
 
-int familynet_group_create(char *group_name, familynet_group_h *group_handle)
+int familynet_group_create(char *group_name)
 {
        int ret = 0;
        familynet_group_t *group;
@@ -141,75 +208,37 @@ int familynet_group_create(char *group_name, familynet_group_h *group_handle)
        /* create group to daemon using gdbus */
        group_call_create_sync(group_proxy, group_name, &ret, NULL, &error);
 
-       group = _create_group_handle(FAMILYNET_GROUP_TYPE_MINE, group_name, 1);
-       *group_handle = (familynet_group_h)group;
-
        return ret;
 }
 
-int familynet_group_find(familynet_group_find_cb callback, void *user_data)
+int familynet_group_find(int timeout, familynet_group_found_cb found_cb, familynet_group_finish_cb finish_cb, void *user_data)
 {
        int ret = 0;
-       int count = 0;
-       bool result = false;
-       GVariant *va = NULL;
        GError *error = NULL;
 
-       /* get groups from daemon using gdbus */
-       group_call_find_sync(group_proxy, &count, &va, &ret, NULL, &error);
-
-       if (count != 0 && (g_variant_n_children(va) == count)) {
-               GVariantIter *iter = NULL, *iter_row = NULL;
-               GVariant *key_value;
-               const gchar *key;
-               guint i = 0;
-
-               g_variant_get(va, "aa{sv}", &iter);
-               while (g_variant_iter_next(iter, "a{sv}", &iter_row)) {
-                       familynet_group_t *group = NULL;
-                       familynet_group_type_e type;
-                       char *name;
-                       int device_count;
-
-                       while (g_variant_iter_loop(iter_row, "{sv}", &key, &key_value)) {
-                               if (g_strcmp0(key, "type") == 0) {
-                                       type = g_variant_get_int32(key_value);
-                               } else if (g_strcmp0(key, "name") == 0) {
-                                       name = g_variant_get_string(key_value, NULL);
-                               } else if (g_strcmp0(key, "device_count") == 0) {
-                                       device_count = g_variant_get_int32(key_value);
-                               }
-                       }
-                       g_variant_iter_free(iter_row);
-
-                       group = _create_group_handle(type, name, device_count);
-                       result = callback(type, group, user_data);
-
-                       if (!result)
-                               break;
-               }
-               g_variant_iter_free(iter);
-       }
+       /* set event cb */
+       event_cb_t *event_t;
 
-       g_variant_unref(va);
+       event_t = g_try_new0(event_cb_t, 1);
+       if (event_t == NULL)
+                         return -1;
 
-       return ret;
-}
+       event_t->found_cb = found_cb;
+       event_t->finish_cb = finish_cb;
+       event_t->user_data = user_data;
 
-int familynet_group_information_get_name(familynet_group_h group_handle, char **name)
-{
-       familynet_group_t *group = (familynet_group_t *)group_handle;
-       *name = g_strdup(group->name);
+       event_cb_list = g_slist_prepend(event_cb_list, event_t);
 
-       return 0;
+       /* get groups from daemon using gdbus */
+       group_call_find_sync(group_proxy, timeout, &ret, NULL, &error);
+
+       return ret;
 }
 
-int familynet_group_information_get_device_count(familynet_group_h group_handle, int *device_count)
+/* group merge */
+int familynet_group_merge(familynet_group_h dest_group, familynet_group_h src_group)
 {
-       familynet_group_t *group = (familynet_group_t *)group_handle;
-       *device_count = group->device_count;
 
-       return 0;
 }
 
 int familynet_group_information_get_type(familynet_group_h group_handle, familynet_group_type_e *type)
index 9e414f9..741ae62 100755 (executable)
                        <arg type="i" name="result" direction="out"/>
                </method>
                <method name="Find">
-                       <arg type="i" name="group_count" direction="out" />
-                       <arg type="aa{sv}" name="groups" direction="out" />
+                       <arg type="i" name="timeout" direction="in" />
                        <arg type="i" name="result" direction="out" />
                </method>
+               <method name="GetFoundGroups">
+                       <arg type="i" name="result" direction="out" />
+                       <arg type="aa{sv}" name="groups" direction="out" />
+               </method>
                <method name="Join">
                        <arg type="i" name="group_count" direction="out" />
                        <arg type="aa{sv}" name="groups" direction="out" />
                        <arg type="aa{sv}" name="groups" direction="out" />
                        <arg type="i" name="result" direction="out" />
                </method>
+
+               <!-- Signal (D-Bus) definitions -->
+               <signal name="GroupFound">
+                       <arg type="a{sv}" name="group_info" direction="out" />
+               </signal>
+               <signal name="Finish">
+                       <arg type="i" name="result" direction="out" />
+               </signal>
        </interface>
 </node>
index 00322ea..a677462 100755 (executable)
@@ -37,35 +37,35 @@ TEST(familynet, familynet_group_create_p) {
        cout << "TEST START" << endl;
 
        int ret;
-       familynet_group_h handle = NULL;
 
        familynet_initialize();
-       ret = familynet_group_create("group1", &handle);
+       ret = familynet_group_create("group1");
 
        cout << "TEST END :" <<  ret << endl;
 }
 
 GMainLoop *main_loop = NULL;
 
-bool _familynet_group_find_cb(familynet_group_type_e type, familynet_group_h group_handle, void *user_data)
+bool _familynet_group_found_cb(familynet_group_type_e type, familynet_group_h group_handle, void *user_data)
 {
-       char *name = NULL;
-       int device_count = 0;
+       cout << "group type : " << type << endl;
 
-       familynet_group_information_get_name(group_handle, &name);
-       familynet_group_information_get_device_count(group_handle, &device_count);
+       return true;
+}
+
+void _familynet_finish_cb(int result, void *user_data)
+{
+       cout << "find finish : " << result << endl;
+       g_main_loop_quit(main_loop);
 
-       cout << "group type : " << type <<", group name : "
-               << name << ", device_count : " << device_count << endl;
 
-       return true;
 }
 
 TEST(familynet, familynet_group_find_p) {
        cout << "TEST START" << endl;
        familynet_initialize();
        main_loop = g_main_loop_new(NULL, FALSE);
-       familynet_group_find(_familynet_group_find_cb, NULL);
+       familynet_group_find(5, _familynet_group_found_cb, _familynet_finish_cb, main_loop);
        g_main_loop_run(main_loop);
        cout << "TEST END" << endl;
 }
old mode 100644 (file)
new mode 100755 (executable)
index 3d6135f..682851a
@@ -8,7 +8,7 @@ Group *group_dbus_get_object();
 gboolean group_create(Group *group, GDBusMethodInvocation *invocation, gchar *group_name,
        gpointer user_data);
 
-gboolean group_find(Group *group, GDBusMethodInvocation *invocation,
+gboolean group_find(Group *group, GDBusMethodInvocation *invocation, gint timeout,
        gpointer user_data);
 
 gboolean group_get_found_groups(Group *group, GDBusMethodInvocation *invocation,
@@ -32,6 +32,7 @@ gboolean group_device_invite(Group *group, GDBusMethodInvocation *invocation,
 gboolean group_device_eject(Group *group, GDBusMethodInvocation *invocation,
        gpointer user_data);
 
-void notify_group_added(GVariant *group_data);
+void notify_group_found(GVariant *group_data);
+void notify_group_finish(int ret);
 
 #endif
old mode 100644 (file)
new mode 100755 (executable)
index f56481f..c2839fb
@@ -20,10 +20,10 @@ int fn_group_create(char* name);
 int fn_group_destroy(fn_group_t *handle);
 
 /* Find Remote groups */
-int fn_group_find();
+int fn_group_find(int timeout);
 GVariant *fn_group_get_found_groups();
 int fn_group_add_new(char *uri_path, char *device_id, char *device_name,
-                                        char *host_addr, char *resource_type);
+                                        char *host_addr, char *resource_type, fn_group_type_e type);
 
 /* Join the remote devices in my daemon */
 int fn_group_get_groups(fn_group_t ***handles, int *count); //Get all of group in my daemon
old mode 100644 (file)
new mode 100755 (executable)
index 03e3fc4..8354d62
@@ -8,7 +8,7 @@
 int fn_iot_initialize();
 int fn_iot_add_resource(fn_resource_type_e resource_type, char *uri);
 int fn_iot_delete_resource(fn_resource_type_e resource_type);
-int fn_iot_discovery_resource(fn_resource_type_e resource_type);
+int fn_iot_discovery_resource(fn_resource_type_e resource_type, int timeout);
 int fn_iot_deinitialize();
 
 #endif
old mode 100644 (file)
new mode 100755 (executable)
index 7980be0..741ae62
@@ -12,6 +12,7 @@
                        <arg type="i" name="result" direction="out"/>
                </method>
                <method name="Find">
+                       <arg type="i" name="timeout" direction="in" />
                        <arg type="i" name="result" direction="out" />
                </method>
                <method name="GetFoundGroups">
                </method>
 
                <!-- Signal (D-Bus) definitions -->
-               <signal name="GroupAdded">
+               <signal name="GroupFound">
                        <arg type="a{sv}" name="group_info" direction="out" />
                </signal>
+               <signal name="Finish">
+                       <arg type="i" name="result" direction="out" />
+               </signal>
        </interface>
 </node>
old mode 100644 (file)
new mode 100755 (executable)
index f6fd841..fac49d9
@@ -17,14 +17,14 @@ gboolean group_create(Group *group, GDBusMethodInvocation *invocation, gchar *gr
        return TRUE;
 }
 
-gboolean group_find(Group *group, GDBusMethodInvocation *invocation,
+gboolean group_find(Group *group, GDBusMethodInvocation *invocation, gint timeout,
        gpointer user_data)
 {
        gint result = 0;
 
        LOG_DEBUG("group find called using dbus successful");
 
-       fn_group_find();
+       fn_group_find(timeout);
 
        group_complete_find(group, invocation, result);
        return TRUE;
@@ -92,7 +92,13 @@ gboolean group_device_eject(Group *group, GDBusMethodInvocation *invocation,
        return TRUE;
 }
 
-void notify_group_added(GVariant *group_data)
+void notify_group_found(GVariant *group_data)
 {
-       group_emit_group_added(group_dbus_get_object(), group_data);
+       group_emit_group_found(group_dbus_get_object(), group_data);
 }
+
+void notify_group_finish(int ret)
+{
+       group_emit_finish(group_dbus_get_object(), ret);
+}
+
old mode 100644 (file)
new mode 100755 (executable)
index 3240e65..81ffb49
@@ -24,7 +24,7 @@ int fn_group_create(char* name)
 
 
        /* A own group device is included in the created group by default. */
-       /* I would like to use multiple group device resource bindings for this created group resources.
+       /* I would like to use multiple group device resource for this created group resources.
                If there is a better way, please change it.
 
                Group/Jihoon (Group (In this daemon))
@@ -33,12 +33,7 @@ int fn_group_create(char* name)
                        - Group/Device1101 (Group Device (remote))
        */
 
-       fn_context_t *fn_ctx = fn_context_get_context();
-
-       ret = fn_iot_bind_resource(FN_RESOURCE_TYPE_GROUP, name, FN_RESOURCE_TYPE_GROUP_DEVICE, fn_ctx->device_uuid);
-       if (ret != FN_ERROR_NONE) {
-               LOG_ERR("Bind resource is failed : %s", fn_log_get_error_string(ret));
-       }
+       fn_resource_print_list();
 
        LOG_END();
 
@@ -50,13 +45,13 @@ int fn_group_destroy(fn_group_t *handle)
 
 }
 
-int fn_group_find()
+int fn_group_find(int timeout)
 {
        int ret;
 
        LOG_BEGIN();
 
-       ret = fn_iot_discovery_resource(FN_RESOURCE_TYPE_GROUP);
+       ret = fn_iot_discovery_resource(FN_RESOURCE_TYPE_GROUP, timeout);
        if (ret != FN_ERROR_NONE) {
                LOG_ERR("Failed to discover resource : %s",
                                 fn_log_get_error_string(ret));
@@ -90,6 +85,9 @@ GVariant *fn_group_get_found_groups()
                                                          g_variant_new_string(group->host_addr));
                g_variant_builder_add(&builder, "{sv}", "GroupDeviceType",
                                                          g_variant_new_string(group->resource_type));
+               /*When we get found groups, we can get my groups also. */
+               g_variant_builder_add(&builder, "{sv}", "GroupType",
+                                                         g_variant_new_int32(group->type));
                g_variant_builder_close(&builder);
 
                iter = g_list_next(iter);
@@ -101,7 +99,7 @@ GVariant *fn_group_get_found_groups()
 }
 
 int fn_group_add_new(char *uri_path, char *device_id, char *device_name,
-                                        char *host_addr, char *resource_type)
+                                        char *host_addr, char *resource_type, fn_group_type_e type)
 {
        int ret;
        fn_group_t *group;
@@ -116,6 +114,7 @@ int fn_group_add_new(char *uri_path, char *device_id, char *device_name,
        group->group_name = g_strdup(device_name);
        group->host_addr = g_strdup(host_addr);
        group->resource_type =  g_strdup(resource_type);
+       group->type = type;
 
        found_group_list = g_list_prepend(found_group_list, group);
 
@@ -131,10 +130,12 @@ int fn_group_add_new(char *uri_path, char *device_id, char *device_name,
                                                  g_variant_new_string(group->host_addr));
        g_variant_builder_add(&builder, "{sv}", "GroupDeviceType",
                                                  g_variant_new_string(group->resource_type));
+       g_variant_builder_add(&builder, "{sv}", "GroupType",
+                                                 g_variant_new_int32(group->type));
 
        group_data = g_variant_builder_end(&builder);
 
-       notify_group_added(group_data);
+       notify_group_found(group_data);
 
        LOG_END();
 
old mode 100644 (file)
new mode 100755 (executable)
index e3cfa8a..66a94b5
@@ -105,44 +105,6 @@ EXIT:
        return FN_ERROR_NONE;
 }
 
-int fn_iot_bind_resource(fn_resource_type_e parent_resource_type, char *parent_uri,
-       fn_resource_type_e child_resource_type, char *child_uri)
-{
-       int ret;
-
-       iotcon_resource_h parent_resource = NULL;
-       iotcon_resource_h child_resource = NULL;
-
-       ret = fn_resource_get_resource_from_uri(parent_resource_type, parent_uri, &parent_resource);
-       if (ret != 0) {
-               LOG_DEBUG("parent Resource can't found");
-               return FN_ERROR_UNKNOWN;
-       }
-
-       ret = fn_resource_get_resource_from_uri(child_resource_type, child_uri, &child_resource);
-       if (ret != 0) {
-               LOG_DEBUG("child Resource can't found");
-               return FN_ERROR_UNKNOWN;
-       }
-
-       ret = iotcon_resource_bind_child_resource(parent_resource, child_resource);
-       if (ret != 0) {
-               LOG_DEBUG("bind resource failed");
-               return FN_ERROR_UNKNOWN;
-       }
-
-       unsigned int *count = 0;
-       ret = iotcon_resource_get_child_count(parent_resource, &count);
-       if (ret != 0) {
-               LOG_DEBUG("get child count failed");
-               return FN_ERROR_UNKNOWN;
-       }
-
-       LOG_DEBUG("Now, resource type %d, uri %s has child count %d", parent_resource_type, parent_uri, count);
-
-       return FN_ERROR_NONE;
-}
-
 static bool _get_res_type_cb(const char *string, void *user_data)
 {
        char **resource_type = user_data;
@@ -154,6 +116,8 @@ static bool _get_res_type_cb(const char *string, void *user_data)
        return IOTCON_FUNC_CONTINUE;
 }
 
+int found_device_count = 0;
+
 static bool _found_resource(iotcon_remote_resource_h resource,
                                                iotcon_error_e result, void *user_data)
 {
@@ -214,18 +178,36 @@ static bool _found_resource(iotcon_remote_resource_h resource,
        }
 
        fn_group_add_new(resource_uri_path, resource_device_id,
-                                        resource_device_name, resource_host, resource_type);
+                                        resource_device_name, resource_host, resource_type, FN_GROUP_REMOTE_DEVICE);
+       found_device_count++;
 
        g_free(resource_type);
 
        return IOTCON_FUNC_CONTINUE;
 }
 
-int fn_iot_discovery_resource(fn_resource_type_e resource_type)
+static gboolean _timeout_cb(gpointer data)
+{
+       int ret = -1;
+       if (found_device_count > 0)
+               ret = 0;
+
+       notify_group_finish(ret);
+}
+
+int fn_iot_discovery_resource(fn_resource_type_e resource_type, int timeout)
 {
        int ret;
        iotcon_query_h query;
 
+       found_device_count = 0;
+
+       ret = iotcon_set_timeout(timeout);
+       if (IOTCON_ERROR_NONE != ret) {
+               LOG_ERR("Failed to set timeout value");
+               return FN_ERROR_OPERATION_FAILED;
+       }
+
        ret = iotcon_query_create(&query);
        if (IOTCON_ERROR_NONE != ret) {
                LOG_ERR("Failed to create iotcon query");
@@ -245,6 +227,8 @@ int fn_iot_discovery_resource(fn_resource_type_e resource_type)
                IOTCON_CONNECTIVITY_IP | IOTCON_CONNECTIVITY_PREFER_UDP,
                query, _found_resource, NULL);
 
+       g_timeout_add_seconds(timeout + 1, _timeout_cb, NULL);
+
        LOG_DEBUG("find resource : %s", get_error_message(ret));
 
        return ret;