From: Pasi Sjöholm <pasi.sjoh...@jollamobile.com> 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 connman@connman.net https://lists.connman.net/mailman/listinfo/connman