mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-29 09:16:33 +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
|
BlueZ - Bluetooth protocol stack for Linux
|
||||||
Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
|
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>
|
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,
|
struct hci_conn *hci_connect_bis(struct hci_dev *hdev, bdaddr_t *dst,
|
||||||
__u8 dst_type, struct bt_iso_qos *qos,
|
__u8 dst_type, struct bt_iso_qos *qos,
|
||||||
__u8 data_len, __u8 *data);
|
__u8 data_len, __u8 *data);
|
||||||
int hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst, __u8 dst_type,
|
struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst,
|
||||||
__u8 sid, struct bt_iso_qos *qos);
|
__u8 dst_type, __u8 sid, struct bt_iso_qos *qos);
|
||||||
int hci_le_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon,
|
int hci_le_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon,
|
||||||
struct bt_iso_qos *qos,
|
struct bt_iso_qos *qos,
|
||||||
__u16 sync_handle, __u8 num_bis, __u8 bis[]);
|
__u16 sync_handle, __u8 num_bis, __u8 bis[]);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
BlueZ - Bluetooth protocol stack for Linux
|
BlueZ - Bluetooth protocol stack for Linux
|
||||||
Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
|
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>
|
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);
|
return hci_update_passive_scan_sync(hdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
int hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst, __u8 dst_type,
|
struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst,
|
||||||
__u8 sid, struct bt_iso_qos *qos)
|
__u8 dst_type, __u8 sid,
|
||||||
|
struct bt_iso_qos *qos)
|
||||||
{
|
{
|
||||||
struct hci_cp_le_pa_create_sync *cp;
|
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))
|
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);
|
cp = kzalloc(sizeof(*cp), GFP_KERNEL);
|
||||||
if (!cp) {
|
if (!cp) {
|
||||||
hci_dev_clear_flag(hdev, HCI_PA_SYNC);
|
hci_dev_clear_flag(hdev, HCI_PA_SYNC);
|
||||||
return -ENOMEM;
|
hci_conn_drop(conn);
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
cp->options = qos->bcast.options;
|
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;
|
cp->sync_cte_type = qos->bcast.sync_cte_type;
|
||||||
|
|
||||||
/* Queue start pa_create_sync and scan */
|
/* 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,
|
int hci_le_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon,
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* BlueZ - Bluetooth protocol stack for Linux
|
* BlueZ - Bluetooth protocol stack for Linux
|
||||||
*
|
*
|
||||||
* Copyright (C) 2022 Intel Corporation
|
* Copyright (C) 2022 Intel Corporation
|
||||||
* Copyright 2023 NXP
|
* Copyright 2023-2024 NXP
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
@ -690,11 +690,8 @@ static void iso_sock_cleanup_listen(struct sock *parent)
|
|||||||
iso_sock_kill(sk);
|
iso_sock_kill(sk);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If listening socket stands for a PA sync connection,
|
/* If listening socket has a hcon, properly disconnect it */
|
||||||
* properly disconnect the hcon and socket.
|
if (iso_pi(parent)->conn && iso_pi(parent)->conn->hcon) {
|
||||||
*/
|
|
||||||
if (iso_pi(parent)->conn && iso_pi(parent)->conn->hcon &&
|
|
||||||
test_bit(HCI_CONN_PA_SYNC, &iso_pi(parent)->conn->hcon->flags)) {
|
|
||||||
iso_sock_disconn(parent);
|
iso_sock_disconn(parent);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1076,6 +1073,8 @@ static int iso_listen_bis(struct sock *sk)
|
|||||||
{
|
{
|
||||||
struct hci_dev *hdev;
|
struct hci_dev *hdev;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
struct iso_conn *conn;
|
||||||
|
struct hci_conn *hcon;
|
||||||
|
|
||||||
BT_DBG("%pMR -> %pMR (SID 0x%2.2x)", &iso_pi(sk)->src,
|
BT_DBG("%pMR -> %pMR (SID 0x%2.2x)", &iso_pi(sk)->src,
|
||||||
&iso_pi(sk)->dst, iso_pi(sk)->bc_sid);
|
&iso_pi(sk)->dst, iso_pi(sk)->bc_sid);
|
||||||
@ -1096,18 +1095,40 @@ static int iso_listen_bis(struct sock *sk)
|
|||||||
if (!hdev)
|
if (!hdev)
|
||||||
return -EHOSTUNREACH;
|
return -EHOSTUNREACH;
|
||||||
|
|
||||||
|
hci_dev_lock(hdev);
|
||||||
|
|
||||||
/* Fail if user set invalid QoS */
|
/* Fail if user set invalid QoS */
|
||||||
if (iso_pi(sk)->qos_user_set && !check_bcast_qos(&iso_pi(sk)->qos)) {
|
if (iso_pi(sk)->qos_user_set && !check_bcast_qos(&iso_pi(sk)->qos)) {
|
||||||
iso_pi(sk)->qos = default_qos;
|
iso_pi(sk)->qos = default_qos;
|
||||||
return -EINVAL;
|
err = -EINVAL;
|
||||||
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = hci_pa_create_sync(hdev, &iso_pi(sk)->dst,
|
hcon = hci_pa_create_sync(hdev, &iso_pi(sk)->dst,
|
||||||
le_addr_type(iso_pi(sk)->dst_type),
|
le_addr_type(iso_pi(sk)->dst_type),
|
||||||
iso_pi(sk)->bc_sid, &iso_pi(sk)->qos);
|
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);
|
hci_dev_put(hdev);
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
hci_dev_unlock(hdev);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user