summaryrefslogtreecommitdiff
path: root/net/bluetooth/hci_event.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth/hci_event.c')
-rw-r--r--net/bluetooth/hci_event.c47
1 files changed, 44 insertions, 3 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index cf4b30ac9e0e..b83995898da0 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -6239,6 +6239,11 @@ static void hci_le_adv_report_evt(struct hci_dev *hdev, void *data,
static u8 ext_evt_type_to_legacy(struct hci_dev *hdev, u16 evt_type)
{
+ u16 pdu_type = evt_type & ~LE_EXT_ADV_DATA_STATUS_MASK;
+
+ if (!pdu_type)
+ return LE_ADV_NONCONN_IND;
+
if (evt_type & LE_EXT_ADV_LEGACY_PDU) {
switch (evt_type) {
case LE_LEGACY_ADV_IND:
@@ -6270,8 +6275,7 @@ static u8 ext_evt_type_to_legacy(struct hci_dev *hdev, u16 evt_type)
if (evt_type & LE_EXT_ADV_SCAN_IND)
return LE_ADV_SCAN_IND;
- if (evt_type == LE_EXT_ADV_NON_CONN_IND ||
- evt_type & LE_EXT_ADV_DIRECT_IND)
+ if (evt_type & LE_EXT_ADV_DIRECT_IND)
return LE_ADV_NONCONN_IND;
invalid:
@@ -6876,7 +6880,8 @@ static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data,
/* Connect all BISes that are bound to the BIG */
while ((conn = hci_conn_hash_lookup_big_state(hdev, ev->handle,
- BT_BOUND))) {
+ BT_BOUND,
+ HCI_ROLE_MASTER))) {
if (ev->status) {
hci_connect_cfm(conn, ev->status);
hci_conn_del(conn);
@@ -6992,6 +6997,37 @@ unlock:
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 *bis, *conn;
+
+ bt_dev_dbg(hdev, "big handle 0x%2.2x", ev->handle);
+
+ hci_dev_lock(hdev);
+
+ /* Delete the pa sync connection */
+ bis = hci_conn_hash_lookup_pa_sync_big_handle(hdev, ev->handle);
+ if (bis) {
+ conn = hci_conn_hash_lookup_pa_sync_handle(hdev,
+ bis->sync_handle);
+ if (conn)
+ hci_conn_del(conn);
+ }
+
+ /* Delete each bis connection */
+ while ((bis = hci_conn_hash_lookup_big_state(hdev, ev->handle,
+ BT_CONNECTED,
+ HCI_ROLE_SLAVE))) {
+ clear_bit(HCI_CONN_BIG_SYNC, &bis->flags);
+ hci_disconn_cfm(bis, ev->reason);
+ hci_conn_del(bis);
+ }
+
+ hci_dev_unlock(hdev);
+}
+
static void hci_le_big_info_adv_report_evt(struct hci_dev *hdev, void *data,
struct sk_buff *skb)
{
@@ -7115,6 +7151,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,