2005-04-01 Dan Williams <dcbw@redhat.com>

Perform scans during device activation, if needed.  Both activation
	and scans run in the same GMainContext.  Therefore, if an access point
	is not found by the time the device starts activation, it will not
	be available until after activation.  We now try to scan during
	activation (in nm_wa_test) every 15s so that all available access
	points are more likely to be found and available for the activation
	procedure.

	Also change nm_wireless_link_state_handle() to only update the "best"
	AP if we are not forcing a device and if we are not about to change
	state.  This attempts to work around a race when forcing a device,
	where the forced AP would get cleared out too soon by the link state
	checking timeout in the main thread, and the activation attempt with
	that AP would fail.


git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@545 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams
2005-04-01 21:30:12 +00:00
parent 2dd3759d36
commit 04eadd092c
4 changed files with 82 additions and 14 deletions

View File

@@ -1,3 +1,20 @@
2005-04-01 Dan Williams <dcbw@redhat.com>
Perform scans during device activation, if needed. Both activation
and scans run in the same GMainContext. Therefore, if an access point
is not found by the time the device starts activation, it will not
be available until after activation. We now try to scan during
activation (in nm_wa_test) every 15s so that all available access
points are more likely to be found and available for the activation
procedure.
Also change nm_wireless_link_state_handle() to only update the "best"
AP if we are not forcing a device and if we are not about to change
state. This attempts to work around a race when forcing a device,
where the forced AP would get cleared out too soon by the link state
checking timeout in the main thread, and the activation attempt with
that AP would fail.
2005-04-01 Dan Williams <dcbw@redhat.com> 2005-04-01 Dan Williams <dcbw@redhat.com>
* po/POTFILES.in * po/POTFILES.in

View File

@@ -409,8 +409,12 @@ gboolean nm_poll_and_update_wireless_link_state (NMData *data)
if ( (dev == data->active_device) if ( (dev == data->active_device)
&& !nm_device_has_active_link (dev)) && !nm_device_has_active_link (dev))
{ {
if (nm_device_get_supports_wireless_scan (dev)) if ( nm_device_get_supports_wireless_scan (dev)
&& !data->forcing_device
&& data->state_modified_idle_id == 0)
{
nm_device_update_best_ap (dev); nm_device_update_best_ap (dev);
}
else else
{ {
if ( !nm_device_is_activating (dev) if ( !nm_device_is_activating (dev)

View File

@@ -57,6 +57,11 @@ typedef struct
struct wireless_scan_head scan_head; struct wireless_scan_head scan_head;
} NMWirelessScanResults; } NMWirelessScanResults;
typedef struct
{
NMDevice *dev;
gboolean reschedule;
} NMWirelessScanCB;
/******************************************************/ /******************************************************/
@@ -479,10 +484,15 @@ static gpointer nm_device_worker (gpointer user_data)
/* Start the scanning timeout for devices that can do scanning */ /* Start the scanning timeout for devices that can do scanning */
if (nm_device_is_wireless (dev) && nm_device_get_supports_wireless_scan (dev)) if (nm_device_is_wireless (dev) && nm_device_get_supports_wireless_scan (dev))
{ {
GSource *source = g_idle_source_new (); GSource *source = g_idle_source_new ();
guint source_id = 0; guint source_id = 0;
NMWirelessScanCB *scan_cb;
g_source_set_callback (source, nm_device_wireless_scan, dev, NULL); scan_cb = g_malloc0 (sizeof (NMWirelessScanCB));
scan_cb->dev = dev;
scan_cb->reschedule = TRUE;
g_source_set_callback (source, nm_device_wireless_scan, scan_cb, NULL);
source_id = g_source_attach (source, dev->context); source_id = g_source_attach (source, dev->context);
g_source_unref (source); g_source_unref (source);
} }
@@ -2304,6 +2314,25 @@ static gboolean nm_wa_test (int tries, va_list args)
*err = FALSE; *err = FALSE;
return TRUE; return TRUE;
} }
else
{
/* Since scanning runs in the device thread, we block scans
* during device activation. So we need to run a scan periodically
* during activation too.
*/
GTimeVal cur_time;
/* If the last scan was done more than 15s before, do another one. */
g_get_current_time (&cur_time);
if (cur_time.tv_sec >= dev->options.wireless.last_scan + 15)
{
NMWirelessScanCB *scan_cb = g_malloc0 (sizeof (NMWirelessScanCB));
scan_cb->dev = dev;
scan_cb->reschedule = FALSE;
nm_device_wireless_scan (scan_cb);
}
}
return FALSE; return FALSE;
} }
@@ -3452,14 +3481,19 @@ static void nm_device_fake_ap_list (NMDevice *dev)
*/ */
static void nm_device_wireless_schedule_scan (NMDevice *dev) static void nm_device_wireless_schedule_scan (NMDevice *dev)
{ {
GSource *wscan_source; GSource *wscan_source;
guint wscan_source_id; guint wscan_source_id;
NMWirelessScanCB *scan_cb;
g_return_if_fail (dev != NULL); g_return_if_fail (dev != NULL);
g_return_if_fail (nm_device_is_wireless (dev)); g_return_if_fail (nm_device_is_wireless (dev));
scan_cb = g_malloc0 (sizeof (NMWirelessScanCB));
scan_cb->dev = dev;
scan_cb->reschedule = TRUE;
wscan_source = g_timeout_source_new (dev->options.wireless.scan_interval * 1000); wscan_source = g_timeout_source_new (dev->options.wireless.scan_interval * 1000);
g_source_set_callback (wscan_source, nm_device_wireless_scan, dev, NULL); g_source_set_callback (wscan_source, nm_device_wireless_scan, scan_cb, NULL);
wscan_source_id = g_source_attach (wscan_source, dev->context); wscan_source_id = g_source_attach (wscan_source, dev->context);
g_source_unref (wscan_source); g_source_unref (wscan_source);
} }
@@ -3570,7 +3604,7 @@ static gboolean nm_device_wireless_process_scan_results (gpointer user_data)
{ {
/* Handle dbus signals that we need to broadcast when the AP is added to the list or changes /* Handle dbus signals that we need to broadcast when the AP is added to the list or changes
* strength. * strength.
*/ */
if (new) if (new)
{ {
nm_dbus_signal_wireless_network_change (dev->app_data->dbus_connection, dev, nm_ap, nm_dbus_signal_wireless_network_change (dev->app_data->dbus_connection, dev, nm_ap,
@@ -3689,12 +3723,19 @@ static gboolean nm_completion_scan_has_results (int tries, va_list args)
*/ */
static gboolean nm_device_wireless_scan (gpointer user_data) static gboolean nm_device_wireless_scan (gpointer user_data)
{ {
NMDevice *dev = (NMDevice *)(user_data); NMWirelessScanCB *scan_cb = (NMWirelessScanCB *)(user_data);
NMDevice *dev = NULL;
int sk; int sk;
NMWirelessScanResults *scan_results = NULL; NMWirelessScanResults *scan_results = NULL;
g_return_val_if_fail (dev != NULL, FALSE); g_return_val_if_fail (scan_cb != NULL, FALSE);
g_return_val_if_fail (dev->app_data != NULL, FALSE);
dev = scan_cb->dev;
if (!dev || !dev->app_data)
{
g_free (scan_cb);
return FALSE;
}
/* Just reschedule ourselves if scanning or all wireless is disabled */ /* Just reschedule ourselves if scanning or all wireless is disabled */
if ( (dev->app_data->scanning_enabled == FALSE) if ( (dev->app_data->scanning_enabled == FALSE)
@@ -3723,8 +3764,7 @@ static gboolean nm_device_wireless_scan (gpointer user_data)
if (devup_err) if (devup_err)
{ {
nm_unlock_mutex (dev->options.wireless.scan_mutex, __FUNCTION__); nm_unlock_mutex (dev->options.wireless.scan_mutex, __FUNCTION__);
nm_device_wireless_schedule_scan (dev); goto reschedule;
return FALSE;
} }
if ((sk = iw_sockets_open ()) >= 0) if ((sk = iw_sockets_open ()) >= 0)
@@ -3780,17 +3820,23 @@ static gboolean nm_device_wireless_scan (gpointer user_data)
{ {
guint scan_process_source_id = 0; guint scan_process_source_id = 0;
GSource *scan_process_source = g_idle_source_new (); GSource *scan_process_source = g_idle_source_new ();
GTimeVal cur_time;
scan_results->dev = dev; scan_results->dev = dev;
g_source_set_callback (scan_process_source, nm_device_wireless_process_scan_results, scan_results, NULL); g_source_set_callback (scan_process_source, nm_device_wireless_process_scan_results, scan_results, NULL);
scan_process_source_id = g_source_attach (scan_process_source, dev->app_data->main_context); scan_process_source_id = g_source_attach (scan_process_source, dev->app_data->main_context);
g_source_unref (scan_process_source); g_source_unref (scan_process_source);
g_get_current_time (&cur_time);
dev->options.wireless.last_scan = cur_time.tv_sec;
} }
reschedule: reschedule:
/* Make sure we reschedule ourselves so we keep scanning */ /* Make sure we reschedule ourselves so we keep scanning */
nm_device_wireless_schedule_scan (dev); if (scan_cb->reschedule)
nm_device_wireless_schedule_scan (dev);
g_free (scan_cb);
return FALSE; return FALSE;
} }

View File

@@ -49,6 +49,7 @@ typedef struct NMDeviceWirelessOptions
GMutex *scan_mutex; GMutex *scan_mutex;
NMAccessPointList *ap_list; NMAccessPointList *ap_list;
guint8 scan_interval; /* seconds */ guint8 scan_interval; /* seconds */
guint32 last_scan;
NMAccessPoint *best_ap; NMAccessPoint *best_ap;
GMutex *best_ap_mutex; GMutex *best_ap_mutex;