Commit 5e3e19d0 authored by Gary Ching-Pang Lin's avatar Gary Ching-Pang Lin Committed by Dan Williams

wifi: add on-demand WiFi scan support

A new D-Bus method was added to invoke the on-demand WiFi scan.
parent 59033928
......@@ -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
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
......@@ -14,6 +14,19 @@
<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">
Options of scan
Request the device to scan
<property name="HwAddress" type="s" access="read">
The active hardware address of the device.
......@@ -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);
/* Ask the manager to authenticate this request for us */
g_signal_emit_by_name (NM_DEVICE (self),
static gboolean
scanning_allowed (NMDeviceWifi *self)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment