Added Dbus method for netlink specific AP scan. 99/163999/3 accepted/tizen/unified/20171219.072637 submit/tizen/20171218.085650
authorNiraj Kumar Goit <niraj.g@samsung.com>
Thu, 14 Dec 2017 12:08:44 +0000 (17:38 +0530)
committerNiraj Kumar Goit <niraj.g@samsung.com>
Mon, 18 Dec 2017 08:46:06 +0000 (08:46 +0000)
Change-Id: I632ee77d9d1f6ac0d0b47c1e75c2fc24d9141062
Signed-off-by: Niraj Kumar Goit <niraj.g@samsung.com>
include/wifi-netlink-scan.h
interfaces/netconfig-iface-wifi.xml
src/wifi-netlink-scan.c
src/wifi.c

index e0c52c3..1bd0ce5 100755 (executable)
@@ -63,8 +63,16 @@ struct netconfig_netlink_scan_handler_args {
     int id;
 };
 
+typedef struct {
+       int id;
+       int if_index;
+       struct nl_sock *socket;
+       struct nl_msg *msg;
+} netconfig_nl_global;
+
 void __netconfig_notify_netlink_scan_done(void);
-gboolean handle_netlink_scan(Wifi *wifi, GDBusMethodInvocation *context);
+int handle_netlink_scan(Wifi *wifi, GDBusMethodInvocation *context);
+int handle_netlink_specific_scan(Wifi *wifi, GDBusMethodInvocation *context, gchar *ssid);
 
 #ifdef __cplusplus
 }
index 590c886..8920b03 100755 (executable)
@@ -47,6 +47,9 @@
                </method>
                <method name="NetlinkScan">
                </method>
+               <method name="NetlinkSpecificScan">
+                       <arg type="s" name="ssid" direction="in"/>
+               </method>
                <method name="RequestWpsCancel">
                </method>
                <method name="RequestWpsConnect">
index 7c3f9b2..d33ae41 100755 (executable)
@@ -376,7 +376,7 @@ static int __netconfig_netlink_scan_reply(struct nl_msg *msg, void *user_data)
        return NL_SKIP;
 }
 
-static int __netconfig_request_netlink_scan(struct nl_sock *socket, int if_index, int id)
+static int __netconfig_request_netlink_scan(struct nl_sock *socket, int if_index, int id, char *ssid)
 {
        struct netconfig_netlink_scan_results results = { .done = 0, .aborted = 0 };
        struct nl_msg *msg = NULL;
@@ -409,7 +409,10 @@ static int __netconfig_request_netlink_scan(struct nl_sock *socket, int if_index
        /** Set nl message and callback functions. */
        genlmsg_put(msg, 0, 0, id, 0, 0, NL80211_CMD_TRIGGER_SCAN, 0);
        nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_index);
-       nla_put(ssids, 1, 0, "");
+       if (!ssid)
+               nla_put(ssids, 1, 0, "");
+       else
+               nla_put(ssids, 1, strlen(ssid), ssid);
        nla_put_nested(msg, NL80211_ATTR_SCAN_SSIDS, ssids);
        nlmsg_free(ssids);
 
@@ -447,36 +450,102 @@ static int __netconfig_request_netlink_scan(struct nl_sock *socket, int if_index
        return 0;
 }
 
-gboolean handle_netlink_scan(Wifi *wifi, GDBusMethodInvocation *context)
+static int __netconfig_initialize_nl80211(netconfig_nl_global *global)
+{
+       int err = 0;
+
+       global->if_index = __netconfig_get_interface_index(WIFI_IFNAME);
+       if (global->if_index < 0) {
+               DBG("Failed to get interface index");
+               return -1;
+       }
+
+       global->socket = nl_socket_alloc();
+       if (!global->socket) {
+               DBG("Failed to allocate netlink socket.");
+               return -ENOMEM;
+       }
+
+       if (genl_connect(global->socket)) {
+               DBG("Failed to connect to generic netlink.");
+               err = -ENOLINK;
+               goto fail;
+       }
+
+       global->id = genl_ctrl_resolve(global->socket, "nl80211");
+       if (global->id < 0) {
+               DBG("Failed to find the nl80211 driver");
+               err = -ENOENT;
+               goto fail;
+       }
+
+       return 0;
+
+fail:
+       nl_socket_free(global->socket);
+       return err;
+}
+
+static int __netconfig_initialize_nl_msg(netconfig_nl_global *global)
+{
+       if (global == NULL) {
+               DBG("Invalid parameter.");
+               return -EINVAL;
+       }
+
+       global->msg = nlmsg_alloc();
+       if (global->msg == NULL) {
+               DBG("Failed to allocate netlink message");
+               return -ENOMEM;
+       }
+
+       /* Set command into message */
+       genlmsg_put(global->msg, 0, 0, global->id, 0, NLM_F_DUMP, NL80211_CMD_GET_SCAN, 0);
+       nla_put_u32(global->msg, NL80211_ATTR_IFINDEX, global->if_index);
+       nl_socket_modify_cb(global->socket, NL_CB_VALID, NL_CB_CUSTOM, __netconfig_netlink_scan_cb, NULL);
+
+       return 0;
+}
+
+int handle_netlink_scan(Wifi *wifi, GDBusMethodInvocation *context)
 {
        DBG("");
-       int if_index = __netconfig_get_interface_index(WIFI_IFNAME);
+       netconfig_nl_global global = {
+               .id = -1,
+               .if_index = -1,
+               .socket = NULL,
+               .msg = NULL,
+       };
 
-       /** Open socket to kernel. */
-       struct nl_sock *socket = nl_socket_alloc();
-       genl_connect(socket);
-       int id = genl_ctrl_resolve(socket, "nl80211");
+       /** Initialize netlink socket */
+       int ret = __netconfig_initialize_nl80211(&global);
+       if (ret < 0) {
+               DBG("__netconfig_initialize_nl80211() failed, error %d", ret);
+               wifi_complete_netlink_specific_scan(wifi, context);
+               return ret;
+       }
 
        /** Request NL80211_CMD_TRIGGER_SCAN to the kernel. */
-       int err = __netconfig_request_netlink_scan(socket, if_index, id);
-       if (err != 0) {
-               DBG("__netconfig_request_netlink_scan() failed, error %d", err);
+       ret = __netconfig_request_netlink_scan(global.socket, global.if_index, global.id, NULL);
+       if (ret < 0) {
+               DBG("__netconfig_request_netlink_scan() failed, error %d", ret);
                wifi_complete_netlink_scan(wifi, context);
-               return err;
+               return ret;
        }
 
-       /** Get info of all available APs. */
-       struct nl_msg *msg = nlmsg_alloc();
-       genlmsg_put(msg, 0, 0, id, 0, NLM_F_DUMP, NL80211_CMD_GET_SCAN, 0);
-       nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_index);
-       nl_socket_modify_cb(socket, NL_CB_VALID, NL_CB_CUSTOM, __netconfig_netlink_scan_cb, NULL);
+       ret = __netconfig_initialize_nl_msg(&global);
+       if (ret < 0) {
+               DBG("__netconfig_initialize_nl_msg() failed, error %d", ret);
+               wifi_complete_netlink_specific_scan(wifi, context);
+               return ret;
+       }
 
-       int ret = nl_send_auto_complete(socket, msg);
+       ret = nl_send_auto_complete(global.socket, global.msg);
        DBG("NL80211_CMD_GET_SCAN sent %d bytes to the kernel", ret);
 
        /** Receive the kernel message. */
-       ret = nl_recvmsgs_default(socket);
-       nlmsg_free(msg);
+       ret = nl_recvmsgs_default(global.socket);
+       nlmsg_free(global.msg);
        if (ret < 0) {
                DBG("nl_recvmsgs_default() failed. ret: %d (error: %s)", ret, nl_geterror(-ret));
                wifi_complete_netlink_scan(wifi, context);
@@ -484,5 +553,54 @@ gboolean handle_netlink_scan(Wifi *wifi, GDBusMethodInvocation *context)
        }
 
        wifi_complete_netlink_scan(wifi, context);
-       return TRUE;
+       return 1;
+}
+
+int handle_netlink_specific_scan(Wifi *wifi, GDBusMethodInvocation *context, gchar *ssid)
+{
+       DBG("ssid: %s", ssid);
+       netconfig_nl_global global = {
+               .id = -1,
+               .if_index = -1,
+               .socket = NULL,
+               .msg = NULL,
+       };
+
+       /** Initialize netlink socket */
+       int ret = __netconfig_initialize_nl80211(&global);
+       if (ret < 0) {
+               DBG("__netconfig_initialize_nl80211() failed, error %d", ret);
+               wifi_complete_netlink_specific_scan(wifi, context);
+               return ret;
+       }
+
+       /** Request NL80211_CMD_TRIGGER_SCAN to the kernel. */
+       ret = __netconfig_request_netlink_scan(global.socket, global.if_index, global.id, ssid);
+       if (ret != 0) {
+               DBG("__netconfig_request_netlink_scan() failed, error %d", ret);
+               wifi_complete_netlink_specific_scan(wifi, context);
+               return ret;
+       }
+
+       ret = __netconfig_initialize_nl_msg(&global);
+       if (ret < 0) {
+               DBG("__netconfig_initialize_nl_msg() failed, error %d", ret);
+               wifi_complete_netlink_specific_scan(wifi, context);
+               return ret;
+       }
+
+       ret = nl_send_auto_complete(global.socket, global.msg);
+       DBG("NL80211_CMD_GET_SCAN sent %d bytes to the kernel", ret);
+
+       /** Receive the kernel message. */
+       ret = nl_recvmsgs_default(global.socket);
+       nlmsg_free(global.msg);
+       if (ret < 0) {
+               DBG("nl_recvmsgs_default() failed. ret: %d (error: %s)", ret, nl_geterror(-ret));
+               wifi_complete_netlink_specific_scan(wifi, context);
+               return ret;
+       }
+
+       wifi_complete_netlink_specific_scan(wifi, context);
+       return 1;
 }
index d47a352..74e19f4 100755 (executable)
@@ -170,6 +170,8 @@ void wifi_object_create_and_init(void)
                        G_CALLBACK(handle_get_bssid_list), NULL);
        g_signal_connect(wifi_object, "handle-netlink-scan",
                        G_CALLBACK(handle_netlink_scan), NULL);
+       g_signal_connect(wifi_object, "handle-netlink-specific-scan",
+                       G_CALLBACK(handle_netlink_specific_scan), NULL);
 
        /* WPS Connect */
        g_signal_connect(wifi_object, "handle-request-wps-connect",