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