Skip to content

Commit 485e062

Browse files
committed
Bluetooth: hci_event: Fix not handling PA Sync Lost event
This handles PA Sync Lost event which previously was assumed to be handled with BIG Sync Lost but their lifetime are not the same thus why there are 2 different events to inform when each sync is lost. Fixes: b2a5f2e ("Bluetooth: hci_event: Add support for handling LE BIG Sync Lost event") Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
1 parent 41bf233 commit 485e062

2 files changed

Lines changed: 40 additions & 14 deletions

File tree

include/net/bluetooth/hci.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2783,6 +2783,11 @@ struct hci_ev_le_per_adv_report {
27832783
__u8 data[];
27842784
} __packed;
27852785

2786+
#define HCI_EV_LE_PA_SYNC_LOST 0x10
2787+
struct hci_ev_le_pa_sync_lost {
2788+
__le16 handle;
2789+
} __packed;
2790+
27862791
#define LE_PA_DATA_COMPLETE 0x00
27872792
#define LE_PA_DATA_MORE_TO_COME 0x01
27882793
#define LE_PA_DATA_TRUNCATED 0x02

net/bluetooth/hci_event.c

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5843,6 +5843,29 @@ static void hci_le_enh_conn_complete_evt(struct hci_dev *hdev, void *data,
58435843
le16_to_cpu(ev->supervision_timeout));
58445844
}
58455845

5846+
static void hci_le_pa_sync_lost_evt(struct hci_dev *hdev, void *data,
5847+
struct sk_buff *skb)
5848+
{
5849+
struct hci_ev_le_pa_sync_lost *ev = data;
5850+
u16 handle = le16_to_cpu(ev->handle);
5851+
struct hci_conn *conn;
5852+
5853+
bt_dev_dbg(hdev, "sync handle 0x%4.4x", handle);
5854+
5855+
hci_dev_lock(hdev);
5856+
5857+
/* Delete the pa sync connection */
5858+
conn = hci_conn_hash_lookup_pa_sync_handle(hdev, handle);
5859+
if (conn) {
5860+
clear_bit(HCI_CONN_BIG_SYNC, &conn->flags);
5861+
clear_bit(HCI_CONN_PA_SYNC, &conn->flags);
5862+
hci_disconn_cfm(conn, HCI_ERROR_REMOTE_USER_TERM);
5863+
hci_conn_del(conn);
5864+
}
5865+
5866+
hci_dev_unlock(hdev);
5867+
}
5868+
58465869
static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, void *data,
58475870
struct sk_buff *skb)
58485871
{
@@ -7046,29 +7069,24 @@ static void hci_le_big_sync_lost_evt(struct hci_dev *hdev, void *data,
70467069
struct sk_buff *skb)
70477070
{
70487071
struct hci_evt_le_big_sync_lost *ev = data;
7049-
struct hci_conn *bis, *conn;
7050-
bool mgmt_conn;
7072+
struct hci_conn *bis;
7073+
bool mgmt_conn = false;
70517074

70527075
bt_dev_dbg(hdev, "big handle 0x%2.2x", ev->handle);
70537076

70547077
hci_dev_lock(hdev);
70557078

7056-
/* Delete the pa sync connection */
7057-
bis = hci_conn_hash_lookup_pa_sync_big_handle(hdev, ev->handle);
7058-
if (bis) {
7059-
conn = hci_conn_hash_lookup_pa_sync_handle(hdev,
7060-
bis->sync_handle);
7061-
if (conn)
7062-
hci_conn_del(conn);
7063-
}
7064-
70657079
/* Delete each bis connection */
70667080
while ((bis = hci_conn_hash_lookup_big_state(hdev, ev->handle,
70677081
BT_CONNECTED,
70687082
HCI_ROLE_SLAVE))) {
7069-
mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &bis->flags);
7070-
mgmt_device_disconnected(hdev, &bis->dst, bis->type, bis->dst_type,
7071-
ev->reason, mgmt_conn);
7083+
if (!mgmt_conn) {
7084+
mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED,
7085+
&bis->flags);
7086+
mgmt_device_disconnected(hdev, &bis->dst, bis->type,
7087+
bis->dst_type, ev->reason,
7088+
mgmt_conn);
7089+
}
70727090

70737091
clear_bit(HCI_CONN_BIG_SYNC, &bis->flags);
70747092
hci_disconn_cfm(bis, ev->reason);
@@ -7182,6 +7200,9 @@ static const struct hci_le_ev {
71827200
hci_le_per_adv_report_evt,
71837201
sizeof(struct hci_ev_le_per_adv_report),
71847202
HCI_MAX_EVENT_SIZE),
7203+
/* [0x10 = HCI_EV_LE_PA_SYNC_LOST] */
7204+
HCI_LE_EV(HCI_EV_LE_PA_SYNC_LOST, hci_le_pa_sync_lost_evt,
7205+
sizeof(struct hci_ev_le_pa_sync_lost)),
71857206
/* [0x12 = HCI_EV_LE_EXT_ADV_SET_TERM] */
71867207
HCI_LE_EV(HCI_EV_LE_EXT_ADV_SET_TERM, hci_le_ext_adv_term_evt,
71877208
sizeof(struct hci_evt_le_ext_adv_set_term)),

0 commit comments

Comments
 (0)