wifi: fix scan list culling when no APs are found in a scan

Bug found by Gustavo Sverzut Barbieri <gustavo.barbieri@canonical.com>
This commit is contained in:
Dan Williams
2009-04-30 10:23:35 -04:00
parent 8067ec9334
commit 7082150fb1
3 changed files with 76 additions and 24 deletions

View File

@@ -114,15 +114,16 @@ typedef struct SupplicantStateTask {
} SupplicantStateTask;
typedef struct Supplicant {
NMSupplicantManager * mgr;
NMSupplicantInterface * iface;
NMSupplicantManager *mgr;
NMSupplicantInterface *iface;
/* signal handler ids */
guint mgr_state_id;
guint iface_error_id;
guint iface_state_id;
guint iface_scanned_ap_id;
guint iface_scan_result_id;
guint iface_scan_request_result_id;
guint iface_scan_results_id;
guint iface_con_state_id;
/* Timeouts and idles */
@@ -206,9 +207,13 @@ static void supplicant_iface_scanned_ap_cb (NMSupplicantInterface * iface,
GHashTable *properties,
NMDeviceWifi * self);
static void supplicant_iface_scan_result_cb (NMSupplicantInterface * iface,
gboolean result,
NMDeviceWifi * self);
static void supplicant_iface_scan_request_result_cb (NMSupplicantInterface * iface,
gboolean success,
NMDeviceWifi * self);
static void supplicant_iface_scan_results_cb (NMSupplicantInterface * iface,
guint32 num_bssids,
NMDeviceWifi * self);
static void supplicant_mgr_state_cb (NMSupplicantInterface * iface,
guint32 new_state,
@@ -217,6 +222,7 @@ static void supplicant_mgr_state_cb (NMSupplicantInterface * iface,
static guint32 nm_device_wifi_get_bitrate (NMDeviceWifi *self);
static void cull_scan_list (NMDeviceWifi *self);
static GQuark
nm_wifi_error_quark (void)
@@ -608,10 +614,16 @@ supplicant_interface_acquire (NMDeviceWifi *self)
priv->supplicant.iface_scanned_ap_id = id;
id = g_signal_connect (priv->supplicant.iface,
"scan-result",
G_CALLBACK (supplicant_iface_scan_result_cb),
"scan-req-result",
G_CALLBACK (supplicant_iface_scan_request_result_cb),
self);
priv->supplicant.iface_scan_result_id = id;
priv->supplicant.iface_scan_request_result_id = id;
id = g_signal_connect (priv->supplicant.iface,
"scan-results",
G_CALLBACK (supplicant_iface_scan_results_cb),
self);
priv->supplicant.iface_scan_results_id = id;
id = g_signal_connect (priv->supplicant.iface,
"connection-state",
@@ -695,9 +707,14 @@ supplicant_interface_release (NMDeviceWifi *self)
priv->supplicant.iface_scanned_ap_id = 0;
}
if (priv->supplicant.iface_scan_result_id > 0) {
g_signal_handler_disconnect (priv->supplicant.iface, priv->supplicant.iface_scan_result_id);
priv->supplicant.iface_scan_result_id = 0;
if (priv->supplicant.iface_scan_request_result_id > 0) {
g_signal_handler_disconnect (priv->supplicant.iface, priv->supplicant.iface_scan_request_result_id);
priv->supplicant.iface_scan_request_result_id = 0;
}
if (priv->supplicant.iface_scan_results_id > 0) {
g_signal_handler_disconnect (priv->supplicant.iface, priv->supplicant.iface_scan_results_id);
priv->supplicant.iface_scan_results_id = 0;
}
if (priv->supplicant.iface_con_state_id > 0) {
@@ -1847,14 +1864,27 @@ cancel_pending_scan (NMDeviceWifi *self)
static void
supplicant_iface_scan_result_cb (NMSupplicantInterface * iface,
gboolean result,
NMDeviceWifi * self)
supplicant_iface_scan_request_result_cb (NMSupplicantInterface *iface,
gboolean success,
NMDeviceWifi *self)
{
if (can_scan (self))
schedule_scan (self, TRUE);
}
static void
supplicant_iface_scan_results_cb (NMSupplicantInterface *iface,
guint32 num_results,
NMDeviceWifi *self)
{
if (num_results == 0) {
/* ensure that old APs get culled, which otherwise only
* happens when there are actual scan results to process.
*/
cull_scan_list (self);
}
}
static gboolean
is_encrypted (guint32 flags, guint32 wpa_flags, guint32 rsn_flags)
{

View File

@@ -76,7 +76,8 @@ enum {
STATE, /* change in the interface's state */
REMOVED, /* interface was removed by the supplicant */
SCANNED_AP, /* interface saw a new access point from a scan */
SCAN_RESULT, /* result of a wireless scan request */
SCAN_REQ_RESULT, /* result of a wireless scan request */
SCAN_RESULTS, /* scan results returned from supplicant */
CONNECTION_STATE, /* link state of the device's connection */
CONNECTION_ERROR, /* an error occurred during a connection request */
LAST_SIGNAL
@@ -422,15 +423,24 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass)
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1, G_TYPE_POINTER);
nm_supplicant_interface_signals[SCAN_RESULT] =
g_signal_new ("scan-result",
nm_supplicant_interface_signals[SCAN_REQ_RESULT] =
g_signal_new ("scan-req-result",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (NMSupplicantInterfaceClass, scan_result),
G_STRUCT_OFFSET (NMSupplicantInterfaceClass, scan_req_result),
NULL, NULL,
g_cclosure_marshal_VOID__BOOLEAN,
G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
nm_supplicant_interface_signals[SCAN_RESULTS] =
g_signal_new ("scan-results",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (NMSupplicantInterfaceClass, scan_results),
NULL, NULL,
g_cclosure_marshal_VOID__UINT,
G_TYPE_NONE, 1, G_TYPE_UINT);
nm_supplicant_interface_signals[CONNECTION_STATE] =
g_signal_new ("connection-state",
G_OBJECT_CLASS_TYPE (object_class),
@@ -529,9 +539,9 @@ scan_results_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
/* Notify listeners of the result of the scan */
g_signal_emit (info->interface,
nm_supplicant_interface_signals[SCAN_RESULT],
nm_supplicant_interface_signals[SCAN_RESULTS],
0,
TRUE);
array->len);
/* Fire off a "properties" call for each returned BSSID */
for (i = 0; i < array->len; i++) {
@@ -1213,7 +1223,7 @@ scan_request_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
/* Notify listeners of the result of the scan */
g_signal_emit (info->interface,
nm_supplicant_interface_signals[SCAN_RESULT],
nm_supplicant_interface_signals[SCAN_REQ_RESULT],
0,
success ? TRUE : FALSE);
}

View File

@@ -81,22 +81,34 @@ struct _NMSupplicantInterface {
typedef struct {
GObjectClass parent;
/* class members */
/* Signals */
/* change in the interface's state */
void (*state) (NMSupplicantInterface * iface,
guint32 new_state,
guint32 old_state);
/* interface was removed by the supplicant */
void (*removed) (NMSupplicantInterface * iface);
/* interface saw a new access point from a scan */
void (*scanned_ap) (NMSupplicantInterface * iface,
DBusMessage * message);
void (*scan_result) (NMSupplicantInterface * iface, gboolean result);
/* result of a wireless scan request */
void (*scan_req_result) (NMSupplicantInterface * iface,
gboolean success);
/* scan results returned from supplicant */
void (*scan_results) (NMSupplicantInterface * iface,
guint num_bssids);
/* link state of the device's connection */
void (*connection_state) (NMSupplicantInterface * iface,
guint32 new_state,
guint32 old_state);
/* an error occurred during a connection request */
void (*connection_error) (NMSupplicantInterface * iface,
const char * name,
const char * message);