From: Pasi Sjöholm <pasi.sjoh...@jollamobile.com> Due unknown reason sometimes device->scanning is not set to false after wifi scanning (connman 1.30 and wpa_supplicant 2.5). This is probably due callback-function not being called after wifi scan and therefore it needs to have a timer to prevent deadlock. --- plugins/wifi.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-)
diff --git a/plugins/wifi.c b/plugins/wifi.c index dfe849f..35d4fe6 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 15 /* 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