adapter: add DisableDiscoveryOnConnect option for combo chip coexistence
PATCH 1/1 adapter: add DisableDiscoveryOnConnect option for combo chip coexistence
From: Bastien Nocera <[email protected]>
On systems with combo chips (shared Wi-Fi/Bluetooth antenna), background LE scanning for auto-connect devices competes with active connections, causing audio stuttering and Wi-Fi packet loss due to antenna multiplexing via Packet Traffic Arbitration (PTA).
Add a DisableDiscoveryOnConnect boolean option to the [General] section of main.conf. When enabled and an active connection exists, the option suppresses adding devices to the kernel auto-connect list in adapter_auto_connect_add() on kernels supporting KERNEL_CONN_CONTROL, and gates trigger_passive_scanning() on older kernels.
The option defaults to false to preserve existing behavior.
--- client/mgmt.c | 4 ---- mesh/prov-initiator.c | 3 +-- src/adapter.c | 24 ++++++++++++++++++++++++ src/btd.h | 2 ++ src/device.c | 4 ---- src/gatt-database.c | 4 ---- src/main.c | 4 ++++ src/main.conf | 6 ++++++ src/shared/gatt-client.c | 8 -------- src/shared/gatt-helpers.c | 4 ---- src/shared/ringbuf.c | 4 ---- src/shared/uhid.c | 4 ---- src/shared/vcp.h | 8 -------- tools/advtest.c | 3 --- tools/btgatt-server.c | 4 ---- tools/hcitool.c | 4 ---- tools/parser/rfcomm.h | 2 -- 17 files changed, 37 insertions(+), 55 deletions(-)
client/mgmt.c +0 -4
@@ -67,10 +67,6 @@ static struct {static int pending_index =0 ; -#ifndef MIN -#define MIN (x, y) ((x) < (y) ? (x) : (y)) -#endif -static void mgmt_menu_pre_run (const struct bt_shell_menu *menu);#define PROMPT_ON COLOR_BLUE "[mgmt]" COLOR_OFF "> "
mesh/prov-initiator.c +1 -2
@@ -18,6 +18,7 @@#include "src/shared/ad.h" #include "src/shared/ecc.h" +#include "src/shared/util.h" #include "mesh/mesh-defs.h" #include "mesh/util.h"
@@ -34,8 +35,6 @@#include "mesh/agent.h" #include "mesh/error.h" -#define MIN (x, y) ((x) < (y) ? (x) : (y)) -/* Quick size sanity check */ static const uint16_t expected_pdu_size[] = {2 ,/* PROV_INVITE */
src/adapter.c +24 -0
@@ -1594,6 +1594,18 @@ static void trigger_passive_scanning(struct btd_adapter *adapter)if (!adapter->connect_list)return ; +/* +* If the user has enabled DisableDiscoveryOnConnect, suppress +* passive scanning whenever there is at least one active connection. +* This prevents antenna multiplexing conflicts on combo chips where +* Wi-Fi and Bluetooth share the same 2.4 GHz radio, which causes +* audio drops and Wi-Fi packet loss during background scans. +*/ +if (btd_opts.disable_discovery_on_connect && adapter->connections) { +DBG ("suppress passive scan: active connection present" ); +return ; + } + adapter->passive_scan_timeout =timeout_add_seconds (CONN_SCAN_TIMEOUT , passive_scanning_timeout, adapter,NULL );
@@ -5717,6 +5729,18 @@ void adapter_auto_connect_add(struct btd_adapter *adapter,return ; } +/* +* If DisableDiscoveryOnConnect is enabled, suppress adding devices +* to the kernel auto-connect list while an active connection exists. +* On combo chips (shared Wi-Fi/Bluetooth antenna), the kernel's +* background scanning for auto-connect devices competes with active +* connections, causing audio drops and Wi-Fi packet loss. +*/ +if (btd_opts.disable_discovery_on_connect && adapter->connections) { +DBG ("suppress kernel auto-connect: active connection present" ); +return ; + } + bdaddr =device_get_address (device); bdaddr_type =btd_device_get_bdaddr_type (device);
src/btd.h +2 -0
@@ -144,6 +144,8 @@ struct btd_opts {bool experimental;bool testing;bool filter_discoverable; +bool disable_discovery_on_connect; +struct queue *kernel;uint16_t did_source;
src/device.c +0 -4
@@ -72,10 +72,6 @@#define DISCOVERY_TIMER 1#define INVALID_FLAGS 0xff -#ifndef MIN -#define MIN (a, b) ((a) < (b) ? (a) : (b)) -#endif -#define RSSI_THRESHOLD 8#define AUTH_FAILURES_THRESHOLD 3
src/gatt-database.c +0 -4
@@ -54,10 +54,6 @@#define UUID_GATT 0x1801#define UUID_DIS 0x180a -#ifndef MIN -#define MIN (a, b) ((a) < (b) ? (a) : (b)) -#endif -struct gatt_record {struct btd_gatt_database *database;uint32_t handle;
src/main.c +4 -0
@@ -92,6 +92,7 @@ static const char *supported_options[] = {"KernelExperimental" ,"RemoteNameRequestRetryDelay" ,"FilterDiscoverable" , +"DisableDiscoveryOnConnect" , NULL };
@@ -1072,6 +1073,8 @@ static void parse_general(GKeyFile *config) 0, UINT32_MAX);parse_config_bool (config,"General" ,"FilterDiscoverable" , &btd_opts.filter_discoverable); +parse_config_bool (config,"General" ,"DisableDiscoveryOnConnect" , + &btd_opts.disable_discovery_on_connect); }static void parse_gatt_cache (GKeyFile *config)
@@ -1283,6 +1286,7 @@ static void init_defaults(void) btd_opts.name_request_retry_delay =DEFAULT_NAME_REQUEST_RETRY_DELAY ; btd_opts.secure_conn =SC_ON ; btd_opts.filter_discoverable = true; + btd_opts.disable_discovery_on_connect = false; btd_opts.defaults.num_entries =0 ; btd_opts.defaults.br.page_scan_type =0xFFFF ;
src/main.conf +6 -0
@@ -157,6 +157,12 @@ # some stacks) or when testing bad/unintended behavior. #FilterDiscoverable = true +# Disables background LE passive scanning when an active connection is +# established. Recommended for combo chips (shared Wi-Fi/Bluetooth antenna) +# to prevent audio stuttering and packet loss caused by antenna multiplexing. +# Defaults to false. +#DisableDiscoveryOnConnect = false + [BR] # The following values are used to load default adapter parameters for BR/EDR. # BlueZ loads the values into the kernel before the adapter is powered if the
src/shared/gatt-client.c +0 -8
@@ -25,14 +25,6 @@#include <limits.h> #include <sys/uio.h> -#ifndef MAX -#define MAX (a, b) ((a) > (b) ? (a) : (b)) -#endif - -#ifndef MIN -#define MIN (a, b) ((a) < (b) ? (a) : (b)) -#endif -#define UUID_BYTES (BT_GATT_UUID_SIZE * sizeof(uint8_t))#define GATT_SVC_UUID 0x1801
src/shared/gatt-helpers.c +0 -4
@@ -20,10 +20,6 @@#include "src/shared/gatt-helpers.h" #include "src/shared/util.h" -#ifndef MIN -#define MIN (a, b) ((a) < (b) ? (a) : (b)) -#endif -struct bt_gatt_result {uint8_t opcode;void *pdu;
src/shared/ringbuf.c +0 -4
@@ -21,10 +21,6 @@#include "src/shared/util.h" #include "src/shared/ringbuf.h" -#ifndef MIN -#define MIN (x,y) ((x)<(y)?(x):(y)) -#endif -struct ringbuf {void *buffer;size_t size;
src/shared/uhid.c +0 -4
@@ -26,10 +26,6 @@#define UHID_DEVICE_FILE "/dev/uhid" -#ifndef MIN -#define MIN (x, y) ((x) < (y) ? (x) : (y)) -#endif -struct uhid_replay {bool active;struct queue *out;
src/shared/vcp.h +0 -8
@@ -23,14 +23,6 @@#define BT_VCP_UNMUTE 0x05#define BT_VCP_MUTE 0x06 -#ifndef MAX -#define MAX (a, b) ((a) > (b) ? (a) : (b)) -#endif - -#ifndef MIN -#define MIN (a, b) ((a) < (b) ? (a) : (b)) -#endif -struct bt_vcp ;typedef void (*bt_vcp_destroy_func_t )(void *user_data);
tools/advtest.c +0 -3
@@ -39,9 +39,6 @@"\xe1\x23\x99\xc1\xca\x9a\xc3\x31" #define SCAN_IRK "\xfa\x73\x09\x11\x3f\x03\x37\x0f" \"\xf4\xf9\x93\x1e\xf9\xa3\x63\xa6" -#ifndef MIN -#define MIN (x, y) ((x) < (y) ? (x) : (y)) -#endif static struct mgmt *mgmt;static uint16_t index1 =MGMT_INDEX_NONE ;
tools/btgatt-server.c +0 -4
@@ -48,10 +48,6 @@print_prompt (); \ } while (0) -#ifndef MIN -#define MIN (a, b) ((a) < (b) ? (a) : (b)) -#endif -#define COLOR_OFF "\x1B[0m"#define COLOR_RED "\x1B[0;91m"#define COLOR_GREEN "\x1B[0;92m"
tools/hcitool.c +0 -4
@@ -34,10 +34,6 @@#include "src/oui.h" -#ifndef MIN -#define MIN (a, b) ((a) < (b) ? (a) : (b)) -#endif -/* Unofficial value, might still change */ #define LE_LINK 0x80
tools/parser/rfcomm.h +0 -2
@@ -33,8 +33,6 @@/* Returns the P/F-bit */ #define GET_PF (ctr) (((ctr) >> 4) & 0x1) -#define MIN (a, b) (((a) < (b)) ? (a) : (b)) -/* Endian-swapping macros for structs */ #define swap_long_frame (x) ((x)->h.length.val = le16_to_cpu((x)->h.length.val))#define swap_mcc_long_frame (x) (swap_long_frame(x))
Signature · 1 line
2.53.0
This is an automated email and please do not reply to this email.
Dear Submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
While preparing the CI tests, the patches you submitted couldn't be applied to the current HEAD of the repository.
----- Output -----
error: patch failed: client/mgmt.c:67
error: client/mgmt.c: patch does not apply
error: patch failed: mesh/prov-initiator.c:18
error: mesh/prov-initiator.c: patch does not apply
error: patch failed: src/device.c:72
error: src/device.c: patch does not apply
error: patch failed: src/gatt-database.c:54
error: src/gatt-database.c: patch does not apply
error: patch failed: src/shared/gatt-client.c:25
error: src/shared/gatt-client.c: patch does not apply
error: patch failed: src/shared/gatt-helpers.c:20
error: src/shared/gatt-helpers.c: patch does not apply
error: patch failed: src/shared/ringbuf.c:21
error: src/shared/ringbuf.c: patch does not apply
error: patch failed: src/shared/uhid.c:26
error: src/shared/uhid.c: patch does not apply
error: patch failed: src/shared/vcp.h:23
error: src/shared/vcp.h: patch does not apply
error: patch failed: tools/advtest.c:39
error: tools/advtest.c: patch does not apply
error: patch failed: tools/btgatt-server.c:48
error: tools/btgatt-server.c: patch does not apply
error: patch failed: tools/hcitool.c:34
error: tools/hcitool.c: patch does not apply
error: patch failed: tools/parser/rfcomm.h:33
error: tools/parser/rfcomm.h: patch does not apply
hint: Use 'git am --show-current-patch' to see the failed patch
Please resolve the issue and submit the patches again.
---
Regards,
Linux Bluetooth
Luiz Augusto von Dentz
maintainerHi,
Quoted 192 lines · StefanCondorache
From: Bastien Nocera <[email protected]>
On systems with combo chips (shared Wi-Fi/Bluetooth antenna), background LE scanning for auto-connect devices competes with active connections, causing audio stuttering and Wi-Fi packet loss due to antenna multiplexing via Packet Traffic Arbitration (PTA).
Add a DisableDiscoveryOnConnect boolean option to the [General] section of main.conf. When enabled and an active connection exists, the option suppresses adding devices to the kernel auto-connect list in
adapter_auto_connect_add()on kernels supportingKERNEL_CONN_CONTROL, and gatestrigger_passive_scanning()on older kernels.The option defaults to false to preserve existing behavior.
Signed-off-by StefanCondorache <[email protected]>--- client/mgmt.c | 4 ---- mesh/prov-initiator.c | 3 +-- src/adapter.c | 24 ++++++++++++++++++++++++ src/btd.h | 2 ++ src/device.c | 4 ---- src/gatt-database.c | 4 ---- src/main.c | 4 ++++ src/main.conf | 6 ++++++ src/shared/gatt-client.c | 8 -------- src/shared/gatt-helpers.c | 4 ---- src/shared/ringbuf.c | 4 ---- src/shared/uhid.c | 4 ---- src/shared/vcp.h | 8 -------- tools/advtest.c | 3 --- tools/btgatt-server.c | 4 ---- tools/hcitool.c | 4 ---- tools/parser/rfcomm.h | 2 -- 17 files changed, 37 insertions(+), 55 deletions(-)client/mgmt.c +0
-4@@ -67,10 +67,6 @@ static struct {static int pending_index =0 ; -#ifndef MIN -#define MIN (x, y) ((x) < (y) ? (x) : (y)) -#endif -static void mgmt_menu_pre_run (const struct bt_shell_menu *menu);#define PROMPT_ON COLOR_BLUE "[mgmt]" COLOR_OFF "> "mesh/prov-initiator.c +1
-2@@ -18,6 +18,7 @@#include "src/shared/ad.h" #include "src/shared/ecc.h" +#include "src/shared/util.h" #include "mesh/mesh-defs.h" #include "mesh/util.h" @@ -34,8 +35,6 @@#include "mesh/agent.h" #include "mesh/error.h" -#define MIN (x, y) ((x) < (y) ? (x) : (y)) -/* Quick size sanity check */ static const uint16_t expected_pdu_size[] = {2 ,/* PROV_INVITE */ src/adapter.c +24
-0@@ -1594,6 +1594,18 @@ static void trigger_passive_scanning(struct btd_adapter *adapter)if (!adapter->connect_list)return ; +/* +* If the user has enabled DisableDiscoveryOnConnect, suppress +* passive scanning whenever there is at least one active connection. +* This prevents antenna multiplexing conflicts on combo chips where +* Wi-Fi and Bluetooth share the same 2.4 GHz radio, which causes +* audio drops and Wi-Fi packet loss during background scans. +*/ +if (btd_opts.disable_discovery_on_connect && adapter->connections) { +DBG ("suppress passive scan: active connection present" ); +return ; + } + adapter->passive_scan_timeout =timeout_add_seconds (CONN_SCAN_TIMEOUT , passive_scanning_timeout, adapter,NULL );@@ -5717,6 +5729,18 @@ void adapter_auto_connect_add(struct btd_adapter *adapter,return ; } +/* +* If DisableDiscoveryOnConnect is enabled, suppress adding devices +* to the kernel auto-connect list while an active connection exists. +* On combo chips (shared Wi-Fi/Bluetooth antenna), the kernel's +* background scanning for auto-connect devices competes with active +* connections, causing audio drops and Wi-Fi packet loss. +*/ +if (btd_opts.disable_discovery_on_connect && adapter->connections) { +DBG ("suppress kernel auto-connect: active connection present" ); +return ; + } + bdaddr =device_get_address (device); bdaddr_type =btd_device_get_bdaddr_type (device);src/btd.h +2
-0@@ -144,6 +144,8 @@ struct btd_opts {bool experimental;bool testing;bool filter_discoverable; +bool disable_discovery_on_connect; +struct queue *kernel;uint16_t did_source;src/device.c +0
-4@@ -72,10 +72,6 @@#define DISCOVERY_TIMER 1#define INVALID_FLAGS 0xff -#ifndef MIN -#define MIN (a, b) ((a) < (b) ? (a) : (b)) -#endif -#define RSSI_THRESHOLD 8#define AUTH_FAILURES_THRESHOLD 3src/gatt-database.c +0
-4@@ -54,10 +54,6 @@#define UUID_GATT 0x1801#define UUID_DIS 0x180a -#ifndef MIN -#define MIN (a, b) ((a) < (b) ? (a) : (b)) -#endif -struct gatt_record {struct btd_gatt_database *database;uint32_t handle;src/main.c +4
-0@@ -92,6 +92,7 @@ static const char *supported_options[] = {"KernelExperimental" ,"RemoteNameRequestRetryDelay" ,"FilterDiscoverable" , +"DisableDiscoveryOnConnect" , NULL };@@ -1072,6 +1073,8 @@ static void parse_general(GKeyFile *config) 0, UINT32_MAX);parse_config_bool (config,"General" ,"FilterDiscoverable" , &btd_opts.filter_discoverable); +parse_config_bool (config,"General" ,"DisableDiscoveryOnConnect" , + &btd_opts.disable_discovery_on_connect); }static void parse_gatt_cache (GKeyFile *config)@@ -1283,6 +1286,7 @@ static void init_defaults(void) btd_opts.name_request_retry_delay =DEFAULT_NAME_REQUEST_RETRY_DELAY ; btd_opts.secure_conn =SC_ON ; btd_opts.filter_discoverable = true; + btd_opts.disable_discovery_on_connect = false; btd_opts.defaults.num_entries =0 ; btd_opts.defaults.br.page_scan_type =0xFFFF ;src/main.conf +0
-0
src/main.conf line 164
Quoted 8 lines
src/main.conf +5
-0@@ -157,6 +157,12 @@ # some stacks) or when testing bad/unintended behavior. #FilterDiscoverable = true +# Disables background LE passive scanning when an active connection is +# established. Recommended for combo chips (shared Wi-Fi/Bluetooth antenna) +# to prevent audio stuttering and packet loss caused by antenna multiplexing. +# Defaults to false. +#DisableDiscoveryOnConnect = false
Wrong place, wrong design. If the controller can't handle passive scanning and wants to disable it while connected, it really needs to do that at the driver level, not in userspace—possibly with a quirk. This is honestly a bad design at the controller side; since it controls passive scanning it should have managed coexistence with Wi-Fi. It really beats me how something like this reaches the market. Anyway, let's have the driver deal with the controller specific mess.
Quoted 146 lines
src/main.conf +0
-0[BR] # The following values are used to load default adapter parameters for BR/EDR. # BlueZ loads the values into the kernel before the adapter is powered if thesrc/shared/gatt-client.c +0
-8@@ -25,14 +25,6 @@#include <limits.h> #include <sys/uio.h> -#ifndef MAX -#define MAX (a, b) ((a) > (b) ? (a) : (b)) -#endif - -#ifndef MIN -#define MIN (a, b) ((a) < (b) ? (a) : (b)) -#endif -#define UUID_BYTES (BT_GATT_UUID_SIZE * sizeof(uint8_t))#define GATT_SVC_UUID 0x1801src/shared/gatt-helpers.c +0
-4@@ -20,10 +20,6 @@#include "src/shared/gatt-helpers.h" #include "src/shared/util.h" -#ifndef MIN -#define MIN (a, b) ((a) < (b) ? (a) : (b)) -#endif -struct bt_gatt_result {uint8_t opcode;void *pdu;src/shared/ringbuf.c +0
-4@@ -21,10 +21,6 @@#include "src/shared/util.h" #include "src/shared/ringbuf.h" -#ifndef MIN -#define MIN (x,y) ((x)<(y)?(x):(y)) -#endif -struct ringbuf {void *buffer;size_t size;src/shared/uhid.c +0
-4@@ -26,10 +26,6 @@#define UHID_DEVICE_FILE "/dev/uhid" -#ifndef MIN -#define MIN (x, y) ((x) < (y) ? (x) : (y)) -#endif -struct uhid_replay {bool active;struct queue *out;src/shared/vcp.h +0
-8@@ -23,14 +23,6 @@#define BT_VCP_UNMUTE 0x05#define BT_VCP_MUTE 0x06 -#ifndef MAX -#define MAX (a, b) ((a) > (b) ? (a) : (b)) -#endif - -#ifndef MIN -#define MIN (a, b) ((a) < (b) ? (a) : (b)) -#endif -struct bt_vcp ;typedef void (*bt_vcp_destroy_func_t )(void *user_data);tools/advtest.c +0
-3@@ -39,9 +39,6 @@"\xe1\x23\x99\xc1\xca\x9a\xc3\x31" #define SCAN_IRK "\xfa\x73\x09\x11\x3f\x03\x37\x0f" \"\xf4\xf9\x93\x1e\xf9\xa3\x63\xa6" -#ifndef MIN -#define MIN (x, y) ((x) < (y) ? (x) : (y)) -#endif static struct mgmt *mgmt;static uint16_t index1 =MGMT_INDEX_NONE ;tools/btgatt-server.c +0
-4@@ -48,10 +48,6 @@print_prompt (); \ } while (0) -#ifndef MIN -#define MIN (a, b) ((a) < (b) ? (a) : (b)) -#endif -#define COLOR_OFF "\x1B[0m"#define COLOR_RED "\x1B[0;91m"#define COLOR_GREEN "\x1B[0;92m"tools/hcitool.c +0
-4@@ -34,10 +34,6 @@#include "src/oui.h" -#ifndef MIN -#define MIN (a, b) ((a) < (b) ? (a) : (b)) -#endif -/* Unofficial value, might still change */ #define LE_LINK 0x80tools/parser/rfcomm.h +0
-3@@ -33,8 +33,6 @@/* Returns the P/F-bit */ #define GET_PF (ctr) (((ctr) >> 4) & 0x1) -#define MIN (a, b) (((a) < (b)) ? (a) : (b)) -/* Endian-swapping macros for structs */ #define swap_long_frame (x) ((x)->h.length.val = le16_to_cpu((x)->h.length.val))#define swap_mcc_long_frame (x) (swap_long_frame(x)) --2.53.0
Signature · 1 line
Luiz Augusto von Dentz