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; } SupplicantStateTask;
typedef struct Supplicant { typedef struct Supplicant {
NMSupplicantManager * mgr; NMSupplicantManager *mgr;
NMSupplicantInterface * iface; NMSupplicantInterface *iface;
/* signal handler ids */ /* signal handler ids */
guint mgr_state_id; guint mgr_state_id;
guint iface_error_id; guint iface_error_id;
guint iface_state_id; guint iface_state_id;
guint iface_scanned_ap_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; guint iface_con_state_id;
/* Timeouts and idles */ /* Timeouts and idles */
@@ -206,9 +207,13 @@ static void supplicant_iface_scanned_ap_cb (NMSupplicantInterface * iface,
GHashTable *properties, GHashTable *properties,
NMDeviceWifi * self); NMDeviceWifi * self);
static void supplicant_iface_scan_result_cb (NMSupplicantInterface * iface, static void supplicant_iface_scan_request_result_cb (NMSupplicantInterface * iface,
gboolean result, gboolean success,
NMDeviceWifi * self); NMDeviceWifi * self);
static void supplicant_iface_scan_results_cb (NMSupplicantInterface * iface,
guint32 num_bssids,
NMDeviceWifi * self);
static void supplicant_mgr_state_cb (NMSupplicantInterface * iface, static void supplicant_mgr_state_cb (NMSupplicantInterface * iface,
guint32 new_state, 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 guint32 nm_device_wifi_get_bitrate (NMDeviceWifi *self);
static void cull_scan_list (NMDeviceWifi *self);
static GQuark static GQuark
nm_wifi_error_quark (void) nm_wifi_error_quark (void)
@@ -608,10 +614,16 @@ supplicant_interface_acquire (NMDeviceWifi *self)
priv->supplicant.iface_scanned_ap_id = id; priv->supplicant.iface_scanned_ap_id = id;
id = g_signal_connect (priv->supplicant.iface, id = g_signal_connect (priv->supplicant.iface,
"scan-result", "scan-req-result",
G_CALLBACK (supplicant_iface_scan_result_cb), G_CALLBACK (supplicant_iface_scan_request_result_cb),
self); 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, id = g_signal_connect (priv->supplicant.iface,
"connection-state", "connection-state",
@@ -695,9 +707,14 @@ supplicant_interface_release (NMDeviceWifi *self)
priv->supplicant.iface_scanned_ap_id = 0; priv->supplicant.iface_scanned_ap_id = 0;
} }
if (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_result_id); g_signal_handler_disconnect (priv->supplicant.iface, priv->supplicant.iface_scan_request_result_id);
priv->supplicant.iface_scan_result_id = 0; 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) { if (priv->supplicant.iface_con_state_id > 0) {
@@ -1847,14 +1864,27 @@ cancel_pending_scan (NMDeviceWifi *self)
static void static void
supplicant_iface_scan_result_cb (NMSupplicantInterface * iface, supplicant_iface_scan_request_result_cb (NMSupplicantInterface *iface,
gboolean result, gboolean success,
NMDeviceWifi * self) NMDeviceWifi *self)
{ {
if (can_scan (self)) if (can_scan (self))
schedule_scan (self, TRUE); 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 static gboolean
is_encrypted (guint32 flags, guint32 wpa_flags, guint32 rsn_flags) is_encrypted (guint32 flags, guint32 wpa_flags, guint32 rsn_flags)
{ {

View File

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

View File

@@ -81,22 +81,34 @@ struct _NMSupplicantInterface {
typedef struct { typedef struct {
GObjectClass parent; GObjectClass parent;
/* class members */ /* Signals */
/* change in the interface's state */
void (*state) (NMSupplicantInterface * iface, void (*state) (NMSupplicantInterface * iface,
guint32 new_state, guint32 new_state,
guint32 old_state); guint32 old_state);
/* interface was removed by the supplicant */
void (*removed) (NMSupplicantInterface * iface); void (*removed) (NMSupplicantInterface * iface);
/* interface saw a new access point from a scan */
void (*scanned_ap) (NMSupplicantInterface * iface, void (*scanned_ap) (NMSupplicantInterface * iface,
DBusMessage * message); 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, void (*connection_state) (NMSupplicantInterface * iface,
guint32 new_state, guint32 new_state,
guint32 old_state); guint32 old_state);
/* an error occurred during a connection request */
void (*connection_error) (NMSupplicantInterface * iface, void (*connection_error) (NMSupplicantInterface * iface,
const char * name, const char * name,
const char * message); const char * message);