Re: [PATCH v2] Bluetooth: Add vendor-specific packet classification for ISO data

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

 



Hi Ying,

On Thu, May 23, 2024 at 2:09 AM Ying Hsu <yinghsu@xxxxxxxxxxxx> wrote:
>
> When HCI raw sockets are opened, the Bluetooth kernel module doesn't
> track CIS/BIS connections. User-space applications have to identify
> ISO data by maintaining connection information and look up the mapping
> for each ACL data packet received. Besides, btsnoop log captured in
> kernel couldn't tell ISO data from ACL data in this case.
>
> To avoid additional lookups, this patch introduces vendor-specific
> packet classification for Intel BT controllers to distinguish
> ISO data packets from ACL data packets.
>
> Signed-off-by: Ying Hsu <yinghsu@xxxxxxxxxxxx>
> ---
> Tested LE audio unicast recording on a ChromeOS device with Intel AX211
>
> Changes in v2:
> - Adds vendor-specific packet classificaton in hci_dev.
> - Keeps reclassification in hci_recv_frame.
>
>  drivers/bluetooth/btusb.c        | 19 +++++++++++++++++++
>  include/net/bluetooth/hci_core.h |  1 +
>  net/bluetooth/hci_core.c         | 16 ++++++++++++++++
>  3 files changed, 36 insertions(+)
>
> diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
> index 79aefdb3324d..75561e749c50 100644
> --- a/drivers/bluetooth/btusb.c
> +++ b/drivers/bluetooth/btusb.c
> @@ -966,6 +966,24 @@ static void btusb_intel_cmd_timeout(struct hci_dev *hdev)
>         gpiod_set_value_cansleep(reset_gpio, 0);
>  }
>
> +#define BT_USB_INTEL_ISODATA_HANDLE_BASE 0x900
> +
> +static u8 btusb_intel_classify_pkt_type(struct hci_dev *hdev, struct sk_buff *skb)

We might as well move this to btintel.c since it should not be USB specific.

> +{
> +       /*
> +        * Distinguish ISO data packets form ACL data packets
> +        * based on their conneciton handle value range.
> +        */
> +       if (hci_skb_pkt_type(skb) == HCI_ACLDATA_PKT) {
> +               __u16 handle = __le16_to_cpu(hci_acl_hdr(skb)->handle);
> +
> +               if (hci_handle(handle) >= BT_USB_INTEL_ISODATA_HANDLE_BASE)
> +                       return HCI_ISODATA_PKT;
> +       }
> +
> +       return hci_skb_pkt_type(skb);
> +}
> +
>  #define RTK_DEVCOREDUMP_CODE_MEMDUMP           0x01
>  #define RTK_DEVCOREDUMP_CODE_HW_ERR            0x02
>  #define RTK_DEVCOREDUMP_CODE_CMD_TIMEOUT       0x03
> @@ -4451,6 +4469,7 @@ static int btusb_probe(struct usb_interface *intf,
>                 /* Transport specific configuration */
>                 hdev->send = btusb_send_frame_intel;
>                 hdev->cmd_timeout = btusb_intel_cmd_timeout;
> +               hdev->classify_pkt_type = btusb_intel_classify_pkt_type;
>
>                 if (id->driver_info & BTUSB_INTEL_NO_WBS_SUPPORT)
>                         btintel_set_flag(hdev, INTEL_ROM_LEGACY_NO_WBS_SUPPORT);
> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> index 9231396fe96f..7b7068a84ff7 100644
> --- a/include/net/bluetooth/hci_core.h
> +++ b/include/net/bluetooth/hci_core.h
> @@ -649,6 +649,7 @@ struct hci_dev {
>         int (*get_codec_config_data)(struct hci_dev *hdev, __u8 type,
>                                      struct bt_codec *codec, __u8 *vnd_len,
>                                      __u8 **vnd_data);
> +       u8 (*classify_pkt_type)(struct hci_dev *hdev, struct sk_buff *skb);
>  };
>
>  #define HCI_PHY_HANDLE(handle) (handle & 0xff)
> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> index b3ee9ff17624..8b817a99cefd 100644
> --- a/net/bluetooth/hci_core.c
> +++ b/net/bluetooth/hci_core.c
> @@ -2941,15 +2941,31 @@ int hci_reset_dev(struct hci_dev *hdev)
>  }
>  EXPORT_SYMBOL(hci_reset_dev);
>
> +static u8 hci_dev_classify_pkt_type(struct hci_dev *hdev, struct sk_buff *skb)
> +{
> +       if (hdev->classify_pkt_type)
> +               return hdev->classify_pkt_type(hdev, skb);
> +
> +       return hci_skb_pkt_type(skb);
> +}
> +
>  /* Receive frame from HCI drivers */
>  int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
>  {
> +       u8 dev_pkt_type;
> +
>         if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
>                       && !test_bit(HCI_INIT, &hdev->flags))) {
>                 kfree_skb(skb);
>                 return -ENXIO;
>         }
>
> +       /* Check if the driver agree with packet type classification */
> +       dev_pkt_type = hci_dev_classify_pkt_type(hdev, skb);
> +       if (hci_skb_pkt_type(skb) != dev_pkt_type) {
> +               hci_skb_pkt_type(skb) = dev_pkt_type;
> +       }
> +
>         switch (hci_skb_pkt_type(skb)) {
>         case HCI_EVENT_PKT:
>                 break;
> --
> 2.45.1.288.g0e0cd299f1-goog
>


-- 
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