p***@jolla.com
2015-10-22 21:47:34 UTC
From: Pasi Sjöholm <***@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);
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
2.1.4