diff options
author | Gary Ching-Pang Lin <chingpang@gmail.com> | 2012-06-05 11:19:41 +0800 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2012-06-07 15:06:48 -0500 |
commit | 5e3e19d02b4884a2cb8429ff384d28dbcd9e3feb (patch) | |
tree | dd8d5edbc88a99891880a6f752f24cd3467c2eb5 | |
parent | 59033928871c5d03f7a314eaffb75a6e991f718c (diff) | |
download | NetworkManager-5e3e19d02b4884a2cb8429ff384d28dbcd9e3feb.tar.gz |
wifi: add on-demand WiFi scan support
A new D-Bus method was added to invoke the on-demand WiFi scan.
-rw-r--r-- | TODO | 38 | ||||
-rw-r--r-- | introspection/nm-device-wifi.xml | 13 | ||||
-rw-r--r-- | src/nm-device-wifi.c | 60 |
3 files changed, 73 insertions, 38 deletions
@@ -53,44 +53,6 @@ provide Ad-Hoc connection sharing support for those devices and switch between Ad-Hoc and AP mode depending on device capabilities. -* On-Demand WiFi Scan support - -Single-user and embedded devices often use a continuous wifi scan when the -networking configuration interface is open to quickly allow users to find their -wifi network. NM periodically scans, but this could take as long as 2 mintues -to update the list. Note that WiFi scans require 2 - 10 seconds to complete, -and during this time normal traffic (video, VOIP, streaming music, downloads, -etc) is not transmitted, so a WiFi scan is a disruptive operation to the user. - -A D-Bus method should be added to the NMDeviceWifi device to allow user -applications to request a scan. This request should be rate-limited to no -more than once every 10 seconds to give time for traffic to resume when the -scan is done, and to lessen the effect of any DDoS by malicious user -applications. This request should also be restricted by one or more PolicyKit -permissions like org.freedesktop.NetworkManager.network-control. - -To begin, a new method definition should be added to the -introspection/nm-device-wifi.xml for a method called "RequestScan" which takes -an argument called "options" of type of "a{sv}". This argument will be used -later. An annotation (like the other functions have) should be added so that -the method will be called "impl_device_request_scan". - -Next, the corresponding method implementation should be added to -src/nm-device-wifi.c by adding the prototype for impl_device_request_scan -near the top of the file, and implementing it below. The implementation will -recieve a GHashTable corresponding to the "a{sv}" argument list from the XML -file, but we can ignore that for now. - -The incoming request should be authenticated using nm_auth_get_caller_uid() -and additionally starting a PolicyKit authentication check with -with nm_auth_chain_new(). See the function manager_device_disconnect_request() -in src/nm-manager.c for an example of this. - -Only after the caller is authorized to scan should the request be checked -against the last scan timestamp, and if the last scan was 10 seconds or more -ago, a new scan should be requested. - - * Reconnect to WiFi Networks Only If They Succeeded Once Currently, NetworkManager will attempt to connect to a previously attempted diff --git a/introspection/nm-device-wifi.xml b/introspection/nm-device-wifi.xml index fb50762438..531fc8930c 100644 --- a/introspection/nm-device-wifi.xml +++ b/introspection/nm-device-wifi.xml @@ -14,6 +14,19 @@ </tp:docstring> </method> + <method name="RequestScan"> + <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_device_request_scan"/> + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> + <arg name="options" type="a{sv}" direction="in"> + <tp:docstring> + Options of scan + </tp:docstring> + </arg> + <tp:docstring> + Request the device to scan + </tp:docstring> + </method> + <property name="HwAddress" type="s" access="read"> <tp:docstring> The active hardware address of the device. diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c index 55ecfdb2cc..15d4732d73 100644 --- a/src/nm-device-wifi.c +++ b/src/nm-device-wifi.c @@ -56,6 +56,7 @@ #include "nm-setting-ip4-config.h" #include "nm-setting-ip6-config.h" #include "nm-system.h" +#include "nm-manager-auth.h" #include "nm-settings-connection.h" #include "nm-enum-types.h" #include "wifi-utils.h" @@ -64,6 +65,10 @@ static gboolean impl_device_get_access_points (NMDeviceWifi *device, GPtrArray **aps, GError **err); +static void impl_device_request_scan (NMDeviceWifi *device, + GHashTable *options, + DBusGMethodInvocation *context); + #include "nm-device-wifi-glue.h" @@ -150,6 +155,8 @@ struct _NMDeviceWifiPrivate { guint periodic_source_id; guint link_timeout_id; + glong request_scan_time; + NMDeviceWifiCapabilities capabilities; }; @@ -191,6 +198,8 @@ static void supplicant_iface_notify_scanning_cb (NMSupplicantInterface * iface, static void schedule_scanlist_cull (NMDeviceWifi *self); +static gboolean request_wireless_scan (gpointer user_data); + /*****************************************************************/ #define NM_WIFI_ERROR (nm_wifi_error_quark ()) @@ -330,6 +339,8 @@ constructor (GType type, } priv->ipw_rfkill_state = nm_device_wifi_get_ipw_rfkill_state (self); + priv->request_scan_time = 0; + return object; } @@ -1441,6 +1452,55 @@ impl_device_get_access_points (NMDeviceWifi *self, return TRUE; } +static void +request_scan_cb (NMDevice *device, + DBusGMethodInvocation *context, + GError *error, + gpointer user_data) +{ + NMDeviceWifi *self = NM_DEVICE_WIFI (device); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + GTimeVal now; + + if (error) { + dbus_g_method_return_error (context, error); + g_clear_error (&error); + } else { + g_get_current_time (&now); + cancel_pending_scan (self); + request_wireless_scan (self); + priv->request_scan_time = now.tv_sec; + + dbus_g_method_return (context); + } +} + +static void +impl_device_request_scan (NMDeviceWifi *self, + GHashTable *options, + DBusGMethodInvocation *context) +{ + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + GTimeVal now; + + g_get_current_time (&now); + if (!priv->enabled || now.tv_sec - priv->request_scan_time < 10) { + dbus_g_method_return (context); + return; + } + + /* Ask the manager to authenticate this request for us */ + g_signal_emit_by_name (NM_DEVICE (self), + NM_DEVICE_AUTH_REQUEST, + context, + NM_AUTH_PERMISSION_NETWORK_CONTROL, + TRUE, + request_scan_cb, + NULL); + + return; +} + static gboolean scanning_allowed (NMDeviceWifi *self) { |