Skip to content

Commit de3c36b

Browse files
committed
Bluetooth: hci_event: Add support for handling LE BIG Sync Lost event
JIRA: https://issues.redhat.com/browse/RHEL-107922 commit b2a5f2e Author: Yang Li <yang.li@amlogic.com> Date: Tue Jul 1 15:56:22 2025 +0800 Bluetooth: hci_event: Add support for handling LE BIG Sync Lost event 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> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: David Marlin <dmarlin@redhat.com>
1 parent 06bf9b9 commit de3c36b

File tree

4 files changed

+49
-4
lines changed

4 files changed

+49
-4
lines changed

include/net/bluetooth/hci.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2852,6 +2852,12 @@ struct hci_evt_le_big_sync_estabilished {
28522852
__le16 bis[];
28532853
} __packed;
28542854

2855+
#define HCI_EVT_LE_BIG_SYNC_LOST 0x1e
2856+
struct hci_evt_le_big_sync_lost {
2857+
__u8 handle;
2858+
__u8 reason;
2859+
} __packed;
2860+
28552861
#define HCI_EVT_LE_BIG_INFO_ADV_REPORT 0x22
28562862
struct hci_evt_le_big_info_adv_report {
28572863
__le16 sync_handle;

include/net/bluetooth/hci_core.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1369,15 +1369,16 @@ hci_conn_hash_lookup_big_sync_pend(struct hci_dev *hdev,
13691369
}
13701370

13711371
static inline struct hci_conn *
1372-
hci_conn_hash_lookup_big_state(struct hci_dev *hdev, __u8 handle, __u16 state)
1372+
hci_conn_hash_lookup_big_state(struct hci_dev *hdev, __u8 handle, __u16 state,
1373+
__u8 role)
13731374
{
13741375
struct hci_conn_hash *h = &hdev->conn_hash;
13751376
struct hci_conn *c;
13761377

13771378
rcu_read_lock();
13781379

13791380
list_for_each_entry_rcu(c, &h->list, list) {
1380-
if (c->type != BIS_LINK || c->state != state)
1381+
if (c->type != BIS_LINK || c->state != state || c->role != role)
13811382
continue;
13821383

13831384
if (handle == c->iso_qos.bcast.big) {

net/bluetooth/hci_conn.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2159,7 +2159,8 @@ struct hci_conn *hci_bind_bis(struct hci_dev *hdev, bdaddr_t *dst, __u8 sid,
21592159
struct hci_link *link;
21602160

21612161
/* Look for any BIS that is open for rebinding */
2162-
conn = hci_conn_hash_lookup_big_state(hdev, qos->bcast.big, BT_OPEN);
2162+
conn = hci_conn_hash_lookup_big_state(hdev, qos->bcast.big, BT_OPEN,
2163+
HCI_ROLE_MASTER);
21632164
if (conn) {
21642165
memcpy(qos, &conn->iso_qos, sizeof(*qos));
21652166
conn->state = BT_CONNECTED;

net/bluetooth/hci_event.c

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6877,7 +6877,8 @@ static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data,
68776877

68786878
/* Connect all BISes that are bound to the BIG */
68796879
while ((conn = hci_conn_hash_lookup_big_state(hdev, ev->handle,
6880-
BT_BOUND))) {
6880+
BT_BOUND,
6881+
HCI_ROLE_MASTER))) {
68816882
if (ev->status) {
68826883
hci_connect_cfm(conn, ev->status);
68836884
hci_conn_del(conn);
@@ -6998,6 +6999,37 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data,
69986999
hci_dev_unlock(hdev);
69997000
}
70007001

7002+
static void hci_le_big_sync_lost_evt(struct hci_dev *hdev, void *data,
7003+
struct sk_buff *skb)
7004+
{
7005+
struct hci_evt_le_big_sync_lost *ev = data;
7006+
struct hci_conn *bis, *conn;
7007+
7008+
bt_dev_dbg(hdev, "big handle 0x%2.2x", ev->handle);
7009+
7010+
hci_dev_lock(hdev);
7011+
7012+
/* Delete the pa sync connection */
7013+
bis = hci_conn_hash_lookup_pa_sync_big_handle(hdev, ev->handle);
7014+
if (bis) {
7015+
conn = hci_conn_hash_lookup_pa_sync_handle(hdev,
7016+
bis->sync_handle);
7017+
if (conn)
7018+
hci_conn_del(conn);
7019+
}
7020+
7021+
/* Delete each bis connection */
7022+
while ((bis = hci_conn_hash_lookup_big_state(hdev, ev->handle,
7023+
BT_CONNECTED,
7024+
HCI_ROLE_SLAVE))) {
7025+
clear_bit(HCI_CONN_BIG_SYNC, &bis->flags);
7026+
hci_disconn_cfm(bis, ev->reason);
7027+
hci_conn_del(bis);
7028+
}
7029+
7030+
hci_dev_unlock(hdev);
7031+
}
7032+
70017033
static void hci_le_big_info_adv_report_evt(struct hci_dev *hdev, void *data,
70027034
struct sk_buff *skb)
70037035
{
@@ -7121,6 +7153,11 @@ static const struct hci_le_ev {
71217153
hci_le_big_sync_established_evt,
71227154
sizeof(struct hci_evt_le_big_sync_estabilished),
71237155
HCI_MAX_EVENT_SIZE),
7156+
/* [0x1e = HCI_EVT_LE_BIG_SYNC_LOST] */
7157+
HCI_LE_EV_VL(HCI_EVT_LE_BIG_SYNC_LOST,
7158+
hci_le_big_sync_lost_evt,
7159+
sizeof(struct hci_evt_le_big_sync_lost),
7160+
HCI_MAX_EVENT_SIZE),
71247161
/* [0x22 = HCI_EVT_LE_BIG_INFO_ADV_REPORT] */
71257162
HCI_LE_EV_VL(HCI_EVT_LE_BIG_INFO_ADV_REPORT,
71267163
hci_le_big_info_adv_report_evt,

0 commit comments

Comments
 (0)