mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-28 16:56:26 +00:00
Bluetooth: ISO: Add hcon for listening bis sk
This creates a hcon instance at bis listen, before the PA sync procedure is started. Signed-off-by: Iulia Tanasescu <iulia.tanasescu@nxp.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
6e62ebfb49
commit
02171da6e8
@ -1,7 +1,7 @@
|
||||
/*
|
||||
BlueZ - Bluetooth protocol stack for Linux
|
||||
Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
|
||||
Copyright 2023 NXP
|
||||
Copyright 2023-2024 NXP
|
||||
|
||||
Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
|
||||
|
||||
@ -1528,8 +1528,8 @@ struct hci_conn *hci_connect_cis(struct hci_dev *hdev, bdaddr_t *dst,
|
||||
struct hci_conn *hci_connect_bis(struct hci_dev *hdev, bdaddr_t *dst,
|
||||
__u8 dst_type, struct bt_iso_qos *qos,
|
||||
__u8 data_len, __u8 *data);
|
||||
int hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst, __u8 dst_type,
|
||||
__u8 sid, struct bt_iso_qos *qos);
|
||||
struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst,
|
||||
__u8 dst_type, __u8 sid, struct bt_iso_qos *qos);
|
||||
int hci_le_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon,
|
||||
struct bt_iso_qos *qos,
|
||||
__u16 sync_handle, __u8 num_bis, __u8 bis[]);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
BlueZ - Bluetooth protocol stack for Linux
|
||||
Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
|
||||
Copyright 2023 NXP
|
||||
Copyright 2023-2024 NXP
|
||||
|
||||
Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
|
||||
|
||||
@ -2057,18 +2057,31 @@ static int create_pa_sync(struct hci_dev *hdev, void *data)
|
||||
return hci_update_passive_scan_sync(hdev);
|
||||
}
|
||||
|
||||
int hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst, __u8 dst_type,
|
||||
__u8 sid, struct bt_iso_qos *qos)
|
||||
struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst,
|
||||
__u8 dst_type, __u8 sid,
|
||||
struct bt_iso_qos *qos)
|
||||
{
|
||||
struct hci_cp_le_pa_create_sync *cp;
|
||||
struct hci_conn *conn;
|
||||
int err;
|
||||
|
||||
if (hci_dev_test_and_set_flag(hdev, HCI_PA_SYNC))
|
||||
return -EBUSY;
|
||||
return ERR_PTR(-EBUSY);
|
||||
|
||||
conn = hci_conn_add_unset(hdev, ISO_LINK, dst, HCI_ROLE_SLAVE);
|
||||
if (!conn)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
conn->iso_qos = *qos;
|
||||
conn->state = BT_LISTEN;
|
||||
|
||||
hci_conn_hold(conn);
|
||||
|
||||
cp = kzalloc(sizeof(*cp), GFP_KERNEL);
|
||||
if (!cp) {
|
||||
hci_dev_clear_flag(hdev, HCI_PA_SYNC);
|
||||
return -ENOMEM;
|
||||
hci_conn_drop(conn);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
cp->options = qos->bcast.options;
|
||||
@ -2080,7 +2093,14 @@ int hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst, __u8 dst_type,
|
||||
cp->sync_cte_type = qos->bcast.sync_cte_type;
|
||||
|
||||
/* Queue start pa_create_sync and scan */
|
||||
return hci_cmd_sync_queue(hdev, create_pa_sync, cp, create_pa_complete);
|
||||
err = hci_cmd_sync_queue(hdev, create_pa_sync, cp, create_pa_complete);
|
||||
if (err < 0) {
|
||||
hci_conn_drop(conn);
|
||||
kfree(cp);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
return conn;
|
||||
}
|
||||
|
||||
int hci_le_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon,
|
||||
|
@ -3,7 +3,7 @@
|
||||
* BlueZ - Bluetooth protocol stack for Linux
|
||||
*
|
||||
* Copyright (C) 2022 Intel Corporation
|
||||
* Copyright 2023 NXP
|
||||
* Copyright 2023-2024 NXP
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
@ -690,11 +690,8 @@ static void iso_sock_cleanup_listen(struct sock *parent)
|
||||
iso_sock_kill(sk);
|
||||
}
|
||||
|
||||
/* If listening socket stands for a PA sync connection,
|
||||
* properly disconnect the hcon and socket.
|
||||
*/
|
||||
if (iso_pi(parent)->conn && iso_pi(parent)->conn->hcon &&
|
||||
test_bit(HCI_CONN_PA_SYNC, &iso_pi(parent)->conn->hcon->flags)) {
|
||||
/* If listening socket has a hcon, properly disconnect it */
|
||||
if (iso_pi(parent)->conn && iso_pi(parent)->conn->hcon) {
|
||||
iso_sock_disconn(parent);
|
||||
return;
|
||||
}
|
||||
@ -1076,6 +1073,8 @@ static int iso_listen_bis(struct sock *sk)
|
||||
{
|
||||
struct hci_dev *hdev;
|
||||
int err = 0;
|
||||
struct iso_conn *conn;
|
||||
struct hci_conn *hcon;
|
||||
|
||||
BT_DBG("%pMR -> %pMR (SID 0x%2.2x)", &iso_pi(sk)->src,
|
||||
&iso_pi(sk)->dst, iso_pi(sk)->bc_sid);
|
||||
@ -1096,18 +1095,40 @@ static int iso_listen_bis(struct sock *sk)
|
||||
if (!hdev)
|
||||
return -EHOSTUNREACH;
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
/* Fail if user set invalid QoS */
|
||||
if (iso_pi(sk)->qos_user_set && !check_bcast_qos(&iso_pi(sk)->qos)) {
|
||||
iso_pi(sk)->qos = default_qos;
|
||||
return -EINVAL;
|
||||
err = -EINVAL;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
err = hci_pa_create_sync(hdev, &iso_pi(sk)->dst,
|
||||
le_addr_type(iso_pi(sk)->dst_type),
|
||||
iso_pi(sk)->bc_sid, &iso_pi(sk)->qos);
|
||||
hcon = hci_pa_create_sync(hdev, &iso_pi(sk)->dst,
|
||||
le_addr_type(iso_pi(sk)->dst_type),
|
||||
iso_pi(sk)->bc_sid, &iso_pi(sk)->qos);
|
||||
if (IS_ERR(hcon)) {
|
||||
err = PTR_ERR(hcon);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
conn = iso_conn_add(hcon);
|
||||
if (!conn) {
|
||||
hci_conn_drop(hcon);
|
||||
err = -ENOMEM;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
err = iso_chan_add(conn, sk, NULL);
|
||||
if (err) {
|
||||
hci_conn_drop(hcon);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
hci_dev_put(hdev);
|
||||
|
||||
unlock:
|
||||
hci_dev_unlock(hdev);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user