[PATCH BlueZ] src/adapter: add timeout for missing discovery

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add a timeout to detect when the controller stops sending discovery
events. Without this, the system silently discovering new devices
and the scan list gradually empties due to DEFAULT_TEMPORARY_TIMEOUT.

When the timeout triggers, issue MGMT_OP_STOP_DISCOVERY to restart the
event loop and resume discovery.

Link: https://github.com/bluez/bluez/issues/1554
---
 src/adapter.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/src/adapter.c b/src/adapter.c
index dc5ba65d7..1ec665c73 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -342,6 +342,7 @@ struct btd_adapter {
 
 	struct queue *exp_pending;
 	struct queue *exps;
+	unsigned int last_discovery_timeout_id;		/* Timeout for discovery stop if no cb is coming */
 };
 
 static char *adapter_power_state_str(uint32_t power_state)
@@ -1727,6 +1728,11 @@ static void discovery_cleanup(struct btd_adapter *adapter, int timeout)
 		adapter->discovery_idle_timeout = 0;
 	}
 
+	if (adapter->last_discovery_timeout_id > 0) {
+		timeout_remove(adapter->last_discovery_timeout_id);
+		adapter->last_discovery_timeout_id = 0;
+	}
+
 	g_slist_free_full(adapter->discovery_found,
 						invalidate_rssi_and_tx_power);
 	adapter->discovery_found = NULL;
@@ -1833,6 +1839,8 @@ static struct discovery_client *discovery_complete(struct btd_adapter *adapter,
 	return client;
 }
 
+static bool time_since_last_discovery_cb(gpointer user_data);
+
 static void start_discovery_complete(uint8_t status, uint16_t length,
 					const void *param, void *user_data)
 {
@@ -1900,6 +1908,20 @@ static void start_discovery_complete(uint8_t status, uint16_t length,
 	trigger_start_discovery(adapter, IDLE_DISCOV_TIMEOUT * 2);
 }
 
+static bool time_since_last_discovery_cb(gpointer user_data)
+{
+	struct btd_adapter *adapter = user_data;
+	struct mgmt_cp_start_discovery cp;
+	DBG("");
+	cp.type =  get_scan_type(adapter);
+	
+	mgmt_send(adapter->mgmt, MGMT_OP_STOP_DISCOVERY,
+		adapter->dev_id, sizeof(cp), &cp,
+		NULL, NULL, NULL);
+
+	return FALSE;
+}
+
 static bool start_discovery_timeout(gpointer user_data)
 {
 	struct btd_adapter *adapter = user_data;
@@ -1909,6 +1931,9 @@ static bool start_discovery_timeout(gpointer user_data)
 	DBG("");
 
 	adapter->discovery_idle_timeout = 0;
+	adapter->last_discovery_timeout_id = timeout_add_seconds(
+		IDLE_DISCOV_TIMEOUT * 3, time_since_last_discovery_cb,
+		adapter, NULL);
 
 	/* If we're doing filtered discovery, it must be quickly restarted */
 	adapter->no_scan_restart_delay = !!adapter->current_discovery_filter;
@@ -2009,6 +2034,11 @@ static void trigger_start_discovery(struct btd_adapter *adapter, guint delay)
 	if (!btd_adapter_get_powered(adapter))
 		return;
 
+	if (adapter->last_discovery_timeout_id > 0) {
+		timeout_remove(adapter->last_discovery_timeout_id);
+		adapter->last_discovery_timeout_id = 0;
+	}
+
 	adapter->discovery_idle_timeout = timeout_add_seconds(delay,
 					start_discovery_timeout, adapter, NULL);
 }
@@ -2053,6 +2083,11 @@ static void suspend_discovery(struct btd_adapter *adapter)
 		adapter->discovery_idle_timeout = 0;
 	}
 
+	if (adapter->last_discovery_timeout_id > 0) {
+		timeout_remove(adapter->last_discovery_timeout_id);
+		adapter->last_discovery_timeout_id = 0;
+	}
+
 	if (adapter->discovery_enable == 0x00)
 		return;
 
-- 
2.43.0





[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux