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:
@@ -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)
|
||||||
{
|
{
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
|
Reference in New Issue
Block a user