diff options
author | Iulia Tanasescu <iulia.tanasescu@nxp.com> | 2024-02-23 15:14:41 +0200 |
---|---|---|
committer | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2024-03-06 17:26:18 -0500 |
commit | 02171da6e86a73e1b343b36722f5d9d5c04b3539 (patch) | |
tree | 0bade8e5cef7dd07d343f366b5dfb3ef99dc3cf3 /net/bluetooth/iso.c | |
parent | 6e62ebfb49eb65bdcbfc5797db55e0ce7f79c3dd (diff) | |
download | lwn-02171da6e86a73e1b343b36722f5d9d5c04b3539.tar.gz lwn-02171da6e86a73e1b343b36722f5d9d5c04b3539.zip |
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>
Diffstat (limited to 'net/bluetooth/iso.c')
-rw-r--r-- | net/bluetooth/iso.c | 41 |
1 files changed, 31 insertions, 10 deletions
diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c index 04f6572d35f1..d9ee69fa1384 100644 --- a/net/bluetooth/iso.c +++ b/net/bluetooth/iso.c @@ -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; } |