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

Reply via email to