Add GDBus interface for port scan 34/205834/3
authorYu <jiung.yu@samsung.com>
Thu, 9 May 2019 11:41:24 +0000 (20:41 +0900)
committerYu <jiung.yu@samsung.com>
Mon, 13 May 2019 04:23:44 +0000 (13:23 +0900)
Change-Id: I880d0b5bfbfc05b38a75340af002b77410c90aa1
Signed-off-by: Yu Jiung <jiung.yu@samsung.com>
include/inm-gdbus.h
include/inm-manager.h
include/inm-port-scan.h
packaging/dbus-inm-manager.conf
src/inm-gdbus.c
src/inm-manager.c
src/inm-port-scan.c
test/inm-test.c

index 41838c338c6f5997986bf0e698d4601e8a2ddd9d..1394d876695cf13ae04de97f807b460c675def56 100644 (file)
@@ -152,6 +152,7 @@ void inm_gdbus_emit_reacher_result(int error_code,
                gboolean found,
                const gchar *url);
 void inm_gdbus_emit_default_dns_lookup_result(gboolean found, const gchar *host_name);
+void inm_gdbus_emit_port_scan_result(GVariant *result);
 void inm_gdbus_emit_ethernet_cable_state(gboolean state);
 void inm_gdbus_emit_wifi_module_state(gboolean state);
 void inm_gdbus_emit_retry_tx_rate_changed(int retry_tx_rate);
index 7fd88f1ce652f85568cd415464bcbd5e79277c5a..c6de75816531aa3b31edc9453e71d277ecdf973e 100644 (file)
@@ -67,6 +67,14 @@ typedef enum {
        INM_MANAGER_ERROR_IN_PROGRESS,
 } inm_manager_error_e;
 
+typedef struct {
+       char *target;
+       int type;
+       int scope;
+       int start;
+       int end;
+} inm_manager_port_scan_target_s;
+
 
 typedef void (*inm_retry_tx_rate_callback)(int retry_rate, void *user_data);
 typedef void (*inm_channel_interference_callback)(int freq, double channel_intf, void *user_data);
@@ -107,6 +115,8 @@ int inm_manager_reachable_urls_start_checking(int type);
 int inm_manager_reachable_urls_stop_checking(int type);
 int inm_manager_reachable_urls_is_check_running(gboolean *is_running);
 int inm_manager_start_default_dns_lookup();
+int inm_manager_port_scan_start(inm_manager_port_scan_target_s *target);
+int inm_manager_port_scan_stop();
 
 int inm_manager_get_wifi_scan_state(gboolean *state);
 
index 3506a93ac69e782b4d75790f2a8e28ed1b0d9ae6..fce2d170f198098a0cfe5a95273914e50bb3584f 100644 (file)
@@ -40,8 +40,17 @@ typedef enum {
        INM_PORT_SCAN_ERROR_HOST_NOT_RESOLVED,
        INM_PORT_SCAN_ERROR_HOST_NOT_FOUND,
        INM_PORT_SCAN_ERROR_TIMEOUT,
+       INM_PORT_SCAN_ERROR_USER_STOP,
 } inm_port_scan_error_e;
 
+typedef enum {
+       INM_PORT_SCAN_RESULT_CODE_SUCCESS,
+       INM_PORT_SCAN_RESULT_CODE_USER_STOP,
+       INM_PORT_SCAN_RESULT_CODE_TIMEOUT,
+       INM_PORT_SCAN_RESULT_CODE_OPERATION_FAILED,
+} inm_port_scan_result_code_e;
+
+
 typedef enum {
        INM_PORT_SCAN_SCOPE_DEFAULT,
        INM_PORT_SCAN_SCOPE_SPECIFIC,
@@ -89,7 +98,7 @@ int inm_port_scan_init(void);
 int inm_port_scan_deinit(void);
 
 typedef void (*port_scan_callback) (
-               inm_port_scan_error_e err,
+               inm_port_scan_result_code_e code,
                inm_port_scan_result_s *result,
                gpointer user_data);
 
index 8a88f7a3738c65318b1ecba1bf9e2a2e819825ef..0d54dc1637221aff63073fd3248a3871d3419cab 100644 (file)
@@ -40,6 +40,8 @@
                <check send_destination="net.inm_manager" send_interface="net.inm_manager" send_member="ReachableUrlsStartChecking" privilege="http://tizen.org/privilege/network.get" />
                <check send_destination="net.inm_manager" send_interface="net.inm_manager" send_member="ReachableUrlsStopChecking" privilege="http://tizen.org/privilege/network.get" />
                <check send_destination="net.inm_manager" send_interface="net.inm_manager" send_member="ReachableUrlIsCheckRunning" privilege="http://tizen.org/privilege/network.get" />
+               <check send_destination="net.inm_manager" send_interface="net.inm_manager" send_member="PortScanStart" privilege="http://tizen.org/privilege/internal/default/platform" />
+               <check send_destination="net.inm_manager" send_interface="net.inm_manager" send_member="PortScanStop" privilege="http://tizen.org/privilege/internal/default/platform" />
                <check send_destination="net.inm_manager" send_interface="net.inm_manager" send_member="GetWifiState" privilege="http://tizen.org/privilege/network.get" />
                <check send_destination="net.inm_manager" send_interface="net.inm_manager" send_member="GetEthernetState" privilege="http://tizen.org/privilege/network.get" />
                <check send_destination="net.inm_manager" send_interface="net.inm_manager" send_member="GetCurrentConnection" privilege="http://tizen.org/privilege/network.get" />
index 9d28d25a25d4d34b239d9af13d2ae320b9438a8c..38c411052cc3b1e2e371989a5b867264c992f235 100644 (file)
@@ -1000,6 +1000,70 @@ static inline void __handle_default_dns_lookup(GVariant *parameters,
        __INM_FUNC_EXIT__;
 }
 
+static inline void __handle_port_scan_start(GVariant *parameters,
+               GDBusMethodInvocation *invocation)
+{
+       int ret = INM_MANAGER_ERROR_NONE;
+       GVariantIter *iter = NULL;
+       gchar *key = NULL;
+       GVariant *var = NULL;
+       inm_manager_port_scan_target_s target = {0,};
+
+       __INM_FUNC_ENTER__;
+
+       g_variant_get(parameters, "(a{sv})", &iter);
+       if (!iter) {
+               INM_LOGE("Failed to get iter");
+               __dbus_return_err(INM_MANAGER_ERROR_OPERATION_FAILED, invocation);
+               __INM_FUNC_EXIT__;
+               return;
+       }
+
+       while (g_variant_iter_loop(iter, "{sv}", &key, &var)) {
+               if (!g_strcmp0(key, "target"))
+                       g_variant_get(var, "&s", &(target.target));
+               else if (!g_strcmp0(key, "type"))
+                       g_variant_get(var, "i", &(target.type));
+               else if (!g_strcmp0(key, "scope"))
+                       g_variant_get(var, "i", &(target.scope));
+               else if (!g_strcmp0(key, "start"))
+                       g_variant_get(var, "i", &(target.start));
+               else if (!g_strcmp0(key, "end"))
+                       g_variant_get(var, "i", &(target.end));
+               else
+                       ;/* Do Nothing */
+       }
+
+       ret = inm_manager_port_scan_start(&target);
+       g_variant_iter_free(iter);
+       if (ret != INM_MANAGER_ERROR_NONE) {
+               __dbus_return_err(INM_MANAGER_ERROR_OPERATION_FAILED, invocation);
+               __INM_FUNC_EXIT__;
+               return;
+       }
+
+       g_dbus_method_invocation_return_value(invocation, NULL);
+       __INM_FUNC_EXIT__;
+}
+
+
+static inline void __handle_port_scan_stop(GVariant *parameters,
+               GDBusMethodInvocation *invocation)
+{
+       int ret = INM_MANAGER_ERROR_NONE;
+
+       __INM_FUNC_ENTER__;
+
+       ret = inm_manager_port_scan_stop();
+       if (ret != INM_MANAGER_ERROR_NONE) {
+               __dbus_return_err(ret, invocation);
+               return;
+       }
+
+       g_dbus_method_invocation_return_value(invocation, NULL);
+       __INM_FUNC_EXIT__;
+}
+
 static inline void __handle_get_links(GVariant *parameters,
                                            GDBusMethodInvocation *invocation)
 {
@@ -1086,6 +1150,10 @@ static void __daemon_method_call(GDBusConnection *connection,
                __handle_reachable_urls_is_check_running(parameters, invocation);
        else if (g_strcmp0(method_name, "DefaultDnsLookupCheck") == 0)
                __handle_default_dns_lookup(parameters, invocation);
+       else if (g_strcmp0(method_name, "PortScanStart") == 0)
+               __handle_port_scan_start(parameters, invocation);
+       else if (g_strcmp0(method_name, "PortScanStop") == 0)
+               __handle_port_scan_stop(parameters, invocation);
        else if (g_strcmp0(method_name, "GetLinks") == 0)
                __handle_get_links(parameters, invocation);
 }
@@ -1206,6 +1274,18 @@ void inm_gdbus_emit_default_dns_lookup_result(gboolean found, const gchar *host_
        __INM_FUNC_EXIT__;
 }
 
+void inm_gdbus_emit_port_scan_result(GVariant * result)
+{
+       __INM_FUNC_ENTER__;
+
+       inm_gdbus_emit_signal(NULL,
+                       INM_MANAGER_OBJ,
+                       INM_MANAGER_SERVICE,
+                       "PortScanResult",
+                       result);
+       __INM_FUNC_EXIT__;
+}
+
 void inm_gdbus_emit_ethernet_cable_state(gboolean state)
 {
        GVariantBuilder *builder = NULL;
@@ -1523,6 +1603,11 @@ static void __init_daemon_introspection()
                                "</method>"
                        "<method name='DefaultDnsLookupCheck'>"
                                "</method>"
+                       "<method name='PortScanStart'>"
+                               "<arg type='a{sv}' name='target' direction='in'/>"
+                               "</method>"
+                       "<method name='PortScanStop'>"
+                               "</method>"
                        "<method name='GetLinks'>"
                                "<arg type='a(ia{sv})' name='links' direction='out'/>"
                                "</method>"
@@ -1540,6 +1625,9 @@ static void __init_daemon_introspection()
                        "<signal name='ReachingResult'>"
                        "<arg type='a{sv}' name='ReachingInfo'/>"
                        "</signal>"
+                       "<signal name='PortScanResult'>"
+                       "<arg type='a{sv}' name='PortScanInfo'/>"
+                       "</signal>"
                        "<signal name='LinksChanged'>"
                        "</signal>"
                        "</interface>"
index 87d2284d3d0f5970ada94943e387e7fd46fe4bc0..8a87a27218c6feb368e03a21ad8ee1b087bcb66a 100644 (file)
@@ -39,6 +39,7 @@
 #include "inm-manager.h"
 #include "inm-rtnl.h"
 #include "inm-dns-lookup.h"
+#include "inm-port-scan.h"
 #include "inm-manager-log.h"
 #include "inm-error.h"
 
@@ -596,6 +597,159 @@ int inm_manager_start_default_dns_lookup()
        return INM_MANAGER_ERROR_NONE;
 }
 
+static GVariant *__port_state_to_variant(int addr_index, int port_num, inm_host_result_s *result)
+{
+       GVariantBuilder builder;
+       int port_index;
+       __INM_FUNC_ENTER__;
+
+       g_variant_builder_init(&builder, G_VARIANT_TYPE("ay"));
+       for (port_index = 0; port_index < port_num; port_index++)
+               g_variant_builder_add(&builder,
+                               "y",
+                               result[addr_index].port_state_array[port_index]);
+
+       __INM_FUNC_EXIT__;
+       return g_variant_builder_end(&builder);
+}
+
+static GVariant *__result_to_variant(int addr_num, int start_port, int port_num, inm_host_result_s *result)
+{
+       GVariantBuilder outer;
+       GVariantBuilder inner;
+       int addr_index;
+       __INM_FUNC_ENTER__;
+       INM_LOGI("addr num %d start port %d port num %d", addr_num, start_port, port_num);
+
+       g_variant_builder_init(&outer, G_VARIANT_TYPE("aa{sv}"));
+
+
+       for (addr_index = 0; addr_index < addr_num; addr_index++) {
+               g_variant_builder_init(&inner, G_VARIANT_TYPE("a{sv}"));
+               g_variant_builder_add(&inner,
+                               "{sv}",
+                               "address",
+                               g_variant_new_string(result[addr_index].host_address));
+               g_variant_builder_add(&inner,
+                               "{sv}",
+                               "port_state_arr",
+                               __port_state_to_variant(addr_index, port_num, result));
+
+               g_variant_builder_add_value(&outer, g_variant_builder_end(&inner));
+       }
+
+       __INM_FUNC_EXIT__;
+       return g_variant_builder_end(&outer);
+}
+
+static GVariant *__build_port_scan_result_args(inm_port_scan_result_code_e code,
+               inm_port_scan_result_s *result)
+{
+       GVariantBuilder *builder = NULL;
+       GVariant *result_variant = NULL;
+       int addr_num;
+       int start_port;
+       int port_num;
+       __INM_FUNC_ENTER__;
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
+       g_variant_builder_add(builder, "{sv}", "code", g_variant_new_int32(code));
+
+       if (code != INM_PORT_SCAN_RESULT_CODE_SUCCESS) {
+               result_variant = g_variant_new("(a{sv})", builder);
+               g_variant_builder_unref(builder);
+               __INM_FUNC_EXIT__;
+               return result_variant;
+       }
+
+       addr_num = result->address_num;
+       start_port = result->start;
+       port_num = result->end - result->start + 1;
+       g_variant_builder_add(builder, "{sv}", "address_cnt", g_variant_new_int32(addr_num));
+       g_variant_builder_add(builder, "{sv}", "start_port", g_variant_new_int32(start_port));
+       g_variant_builder_add(builder, "{sv}", "port_cnt", g_variant_new_int32(port_num));
+       g_variant_builder_add(builder,
+                       "{sv}",
+                       "address_port_state_arr",
+                       __result_to_variant(addr_num, start_port, port_num, result->result_array));
+
+       result_variant = g_variant_new("(a{sv})", builder);
+       g_variant_builder_unref(builder);
+       __INM_FUNC_EXIT__;
+       return result_variant;
+}
+
+static void __port_scan_callback(
+               inm_port_scan_result_code_e code,
+               inm_port_scan_result_s *result,
+               gpointer user_data)
+{
+
+       GVariant *result_variant = NULL;
+
+       result_variant = __build_port_scan_result_args(code, result);
+       inm_gdbus_emit_port_scan_result(result_variant);
+}
+
+int inm_manager_port_scan_start(inm_manager_port_scan_target_s *target)
+{
+       inm_port_scan_handle_s handle = {0,};
+       gboolean is_running = FALSE;
+       int ret = 0;
+
+       __INM_FUNC_ENTER__;
+
+       ret = inm_port_scan_is_running(&is_running);
+       if (ret != INM_PORT_SCAN_ERROR_NONE) {
+               __INM_FUNC_EXIT__;
+               return INM_MANAGER_ERROR_OPERATION_FAILED;
+       }
+
+       if (is_running) {
+               __INM_FUNC_EXIT__;
+               return INM_MANAGER_ERROR_IN_PROGRESS;
+       }
+
+       handle.target = target->target;
+       handle.type = target->type;
+       handle.scope = target->scope;
+       handle.start = target->start;
+       handle.end = target->end;
+
+       ret = inm_port_scan_start(&handle, __port_scan_callback, NULL);
+       if (ret != INM_PORT_SCAN_ERROR_NONE)
+               ret = INM_MANAGER_ERROR_OPERATION_FAILED;
+
+       __INM_FUNC_EXIT__;
+       return ret;
+}
+
+int inm_manager_port_scan_stop()
+{
+       gboolean is_running = FALSE;
+       int ret = INM_PORT_SCAN_ERROR_NONE;
+
+       __INM_FUNC_ENTER__;
+
+       ret = inm_port_scan_is_running(&is_running);
+       if (ret != INM_PORT_SCAN_ERROR_NONE) {
+               __INM_FUNC_EXIT__;
+               return INM_MANAGER_ERROR_OPERATION_FAILED;
+       }
+
+       if (!is_running) {
+               __INM_FUNC_EXIT__;
+               return INM_MANAGER_ERROR_NONE;
+       }
+
+       ret = inm_port_scan_stop();
+       if (ret != INM_PORT_SCAN_ERROR_NONE)
+               ret = INM_MANAGER_ERROR_OPERATION_FAILED;
+
+       __INM_FUNC_EXIT__;
+       return ret;
+}
+
 int inm_manager_get_wifi_scan_state(gboolean *state)
 {
        inm_supplicant_iface_s *iface = NULL;
@@ -749,6 +903,29 @@ static inline void __deinit_dns_lookup()
        return;
 }
 
+
+static inline void __init_port_scan()
+{
+       __INM_FUNC_ENTER__;
+
+       if (inm_port_scan_init() < 0)
+               INM_LOGW("port scan init failed");
+
+       __INM_FUNC_EXIT__;
+       return;
+}
+
+static inline void __deinit_port_scan()
+{
+       __INM_FUNC_ENTER__;
+
+       if (inm_port_scan_deinit() < 0)
+               INM_LOGW("port scan deinit failed");
+
+       __INM_FUNC_EXIT__;
+       return;
+}
+
 static void __ethernet_cable_state_changed_cb(char *iface_name, int state, void *user_data)
 {
        gboolean is_attached = FALSE;
@@ -908,7 +1085,6 @@ static inline void __deinit_congestion_mon()
        __INM_FUNC_EXIT__;
 }
 
-
 static inline void __init_rtnl_mon()
 {
        int ret = 0;
@@ -1254,6 +1430,7 @@ int inm_manager_init()
        __init_channel_interference_monitor();
        __init_congestion_mon();
        __init_dns_lookup();
+       __init_port_scan();
 
        __INM_FUNC_EXIT__;
        return ret;
@@ -1282,6 +1459,7 @@ int inm_manager_deinit()
        __deinit_channel_interference_monitor();
        __deinit_congestion_mon();
        __deinit_dns_lookup();
+       __deinit_port_scan();
 
 
        g_free(g_inm_manager);
index 98aeea4995d983f7ac832a07b61f86ad9ed438ae..5d5ae22e0f80ab0b49ad60ba3cf2d5a5b57e7427 100644 (file)
@@ -1214,25 +1214,25 @@ static void __debug_scan_result(result_manager_s *p_result_manager)
        return;
 }
 
-static inline void __scanner_notify_result_error_none(port_scan_data_s *p_port_scan)
+static inline void __scanner_notify_result_success(port_scan_data_s *p_port_scan)
 {
        result_manager_s *p_result_manager = &(p_port_scan->result_manager);
 
        __debug_scan_result(p_result_manager);
 
        if (p_port_scan->cb)
-               p_port_scan->cb(INM_PORT_SCAN_ERROR_NONE,
+               p_port_scan->cb(INM_PORT_SCAN_RESULT_CODE_SUCCESS,
                                &(p_result_manager->result),
                                p_port_scan->cb_user_data);
 }
 
-static inline void __scanner_notify_result_operation_failed(port_scan_data_s *p_port_scan)
+static inline void __scanner_notify_result_user_stop(port_scan_data_s *p_port_scan)
 {
        result_manager_s *p_result_manager = &(p_port_scan->result_manager);
 
-       INM_LOGI("Operation failed");
+       INM_LOGI("Stop requested from user");
        if (p_port_scan->cb)
-               p_port_scan->cb(INM_PORT_SCAN_ERROR_NONE,
+               p_port_scan->cb(INM_PORT_SCAN_RESULT_CODE_USER_STOP,
                                &(p_result_manager->result),
                                p_port_scan->cb_user_data);
 }
@@ -1243,7 +1243,18 @@ static inline void __scanner_notify_result_time_out(port_scan_data_s *p_port_sca
 
        INM_LOGI("Time up");
        if (p_port_scan->cb)
-               p_port_scan->cb(INM_PORT_SCAN_ERROR_TIMEOUT,
+               p_port_scan->cb(INM_PORT_SCAN_RESULT_CODE_TIMEOUT,
+                               &(p_result_manager->result),
+                               p_port_scan->cb_user_data);
+}
+
+static inline void __scanner_notify_result_operation_failed(port_scan_data_s *p_port_scan)
+{
+       result_manager_s *p_result_manager = &(p_port_scan->result_manager);
+
+       INM_LOGI("Operation failed");
+       if (p_port_scan->cb)
+               p_port_scan->cb(INM_PORT_SCAN_RESULT_CODE_OPERATION_FAILED,
                                &(p_result_manager->result),
                                p_port_scan->cb_user_data);
 }
@@ -1352,10 +1363,6 @@ static void __scanner_next_port(port_scan_data_s *p_port_scan_data)
        p_target_manager = &(p_port_scan_data->target_manager);
        p_port_manager  = &(p_port_scan_data->port_manager);
        p_result_manager  = &(p_port_scan_data->result_manager);
-       if (!p_target_manager || !p_port_manager || !p_result_manager) {
-               __INM_FUNC_EXIT__;
-               return;
-       }
 
        __port_manager_shutdown_current_sock(p_port_manager);
 
@@ -1366,7 +1373,7 @@ static void __scanner_next_port(port_scan_data_s *p_port_scan_data)
        }
 
        if (!p_target_manager->p_addr_info_current) {
-               __scanner_notify_result_error_none(p_port_scan_data);
+               __scanner_notify_result_success(p_port_scan_data);
                __scanner_deinit(p_port_scan_data);
                INM_LOGI("Scanning done");
                return;
@@ -1525,8 +1532,6 @@ static int __handle_ip_recv_err(struct cmsghdr *cmsg,
        INM_LOGI("We got IP_RECVERR message");
 
        sock_err = (struct sock_extended_err*)CMSG_DATA(cmsg);
-       if (!sock_err)
-               return -1;
 
        addr = SO_EE_OFFENDER(sock_err);
        addr_in = (struct sockaddr_in *)addr;
@@ -1749,9 +1754,6 @@ static int __scanner_scan_start(port_scan_data_s *p_port_scan)
                return -1;
 
        p_port_manager  = &(p_port_scan->port_manager);
-       if (!p_port_manager)
-               return -1;
-
        if (scan_start_funcs[p_port_scan->type](p_port_manager) < 0)
                return -1;
 
@@ -1763,6 +1765,11 @@ static int __scanner_scan_start(port_scan_data_s *p_port_scan)
 
        if (p_port_scan->type != INM_PORT_SCAN_TYPE_CONN) {
                p_port_handle = __port_manager_get_current_port_handle(p_port_manager);
+               if (!p_port_handle) {
+                       scan_stop_funcs[p_port_scan->type](p_port_manager);
+                       return -1;
+               }
+
                p_port_handle->retry_timer_source_id =
                                g_timeout_add(DEFAULT_RETRY_TIMEOUT_MS,
                                                __scanner_retry_port_scan,
@@ -1896,6 +1903,8 @@ int inm_port_scan_stop()
 
        g_port_scan->cb = NULL;
        g_port_scan->cb_user_data = NULL;
+       if (__scanner_is_running(g_port_scan))
+               __scanner_notify_result_user_stop(g_port_scan);
        __scanner_stop_scan(g_port_scan);
        __scanner_deinit(g_port_scan);
 
index c7dc6c977937dda713e09d1826caf611eb159865..01e832e82bb813ee74cdd720d50dc0a1c64b49b9 100644 (file)
 #define MAKE_RED "\e[31m"
 #define MAKE_GREEN "\e[32m"
 
+#define DBUS_DEBUG_VARIANT(parameters) \
+       do {\
+               gchar *parameters_debug_str = NULL;\
+               if (parameters)\
+                       parameters_debug_str = g_variant_print(parameters, TRUE);\
+               INM_LOGD("signal params [%s]", parameters_debug_str ? parameters_debug_str : "NULL");\
+               g_free(parameters_debug_str);\
+       } while (0)
+
 enum {
        CMD_QUIT,
        CMD_FULL_MENU,
@@ -2233,12 +2242,103 @@ void test_inm_port_scan_deinit()
        return;
 }
 
+
+
+static GVariant *__port_state_to_variant(int addr_index, int port_num, inm_host_result_s *result)
+{
+       GVariantBuilder builder;
+       int port_index;
+       __INM_FUNC_ENTER__;
+
+       g_variant_builder_init(&builder, G_VARIANT_TYPE("ay"));
+       for (port_index = 0; port_index < port_num; port_index++)
+               g_variant_builder_add(&builder,
+                               "y",
+                               result[addr_index].port_state_array[port_index]);
+
+       __INM_FUNC_EXIT__;
+       return g_variant_builder_end(&builder);
+}
+
+static GVariant *__result_to_variant(int addr_num, int start_port, int port_num, inm_host_result_s *result)
+{
+       GVariantBuilder outer;
+       GVariantBuilder inner;
+       int addr_index;
+       __INM_FUNC_ENTER__;
+       INM_LOGI("addr num %d start port %d port num %d", addr_num, start_port, port_num);
+
+       g_variant_builder_init(&outer, G_VARIANT_TYPE("aa{sv}"));
+
+
+       for (addr_index = 0; addr_index < addr_num; addr_index++) {
+               g_variant_builder_init(&inner, G_VARIANT_TYPE("a{sv}"));
+               g_variant_builder_add(&inner,
+                               "{sv}",
+                               "address",
+                               g_variant_new_string(result[addr_index].host_address));
+               g_variant_builder_add(&inner,
+                               "{sv}",
+                               "port_state_arr",
+                               __port_state_to_variant(addr_index, port_num, result));
+
+               g_variant_builder_add_value(&outer, g_variant_builder_end(&inner));
+       }
+
+       __INM_FUNC_EXIT__;
+       return g_variant_builder_end(&outer);
+}
+
+static GVariant *__build_port_scan_result_args(inm_port_scan_result_code_e code,
+               inm_port_scan_result_s *result)
+{
+       GVariantBuilder *builder = NULL;
+       GVariant *result_variant = NULL;
+       int addr_num;
+       int start_port;
+       int port_num;
+       __INM_FUNC_ENTER__;
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
+       g_variant_builder_add(builder, "{sv}", "code", g_variant_new_int32(code));
+
+       if (code != INM_PORT_SCAN_RESULT_CODE_SUCCESS) {
+               result_variant = g_variant_new("(a{sv})", builder);
+               g_variant_builder_unref(builder);
+               __INM_FUNC_EXIT__;
+               return result_variant;
+       }
+
+       addr_num = result->address_num;
+       start_port = result->start;
+       port_num = result->end - result->start + 1;
+       g_variant_builder_add(builder, "{sv}", "address_cnt", g_variant_new_int32(addr_num));
+       g_variant_builder_add(builder, "{sv}", "start_port", g_variant_new_int32(start_port));
+       g_variant_builder_add(builder, "{sv}", "port_cnt", g_variant_new_int32(port_num));
+       g_variant_builder_add(builder,
+                       "{sv}",
+                       "address_port_state_arr",
+                       __result_to_variant(addr_num, start_port, port_num, result->result_array));
+
+       result_variant = g_variant_new("(a{sv})", builder);
+       g_variant_builder_unref(builder);
+       __INM_FUNC_EXIT__;
+       return result_variant;
+}
+
 static void __port_scan_callback(
-               inm_port_scan_error_e err,
+               inm_port_scan_result_code_e code,
                inm_port_scan_result_s *result,
                gpointer user_data)
 {
-       /* TODO : print port scan result */
+
+       GVariant *result_variant = NULL;
+
+       result_variant = __build_port_scan_result_args(code, result);
+
+       DBUS_DEBUG_VARIANT(result_variant);
+
+       inm_gdbus_emit_port_scan_result(result_variant);
 }
 
 void test_inm_port_scan_start()