Linux bluetooth development
 help / color / mirror / Atom feed
* [RFC PATCH RESEND] asha: Defer BR/EDR inquiry while streaming
@ 2026-10-28 13:32 Kyle Pepper
  2026-10-28 16:24 ` [RFC,RESEND] " bluez.test.bot
  2026-11-07  1:49 ` [RFC PATCH v2] " Kyle Pepper
  0 siblings, 2 replies; 7+ messages in thread
From: Kyle Pepper @ 2026-10-28 13:32 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Marcel Holtmann, Luiz Augusto von Dentz

Defer BR/EDR discovery while ASHA streams are active on the adapter.
Keep client filters intact and leave LE discovery available.

Reject a new BR/EDR-only discovery request with Busy rather than
leaving its reply pending. Re-evaluate the scan type after START
completes, and leave suspended discovery suspended.

Assisted-by: OpenCode:gpt-6.1-sol
---
Resending unchanged after automated CI PR2668 expiry; no source changes.
Previous submission: https://lore.kernel.org/linux-bluetooth/20261013035348.525335-1-cochcoder@proton.me/
Earlier remote functional, lowercase checkpatch, Codacy Security Scan and
outer-CI failures remain unresolved. Historical local passes do not
establish remote success; no new hardware or functional test is claimed.

Submission review notes (not part of the commit message):
Local validation is for base 7428ca2df9356363079db0f48412c20cbdb9471f.
Compatibility with newer upstream tips has not been verified locally.
October 12 N8/UB500 capture 182750 has successful LE discovery during
streaming, 5342 audio SDUs, no in-stream Inquiry, and BR/EDR Inquiry after
STOP. This tests the combined package. Native MGMT acknowledgments,
cancellation, failure unwind and concurrent-client arbitration remain
review gates. A separate baseline SPA plugin crash occurs at daemon swap;
the capture does not establish the source-level cause of that crash.

 profiles/audio/asha.c |  30 ++++++++++-
 src/adapter.c         | 119 ++++++++++++++++++++++++++++++++++++++++--
 src/adapter.h         |   5 ++
 3 files changed, 147 insertions(+), 7 deletions(-)

diff --git a/profiles/audio/asha.c b/profiles/audio/asha.c
index 8e625fdca3..602da68da4 100644
--- a/profiles/audio/asha.c
+++ b/profiles/audio/asha.c
@@ -60,8 +60,26 @@ struct bt_asha_device {
 	uint16_t imtu, omtu;
 
 	unsigned int resume_id;
+	bool streaming_counted;
 };
 
+/*
+ * Count each device once so inquiry stays deferred until all streams stop.
+ */
+static void asha_set_streaming(struct bt_asha_device *asha_dev, bool streaming)
+{
+	if (streaming == asha_dev->streaming_counted)
+		return;
+
+	if (streaming)
+		btd_adapter_le_audio_ref(device_get_adapter(asha_dev->device));
+	else
+		btd_adapter_le_audio_unref(
+					device_get_adapter(asha_dev->device));
+
+	asha_dev->streaming_counted = streaming;
+}
+
 static char *make_endpoint_path(struct bt_asha_device *asha_dev)
 {
 	char *path;
@@ -91,6 +109,7 @@ static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
 
 	if (err) {
 		error("%s", err->message);
+		asha_set_streaming(asha_dev, false);
 		return;
 	}
 
@@ -171,12 +190,15 @@ unsigned int bt_asha_device_start(struct bt_asha_device *asha_dev,
 
 	if (ret < 0)
 		return 0;
-	else
-		return (++asha_dev->resume_id);
+
+	asha_set_streaming(asha_dev, true);
+	return (++asha_dev->resume_id);
 }
 
 unsigned int bt_asha_device_stop(struct bt_asha_device *asha_dev)
 {
+	asha_set_streaming(asha_dev, false);
+
 	bt_asha_stop(asha_dev->asha);
 
 	if (asha_dev->io) {
@@ -190,6 +212,8 @@ unsigned int bt_asha_device_stop(struct bt_asha_device *asha_dev)
 
 void bt_asha_device_state_reset(struct bt_asha_device *asha_dev)
 {
+	asha_set_streaming(asha_dev, false);
+
 	if (asha_dev->io) {
 		g_io_channel_shutdown(asha_dev->io, TRUE, NULL);
 		g_io_channel_unref(asha_dev->io);
@@ -371,6 +395,8 @@ static void asha_source_device_remove(struct btd_service *service)
 		return;
 	}
 
+	asha_set_streaming(asha_dev, false);
+
 	bt_asha_free(asha_dev->asha);
 	g_free(asha_dev);
 }
diff --git a/src/adapter.c b/src/adapter.c
index d3aa03fb70..28c58106dd 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -302,6 +302,7 @@ struct btd_adapter {
 					 * without delay */
 	uint8_t discovery_type;		/* current active discovery type */
 	uint8_t discovery_enable;	/* discovery enabled/disabled */
+	unsigned int le_audio_active;	/* Active ASHA streams */
 	bool discovery_suspended;	/* discovery has been suspended */
 	bool discovery_discoverable;	/* discoverable while discovering */
 	GSList *discovery_list;		/* list of discovery clients */
@@ -1833,6 +1834,8 @@ static void discovery_remove(struct discovery_client *client)
 }
 
 static void trigger_start_discovery(struct btd_adapter *adapter, guint delay);
+static int update_discovery_filter(struct btd_adapter *adapter);
+static uint8_t discovery_scan_type(struct btd_adapter *adapter, uint8_t type);
 
 static struct discovery_client *discovery_complete(struct btd_adapter *adapter,
 						uint8_t status)
@@ -1867,6 +1870,7 @@ static void start_discovery_complete(uint8_t status, uint16_t length,
 	struct btd_adapter *adapter = user_data;
 	struct discovery_client *client;
 	const struct mgmt_cp_start_discovery *rp = param;
+	uint8_t type;
 
 	DBG("status 0x%02x", status);
 
@@ -1911,6 +1915,16 @@ static void start_discovery_complete(uint8_t status, uint16_t length,
 
 		discovery_complete(adapter, status);
 
+		/* Audio or filters may change while START is pending. */
+		type = adapter->current_discovery_filter ?
+				adapter->current_discovery_filter->type :
+				get_scan_type(adapter);
+		type = discovery_scan_type(adapter, type);
+
+		if (!adapter->discovery_suspended &&
+						adapter->discovery_type != type)
+			trigger_start_discovery(adapter, 0);
+
 		if (adapter->discovering)
 			return;
 
@@ -1934,23 +1948,60 @@ static void start_discovery_complete(uint8_t status, uint16_t length,
 	trigger_start_discovery(adapter, IDLE_DISCOV_TIMEOUT * 2);
 }
 
+/*
+ * Defer BR/EDR discovery during ASHA streaming, leaving LE discovery available.
+ * A zero result means the client requested only BR/EDR discovery.
+ */
+static uint8_t discovery_scan_type(struct btd_adapter *adapter, uint8_t type)
+{
+	if ((type & SCAN_TYPE_BREDR) && btd_adapter_le_audio_active(adapter)) {
+		DBG("LE audio active: deferring BR/EDR inquiry");
+		type &= ~SCAN_TYPE_BREDR;
+	}
+
+	return type;
+}
+
+static void defer_discovery(struct btd_adapter *adapter)
+{
+	struct discovery_client *client;
+
+	/* Do not leave a new BR/EDR-only StartDiscovery call unanswered. */
+	client = discovery_complete(adapter, MGMT_STATUS_BUSY);
+	if (client) {
+		discovery_remove(client);
+
+		if (adapter->discovery_list)
+			update_discovery_filter(adapter);
+
+		return;
+	}
+
+	/* Keep accepted sessions until audio releases the adapter. */
+	trigger_start_discovery(adapter, IDLE_DISCOV_TIMEOUT);
+}
+
 static bool start_discovery_timeout(gpointer user_data)
 {
 	struct btd_adapter *adapter = user_data;
 	struct mgmt_cp_start_service_discovery *sd_cp;
+	size_t sd_len;
 	uint8_t new_type;
 
 	DBG("");
 
 	adapter->discovery_idle_timeout = 0;
 
+	if (!adapter->discovery_list || adapter->discovery_suspended)
+		return FALSE;
+
 	/* If we're doing filtered discovery, it must be quickly restarted */
 	adapter->no_scan_restart_delay = !!adapter->current_discovery_filter;
 
 	DBG("adapter->current_discovery_filter == %d",
 	    !!adapter->current_discovery_filter);
 
-	new_type = get_scan_type(adapter);
+	new_type = discovery_scan_type(adapter, get_scan_type(adapter));
 
 	if (adapter->discovery_enable == 0x01) {
 		struct mgmt_cp_stop_discovery cp;
@@ -1999,6 +2050,12 @@ static bool start_discovery_timeout(gpointer user_data)
 		struct mgmt_cp_start_discovery cp;
 
 		cp.type = new_type;
+
+		if (!cp.type) {
+			defer_discovery(adapter);
+			return FALSE;
+		}
+
 		mgmt_send(adapter->mgmt, MGMT_OP_START_DISCOVERY,
 					adapter->dev_id, sizeof(cp), &cp,
 					start_discovery_complete, adapter,
@@ -2007,18 +2064,32 @@ static bool start_discovery_timeout(gpointer user_data)
 		return FALSE;
 	}
 
-	/* Filtered discovery is required */
-	sd_cp = adapter->current_discovery_filter;
+	/* Filtered discovery is required. Keep the cached client filter intact;
+	 * it is needed to restore BR/EDR discovery after audio stops.
+	 */
+	sd_len = sizeof(*sd_cp) +
+		btohs(adapter->current_discovery_filter->uuid_count) * 16;
+	sd_cp = util_memdup(adapter->current_discovery_filter, sd_len);
+	if (!sd_cp)
+		return FALSE;
+
+	sd_cp->type = discovery_scan_type(adapter, sd_cp->type);
+	if (!sd_cp->type) {
+		free(sd_cp);
+		defer_discovery(adapter);
+		return FALSE;
+	}
 
 	DBG("sending MGMT_OP_START_SERVICE_DISCOVERY %d, %d, %d",
 				sd_cp->rssi, sd_cp->type,
 				btohs(sd_cp->uuid_count));
 
 	mgmt_send(adapter->mgmt, MGMT_OP_START_SERVICE_DISCOVERY,
-		  adapter->dev_id, sizeof(*sd_cp) +
-		  btohs(sd_cp->uuid_count) * 16,
+		  adapter->dev_id, sd_len,
 		  sd_cp, start_discovery_complete, adapter, NULL);
 
+	free(sd_cp);
+
 	return FALSE;
 }
 
@@ -6266,6 +6337,44 @@ struct btd_adapter *btd_adapter_ref(struct btd_adapter *adapter)
 	return adapter;
 }
 
+void btd_adapter_le_audio_ref(struct btd_adapter *adapter)
+{
+	if (!adapter)
+		return;
+
+	adapter->le_audio_active++;
+
+	/* First active stream: re-evaluate any running discovery so an
+	 * in-progress BR/EDR inquiry is dropped right away rather than only at
+	 * the next ~5 s re-arm.
+	 */
+	if (adapter->le_audio_active == 1 && adapter->discovery_list &&
+						!adapter->discovery_suspended) {
+		DBG("LE audio active: restarting discovery without BR/EDR");
+		trigger_start_discovery(adapter, 0);
+	}
+}
+
+void btd_adapter_le_audio_unref(struct btd_adapter *adapter)
+{
+	if (!adapter || !adapter->le_audio_active)
+		return;
+
+	adapter->le_audio_active--;
+
+	/* Restore requested discovery after the last stream stops. */
+	if (adapter->le_audio_active == 0 && adapter->discovery_list &&
+						!adapter->discovery_suspended) {
+		DBG("LE audio idle: restoring BR/EDR discovery");
+		trigger_start_discovery(adapter, 0);
+	}
+}
+
+bool btd_adapter_le_audio_active(struct btd_adapter *adapter)
+{
+	return adapter && adapter->le_audio_active > 0;
+}
+
 void btd_adapter_unref(struct btd_adapter *adapter)
 {
 	if (__sync_sub_and_fetch(&adapter->ref_count, 1))
diff --git a/src/adapter.h b/src/adapter.h
index 583168f4bc..6ad8fb096f 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -119,6 +119,11 @@ bool btd_adapter_uuid_is_allowed(struct btd_adapter *adapter, const char *uuid);
 struct btd_adapter *btd_adapter_ref(struct btd_adapter *adapter);
 void btd_adapter_unref(struct btd_adapter *adapter);
 
+/* Defer BR/EDR discovery while ASHA streams are active. */
+void btd_adapter_le_audio_ref(struct btd_adapter *adapter);
+void btd_adapter_le_audio_unref(struct btd_adapter *adapter);
+bool btd_adapter_le_audio_active(struct btd_adapter *adapter);
+
 void btd_adapter_set_class(struct btd_adapter *adapter, uint8_t major,
 							uint8_t minor);
 int btd_adapter_set_name(struct btd_adapter *adapter, const char *name);

base-commit: 7428ca2df9356363079db0f48412c20cbdb9471f


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

* RE: [RFC,RESEND] asha: Defer BR/EDR inquiry while streaming
  2026-10-28 13:32 [RFC PATCH RESEND] asha: Defer BR/EDR inquiry while streaming Kyle Pepper
@ 2026-10-28 16:24 ` bluez.test.bot
  2026-11-07  1:49 ` [RFC PATCH v2] " Kyle Pepper
  1 sibling, 0 replies; 7+ messages in thread
From: bluez.test.bot @ 2026-10-28 16:24 UTC (permalink / raw)
  To: linux-bluetooth, cochcoder

[-- Attachment #1: Type: text/plain, Size: 1022 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/series/1195453/

---Test result---

Test Summary:
CheckPatch                    PASS      0.68 seconds
GitLint                       PASS      0.35 seconds
BuildEll                      PASS      20.56 seconds
BluezMake                     PASS      306.64 seconds
MakeCheck                     PASS      2.86 seconds
MakeDistcheck                 PASS      145.73 seconds
CheckValgrind                 PASS      157.62 seconds
CheckSmatch                   PASS      300.51 seconds
bluezmakeextell               PASS      100.36 seconds
TestFunctional                PASS      1167.22 seconds
IncrementalBuild              PASS      308.60 seconds
ScanBuild                     PASS      1169.38 seconds



https://github.com/bluez/bluez/pull/2730

---
Regards,
Linux Bluetooth


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

* [RFC PATCH v2] asha: Defer BR/EDR inquiry while streaming
  2026-10-28 13:32 [RFC PATCH RESEND] asha: Defer BR/EDR inquiry while streaming Kyle Pepper
  2026-10-28 16:24 ` [RFC,RESEND] " bluez.test.bot
@ 2026-11-07  1:49 ` Kyle Pepper
  2026-11-07  2:32   ` [RFC,v2] " bluez.test.bot
  2026-11-07  2:47   ` [RFC PATCH v3] " Kyle Pepper
  1 sibling, 2 replies; 7+ messages in thread
From: Kyle Pepper @ 2026-11-07  1:49 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: marcel, luiz.dentz

Defer BR/EDR inquiry while ASHA streams are active. Keep LE discovery
available and preserve client filters for restoration after audio stops.
Return Busy if a new request leaves no permitted scan type. Recheck
pending discovery starts when audio changes.

Release the stream count when START cannot be queued or its callback
reports failure, so a failed acquisition cannot keep inquiry suppressed.

Assisted-by: OpenCode:gpt-6.1-sol
Assisted-by: Codex:gpt-6
---
v2: Consolidate scan selection and remove periodic polling. Release the
stream count on START queue and callback failures. Clarify Busy behavior.

Previous version:
https://lore.kernel.org/linux-bluetooth/20261028133243.262314-1-cochcoder@proton.me/

The resend passed all 12 archived CI checks. Local mocked tests exercise
discovery and START failures; native MGMT/client arbitration and isolated
hardware validation remain. Full local make check is blocked by an SDP
debug-symbol linker failure also reproduced on unchanged upstream.


 profiles/audio/asha.c | 46 +++++++++++++++++++++++---
 src/adapter.c         | 75 ++++++++++++++++++++++++++++++++++++++++---
 src/adapter.h         |  4 +++
 3 files changed, 116 insertions(+), 9 deletions(-)

diff --git a/profiles/audio/asha.c b/profiles/audio/asha.c
index 8e625fdca3..59a0247b37 100644
--- a/profiles/audio/asha.c
+++ b/profiles/audio/asha.c
@@ -60,8 +60,35 @@ struct bt_asha_device {
 	uint16_t imtu, omtu;
 
 	unsigned int resume_id;
+	bool streaming_counted;
+	bt_asha_cb_t start_cb;
+	void *start_cb_data;
 };
 
+static void asha_set_streaming(struct bt_asha_device *asha_dev, bool streaming)
+{
+	if (streaming == asha_dev->streaming_counted)
+		return;
+
+	if (streaming)
+		btd_adapter_le_audio_ref(device_get_adapter(asha_dev->device));
+	else
+		btd_adapter_le_audio_unref(device_get_adapter(asha_dev->device));
+
+	asha_dev->streaming_counted = streaming;
+}
+
+static void asha_start_cb(int status, void *user_data)
+{
+	struct bt_asha_device *asha_dev = user_data;
+
+	if (status)
+		asha_set_streaming(asha_dev, false);
+
+	if (asha_dev->start_cb)
+		asha_dev->start_cb(status, asha_dev->start_cb_data);
+}
+
 static char *make_endpoint_path(struct bt_asha_device *asha_dev)
 {
 	char *path;
@@ -91,6 +118,7 @@ static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
 
 	if (err) {
 		error("%s", err->message);
+		asha_set_streaming(asha_dev, false);
 		return;
 	}
 
@@ -107,8 +135,11 @@ static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
 
 	asha_dev->io = io;
 
-	bt_asha_start(asha_dev->asha, conn_data->cb,
-					conn_data->cb_user_data);
+	asha_dev->start_cb = conn_data->cb;
+	asha_dev->start_cb_data = conn_data->cb_user_data;
+
+	if (bt_asha_start(asha_dev->asha, asha_start_cb, asha_dev))
+		asha_set_streaming(asha_dev, false);
 }
 
 static int asha_connect_socket(struct bt_asha_device *asha_dev,
@@ -171,12 +202,15 @@ unsigned int bt_asha_device_start(struct bt_asha_device *asha_dev,
 
 	if (ret < 0)
 		return 0;
-	else
-		return (++asha_dev->resume_id);
+
+	asha_set_streaming(asha_dev, true);
+	return (++asha_dev->resume_id);
 }
 
 unsigned int bt_asha_device_stop(struct bt_asha_device *asha_dev)
 {
+	asha_set_streaming(asha_dev, false);
+
 	bt_asha_stop(asha_dev->asha);
 
 	if (asha_dev->io) {
@@ -190,6 +224,8 @@ unsigned int bt_asha_device_stop(struct bt_asha_device *asha_dev)
 
 void bt_asha_device_state_reset(struct bt_asha_device *asha_dev)
 {
+	asha_set_streaming(asha_dev, false);
+
 	if (asha_dev->io) {
 		g_io_channel_shutdown(asha_dev->io, TRUE, NULL);
 		g_io_channel_unref(asha_dev->io);
@@ -371,6 +407,8 @@ static void asha_source_device_remove(struct btd_service *service)
 		return;
 	}
 
+	asha_set_streaming(asha_dev, false);
+
 	bt_asha_free(asha_dev->asha);
 	g_free(asha_dev);
 }
diff --git a/src/adapter.c b/src/adapter.c
index 6588a6e2bd..74fdfb41c4 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -304,6 +304,7 @@ struct btd_adapter {
 					 * without delay */
 	uint8_t discovery_type;		/* current active discovery type */
 	uint8_t discovery_enable;	/* discovery enabled/disabled */
+	unsigned int le_audio_active;	/* Active ASHA streams */
 	bool discovery_suspended;	/* discovery has been suspended */
 	bool discovery_discoverable;	/* discoverable while discovering */
 	GSList *discovery_list;		/* list of discovery clients */
@@ -1886,6 +1887,8 @@ static void discovery_remove(struct discovery_client *client)
 }
 
 static void trigger_start_discovery(struct btd_adapter *adapter, guint delay);
+static int update_discovery_filter(struct btd_adapter *adapter);
+static uint8_t discovery_scan_type(struct btd_adapter *adapter);
 
 static struct discovery_client *discovery_complete(struct btd_adapter *adapter,
 						uint8_t status)
@@ -1964,6 +1967,11 @@ static void start_discovery_complete(uint8_t status, uint16_t length,
 
 		discovery_complete(adapter, status);
 
+		/* Audio or filters may change while START is pending. */
+		if (!adapter->discovery_suspended &&
+		    adapter->discovery_type != discovery_scan_type(adapter))
+			trigger_start_discovery(adapter, 0);
+
 		if (adapter->discovering)
 			return;
 
@@ -1987,23 +1995,39 @@ static void start_discovery_complete(uint8_t status, uint16_t length,
 	trigger_start_discovery(adapter, IDLE_DISCOV_TIMEOUT * 2);
 }
 
+static uint8_t discovery_scan_type(struct btd_adapter *adapter)
+{
+	uint8_t type = adapter->current_discovery_filter ?
+				adapter->current_discovery_filter->type :
+				get_scan_type(adapter);
+
+	if (adapter->le_audio_active)
+		type &= ~SCAN_TYPE_BREDR;
+
+	return type;
+}
+
 static bool start_discovery_timeout(gpointer user_data)
 {
 	struct btd_adapter *adapter = user_data;
 	struct mgmt_cp_start_service_discovery *sd_cp;
+	size_t sd_len;
 	uint8_t new_type;
 
 	DBG("");
 
 	adapter->discovery_idle_timeout = 0;
 
+	if (!adapter->discovery_list || adapter->discovery_suspended)
+		return FALSE;
+
 	/* If we're doing filtered discovery, it must be quickly restarted */
 	adapter->no_scan_restart_delay = !!adapter->current_discovery_filter;
 
 	DBG("adapter->current_discovery_filter == %d",
 	    !!adapter->current_discovery_filter);
 
-	new_type = get_scan_type(adapter);
+	new_type = discovery_scan_type(adapter);
 
 	if (adapter->discovery_enable == 0x01) {
 		struct mgmt_cp_stop_discovery cp;
@@ -2047,11 +2071,27 @@ static bool start_discovery_timeout(gpointer user_data)
 
 	}
 
+	if (!new_type) {
+		struct discovery_client *client;
+
+		/* Reject new requests; retain accepted sessions until audio stops. */
+		client = discovery_complete(adapter, MGMT_STATUS_BUSY);
+		if (client) {
+			discovery_remove(client);
+
+			if (adapter->discovery_list)
+				update_discovery_filter(adapter);
+		}
+
+		return FALSE;
+	}
+
 	/* Regular discovery is required */
 	if (!adapter->current_discovery_filter) {
 		struct mgmt_cp_start_discovery cp;
 
 		cp.type = new_type;
+
 		mgmt_send(adapter->mgmt, MGMT_OP_START_DISCOVERY,
 					adapter->dev_id, sizeof(cp), &cp,
 					start_discovery_complete, adapter,
@@ -2060,18 +2100,25 @@ static bool start_discovery_timeout(gpointer user_data)
 		return FALSE;
 	}
 
-	/* Filtered discovery is required */
-	sd_cp = adapter->current_discovery_filter;
+	/* Keep the requested filter intact for when audio stops. */
+	sd_len = sizeof(*sd_cp) +
+		btohs(adapter->current_discovery_filter->uuid_count) * 16;
+	sd_cp = util_memdup(adapter->current_discovery_filter, sd_len);
+	if (!sd_cp)
+		return FALSE;
+
+	sd_cp->type = new_type;
 
 	DBG("sending MGMT_OP_START_SERVICE_DISCOVERY %d, %d, %d",
 				sd_cp->rssi, sd_cp->type,
 				btohs(sd_cp->uuid_count));
 
 	mgmt_send(adapter->mgmt, MGMT_OP_START_SERVICE_DISCOVERY,
-		  adapter->dev_id, sizeof(*sd_cp) +
-		  btohs(sd_cp->uuid_count) * 16,
+		  adapter->dev_id, sd_len,
 		  sd_cp, start_discovery_complete, adapter, NULL);
 
+	free(sd_cp);
+
 	return FALSE;
 }
 
@@ -6358,6 +6405,24 @@ struct btd_adapter *btd_adapter_ref(struct btd_adapter *adapter)
 	return adapter;
 }
 
+void btd_adapter_le_audio_ref(struct btd_adapter *adapter)
+{
+	if (adapter->le_audio_active++)
+		return;
+
+	if (adapter->discovery_list && !adapter->discovery_suspended)
+		trigger_start_discovery(adapter, 0);
+}
+
+void btd_adapter_le_audio_unref(struct btd_adapter *adapter)
+{
+	if (!adapter->le_audio_active || --adapter->le_audio_active)
+		return;
+
+	if (adapter->discovery_list && !adapter->discovery_suspended)
+		trigger_start_discovery(adapter, 0);
+}
+
 void btd_adapter_unref(struct btd_adapter *adapter)
 {
 	if (__sync_sub_and_fetch(&adapter->ref_count, 1))
diff --git a/src/adapter.h b/src/adapter.h
index 583168f4bc..d5cda2d96b 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -119,6 +119,10 @@ bool btd_adapter_uuid_is_allowed(struct btd_adapter *adapter, const char *uuid);
 struct btd_adapter *btd_adapter_ref(struct btd_adapter *adapter);
 void btd_adapter_unref(struct btd_adapter *adapter);
 
+/* Defer BR/EDR discovery while ASHA streams are active. */
+void btd_adapter_le_audio_ref(struct btd_adapter *adapter);
+void btd_adapter_le_audio_unref(struct btd_adapter *adapter);
+
 void btd_adapter_set_class(struct btd_adapter *adapter, uint8_t major,
 							uint8_t minor);
 int btd_adapter_set_name(struct btd_adapter *adapter, const char *name);

base-commit: a8067198717b38391ca183ed7f41a69ec4b81b6e
-- 
2.56.0



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

* RE: [RFC,v2] asha: Defer BR/EDR inquiry while streaming
  2026-11-07  1:49 ` [RFC PATCH v2] " Kyle Pepper
@ 2026-11-07  2:32   ` bluez.test.bot
  2026-11-07  2:47   ` [RFC PATCH v3] " Kyle Pepper
  1 sibling, 0 replies; 7+ messages in thread
From: bluez.test.bot @ 2026-11-07  2:32 UTC (permalink / raw)
  To: linux-bluetooth, cochcoder

[-- Attachment #1: Type: text/plain, Size: 2138 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/series/1204674/

---Test result---

Test Summary:
CheckPatch                    FAIL      0.43 seconds
GitLint                       PASS      0.26 seconds
BuildEll                      PASS      13.16 seconds
BluezMake                     PASS      172.69 seconds
MakeCheck                     PASS      4.37 seconds
MakeDistcheck                 PASS      97.45 seconds
CheckValgrind                 PASS      99.01 seconds
CheckSmatch                   PASS      167.41 seconds
bluezmakeextell               PASS      63.27 seconds
TestFunctional                PASS      849.21 seconds
IncrementalBuild              PASS      171.57 seconds
ScanBuild                     PASS      583.59 seconds

Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
[RFC,v2] asha: Defer BR/EDR inquiry while streaming
WARNING:LONG_LINE: line length of 81 exceeds 80 columns
#134: FILE: profiles/audio/asha.c:76:
+		btd_adapter_le_audio_unref(device_get_adapter(asha_dev->device));

WARNING:LONG_LINE_COMMENT: line length of 86 exceeds 80 columns
#292: FILE: src/adapter.c:2077:
+		/* Reject new requests; retain accepted sessions until audio stops. */

/home/runner/work/bluez/bluez/src/patch/14959730.patch total: 0 errors, 2 warnings, 244 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
      mechanically convert to the typical style using --fix or --fix-inplace.

/home/runner/work/bluez/bluez/src/patch/14959730.patch has style problems, please review.

NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO

NOTE: If any of the errors are false positives, please report
      them to the maintainer, see CHECKPATCH in MAINTAINERS.




https://github.com/bluez/bluez/pull/2776

---
Regards,
Linux Bluetooth


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

* [RFC PATCH v3] asha: Defer BR/EDR inquiry while streaming
  2026-11-07  1:49 ` [RFC PATCH v2] " Kyle Pepper
  2026-11-07  2:32   ` [RFC,v2] " bluez.test.bot
@ 2026-11-07  2:47   ` Kyle Pepper
  2026-11-07  8:58     ` [RFC,v3] " bluez.test.bot
  2026-11-10 21:30     ` [RFC PATCH v3] " Luiz Augusto von Dentz
  1 sibling, 2 replies; 7+ messages in thread
From: Kyle Pepper @ 2026-11-07  2:47 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: marcel, luiz.dentz

Defer BR/EDR inquiry while ASHA streams are active. Keep LE discovery
available and preserve client filters for restoration after audio stops.
Return Busy if a new request leaves no permitted scan type. Recheck
pending discovery starts when audio changes.

Release the stream count when START cannot be queued or its callback
reports failure, so a failed acquisition cannot keep inquiry suppressed.

Assisted-by: OpenCode:gpt-6.1-sol
Assisted-by: Codex:gpt-6
---
v3: Wrap the unref call and shorten a comment to meet the
80-column limit. No behavior changes from v2.

Previous version:
https://lore.kernel.org/linux-bluetooth/20261107014841.1452698-1-cochcoder@proton.me/

v2 CI: CheckPatch failed on these two long lines; the other
11 checks passed. Native MGMT/client arbitration and isolated
hardware validation remain open.

 profiles/audio/asha.c | 47 ++++++++++++++++++++++++---
 src/adapter.c         | 75 ++++++++++++++++++++++++++++++++++++++++---
 src/adapter.h         |  4 +++
 3 files changed, 117 insertions(+), 9 deletions(-)

diff --git a/profiles/audio/asha.c b/profiles/audio/asha.c
index 8e625fdca3..d1fcddbcee 100644
--- a/profiles/audio/asha.c
+++ b/profiles/audio/asha.c
@@ -60,8 +60,36 @@ struct bt_asha_device {
 	uint16_t imtu, omtu;
 
 	unsigned int resume_id;
+	bool streaming_counted;
+	bt_asha_cb_t start_cb;
+	void *start_cb_data;
 };
 
+static void asha_set_streaming(struct bt_asha_device *asha_dev, bool streaming)
+{
+	if (streaming == asha_dev->streaming_counted)
+		return;
+
+	if (streaming)
+		btd_adapter_le_audio_ref(device_get_adapter(asha_dev->device));
+	else
+		btd_adapter_le_audio_unref(
+					device_get_adapter(asha_dev->device));
+
+	asha_dev->streaming_counted = streaming;
+}
+
+static void asha_start_cb(int status, void *user_data)
+{
+	struct bt_asha_device *asha_dev = user_data;
+
+	if (status)
+		asha_set_streaming(asha_dev, false);
+
+	if (asha_dev->start_cb)
+		asha_dev->start_cb(status, asha_dev->start_cb_data);
+}
+
 static char *make_endpoint_path(struct bt_asha_device *asha_dev)
 {
 	char *path;
@@ -91,6 +119,7 @@ static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
 
 	if (err) {
 		error("%s", err->message);
+		asha_set_streaming(asha_dev, false);
 		return;
 	}
 
@@ -107,8 +136,11 @@ static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
 
 	asha_dev->io = io;
 
-	bt_asha_start(asha_dev->asha, conn_data->cb,
-					conn_data->cb_user_data);
+	asha_dev->start_cb = conn_data->cb;
+	asha_dev->start_cb_data = conn_data->cb_user_data;
+
+	if (bt_asha_start(asha_dev->asha, asha_start_cb, asha_dev))
+		asha_set_streaming(asha_dev, false);
 }
 
 static int asha_connect_socket(struct bt_asha_device *asha_dev,
@@ -171,12 +203,15 @@ unsigned int bt_asha_device_start(struct bt_asha_device *asha_dev,
 
 	if (ret < 0)
 		return 0;
-	else
-		return (++asha_dev->resume_id);
+
+	asha_set_streaming(asha_dev, true);
+	return (++asha_dev->resume_id);
 }
 
 unsigned int bt_asha_device_stop(struct bt_asha_device *asha_dev)
 {
+	asha_set_streaming(asha_dev, false);
+
 	bt_asha_stop(asha_dev->asha);
 
 	if (asha_dev->io) {
@@ -190,6 +225,8 @@ unsigned int bt_asha_device_stop(struct bt_asha_device *asha_dev)
 
 void bt_asha_device_state_reset(struct bt_asha_device *asha_dev)
 {
+	asha_set_streaming(asha_dev, false);
+
 	if (asha_dev->io) {
 		g_io_channel_shutdown(asha_dev->io, TRUE, NULL);
 		g_io_channel_unref(asha_dev->io);
@@ -371,6 +408,8 @@ static void asha_source_device_remove(struct btd_service *service)
 		return;
 	}
 
+	asha_set_streaming(asha_dev, false);
+
 	bt_asha_free(asha_dev->asha);
 	g_free(asha_dev);
 }
diff --git a/src/adapter.c b/src/adapter.c
index 6588a6e2bd..16a0920923 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -304,6 +304,7 @@ struct btd_adapter {
 					 * without delay */
 	uint8_t discovery_type;		/* current active discovery type */
 	uint8_t discovery_enable;	/* discovery enabled/disabled */
+	unsigned int le_audio_active;	/* Active ASHA streams */
 	bool discovery_suspended;	/* discovery has been suspended */
 	bool discovery_discoverable;	/* discoverable while discovering */
 	GSList *discovery_list;		/* list of discovery clients */
@@ -1886,6 +1887,8 @@ static void discovery_remove(struct discovery_client *client)
 }
 
 static void trigger_start_discovery(struct btd_adapter *adapter, guint delay);
+static int update_discovery_filter(struct btd_adapter *adapter);
+static uint8_t discovery_scan_type(struct btd_adapter *adapter);
 
 static struct discovery_client *discovery_complete(struct btd_adapter *adapter,
 						uint8_t status)
@@ -1964,6 +1967,11 @@ static void start_discovery_complete(uint8_t status, uint16_t length,
 
 		discovery_complete(adapter, status);
 
+		/* Audio or filters may change while START is pending. */
+		if (!adapter->discovery_suspended &&
+		    adapter->discovery_type != discovery_scan_type(adapter))
+			trigger_start_discovery(adapter, 0);
+
 		if (adapter->discovering)
 			return;
 
@@ -1987,23 +1995,39 @@ static void start_discovery_complete(uint8_t status, uint16_t length,
 	trigger_start_discovery(adapter, IDLE_DISCOV_TIMEOUT * 2);
 }
 
+static uint8_t discovery_scan_type(struct btd_adapter *adapter)
+{
+	uint8_t type = adapter->current_discovery_filter ?
+				adapter->current_discovery_filter->type :
+				get_scan_type(adapter);
+
+	if (adapter->le_audio_active)
+		type &= ~SCAN_TYPE_BREDR;
+
+	return type;
+}
+
 static bool start_discovery_timeout(gpointer user_data)
 {
 	struct btd_adapter *adapter = user_data;
 	struct mgmt_cp_start_service_discovery *sd_cp;
+	size_t sd_len;
 	uint8_t new_type;
 
 	DBG("");
 
 	adapter->discovery_idle_timeout = 0;
 
+	if (!adapter->discovery_list || adapter->discovery_suspended)
+		return FALSE;
+
 	/* If we're doing filtered discovery, it must be quickly restarted */
 	adapter->no_scan_restart_delay = !!adapter->current_discovery_filter;
 
 	DBG("adapter->current_discovery_filter == %d",
 	    !!adapter->current_discovery_filter);
 
-	new_type = get_scan_type(adapter);
+	new_type = discovery_scan_type(adapter);
 
 	if (adapter->discovery_enable == 0x01) {
 		struct mgmt_cp_stop_discovery cp;
@@ -2047,11 +2071,27 @@ static bool start_discovery_timeout(gpointer user_data)
 
 	}
 
+	if (!new_type) {
+		struct discovery_client *client;
+
+		/* Reject new requests; keep sessions until audio stops. */
+		client = discovery_complete(adapter, MGMT_STATUS_BUSY);
+		if (client) {
+			discovery_remove(client);
+
+			if (adapter->discovery_list)
+				update_discovery_filter(adapter);
+		}
+
+		return FALSE;
+	}
+
 	/* Regular discovery is required */
 	if (!adapter->current_discovery_filter) {
 		struct mgmt_cp_start_discovery cp;
 
 		cp.type = new_type;
+
 		mgmt_send(adapter->mgmt, MGMT_OP_START_DISCOVERY,
 					adapter->dev_id, sizeof(cp), &cp,
 					start_discovery_complete, adapter,
@@ -2060,18 +2100,25 @@ static bool start_discovery_timeout(gpointer user_data)
 		return FALSE;
 	}
 
-	/* Filtered discovery is required */
-	sd_cp = adapter->current_discovery_filter;
+	/* Keep the requested filter intact for when audio stops. */
+	sd_len = sizeof(*sd_cp) +
+		btohs(adapter->current_discovery_filter->uuid_count) * 16;
+	sd_cp = util_memdup(adapter->current_discovery_filter, sd_len);
+	if (!sd_cp)
+		return FALSE;
+
+	sd_cp->type = new_type;
 
 	DBG("sending MGMT_OP_START_SERVICE_DISCOVERY %d, %d, %d",
 				sd_cp->rssi, sd_cp->type,
 				btohs(sd_cp->uuid_count));
 
 	mgmt_send(adapter->mgmt, MGMT_OP_START_SERVICE_DISCOVERY,
-		  adapter->dev_id, sizeof(*sd_cp) +
-		  btohs(sd_cp->uuid_count) * 16,
+		  adapter->dev_id, sd_len,
 		  sd_cp, start_discovery_complete, adapter, NULL);
 
+	free(sd_cp);
+
 	return FALSE;
 }
 
@@ -6358,6 +6405,24 @@ struct btd_adapter *btd_adapter_ref(struct btd_adapter *adapter)
 	return adapter;
 }
 
+void btd_adapter_le_audio_ref(struct btd_adapter *adapter)
+{
+	if (adapter->le_audio_active++)
+		return;
+
+	if (adapter->discovery_list && !adapter->discovery_suspended)
+		trigger_start_discovery(adapter, 0);
+}
+
+void btd_adapter_le_audio_unref(struct btd_adapter *adapter)
+{
+	if (!adapter->le_audio_active || --adapter->le_audio_active)
+		return;
+
+	if (adapter->discovery_list && !adapter->discovery_suspended)
+		trigger_start_discovery(adapter, 0);
+}
+
 void btd_adapter_unref(struct btd_adapter *adapter)
 {
 	if (__sync_sub_and_fetch(&adapter->ref_count, 1))
diff --git a/src/adapter.h b/src/adapter.h
index 583168f4bc..d5cda2d96b 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -119,6 +119,10 @@ bool btd_adapter_uuid_is_allowed(struct btd_adapter *adapter, const char *uuid);
 struct btd_adapter *btd_adapter_ref(struct btd_adapter *adapter);
 void btd_adapter_unref(struct btd_adapter *adapter);
 
+/* Defer BR/EDR discovery while ASHA streams are active. */
+void btd_adapter_le_audio_ref(struct btd_adapter *adapter);
+void btd_adapter_le_audio_unref(struct btd_adapter *adapter);
+
 void btd_adapter_set_class(struct btd_adapter *adapter, uint8_t major,
 							uint8_t minor);
 int btd_adapter_set_name(struct btd_adapter *adapter, const char *name);

base-commit: a8067198717b38391ca183ed7f41a69ec4b81b6e
-- 
2.56.0



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

* RE: [RFC,v3] asha: Defer BR/EDR inquiry while streaming
  2026-11-07  2:47   ` [RFC PATCH v3] " Kyle Pepper
@ 2026-11-07  8:58     ` bluez.test.bot
  2026-11-10 21:30     ` [RFC PATCH v3] " Luiz Augusto von Dentz
  1 sibling, 0 replies; 7+ messages in thread
From: bluez.test.bot @ 2026-11-07  8:58 UTC (permalink / raw)
  To: linux-bluetooth, cochcoder

[-- Attachment #1: Type: text/plain, Size: 55641 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/series/1204705/

---Test result---

Test Summary:
CheckPatch                    PASS      0.46 seconds
GitLint                       PASS      0.22 seconds
BuildEll                      PASS      20.53 seconds
BluezMake                     PASS      306.35 seconds
MakeCheck                     PASS      3.40 seconds
MakeDistcheck                 PASS      145.03 seconds
CheckValgrind                 PASS      157.60 seconds
CheckSmatch                   PASS      301.65 seconds
bluezmakeextell               PASS      99.84 seconds
TestFunctional                FAIL      1203.89 seconds
IncrementalBuild              PASS      314.36 seconds
ScanBuild                     PASS      1188.82 seconds

Details
##############################
Test: TestFunctional - FAIL
Desc: Run test-functional
Output:
FAIL functional.test_bearer::test_bearer_le_conn_update[hosts14-vm2]: failed on teardown with "pytest_bluezenv.plugin.CoredumpWarning: Core dump: test-bluezenv-hosts14.1-bluetoothd-1794040164-188.core
        /usr/bin/gdb: warning: Couldn't determine a path for the index cache directory.
        [New LWP 188]
        [Thread debugging using libthread_db enabled]
        Using host libthread_db library "/usr/lib/x86_64-linux-gnu/libthread_db.so.1".
        Core was generated by `/home/runner/work/bluez/bluez/src/src/src/bluetoothd --nodetach -f /run/bluetoo'.
        Program terminated with signal SIGABRT, Aborted.
        #0  __pthread_kill_implementation (threadid=<optimized out>, signo=6, no_tid=0) at ./nptl/pthread_kill.c:44

        warning: 44	./nptl/pthread_kill.c: No such file or directory

        Thread 1 (Thread 0x7fb9f854f900 (LWP 188)):
        #0  __pthread_kill_implementation (threadid=<optimized out>, signo=6, no_tid=0) at ./nptl/pthread_kill.c:44
                tid = <optimized out>
                ret = 0
                pd = <optimized out>
                old_mask = {__val = {4412750543122677053}}
                ret = <optimized out>
        #1  __pthread_kill_internal (threadid=<optimized out>, signo=6) at ./nptl/pthread_kill.c:89
        No locals.
        #2  __GI___pthread_kill (threadid=<optimized out>, signo=signo@entry=6) at ./nptl/pthread_kill.c:100
        No locals.
        #3  0x00007fb9f8caab7e in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
                ret = <optimized out>
        #4  0x00007fb9f8c8d8ec in __GI_abort () at ./stdlib/abort.c:77
                act = {__sigaction_handler = {sa_handler = 0x4, sa_sigaction = 0x4}, sa_mask = {__val = {136038628462384, 136038628462240, 17308540006477040896, 140728048536272, 140728048536560, 140728048536416, 22, 140436716612560, 0, 140728048536352, 140436733457942, 140436703768576, 4096, 0, 17308540006477040896, 140436707950616}}, sa_flags = -100835328, sa_restorer = 0x16}
        #5  0x00007fb9f98b5a0f in __sanitizer::Abort () at ../../../../src/libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cpp:165
        No locals.
        #6  0x00007fb9f99dbc2d in __sanitizer::Die () at ../../../../src/libsanitizer/sanitizer_common/sanitizer_termination.cpp:58
        No locals.
        #7  0x00007fb9f99b093c in __asan::ScopedInErrorReport::~ScopedInErrorReport (this=0x7ffdcd57cc96) at ../../../../src/libsanitizer/asan/asan_report.cpp:221
                buffer_copy = {buffer_ = {<__sanitizer::InternalMmapVectorNoCtor<char, false>> = {data_ = 0x7bb9f2818000 '=' <repeats 65 times>, "\n==188==ERROR: AddressSanitizer: heap-use-after-free on address 0x7cc9f79e1720 at pc 0x560b1288fa7d bp 0x7ffdcd57d910 sp 0x7ffdcd57d900"..., capacity_bytes_ = 8192, size_ = 4282}, <No data fields>}}
                buffer_copy = <optimized out>
                l = <optimized out>
        #8  0x00007fb9f99afe02 in __asan::ReportGenericError (pc=94605555595901, bp=140728048539920, sp=sp@entry=140728048539904, addr=137206884603680, is_write=is_write@entry=false, access_size=8, fatal=true, exp=<optimized out>) at ../../../../src/libsanitizer/asan/asan_report.cpp:536
                in_report = {error_report_lock_ = {<No data fields>}, static current_error_ = {kind = __asan::kErrorKindGeneric, {Base = {scariness = {score = 51, descr = "8-byte-read-heap-use-after-free\000\271\177\000\000\305\274\233\371\271\177\000\000\340~\236\367\031|\000\000:\000\000\000\000\000\000\000\300~\236\367\031|\000\000\320~\236\367\031|\000\000\200\315W\315\375\177\000\000\005\034\220\371\271\177\000\000\320\315W\315\375\177\000\000\000\220\031\370\271\177\000\000\001\000\000\000\000\000\000\000\001\000\000\000\v\000\001\001\000\000\000\000\000\000\000\000\370\377\377\377\377\377\377\377\032\177\236\367\031|\000\000\300\315W\315\375\177\000\000\001\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\330\314\375\177\000\000:\000\000\000\000\000\000\000 5\177\366\271{\000\0009\000\000\000"...}, tid = 0}, DeadlySignal = {<__asan::ErrorBase> = {scariness = {score = 51, descr = "8-byte-read-heap-use-after-free\000\271\177\000\000\305\274\233\371\271\177\000\000\340~\236\367\031|\000\000:\000\000\000\000\000\000\000\300~\236\367\031|\000\000\320~\236\367\031|\000\000\200\315W\315\375\177\000\000\005\034\220\371\271\177\000\000\320\315W\315\375\177\000\000\000\220\031\370\271\177\000\000\001\000\000\000\000\000\000\000\001\000\000\000\v\000\001\001\000\000\000\000\000\000\000\000\370\377\377\377\377\377\377\377\032\177\236\367\031|\000\000\300\315W\315\375\177\000\000\001\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\330\314\375\177\000\000:\000\000\000\000\000\000\000 5\177\366\271{\000\0009\000\000\000"...}, tid = 0}, signal = {siginfo = 0xf034496e00000002, context = 0x7cc9f79e1720, addr = 0, pc = 0, sp = 6116033429960, bp = 137206884603680, is_memory_access = 96, write_flag = __sanitizer::SignalContext::Unknown, is_true_faulting_addr = 192}}, DoubleFree = {<__asan::ErrorBase> = {scariness = {score = 51, descr = "8-byte-read-heap-use-after-free\000\271\177\000\000\305\274\233\371\271\177\000\000\340~\236\367\031|\000\000:\000\000\000\000\000\000\000\300~\236\367\031|\000\000\320~\236\367\031|\000\000\200\315W\315\375\177\000\000\005\034\220\371\271\177\000\000\320\315W\315\375\177\000\000\000\220\031\370\271\177\000\000\001\000\000\000\000\000\000\000\001\000\000\000\v\000\001\001\000\000\000\000\000\000\000\000\370\377\377\377\377\377\377\377\032\177\236\367\031|\000\000\300\315W\315\375\177\000\000\001\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\330\314\375\177\000\000:\000\000\000\000\000\000\000 5\177\366\271{\000\0009\000\000\000"...}, tid = 0}, second_free_stack = 0xf034496e00000002, addr_description = {addr = 137206884603680, alloc_tid = 0, free_tid = 0, alloc_stack_id = 456, free_stack_id = 1424, chunk_access = {bad_addr = 137206884603680, offset = 96, chunk_begin = 137206884603584, chunk_size = 232, user_requested_alignment = 8, access_type = 2, alloc_type = 1}}}, NewDeleteTypeMismatch = {<__asan::ErrorBase> = {scariness = {score = 51, descr = "8-byte-read-heap-use-after-free\000\271\177\000\000\305\274\233\371\271\177\000\000\340~\236\367\031|\000\000:\000\000\000\000\000\000\000\300~\236\367\031|\000\000\320~\236\367\031|\000\000\200\315W\315\375\177\000\000\005\034\220\371\271\177\000\000\320\315W\315\375\177\000\000\000\220\031\370\271\177\000\000\001\000\000\000\000\000\000\000\001\000\000\000\v\000\001\001\000\000\000\000\000\000\000\000\370\377\377\377\377\377\377\377\032\177\236\367\031|\000\000\300\315W\315\375\177\000\000\001\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\330\314\375\177\000\000:\000\000\000\000\000\000\000 5\177\366\271{\000\0009\000\000\000"...}, tid = 0}, free_stack = 0xf034496e00000002, addr_description = {addr = 137206884603680, alloc_tid = 0, free_tid = 0, alloc_stack_id = 456, free_stack_id = 1424, chunk_access = {bad_addr = 137206884603680, offset = 96, chunk_begin = 137206884603584, chunk_size = 232, user_requested_alignment = 8, access_type = 2, alloc_type = 1}}, delete_size = 140436705401120, delete_alignment = 140728048538016}, FreeNotMalloced = {<__asan::ErrorBase> = {scariness = {score = 51, descr = "8-byte-read-heap-use-after-free\000\271\177\000\000\305\274\233\371\271\177\000\000\340~\236\367\031|\000\000:\000\000\000\000\000\000\000\300~\236\367\031|\000\000\320~\236\367\031|\000\000\200\315W\315\375\177\000\000\005\034\220\371\271\177\000\000\320\315W\315\375\177\000\000\000\220\031\370\271\177\000\000\001\000\000\000\000\000\000\000\001\000\000\000\v\000\001\001\000\000\000\000\000\000\000\000\370\377\377\377\377\377\377\377\032\177\236\367\031|\000\000\300\315W\315\375\177\000\000\001\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\330\314\375\177\000\000:\000\000\000\000\000\000\000 5\177\366\271{\000\0009\000\000\000"...}, tid = 0}, free_stack = 0xf034496e00000002, addr_description = {data = {kind = 4154332960, {shadow = {addr = 0, kind = __asan::kShadowKindLow, shadow_byte = 0 '\000'}, heap = {addr = 0, alloc_tid = 0, free_tid = 6116033429960, alloc_stack_id = 4154332960, free_stack_id = 31945, chunk_access = {bad_addr = 96, offset = 137206884603584, chunk_begin = 232, chunk_size = 140724603478024, user_requested_alignment = 2336, access_type = 1, alloc_type = 1}}, stack = {addr = 0, tid = 0, offset = 6116033429960, frame_pc = 137206884603680, access_size = 96, frame_descr = 0x7cc9f79e16c0 "\220\005"}, global = {addr = 0, static kMaxGlobals = 4, globals = {{beg = 0, size = 6116033429960, size_with_redzone = 137206884603680, name = 0x60 <error: Cannot access memory at address 0x60>, module_name = 0x7cc9f79e16c0 "\220\005", has_dynamic_init = 232, gcc_location = 0x7ffd00006008, odr_indicator = 140436705401120}, {beg = 140728048538016, size = 2, size_with_redzone = 140436734025664, name = 0x7c99f79e0b90 "\003\021", module_name = 0x7ffdcd57d170 "\300\331W\315\375\177", has_dynamic_init = 140436732376888, gcc_location = 0xa0, odr_indicator = 137000726170512}, {beg = 140436708102352, size = 140728048538000, size_with_redzone = 137000726170528, name = 0x560b127a4420 <device_free> "\363\017\036\372USH\211\373H\203\354\030H\205\377\017\204-\n", module_name = 0x7ffdcd57daa0 "", has_dynamic_init = 136038633557088, gcc_location = 0x7ffdcd57d9c0, odr_indicator = 140436733305793}, {beg = 140728048538000, size = 133024724610, size_with_redzone = 140728048538016, name = 0x2 <error: Cannot access memory at address 0x2>, module_name = 0x7fb9f99a2400 <___interceptor_free(void*)+176> "D\213\215\314\367\377\377E\205\311t4H\211m\330A\203\371\001tzE\017\276\3061\311H\211\352H\211\306H\215\275\320\367\377\377\3502\026\001", has_dynamic_init = 94605554543896, gcc_location = 0x7ffdcd57d9a0, odr_indicator = 140728048539824}}, reg_sites = {4175912416, 32697, 4174736227, 32697}, access_size = 1, size = 125 '}'}, wild = {addr = 0, access_size = 0}}}}}, AllocTypeMismatch = {<__asan::ErrorBase> = {scariness = {score = 51, descr = "8-byte-read-heap-use-after-free\000\271\177\000\000\305\274\233\371\271\177\000\000\340~\236\367\031|\000\000:\000\000\000\000\000\000\000\300~\236\367\031|\000\000\320~\236\367\031|\000\000\200\315W\315\375\177\000\000\005\034\220\371\271\177\000\000\320\315W\315\375\177\000\000\000\220\031\370\271\177\000\000\001\000\000\000\000\000\000\000\001\000\000\000\v\000\001\001\000\000\000\000\000\000\000\000\370\377\377\377\377\377\377\377\032\177\236\367\031|\000\000\300\315W\315\375\177\000\000\001\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\330\314\375\177\000\000:\000\000\000\000\000\000\000 5\177\366\271{\000\0009\000\000\000"...}, tid = 0}, dealloc_stack = 0xf034496e00000002, alloc_type = 4154332960, dealloc_type = 31945, addr_description = {data = {kind = __asan::kAddressKindWild, {shadow = {addr = 0, kind = (unknown: 0xc8), shadow_byte = 1 '\001'}, heap = {addr = 0, alloc_tid = 6116033429960, free_tid = 137206884603680, alloc_stack_id = 96, free_stack_id = 0, chunk_access = {bad_addr = 137206884603584, offset = 232, chunk_begin = 140724603478024, chunk_size = 140436705401120, user_requested_alignment = 416, access_type = 1, alloc_type = 3}}, stack = {addr = 0, tid = 6116033429960, offset = 137206884603680, frame_pc = 96, access_size = 137206884603584, frame_descr = 0xe8 <error: Cannot access memory at address 0xe8>}, global = {addr = 0, static kMaxGlobals = 4, globals = {{beg = 6116033429960, size = 137206884603680, size_with_redzone = 96, name = 0x7cc9f79e16c0 "\220\005", module_name = 0xe8 <error: Cannot access memory at address 0xe8>, has_dynamic_init = 140724603478024, gcc_location = 0x7fb9f7f05920, odr_indicator = 140728048538016}, {beg = 2, size = 140436734025664, size_with_redzone = 137000726170512, name = 0x7ffdcd57d170 "\300\331W\315\375\177", module_name = 0x7fb9f98bf738 <__sanitizer::Quarantine<__asan::QuarantineCallback, __asan::AsanChunk>::Put(__sanitizer::QuarantineCache<__asan::QuarantineCallback>*, __asan::QuarantineCallback, __asan::AsanChunk*, unsigned long)+248> "H\203;", has_dynamic_init = 160, gcc_location = 0x7c99f79e0b90, odr_indicator = 140436708102352}, {beg = 140728048538000, size = 137000726170528, size_with_redzone = 94605554631712, name = 0x7ffdcd57daa0 "", module_name = 0x7bb9f66dcc60 "pU\236\367)|", has_dynamic_init = 140728048540096, gcc_location = 0x7fb9f99a23c1 <___interceptor_free(void*)+113>, odr_indicator = 140728048538000}, {beg = 133024724610, size = 140728048538016, size_with_redzone = 2, name = 0x7fb9f99a2400 <___interceptor_free(void*)+176> "D\213\215\314\367\377\377E\205\311t4H\211m\330A\203\371\001tzE\017\276\3061\311H\211\352H\211\306H\215\275\320\367\377\377\3502\026\001", module_name = 0x560b1278ed18 <gatt_server_cleanup+200> "H\205\333t{\366\303\auvH\211\350H\301\350\003\200\270", has_dynamic_init = 140728048540064, gcc_location = 0x7ffdcd57d8b0, odr_indicator = 140436721589728}}, reg_sites = {4174736227, 32697, 1, 0}, access_size = 94605555595901, size = 16 '\020'}, wild = {addr = 0, access_size = 6116033429960}}}}}, MallocUsableSizeNotOwned = {<__asan::ErrorBase> = {scariness = {score = 51, descr = "8-byte-read-heap-use-after-free\000\271\177\000\000\305\274\233\371\271\177\000\000\340~\236\367\031|\000\000:\000\000\000\000\000\000\000\300~\236\367\031|\000\000\320~\236\367\031|\000\000\200\315W\315\375\177\000\000\005\034\220\371\271\177\000\000\320\315W\315\375\177\000\000\000\220\031\370\271\177\000\000\001\000\000\000\000\000\000\000\001\000\000\000\v\000\001\001\000\000\000\000\000\000\000\000\370\377\377\377\377\377\377\377\032\177\236\367\031|\000\000\300\315W\315\375\177\000\000\001\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\330\314\375\177\000\000:\000\000\000\000\000\000\000 5\177\366\271{\000\0009\000\000\000"...}, tid = 0}, stack = 0xf034496e00000002, addr_description = {data = {kind = 4154332960, {shadow = {addr = 0, kind = __asan::kShadowKindLow, shadow_byte = 0 '\000'}, heap = {addr = 0, alloc_tid = 0, free_tid = 6116033429960, alloc_stack_id = 4154332960, free_stack_id = 31945, chunk_access = {bad_addr = 96, offset = 137206884603584, chunk_begin = 232, chunk_size = 140724603478024, user_requested_alignment = 2336, access_type = 1, alloc_type = 1}}, stack = {addr = 0, tid = 0, offset = 6116033429960, frame_pc = 137206884603680, access_size = 96, frame_descr = 0x7cc9f79e16c0 "\220\005"}, global = {addr = 0, static kMaxGlobals = 4, globals = {{beg = 0, size = 6116033429960, size_with_redzone = 137206884603680, name = 0x60 <error: Cannot access memory at address 0x60>, module_name = 0x7cc9f79e16c0 "\220\005", has_dynamic_init = 232, gcc_location = 0x7ffd00006008, odr_indicator = 140436705401120}, {beg = 140728048538016, size = 2, size_with_redzone = 140436734025664, name = 0x7c99f79e0b90 "\003\021", module_name = 0x7ffdcd57d170 "\300\331W\315\375\177", has_dynamic_init = 140436732376888, gcc_location = 0xa0, odr_indicator = 137000726170512}, {beg = 140436708102352, size = 140728048538000, size_with_redzone = 137000726170528, name = 0x560b127a4420 <device_free> "\363\017\036\372USH\211\373H\203\354\030H\205\377\017\204-\n", module_name = 0x7ffdcd57daa0 "", has_dynamic_init = 136038633557088, gcc_location = 0x7ffdcd57d9c0, odr_indicator = 140436733305793}, {beg = 140728048538000, size = 133024724610, size_with_redzone = 140728048538016, name = 0x2 <error: Cannot access memory at address 0x2>, module_name = 0x7fb9f99a2400 <___interceptor_free(void*)+176> "D\213\215\314\367\377\377E\205\311t4H\211m\330A\203\371\001tzE\017\276\3061\311H\211\352H\211\306H\215\275\320\367\377\377\3502\026\001", has_dynamic_init = 94605554543896, gcc_location = 0x7ffdcd57d9a0, odr_indicator = 140728048539824}}, reg_sites = {4175912416, 32697, 4174736227, 32697}, access_size = 1, size = 125 '}'}, wild = {addr = 0, access_size = 0}}}}}, SanitizerGetAllocatedSizeNotOwned = {<__asan::ErrorBase> = {scariness = {score = 51, descr = "8-byte-read-heap-use-after-free\000\271\177\000\000\305\274\233\371\271\177\000\000\340~\236\367\031|\000\000:\000\000\000\000\000\000\000\300~\236\367\031|\000\000\320~\236\367\031|\000\000\200\315W\315\375\177\000\000\005\034\220\371\271\177\000\000\320\315W\315\375\177\000\000\000\220\031\370\271\177\000\000\001\000\000\000\000\000\000\000\001\000\000\000\v\000\001\001\000\000\000\000\000\000\000\000\370\377\377\377\377\377\377\377\032\177\236\367\031|\000\000\300\315W\315\375\177\000\000\001\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\330\314\375\177\000\000:\000\000\000\000\000\000\000 5\177\366\271{\000\0009\000\000\000"...}, tid = 0}, stack = 0xf034496e00000002, addr_description = {data = {kind = 4154332960, {shadow = {addr = 0, kind = __asan::kShadowKindLow, shadow_byte = 0 '\000'}, heap = {addr = 0, alloc_tid = 0, free_tid = 6116033429960, alloc_stack_id = 4154332960, free_stack_id = 31945, chunk_access = {bad_addr = 96, offset = 137206884603584, chunk_begin = 232, chunk_size = 140724603478024, user_requested_alignment = 2336, access_type = 1, alloc_type = 1}}, stack = {addr = 0, tid = 0, offset = 6116033429960, frame_pc = 137206884603680, access_size = 96, frame_descr = 0x7cc9f79e16c0 "\220\005"}, global = {addr = 0, static kMaxGlobals = 4, globals = {{beg = 0, size = 6116033429960, size_with_redzone = 137206884603680, name = 0x60 <error: Cannot access memory at address 0x60>, module_name = 0x7cc9f79e16c0 "\220\005", has_dynamic_init = 232, gcc_location = 0x7ffd00006008, odr_indicator = 140436705401120}, {beg = 140728048538016, size = 2, size_with_redzone = 140436734025664, name = 0x7c99f79e0b90 "\003\021", module_name = 0x7ffdcd57d170 "\300\331W\315\375\177", has_dynamic_init = 140436732376888, gcc_location = 0xa0, odr_indicator = 137000726170512}, {beg = 140436708102352, size = 140728048538000, size_with_redzone = 137000726170528, name = 0x560b127a4420 <device_free> "\363\017\036\372USH\211\373H\203\354\030H\205\377\017\204-\n", module_name = 0x7ffdcd57daa0 "", has_dynamic_init = 136038633557088, gcc_location = 0x7ffdcd57d9c0, odr_indicator = 140436733305793}, {beg = 140728048538000, size = 133024724610, size_with_redzone = 140728048538016, name = 0x2 <error: Cannot access memory at address 0x2>, module_name = 0x7fb9f99a2400 <___interceptor_free(void*)+176> "D\213\215\314\367\377\377E\205\311t4H\211m\330A\203\371\001tzE\017\276\3061\311H\211\352H\211\306H\215\275\320\367\377\377\3502\026\001", has_dynamic_init = 94605554543896, gcc_location = 0x7ffdcd57d9a0, odr_indicator = 140728048539824}}, reg_sites = {4175912416, 32697, 4174736227, 32697}, access_size = 1, size = 125 '}'}, wild = {addr = 0, access_size = 0}}}}}, CallocOverflow = {<__asan::ErrorBase> = {scariness = {score = 51, descr = "8-byte-read-heap-use-after-free\000\271\177\000\000\305\274\233\371\271\177\000\000\340~\236\367\031|\000\000:\000\000\000\000\000\000\000\300~\236\367\031|\000\000\320~\236\367\031|\000\000\200\315W\315\375\177\000\000\005\034\220\371\271\177\000\000\320\315W\315\375\177\000\000\000\220\031\370\271\177\000\000\001\000\000\000\000\000\000\000\001\000\000\000\v\000\001\001\000\000\000\000\000\000\000\000\370\377\377\377\377\377\377\377\032\177\236\367\031|\000\000\300\315W\315\375\177\000\000\001\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\330\314\375\177\000\000:\000\000\000\000\000\000\000 5\177\366\271{\000\0009\000\000\000"...}, tid = 0}, stack = 0xf034496e00000002, count = 137206884603680, size = 0}, ReallocArrayOverflow = {<__asan::ErrorBase> = {scariness = {score = 51, descr = "8-byte-read-heap-use-after-free\000\271\177\000\000\305\274\233\371\271\177\000\000\340~\236\367\031|\000\000:\000\000\000\000\000\000\000\300~\236\367\031|\000\000\320~\236\367\031|\000\000\200\315W\315\375\177\000\000\005\034\220\371\271\177\000\000\320\315W\315\375\177\000\000\000\220\031\370\271\177\000\000\001\000\000\000\000\000\000\000\001\000\000\000\v\000\001\001\000\000\000\000\000\000\000\000\370\377\377\377\377\377\377\377\032\177\236\367\031|\000\000\300\315W\315\375\177\000\000\001\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\330\314\375\177\000\000:\000\000\000\000\000\000\000 5\177\366\271{\000\0009\000\000\000"...}, tid = 0}, stack = 0xf034496e00000002, count = 137206884603680, size = 0}, PvallocOverflow = {<__asan::ErrorBase> = {scariness = {score = 51, descr = "8-byte-read-heap-use-after-free\000\271\177\000\000\305\274\233\371\271\177\000\000\340~\236\367\031|\000\000:\000\000\000\000\000\000\000\300~\236\367\031|\000\000\320~\236\367\031|\000\000\200\315W\315\375\177\000\000\005\034\220\371\271\177\000\000\320\315W\315\375\177\000\000\000\220\031\370\271\177\000\000\001\000\000\000\000\000\000\000\001\000\000\000\v\000\001\001\000\000\000\000\000\000\000\000\370\377\377\377\377\377\377\377\032\177\236\367\031|\000\000\300\315W\315\375\177\000\000\001\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\330\314\375\177\000\000:\000\000\000\000\000\000\000 5\177\366\271{\000\0009\000\000\000"...}, tid = 0}, stack = 0xf034496e00000002, size = 137206884603680}, InvalidAllocationAlignment = {<__asan::ErrorBase> = {scariness = {score = 51, descr = "8-byte-read-heap-use-after-free\000\271\177\000\000\305\274\233\371\271\177\000\000\340~\236\367\031|\000\000:\000\000\000\000\000\000\000\300~\236\367\031|\000\000\320~\236\367\031|\000\000\200\315W\315\375\177\000\000\005\034\220\371\271\177\000\000\320\315W\315\375\177\000\000\000\220\031\370\271\177\000\000\001\000\000\000\000\000\000\000\001\000\000\000\v\000\001\001\000\000\000\000\000\000\000\000\370\377\377\377\377\377\377\377\032\177\236\367\031|\000\000\300\315W\315\375\177\000\000\001\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\330\314\375\177\000\000:\000\000\000\000\000\000\000 5\177\366\271{\000\0009\000\000\000"...}, tid = 0}, stack = 0xf034496e00000002, alignment = 137206884603680}, InvalidAlignedAllocAlignment = {<__asan::ErrorBase> = {scariness = {score = 51, descr = "8-byte-read-heap-use-after-free\000\271\177\000\000\305\274\233\371\271\177\000\000\340~\236\367\031|\000\000:\000\000\000\000\000\000\000\300~\236\367\031|\000\000\320~\236\367\031|\000\000\200\315W\315\375\177\000\000\005\034\220\371\271\177\000\000\320\315W\315\375\177\000\000\000\220\031\370\271\177\000\000\001\000\000\000\000\000\000\000\001\000\000\000\v\000\001\001\000\000\000\000\000\000\000\000\370\377\377\377\377\377\377\377\032\177\236\367\031|\000\000\300\315W\315\375\177\000\000\001\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\330\314\375\177\000\000:\000\000\000\000\000\000\000 5\177\366\271{\000\0009\000\000\000"...}, tid = 0}, stack = 0xf034496e00000002, size = 137206884603680, alignment = 0}, InvalidPosixMemalignAlignment = {<__asan::ErrorBase> = {scariness = {score = 51, descr = "8-byte-read-heap-use-after-free\000\271\177\000\000\305\274\233\371\271\177\000\000\340~\236\367\031|\000\000:\000\000\000\000\000\000\000\300~\236\367\031|\000\000\320~\236\367\031|\000\000\200\315W\315\375\177\000\000\005\034\220\371\271\177\000\000\320\315W\315\375\177\000\000\000\220\031\370\271\177\000\000\001\000\000\000\000\000\000\000\001\000\000\000\v\000\001\001\000\000\000\000\000\000\000\000\370\377\377\377\377\377\377\377\032\177\236\367\031|\000\000\300\315W\315\375\177\000\000\001\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\330\314\375\177\000\000:\000\000\000\000\000\000\000 5\177\366\271{\000\0009\000\000\000"...}, tid = 0}, stack = 0xf034496e00000002, alignment = 137206884603680}, AllocationSizeTooBig = {<__asan::ErrorBase> = {scariness = {score = 51, descr = "8-byte-read-heap-use-after-free\000\271\177\000\000\305\274\233\371\271\177\000\000\340~\236\367\031|\000\000:\000\000\000\000\000\000\000\300~\236\367\031|\000\000\320~\236\367\031|\000\000\200\315W\315\375\177\000\000\005\034\220\371\271\177\000\000\320\315W\315\375\177\000\000\000\220\031\370\271\177\000\000\001\000\000\000\000\000\000\000\001\000\000\000\v\000\001\001\000\000\000\000\000\000\000\000\370\377\377\377\377\377\377\377\032\177\236\367\031|\000\000\300\315W\315\375\177\000\000\001\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\330\314\375\177\000\000:\000\000\000\000\000\000\000 5\177\366\271{\000\0009\000\000\000"...}, tid = 0}, stack = 0xf034496e00000002, user_size = 137206884603680, total_size = 0, max_size = 0}, RssLimitExceeded = {<__asan::ErrorBase> = {scariness = {score = 51, descr = "8-byte-read-heap-use-after-free\000\271\177\000\000\305\274\233\371\271\177\000\000\340~\236\367\031|\000\000:\000\000\000\000\000\000\000\300~\236\367\031|\000\000\320~\236\367\031|\000\000\200\315W\315\375\177\000\000\005\034\220\371\271\177\000\000\320\315W\315\375\177\000\000\000\220\031\370\271\177\000\000\001\000\000\000\000\000\000\000\001\000\000\000\v\000\001\001\000\000\000\000\000\000\000\000\370\377\377\377\377\377\377\377\032\177\236\367\031|\000\000\300\315W\315\375\177\000\000\001\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\330\314\375\177\000\000:\000\000\000\000\000\000\000 5\177\366\271{\000\0009\000\000\000"...}, tid = 0}, stack = 0xf034496e00000002}, OutOfMemory = {<__asan::ErrorBase> = {scariness = {score = 51, descr = "8-byte-read-heap-use-after-free\000\271\177\000\000\305\274\233\371\271\177\000\000\340~\236\367\031|\000\000:\000\000\000\000\000\000\000\300~\236\367\031|\000\000\320~\236\367\031|\000\000\200\315W\315\375\177\000\000\005\034\220\371\271\177\000\000\320\315W\315\375\177\000\000\000\220\031\370\271\177\000\000\001\000\000\000\000\000\000\000\001\000\000\000\v\000\001\001\000\000\000\000\000\000\000\000\370\377\377\377\377\377\377\377\032\177\236\367\031|\000\000\300\315W\315\375\177\000\000\001\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\330\314\375\177\000\000:\000\000\000\000\000\000\000 5\177\366\271{\000\0009\000\000\000"...}, tid = 0}, stack = 0xf034496e00000002, requested_size = 137206884603680}, StringFunctionMemoryRangesOverlap = {<__asan::ErrorBase> = {scariness = {score = 51, descr = "8-byte-read-heap-use-after-free\000\271\177\000\000\305\274\233\371\271\177\000\000\340~\236\367\031|\000\000:\000\000\000\000\000\000\000\300~\236\367\031|\000\000\320~\236\367\031|\000\000\200\315W\315\375\177\000\000\005\034\220\371\271\177\000\000\320\315W\315\375\177\000\000\000\220\031\370\271\177\000\000\001\000\000\000\000\000\000\000\001\000\000\000\v\000\001\001\000\000\000\000\000\000\000\000\370\377\377\377\377\377\377\377\032\177\236\367\031|\000\000\300\315W\315\375\177\000\000\001\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\330\314\375\177\000\000:\000\000\000\000\000\000\000 5\177\366\271{\000\0009\000\000\000"...}, tid = 0}, stack = 0xf034496e00000002, length1 = 137206884603680, length2 = 0, addr1_description = {data = {kind = __asan::kAddressKindWild, {shadow = {addr = 6116033429960, kind = (unknown: 0x20), shadow_byte = 23 '\027'}, heap = {addr = 6116033429960, alloc_tid = 137206884603680, free_tid = 96, alloc_stack_id = 4154332864, free_stack_id = 31945, chunk_access = {bad_addr = 232, offset = 140724603478024, chunk_begin = 140436705401120, chunk_size = 140728048538016, user_requested_alignment = 2, access_type = 0, alloc_type = 0}}, stack = {addr = 6116033429960, tid = 137206884603680, offset = 96, frame_pc = 137206884603584, access_size = 232, frame_descr = 0x7ffd00006008 <error: Cannot access memory at address 0x7ffd00006008>}, global = {addr = 6116033429960, static kMaxGlobals = 4, globals = {{beg = 137206884603680, size = 96, size_with_redzone = 137206884603584, name = 0xe8 <error: Cannot access memory at address 0xe8>, module_name = 0x7ffd00006008 <error: Cannot access memory at address 0x7ffd00006008>, has_dynamic_init = 140436705401120, gcc_location = 0x7ffdcd57d1a0, odr_indicator = 2}, {beg = 140436734025664, size = 137000726170512, size_with_redzone = 140728048537968, name = 0x7fb9f98bf738 <__sanitizer::Quarantine<__asan::QuarantineCallback, __asan::AsanChunk>::Put(__sanitizer::QuarantineCache<__asan::QuarantineCallback>*, __asan::QuarantineCallback, __asan::AsanChunk*, unsigned long)+248> "H\203;", module_name = 0xa0 <error: Cannot access memory at address 0xa0>, has_dynamic_init = 137000726170512, gcc_location = 0x7fb9f81990d0, odr_indicator = 140728048538000}, {beg = 137000726170528, size = 94605554631712, size_with_redzone = 140728048540320, name = 0x7bb9f66dcc60 "pU\236\367)|", module_name = 0x7ffdcd57d9c0 "", has_dynamic_init = 140436733305793, gcc_location = 0x7ffdcd57d190, odr_indicator = 133024724610}, {beg = 140728048538016, size = 2, size_with_redzone = 140436733305856, name = 0x560b1278ed18 <gatt_server_cleanup+200> "H\205\333t{\366\303\auvH\211\350H\301\350\003\200\270", module_name = 0x7ffdcd57d9a0 "`\314m\366\271{", has_dynamic_init = 140728048539824, gcc_location = 0x7fb9f8e75de0 <_nl_C_locobj>, odr_indicator = 140436720413539}}, reg_sites = {1, 0, 310966909, 22027}, access_size = 140728048539920, size = 0 '\000'}, wild = {addr = 6116033429960, access_size = 137206884603680}}}}, addr2_description = {data = {kind = 8, {shadow = {addr = 140436733736855, kind = __asan::kShadowKindLow, shadow_byte = 253 '\375'}, heap = {addr = 140436733736855, alloc_tid = 140728048549120, free_tid = 140728048539560, alloc_stack_id = 1790151936, free_stack_id = 4029958510, chunk_access = {bad_addr = 140728048539760, offset = 140436733566845, chunk_begin = 136519689852296, chunk_size = 140436734001016, user_requested_alignment = 4095, access_type = 3, alloc_type = 3}}, stack = {addr = 140436733736855, tid = 140728048549120, offset = 140728048539560, frame_pc = 17308540006477040896, access_size = 140728048539760, frame_descr = 0x7fb9f99e1f7d <__sanitizer::DTLS_on_tls_get_addr(void*, void*, unsigned long, unsigned long)+125> "I\211\302H\205\300u\035\351\213"}, global = {addr = 140436733736855, static kMaxGlobals = 4, globals = {{beg = 140728048549120, size = 140728048539560, size_with_redzone = 17308540006477040896, name = 0x7ffdcd57d870 "H\024\236\367\271|", module_name = 0x7fb9f99e1f7d <__sanitizer::DTLS_on_tls_get_addr(void*, void*, unsigned long, unsigned long)+125> "I\211\302H\205\300u\035\351\213", has_dynamic_init = 136519689852296, gcc_location = 0x7fb9f9a4bf78, odr_indicator = 65535}, {beg = 17308540006477040896, size = 140436711995576, size_with_redzone = 140436734001016, name = 0x7c19f79e7a90 "", module_name = 0x7ffdcd57daa0 "", has_dynamic_init = 136450970384992, gcc_location = 0x7c19f79e7a88, odr_indicator = 136450970385040}, {beg = 94605555520324, size = 64, size_with_redzone = 17004829194636, name = 0x7c39f79e1620 "@\024\236\367\271|", module_name = 0x7bb9f66dcd00 "\0166\340E", has_dynamic_init = 136176092529104, gcc_location = 0x560b12887302 <bt_att_chan_cancel+402>, odr_indicator = 10}, {beg = 136450970385040, size = 10, size_with_redzone = 94605555561928, name = 0x7cb9f79e1440 "", module_name = 0x7bb9f66dcd60 "", has_dynamic_init = 17004829194656, gcc_location = 0x7ffdcd57d880, odr_indicator = 137138165126216}}, reg_sites = {3445086880, 32765, 4166318264, 32697}, access_size = 136863287218176, size = 176 '\260'}, wild = {addr = 140436733736855, access_size = 140728048549120}}}}, function = 0x7fb9f997a359 <___interceptor___tls_get_addr(void*)+89> "L\211\360H\213]\360L\213u\370\311\303f.\017\037\204"}, StringFunctionSizeOverflow = {<__asan::ErrorBase> = {scariness = {score = 51, descr = "8-byte-read-heap-use-after-free\000\271\177\000\000\305\274\233\371\271\177\000\000\340~\236\367\031|\000\000:\000\000\000\000\000\000\000\300~\236\367\031|\000\000\320~\236\367\031|\000\000\200\315W\315\375\177\000\000\005\034\220\371\271\177\000\000\320\315W\315\375\177\000\000\000\220\031\370\271\177\000\000\001\000\000\000\000\000\000\000\001\000\000\000\v\000\001\001\000\000\000\000\000\000\000\000\370\377\377\377\377\377\377\377\032\177\236\367\031|\000\000\300\315W\315\375\177\000\000\001\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\330\314\375\177\000\000:\000\000\000\000\000\000\000 5\177\366\271{\000\0009\000\000\000"...}, tid = 0}, stack = 0xf034496e00000002, addr_description = {data = {kind = 4154332960, {shadow = {addr = 0, kind = __asan::kShadowKindLow, shadow_byte = 0 '\000'}, heap = {addr = 0, alloc_tid = 0, free_tid = 6116033429960, alloc_stack_id = 4154332960, free_stack_id = 31945, chunk_access = {bad_addr = 96, offset = 137206884603584, chunk_begin = 232, chunk_size = 140724603478024, user_requested_alignment = 2336, access_type = 1, alloc_type = 1}}, stack = {addr = 0, tid = 0, offset = 6116033429960, frame_pc = 137206884603680, access_size = 96, frame_descr = 0x7cc9f79e16c0 "\220\005"}, global = {addr = 0, static kMaxGlobals = 4, globals = {{beg = 0, size = 6116033429960, size_with_redzone = 137206884603680, name = 0x60 <error: Cannot access memory at address 0x60>, module_name = 0x7cc9f79e16c0 "\220\005", has_dynamic_init = 232, gcc_location = 0x7ffd00006008, odr_indicator = 140436705401120}, {beg = 140728048538016, size = 2, size_with_redzone = 140436734025664, name = 0x7c99f79e0b90 "\003\021", module_name = 0x7ffdcd57d170 "\300\331W\315\375\177", has_dynamic_init = 140436732376888, gcc_location = 0xa0, odr_indicator = 137000726170512}, {beg = 140436708102352, size = 140728048538000, size_with_redzone = 137000726170528, name = 0x560b127a4420 <device_free> "\363\017\036\372USH\211\373H\203\354\030H\205\377\017\204-\n", module_name = 0x7ffdcd57daa0 "", has_dynamic_init = 136038633557088, gcc_location = 0x7ffdcd57d9c0, odr_indicator = 140436733305793}, {beg = 140728048538000, size = 133024724610, size_with_redzone = 140728048538016, name = 0x2 <error: Cannot access memory at address 0x2>, module_name = 0x7fb9f99a2400 <___interceptor_free(void*)+176> "D\213\215\314\367\377\377E\205\311t4H\211m\330A\203\371\001tzE\017\276\3061\311H\211\352H\211\306H\215\275\320\367\377\377\3502\026\001", has_dynamic_init = 94605554543896, gcc_location = 0x7ffdcd57d9a0, odr_indicator = 140728048539824}}, reg_sites = {4175912416, 32697, 4174736227, 32697}, access_size = 1, size = 125 '}'}, wild = {addr = 0, access_size = 0}}}}, size = 140728048539920}, BadParamsToAnnotateContiguousContainer = {<__asan::ErrorBase> = {scariness = {score = 51, descr = "8-byte-read-heap-use-after-free\000\271\177\000\000\305\274\233\371\271\177\000\000\340~\236\367\031|\000\000:\000\000\000\000\000\000\000\300~\236\367\031|\000\000\320~\236\367\031|\000\000\200\315W\315\375\177\000\000\005\034\220\371\271\177\000\000\320\315W\315\375\177\000\000\000\220\031\370\271\177\000\000\001\000\000\000\000\000\000\000\001\000\000\000\v\000\001\001\000\000\000\000\000\000\000\000\370\377\377\377\377\377\377\377\032\177\236\367\031|\000\000\300\315W\315\375\177\000\000\001\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\330\314\375\177\000\000:\000\000\000\000\000\000\000 5\177\366\271{\000\0009\000\000\000"...}, tid = 0}, stack = 0xf034496e00000002, beg = 137206884603680, end = 0, old_mid = 0, new_mid = 6116033429960}, BadParamsToAnnotateDoubleEndedContiguousContainer = {<__asan::ErrorBase> = {scariness = {score = 51, descr = "8-byte-read-heap-use-after-free\000\271\177\000\000\305\274\233\371\271\177\000\000\340~\236\367\031|\000\000:\000\000\000\000\000\000\000\300~\236\367\031|\000\000\320~\236\367\031|\000\000\200\315W\315\375\177\000\000\005\034\220\371\271\177\000\000\320\315W\315\375\177\000\000\000\220\031\370\271\177\000\000\001\000\000\000\000\000\000\000\001\000\000\000\v\000\001\001\000\000\000\000\000\000\000\000\370\377\377\377\377\377\377\377\032\177\236\367\031|\000\000\300\315W\315\375\177\000\000\001\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\330\314\375\177\000\000:\000\000\000\000\000\000\000 5\177\366\271{\000\0009\000\000\000"...}, tid = 0}, stack = 0xf034496e00000002, storage_beg = 137206884603680, storage_end = 0, old_container_beg = 0, old_container_end = 6116033429960, new_container_beg = 137206884603680, new_container_end = 96}, BadParamsToCopyContiguousContainerAnnotations = {<__asan::ErrorBase> = {scariness = {score = 51, descr = "8-byte-read-heap-use-after-free\000\271\177\000\000\305\274\233\371\271\177\000\000\340~\236\367\031|\000\000:\000\000\000\000\000\000\000\300~\236\367\031|\000\000\320~\236\367\031|\000\000\200\315W\315\375\177\000\000\005\034\220\371\271\177\000\000\320\315W\315\375\177\000\000\000\220\031\370\271\177\000\000\001\000\000\000\000\000\000\000\001\000\000\000\v\000\001\001\000\000\000\000\000\000\000\000\370\377\377\377\377\377\377\377\032\177\236\367\031|\000\000\300\315W\315\375\177\000\000\001\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\330\314\375\177\000\000:\000\000\000\000\000\000\000 5\177\366\271{\000\0009\000\000\000"...}, tid = 0}, stack = 0xf034496e00000002, old_storage_beg = 137206884603680, old_storage_end = 0, new_storage_beg = 0, new_storage_end = 6116033429960}, ODRViolation = {<__asan::ErrorBase> = {scariness = {score = 51, descr = "8-byte-read-heap-use-after-free\000\271\177\000\000\305\274\233\371\271\177\000\000\340~\236\367\031|\000\000:\000\000\000\000\000\000\000\300~\236\367\031|\000\000\320~\236\367\031|\000\000\200\315W\315\375\177\000\000\005\034\220\371\271\177\000\000\320\315W\315\375\177\000\000\000\220\031\370\271\177\000\000\001\000\000\000\000\000\000\000\001\000\000\000\v\000\001\001\000\000\000\000\000\000\000\000\370\377\377\377\377\377\377\377\032\177\236\367\031|\000\000\300\315W\315\375\177\000\000\001\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\330\314\375\177\000\000:\000\000\000\000\000\000\000 5\177\366\271{\000\0009\000\000\000"...}, tid = 0}, global1 = {beg = 17308540004686888962, size = 137206884603680, size_with_redzone = 0, name = 0x0, module_name = 0x590000001c8 <error: Cannot access memory at address 0x590000001c8>, has_dynamic_init = 137206884603680, gcc_location = 0x60, odr_indicator = 137206884603584}, global2 = {beg = 232, size = 140724603478024, size_with_redzone = 140436705401120, name = 0x7ffdcd57d1a0 "", module_name = 0x2 <error: Cannot access memory at address 0x2>, has_dynamic_init = 140436734025664, gcc_location = 0x7c99f79e0b90, odr_indicator = 140728048537968}, stack_id1 = 4186699576, stack_id2 = 32697}, InvalidPointerPair = {<__asan::ErrorBase> = {scariness = {score = 51, descr = "8-byte-read-heap-use-after-free\000\271\177\000\000\305\274\233\371\271\177\000\000\340~\236\367\031|\000\000:\000\000\000\000\000\000\000\300~\236\367\031|\000\000\320~\236\367\031|\000\000\200\315W\315\375\177\000\000\005\034\220\371\271\177\000\000\320\315W\315\375\177\000\000\000\220\031\370\271\177\000\000\001\000\000\000\000\000\000\000\001\000\000\000\v\000\001\001\000\000\000\000\000\000\000\000\370\377\377\377\377\377\377\377\032\177\236\367\031|\000\000\300\315W\315\375\177\000\000\001\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\330\314\375\177\000\000:\000\000\000\000\000\000\000 5\177\366\271{\000\0009\000\000\000"...}, tid = 0}, pc = 17308540004686888962, bp = 137206884603680, sp = 0, addr1_description = {data = {kind = __asan::kAddressKindWild, {shadow = {addr = 6116033429960, kind = (unknown: 0x20), shadow_byte = 23 '\027'}, heap = {addr = 6116033429960, alloc_tid = 137206884603680, free_tid = 96, alloc_stack_id = 4154332864, free_stack_id = 31945, chunk_access = {bad_addr = 232, offset = 140724603478024, chunk_begin = 140436705401120, chunk_size = 140728048538016, user_requested_alignment = 2, access_type = 0, alloc_type = 0}}, stack = {addr = 6116033429960, tid = 137206884603680, offset = 96, frame_pc = 137206884603584, access_size = 232, frame_descr = 0x7ffd00006008 <error: Cannot access memory at address 0x7ffd00006008>}, global = {addr = 6116033429960, static kMaxGlobals = 4, globals = {{beg = 137206884603680, size = 96, size_with_redzone = 137206884603584, name = 0xe8 <error: Cannot access memory at address 0xe8>, module_name = 0x7ffd00006008 <error: Cannot access memory at address 0x7ffd00006008>, has_dynamic_init = 140436705401120, gcc_location = 0x7ffdcd57d1a0, odr_indicator = 2}, {beg = 140436734025664, size = 137000726170512, size_with_redzone = 140728048537968, name = 0x7fb9f98bf738 <__sanitizer::Quarantine<__asan::QuarantineCallback, __asan::AsanChunk>::Put(__sanitizer::QuarantineCache<__asan::QuarantineCallback>*, __asan::QuarantineCallback, __asan::AsanChunk*, unsigned long)+248> "H\203;", module_name = 0xa0 <error: Cannot access memory at address 0xa0>, has_dynamic_init = 137000726170512, gcc_location = 0x7fb9f81990d0, odr_indicator = 140728048538000}, {beg = 137000726170528, size = 94605554631712, size_with_redzone = 140728048540320, name = 0x7bb9f66dcc60 "pU\236\367)|", module_name = 0x7ffdcd57d9c0 "", has_dynamic_init = 140436733305793, gcc_location = 0x7ffdcd57d190, odr_indicator = 133024724610}, {beg = 140728048538016, size = 2, size_with_redzone = 140436733305856, name = 0x560b1278ed18 <gatt_server_cleanup+200> "H\205\333t{\366\303\auvH\211\350H\301\350\003\200\270", module_name = 0x7ffdcd57d9a0 "`\314m\366\271{", has_dynamic_init = 140728048539824, gcc_location = 0x7fb9f8e75de0 <_nl_C_locobj>, odr_indicator = 140436720413539}}, reg_sites = {1, 0, 310966909, 22027}, access_size = 140728048539920, size = 0 '\000'}, wild = {addr = 6116033429960, access_size = 137206884603680}}}}, addr2_description = {data = {kind = 8, {shadow = {addr = 140436733736855, kind = __asan::kShadowKindLow, shadow_byte = 253 '\375'}, heap = {addr = 140436733736855, alloc_tid = 140728048549120, free_tid = 140728048539560, alloc_stack_id = 1790151936, free_stack_id = 4029958510, chunk_access = {bad_addr = 140728048539760, offset = 140436733566845, chunk_begin = 136519689852296, chunk_size = 140436734001016, user_requested_alignment = 4095, access_type = 3, alloc_type = 3}}, stack = {addr = 140436733736855, tid = 140728048549120, offset = 140728048539560, frame_pc = 17308540006477040896, access_size = 140728048539760, frame_descr = 0x7fb9f99e1f7d <__sanitizer::DTLS_on_tls_get_addr(void*, void*, unsigned long, unsigned long)+125> "I\211\302H\205\300u\035\351\213"}, global = {addr = 140436733736855, static kMaxGlobals = 4, globals = {{beg = 140728048549120, size = 140728048539560, size_with_redzone = 17308540006477040896, name = 0x7ffdcd57d870 "H\024\236\367\271|", module_name = 0x7fb9f99e1f7d <__sanitizer::DTLS_on_tls_get_addr(void*, void*, unsigned long, unsigned long)+125> "I\211\302H\205\300u\035\351\213", has_dynamic_init = 136519689852296, gcc_location = 0x7fb9f9a4bf78, odr_indicator = 65535}, {beg = 17308540006477040896, size = 140436711995576, size_with_redzone = 140436734001016, name = 0x7c19f79e7a90 "", module_name = 0x7ffdcd57daa0 "", has_dynamic_init = 136450970384992, gcc_location = 0x7c19f79e7a88, odr_indicator = 136450970385040}, {beg = 94605555520324, size = 64, size_with_redzone = 17004829194636, name = 0x7c39f79e1620 "@\024\236\367\271|", module_name = 0x7bb9f66dcd00 "\0166\340E", has_dynamic_init = 136176092529104, gcc_location = 0x560b12887302 <bt_att_chan_cancel+402>, odr_indicator = 10}, {beg = 136450970385040, size = 10, size_with_redzone = 94605555561928, name = 0x7cb9f79e1440 "", module_name = 0x7bb9f66dcd60 "", has_dynamic_init = 17004829194656, gcc_location = 0x7ffdcd57d880, odr_indicator = 137138165126216}}, reg_sites = {3445086880, 32765, 4166318264, 32697}, access_size = 136863287218176, size = 176 '\260'}, wild = {addr = 140436733736855, access_size = 140728048549120}}}}}, Generic = {<__asan::ErrorBase> = {scariness = {score = 51, descr = "8-byte-read-heap-use-after-free\000\271\177\000\000\305\274\233\371\271\177\000\000\340~\236\367\031|\000\000:\000\000\000\000\000\000\000\300~\236\367\031|\000\000\320~\236\367\031|\000\000\200\315W\315\375\177\000\000\005\034\220\371\271\177\000\000\320\315W\315\375\177\000\000\000\220\031\370\271\177\000\000\001\000\000\000\000\000\000\000\001\000\000\000\v\000\001\001\000\000\000\000\000\000\000\000\370\377\377\377\377\377\377\377\032\177\236\367\031|\000\000\300\315W\315\375\177\000\000\001\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\330\314\375\177\000\000:\000\000\000\000\000\000\000 5\177\366\271{\000\0009\000\000\000"...}, tid = 0}, addr_description = {data = {kind = __asan::kAddressKindHeap, {shadow = {addr = 137206884603680, kind = __asan::kShadowKindLow, shadow_byte = 0 '\000'}, heap = {addr = 137206884603680, alloc_tid = 0, free_tid = 0, alloc_stack_id = 456, free_stack_id = 1424, chunk_access = {bad_addr = 137206884603680, offset = 96, chunk_begin = 137206884603584, chunk_size = 232, user_requested_alignment = 8, access_type = 2, alloc_type = 1}}, stack = {addr = 137206884603680, tid = 0, offset = 0, frame_pc = 6116033429960, access_size = 137206884603680, frame_descr = 0x60 <error: Cannot access memory at address 0x60>}, global = {addr = 137206884603680, static kMaxGlobals = 4, globals = {{beg = 0, size = 0, size_with_redzone = 6116033429960, name = 0x7cc9f79e1720 "\240\025\236\3679|", module_name = 0x60 <error: Cannot access memory at address 0x60>, has_dynamic_init = 137206884603584, gcc_location = 0xe8, odr_indicator = 140724603478024}, {beg = 140436705401120, size = 140728048538016, size_with_redzone = 2, name = 0x7fb9f9a51fc0 <__asan::instance> "", module_name = 0x7c99f79e0b90 "\003\021", has_dynamic_init = 140728048537968, gcc_location = 0x7fb9f98bf738 <__sanitizer::Quarantine<__asan::QuarantineCallback, __asan::AsanChunk>::Put(__sanitizer::QuarantineCache<__asan::QuarantineCallback>*, __asan::QuarantineCallback, __asan::AsanChunk*, unsigned long)+248>, odr_indicator = 160}, {beg = 137000726170512, size = 140436708102352, size_with_redzone = 140728048538000, name = 0x7c99f79e0ba0 "\222\005", module_name = 0x560b127a4420 <device_free> "\363\017\036\372USH\211\373H\203\354\030H\205\377\017\204-\n", has_dynamic_init = 140728048540320, gcc_location = 0x7bb9f66dcc60, odr_indicator = 140728048540096}, {beg = 140436733305793, size = 140728048538000, size_with_redzone = 133024724610, name = 0x7ffdcd57d1a0 "", module_name = 0x2 <error: Cannot access memory at address 0x2>, has_dynamic_init = 140436733305856, gcc_location = 0x560b1278ed18 <gatt_server_cleanup+200>, odr_indicator = 140728048540064}}, reg_sites = {3445086384, 32765, 4175912416, 32697}, access_size = 140436720413539, size = 1 '\001'}, wild = {addr = 137206884603680, access_size = 0}}}}, pc = 94605555595901, bp = 140728048539920, sp = 140728048539904, access_size = 8, bug_descr = 0x7fb9f9a0b797 "heap-use-after-free", is_write = false, shadow_val = 253 '\375'}}}, halt_on_error_ = true}
                error = {<__asan::ErrorBase> = {scariness = {score = 51, descr = "8-byte-read-heap-use-after-free\000\271\177\000\000\305\274\233\371\271\177\000\000\340~\236\367\031|\000\000:\000\000\000\000\000\000\000\300~\236\367\031|\000\000\320~\236\367\031|\000\000\200\315W\315\375\177\000\000\005\034\220\371\271\177\000\000\320\315W\315\375\177\000\000\000\220\031\370\271\177\000\000\001\000\000\000\000\000\000\000\001\000\000\000\v\000\001\001\000\000\000\000\000\000\000\000\370\377\377\377\377\377\377\377\032\177\236\367\031|\000\000\300\315W\315\375\177\000\000\001\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\330\314\375\177\000\000:\000\000\000\000\000\000\000 5\177\366\271{\000\0009\000\000\000"...}, tid = 0}, addr_description = {data = {kind = __asan::kAddressKindHeap, {shadow = {addr = 137206884603680, kind = __asan::kShadowKindLow, shadow_byte = 0 '\000'}, heap = {addr = 137206884603680, alloc_tid = 0, free_tid = 0, alloc_stack_id = 456, free_stack_id = 1424, chunk_access = {bad_addr = 137206884603680, offset = 96, chunk_begin = 137206884603584, chunk_size = 232, user_requested_alignment = 8, access_type = 2, alloc_type = 1}}, stack = {addr = 137206884603680, tid = 0, offset = 0, frame_pc = 6116033429960, access_size = 137206884603680, frame_descr = 0x60 <error: Cannot access memory at address 0x60>}, global = {addr = 137206884603680, static kMaxGlobals = 4, globals = {{beg = 0, size = 0, size_with_redzone = 6116033429960, name = 0x7cc9f79e1720 "\240\025\236\3679|", module_name = 0x60 <error: Cannot access memory at address 0x60>, has_dynamic_init = 137206884603584, gcc_location = 0xe8, odr_indicator = 140724603478024}, {beg = 140436705401120, size = 140728048538016, size_with_redzone = 2, name = 0x7fb9f9a51fc0 <__asan::instance> "", module_name = 0x7c99f79e0b90 "\003\021", has_dynamic_init = 140728048537968, gcc_location = 0x7fb9f98bf738 <__sanitizer::Quarantine<__asan::QuarantineCallback, __asan::AsanChunk>::Put(__sanitizer::QuarantineCache<__asan::QuarantineCallback>*, __asan::QuarantineCallback, __asan::AsanChunk*, unsigned long)+248>, odr_indicator = 160}, {beg = 137000726170512, size = 140436708102352, size_with_redzone = 140728048538000, name = 0x7c99f79e0ba0 "\222\005", module_name = 0x560b127a4420 <device_free> "\363\017\036\372USH\211\373H\203\354\030H\205\377\017\204-\n", has_dynamic_init = 140728048540320, gcc_location = 0x7bb9f66dcc60, odr_indicator = 140728048540096}, {beg = 140436733305793, size = 140728048538000, size_with_redzone = 133024724610, name = 0x7ffdcd57d1a0 "", module_name = 0x2 <error: Cannot access memory at address 0x2>, has_dynamic_init = 140436733305856, gcc_location = 0x560b1278ed18 <gatt_server_cleanup+200>, odr_indicator = 140728048540064}}, reg_sites = {3445086384, 32765, 4175912416, 32697}, access_size = 140436720413539, size = 1 '\001'}, wild = {addr = 137206884603680, access_size = 0}}}}, pc = 94605555595901, bp = 140728048539920, sp = 140728048539904, access_size = 8, bug_descr = 0x7fb9f9a0b797 "heap-use-after-free", is_write = false, shadow_val = 253 '\375'}
        #9  0x00007fb9f99aff8d in __asan::ReportGenericError (pc=<optimized out>, bp=bp@entry=140728048539920, sp=sp@entry=140728048539904, addr=<optimized out>, is_write=is_write@entry=false, access_size=access_size@entry=8, exp=<optimized out>, fatal=true) at ../../../../src/libsanitizer/asan/asan_report.cpp:536
                in_report = <optimized out>
                error = <optimized out>
                enable_fp = <optimized out>
        #10 0x00007fb9f99b13f9 in __asan::__asan_report_load8 (addr=<optimized out>) at ../../../../src/libsanitizer/asan/asan_rtl.cpp:131
                bp = 140728048539920
                pc = <optimized out>
                local_stack = 140728048540320
                sp = 140728048539904
        #11 0x0000560b1288fa7d in discovery_op_free (op=0x7c39f79e16a0) at src/shared/gatt-client.c:407
        No locals.
        #12 0x0000560b129bcc6a in bt_gatt_request_unref (req=0x7c39f79e1fa0) at src/shared/gatt-helpers.c:577
        No locals.
        #13 bt_gatt_request_unref (req=0x7c39f79e1fa0) at src/shared/gatt-helpers.c:566
        No locals.
        #14 0x0000560b1287d344 in cancel_att_send_op (data=0x7c19f79e7a60) at src/shared/att.c:226
                op = 0x7c19f79e7a60
        #15 0x0000560b12888089 in bt_att_cancel_all (att=<optimized out>) at src/shared/att.c:1951
                chan = 0x7c39f79e1620
                entry = 0x7bd9f79f41d0
        #16 bt_att_cancel_all (att=<optimized out>) at src/shared/att.c:1932
                entry = <optimized out>
                chan = <optimized out>
        #17 0x0000560b12888e70 in bt_att_unref (att=0x7cb9f79e1440) at src/shared/att.c:1350
        No locals.
        #18 bt_att_unref (att=0x7cb9f79e1440) at src/shared/att.c:1341
        No locals.
        #19 0x0000560b127a408f in attio_cleanup (device=device@entry=0x7d29f79e0b00) at src/device.c:873
        No locals.
        #20 0x0000560b127a45c7 in device_free (user_data=0x7d29f79e0b00) at src/device.c:918
                device = 0x7d29f79e0b00
                __func__ = "device_free"
        #21 0x0000560b1282537a in remove_interface (data=0x7c29f79e5570, name=name@entry=0x560b12a4b3a0 "org.bluez.Device1") at gdbus/object.c:742
                iface = 0x7c19f79e6260
        #22 0x0000560b12827f3c in g_dbus_unregister_interface (connection=<optimized out>, path=<optimized out>, name=<optimized out>) at gdbus/object.c:1499
                data = <optimized out>
        #23 0x0000560b127593db in remove_temporary_devices (adapter=adapter@entry=0x7cf9f79e0040) at src/adapter.c:827
                dev = 0x7d29f79e0b00
                l = <optimized out>
                next = 0x0
        #24 0x0000560b1275a73a in adapter_shutdown () at src/adapter.c:11568
                adapter = 0x7cf9f79e0040
                list = 0x7be9f79e3910 = {0x7cf9f79e0040}
                __func__ = "adapter_shutdown"
        #25 0x0000560b127fc04c in signal_callback (signum=<optimized out>, user_data=<optimized out>) at src/main.c:1517
                terminated = false
        #26 signal_callback (signum=<optimized out>, user_data=<optimized out>) at src/main.c:1504
                terminated = false
        #27 0x0000560b129b11fe in signal_read (io=<optimized out>, user_data=0x7be9f79e34c0) at src/shared/mainloop-notify.c:145
                data = <optimized out>
                si = <optimized out>
                result = <optimized out>
                fd = <optimized out>
        #28 0x0000560b129ae0f5 in watch_callback (channel=<optimized out>, cond=<optimized out>, user_data=<optimized out>) at src/shared/io-glib.c:173
                watch = <optimized out>
                result = <optimized out>
                destroy = <optimized out>
        #29 0x00007fb9f96bbb9b in ?? () from /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
        No symbol table info available.
        #30 0x00007fb9f96bd1d7 in ?? () from /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
        No symbol table info available.
        #31 0x00007fb9f96bd577 in g_main_loop_run () from /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
        No symbol table info available.
        #32 0x0000560b129b1059 in mainloop_run () at src/shared/mainloop-glib.c:65
        No locals.
        #33 0x0000560b129b198b in mainloop_run_with_signal (func=func@entry=0x560b127fbfd0 <signal_callback>, user_data=user_data@entry=0x0) at src/shared/mainloop-notify.c:196
                data = 0x7be9f79e34c0
                io = 0x7bf9f79f9590
                ret = <optimized out>
        #34 0x0000560b1252c4bb in main (argc=<optimized out>, argv=<optimized out>) at src/main.c:1745
                context = <optimized out>
                err = <optimized out>
                sdp_mtu = 0
                sdp_flags = <optimized out>
                gdbus_flags = <optimized out>
                __func__ = "main""


https://github.com/bluez/bluez/pull/2778

---
Regards,
Linux Bluetooth


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

* Re: [RFC PATCH v3] asha: Defer BR/EDR inquiry while streaming
  2026-11-07  2:47   ` [RFC PATCH v3] " Kyle Pepper
  2026-11-07  8:58     ` [RFC,v3] " bluez.test.bot
@ 2026-11-10 21:30     ` Luiz Augusto von Dentz
  1 sibling, 0 replies; 7+ messages in thread
From: Luiz Augusto von Dentz @ 2026-11-10 21:30 UTC (permalink / raw)
  To: Kyle Pepper; +Cc: linux-bluetooth, marcel

Hi Arun,

On Fri, Nov 6, 2026 at 9:47 PM Kyle Pepper <cochcoder@proton.me> wrote:
>
> Defer BR/EDR inquiry while ASHA streams are active. Keep LE discovery
> available and preserve client filters for restoration after audio stops.
> Return Busy if a new request leaves no permitted scan type. Recheck
> pending discovery starts when audio changes.
>
> Release the stream count when START cannot be queued or its callback
> reports failure, so a failed acquisition cannot keep inquiry suppressed.
>
> Assisted-by: OpenCode:gpt-6.1-sol
> Assisted-by: Codex:gpt-6
> ---
> v3: Wrap the unref call and shorten a comment to meet the
> 80-column limit. No behavior changes from v2.
>
> Previous version:
> https://lore.kernel.org/linux-bluetooth/20261107014841.1452698-1-cochcoder@proton.me/
>
> v2 CI: CheckPatch failed on these two long lines; the other
> 11 checks passed. Native MGMT/client arbitration and isolated
> hardware validation remain open.
>
>  profiles/audio/asha.c | 47 ++++++++++++++++++++++++---
>  src/adapter.c         | 75 ++++++++++++++++++++++++++++++++++++++++---
>  src/adapter.h         |  4 +++
>  3 files changed, 117 insertions(+), 9 deletions(-)
>
> diff --git a/profiles/audio/asha.c b/profiles/audio/asha.c
> index 8e625fdca3..d1fcddbcee 100644
> --- a/profiles/audio/asha.c
> +++ b/profiles/audio/asha.c
> @@ -60,8 +60,36 @@ struct bt_asha_device {
>         uint16_t imtu, omtu;
>
>         unsigned int resume_id;
> +       bool streaming_counted;
> +       bt_asha_cb_t start_cb;
> +       void *start_cb_data;
>  };
>
> +static void asha_set_streaming(struct bt_asha_device *asha_dev, bool streaming)
> +{
> +       if (streaming == asha_dev->streaming_counted)
> +               return;
> +
> +       if (streaming)
> +               btd_adapter_le_audio_ref(device_get_adapter(asha_dev->device));
> +       else
> +               btd_adapter_le_audio_unref(
> +                                       device_get_adapter(asha_dev->device));
> +
> +       asha_dev->streaming_counted = streaming;
> +}
> +
> +static void asha_start_cb(int status, void *user_data)
> +{
> +       struct bt_asha_device *asha_dev = user_data;
> +
> +       if (status)
> +               asha_set_streaming(asha_dev, false);
> +
> +       if (asha_dev->start_cb)
> +               asha_dev->start_cb(status, asha_dev->start_cb_data);
> +}
> +
>  static char *make_endpoint_path(struct bt_asha_device *asha_dev)
>  {
>         char *path;
> @@ -91,6 +119,7 @@ static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
>
>         if (err) {
>                 error("%s", err->message);
> +               asha_set_streaming(asha_dev, false);
>                 return;
>         }
>
> @@ -107,8 +136,11 @@ static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
>
>         asha_dev->io = io;
>
> -       bt_asha_start(asha_dev->asha, conn_data->cb,
> -                                       conn_data->cb_user_data);
> +       asha_dev->start_cb = conn_data->cb;
> +       asha_dev->start_cb_data = conn_data->cb_user_data;
> +
> +       if (bt_asha_start(asha_dev->asha, asha_start_cb, asha_dev))
> +               asha_set_streaming(asha_dev, false);
>  }
>
>  static int asha_connect_socket(struct bt_asha_device *asha_dev,
> @@ -171,12 +203,15 @@ unsigned int bt_asha_device_start(struct bt_asha_device *asha_dev,
>
>         if (ret < 0)
>                 return 0;
> -       else
> -               return (++asha_dev->resume_id);
> +
> +       asha_set_streaming(asha_dev, true);
> +       return (++asha_dev->resume_id);
>  }
>
>  unsigned int bt_asha_device_stop(struct bt_asha_device *asha_dev)
>  {
> +       asha_set_streaming(asha_dev, false);
> +
>         bt_asha_stop(asha_dev->asha);
>
>         if (asha_dev->io) {
> @@ -190,6 +225,8 @@ unsigned int bt_asha_device_stop(struct bt_asha_device *asha_dev)
>
>  void bt_asha_device_state_reset(struct bt_asha_device *asha_dev)
>  {
> +       asha_set_streaming(asha_dev, false);
> +
>         if (asha_dev->io) {
>                 g_io_channel_shutdown(asha_dev->io, TRUE, NULL);
>                 g_io_channel_unref(asha_dev->io);
> @@ -371,6 +408,8 @@ static void asha_source_device_remove(struct btd_service *service)
>                 return;
>         }
>
> +       asha_set_streaming(asha_dev, false);
> +
>         bt_asha_free(asha_dev->asha);
>         g_free(asha_dev);
>  }
> diff --git a/src/adapter.c b/src/adapter.c
> index 6588a6e2bd..16a0920923 100644
> --- a/src/adapter.c
> +++ b/src/adapter.c
> @@ -304,6 +304,7 @@ struct btd_adapter {
>                                          * without delay */
>         uint8_t discovery_type;         /* current active discovery type */
>         uint8_t discovery_enable;       /* discovery enabled/disabled */
> +       unsigned int le_audio_active;   /* Active ASHA streams */
>         bool discovery_suspended;       /* discovery has been suspended */
>         bool discovery_discoverable;    /* discoverable while discovering */
>         GSList *discovery_list;         /* list of discovery clients */
> @@ -1886,6 +1887,8 @@ static void discovery_remove(struct discovery_client *client)
>  }
>
>  static void trigger_start_discovery(struct btd_adapter *adapter, guint delay);
> +static int update_discovery_filter(struct btd_adapter *adapter);
> +static uint8_t discovery_scan_type(struct btd_adapter *adapter);
>
>  static struct discovery_client *discovery_complete(struct btd_adapter *adapter,
>                                                 uint8_t status)
> @@ -1964,6 +1967,11 @@ static void start_discovery_complete(uint8_t status, uint16_t length,
>
>                 discovery_complete(adapter, status);
>
> +               /* Audio or filters may change while START is pending. */
> +               if (!adapter->discovery_suspended &&
> +                   adapter->discovery_type != discovery_scan_type(adapter))
> +                       trigger_start_discovery(adapter, 0);
> +
>                 if (adapter->discovering)
>                         return;
>
> @@ -1987,23 +1995,39 @@ static void start_discovery_complete(uint8_t status, uint16_t length,
>         trigger_start_discovery(adapter, IDLE_DISCOV_TIMEOUT * 2);
>  }
>
> +static uint8_t discovery_scan_type(struct btd_adapter *adapter)
> +{
> +       uint8_t type = adapter->current_discovery_filter ?
> +                               adapter->current_discovery_filter->type :
> +                               get_scan_type(adapter);
> +
> +       if (adapter->le_audio_active)
> +               type &= ~SCAN_TYPE_BREDR;
> +
> +       return type;
> +}
> +
>  static bool start_discovery_timeout(gpointer user_data)
>  {
>         struct btd_adapter *adapter = user_data;
>         struct mgmt_cp_start_service_discovery *sd_cp;
> +       size_t sd_len;
>         uint8_t new_type;
>
>         DBG("");
>
>         adapter->discovery_idle_timeout = 0;
>
> +       if (!adapter->discovery_list || adapter->discovery_suspended)
> +               return FALSE;
> +
>         /* If we're doing filtered discovery, it must be quickly restarted */
>         adapter->no_scan_restart_delay = !!adapter->current_discovery_filter;
>
>         DBG("adapter->current_discovery_filter == %d",
>             !!adapter->current_discovery_filter);
>
> -       new_type = get_scan_type(adapter);
> +       new_type = discovery_scan_type(adapter);
>
>         if (adapter->discovery_enable == 0x01) {
>                 struct mgmt_cp_stop_discovery cp;
> @@ -2047,11 +2071,27 @@ static bool start_discovery_timeout(gpointer user_data)
>
>         }
>
> +       if (!new_type) {
> +               struct discovery_client *client;
> +
> +               /* Reject new requests; keep sessions until audio stops. */
> +               client = discovery_complete(adapter, MGMT_STATUS_BUSY);
> +               if (client) {
> +                       discovery_remove(client);
> +
> +                       if (adapter->discovery_list)
> +                               update_discovery_filter(adapter);
> +               }
> +
> +               return FALSE;
> +       }
> +
>         /* Regular discovery is required */
>         if (!adapter->current_discovery_filter) {
>                 struct mgmt_cp_start_discovery cp;
>
>                 cp.type = new_type;
> +
>                 mgmt_send(adapter->mgmt, MGMT_OP_START_DISCOVERY,
>                                         adapter->dev_id, sizeof(cp), &cp,
>                                         start_discovery_complete, adapter,
> @@ -2060,18 +2100,25 @@ static bool start_discovery_timeout(gpointer user_data)
>                 return FALSE;
>         }
>
> -       /* Filtered discovery is required */
> -       sd_cp = adapter->current_discovery_filter;
> +       /* Keep the requested filter intact for when audio stops. */
> +       sd_len = sizeof(*sd_cp) +
> +               btohs(adapter->current_discovery_filter->uuid_count) * 16;
> +       sd_cp = util_memdup(adapter->current_discovery_filter, sd_len);
> +       if (!sd_cp)
> +               return FALSE;
> +
> +       sd_cp->type = new_type;
>
>         DBG("sending MGMT_OP_START_SERVICE_DISCOVERY %d, %d, %d",
>                                 sd_cp->rssi, sd_cp->type,
>                                 btohs(sd_cp->uuid_count));
>
>         mgmt_send(adapter->mgmt, MGMT_OP_START_SERVICE_DISCOVERY,
> -                 adapter->dev_id, sizeof(*sd_cp) +
> -                 btohs(sd_cp->uuid_count) * 16,
> +                 adapter->dev_id, sd_len,
>                   sd_cp, start_discovery_complete, adapter, NULL);
>
> +       free(sd_cp);
> +
>         return FALSE;
>  }
>
> @@ -6358,6 +6405,24 @@ struct btd_adapter *btd_adapter_ref(struct btd_adapter *adapter)
>         return adapter;
>  }
>
> +void btd_adapter_le_audio_ref(struct btd_adapter *adapter)
> +{
> +       if (adapter->le_audio_active++)
> +               return;
> +
> +       if (adapter->discovery_list && !adapter->discovery_suspended)
> +               trigger_start_discovery(adapter, 0);
> +}
> +
> +void btd_adapter_le_audio_unref(struct btd_adapter *adapter)
> +{
> +       if (!adapter->le_audio_active || --adapter->le_audio_active)
> +               return;
> +
> +       if (adapter->discovery_list && !adapter->discovery_suspended)
> +               trigger_start_discovery(adapter, 0);
> +}
> +
>  void btd_adapter_unref(struct btd_adapter *adapter)
>  {
>         if (__sync_sub_and_fetch(&adapter->ref_count, 1))
> diff --git a/src/adapter.h b/src/adapter.h
> index 583168f4bc..d5cda2d96b 100644
> --- a/src/adapter.h
> +++ b/src/adapter.h
> @@ -119,6 +119,10 @@ bool btd_adapter_uuid_is_allowed(struct btd_adapter *adapter, const char *uuid);
>  struct btd_adapter *btd_adapter_ref(struct btd_adapter *adapter);
>  void btd_adapter_unref(struct btd_adapter *adapter);
>
> +/* Defer BR/EDR discovery while ASHA streams are active. */
> +void btd_adapter_le_audio_ref(struct btd_adapter *adapter);
> +void btd_adapter_le_audio_unref(struct btd_adapter *adapter);

Ok, I don't think I agree with this design. First, what does BR/EDR
have to do with ASHA streams? I thought ASHA was LE only, and then the
naming says le_audio_ref? ASHA is not LE Audio. If we want to express
conflicts, that needs to be part of the driver resolving logic at the
core so it doesn't probe conflicting drivers.

>  void btd_adapter_set_class(struct btd_adapter *adapter, uint8_t major,
>                                                         uint8_t minor);
>  int btd_adapter_set_name(struct btd_adapter *adapter, const char *name);
>
> base-commit: a8067198717b38391ca183ed7f41a69ec4b81b6e
> --
> 2.56.0
>
>


-- 
Luiz Augusto von Dentz

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

end of thread, other threads:[~2026-11-10 21:30 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-28 13:32 [RFC PATCH RESEND] asha: Defer BR/EDR inquiry while streaming Kyle Pepper
2026-10-28 16:24 ` [RFC,RESEND] " bluez.test.bot
2026-11-07  1:49 ` [RFC PATCH v2] " Kyle Pepper
2026-11-07  2:32   ` [RFC,v2] " bluez.test.bot
2026-11-07  2:47   ` [RFC PATCH v3] " Kyle Pepper
2026-11-07  8:58     ` [RFC,v3] " bluez.test.bot
2026-11-10 21:30     ` [RFC PATCH v3] " Luiz Augusto von Dentz

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