From: Pasi Sjöholm <[email protected]>
Due unknown reason sometimes scan_callback()-function is not being called
after the scan has been succesfully initiated.
This will lead into deadlock situation where device->scanning is
indefinitely true and will forbid any future attemps of scanning available
wifi networks.
The deadlock can be manually sorted out by commanding wpa_supplicant
to scan available networks. If any networks are available and one or
more of them being autoconnectable ConnMan will connect them after
receiving NetworkAdded-signal from wpa_supplicant. This will cause
autoscan-feature to stop and setting the device->scanning to false.
---
plugins/wifi.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 49 insertions(+), 1 deletion(-)
diff --git a/plugins/wifi.c b/plugins/wifi.c
index dfe849f..1e6507b 100644
--- a/plugins/wifi.c
+++ b/plugins/wifi.c
@@ -61,6 +61,7 @@
#define CLEANUP_TIMEOUT 8 /* in seconds */
#define INACTIVE_TIMEOUT 12 /* in seconds */
+#define SCAN_FAIL_TIMEOUT 60 /* in seconds */
#define FAVORITE_MAXIMUM_RETRIES 2
#define BGSCAN_DEFAULT "simple:30:-45:300"
@@ -131,6 +132,7 @@ struct wifi_data {
struct hidden_params *hidden;
bool postpone_hidden;
struct wifi_tethering_info *tethering_param;
+ unsigned int scan_fail_timeout;
/**
* autoscan "emulation".
*/
@@ -817,9 +819,25 @@ static void reset_autoscan(struct connman_device *device)
connman_device_unref(device);
}
+static gboolean scan_fail_timeout(gpointer data)
+{
+ struct connman_device *device = data;
+ struct wifi_data *wifi = connman_device_get_data(device);
+
+ DBG("");
+
+ if (!wifi)
+ return FALSE;
+
+ connman_device_set_scanning(device, CONNMAN_SERVICE_TYPE_WIFI, false);
+ wifi->scan_fail_timeout = 0;
+
+ return FALSE;
+}
+
static void stop_autoscan(struct connman_device *device)
{
- const struct wifi_data *wifi = connman_device_get_data(device);
+ struct wifi_data *wifi = connman_device_get_data(device);
if (!wifi || !wifi->autoscan)
return;
@@ -827,6 +845,11 @@ static void stop_autoscan(struct connman_device *device)
reset_autoscan(device);
connman_device_set_scanning(device, CONNMAN_SERVICE_TYPE_WIFI, false);
+
+ if (wifi->scan_fail_timeout) {
+ g_source_remove(wifi->scan_fail_timeout);
+ wifi->scan_fail_timeout = 0;
+ }
}
static void check_p2p_technology(void)
@@ -876,6 +899,10 @@ static void wifi_remove(struct connman_device *device)
if (wifi->p2p_connection_timeout)
g_source_remove(wifi->p2p_connection_timeout);
+ if (wifi->scan_fail_timeout) {
+ g_source_remove(wifi->scan_fail_timeout);
+ }
+
remove_networks(device, wifi);
connman_device_set_powered(device, false);
@@ -1193,6 +1220,11 @@ static int throw_wifi_scan(struct connman_device *device,
if (ret == 0) {
connman_device_set_scanning(device,
CONNMAN_SERVICE_TYPE_WIFI, true);
+
+ wifi->scan_fail_timeout = g_timeout_add_seconds(
+ SCAN_FAIL_TIMEOUT,
+ scan_fail_timeout,
+ device);
} else
connman_device_unref(device);
@@ -1262,6 +1294,11 @@ static void scan_callback(int result,
GSupplicantInterface *interface,
if (scanning) {
connman_device_set_scanning(device,
CONNMAN_SERVICE_TYPE_WIFI, false);
+
+ if (wifi && wifi->scan_fail_timeout) {
+ g_source_remove(wifi->scan_fail_timeout);
+ wifi->scan_fail_timeout = 0;
+ }
}
if (result != -ENOLINK)
@@ -1516,6 +1553,11 @@ static int wifi_disable(struct connman_device *device)
connman_device_unref(wifi->device);
}
+ if (wifi->scan_fail_timeout) {
+ g_source_remove(wifi->scan_fail_timeout);
+ wifi->scan_fail_timeout = 0;
+ }
+
/* In case of a user scan, device is still referenced */
if (connman_device_get_scanning(device)) {
connman_device_set_scanning(device,
@@ -1864,6 +1906,12 @@ static int wifi_scan(enum connman_service_type type,
if (ret == 0) {
connman_device_set_scanning(device,
CONNMAN_SERVICE_TYPE_WIFI, true);
+
+ wifi->scan_fail_timeout = g_timeout_add_seconds(
+ SCAN_FAIL_TIMEOUT,
+ scan_fail_timeout,
+ device);
+
} else {
g_supplicant_free_scan_params(scan_params);
connman_device_unref(device);
--
2.1.4
_______________________________________________
connman mailing list
[email protected]
https://lists.connman.net/mailman/listinfo/connman