2008-02-29 Dan Williams <dcbw@redhat.com>

* src/nm-device-802-11-wireless.c
	  src/nm-device-802-11-wireless.h
		- (nm_device_802_11_wireless_reset_scan_interval): remove, unused
			elsewhere; fold into the sole user in nm-device-802-11-wireless.c
		- (device_cleanup): reset the scan interval lower when the device
			deactivates
		- (can_scan): base decision mostly off device state, not supplicant
			interface state since the supplicant interface state isn't a
			great indicator of whether the device is active or not
		- (request_wireless_scan): clean up; schedule the next scan here
		- (schedule_scan): only back the scan interval off if a new scan
			actually gets scheduled; and make scan intervals tighter when the
			device is disconnected
		- (supplicant_iface_state_cb_handler): fold in the bits of
			nm_device_802_11_wireless_reset_scan_interval() by resetting scan
			interval to minimum
		- (activation_success_handler): reset scan interval to something
			reasonable 



git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3365 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams
2008-02-29 16:33:59 +00:00
parent edcd32c443
commit 0bd48088c8
3 changed files with 98 additions and 59 deletions

View File

@@ -1,3 +1,24 @@
2008-02-29 Dan Williams <dcbw@redhat.com>
* src/nm-device-802-11-wireless.c
src/nm-device-802-11-wireless.h
- (nm_device_802_11_wireless_reset_scan_interval): remove, unused
elsewhere; fold into the sole user in nm-device-802-11-wireless.c
- (device_cleanup): reset the scan interval lower when the device
deactivates
- (can_scan): base decision mostly off device state, not supplicant
interface state since the supplicant interface state isn't a
great indicator of whether the device is active or not
- (request_wireless_scan): clean up; schedule the next scan here
- (schedule_scan): only back the scan interval off if a new scan
actually gets scheduled; and make scan intervals tighter when the
device is disconnected
- (supplicant_iface_state_cb_handler): fold in the bits of
nm_device_802_11_wireless_reset_scan_interval() by resetting scan
interval to minimum
- (activation_success_handler): reset scan interval to something
reasonable
2008-02-28 Saleem Abdulrasool <compnerd@compnerd.org> 2008-02-28 Saleem Abdulrasool <compnerd@compnerd.org>
reviewed by: Steev <steev@steev.net> reviewed by: Steev <steev@steev.net>

View File

@@ -148,7 +148,7 @@ struct _NMDevice80211WirelessPrivate
}; };
static void schedule_scan (NMDevice80211Wireless *self); static void schedule_scan (NMDevice80211Wireless *self, gboolean backoff);
static void cancel_pending_scan (NMDevice80211Wireless *self); static void cancel_pending_scan (NMDevice80211Wireless *self);
@@ -745,6 +745,8 @@ device_cleanup (NMDevice80211Wireless *self)
} }
cancel_pending_scan (self); cancel_pending_scan (self);
/* Reset the scan interval to be pretty frequent when disconnected */
priv->scan_interval = SCAN_INTERVAL_MIN + SCAN_INTERVAL_STEP;
cleanup_association_attempt (self, TRUE); cleanup_association_attempt (self, TRUE);
@@ -972,20 +974,6 @@ nm_device_802_11_wireless_can_activate (NMDevice80211Wireless * self)
return FALSE; return FALSE;
} }
void
nm_device_802_11_wireless_reset_scan_interval (NMDevice80211Wireless *self)
{
NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self);
g_return_if_fail (NM_IS_DEVICE_802_11_WIRELESS (self));
priv->scan_interval = SCAN_INTERVAL_MIN;
if (priv->pending_scan_id)
schedule_scan (self);
}
/* /*
* nm_device_get_mode * nm_device_get_mode
* *
@@ -1452,31 +1440,36 @@ static gboolean
can_scan (NMDevice80211Wireless *self) can_scan (NMDevice80211Wireless *self)
{ {
NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self); NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self);
guint32 state; guint32 sup_state;
gboolean scan = FALSE; NMDeviceState dev_state;
gboolean is_disconnected = FALSE;
state = nm_supplicant_interface_get_connection_state (priv->supplicant.iface); sup_state = nm_supplicant_interface_get_connection_state (priv->supplicant.iface);
dev_state = nm_device_get_state (NM_DEVICE (self));
if (priv->num_freqs >= 14) { is_disconnected = ( sup_state == NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED
/* A/B/G cards should only scan if they are disconnected. */ || sup_state == NM_SUPPLICANT_INTERFACE_CON_STATE_INACTIVE
if (state == NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED || || sup_state == NM_SUPPLICANT_INTERFACE_CON_STATE_SCANNING
state == NM_SUPPLICANT_INTERFACE_CON_STATE_INACTIVE) || dev_state == NM_DEVICE_STATE_UNKNOWN
scan = TRUE; || dev_state == NM_DEVICE_STATE_DOWN
} else if (state == NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED || || dev_state == NM_DEVICE_STATE_DISCONNECTED
state == NM_SUPPLICANT_INTERFACE_CON_STATE_INACTIVE || || dev_state == NM_DEVICE_STATE_FAILED
state == NM_SUPPLICANT_INTERFACE_CON_STATE_COMPLETED) || dev_state == NM_DEVICE_STATE_CANCELLED) ? TRUE : FALSE;
scan = TRUE;
return scan; /* All wireless devices can scan when disconnected */
} if (is_disconnected)
return TRUE;
static void /* Devices supporting only B/G frequencies can scan when disconnected
supplicant_iface_scan_result_cb (NMSupplicantInterface * iface, * and activated, but not when activating. We don't allow a/b/g devices to
gboolean result, * scan when activated, because there are just too many channels to scan and
NMDevice80211Wireless * self) * it takes too long to scan them, so users get angry when their SSH
{ * sessions lag.
if (can_scan (self)) */
schedule_scan (self); if ((priv->num_freqs <= 14) && (dev_state == NM_DEVICE_STATE_ACTIVATED))
return TRUE;
return FALSE;
} }
static gboolean static gboolean
@@ -1484,18 +1477,18 @@ request_wireless_scan (gpointer user_data)
{ {
NMDevice80211Wireless *self = NM_DEVICE_802_11_WIRELESS (user_data); NMDevice80211Wireless *self = NM_DEVICE_802_11_WIRELESS (user_data);
NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self); NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self);
gboolean success = TRUE; gboolean backoff = FALSE;
if (can_scan (self)) { if (can_scan (self)) {
// nm_debug ("Starting wireless scan for device %s.", if (nm_supplicant_interface_request_scan (priv->supplicant.iface)) {
// nm_device_get_iface (NM_DEVICE (user_data))); /* success */
backoff = TRUE;
success = nm_supplicant_interface_request_scan (priv->supplicant.iface); }
if (success)
priv->pending_scan_id = 0;
} }
return !success; priv->pending_scan_id = 0;
schedule_scan (self, backoff);
return FALSE;
} }
@@ -1506,25 +1499,37 @@ request_wireless_scan (gpointer user_data)
* *
*/ */
static void static void
schedule_scan (NMDevice80211Wireless *self) schedule_scan (NMDevice80211Wireless *self, gboolean backoff)
{ {
NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self); NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self);
GTimeVal current_time; GTimeVal now;
g_get_current_time (&current_time); g_get_current_time (&now);
/* Cancel the pending scan only if it would happen later than what is scheduled right now */ /* Cancel the pending scan if it would happen later than (now + the scan_interval) */
if (priv->pending_scan_id && (current_time.tv_sec + priv->scan_interval < priv->scheduled_scan_time)) if (priv->pending_scan_id) {
cancel_pending_scan (self); if (now.tv_sec + priv->scan_interval < priv->scheduled_scan_time)
cancel_pending_scan (self);
}
if (!priv->pending_scan_id) {
guint factor = 2;
if ( nm_device_is_activating (NM_DEVICE (self))
|| (nm_device_get_state (NM_DEVICE (self)) == NM_DEVICE_STATE_ACTIVATED))
factor = 1;
if (!priv->pending_scan_id)
priv->pending_scan_id = g_timeout_add (priv->scan_interval * 1000, priv->pending_scan_id = g_timeout_add (priv->scan_interval * 1000,
request_wireless_scan, request_wireless_scan,
self); self);
priv->scheduled_scan_time = current_time.tv_sec + priv->scan_interval; priv->scheduled_scan_time = now.tv_sec + priv->scan_interval;
if (priv->scan_interval < SCAN_INTERVAL_MAX) if (backoff && (priv->scan_interval < (SCAN_INTERVAL_MAX / factor))) {
priv->scan_interval += SCAN_INTERVAL_STEP; priv->scan_interval += (SCAN_INTERVAL_STEP / factor);
/* Ensure the scan interval will never be less than 20s... */
priv->scan_interval = MAX(priv->scan_interval, SCAN_INTERVAL_MIN + SCAN_INTERVAL_STEP);
}
}
} }
@@ -1540,6 +1545,15 @@ cancel_pending_scan (NMDevice80211Wireless *self)
} }
static void
supplicant_iface_scan_result_cb (NMSupplicantInterface * iface,
gboolean result,
NMDevice80211Wireless * self)
{
if (can_scan (self))
schedule_scan (self, TRUE);
}
static gboolean static gboolean
is_encrypted (guint32 flags, guint32 wpa_flags, guint32 rsn_flags) is_encrypted (guint32 flags, guint32 wpa_flags, guint32 rsn_flags)
{ {
@@ -1945,12 +1959,14 @@ supplicant_iface_state_cb_handler (gpointer user_data)
{ {
struct state_cb_data * cb_data = (struct state_cb_data *) user_data; struct state_cb_data * cb_data = (struct state_cb_data *) user_data;
NMDevice80211Wireless * self; NMDevice80211Wireless * self;
NMDevice80211WirelessPrivate *priv;
guint32 new_state, old_state; guint32 new_state, old_state;
g_return_val_if_fail (cb_data != NULL, FALSE); g_return_val_if_fail (cb_data != NULL, FALSE);
self = cb_data->self; self = cb_data->self;
new_state = cb_data->new_state; priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self);
new_state = cb_data->new_state;
old_state = cb_data->old_state; old_state = cb_data->old_state;
nm_info ("(%s) supplicant interface is now in state %d (from %d).", nm_info ("(%s) supplicant interface is now in state %d (from %d).",
@@ -1959,8 +1975,8 @@ supplicant_iface_state_cb_handler (gpointer user_data)
old_state); old_state);
if (new_state == NM_SUPPLICANT_INTERFACE_STATE_READY) { if (new_state == NM_SUPPLICANT_INTERFACE_STATE_READY) {
nm_device_802_11_wireless_reset_scan_interval (self); priv->scan_interval = SCAN_INTERVAL_MIN;
schedule_scan (self); schedule_scan (self, TRUE);
} else if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) { } else if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) {
cancel_pending_scan (self); cancel_pending_scan (self);
cleanup_association_attempt (self, FALSE); cleanup_association_attempt (self, FALSE);
@@ -2820,6 +2836,7 @@ static void
activation_success_handler (NMDevice *dev) activation_success_handler (NMDevice *dev)
{ {
NMDevice80211Wireless *self = NM_DEVICE_802_11_WIRELESS (dev); NMDevice80211Wireless *self = NM_DEVICE_802_11_WIRELESS (dev);
NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self);
NMAccessPoint *ap; NMAccessPoint *ap;
struct ether_addr bssid = { {0x0, 0x0, 0x0, 0x0, 0x0, 0x0} }; struct ether_addr bssid = { {0x0, 0x0, 0x0, 0x0, 0x0, 0x0} };
NMAccessPoint *tmp_ap; NMAccessPoint *tmp_ap;
@@ -2871,6 +2888,9 @@ activation_success_handler (NMDevice *dev)
done: done:
periodic_update (self); periodic_update (self);
/* Reset scan interval to something reasonable */
priv->scan_interval = SCAN_INTERVAL_MIN + (SCAN_INTERVAL_STEP * 2);
} }

View File

@@ -98,8 +98,6 @@ const GByteArray * nm_device_802_11_wireless_get_ssid (NMDevice80211Wireless *se
gboolean nm_device_802_11_wireless_set_mode (NMDevice80211Wireless *self, gboolean nm_device_802_11_wireless_set_mode (NMDevice80211Wireless *self,
const int mode); const int mode);
void nm_device_802_11_wireless_reset_scan_interval (NMDevice80211Wireless *dev);
int nm_device_802_11_wireless_get_mode (NMDevice80211Wireless *self); int nm_device_802_11_wireless_get_mode (NMDevice80211Wireless *self);
gboolean nm_device_802_11_wireless_can_activate (NMDevice80211Wireless * self); gboolean nm_device_802_11_wireless_can_activate (NMDevice80211Wireless * self);