include/net/bluetooth/hci.h | 6 ++++++ net/bluetooth/hci_event.c | 23 +++++++++++++++++++++++ 2 files changed, 29 insertions(+)
From: Yang Li <yang.li@amlogic.com>
When the BIS source stops, the controller sends an LE BIG Sync Lost
event (subevent 0x1E). Currently, this event is not handled, causing
the BIS stream to remain active in BlueZ and preventing recovery.
Signed-off-by: Yang Li <yang.li@amlogic.com>
---
include/net/bluetooth/hci.h | 6 ++++++
net/bluetooth/hci_event.c | 23 +++++++++++++++++++++++
2 files changed, 29 insertions(+)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 82cbd54443ac..48389a64accb 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -2849,6 +2849,12 @@ struct hci_evt_le_big_sync_estabilished {
__le16 bis[];
} __packed;
+#define HCI_EVT_LE_BIG_SYNC_LOST 0x1e
+struct hci_evt_le_big_sync_lost {
+ __u8 handle;
+ __u8 reason;
+} __packed;
+
#define HCI_EVT_LE_BIG_INFO_ADV_REPORT 0x22
struct hci_evt_le_big_info_adv_report {
__le16 sync_handle;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 66052d6aaa1d..730deaf1851f 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -7026,6 +7026,24 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data,
hci_dev_unlock(hdev);
}
+static void hci_le_big_sync_lost_evt(struct hci_dev *hdev, void *data,
+ struct sk_buff *skb)
+{
+ struct hci_evt_le_big_sync_lost *ev = data;
+ struct hci_conn *conn;
+
+ bt_dev_dbg(hdev, "BIG Sync Lost: big_handle 0x%2.2x", ev->handle);
+
+ hci_dev_lock(hdev);
+
+ list_for_each_entry(conn, &hdev->conn_hash.list, list) {
+ if (test_bit(HCI_CONN_BIG_SYNC, &conn->flags))
+ hci_disconn_cfm(conn, HCI_ERROR_REMOTE_USER_TERM);
+ }
+
+ hci_dev_unlock(hdev);
+}
+
static void hci_le_big_info_adv_report_evt(struct hci_dev *hdev, void *data,
struct sk_buff *skb)
{
@@ -7149,6 +7167,11 @@ static const struct hci_le_ev {
hci_le_big_sync_established_evt,
sizeof(struct hci_evt_le_big_sync_estabilished),
HCI_MAX_EVENT_SIZE),
+ /* [0x1e = HCI_EVT_LE_BIG_SYNC_LOST] */
+ HCI_LE_EV_VL(HCI_EVT_LE_BIG_SYNC_LOST,
+ hci_le_big_sync_lost_evt,
+ sizeof(struct hci_evt_le_big_sync_lost),
+ HCI_MAX_EVENT_SIZE),
/* [0x22 = HCI_EVT_LE_BIG_INFO_ADV_REPORT] */
HCI_LE_EV_VL(HCI_EVT_LE_BIG_INFO_ADV_REPORT,
hci_le_big_info_adv_report_evt,
---
base-commit: bd35cd12d915bc410c721ba28afcada16f0ebd16
change-id: 20250612-handle_big_sync_lost_event-4c7dc64390a2
Best regards,
--
Yang Li <yang.li@amlogic.com>
Hi, On Tue, Jun 24, 2025 at 1:20 AM Yang Li via B4 Relay <devnull+yang.li.amlogic.com@kernel.org> wrote: > > From: Yang Li <yang.li@amlogic.com> > > When the BIS source stops, the controller sends an LE BIG Sync Lost > event (subevent 0x1E). Currently, this event is not handled, causing > the BIS stream to remain active in BlueZ and preventing recovery. > > Signed-off-by: Yang Li <yang.li@amlogic.com> > --- > include/net/bluetooth/hci.h | 6 ++++++ > net/bluetooth/hci_event.c | 23 +++++++++++++++++++++++ > 2 files changed, 29 insertions(+) > > diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h > index 82cbd54443ac..48389a64accb 100644 > --- a/include/net/bluetooth/hci.h > +++ b/include/net/bluetooth/hci.h > @@ -2849,6 +2849,12 @@ struct hci_evt_le_big_sync_estabilished { > __le16 bis[]; > } __packed; > > +#define HCI_EVT_LE_BIG_SYNC_LOST 0x1e > +struct hci_evt_le_big_sync_lost { > + __u8 handle; > + __u8 reason; > +} __packed; > + > #define HCI_EVT_LE_BIG_INFO_ADV_REPORT 0x22 > struct hci_evt_le_big_info_adv_report { > __le16 sync_handle; > diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c > index 66052d6aaa1d..730deaf1851f 100644 > --- a/net/bluetooth/hci_event.c > +++ b/net/bluetooth/hci_event.c > @@ -7026,6 +7026,24 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data, > hci_dev_unlock(hdev); > } > > +static void hci_le_big_sync_lost_evt(struct hci_dev *hdev, void *data, > + struct sk_buff *skb) > +{ > + struct hci_evt_le_big_sync_lost *ev = data; > + struct hci_conn *conn; > + > + bt_dev_dbg(hdev, "BIG Sync Lost: big_handle 0x%2.2x", ev->handle); > + > + hci_dev_lock(hdev); > + > + list_for_each_entry(conn, &hdev->conn_hash.list, list) { > + if (test_bit(HCI_CONN_BIG_SYNC, &conn->flags)) > + hci_disconn_cfm(conn, HCI_ERROR_REMOTE_USER_TERM); > + } Let's start with the obvious problems: 1. This does not use the handle, instead it disconnects all the connections with HCI_CONN_BIG_SYNC 2. It doesn't use the reason either 3. hci_disconnect_cfm should be followed with hci_conn_del to free the hci_conn So this does tell me you don't fully understand what you are doing, I hope I am not dealing with some AI generated code otherwise I would just do it myself. > + hci_dev_unlock(hdev); > +} > + > static void hci_le_big_info_adv_report_evt(struct hci_dev *hdev, void *data, > struct sk_buff *skb) > { > @@ -7149,6 +7167,11 @@ static const struct hci_le_ev { > hci_le_big_sync_established_evt, > sizeof(struct hci_evt_le_big_sync_estabilished), > HCI_MAX_EVENT_SIZE), > + /* [0x1e = HCI_EVT_LE_BIG_SYNC_LOST] */ > + HCI_LE_EV_VL(HCI_EVT_LE_BIG_SYNC_LOST, > + hci_le_big_sync_lost_evt, > + sizeof(struct hci_evt_le_big_sync_lost), > + HCI_MAX_EVENT_SIZE), > /* [0x22 = HCI_EVT_LE_BIG_INFO_ADV_REPORT] */ > HCI_LE_EV_VL(HCI_EVT_LE_BIG_INFO_ADV_REPORT, > hci_le_big_info_adv_report_evt, > > --- > base-commit: bd35cd12d915bc410c721ba28afcada16f0ebd16 > change-id: 20250612-handle_big_sync_lost_event-4c7dc64390a2 > > Best regards, > -- > Yang Li <yang.li@amlogic.com> > > -- Luiz Augusto von Dentz
Hi, On Tue, Jun 24, 2025 at 12:56 PM Luiz Augusto von Dentz <luiz.dentz@gmail.com> wrote: > > Hi, > > On Tue, Jun 24, 2025 at 1:20 AM Yang Li via B4 Relay > <devnull+yang.li.amlogic.com@kernel.org> wrote: > > > > From: Yang Li <yang.li@amlogic.com> > > > > When the BIS source stops, the controller sends an LE BIG Sync Lost > > event (subevent 0x1E). Currently, this event is not handled, causing > > the BIS stream to remain active in BlueZ and preventing recovery. > > > > Signed-off-by: Yang Li <yang.li@amlogic.com> > > --- > > include/net/bluetooth/hci.h | 6 ++++++ > > net/bluetooth/hci_event.c | 23 +++++++++++++++++++++++ > > 2 files changed, 29 insertions(+) > > > > diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h > > index 82cbd54443ac..48389a64accb 100644 > > --- a/include/net/bluetooth/hci.h > > +++ b/include/net/bluetooth/hci.h > > @@ -2849,6 +2849,12 @@ struct hci_evt_le_big_sync_estabilished { > > __le16 bis[]; > > } __packed; > > > > +#define HCI_EVT_LE_BIG_SYNC_LOST 0x1e > > +struct hci_evt_le_big_sync_lost { > > + __u8 handle; > > + __u8 reason; > > +} __packed; > > + > > #define HCI_EVT_LE_BIG_INFO_ADV_REPORT 0x22 > > struct hci_evt_le_big_info_adv_report { > > __le16 sync_handle; > > diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c > > index 66052d6aaa1d..730deaf1851f 100644 > > --- a/net/bluetooth/hci_event.c > > +++ b/net/bluetooth/hci_event.c > > @@ -7026,6 +7026,24 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data, > > hci_dev_unlock(hdev); > > } > > > > +static void hci_le_big_sync_lost_evt(struct hci_dev *hdev, void *data, > > + struct sk_buff *skb) > > +{ > > + struct hci_evt_le_big_sync_lost *ev = data; > > + struct hci_conn *conn; > > + > > + bt_dev_dbg(hdev, "BIG Sync Lost: big_handle 0x%2.2x", ev->handle); > > + > > + hci_dev_lock(hdev); > > + > > + list_for_each_entry(conn, &hdev->conn_hash.list, list) { > > + if (test_bit(HCI_CONN_BIG_SYNC, &conn->flags)) > > + hci_disconn_cfm(conn, HCI_ERROR_REMOTE_USER_TERM); > > + } > > Let's start with the obvious problems: > > 1. This does not use the handle, instead it disconnects all the > connections with HCI_CONN_BIG_SYNC > 2. It doesn't use the reason either > 3. hci_disconnect_cfm should be followed with hci_conn_del to free the hci_conn > > So this does tell me you don't fully understand what you are doing, I > hope I am not dealing with some AI generated code otherwise I would > just do it myself. Btw, the spec does says the controller shall cleanup the connection handle and data path: When the HCI_LE_BIG_Sync_Lost event occurs, the Controller shall remove the connection handle(s) and data paths of all BIS(s) in the BIG with which the Controller was synchronized. I wonder if that shall be interpreted as no HCI_Disconnection_Complete shall be generated or what, also we might need to implement this into BlueZ emulator in order to replicate this in our CI tests. It seems we are not sending anything to the remote devices when receiving BT_HCI_CMD_LE_BIG_TERM_SYNC: https://github.com/bluez/bluez/blob/master/emulator/btdev.c#L6661 > > + hci_dev_unlock(hdev); > > +} > > + > > static void hci_le_big_info_adv_report_evt(struct hci_dev *hdev, void *data, > > struct sk_buff *skb) > > { > > @@ -7149,6 +7167,11 @@ static const struct hci_le_ev { > > hci_le_big_sync_established_evt, > > sizeof(struct hci_evt_le_big_sync_estabilished), > > HCI_MAX_EVENT_SIZE), > > + /* [0x1e = HCI_EVT_LE_BIG_SYNC_LOST] */ > > + HCI_LE_EV_VL(HCI_EVT_LE_BIG_SYNC_LOST, > > + hci_le_big_sync_lost_evt, > > + sizeof(struct hci_evt_le_big_sync_lost), > > + HCI_MAX_EVENT_SIZE), > > /* [0x22 = HCI_EVT_LE_BIG_INFO_ADV_REPORT] */ > > HCI_LE_EV_VL(HCI_EVT_LE_BIG_INFO_ADV_REPORT, > > hci_le_big_info_adv_report_evt, > > > > --- > > base-commit: bd35cd12d915bc410c721ba28afcada16f0ebd16 > > change-id: 20250612-handle_big_sync_lost_event-4c7dc64390a2 > > > > Best regards, > > -- > > Yang Li <yang.li@amlogic.com> > > > > > > > -- > Luiz Augusto von Dentz -- Luiz Augusto von Dentz
在 2025/6/25 1:17, Luiz Augusto von Dentz 写道: > [ EXTERNAL EMAIL ] > > Hi, > > On Tue, Jun 24, 2025 at 12:56 PM Luiz Augusto von Dentz > <luiz.dentz@gmail.com> wrote: >> Hi, >> >> On Tue, Jun 24, 2025 at 1:20 AM Yang Li via B4 Relay >> <devnull+yang.li.amlogic.com@kernel.org> wrote: >>> From: Yang Li <yang.li@amlogic.com> >>> >>> When the BIS source stops, the controller sends an LE BIG Sync Lost >>> event (subevent 0x1E). Currently, this event is not handled, causing >>> the BIS stream to remain active in BlueZ and preventing recovery. >>> >>> Signed-off-by: Yang Li <yang.li@amlogic.com> >>> --- >>> include/net/bluetooth/hci.h | 6 ++++++ >>> net/bluetooth/hci_event.c | 23 +++++++++++++++++++++++ >>> 2 files changed, 29 insertions(+) >>> >>> diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h >>> index 82cbd54443ac..48389a64accb 100644 >>> --- a/include/net/bluetooth/hci.h >>> +++ b/include/net/bluetooth/hci.h >>> @@ -2849,6 +2849,12 @@ struct hci_evt_le_big_sync_estabilished { >>> __le16 bis[]; >>> } __packed; >>> >>> +#define HCI_EVT_LE_BIG_SYNC_LOST 0x1e >>> +struct hci_evt_le_big_sync_lost { >>> + __u8 handle; >>> + __u8 reason; >>> +} __packed; >>> + >>> #define HCI_EVT_LE_BIG_INFO_ADV_REPORT 0x22 >>> struct hci_evt_le_big_info_adv_report { >>> __le16 sync_handle; >>> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c >>> index 66052d6aaa1d..730deaf1851f 100644 >>> --- a/net/bluetooth/hci_event.c >>> +++ b/net/bluetooth/hci_event.c >>> @@ -7026,6 +7026,24 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data, >>> hci_dev_unlock(hdev); >>> } >>> >>> +static void hci_le_big_sync_lost_evt(struct hci_dev *hdev, void *data, >>> + struct sk_buff *skb) >>> +{ >>> + struct hci_evt_le_big_sync_lost *ev = data; >>> + struct hci_conn *conn; >>> + >>> + bt_dev_dbg(hdev, "BIG Sync Lost: big_handle 0x%2.2x", ev->handle); >>> + >>> + hci_dev_lock(hdev); >>> + >>> + list_for_each_entry(conn, &hdev->conn_hash.list, list) { >>> + if (test_bit(HCI_CONN_BIG_SYNC, &conn->flags)) >>> + hci_disconn_cfm(conn, HCI_ERROR_REMOTE_USER_TERM); >>> + } >> Let's start with the obvious problems: >> >> 1. This does not use the handle, instead it disconnects all the >> connections with HCI_CONN_BIG_SYNC >> 2. It doesn't use the reason either >> 3. hci_disconnect_cfm should be followed with hci_conn_del to free the hci_conn >> >> So this does tell me you don't fully understand what you are doing, I >> hope I am not dealing with some AI generated code otherwise I would >> just do it myself. Thank you for pointing that out. I overlooked these three issues, and they will be fixed in the next revision. > Btw, the spec does says the controller shall cleanup the connection > handle and data path: > > When the HCI_LE_BIG_Sync_Lost event occurs, the Controller shall > remove the connection handle(s) and data paths of all BIS(s) in the > BIG with which the Controller was synchronized. > > I wonder if that shall be interpreted as no HCI_Disconnection_Complete > shall be generated or what, also we might need to implement this into > BlueZ emulator in order to replicate this in our CI tests. > > It seems we are not sending anything to the remote devices when > receiving BT_HCI_CMD_LE_BIG_TERM_SYNC: > > https://github.com/bluez/bluez/blob/master/emulator/btdev.c#L6661 When the HCI_LE_BIG_Sync_Lost event occurs, there is no accompanying HCI_Disconnection_Complete event. However, in the patch submitted to BlueZ, it is described that the HCI_Disconnection_Complete event will be reported when the CIS link is disconnected. https://lore.kernel.org/all/20250624-bap_for_big_sync_lost-v1-1-0df90a0f55d0@amlogic.com/ I believe that the HCI_LE_BIG_Sync_Lost event is triggered passively by the controller when it is unable to synchronize with the BIS stream. This may occur for various reasons — such as the BIS source pausing transmission, the device moving out of range, or interference. This behavior is different from the host actively issuing the LE_BIG_Terminate_Sync command. In actual products, this condition can be communicated back to the phone (Assistant) via the Broadcast Receive State characteristic defined in BASS. However, in a simulator or test environment, there's often not much that needs to be done when sending LE_BIG_Terminate_Sync command. > >>> + hci_dev_unlock(hdev); >>> +} >>> + >>> static void hci_le_big_info_adv_report_evt(struct hci_dev *hdev, void *data, >>> struct sk_buff *skb) >>> { >>> @@ -7149,6 +7167,11 @@ static const struct hci_le_ev { >>> hci_le_big_sync_established_evt, >>> sizeof(struct hci_evt_le_big_sync_estabilished), >>> HCI_MAX_EVENT_SIZE), >>> + /* [0x1e = HCI_EVT_LE_BIG_SYNC_LOST] */ >>> + HCI_LE_EV_VL(HCI_EVT_LE_BIG_SYNC_LOST, >>> + hci_le_big_sync_lost_evt, >>> + sizeof(struct hci_evt_le_big_sync_lost), >>> + HCI_MAX_EVENT_SIZE), >>> /* [0x22 = HCI_EVT_LE_BIG_INFO_ADV_REPORT] */ >>> HCI_LE_EV_VL(HCI_EVT_LE_BIG_INFO_ADV_REPORT, >>> hci_le_big_info_adv_report_evt, >>> >>> --- >>> base-commit: bd35cd12d915bc410c721ba28afcada16f0ebd16 >>> change-id: 20250612-handle_big_sync_lost_event-4c7dc64390a2 >>> >>> Best regards, >>> -- >>> Yang Li <yang.li@amlogic.com> >>> >>> >> >> -- >> Luiz Augusto von Dentz > > > -- > Luiz Augusto von Dentz
Dear Li, Thank you for your patch. Am 24.06.25 um 07:20 schrieb Yang Li via B4 Relay: > From: Yang Li <yang.li@amlogic.com> > > When the BIS source stops, the controller sends an LE BIG Sync Lost > event (subevent 0x1E). Currently, this event is not handled, causing > the BIS stream to remain active in BlueZ and preventing recovery. How can this situation be emulated to test your patch? > Signed-off-by: Yang Li <yang.li@amlogic.com> > --- > include/net/bluetooth/hci.h | 6 ++++++ > net/bluetooth/hci_event.c | 23 +++++++++++++++++++++++ > 2 files changed, 29 insertions(+) > > diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h > index 82cbd54443ac..48389a64accb 100644 > --- a/include/net/bluetooth/hci.h > +++ b/include/net/bluetooth/hci.h > @@ -2849,6 +2849,12 @@ struct hci_evt_le_big_sync_estabilished { > __le16 bis[]; > } __packed; > > +#define HCI_EVT_LE_BIG_SYNC_LOST 0x1e > +struct hci_evt_le_big_sync_lost { > + __u8 handle; > + __u8 reason; > +} __packed; > + > #define HCI_EVT_LE_BIG_INFO_ADV_REPORT 0x22 > struct hci_evt_le_big_info_adv_report { > __le16 sync_handle; > diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c > index 66052d6aaa1d..730deaf1851f 100644 > --- a/net/bluetooth/hci_event.c > +++ b/net/bluetooth/hci_event.c > @@ -7026,6 +7026,24 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data, > hci_dev_unlock(hdev); > } > > +static void hci_le_big_sync_lost_evt(struct hci_dev *hdev, void *data, > + struct sk_buff *skb) > +{ > + struct hci_evt_le_big_sync_lost *ev = data; > + struct hci_conn *conn; > + > + bt_dev_dbg(hdev, "BIG Sync Lost: big_handle 0x%2.2x", ev->handle); > + > + hci_dev_lock(hdev); > + > + list_for_each_entry(conn, &hdev->conn_hash.list, list) { > + if (test_bit(HCI_CONN_BIG_SYNC, &conn->flags)) > + hci_disconn_cfm(conn, HCI_ERROR_REMOTE_USER_TERM); > + } > + > + hci_dev_unlock(hdev); > +} > + > static void hci_le_big_info_adv_report_evt(struct hci_dev *hdev, void *data, > struct sk_buff *skb) > { > @@ -7149,6 +7167,11 @@ static const struct hci_le_ev { > hci_le_big_sync_established_evt, > sizeof(struct hci_evt_le_big_sync_estabilished), > HCI_MAX_EVENT_SIZE), > + /* [0x1e = HCI_EVT_LE_BIG_SYNC_LOST] */ > + HCI_LE_EV_VL(HCI_EVT_LE_BIG_SYNC_LOST, > + hci_le_big_sync_lost_evt, > + sizeof(struct hci_evt_le_big_sync_lost), > + HCI_MAX_EVENT_SIZE), > /* [0x22 = HCI_EVT_LE_BIG_INFO_ADV_REPORT] */ > HCI_LE_EV_VL(HCI_EVT_LE_BIG_INFO_ADV_REPORT, > hci_le_big_info_adv_report_evt, Kind regards, Paul
Hi, > [ EXTERNAL EMAIL ] > > Dear Li, > > > Thank you for your patch. > > > Am 24.06.25 um 07:20 schrieb Yang Li via B4 Relay: >> From: Yang Li <yang.li@amlogic.com> >> >> When the BIS source stops, the controller sends an LE BIG Sync Lost >> event (subevent 0x1E). Currently, this event is not handled, causing >> the BIS stream to remain active in BlueZ and preventing recovery. > > How can this situation be emulated to test your patch? My test environment is as follows: I connect a Pixel phone to the DUT and use the phone as a BIS source for audio sharing. The DUT synchronizes with the audio stream from the phone. After I pause the music on the phone, the DUT's controller reports a BIG Sync Lost event. I believe this scenario can also be reproduced using the isotest tool. For example: - Use Board A as the BIS source. - Use Board B to execute scan on. - Once Board B synchronizes with Board A, exit isotest on Board A. - Board B should then receive the BIG Sync Lost event as well. Additionally, the following BlueZ patch is required for proper handling of this event: https://lore.kernel.org/all/20250624-bap_for_big_sync_lost-v1-1-0df90a0f55d0@amlogic.com/ > >> Signed-off-by: Yang Li <yang.li@amlogic.com> >> --- >> include/net/bluetooth/hci.h | 6 ++++++ >> net/bluetooth/hci_event.c | 23 +++++++++++++++++++++++ >> 2 files changed, 29 insertions(+) >> >> diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h >> index 82cbd54443ac..48389a64accb 100644 >> --- a/include/net/bluetooth/hci.h >> +++ b/include/net/bluetooth/hci.h >> @@ -2849,6 +2849,12 @@ struct hci_evt_le_big_sync_estabilished { >> __le16 bis[]; >> } __packed; >> >> +#define HCI_EVT_LE_BIG_SYNC_LOST 0x1e >> +struct hci_evt_le_big_sync_lost { >> + __u8 handle; >> + __u8 reason; >> +} __packed; >> + >> #define HCI_EVT_LE_BIG_INFO_ADV_REPORT 0x22 >> struct hci_evt_le_big_info_adv_report { >> __le16 sync_handle; >> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c >> index 66052d6aaa1d..730deaf1851f 100644 >> --- a/net/bluetooth/hci_event.c >> +++ b/net/bluetooth/hci_event.c >> @@ -7026,6 +7026,24 @@ static void >> hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data, >> hci_dev_unlock(hdev); >> } >> >> +static void hci_le_big_sync_lost_evt(struct hci_dev *hdev, void *data, >> + struct sk_buff *skb) >> +{ >> + struct hci_evt_le_big_sync_lost *ev = data; >> + struct hci_conn *conn; >> + >> + bt_dev_dbg(hdev, "BIG Sync Lost: big_handle 0x%2.2x", ev->handle); >> + >> + hci_dev_lock(hdev); >> + >> + list_for_each_entry(conn, &hdev->conn_hash.list, list) { >> + if (test_bit(HCI_CONN_BIG_SYNC, &conn->flags)) >> + hci_disconn_cfm(conn, HCI_ERROR_REMOTE_USER_TERM); >> + } >> + >> + hci_dev_unlock(hdev); >> +} >> + >> static void hci_le_big_info_adv_report_evt(struct hci_dev *hdev, >> void *data, >> struct sk_buff *skb) >> { >> @@ -7149,6 +7167,11 @@ static const struct hci_le_ev { >> hci_le_big_sync_established_evt, >> sizeof(struct hci_evt_le_big_sync_estabilished), >> HCI_MAX_EVENT_SIZE), >> + /* [0x1e = HCI_EVT_LE_BIG_SYNC_LOST] */ >> + HCI_LE_EV_VL(HCI_EVT_LE_BIG_SYNC_LOST, >> + hci_le_big_sync_lost_evt, >> + sizeof(struct hci_evt_le_big_sync_lost), >> + HCI_MAX_EVENT_SIZE), >> /* [0x22 = HCI_EVT_LE_BIG_INFO_ADV_REPORT] */ >> HCI_LE_EV_VL(HCI_EVT_LE_BIG_INFO_ADV_REPORT, >> hci_le_big_info_adv_report_evt, > > Kind regards, > > Paul
Dear Li, Thank you for your immediate reply. Am 24.06.25 um 08:26 schrieb Yang Li: >> Am 24.06.25 um 07:20 schrieb Yang Li via B4 Relay: >>> From: Yang Li <yang.li@amlogic.com> >>> >>> When the BIS source stops, the controller sends an LE BIG Sync Lost >>> event (subevent 0x1E). Currently, this event is not handled, causing >>> the BIS stream to remain active in BlueZ and preventing recovery. >> >> How can this situation be emulated to test your patch? > > My test environment is as follows: > > I connect a Pixel phone to the DUT and use the phone as a BIS source for > audio sharing. The DUT synchronizes with the audio stream from the phone. > After I pause the music on the phone, the DUT's controller reports a BIG > Sync Lost event. Excuse my ignorance, but it might be good to have documented. How do you connect the Pixel phone to the DUT? Pairing is not needed for BIS (Broadcast Isochronous Stream), and using wireless technology no connection is needed? What app do you use on the Android phone? > I believe this scenario can also be reproduced using the isotest tool. > For example: > - Use Board A as the BIS source. > - Use Board B to execute scan on. > - Once Board B synchronizes with Board A, exit isotest on Board A. > - Board B should then receive the BIG Sync Lost event as well. Thank you for sharing this idea. > Additionally, the following BlueZ patch is required for proper handling > of this event: > https://lore.kernel.org/all/20250624-bap_for_big_sync_lost-v1-1-0df90a0f55d0@amlogic.com/ Yes, I saw it. Thank you. >>> Signed-off-by: Yang Li <yang.li@amlogic.com> >>> --- >>> include/net/bluetooth/hci.h | 6 ++++++ >>> net/bluetooth/hci_event.c | 23 +++++++++++++++++++++++ >>> 2 files changed, 29 insertions(+) >>> >>> diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h >>> index 82cbd54443ac..48389a64accb 100644 >>> --- a/include/net/bluetooth/hci.h >>> +++ b/include/net/bluetooth/hci.h >>> @@ -2849,6 +2849,12 @@ struct hci_evt_le_big_sync_estabilished { >>> __le16 bis[]; >>> } __packed; >>> >>> +#define HCI_EVT_LE_BIG_SYNC_LOST 0x1e >>> +struct hci_evt_le_big_sync_lost { >>> + __u8 handle; >>> + __u8 reason; >>> +} __packed; >>> + >>> #define HCI_EVT_LE_BIG_INFO_ADV_REPORT 0x22 >>> struct hci_evt_le_big_info_adv_report { >>> __le16 sync_handle; >>> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c >>> index 66052d6aaa1d..730deaf1851f 100644 >>> --- a/net/bluetooth/hci_event.c >>> +++ b/net/bluetooth/hci_event.c >>> @@ -7026,6 +7026,24 @@ static void >>> hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data, >>> hci_dev_unlock(hdev); >>> } >>> >>> +static void hci_le_big_sync_lost_evt(struct hci_dev *hdev, void *data, >>> + struct sk_buff *skb) >>> +{ >>> + struct hci_evt_le_big_sync_lost *ev = data; >>> + struct hci_conn *conn; >>> + >>> + bt_dev_dbg(hdev, "BIG Sync Lost: big_handle 0x%2.2x", ev->handle); >>> + >>> + hci_dev_lock(hdev); >>> + >>> + list_for_each_entry(conn, &hdev->conn_hash.list, list) { >>> + if (test_bit(HCI_CONN_BIG_SYNC, &conn->flags)) >>> + hci_disconn_cfm(conn, HCI_ERROR_REMOTE_USER_TERM); >>> + } >>> + >>> + hci_dev_unlock(hdev); >>> +} >>> + >>> static void hci_le_big_info_adv_report_evt(struct hci_dev *hdev, >>> void *data, >>> struct sk_buff *skb) >>> { >>> @@ -7149,6 +7167,11 @@ static const struct hci_le_ev { >>> hci_le_big_sync_established_evt, >>> sizeof(struct hci_evt_le_big_sync_estabilished), >>> HCI_MAX_EVENT_SIZE), >>> + /* [0x1e = HCI_EVT_LE_BIG_SYNC_LOST] */ >>> + HCI_LE_EV_VL(HCI_EVT_LE_BIG_SYNC_LOST, >>> + hci_le_big_sync_lost_evt, >>> + sizeof(struct hci_evt_le_big_sync_lost), >>> + HCI_MAX_EVENT_SIZE), >>> /* [0x22 = HCI_EVT_LE_BIG_INFO_ADV_REPORT] */ >>> HCI_LE_EV_VL(HCI_EVT_LE_BIG_INFO_ADV_REPORT, >>> hci_le_big_info_adv_report_evt, Kind regards, Paul
Hi Paul, > [ EXTERNAL EMAIL ] > > Dear Li, > > > Thank you for your immediate reply. > > Am 24.06.25 um 08:26 schrieb Yang Li: > >>> Am 24.06.25 um 07:20 schrieb Yang Li via B4 Relay: >>>> From: Yang Li <yang.li@amlogic.com> >>>> >>>> When the BIS source stops, the controller sends an LE BIG Sync Lost >>>> event (subevent 0x1E). Currently, this event is not handled, causing >>>> the BIS stream to remain active in BlueZ and preventing recovery. >>> >>> How can this situation be emulated to test your patch? >> >> My test environment is as follows: >> >> I connect a Pixel phone to the DUT and use the phone as a BIS source for >> audio sharing. The DUT synchronizes with the audio stream from the >> phone. >> After I pause the music on the phone, the DUT's controller reports a BIG >> Sync Lost event. > > Excuse my ignorance, but it might be good to have documented. How do you > connect the Pixel phone to the DUT? Pairing is not needed for BIS > (Broadcast Isochronous Stream), and using wireless technology no > connection is needed? Yes, you're correct that pairing and connection are not required for BIS (Broadcast Isochronous Stream). However, the DUT is typically a resource-constrained device with limited input/output capabilities. As a result, we rely on the phone to act as an assistant in configuring the BIS source information via BASS (Broadcast Audio Scan Service). The basic flow is as follows: - Establish a Bluetooth LE connection between the phone and the DUT. - Start audio playback on the phone and enable audio sharing from the device details page. At this point, the phone becomes the BIS source and configures the DUT (BIS sink) using the BASS Control Point (Refs. https://bluetooth.fluidtopics.net/r/lgpAAcjFeoVMObE~cpMDZw/nkLg6cYqSphBI_2mYkaxDw). - When music playback is paused on the phone, the BIS source will stop broadcasting. - If the DUT fails to maintain synchronization, it will report a BIG Sync Lost event, as it can no longer receive the broadcast stream. > > What app do you use on the Android phone? Pixel 9 and upgrade to Android 16. > >> I believe this scenario can also be reproduced using the isotest tool. >> For example: >> - Use Board A as the BIS source. >> - Use Board B to execute scan on. >> - Once Board B synchronizes with Board A, exit isotest on Board A. >> - Board B should then receive the BIG Sync Lost event as well. > > Thank you for sharing this idea. > >> Additionally, the following BlueZ patch is required for proper handling >> of this event: >> https://lore.kernel.org/all/20250624-bap_for_big_sync_lost-v1-1-0df90a0f55d0@amlogic.com/ >> > > Yes, I saw it. Thank you. > >>>> Signed-off-by: Yang Li <yang.li@amlogic.com> >>>> --- >>>> include/net/bluetooth/hci.h | 6 ++++++ >>>> net/bluetooth/hci_event.c | 23 +++++++++++++++++++++++ >>>> 2 files changed, 29 insertions(+) >>>> >>>> diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h >>>> index 82cbd54443ac..48389a64accb 100644 >>>> --- a/include/net/bluetooth/hci.h >>>> +++ b/include/net/bluetooth/hci.h >>>> @@ -2849,6 +2849,12 @@ struct hci_evt_le_big_sync_estabilished { >>>> __le16 bis[]; >>>> } __packed; >>>> >>>> +#define HCI_EVT_LE_BIG_SYNC_LOST 0x1e >>>> +struct hci_evt_le_big_sync_lost { >>>> + __u8 handle; >>>> + __u8 reason; >>>> +} __packed; >>>> + >>>> #define HCI_EVT_LE_BIG_INFO_ADV_REPORT 0x22 >>>> struct hci_evt_le_big_info_adv_report { >>>> __le16 sync_handle; >>>> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c >>>> index 66052d6aaa1d..730deaf1851f 100644 >>>> --- a/net/bluetooth/hci_event.c >>>> +++ b/net/bluetooth/hci_event.c >>>> @@ -7026,6 +7026,24 @@ static void >>>> hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data, >>>> hci_dev_unlock(hdev); >>>> } >>>> >>>> +static void hci_le_big_sync_lost_evt(struct hci_dev *hdev, void >>>> *data, >>>> + struct sk_buff *skb) >>>> +{ >>>> + struct hci_evt_le_big_sync_lost *ev = data; >>>> + struct hci_conn *conn; >>>> + >>>> + bt_dev_dbg(hdev, "BIG Sync Lost: big_handle 0x%2.2x", >>>> ev->handle); >>>> + >>>> + hci_dev_lock(hdev); >>>> + >>>> + list_for_each_entry(conn, &hdev->conn_hash.list, list) { >>>> + if (test_bit(HCI_CONN_BIG_SYNC, &conn->flags)) >>>> + hci_disconn_cfm(conn, >>>> HCI_ERROR_REMOTE_USER_TERM); >>>> + } >>>> + >>>> + hci_dev_unlock(hdev); >>>> +} >>>> + >>>> static void hci_le_big_info_adv_report_evt(struct hci_dev *hdev, >>>> void *data, >>>> struct sk_buff *skb) >>>> { >>>> @@ -7149,6 +7167,11 @@ static const struct hci_le_ev { >>>> hci_le_big_sync_established_evt, >>>> sizeof(struct hci_evt_le_big_sync_estabilished), >>>> HCI_MAX_EVENT_SIZE), >>>> + /* [0x1e = HCI_EVT_LE_BIG_SYNC_LOST] */ >>>> + HCI_LE_EV_VL(HCI_EVT_LE_BIG_SYNC_LOST, >>>> + hci_le_big_sync_lost_evt, >>>> + sizeof(struct hci_evt_le_big_sync_lost), >>>> + HCI_MAX_EVENT_SIZE), >>>> /* [0x22 = HCI_EVT_LE_BIG_INFO_ADV_REPORT] */ >>>> HCI_LE_EV_VL(HCI_EVT_LE_BIG_INFO_ADV_REPORT, >>>> hci_le_big_info_adv_report_evt, > > Kind regards, > > Paul
© 2016 - 2025 Red Hat, Inc.