public inbox for linux-bluetooth@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH BlueZ] src/adapter: add timeout for missing discovery
@ 2025-09-12 10:35 Andreas Glinserer
  2025-09-12 12:03 ` [BlueZ] " bluez.test.bot
  2025-09-12 14:15 ` [PATCH BlueZ] " Luiz Augusto von Dentz
  0 siblings, 2 replies; 4+ messages in thread
From: Andreas Glinserer @ 2025-09-12 10:35 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andreas Glinserer

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


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* RE: [BlueZ] src/adapter: add timeout for missing discovery
  2025-09-12 10:35 [PATCH BlueZ] src/adapter: add timeout for missing discovery Andreas Glinserer
@ 2025-09-12 12:03 ` bluez.test.bot
  2025-09-12 14:15 ` [PATCH BlueZ] " Luiz Augusto von Dentz
  1 sibling, 0 replies; 4+ messages in thread
From: bluez.test.bot @ 2025-09-12 12:03 UTC (permalink / raw)
  To: linux-bluetooth, andreas.glinserer

[-- Attachment #1: Type: text/plain, Size: 1262 bytes --]

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1001717

---Test result---

Test Summary:
CheckPatch                    PENDING   0.36 seconds
GitLint                       PENDING   0.39 seconds
BuildEll                      PASS      20.36 seconds
BluezMake                     PASS      2873.61 seconds
MakeCheck                     PASS      20.05 seconds
MakeDistcheck                 PASS      189.60 seconds
CheckValgrind                 PASS      241.75 seconds
CheckSmatch                   PASS      313.32 seconds
bluezmakeextell               PASS      131.99 seconds
IncrementalBuild              PENDING   0.34 seconds
ScanBuild                     PASS      946.39 seconds

Details
##############################
Test: CheckPatch - PENDING
Desc: Run checkpatch.pl script
Output:

##############################
Test: GitLint - PENDING
Desc: Run gitlint
Output:

##############################
Test: IncrementalBuild - PENDING
Desc: Incremental build with the patches in the series
Output:



---
Regards,
Linux Bluetooth


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH BlueZ] src/adapter: add timeout for missing discovery
  2025-09-12 10:35 [PATCH BlueZ] src/adapter: add timeout for missing discovery Andreas Glinserer
  2025-09-12 12:03 ` [BlueZ] " bluez.test.bot
@ 2025-09-12 14:15 ` Luiz Augusto von Dentz
  2025-09-12 15:43   ` Andreas Glinserer
  1 sibling, 1 reply; 4+ messages in thread
From: Luiz Augusto von Dentz @ 2025-09-12 14:15 UTC (permalink / raw)
  To: Andreas Glinserer; +Cc: linux-bluetooth

Hi Andreas,

On Fri, Sep 12, 2025 at 6:36 AM Andreas Glinserer
<andreas.glinserer@canonical.com> wrote:
>
> 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.

I'm not really sure how sending stop would make any difference?

>
> Link: https://github.com/bluez/bluez/issues/1554

The bug mentioned BlueZ version 1.72?, well I guess that is 4.72 which
is very old, have you tried with something more recent?

> ---
>  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
>
>


-- 
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH BlueZ] src/adapter: add timeout for missing discovery
  2025-09-12 14:15 ` [PATCH BlueZ] " Luiz Augusto von Dentz
@ 2025-09-12 15:43   ` Andreas Glinserer
  0 siblings, 0 replies; 4+ messages in thread
From: Andreas Glinserer @ 2025-09-12 15:43 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth

Hi Luiz,

On 9/12/25 16:15, Luiz Augusto von Dentz wrote:
> Hi Andreas,
> 
> On Fri, Sep 12, 2025 at 6:36 AM Andreas Glinserer
> <andreas.glinserer@canonical.com> wrote:
>>
>> 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.
> 
> I'm not really sure how sending stop would make any difference?
The correct technical reason I also do not understand. Sending the stop 
gets the controller out of the (presumably) faulty state and correctly 
starts rediscovering. To get to the bottom of this, I am missing more 
fundamental knowledge. My first assumption was, that just sending 
another start discovery would work, but this returned a busy. From this 
I concluded, that the controller is doing something and stuck at doing 
it. The next logical thing for me was stopping it by sending stop which 
is working and getting the controller back into a working event loop.

 From my testing I can see it is not a hardware specific issue. I had 
this issue on the following devices/bluetooth controller on different pcs:
- Intel Bluetooth 9460/9560 Jefferson Peak
- Mediatek 7925
- Intel BE200 usb device
> 
>>
>> Link: https://github.com/bluez/bluez/issues/1554
> 
> The bug mentioned BlueZ version 1.72?, well I guess that is 4.72 which
> is very old, have you tried with something more recent?
I am terribly sorry, version is 5.72 (Ubuntu 24.04). I also corrected it 
in the GH issue. I see this issue with 5.79 (Ubuntu 25.04) as well.
> 
>> ---
>>   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
>>
>>
> 
> 


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2025-09-12 15:43 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-12 10:35 [PATCH BlueZ] src/adapter: add timeout for missing discovery Andreas Glinserer
2025-09-12 12:03 ` [BlueZ] " bluez.test.bot
2025-09-12 14:15 ` [PATCH BlueZ] " Luiz Augusto von Dentz
2025-09-12 15:43   ` Andreas Glinserer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox