wifi: use supplicant's last_scan time for on-demand scan checking
authorDan Williams <dcbw@redhat.com>
Thu, 7 Jun 2012 20:04:14 +0000 (15:04 -0500)
committerDan Williams <dcbw@redhat.com>
Thu, 7 Jun 2012 20:06:48 +0000 (15:06 -0500)
And return errors when we refuse an on-demand scan.

src/nm-device-wifi.c
src/nm-device-wifi.h
src/supplicant-manager/nm-supplicant-interface.c
src/supplicant-manager/nm-supplicant-interface.h

index afc4f09..5fbbac7 100644 (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
+           || !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 (!priv->enabled || (time (NULL) - priv->request_scan_time) < 10) {
-               dbus_g_method_return (context);
-               return;
+       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
index 1e665fc..b22c78b 100644 (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"
index 208545a..cbe7032 100644 (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);
 }
 
index 77abec0..b99c0f2 100644 (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);