wifi: use supplicant's last_scan time for on-demand scan checking

And return errors when we refuse an on-demand scan.
This commit is contained in:
Dan Williams 2012-06-07 15:04:14 -05:00
parent c0131f767f
commit e9457176f5
4 changed files with 68 additions and 11 deletions

View file

@ -144,7 +144,6 @@ struct _NMDeviceWifiPrivate {
gboolean enabled; /* rfkilled or not */
time_t scheduled_scan_time;
time_t request_scan_time;
guint8 scan_interval; /* seconds */
guint pending_scan_id;
guint scanlist_cull_id;
@ -159,6 +158,8 @@ struct _NMDeviceWifiPrivate {
NMDeviceWifiCapabilities capabilities;
};
static gboolean check_scanning_allowed (NMDeviceWifi *self);
static void schedule_scan (NMDeviceWifi *self, gboolean backoff);
static void cancel_pending_scan (NMDeviceWifi *self);
@ -1456,16 +1457,19 @@ request_scan_cb (NMDevice *device,
gpointer user_data)
{
NMDeviceWifi *self = NM_DEVICE_WIFI (device);
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
if (error) {
dbus_g_method_return_error (context, error);
g_clear_error (&error);
} else if (!check_scanning_allowed (self)) {
error = g_error_new_literal (NM_WIFI_ERROR,
NM_WIFI_ERROR_SCAN_NOT_ALLOWED,
"Scanning not allowed at this time");
dbus_g_method_return_error (context, error);
g_error_free (error);
} else {
cancel_pending_scan (self);
request_wireless_scan (self);
priv->request_scan_time = time (NULL);
dbus_g_method_return (context);
}
}
@ -1476,22 +1480,48 @@ impl_device_request_scan (NMDeviceWifi *self,
DBusGMethodInvocation *context)
{
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
NMDevice *device = NM_DEVICE (self);
time_t last_scan;
GError *error;
if (!priv->enabled || (time (NULL) - priv->request_scan_time) < 10) {
dbus_g_method_return (context);
return;
if ( !priv->enabled
|| !priv->supplicant.iface
|| nm_device_get_state (device) < NM_DEVICE_STATE_DISCONNECTED
|| nm_device_is_activating (device)) {
error = g_error_new_literal (NM_WIFI_ERROR,
NM_WIFI_ERROR_SCAN_NOT_ALLOWED,
"Scanning not allowed while unavailable or activating");
goto error;
}
if (nm_supplicant_interface_get_scanning (priv->supplicant.iface)) {
error = g_error_new_literal (NM_WIFI_ERROR,
NM_WIFI_ERROR_SCAN_NOT_ALLOWED,
"Scanning not allowed while already scanning");
goto error;
}
last_scan = nm_supplicant_interface_get_last_scan_time (priv->supplicant.iface);
if ((time (NULL) - last_scan) < 10) {
error = g_error_new_literal (NM_WIFI_ERROR,
NM_WIFI_ERROR_SCAN_NOT_ALLOWED,
"Scanning not allowed immediately following previous scan");
goto error;
}
/* Ask the manager to authenticate this request for us */
g_signal_emit_by_name (NM_DEVICE (self),
g_signal_emit_by_name (device,
NM_DEVICE_AUTH_REQUEST,
context,
NM_AUTH_PERMISSION_NETWORK_CONTROL,
TRUE,
request_scan_cb,
NULL);
return;
error:
dbus_g_method_return_error (context, error);
g_error_free (error);
}
static gboolean

View file

@ -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_SCAN_NOT_ALLOWED, /*< nick=ScanNotAllowed >*/
} NMWifiError;
#define NM_DEVICE_WIFI_HW_ADDRESS "hw-address"

View file

@ -261,6 +261,10 @@ bss_properties_changed (DBusGProxy *proxy,
gpointer user_data)
{
NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
if (priv->scanning)
priv->last_scan = time (NULL);
if (g_strcmp0 (interface, WPAS_DBUS_IFACE_BSS) == 0)
g_signal_emit (self, signals[BSS_UPDATED], 0, dbus_g_proxy_get_path (proxy), props);
@ -272,6 +276,10 @@ old_bss_properties_changed (DBusGProxy *proxy,
gpointer user_data)
{
NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
if (priv->scanning)
priv->last_scan = time (NULL);
g_signal_emit (self, signals[BSS_UPDATED], 0, dbus_g_proxy_get_path (proxy), props);
}
@ -350,7 +358,13 @@ wpas_iface_bss_added (DBusGProxy *proxy,
GHashTable *props,
gpointer user_data)
{
handle_new_bss (NM_SUPPLICANT_INTERFACE (user_data), object_path, props);
NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
if (priv->scanning)
priv->last_scan = time (NULL);
handle_new_bss (self, object_path, props);
}
static void
@ -449,6 +463,11 @@ set_state (NMSupplicantInterface *self, guint32 new_state)
}
priv->state = new_state;
if ( priv->state == NM_SUPPLICANT_INTERFACE_STATE_SCANNING
|| old_state == NM_SUPPLICANT_INTERFACE_STATE_SCANNING)
priv->last_scan = time (NULL);
g_signal_emit (self, signals[STATE], 0, priv->state, old_state);
}
@ -494,6 +513,12 @@ nm_supplicant_interface_get_scanning (NMSupplicantInterface *self)
return FALSE;
}
time_t
nm_supplicant_interface_get_last_scan_time (NMSupplicantInterface *self)
{
return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->last_scan;
}
static void
wpas_iface_scan_done (DBusGProxy *proxy,
gboolean success,
@ -504,7 +529,6 @@ wpas_iface_scan_done (DBusGProxy *proxy,
/* Cache last scan completed time */
priv->last_scan = time (NULL);
g_signal_emit (self, signals[SCAN_DONE], 0, success);
}

View file

@ -136,6 +136,8 @@ const char *nm_supplicant_interface_state_to_string (guint32 state);
gboolean nm_supplicant_interface_get_scanning (NMSupplicantInterface *self);
time_t nm_supplicant_interface_get_last_scan_time (NMSupplicantInterface *self);
const char *nm_supplicant_interface_get_ifname (NMSupplicantInterface *self);
guint nm_supplicant_interface_get_max_scan_ssids (NMSupplicantInterface *self);