Re: [PATCH v2 1/1] Bluetooth: ISO: Fix BIS cleanup

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Iulia,

On Wed, Sep 6, 2023 at 7:00 AM Iulia Tanasescu <iulia.tanasescu@xxxxxxx> wrote:
>
> This fixes the master BIS cleanup procedure - as opposed to CIS cleanup,
> no HCI disconnect command should be issued. A master BIS should only be
> terminated by disabling periodic and extended advertising, and terminating
> the BIG.
>
> In case of a Broadcast Receiver, all BIS and PA connections can be
> cleaned up by calling hci_conn_failed, since it contains all function
> calls that are necessary for successful cleanup.
>
> Signed-off-by: Iulia Tanasescu <iulia.tanasescu@xxxxxxx>
> ---
>  include/net/bluetooth/hci_sync.h |  2 ++
>  net/bluetooth/hci_conn.c         |  7 +++++++
>  net/bluetooth/hci_sync.c         | 28 ++++++++++++----------------
>  3 files changed, 21 insertions(+), 16 deletions(-)
>
> diff --git a/include/net/bluetooth/hci_sync.h b/include/net/bluetooth/hci_sync.h
> index 57eeb07aeb25..6efbc2152146 100644
> --- a/include/net/bluetooth/hci_sync.h
> +++ b/include/net/bluetooth/hci_sync.h
> @@ -80,6 +80,8 @@ int hci_start_per_adv_sync(struct hci_dev *hdev, u8 instance, u8 data_len,
>                            u8 *data, u32 flags, u16 min_interval,
>                            u16 max_interval, u16 sync_interval);
>
> +int hci_disable_per_advertising_sync(struct hci_dev *hdev, u8 instance);
> +
>  int hci_remove_advertising_sync(struct hci_dev *hdev, struct sock *sk,
>                                 u8 instance, bool force);
>  int hci_disable_advertising_sync(struct hci_dev *hdev);
> diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
> index 9d5057cef30a..7c8a5cc72e89 100644
> --- a/net/bluetooth/hci_conn.c
> +++ b/net/bluetooth/hci_conn.c
> @@ -759,6 +759,7 @@ static int terminate_big_sync(struct hci_dev *hdev, void *data)
>
>         bt_dev_dbg(hdev, "big 0x%2.2x bis 0x%2.2x", d->big, d->bis);
>
> +       hci_disable_per_advertising_sync(hdev, d->bis);
>         hci_remove_ext_adv_instance_sync(hdev, d->bis, NULL);
>
>         /* Only terminate BIG if it has been created */
> @@ -1247,6 +1248,12 @@ void hci_conn_failed(struct hci_conn *conn, u8 status)
>                 break;
>         }
>
> +       /* In case of BIG/PA sync failed, clear conn flags so that
> +        * the conns will be correctly cleaned up by ISO layer
> +        */
> +       test_and_clear_bit(HCI_CONN_BIG_SYNC_FAILED, &conn->flags);
> +       test_and_clear_bit(HCI_CONN_PA_SYNC_FAILED, &conn->flags);
> +

I guess we can just use clear_bit here since we won't be using their return.

>         conn->state = BT_CLOSED;
>         hci_connect_cfm(conn, status);
>         hci_conn_del(conn);
> diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
> index fd7c5d902856..ec4dfc4c5749 100644
> --- a/net/bluetooth/hci_sync.c
> +++ b/net/bluetooth/hci_sync.c
> @@ -1312,7 +1312,7 @@ int hci_start_ext_adv_sync(struct hci_dev *hdev, u8 instance)
>         return hci_enable_ext_advertising_sync(hdev, instance);
>  }
>
> -static int hci_disable_per_advertising_sync(struct hci_dev *hdev, u8 instance)
> +int hci_disable_per_advertising_sync(struct hci_dev *hdev, u8 instance)
>  {
>         struct hci_cp_le_set_per_adv_enable cp;
>         struct adv_info *adv = NULL;
> @@ -5231,6 +5231,17 @@ static int hci_disconnect_sync(struct hci_dev *hdev, struct hci_conn *conn,
>         if (conn->type == AMP_LINK)
>                 return hci_disconnect_phy_link_sync(hdev, conn->handle, reason);
>
> +       if (test_bit(HCI_CONN_BIG_CREATED, &conn->flags)) {
> +               /* This is a BIS connection, hci_conn_del will
> +                * do the necessary cleanup.
> +                */
> +               hci_dev_lock(hdev);
> +               hci_conn_failed(conn, reason);
> +               hci_dev_unlock(hdev);
> +
> +               return 0;
> +       }
> +
>         memset(&cp, 0, sizeof(cp));
>         cp.handle = cpu_to_le16(conn->handle);
>         cp.reason = reason;
> @@ -5382,21 +5393,6 @@ int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, u8 reason)
>                 err = hci_reject_conn_sync(hdev, conn, reason);
>                 break;
>         case BT_OPEN:
> -               hci_dev_lock(hdev);
> -
> -               /* Cleanup bis or pa sync connections */
> -               if (test_and_clear_bit(HCI_CONN_BIG_SYNC_FAILED, &conn->flags) ||
> -                   test_and_clear_bit(HCI_CONN_PA_SYNC_FAILED, &conn->flags)) {
> -                       hci_conn_failed(conn, reason);
> -               } else if (test_bit(HCI_CONN_PA_SYNC, &conn->flags) ||
> -                          test_bit(HCI_CONN_BIG_SYNC, &conn->flags)) {
> -                       conn->state = BT_CLOSED;
> -                       hci_disconn_cfm(conn, reason);
> -                       hci_conn_del(conn);
> -               }
> -
> -               hci_dev_unlock(hdev);
> -               return 0;
>         case BT_BOUND:
>                 hci_dev_lock(hdev);
>                 hci_conn_failed(conn, reason);
> --
> 2.34.1
>


-- 
Luiz Augusto von Dentz




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux