Linux bluetooth development
 help / color / mirror / Atom feed
* [bluez/bluez]
From: BluezTestBot @ 2026-06-14 12:08 UTC (permalink / raw)
  To: linux-bluetooth

  Branch: refs/heads/1111248
  Home:   https://github.com/bluez/bluez

To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications

^ permalink raw reply

* [bluez/bluez] ddb5d4: media: use custom DBus timeouts only when remote s...
From: Pauli Virtanen @ 2026-06-14 12:08 UTC (permalink / raw)
  To: linux-bluetooth

  Branch: refs/heads/1111256
  Home:   https://github.com/bluez/bluez
  Commit: ddb5d4c135465f5645d42dbe978912fbf0552ee1
      https://github.com/bluez/bluez/commit/ddb5d4c135465f5645d42dbe978912fbf0552ee1
  Author: Pauli Virtanen <pav@iki.fi>
  Date:   2026-06-14 (Sun, 14 Jun 2026)

  Changed paths:
    M profiles/audio/media.c

  Log Message:
  -----------
  media: use custom DBus timeouts only when remote side is waiting

Under high system load (VM instance on boot) it's observed the 3 sec
timeout BlueZ uses for BAP broadcast SetConfiguration may be missed by
Wireplumber, as these are set up immediately on startup together with
any other setup (eg ALSA) that may need time.

There's no actual need for using a short custom timeout in BlueZ for
this, as in this case there is no remote side that is waiting for a reply.

Fix by limiting custom timeouts to cases where there is a waiting
remote, and use separate defines for A2DP and BAP.



To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications

^ permalink raw reply

* [bluez/bluez] 9a87a6: shared/bap: Initialize ucast/bcast IDs as unset
From: Šimon Mikuda @ 2026-06-14 12:08 UTC (permalink / raw)
  To: linux-bluetooth

  Branch: refs/heads/1111255
  Home:   https://github.com/bluez/bluez
  Commit: 9a87a631641c71b07e2c56a71c5ec144c5a01d17
      https://github.com/bluez/bluez/commit/9a87a631641c71b07e2c56a71c5ec144c5a01d17
  Author: Simon Mikuda <simon.mikuda@streamunlimited.com>
  Date:   2026-06-14 (Sun, 14 Jun 2026)

  Changed paths:
    M src/shared/bap.c
    M unit/test-bap.c

  Log Message:
  -----------
  shared/bap: Initialize ucast/bcast IDs as unset

Also change some lines where CIS should be used instead of CIG


  Commit: 06237947f55082754809d11340a6639c87a2e295
      https://github.com/bluez/bluez/commit/06237947f55082754809d11340a6639c87a2e295
  Author: Simon Mikuda <simon.mikuda@streamunlimited.com>
  Date:   2026-06-14 (Sun, 14 Jun 2026)

  Changed paths:
    M src/shared/bap.c

  Log Message:
  -----------
  shared/bap: Don't link server ucast streams before CIS IDs are assigned

bap_ucast_io_link pairs streams whose CIG/CIS IDs match, but the IDs
are unset in Codec Configured state, so a Sink and Source bound for
different CISes get linked. The stray link later propagates a
disconnect to the wrong ASE and breaks Receiver Start Ready.

Skip linking until QoS Configured assigns the IDs.

Fixes PTS test BAP/USR/STR/BV-362-C


Compare: https://github.com/bluez/bluez/compare/9a87a631641c%5E...06237947f550

To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications

^ permalink raw reply

* [bluez/bluez] 5b79ca: gatt-database: Prefer notifications over indications
From: Šimon Mikuda @ 2026-06-14 12:08 UTC (permalink / raw)
  To: linux-bluetooth

  Branch: refs/heads/1111253
  Home:   https://github.com/bluez/bluez
  Commit: 5b79ca3d0746d5f3baaf1cabc63c7daf898db7af
      https://github.com/bluez/bluez/commit/5b79ca3d0746d5f3baaf1cabc63c7daf898db7af
  Author: Simon Mikuda <simon.mikuda@streamunlimited.com>
  Date:   2026-06-14 (Sun, 14 Jun 2026)

  Changed paths:
    M src/gatt-database.c

  Log Message:
  -----------
  gatt-database: Prefer notifications over indications

When both notifications and indications are enabled (CCC value=0x0003)
we will send notifications by default.



To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications

^ permalink raw reply

* [bluez/bluez] 038ea1: shared/bap: Transition ASE to QoS Configured on CI...
From: Šimon Mikuda @ 2026-06-14 12:08 UTC (permalink / raw)
  To: linux-bluetooth

  Branch: refs/heads/1111249
  Home:   https://github.com/bluez/bluez
  Commit: 038ea13b8cc1c3e46a4ef8d4956af74696470a39
      https://github.com/bluez/bluez/commit/038ea13b8cc1c3e46a4ef8d4956af74696470a39
  Author: Simon Mikuda <simon.mikuda@streamunlimited.com>
  Date:   2026-06-14 (Sun, 14 Jun 2026)

  Changed paths:
    M src/shared/bap.c

  Log Message:
  -----------
  shared/bap: Transition ASE to QoS Configured on CIS loss

stream_io_disconnected() only handled the Releasing state, leaving
Enabling, Streaming and Disabling ASEs stuck when the CIS was lost
unexpectedly.

The ASE shall autonomously move to QoS Configured on loss of the
CIS and notify the peer

Fixes PTS test BAP/USR/SCC/BV-167-C


  Commit: df54038451324d0a5be729ba7cd155b5a8c0b27e
      https://github.com/bluez/bluez/commit/df54038451324d0a5be729ba7cd155b5a8c0b27e
  Author: Simon Mikuda <simon.mikuda@streamunlimited.com>
  Date:   2026-06-14 (Sun, 14 Jun 2026)

  Changed paths:
    M unit/test-bap.c

  Log Message:
  -----------
  unit/bap: Add CIS loss test

Verify a Source ASE in the Enabling state transitions to QoS Configured
rather than Disabling when its CIS is lost.

Assisted-by: ClaudeCode:claude-opus-4.8


Compare: https://github.com/bluez/bluez/compare/038ea13b8cc1%5E...df5403845132

To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications

^ permalink raw reply

* [PATCH BlueZ v2] media: use custom DBus timeouts only when remote side is waiting
From: Pauli Virtanen @ 2026-06-14 11:22 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Pauli Virtanen

Under high system load (VM instance on boot) it's observed the 3 sec
timeout BlueZ uses for BAP broadcast SetConfiguration may be missed by
Wireplumber, as these are set up immediately on startup together with
any other setup (eg ALSA) that may need time.

There's no actual need for using a short custom timeout in BlueZ for
this, as in this case there is no remote side that is waiting for a reply.

Fix by limiting custom timeouts to cases where there is a waiting
remote, and use separate defines for A2DP and BAP.
---

Notes:
    v2: shorter BAP_REQUEST_TIMEOUT_MSEC, no particular reason to have
        it 20 sec. Use that for cases where there may be remote side,
        i.e. all except us being bcast source.

 profiles/audio/media.c | 30 ++++++++++++++++++++++--------
 1 file changed, 22 insertions(+), 8 deletions(-)

diff --git a/profiles/audio/media.c b/profiles/audio/media.c
index cdaafb04e..5d9ea2cbc 100644
--- a/profiles/audio/media.c
+++ b/profiles/audio/media.c
@@ -71,7 +71,11 @@
 #define MEDIA_ENDPOINT_INTERFACE "org.bluez.MediaEndpoint1"
 #define MEDIA_PLAYER_INTERFACE "org.mpris.MediaPlayer2.Player"
 
-#define REQUEST_TIMEOUT (3 * 1000)		/* 3 seconds */
+/* Timeout should be less than avdtp request timeout (4 seconds) */
+#define A2DP_REQUEST_TIMEOUT_MSEC	(3 * 1000)
+
+/* Timeout should be less than ATT timeout (30 seconds) */
+#define BAP_REQUEST_TIMEOUT_MSEC	(3 * 1000)
 
 struct media_app {
 	struct media_adapter	*adapter;
@@ -465,16 +469,16 @@ static gboolean media_endpoint_async_call(DBusMessage *msg,
 					struct media_transport *transport,
 					media_endpoint_cb_t cb,
 					void *user_data,
-					GDestroyNotify destroy)
+					GDestroyNotify destroy,
+					int timeout_msec)
 {
 	struct endpoint_request *request;
 
 	request = g_new0(struct endpoint_request, 1);
 
-	/* Timeout should be less than avdtp request timeout (4 seconds) */
 	if (g_dbus_send_message_with_reply(btd_get_dbus_connection(),
 						msg, &request->call,
-						REQUEST_TIMEOUT) == FALSE) {
+						timeout_msec) == FALSE) {
 		error("D-Bus send failed");
 		g_free(request);
 		return FALSE;
@@ -521,7 +525,7 @@ static gboolean select_configuration(struct media_endpoint *endpoint,
 					DBUS_TYPE_INVALID);
 
 	return media_endpoint_async_call(msg, endpoint, NULL,
-						cb, user_data, destroy);
+						cb, user_data, destroy, -1);
 }
 
 static int transport_device_cmp(gconstpointer data, gconstpointer user_data)
@@ -604,7 +608,8 @@ static gboolean set_configuration(struct media_endpoint *endpoint,
 	g_dbus_get_properties(conn, path, "org.bluez.MediaTransport1", &iter);
 
 	return media_endpoint_async_call(msg, endpoint, transport,
-						cb, user_data, destroy);
+						cb, user_data, destroy,
+						A2DP_REQUEST_TIMEOUT_MSEC);
 }
 #endif
 
@@ -1093,7 +1098,7 @@ static int pac_select(struct bt_bap_pac *lpac, struct bt_bap_pac *rpac,
 	dbus_message_iter_close_container(&iter, &dict);
 
 	if (!media_endpoint_async_call(msg, endpoint, NULL, pac_select_cb,
-								data, free))
+								data, free, -1))
 		return -EIO;
 
 	return 0;
@@ -1233,6 +1238,7 @@ static int pac_config(struct bt_bap_stream *stream, struct iovec *cfg,
 	DBusMessage *msg;
 	DBusMessageIter iter;
 	const char *path;
+	int timeout_msec;
 
 	DBG("endpoint %p stream %p", endpoint, stream);
 
@@ -1243,9 +1249,16 @@ static int pac_config(struct bt_bap_stream *stream, struct iovec *cfg,
 	switch (bt_bap_stream_get_type(stream)) {
 	case BT_BAP_STREAM_TYPE_UCAST:
 		transport = pac_ucast_config(stream, cfg, endpoint);
+		timeout_msec = BAP_REQUEST_TIMEOUT_MSEC;
 		break;
 	case BT_BAP_STREAM_TYPE_BCAST:
 		transport = pac_bcast_config(stream, cfg, endpoint);
+
+		/* If we are sink, BASS remote may be waiting: custom timeout */
+		if (bt_bap_stream_get_dir(stream) == BT_BAP_SOURCE)
+			timeout_msec = BAP_REQUEST_TIMEOUT_MSEC;
+		else
+			timeout_msec = -1;
 		break;
 	default:
 		transport = NULL;
@@ -1279,7 +1292,8 @@ static int pac_config(struct bt_bap_stream *stream, struct iovec *cfg,
 	g_dbus_get_properties(conn, path, "org.bluez.MediaTransport1", &iter);
 
 	if (!media_endpoint_async_call(msg, endpoint, transport,
-						pac_config_cb, data, free))
+						pac_config_cb, data, free,
+						timeout_msec))
 		return -EIO;
 
 	return 0;
-- 
2.54.0


^ permalink raw reply related

* RE: [BlueZ,v2,1/2] shared/bap: Initialize ucast/bcast IDs as unset
From: bluez.test.bot @ 2026-06-14 11:05 UTC (permalink / raw)
  To: linux-bluetooth, simon.mikuda
In-Reply-To: <20260614095520.1090106-1-simon.mikuda@streamunlimited.com>

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

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

Dear submitter,

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

---Test result---

Test Summary:
CheckPatch                    PASS      0.92 seconds
GitLint                       FAIL      0.63 seconds
BuildEll                      PASS      20.70 seconds
BluezMake                     PASS      656.66 seconds
MakeCheck                     PASS      18.62 seconds
MakeDistcheck                 PASS      246.18 seconds
CheckValgrind                 PASS      294.94 seconds
CheckSmatch                   WARNING   355.15 seconds
bluezmakeextell               PASS      183.39 seconds
IncrementalBuild              PASS      673.90 seconds
ScanBuild                     PASS      1033.04 seconds

Details
##############################
Test: GitLint - FAIL
Desc: Run gitlint
Output:
[BlueZ,v2,2/2] shared/bap: Don't link server ucast streams before CIS IDs are assigned

1: T1 Title exceeds max length (86>80): "[BlueZ,v2,2/2] shared/bap: Don't link server ucast streams before CIS IDs are assigned"
##############################
Test: CheckSmatch - WARNING
Desc: Run smatch tool with source
Output:
src/shared/bap.c:317:25: warning: array of flexible structuressrc/shared/bap.c: note: in included file:./src/shared/ascs.h:88:25: warning: array of flexible structuressrc/shared/bap.c:317:25: warning: array of flexible structuressrc/shared/bap.c: note: in included file:./src/shared/ascs.h:88:25: warning: array of flexible structuressrc/shared/bap.c:317:25: warning: array of flexible structuressrc/shared/bap.c: note: in included file:./src/shared/ascs.h:88:25: warning: array of flexible structuressrc/shared/bap.c:317:25: warning: array of flexible structuressrc/shared/bap.c: note: in included file:./src/shared/ascs.h:88:25: warning: array of flexible structuressrc/shared/bap.c:317:25: warning: array of flexible structuressrc/shared/bap.c: note: in included file:./src/shared/ascs.h:88:25: warning: array of flexible structuressrc/shared/bap.c:317:25: warning: array of flexible structuressrc/shared/bap.c: note: in included file:./src/shared/ascs.h:88:25: warning: array of flexible structures


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

---
Regards,
Linux Bluetooth


^ permalink raw reply

* [PATCH BlueZ v3 2/2] shared/bap: Don't link server ucast streams before CIS IDs are assigned
From: Simon Mikuda @ 2026-06-14 10:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Simon Mikuda
In-Reply-To: <20260614105016.1147112-1-simon.mikuda@streamunlimited.com>

bap_ucast_io_link pairs streams whose CIG/CIS IDs match, but the IDs
are unset in Codec Configured state, so a Sink and Source bound for
different CISes get linked. The stray link later propagates a
disconnect to the wrong ASE and breaks Receiver Start Ready.

Skip linking until QoS Configured assigns the IDs.

Fixes PTS test BAP/USR/STR/BV-362-C
---
 src/shared/bap.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/shared/bap.c b/src/shared/bap.c
index e8fbf0899..6ba9d3e06 100644
--- a/src/shared/bap.c
+++ b/src/shared/bap.c
@@ -2679,6 +2679,15 @@ static int bap_ucast_io_link(struct bt_bap_stream *stream,
 			stream->ep->dir == link->ep->dir)
 		return -EINVAL;
 
+	/* The server pairs Sink and Source by matching CIG/CIS, but those are
+	 * unset until QoS Configured, so it would link unrelated ASEs (CIS 0
+	 * is otherwise a valid ID). Clients gate linking on the lock instead.
+	 */
+	if (!stream->client &&
+			(stream->qos.ucast.cis_id == BT_ISO_QOS_CIS_UNSET ||
+			link->qos.ucast.cis_id == BT_ISO_QOS_CIS_UNSET))
+		return -EINVAL;
+
 	if (stream->client && !(stream->locked && link->locked))
 		return -EINVAL;
 
-- 
2.43.0


^ permalink raw reply related

* [PATCH BlueZ v3 1/2] shared/bap: Initialize ucast/bcast IDs as unset
From: Simon Mikuda @ 2026-06-14 10:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Simon Mikuda
In-Reply-To: <fa0febe1-5866-4a3f-9f86-ae70e9d4b22d@streamunlimited.com>

Also change some lines where CIS should be used instead of CIG
---
 src/shared/bap.c | 13 +++++++++++++
 unit/test-bap.c  |  4 ++--
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/src/shared/bap.c b/src/shared/bap.c
index deb85b264..e8fbf0899 100644
--- a/src/shared/bap.c
+++ b/src/shared/bap.c
@@ -2902,6 +2902,19 @@ static struct bt_bap_stream *bap_stream_new(struct bt_bap *bap,
 	stream->ops = bap_stream_new_ops(stream);
 	stream->pending_states = queue_new();
 
+	switch (bt_bap_pac_get_type(lpac)) {
+	case BT_BAP_SINK:
+	case BT_BAP_SOURCE:
+		stream->qos.ucast.cig_id = BT_ISO_QOS_CIG_UNSET;
+		stream->qos.ucast.cis_id = BT_ISO_QOS_CIS_UNSET;
+		break;
+	case BT_BAP_BCAST_SOURCE:
+	case BT_BAP_BCAST_SINK:
+		stream->qos.bcast.big = BT_ISO_QOS_BIG_UNSET;
+		stream->qos.bcast.bis = BT_ISO_QOS_BIS_UNSET;
+		break;
+	}
+
 	queue_push_tail(bap->streams, stream);
 
 	return bt_bap_stream_ref(stream);
diff --git a/unit/test-bap.c b/unit/test-bap.c
index 03b19678e..4ac9a207c 100644
--- a/unit/test-bap.c
+++ b/unit/test-bap.c
@@ -9894,7 +9894,7 @@ static int streaming_ucl_create_io(struct bt_bap_stream *stream,
 
 	i = qos[0] ? qos[0]->ucast.cis_id : qos[1]->ucast.cis_id;
 
-	if (i == BT_ISO_QOS_CIG_UNSET) {
+	if (i == BT_ISO_QOS_CIS_UNSET) {
 		for (i = 0; i < ARRAY_SIZE(data->fds); ++i) {
 			if (data->fds[i][0] > 0)
 				continue;
@@ -10000,7 +10000,7 @@ static void test_select_cb(struct bt_bap_pac *pac, int err,
 
 	if (!data->cfg->streams) {
 		qos->ucast.cig_id = BT_ISO_QOS_CIG_UNSET;
-		qos->ucast.cis_id = BT_ISO_QOS_CIG_UNSET;
+		qos->ucast.cis_id = BT_ISO_QOS_CIS_UNSET;
 	} else {
 		/* All streams to separate CIS.
 		 *
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH BlueZ] gatt-client: Add PreferredNotifyType property
From: Simon Mikuda @ 2026-06-14 10:34 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <CABBYNZL-A=NpnfiO9GO66TNX5QaEuvpSZ9fuBk0Jo+aNtr7huA@mail.gmail.com>

I send a patch that will use notifications by default, when both 
indications+notifications are enabled.

I am not sure what is meant by this:

 > when an acknowledgment is not required by a higher-layer specification

in that case we should send indication, which was previous behavior...

On 6/8/26 17:21, Luiz Augusto von Dentz wrote:
> Hi Simon,
>
> On Mon, Jun 8, 2026 at 10:31 AM Simon Mikuda
> <simon.mikuda@streamunlimited.com> wrote:
>> When a characteristic supports both notifications and indications the
>> CCC we always register for notifications, leaving no way to choose
>> indications from D-Bus.
>>
>> Add PreferredNotifyType (string, "notification"/"indication") to
>> org.bluez.GattCharacteristic1, only present when both flags are set.
>> StartNotify() and AcquireNotify() honor it on the next CCC write.
>> ---
>>   doc/org.bluez.GattCharacteristic.rst | 21 +++++++
>>   src/gatt-client.c                    | 85 ++++++++++++++++++++++++++++
>>   src/shared/gatt-client.c             | 31 +++++++++-
>>   src/shared/gatt-client.h             |  3 +
>>   4 files changed, 138 insertions(+), 2 deletions(-)
>>
>> diff --git a/doc/org.bluez.GattCharacteristic.rst b/doc/org.bluez.GattCharacteristic.rst
>> index 805f39593..f7e541590 100644
>> --- a/doc/org.bluez.GattCharacteristic.rst
>> +++ b/doc/org.bluez.GattCharacteristic.rst
>> @@ -401,3 +401,24 @@ uint16 MTU [read-only]
>>
>>   Characteristic MTU, this is valid both for **ReadValue()** and **WriteValue()**
>>   but either method can use long procedures when supported.
>> +
>> +string PreferredNotifyType [readwrite, optional, experimental]
>> +``````````````````````````````````````````````````````````````
>> +
>> +Selects whether **StartNotify()** and **AcquireNotify()** enable notifications
>> +or indications when the characteristic supports both. Only present when both
>> +"notify" and "indicate" flags are set.
>> +
>> +Possible values:
>> +
>> +:"notification":
>> +
>> +       Enable notifications (CCC = 0x0001). Default.
>> +
>> +:"indication":
>> +
>> +       Enable indications (CCC = 0x0002).
>> +
>> +Note: the preference applies on the next CCC write. If another client has
>> +already enabled the CCC on this characteristic, the existing setting is kept
>> +and the new preference takes effect only after the last subscriber stops.
> Well the spec seems to have changed to allow setting both notify and
> indicate simultaneously as well:
>
> If both the Notification and Indication bits are set, then the server
> shall use the notification procedure (see Section 4.10) when an
> acknowledgment is not required by a higher-layer specification or
> shall use the indication procedure (see Section 4.11) when an
> acknowledgment is required. The server should not use both procedures
> to send the same characteristic value.
>
> So perhaps we need to handle that as well, that said I don't know if
> it wouldn't be more efficient to add another method which would enable
> passing the value directly rather modifying the
> StartNotify/AcquireNotify behavior, but then we would need to create a
> different interface name in order to break the existing methods, so
> maybe going wit this is better and we just need to handle 0x0003 as
> being both enabled and the server decides what to do with it.
>
>> diff --git a/src/gatt-client.c b/src/gatt-client.c
>> index 3baf95c4f..29564a87d 100644
>> --- a/src/gatt-client.c
>> +++ b/src/gatt-client.c
>> @@ -115,6 +115,7 @@ struct characteristic {
>>          struct queue *descs;
>>
>>          bool notifying;
>> +       bool prefer_indicate;
>>          struct queue *notify_clients;
>>   };
>>
>> @@ -1595,6 +1596,9 @@ static DBusMessage *characteristic_acquire_notify(DBusConnection *conn,
>>          if (!client)
>>                  return btd_error_failed(msg, "Failed allocate notify session");
>>
>> +       bt_gatt_client_set_notify_prefer_indicate(gatt, chrc->value_handle,
>> +                                                       chrc->prefer_indicate);
>> +
>>          client->notify_id = bt_gatt_client_register_notify(gatt,
>>                                                  chrc->value_handle,
>>                                                  register_notify_io_cb,
>> @@ -1673,6 +1677,9 @@ static DBusMessage *characteristic_start_notify(DBusConnection *conn,
>>
>>          op = async_dbus_op_new(msg, client);
>>
>> +       bt_gatt_client_set_notify_prefer_indicate(gatt, chrc->value_handle,
>> +                                                       chrc->prefer_indicate);
>> +
>>          client->notify_id = bt_gatt_client_register_notify(gatt,
>>                                                  chrc->value_handle,
>>                                                  register_notify_cb, notify_cb,
>> @@ -1719,6 +1726,76 @@ static DBusMessage *characteristic_stop_notify(DBusConnection *conn,
>>          return dbus_message_new_method_return(msg);
>>   }
>>
>> +static gboolean
>> +characteristic_get_prefer_notify_type(const GDBusPropertyTable *property,
>> +                                       DBusMessageIter *iter, void *data)
>> +{
>> +       struct characteristic *chrc = data;
>> +       const char *str = chrc->prefer_indicate ? "indication" : "notification";
>> +
>> +       dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &str);
>> +
>> +       return TRUE;
>> +}
>> +
>> +static void
>> +characteristic_set_prefer_notify_type(const GDBusPropertyTable *property,
>> +                                       DBusMessageIter *iter,
>> +                                       GDBusPendingPropertySet id, void *data)
>> +{
>> +       struct characteristic *chrc = data;
>> +       struct bt_gatt_client *gatt = chrc->service->client->gatt;
>> +       const char *str;
>> +       bool prefer;
>> +
>> +       if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_STRING) {
>> +               g_dbus_pending_property_error(id,
>> +                                       ERROR_INTERFACE ".InvalidArguments",
>> +                                       "Invalid arguments in method call");
>> +               return;
>> +       }
>> +
>> +       dbus_message_iter_get_basic(iter, &str);
>> +
>> +       if (!strcmp(str, "notification"))
>> +               prefer = false;
>> +       else if (!strcmp(str, "indication"))
>> +               prefer = true;
>> +       else {
>> +               g_dbus_pending_property_error(id,
>> +                                       ERROR_INTERFACE ".InvalidArguments",
>> +                                       "Invalid arguments in method call");
>> +               return;
>> +       }
>> +
>> +       if (chrc->prefer_indicate == prefer) {
>> +               g_dbus_pending_property_success(id);
>> +               return;
>> +       }
>> +
>> +       chrc->prefer_indicate = prefer;
>> +
>> +       if (gatt)
>> +               bt_gatt_client_set_notify_prefer_indicate(gatt,
>> +                                               chrc->value_handle, prefer);
>> +
>> +       g_dbus_emit_property_changed(btd_get_dbus_connection(), chrc->path,
>> +                                       GATT_CHARACTERISTIC_IFACE,
>> +                                       "PreferredNotifyType");
>> +
>> +       g_dbus_pending_property_success(id);
>> +}
>> +
>> +static gboolean
>> +characteristic_prefer_notify_type_exists(const GDBusPropertyTable *property,
>> +                                       void *data)
>> +{
>> +       struct characteristic *chrc = data;
>> +
>> +       return (chrc->props & BT_GATT_CHRC_PROP_NOTIFY) &&
>> +                               (chrc->props & BT_GATT_CHRC_PROP_INDICATE);
>> +}
>> +
>>   static const GDBusPropertyTable characteristic_properties[] = {
>>          { "Handle", "q", characteristic_get_handle },
>>          { "UUID", "s", characteristic_get_uuid, NULL, NULL },
>> @@ -1733,6 +1810,10 @@ static const GDBusPropertyTable characteristic_properties[] = {
>>          { "NotifyAcquired", "b", characteristic_get_notify_acquired, NULL,
>>                                  characteristic_notify_acquired_exists },
>>          { "MTU", "q", characteristic_get_mtu, NULL, characteristic_mtu_exists },
>> +       { "PreferredNotifyType", "s", characteristic_get_prefer_notify_type,
>> +                               characteristic_set_prefer_notify_type,
>> +                               characteristic_prefer_notify_type_exists,
>> +                               G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
>>          { }
>>   };
>>
>> @@ -2282,6 +2363,10 @@ static void register_notify(void *data, void *user_data)
>>          op = new0(struct async_dbus_op, 1);
>>          op->data = notify_client;
>>
>> +       bt_gatt_client_set_notify_prefer_indicate(client->gatt,
>> +                                       notify_client->chrc->value_handle,
>> +                                       notify_client->chrc->prefer_indicate);
>> +
>>          notify_client->notify_id = bt_gatt_client_register_notify(client->gatt,
>>                                          notify_client->chrc->value_handle,
>>                                          register_notify_cb, notify_cb,
>> diff --git a/src/shared/gatt-client.c b/src/shared/gatt-client.c
>> index a6abe8ac2..403d22758 100644
>> --- a/src/shared/gatt-client.c
>> +++ b/src/shared/gatt-client.c
>> @@ -217,6 +217,7 @@ struct notify_chrc {
>>          uint16_t properties;
>>          unsigned int notify_id;
>>          int notify_count;  /* Reference count of registered notify callbacks */
>> +       bool prefer_indicate;
>>
>>          /* Pending calls to register_notify are queued here so that they can be
>>           * processed after a write that modifies the CCC descriptor.
>> @@ -1671,9 +1672,13 @@ static bool notify_data_write_ccc(struct notify_data *notify_data, bool enable,
>>
>>          if (enable) {
>>                  /* Try to enable notifications or indications based on
>> -                * whatever the characteristic supports.
>> +                * whatever the characteristic supports. If both are
>> +                * available honor the per-chrc prefer_indicate flag.
>>                   */
>> -               if (properties & BT_GATT_CHRC_PROP_NOTIFY)
>> +               if (notify_data->chrc->prefer_indicate &&
>> +                               (properties & BT_GATT_CHRC_PROP_INDICATE))
>> +                       value = cpu_to_le16(0x0002);
>> +               else if (properties & BT_GATT_CHRC_PROP_NOTIFY)
>>                          value = cpu_to_le16(0x0001);
>>                  else if (properties & BT_GATT_CHRC_PROP_INDICATE)
>>                          value = cpu_to_le16(0x0002);
>> @@ -3838,6 +3843,28 @@ unsigned int bt_gatt_client_register_notify(struct bt_gatt_client *client,
>>                                                          user_data, destroy);
>>   }
>>
>> +bool bt_gatt_client_set_notify_prefer_indicate(struct bt_gatt_client *client,
>> +                                               uint16_t value_handle,
>> +                                               bool prefer)
>> +{
>> +       struct notify_chrc *chrc;
>> +
>> +       if (!client || !client->db || !value_handle)
>> +               return false;
>> +
>> +       chrc = queue_find(client->notify_chrcs, match_notify_chrc_value_handle,
>> +                                               UINT_TO_PTR(value_handle));
>> +       if (!chrc) {
>> +               chrc = notify_chrc_create(client, value_handle);
>> +               if (!chrc)
>> +                       return false;
>> +       }
>> +
>> +       chrc->prefer_indicate = prefer;
>> +
>> +       return true;
>> +}
>> +
>>   bool bt_gatt_client_unregister_notify(struct bt_gatt_client *client,
>>                                                          unsigned int id)
>>   {
>> diff --git a/src/shared/gatt-client.h b/src/shared/gatt-client.h
>> index 63cf99500..0d08f8014 100644
>> --- a/src/shared/gatt-client.h
>> +++ b/src/shared/gatt-client.h
>> @@ -124,6 +124,9 @@ unsigned int bt_gatt_client_register_notify(struct bt_gatt_client *client,
>>                                  bt_gatt_client_destroy_func_t destroy);
>>   bool bt_gatt_client_unregister_notify(struct bt_gatt_client *client,
>>                                                          unsigned int id);
>> +bool bt_gatt_client_set_notify_prefer_indicate(struct bt_gatt_client *client,
>> +                                               uint16_t value_handle,
>> +                                               bool prefer);
>>
>>   bool bt_gatt_client_set_security(struct bt_gatt_client *client, int level);
>>   int bt_gatt_client_get_security(struct bt_gatt_client *client);
>> --
>> 2.43.0
>>
>>
>

^ permalink raw reply

* [PATCH BlueZ 2/2] gatt-database: Prefer notifications over indications
From: Simon Mikuda @ 2026-06-14 10:29 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Simon Mikuda
In-Reply-To: <CABBYNZL-A=NpnfiO9GO66TNX5QaEuvpSZ9fuBk0Jo+aNtr7huA@mail.gmail.com>

When both notifications and indications are enabled (CCC value=0x0003)
we will send notifications by default.
---
 src/gatt-database.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/gatt-database.c b/src/gatt-database.c
index 680a52952..dfa83b31a 100644
--- a/src/gatt-database.c
+++ b/src/gatt-database.c
@@ -1446,7 +1446,7 @@ static void send_notification_to_device(void *data, void *user_data)
 	 * TODO: If the device is not connected but bonded, send the
 	 * notification/indication when it becomes connected.
 	 */
-	if (!(ccc->value & 0x0002)) {
+	if (ccc->value & 0x0001) {
 		DBG("GATT server sending notification");
 		bt_gatt_server_send_notification(server,
 					notify->handle, notify->value,
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 5/5] Bluetooth: enable context analysis
From: Pauli Virtanen @ 2026-06-14 10:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Pauli Virtanen
In-Reply-To: <cover.1781432726.git.pav@iki.fi>

Enable compiler context analysis for Bluetooth subsystem and drivers.

Signed-off-by: Pauli Virtanen <pav@iki.fi>
---
 drivers/bluetooth/Makefile    | 2 ++
 net/bluetooth/Makefile        | 2 ++
 net/bluetooth/bnep/Makefile   | 2 ++
 net/bluetooth/hidp/Makefile   | 2 ++
 net/bluetooth/rfcomm/Makefile | 2 ++
 5 files changed, 10 insertions(+)

diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile
index bafc26250b63..e6b1c1180d1d 100644
--- a/drivers/bluetooth/Makefile
+++ b/drivers/bluetooth/Makefile
@@ -50,3 +50,5 @@ hci_uart-$(CONFIG_BT_HCIUART_AG6XX)	+= hci_ag6xx.o
 hci_uart-$(CONFIG_BT_HCIUART_MRVL)	+= hci_mrvl.o
 hci_uart-$(CONFIG_BT_HCIUART_AML)	+= hci_aml.o
 hci_uart-objs				:= $(hci_uart-y)
+
+CONTEXT_ANALYSIS := y
diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
index 41049b280887..ff466ea97436 100644
--- a/net/bluetooth/Makefile
+++ b/net/bluetooth/Makefile
@@ -25,3 +25,5 @@ bluetooth-$(CONFIG_BT_MSFTEXT) += msft.o
 bluetooth-$(CONFIG_BT_AOSPEXT) += aosp.o
 bluetooth-$(CONFIG_BT_DEBUGFS) += hci_debugfs.o
 bluetooth-$(CONFIG_BT_SELFTEST) += selftest.o
+
+CONTEXT_ANALYSIS := y
diff --git a/net/bluetooth/bnep/Makefile b/net/bluetooth/bnep/Makefile
index 8af9d56bb012..f42015cc3245 100644
--- a/net/bluetooth/bnep/Makefile
+++ b/net/bluetooth/bnep/Makefile
@@ -6,3 +6,5 @@
 obj-$(CONFIG_BT_BNEP) += bnep.o
 
 bnep-objs := core.o sock.o netdev.o
+
+CONTEXT_ANALYSIS := y
diff --git a/net/bluetooth/hidp/Makefile b/net/bluetooth/hidp/Makefile
index f41b0aa02b23..53e139e41bdc 100644
--- a/net/bluetooth/hidp/Makefile
+++ b/net/bluetooth/hidp/Makefile
@@ -6,3 +6,5 @@
 obj-$(CONFIG_BT_HIDP) += hidp.o
 
 hidp-objs := core.o sock.o
+
+CONTEXT_ANALYSIS := y
diff --git a/net/bluetooth/rfcomm/Makefile b/net/bluetooth/rfcomm/Makefile
index 593e5c48c131..15f909f40f25 100644
--- a/net/bluetooth/rfcomm/Makefile
+++ b/net/bluetooth/rfcomm/Makefile
@@ -7,3 +7,5 @@ obj-$(CONFIG_BT_RFCOMM) += rfcomm.o
 
 rfcomm-y			:= core.o sock.o
 rfcomm-$(CONFIG_BT_RFCOMM_TTY)	+= tty.o
+
+CONTEXT_ANALYSIS := y
-- 
2.54.0


^ permalink raw reply related

* [PATCH v2 4/5] Bluetooth: RFCOMM: Add minimal context analysis annotations
From: Pauli Virtanen @ 2026-06-14 10:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Pauli Virtanen
In-Reply-To: <cover.1781432726.git.pav@iki.fi>

Add minimal compiler context analysis annotations, required for
compilation to pass.

Signed-off-by: Pauli Virtanen <pav@iki.fi>
---
 net/bluetooth/rfcomm/sock.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index feb302a491fa..958081adb9b5 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -60,6 +60,7 @@ static void rfcomm_sk_data_ready(struct rfcomm_dlc *d, struct sk_buff *skb)
 }
 
 static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
+	__must_hold(&d->lock)
 {
 	struct sock *sk = d->owner, *parent;
 
-- 
2.54.0


^ permalink raw reply related

* [PATCH v2 2/5] Bluetooth: hci_core: Add minimal context analysis annotations
From: Pauli Virtanen @ 2026-06-14 10:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Pauli Virtanen
In-Reply-To: <cover.1781432726.git.pav@iki.fi>

Add minimal compiler context analysis annotations, required for
compilation to pass.

compiler-context-analysis.h doesn't have tools to deal with the
conditional SRCU locking on return value used here, so just disable the
analysis in places instead of refactoring, in order to not make code
changes here.

Signed-off-by: Pauli Virtanen <pav@iki.fi>
---
 net/bluetooth/hci_core.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 5ba9fe8261ec..d1e78ae7728e 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -62,6 +62,7 @@ static DEFINE_IDA(hci_index_ida);
 /* Get HCI device by index.
  * Device is held on return. */
 static struct hci_dev *__hci_dev_get(int index, int *srcu_index)
+	__context_unsafe(/* conditional locking */)
 {
 	struct hci_dev *hdev = NULL, *d;
 
@@ -89,11 +90,13 @@ struct hci_dev *hci_dev_get(int index)
 }
 
 static struct hci_dev *hci_dev_get_srcu(int index, int *srcu_index)
+	__context_unsafe(/* conditional locking vs return */)
 {
 	return __hci_dev_get(index, srcu_index);
 }
 
 static void hci_dev_put_srcu(struct hci_dev *hdev, int srcu_index)
+	__context_unsafe(/* conditional locking vs return */)
 {
 	srcu_read_unlock(&hdev->srcu, srcu_index);
 	hci_dev_put(hdev);
-- 
2.54.0


^ permalink raw reply related

* [PATCH v2 0/5] Bluetooth: enable context analysis
From: Pauli Virtanen @ 2026-06-14 10:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Pauli Virtanen

v2:
- Add annotations to RFCOMM
- Enable analysis also for BNEP, RFCOMM, HIDP

***

Set up compiler context analysis that generate compiler warnings on
problems that Clang -Wthread-safety can detect:

https://docs.kernel.org/dev-tools/context-analysis.html

Sparse locking analysis support was removed in commit
5b63d0ae94ccfd64dcbdb693d88eb3650eb3c64c, this is its successor.

Clang 22 is required, and likely in future Clang 23 [1] (unreleased, use
snapshot eg from
https://mirrors.edge.kernel.org/pub/tools/llvm/files/prerelease/ )

This series enables the analysis and adds minimal annotations to remove
all warnings.

In future, it probably is a good idea to make more use of it and add
__must_hold, __guarded_by etc annotations.

Kernel test robot appears to be checking for these, but not sure in what
trees [2]

BlueZ testbot doesn't check these currently but it's possible to add
https://github.com/bluez/action-ci/pull/4

[1] https://lore.kernel.org/all/177996424926.1039918.344230591161201072.tip-bot2@tip-bot2/
[2] https://lore.kernel.org/all/202605060005.JYWpZXr2-lkp@intel.com/

Pauli Virtanen (5):
  Bluetooth: af_bluetooth: Add minimal context analysis annotations
  Bluetooth: hci_core: Add minimal context analysis annotations
  Bluetooth: L2CAP: Add minimal context analysis annotations
  Bluetooth: RFCOMM: Add minimal context analysis annotations
  Bluetooth: enable context analysis

 drivers/bluetooth/Makefile    | 2 ++
 net/bluetooth/Makefile        | 2 ++
 net/bluetooth/af_bluetooth.c  | 7 +++++--
 net/bluetooth/bnep/Makefile   | 2 ++
 net/bluetooth/hci_core.c      | 3 +++
 net/bluetooth/hidp/Makefile   | 2 ++
 net/bluetooth/l2cap_sock.c    | 1 +
 net/bluetooth/rfcomm/Makefile | 2 ++
 net/bluetooth/rfcomm/sock.c   | 1 +
 9 files changed, 20 insertions(+), 2 deletions(-)

-- 
2.54.0


^ permalink raw reply

* [PATCH v2 3/5] Bluetooth: L2CAP: Add minimal context analysis annotations
From: Pauli Virtanen @ 2026-06-14 10:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Pauli Virtanen
In-Reply-To: <cover.1781432726.git.pav@iki.fi>

Add minimal compiler context analysis annotations, required for
compilation to pass.

Don't check complex conn->lock usage in l2cap_sock_shutdown().  The
analysis cannot know that chan->conn pointer is never replaced by a
different l2cap_conn.

Signed-off-by: Pauli Virtanen <pav@iki.fi>
---
 net/bluetooth/l2cap_sock.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 4853f1b33449..8558a7071ff5 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1351,6 +1351,7 @@ static int __l2cap_wait_ack(struct sock *sk, struct l2cap_chan *chan)
 }
 
 static int l2cap_sock_shutdown(struct socket *sock, int how)
+	__context_unsafe(/* complex chan->conn locking */)
 {
 	struct sock *sk = sock->sk;
 	struct l2cap_chan *chan;
-- 
2.54.0


^ permalink raw reply related

* [PATCH v2 1/5] Bluetooth: af_bluetooth: Add minimal context analysis annotations
From: Pauli Virtanen @ 2026-06-14 10:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Pauli Virtanen
In-Reply-To: <cover.1781432726.git.pav@iki.fi>

Add minimal compiler context analysis annotations, required for
compilation to pass.

Signed-off-by: Pauli Virtanen <pav@iki.fi>
---
 net/bluetooth/af_bluetooth.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index bcbc11c9cb15..62b751203fb0 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -209,6 +209,7 @@ bool bt_sock_linked(struct bt_sock_list *l, struct sock *s)
 EXPORT_SYMBOL(bt_sock_linked);
 
 void bt_accept_enqueue(struct sock *parent, struct sock *sk, bool bh)
+	__context_unsafe(/* conditional locking */)
 {
 	const struct cred *old_cred;
 	struct pid *old_pid;
@@ -826,7 +827,8 @@ EXPORT_SYMBOL(bt_sock_wait_ready);
 
 #ifdef CONFIG_PROC_FS
 static void *bt_seq_start(struct seq_file *seq, loff_t *pos)
-	__acquires(seq->private->l->lock)
+	__acquires_shared(&((struct bt_sock_list *)
+			    pde_data(file_inode(seq->file)))->lock)
 {
 	struct bt_sock_list *l = pde_data(file_inode(seq->file));
 
@@ -842,7 +844,8 @@ static void *bt_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void bt_seq_stop(struct seq_file *seq, void *v)
-	__releases(seq->private->l->lock)
+	__releases_shared(&((struct bt_sock_list *)
+			    pde_data(file_inode(seq->file)))->lock)
 {
 	struct bt_sock_list *l = pde_data(file_inode(seq->file));
 
-- 
2.54.0


^ permalink raw reply related

* Re: [PATCH BlueZ v2 1/2] shared/bap: Initialize ucast/bcast IDs as unset
From: Pauli Virtanen @ 2026-06-14 10:24 UTC (permalink / raw)
  To: Simon Mikuda, linux-bluetooth
In-Reply-To: <20260614095520.1090106-1-simon.mikuda@streamunlimited.com>

Hi,

su, 2026-06-14 kello 11:55 +0200, Simon Mikuda kirjoitti:
> Also change some lines where CIS should be used instead of CIG
> ---
>  src/shared/bap.c | 4 ++++
>  unit/test-bap.c  | 4 ++--
>  2 files changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/src/shared/bap.c b/src/shared/bap.c
> index deb85b264..41139181b 100644
> --- a/src/shared/bap.c
> +++ b/src/shared/bap.c
> @@ -2901,6 +2901,10 @@ static struct bt_bap_stream *bap_stream_new(struct bt_bap *bap,
>  	stream->client = client;
>  	stream->ops = bap_stream_new_ops(stream);
>  	stream->pending_states = queue_new();
> +	stream->qos.bcast.big = BT_ISO_QOS_BIG_UNSET;
> +	stream->qos.bcast.bis = BT_ISO_QOS_BIS_UNSET;
> +	stream->qos.ucast.cig_id = BT_ISO_QOS_CIG_UNSET;
> +	stream->qos.ucast.cis_id = BT_ISO_QOS_CIS_UNSET;

qos.bcast and qos.ucast are overlapping union members, so strictly
speaking this should check bt_bap_stream_get_type(stream) and set the
relevant union member.

>  
>  	queue_push_tail(bap->streams, stream);
>  
> diff --git a/unit/test-bap.c b/unit/test-bap.c
> index 03b19678e..4ac9a207c 100644
> --- a/unit/test-bap.c
> +++ b/unit/test-bap.c
> @@ -9894,7 +9894,7 @@ static int streaming_ucl_create_io(struct bt_bap_stream *stream,
>  
>  	i = qos[0] ? qos[0]->ucast.cis_id : qos[1]->ucast.cis_id;
>  
> -	if (i == BT_ISO_QOS_CIG_UNSET) {
> +	if (i == BT_ISO_QOS_CIS_UNSET) {
>  		for (i = 0; i < ARRAY_SIZE(data->fds); ++i) {
>  			if (data->fds[i][0] > 0)
>  				continue;
> @@ -10000,7 +10000,7 @@ static void test_select_cb(struct bt_bap_pac *pac, int err,
>  
>  	if (!data->cfg->streams) {
>  		qos->ucast.cig_id = BT_ISO_QOS_CIG_UNSET;
> -		qos->ucast.cis_id = BT_ISO_QOS_CIG_UNSET;
> +		qos->ucast.cis_id = BT_ISO_QOS_CIS_UNSET;
>  	} else {
>  		/* All streams to separate CIS.
>  		 *

-- 
Pauli Virtanen

^ permalink raw reply

* [bluez/bluez] 36c635: shared/bap: Initialize ucast/bcast IDs as unset
From: Šimon Mikuda @ 2026-06-14 10:06 UTC (permalink / raw)
  To: linux-bluetooth

  Branch: refs/heads/1111248
  Home:   https://github.com/bluez/bluez
  Commit: 36c635d5936726274ecb7cc07556be591a2248f4
      https://github.com/bluez/bluez/commit/36c635d5936726274ecb7cc07556be591a2248f4
  Author: Simon Mikuda <simon.mikuda@streamunlimited.com>
  Date:   2026-06-14 (Sun, 14 Jun 2026)

  Changed paths:
    M src/shared/bap.c
    M unit/test-bap.c

  Log Message:
  -----------
  shared/bap: Initialize ucast/bcast IDs as unset

Also change some lines where CIS should be used instead of CIG


  Commit: 964d7f50d6baeb1b506d9f96f469a0ecf205ac85
      https://github.com/bluez/bluez/commit/964d7f50d6baeb1b506d9f96f469a0ecf205ac85
  Author: Simon Mikuda <simon.mikuda@streamunlimited.com>
  Date:   2026-06-14 (Sun, 14 Jun 2026)

  Changed paths:
    M src/shared/bap.c

  Log Message:
  -----------
  shared/bap: Don't link server ucast streams before CIS IDs are assigned

bap_ucast_io_link pairs streams whose CIG/CIS IDs match, but the IDs
are unset in Codec Configured state, so a Sink and Source bound for
different CISes get linked. The stray link later propagates a
disconnect to the wrong ASE and breaks Receiver Start Ready.

Skip linking until QoS Configured assigns the IDs.

Fixes PTS test BAP/USR/STR/BV-362-C


Compare: https://github.com/bluez/bluez/compare/36c635d59367%5E...964d7f50d6ba

To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications

^ permalink raw reply

* [PATCH BlueZ v2 2/2] unit/bap: Add CIS loss test
From: Simon Mikuda @ 2026-06-14 10:02 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Simon Mikuda
In-Reply-To: <20260614100208.1091560-1-simon.mikuda@streamunlimited.com>

Verify a Source ASE in the Enabling state transitions to QoS Configured
rather than Disabling when its CIS is lost.

Assisted-by: ClaudeCode:claude-opus-4.8
---
 unit/test-bap.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)

diff --git a/unit/test-bap.c b/unit/test-bap.c
index 03b19678e..2847f5743 100644
--- a/unit/test-bap.c
+++ b/unit/test-bap.c
@@ -1486,6 +1486,37 @@ static void test_server(const void *user_data)
 	tester_io_send();
 }
 
+static void bap_attached_state(struct bt_bap *bap, void *user_data)
+{
+	struct test_data *data = user_data;
+
+	data->bap = bap;
+
+	bt_bap_set_debug(data->bap, print_debug, "bt_bap:", NULL);
+
+	bt_bap_state_register(data->bap, data->cfg->state_func, NULL, data,
+									NULL);
+}
+
+/* Like test_server() but registers the config's state callback so the test can
+ * drive autonomous server transitions (e.g. loss of the CIS).
+ */
+static void test_server_state(const void *user_data)
+{
+	struct test_data *data = (void *)user_data;
+	struct io *io;
+
+	io = tester_setup_io(data->iov, data->iovcnt);
+	g_assert(io);
+
+	tester_io_set_complete_func(test_complete_cb);
+
+	data->id = bt_bap_register(bap_attached_state, NULL, data);
+	g_assert(data->id);
+
+	tester_io_send();
+}
+
 static void test_usr_disc(void)
 {
 	/* BAP/USR/DISC/BV-01-C [Expose Audio Sink Capabilities]
@@ -4427,6 +4458,48 @@ static void test_spe(void)
 	IOV_DATA(0x1b, 0x16, 0x00, 0x01, 0x04, 0x00, 0x00, 0x04, 0x03, 0x02, \
 			0x01, 0x00)
 
+static void state_cis_loss(struct bt_bap_stream *stream, uint8_t old_state,
+					uint8_t new_state, void *user_data)
+{
+	struct test_data *data = user_data;
+	int fds[2];
+	int err;
+
+	if (new_state != data->cfg->state)
+		return;
+
+	/* Attach a CIS and tear it down to simulate its loss. */
+	err = socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, fds);
+	g_assert(err == 0);
+	g_assert(bt_bap_stream_io_connecting(stream, fds[0]) == 0);
+	close(fds[1]);
+}
+
+static struct test_config cfg_src_enabling_cis_loss = {
+	.cc = LC3_CONFIG_16_2,
+	.qos = LC3_QOS_16_2_1,
+	.src = true,
+	.state = BT_BAP_STREAM_STATE_ENABLING,
+	.state_func = state_cis_loss,
+};
+
+/* On loss of the CIS a Source ASE in Enabling moves to QoS Configured, not
+ * Disabling.
+ */
+#define SCC_SRC_ENABLING_CIS_LOSS \
+	SCC_SRC_16_2_1, \
+	ENABLE_ASE(SRC_ID(0)), \
+	QOS_SRC_NOTIFY(0, 0, 0x10, 0x27, 0x00, 0x00, 0x02, 0x28, 0x00, \
+			0x02, 0x0a, 0x00, 0x40, 0x9c, 0x00)
+
+static void test_usr_scc_cis_loss(void)
+{
+	define_test("BAP/USR/SCC/BV-167-C [USR SRC QoS Configured on CIS loss]",
+			test_setup_server, test_server_state,
+			&cfg_src_enabling_cis_loss,
+			SCC_SRC_ENABLING_CIS_LOSS);
+}
+
 static struct test_config str_snk_ac2_8_1_1 = {
 	.cc = LC3_CONFIG_8_1_AC(1),
 	.qos = LC3_QOS_8_1_1_AC(1),
@@ -7287,6 +7360,7 @@ static void test_scc(void)
 	test_scc_enable();
 	test_scc_disable();
 	test_scc_release();
+	test_usr_scc_cis_loss();
 	test_scc_metadata();
 	test_str_1_1_1_lc3();
 }
-- 
2.43.0


^ permalink raw reply related

* [PATCH BlueZ v2 1/2] shared/bap: Transition ASE to QoS Configured on CIS loss
From: Simon Mikuda @ 2026-06-14 10:02 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Simon Mikuda
In-Reply-To: <CABBYNZ+3vm1APyYtKYbXSVYMDC4YjXDrZEmNHeTKEGMg_Stpyg@mail.gmail.com>

stream_io_disconnected() only handled the Releasing state, leaving
Enabling, Streaming and Disabling ASEs stuck when the CIS was lost
unexpectedly.

The ASE shall autonomously move to QoS Configured on loss of the
CIS and notify the peer

Fixes PTS test BAP/USR/SCC/BV-167-C
---
 src/shared/bap.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/src/shared/bap.c b/src/shared/bap.c
index deb85b264..8d1f25719 100644
--- a/src/shared/bap.c
+++ b/src/shared/bap.c
@@ -6776,8 +6776,16 @@ static bool stream_io_disconnected(struct io *io, void *user_data)
 		return false;
 	}
 
-	if (stream->ep->state == BT_ASCS_ASE_STATE_RELEASING)
+	switch (stream->ep->state) {
+	case BT_ASCS_ASE_STATE_RELEASING:
 		stream_set_state(stream, BT_BAP_STREAM_STATE_CONFIG);
+		break;
+	case BT_ASCS_ASE_STATE_ENABLING:
+	case BT_ASCS_ASE_STATE_STREAMING:
+	case BT_ASCS_ASE_STATE_DISABLING:
+		stream_set_state(stream, BT_BAP_STREAM_STATE_QOS);
+		break;
+	}
 
 	bt_bap_stream_set_io(stream, -1);
 	return false;
-- 
2.43.0


^ permalink raw reply related

* [PATCH BlueZ v2 2/2] shared/bap: Don't link server ucast streams before CIS IDs are assigned
From: Simon Mikuda @ 2026-06-14  9:55 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Simon Mikuda
In-Reply-To: <20260614095520.1090106-1-simon.mikuda@streamunlimited.com>

bap_ucast_io_link pairs streams whose CIG/CIS IDs match, but the IDs
are unset in Codec Configured state, so a Sink and Source bound for
different CISes get linked. The stray link later propagates a
disconnect to the wrong ASE and breaks Receiver Start Ready.

Skip linking until QoS Configured assigns the IDs.

Fixes PTS test BAP/USR/STR/BV-362-C
---
 src/shared/bap.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/shared/bap.c b/src/shared/bap.c
index 41139181b..935387a76 100644
--- a/src/shared/bap.c
+++ b/src/shared/bap.c
@@ -2679,6 +2679,15 @@ static int bap_ucast_io_link(struct bt_bap_stream *stream,
 			stream->ep->dir == link->ep->dir)
 		return -EINVAL;
 
+	/* The server pairs Sink and Source by matching CIG/CIS, but those are
+	 * unset until QoS Configured, so it would link unrelated ASEs (CIS 0
+	 * is otherwise a valid ID). Clients gate linking on the lock instead.
+	 */
+	if (!stream->client &&
+			(stream->qos.ucast.cis_id == BT_ISO_QOS_CIS_UNSET ||
+			link->qos.ucast.cis_id == BT_ISO_QOS_CIS_UNSET))
+		return -EINVAL;
+
 	if (stream->client && !(stream->locked && link->locked))
 		return -EINVAL;
 
-- 
2.43.0


^ permalink raw reply related

* [PATCH BlueZ v2 1/2] shared/bap: Initialize ucast/bcast IDs as unset
From: Simon Mikuda @ 2026-06-14  9:55 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Simon Mikuda
In-Reply-To: <fa0febe1-5866-4a3f-9f86-ae70e9d4b22d@streamunlimited.com>

Also change some lines where CIS should be used instead of CIG
---
 src/shared/bap.c | 4 ++++
 unit/test-bap.c  | 4 ++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/shared/bap.c b/src/shared/bap.c
index deb85b264..41139181b 100644
--- a/src/shared/bap.c
+++ b/src/shared/bap.c
@@ -2901,6 +2901,10 @@ static struct bt_bap_stream *bap_stream_new(struct bt_bap *bap,
 	stream->client = client;
 	stream->ops = bap_stream_new_ops(stream);
 	stream->pending_states = queue_new();
+	stream->qos.bcast.big = BT_ISO_QOS_BIG_UNSET;
+	stream->qos.bcast.bis = BT_ISO_QOS_BIS_UNSET;
+	stream->qos.ucast.cig_id = BT_ISO_QOS_CIG_UNSET;
+	stream->qos.ucast.cis_id = BT_ISO_QOS_CIS_UNSET;
 
 	queue_push_tail(bap->streams, stream);
 
diff --git a/unit/test-bap.c b/unit/test-bap.c
index 03b19678e..4ac9a207c 100644
--- a/unit/test-bap.c
+++ b/unit/test-bap.c
@@ -9894,7 +9894,7 @@ static int streaming_ucl_create_io(struct bt_bap_stream *stream,
 
 	i = qos[0] ? qos[0]->ucast.cis_id : qos[1]->ucast.cis_id;
 
-	if (i == BT_ISO_QOS_CIG_UNSET) {
+	if (i == BT_ISO_QOS_CIS_UNSET) {
 		for (i = 0; i < ARRAY_SIZE(data->fds); ++i) {
 			if (data->fds[i][0] > 0)
 				continue;
@@ -10000,7 +10000,7 @@ static void test_select_cb(struct bt_bap_pac *pac, int err,
 
 	if (!data->cfg->streams) {
 		qos->ucast.cig_id = BT_ISO_QOS_CIG_UNSET;
-		qos->ucast.cis_id = BT_ISO_QOS_CIG_UNSET;
+		qos->ucast.cis_id = BT_ISO_QOS_CIS_UNSET;
 	} else {
 		/* All streams to separate CIS.
 		 *
-- 
2.43.0


^ permalink raw reply related

* [Bug 221637] Regression for Intel Corporation Device a876 (rev 10)
From: bugzilla-daemon @ 2026-06-14  7:04 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <bug-221637-62941@https.bugzilla.kernel.org/>

https://bugzilla.kernel.org/show_bug.cgi?id=221637

--- Comment #6 from Paul Menzel (pmenzel+bugzilla.kernel.org@molgen.mpg.de) ---
Bianca sent a message to the mailing list: [REGRESSION] Intel Corporation
Device a876 (rev 10) firmware crashes since ed10eae8 [1].


[1]:
https://lore.kernel.org/all/635e5e63-dc67-4dac-8590-d613582c94c8@posteo.net/

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are the assignee for the bug.

^ permalink raw reply

* Re: [REGRESSION] Intel Corporation Device a876 (rev 10) firmware crashes since ed10eae8
From: Paul Menzel @ 2026-06-14  7:01 UTC (permalink / raw)
  To: Bianca Fürstenau, Ravindra, Dmitry Baryshkov, Kiran K,
	Josh Boyer
  Cc: linux-firmware, linux-bluetooth, regressions, Sai Teja Aluvala,
	Thorsten Leemhuis, Mario Limonciello, Pierre-Olivier Vallès
In-Reply-To: <635e5e63-dc67-4dac-8590-d613582c94c8@posteo.net>

[To: +Josh, +Kiran]
[Cc: +linux-firmware@]

Am 13.06.26 um 23:09 schrieb Bianca Fürstenau:
> Dear Dmitry,
> 
> It seems that the linux-firmware commit ed10eae8 introduced a regression 
> causing the firmware to fail on Intel Corporation Device a876 (rev 10). 
> The next update to the firmware images in 7df47664 did not remedy this.
> 
> For dmesg extracts and other details, see:
> https://bugzilla.kernel.org/show_bug.cgi?id=221637 (Upstream bug report 
> where Thorsten informed us that we were sent to the wrong place)
> https://gitlab.archlinux.org/archlinux/packaging/packages/linux-firmware/-/work_items/45
> (Downstream bug report by Pierre-Olivier)
> https://github.com/NixOS/nixpkgs/issues/530344 (Downstream bug report by 
> me)
> 
> Please let us know if you need any further information. I’m sure both of 
> us would be happier to have working Bluetooth with current firmware 
> rather than at most one of these.
> 
> Kind regards,
> Bianca
> 
> ed10eae8: linux-firmware: Update firmware file for Intel BlazarI core
> 
> https://gitlab.com/kernel-firmware/linux-firmware/-/commit/ed10eae8facb3b4bf2da7104cec95afdf0209114
> 7df47664: linux-firmware: Update firmware file for Intel BlazarI core
> 
> https://gitlab.com/kernel-firmware/linux-firmware/-/commit/7df47664dd1d94111858b3224c15908517c73e73
> Merge Request for ed10eae8: https://gitlab.com/kernel-firmware/linux-firmware/-/merge_requests/955
> Merge Request for 7df47664: https://gitlab.com/kernel-firmware/linux-firmware/-/merge_requests/1018
> 
> #regzbot introduced: ed10eae8facb3b4bf2da7104cec95afdf0209114
> #regzbot link: https://bugzilla.kernel.org/show_bug.cgi?id=221637 
> [Bugzilla report]
> #regzbot monitor: https://lore.kernel.org/linux-bluetooth/bug-221637-62941@https.bugzilla.kernel.org%2F/
> #regzbot link: https://gitlab.archlinux.org/archlinux/packaging/packages/linux-firmware/-/work_items/45 [Arch downstream report]
> #regzbot link: https://github.com/NixOS/nixpkgs/issues/530344 [NixOS downstream report]
> #regzbot link: https://discussion.fedoraproject.org/t/bluetooth-not-working-on-fedora-cosmic-atomic-intel-core-ultra-7-kernel-7-0-8-200fc44-x86-64/191881 [Fedora downstream report]

^ permalink raw reply


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