Skip to content

Commit

Permalink
Bluetooth: ISO: Add hcon for listening bis sk
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
iulia-tanasescu authored and Vudentz committed Mar 6, 2024
1 parent 6e62ebf commit 02171da
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 19 deletions.
6 changes: 3 additions & 3 deletions include/net/bluetooth/hci_core.h
Original file line number Diff line number Diff line change
@@ -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>
Expand Down Expand Up @@ -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[]);
Expand Down
32 changes: 26 additions & 6 deletions net/bluetooth/hci_conn.c
Original file line number Diff line number Diff line change
@@ -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>
Expand Down Expand Up @@ -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;
Expand All @@ -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,
Expand Down
41 changes: 31 additions & 10 deletions net/bluetooth/iso.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}

Expand Down

0 comments on commit 02171da

Please sign in to comment.