[PATCH] wifi: add the on-demand WiFi scan support
- From: Gary Ching-Pang Lin <chingpang gmail com>
- To: NetworkManager-list gnome org
- Subject: [PATCH] wifi: add the on-demand WiFi scan support
- Date: Mon, 28 May 2012 16:31:08 +0800
A new dbus method was added to request the wifi device to scan the
access points.
---
introspection/nm-device-wifi.xml | 13 ++++
src/nm-device-wifi.c | 130 ++++++++++++++++++++++++++++++++++++++
src/nm-device-wifi.h | 1 +
3 files changed, 144 insertions(+), 0 deletions(-)
diff --git a/introspection/nm-device-wifi.xml b/introspection/nm-device-wifi.xml
index fb50762..531fc89 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 ad1cfe3..417969e 100644
--- a/src/nm-device-wifi.c
+++ b/src/nm-device-wifi.c
@@ -45,6 +45,7 @@
#include "nm-marshal.h"
#include "NetworkManagerUtils.h"
#include "nm-activation-request.h"
+#include "nm-dbus-manager.h"
#include "nm-supplicant-manager.h"
#include "nm-supplicant-interface.h"
#include "nm-supplicant-config.h"
@@ -57,6 +58,7 @@
#include "nm-setting-ip6-config.h"
#include "nm-system.h"
#include "nm-settings-connection.h"
+#include "nm-manager-auth.h"
#include "nm-enum-types.h"
#include "wifi-utils.h"
@@ -64,6 +66,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 +156,10 @@ struct _NMDeviceWifiPrivate {
guint periodic_source_id;
guint link_timeout_id;
+ NMDBusManager * dbus_mgr;
+ GSList * auth_chains;
+ glong request_scan_time;
+
NMDeviceWifiCapabilities capabilities;
};
@@ -330,6 +340,12 @@ constructor (GType type,
}
priv->ipw_rfkill_state = nm_device_wifi_get_ipw_rfkill_state (self);
+ priv->dbus_mgr = nm_dbus_manager_get ();
+ g_assert (priv->dbus_mgr);
+
+ priv->auth_chains = NULL;
+ priv->request_scan_time = 0;
+
return object;
}
@@ -1441,6 +1457,112 @@ impl_device_get_access_points (NMDeviceWifi *self,
return TRUE;
}
+static GError *
+request_scan_check_error (GError *auth_error,
+ NMAuthCallResult result)
+{
+ if (auth_error) {
+ nm_log_dbg (LOGD_WIFI, "request scan failed: %s", auth_error->message);
+ return g_error_new (NM_WIFI_ERROR,
+ NM_WIFI_ERROR_PERMISSION_DENIED,
+ "request scan failed: %s",
+ auth_error->message);
+ } else if (result != NM_AUTH_CALL_RESULT_YES) {
+ return g_error_new (NM_WIFI_ERROR,
+ NM_WIFI_ERROR_PERMISSION_DENIED,
+ "Not authorized to request scan");
+ }
+ return NULL;
+}
+
+static void
+do_request_scan (NMAuthChain *chain,
+ GError *auth_error,
+ DBusGMethodInvocation *context,
+ gpointer user_data)
+
+{
+ NMDeviceWifi *self = NM_DEVICE_WIFI (user_data);
+ NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
+ NMAuthCallResult result;
+ GError *error = NULL;
+ GTimeVal now;
+
+ priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
+
+ result = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL));
+ error = request_scan_check_error (auth_error, result);
+ if (!error) {
+ 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);
+ } else {
+ dbus_g_method_return_error (context, error);
+ }
+
+ g_clear_error (&error);
+ nm_auth_chain_unref (chain);
+}
+
+static void
+impl_device_request_scan (NMDeviceWifi *self,
+ GHashTable *options,
+ DBusGMethodInvocation *context)
+{
+ NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
+ gulong sender_uid = G_MAXULONG;
+ char *error_desc = NULL;
+ GError *error = NULL;
+ NMAuthChain *chain;
+ GTimeVal now;
+
+ if (!priv->enabled)
+ return;
+
+ g_get_current_time (&now);
+ if (now.tv_sec - priv->request_scan_time < 10) {
+ dbus_g_method_return (context);
+ return;
+ }
+
+ /* Need to check the caller's permissions and stuff before we can
+ * start the scan.
+ */
+ if (!nm_auth_get_caller_uid (context,
+ priv->dbus_mgr,
+ &sender_uid,
+ &error_desc)) {
+ error = g_error_new_literal (NM_WIFI_ERROR,
+ NM_WIFI_ERROR_PERMISSION_DENIED,
+ error_desc);
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ g_free (error_desc);
+ return;
+ }
+
+ /* Yay for root */
+ if (0 == sender_uid) {
+ cancel_pending_scan (self);
+ request_wireless_scan (self);
+ priv->request_scan_time = now.tv_sec;
+ dbus_g_method_return (context);
+ return;
+ }
+
+ /* Otherwise validate the user request */
+ chain = nm_auth_chain_new (context, NULL, do_request_scan, self);
+ g_assert (chain);
+ priv->auth_chains = g_slist_append (priv->auth_chains, chain);
+
+ nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE);
+
+ return;
+}
+
static gboolean
scanning_allowed (NMDeviceWifi *self)
{
@@ -3399,6 +3521,14 @@ dispose (GObject *object)
priv->ipw_rfkill_id = 0;
}
+ g_slist_foreach (priv->auth_chains, (GFunc) nm_auth_chain_unref, NULL);
+ g_slist_free (priv->auth_chains);
+
+ if (priv->dbus_mgr) {
+ g_object_unref (priv->dbus_mgr);
+ priv->dbus_mgr = NULL;
+ }
+
G_OBJECT_CLASS (nm_device_wifi_parent_class)->dispose (object);
}
diff --git a/src/nm-device-wifi.h b/src/nm-device-wifi.h
index 1e665fc..1541121 100644
--- a/src/nm-device-wifi.h
+++ b/src/nm-device-wifi.h
@@ -46,6 +46,7 @@ typedef enum {
NM_WIFI_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/
NM_WIFI_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/
NM_WIFI_ERROR_ACCESS_POINT_NOT_FOUND, /*< nick=AccessPointNotFound >*/
+ NM_WIFI_ERROR_PERMISSION_DENIED, /*< nick=PermissionDenied >*/
} NMWifiError;
#define NM_DEVICE_WIFI_HW_ADDRESS "hw-address"
--
1.7.7
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]