Bluetooth: hci_event: Fix not indicating new connection for BIG Sync

BIG Sync (aka. Broadcast sink) requires to inform that the device is
connected when a data path is active otherwise userspace could attempt
to free resources allocated to the device object while scanning.

Fixes: 1d11d70d ("Bluetooth: ISO: Pass BIG encryption info through QoS")
Signed-off-by: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
parent e7b02296
...@@ -2524,9 +2524,7 @@ static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn, ...@@ -2524,9 +2524,7 @@ static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
* Only those in BT_CONFIG or BT_CONNECTED states can be * Only those in BT_CONFIG or BT_CONNECTED states can be
* considered connected. * considered connected.
*/ */
if (conn && if (conn && (conn->state == BT_CONFIG || conn->state == BT_CONNECTED))
(conn->state == BT_CONFIG || conn->state == BT_CONNECTED) &&
!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
mgmt_device_connected(hdev, conn, name, name_len); mgmt_device_connected(hdev, conn, name, name_len);
if (discov->state == DISCOVERY_STOPPED) if (discov->state == DISCOVERY_STOPPED)
...@@ -3758,8 +3756,9 @@ static void hci_remote_features_evt(struct hci_dev *hdev, void *data, ...@@ -3758,8 +3756,9 @@ static void hci_remote_features_evt(struct hci_dev *hdev, void *data,
bacpy(&cp.bdaddr, &conn->dst); bacpy(&cp.bdaddr, &conn->dst);
cp.pscan_rep_mode = 0x02; cp.pscan_rep_mode = 0x02;
hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
} else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) } else {
mgmt_device_connected(hdev, conn, NULL, 0); mgmt_device_connected(hdev, conn, NULL, 0);
}
if (!hci_outgoing_auth_needed(hdev, conn)) { if (!hci_outgoing_auth_needed(hdev, conn)) {
conn->state = BT_CONNECTED; conn->state = BT_CONNECTED;
...@@ -3932,6 +3931,11 @@ static u8 hci_cc_le_setup_iso_path(struct hci_dev *hdev, void *data, ...@@ -3932,6 +3931,11 @@ static u8 hci_cc_le_setup_iso_path(struct hci_dev *hdev, void *data,
* last. * last.
*/ */
hci_connect_cfm(conn, rp->status); hci_connect_cfm(conn, rp->status);
/* Notify device connected in case it is a BIG Sync */
if (!rp->status && test_bit(HCI_CONN_BIG_SYNC, &conn->flags))
mgmt_device_connected(hdev, conn, NULL, 0);
break; break;
} }
...@@ -5006,8 +5010,9 @@ static void hci_remote_ext_features_evt(struct hci_dev *hdev, void *data, ...@@ -5006,8 +5010,9 @@ static void hci_remote_ext_features_evt(struct hci_dev *hdev, void *data,
bacpy(&cp.bdaddr, &conn->dst); bacpy(&cp.bdaddr, &conn->dst);
cp.pscan_rep_mode = 0x02; cp.pscan_rep_mode = 0x02;
hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
} else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) } else {
mgmt_device_connected(hdev, conn, NULL, 0); mgmt_device_connected(hdev, conn, NULL, 0);
}
if (!hci_outgoing_auth_needed(hdev, conn)) { if (!hci_outgoing_auth_needed(hdev, conn)) {
conn->state = BT_CONNECTED; conn->state = BT_CONNECTED;
...@@ -5980,8 +5985,7 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status, ...@@ -5980,8 +5985,7 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
goto unlock; goto unlock;
} }
if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) mgmt_device_connected(hdev, conn, NULL, 0);
mgmt_device_connected(hdev, conn, NULL, 0);
conn->sec_level = BT_SECURITY_LOW; conn->sec_level = BT_SECURITY_LOW;
conn->state = BT_CONFIG; conn->state = BT_CONFIG;
...@@ -7210,6 +7214,9 @@ static void hci_le_big_info_adv_report_evt(struct hci_dev *hdev, void *data, ...@@ -7210,6 +7214,9 @@ static void hci_le_big_info_adv_report_evt(struct hci_dev *hdev, void *data,
/* Notify iso layer */ /* Notify iso layer */
hci_connect_cfm(pa_sync, 0x00); hci_connect_cfm(pa_sync, 0x00);
/* Notify MGMT layer */
mgmt_device_connected(hdev, pa_sync, NULL, 0);
unlock: unlock:
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
} }
......
...@@ -3126,6 +3126,7 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data, ...@@ -3126,6 +3126,7 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data,
static u8 link_to_bdaddr(u8 link_type, u8 addr_type) static u8 link_to_bdaddr(u8 link_type, u8 addr_type)
{ {
switch (link_type) { switch (link_type) {
case ISO_LINK:
case LE_LINK: case LE_LINK:
switch (addr_type) { switch (addr_type) {
case ADDR_LE_DEV_PUBLIC: case ADDR_LE_DEV_PUBLIC:
...@@ -9618,6 +9619,9 @@ void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn, ...@@ -9618,6 +9619,9 @@ void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn,
u16 eir_len = 0; u16 eir_len = 0;
u32 flags = 0; u32 flags = 0;
if (test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
return;
/* allocate buff for LE or BR/EDR adv */ /* allocate buff for LE or BR/EDR adv */
if (conn->le_adv_data_len > 0) if (conn->le_adv_data_len > 0)
skb = mgmt_alloc_skb(hdev, MGMT_EV_DEVICE_CONNECTED, skb = mgmt_alloc_skb(hdev, MGMT_EV_DEVICE_CONNECTED,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment