diff mbox series

Bluetooth: vendor specific ISO data packet identification by handle

Message ID 20240522111139.2612601-1-yinghsu@chromium.org (mailing list archive)
State New
Headers show
Series Bluetooth: vendor specific ISO data packet identification by handle | expand

Checks

Context Check Description
tedd_an/pre-ci_am success Success
tedd_an/CheckPatch success CheckPatch PASS
tedd_an/GitLint success Gitlint PASS
tedd_an/SubjectPrefix success Gitlint PASS
tedd_an/BuildKernel success BuildKernel PASS
tedd_an/CheckAllWarning success CheckAllWarning PASS
tedd_an/CheckSparse success CheckSparse PASS
tedd_an/CheckSmatch fail CheckSparse: FAIL: Segmentation fault (core dumped) make[4]: *** [scripts/Makefile.build:244: net/bluetooth/hci_core.o] Error 139 make[4]: *** Deleting file 'net/bluetooth/hci_core.o' make[3]: *** [scripts/Makefile.build:485: net/bluetooth] Error 2 make[2]: *** [scripts/Makefile.build:485: net] Error 2 make[2]: *** Waiting for unfinished jobs.... Segmentation fault (core dumped) make[4]: *** [scripts/Makefile.build:244: drivers/bluetooth/bcm203x.o] Error 139 make[4]: *** Deleting file 'drivers/bluetooth/bcm203x.o' make[4]: *** Waiting for unfinished jobs.... make[3]: *** [scripts/Makefile.build:485: drivers/bluetooth] Error 2 make[2]: *** [scripts/Makefile.build:485: drivers] Error 2 make[1]: *** [/github/workspace/src/src/Makefile:1919: .] Error 2 make: *** [Makefile:240: __sub-make] Error 2
tedd_an/BuildKernel32 success BuildKernel32 PASS
tedd_an/TestRunnerSetup success TestRunnerSetup PASS
tedd_an/TestRunner_l2cap-tester success TestRunner PASS
tedd_an/TestRunner_iso-tester success TestRunner PASS
tedd_an/TestRunner_bnep-tester success TestRunner PASS
tedd_an/TestRunner_mgmt-tester fail TestRunner_mgmt-tester: Total: 492, Passed: 489 (99.4%), Failed: 1, Not Run: 2
tedd_an/TestRunner_rfcomm-tester success TestRunner PASS
tedd_an/TestRunner_sco-tester success TestRunner PASS
tedd_an/TestRunner_ioctl-tester success TestRunner PASS
tedd_an/TestRunner_mesh-tester success TestRunner PASS
tedd_an/TestRunner_smp-tester success TestRunner PASS
tedd_an/TestRunner_userchan-tester success TestRunner PASS
tedd_an/IncrementalBuild success Incremental Build PASS

Commit Message

Ying Hsu May 22, 2024, 11:11 a.m. UTC
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 catpured in
kernel would couldn't tell ISO data from ACL data in this case.

By differentiating ISO data from ACL data earlier in btusb, we can
eliminate unnecessary lookups and improve btsnoop log clarity.
This patch enables vendor-specific differentiation between ISO and
ACL data packets.

Signed-off-by: Ying Hsu <yinghsu@chromium.org>
---
Tested LE unicast recording on a ChromeOS device with Intel AX211

 drivers/bluetooth/btusb.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

Comments

Paul Menzel May 22, 2024, 11:22 a.m. UTC | #1
Dear Ying,


Thank you for your patch. Some minor comments.

Could you please make the summary/title a statement by using a verb (in 
imperative mood).

Am 22.05.24 um 13:11 schrieb Ying Hsu:
> 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 catpured in

captured

> kernel would couldn't tell ISO data from ACL data in this case.

Excessive *would*?

> By differentiating ISO data from ACL data earlier in btusb, we can
> eliminate unnecessary lookups and improve btsnoop log clarity.
> This patch enables vendor-specific differentiation between ISO and
> ACL data packets.

Make it clear, that this is only done for Intel devices?

> Signed-off-by: Ying Hsu <yinghsu@chromium.org>
> ---
> Tested LE unicast recording on a ChromeOS device with Intel AX211

I’d add that to the commit message, and also name the exact device name 
you used.

>   drivers/bluetooth/btusb.c | 14 ++++++++++++++
>   1 file changed, 14 insertions(+)
> 
> diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
> index 79aefdb3324d..543961b6c671 100644
> --- a/drivers/bluetooth/btusb.c
> +++ b/drivers/bluetooth/btusb.c
> @@ -889,6 +889,8 @@ struct btusb_data {
>   	int (*recv_acl)(struct hci_dev *hdev, struct sk_buff *skb);
>   	int (*recv_bulk)(struct btusb_data *data, void *buffer, int count);
>   
> +	int (*is_iso_data_pkt)(struct sk_buff *skb);
> +
>   	int (*setup_on_usb)(struct hci_dev *hdev);
>   
>   	int oob_wake_irq;   /* irq for out-of-band wake-on-bt */
> @@ -1229,6 +1231,8 @@ static int btusb_recv_bulk(struct btusb_data *data, void *buffer, int count)
>   
>   		if (!hci_skb_expect(skb)) {
>   			/* Complete frame */
> +			if (data->is_iso_data_pkt && data->is_iso_data_pkt(skb))
> +				hci_skb_pkt_type(skb) = HCI_ISODATA_PKT;
>   			btusb_recv_acl(data, skb);
>   			skb = NULL;
>   		}
> @@ -2539,6 +2543,13 @@ static int btusb_recv_bulk_intel(struct btusb_data *data, void *buffer,
>   	return btusb_recv_bulk(data, buffer, count);
>   }
>   
> +static int btusb_is_iso_data_pkt_intel(struct sk_buff *skb)

Why not return `bool`?

> +{
> +	__u16 handle = (__le16_to_cpu(hci_acl_hdr(skb)->handle) & 0xfff);
> +
> +	return (handle >= 0x900);

Define a macro?

> +}
> +
>   static int btusb_send_frame_intel(struct hci_dev *hdev, struct sk_buff *skb)
>   {
>   	struct urb *urb;
> @@ -4361,6 +4372,9 @@ static int btusb_probe(struct usb_interface *intf,
>   		/* Override the rx handlers */
>   		data->recv_event = btintel_recv_event;
>   		data->recv_bulk = btusb_recv_bulk_intel;
> +
> +		/* Override for ISO data packet*/

Please add a space before */.

> +		data->is_iso_data_pkt = btusb_is_iso_data_pkt_intel;
>   	} else if (id->driver_info & BTUSB_REALTEK) {
>   		/* Allocate extra space for Realtek device */
>   		priv_size += sizeof(struct btrealtek_data);
bluez.test.bot@gmail.com May 22, 2024, 11:57 a.m. UTC | #2
This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=855020

---Test result---

Test Summary:
CheckPatch                    PASS      1.04 seconds
GitLint                       PASS      0.34 seconds
SubjectPrefix                 PASS      0.13 seconds
BuildKernel                   PASS      30.30 seconds
CheckAllWarning               PASS      32.73 seconds
CheckSparse                   PASS      38.52 seconds
CheckSmatch                   FAIL      35.58 seconds
BuildKernel32                 PASS      29.17 seconds
TestRunnerSetup               PASS      527.00 seconds
TestRunner_l2cap-tester       PASS      20.46 seconds
TestRunner_iso-tester         PASS      32.82 seconds
TestRunner_bnep-tester        PASS      4.74 seconds
TestRunner_mgmt-tester        FAIL      113.45 seconds
TestRunner_rfcomm-tester      PASS      7.40 seconds
TestRunner_sco-tester         PASS      10.93 seconds
TestRunner_ioctl-tester       PASS      7.82 seconds
TestRunner_mesh-tester        PASS      5.89 seconds
TestRunner_smp-tester         PASS      6.88 seconds
TestRunner_userchan-tester    PASS      8.56 seconds
IncrementalBuild              PASS      29.36 seconds

Details
##############################
Test: CheckSmatch - FAIL
Desc: Run smatch tool with source
Output:

Segmentation fault (core dumped)
make[4]: *** [scripts/Makefile.build:244: net/bluetooth/hci_core.o] Error 139
make[4]: *** Deleting file 'net/bluetooth/hci_core.o'
make[3]: *** [scripts/Makefile.build:485: net/bluetooth] Error 2
make[2]: *** [scripts/Makefile.build:485: net] Error 2
make[2]: *** Waiting for unfinished jobs....
Segmentation fault (core dumped)
make[4]: *** [scripts/Makefile.build:244: drivers/bluetooth/bcm203x.o] Error 139
make[4]: *** Deleting file 'drivers/bluetooth/bcm203x.o'
make[4]: *** Waiting for unfinished jobs....
make[3]: *** [scripts/Makefile.build:485: drivers/bluetooth] Error 2
make[2]: *** [scripts/Makefile.build:485: drivers] Error 2
make[1]: *** [/github/workspace/src/src/Makefile:1919: .] Error 2
make: *** [Makefile:240: __sub-make] Error 2
##############################
Test: TestRunner_mgmt-tester - FAIL
Desc: Run mgmt-tester with test-runner
Output:
Total: 492, Passed: 489 (99.4%), Failed: 1, Not Run: 2

Failed Test Cases
LL Privacy - Add Device 7 (AL is full)               Failed       0.198 seconds


---
Regards,
Linux Bluetooth
Luiz Augusto von Dentz May 22, 2024, 2:10 p.m. UTC | #3
Hi Ying,

On Wed, May 22, 2024 at 7:11 AM Ying Hsu <yinghsu@chromium.org> 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 catpured in
> kernel would couldn't tell ISO data from ACL data in this case.
>
> By differentiating ISO data from ACL data earlier in btusb, we can
> eliminate unnecessary lookups and improve btsnoop log clarity.
> This patch enables vendor-specific differentiation between ISO and
> ACL data packets.
>
> Signed-off-by: Ying Hsu <yinghsu@chromium.org>
> ---
> Tested LE unicast recording on a ChromeOS device with Intel AX211
>
>  drivers/bluetooth/btusb.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
>
> diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
> index 79aefdb3324d..543961b6c671 100644
> --- a/drivers/bluetooth/btusb.c
> +++ b/drivers/bluetooth/btusb.c
> @@ -889,6 +889,8 @@ struct btusb_data {
>         int (*recv_acl)(struct hci_dev *hdev, struct sk_buff *skb);
>         int (*recv_bulk)(struct btusb_data *data, void *buffer, int count);
>
> +       int (*is_iso_data_pkt)(struct sk_buff *skb);

I'd had this sort of callback in hdev itself so the stack can consult
the driver about packet types at any stage, see bellow.

> +
>         int (*setup_on_usb)(struct hci_dev *hdev);
>
>         int oob_wake_irq;   /* irq for out-of-band wake-on-bt */
> @@ -1229,6 +1231,8 @@ static int btusb_recv_bulk(struct btusb_data *data, void *buffer, int count)
>
>                 if (!hci_skb_expect(skb)) {
>                         /* Complete frame */
> +                       if (data->is_iso_data_pkt && data->is_iso_data_pkt(skb))
> +                               hci_skb_pkt_type(skb) = HCI_ISODATA_PKT;

Id keep a single point in the stack doing the reclassification of the
packets, which should probably be in hci_recv_frame, Id suggesting
doing something like:

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index b3ee9ff17624..505ef0b58f8c 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2941,6 +2941,14 @@ int hci_reset_dev(struct hci_dev *hdev)
 }
 EXPORT_SYMBOL(hci_reset_dev);

+static u8 hci_pkt_type(struct hic_dev *dev, struct sk_buff *skb)
+{
+       if (hdev->pkt_type)
+               return hdev->pkt_type(dev, skb);
+
+       return hci_skb_pkt_type(skb);
+}
+
 /* Receive frame from HCI drivers */
 int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
@@ -2950,6 +2958,10 @@ int hci_recv_frame(struct hci_dev *hdev, struct
sk_buff *skb)
                return -ENXIO;
        }

+       /* Check if the driver agree with packet type classification */
+       if (hci_skb_pkt_type(skb) != hci_pkt_type(skb))
+               hci_skb_pkt_type(skb) = hci_pkt_type(skb);
+
        switch (hci_skb_pkt_type(skb)) {
        case HCI_EVENT_PKT:
                break;


>                         btusb_recv_acl(data, skb);
>                         skb = NULL;
>                 }
> @@ -2539,6 +2543,13 @@ static int btusb_recv_bulk_intel(struct btusb_data *data, void *buffer,
>         return btusb_recv_bulk(data, buffer, count);
>  }
>
> +static int btusb_is_iso_data_pkt_intel(struct sk_buff *skb)
> +{
> +       __u16 handle = (__le16_to_cpu(hci_acl_hdr(skb)->handle) & 0xfff);
> +
> +       return (handle >= 0x900);
> +}
> +
>  static int btusb_send_frame_intel(struct hci_dev *hdev, struct sk_buff *skb)
>  {
>         struct urb *urb;
> @@ -4361,6 +4372,9 @@ static int btusb_probe(struct usb_interface *intf,
>                 /* Override the rx handlers */
>                 data->recv_event = btintel_recv_event;
>                 data->recv_bulk = btusb_recv_bulk_intel;
> +
> +               /* Override for ISO data packet*/
> +               data->is_iso_data_pkt = btusb_is_iso_data_pkt_intel;
>         } else if (id->driver_info & BTUSB_REALTEK) {
>                 /* Allocate extra space for Realtek device */
>                 priv_size += sizeof(struct btrealtek_data);
> --
> 2.45.1.288.g0e0cd299f1-goog
>
Ying Hsu May 23, 2024, 3:25 a.m. UTC | #4
Paul and Luiz, thanks for the suggestions.
I would like to use different names for hci_pkt_type and pkt_type for
clear layering. Will post another revision later today.


On Wed, May 22, 2024 at 10:11 PM Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
>
> Hi Ying,
>
> On Wed, May 22, 2024 at 7:11 AM Ying Hsu <yinghsu@chromium.org> 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 catpured in
> > kernel would couldn't tell ISO data from ACL data in this case.
> >
> > By differentiating ISO data from ACL data earlier in btusb, we can
> > eliminate unnecessary lookups and improve btsnoop log clarity.
> > This patch enables vendor-specific differentiation between ISO and
> > ACL data packets.
> >
> > Signed-off-by: Ying Hsu <yinghsu@chromium.org>
> > ---
> > Tested LE unicast recording on a ChromeOS device with Intel AX211
> >
> >  drivers/bluetooth/btusb.c | 14 ++++++++++++++
> >  1 file changed, 14 insertions(+)
> >
> > diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
> > index 79aefdb3324d..543961b6c671 100644
> > --- a/drivers/bluetooth/btusb.c
> > +++ b/drivers/bluetooth/btusb.c
> > @@ -889,6 +889,8 @@ struct btusb_data {
> >         int (*recv_acl)(struct hci_dev *hdev, struct sk_buff *skb);
> >         int (*recv_bulk)(struct btusb_data *data, void *buffer, int count);
> >
> > +       int (*is_iso_data_pkt)(struct sk_buff *skb);
>
> I'd had this sort of callback in hdev itself so the stack can consult
> the driver about packet types at any stage, see bellow.
>
> > +
> >         int (*setup_on_usb)(struct hci_dev *hdev);
> >
> >         int oob_wake_irq;   /* irq for out-of-band wake-on-bt */
> > @@ -1229,6 +1231,8 @@ static int btusb_recv_bulk(struct btusb_data *data, void *buffer, int count)
> >
> >                 if (!hci_skb_expect(skb)) {
> >                         /* Complete frame */
> > +                       if (data->is_iso_data_pkt && data->is_iso_data_pkt(skb))
> > +                               hci_skb_pkt_type(skb) = HCI_ISODATA_PKT;
>
> Id keep a single point in the stack doing the reclassification of the
> packets, which should probably be in hci_recv_frame, Id suggesting
> doing something like:
>
> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> index b3ee9ff17624..505ef0b58f8c 100644
> --- a/net/bluetooth/hci_core.c
> +++ b/net/bluetooth/hci_core.c
> @@ -2941,6 +2941,14 @@ int hci_reset_dev(struct hci_dev *hdev)
>  }
>  EXPORT_SYMBOL(hci_reset_dev);
>
> +static u8 hci_pkt_type(struct hic_dev *dev, struct sk_buff *skb)
> +{
> +       if (hdev->pkt_type)
> +               return hdev->pkt_type(dev, skb);
> +
> +       return hci_skb_pkt_type(skb);
> +}
> +
>  /* Receive frame from HCI drivers */
>  int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
>  {
> @@ -2950,6 +2958,10 @@ int hci_recv_frame(struct hci_dev *hdev, struct
> sk_buff *skb)
>                 return -ENXIO;
>         }
>
> +       /* Check if the driver agree with packet type classification */
> +       if (hci_skb_pkt_type(skb) != hci_pkt_type(skb))
> +               hci_skb_pkt_type(skb) = hci_pkt_type(skb);
> +
>         switch (hci_skb_pkt_type(skb)) {
>         case HCI_EVENT_PKT:
>                 break;
>
>
> >                         btusb_recv_acl(data, skb);
> >                         skb = NULL;
> >                 }
> > @@ -2539,6 +2543,13 @@ static int btusb_recv_bulk_intel(struct btusb_data *data, void *buffer,
> >         return btusb_recv_bulk(data, buffer, count);
> >  }
> >
> > +static int btusb_is_iso_data_pkt_intel(struct sk_buff *skb)
> > +{
> > +       __u16 handle = (__le16_to_cpu(hci_acl_hdr(skb)->handle) & 0xfff);
> > +
> > +       return (handle >= 0x900);
> > +}
> > +
> >  static int btusb_send_frame_intel(struct hci_dev *hdev, struct sk_buff *skb)
> >  {
> >         struct urb *urb;
> > @@ -4361,6 +4372,9 @@ static int btusb_probe(struct usb_interface *intf,
> >                 /* Override the rx handlers */
> >                 data->recv_event = btintel_recv_event;
> >                 data->recv_bulk = btusb_recv_bulk_intel;
> > +
> > +               /* Override for ISO data packet*/
> > +               data->is_iso_data_pkt = btusb_is_iso_data_pkt_intel;
> >         } else if (id->driver_info & BTUSB_REALTEK) {
> >                 /* Allocate extra space for Realtek device */
> >                 priv_size += sizeof(struct btrealtek_data);
> > --
> > 2.45.1.288.g0e0cd299f1-goog
> >
>
>
> --
> Luiz Augusto von Dentz
diff mbox series

Patch

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 79aefdb3324d..543961b6c671 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -889,6 +889,8 @@  struct btusb_data {
 	int (*recv_acl)(struct hci_dev *hdev, struct sk_buff *skb);
 	int (*recv_bulk)(struct btusb_data *data, void *buffer, int count);
 
+	int (*is_iso_data_pkt)(struct sk_buff *skb);
+
 	int (*setup_on_usb)(struct hci_dev *hdev);
 
 	int oob_wake_irq;   /* irq for out-of-band wake-on-bt */
@@ -1229,6 +1231,8 @@  static int btusb_recv_bulk(struct btusb_data *data, void *buffer, int count)
 
 		if (!hci_skb_expect(skb)) {
 			/* Complete frame */
+			if (data->is_iso_data_pkt && data->is_iso_data_pkt(skb))
+				hci_skb_pkt_type(skb) = HCI_ISODATA_PKT;
 			btusb_recv_acl(data, skb);
 			skb = NULL;
 		}
@@ -2539,6 +2543,13 @@  static int btusb_recv_bulk_intel(struct btusb_data *data, void *buffer,
 	return btusb_recv_bulk(data, buffer, count);
 }
 
+static int btusb_is_iso_data_pkt_intel(struct sk_buff *skb)
+{
+	__u16 handle = (__le16_to_cpu(hci_acl_hdr(skb)->handle) & 0xfff);
+
+	return (handle >= 0x900);
+}
+
 static int btusb_send_frame_intel(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct urb *urb;
@@ -4361,6 +4372,9 @@  static int btusb_probe(struct usb_interface *intf,
 		/* Override the rx handlers */
 		data->recv_event = btintel_recv_event;
 		data->recv_bulk = btusb_recv_bulk_intel;
+
+		/* Override for ISO data packet*/
+		data->is_iso_data_pkt = btusb_is_iso_data_pkt_intel;
 	} else if (id->driver_info & BTUSB_REALTEK) {
 		/* Allocate extra space for Realtek device */
 		priv_size += sizeof(struct btrealtek_data);