Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH BlueZ v2 0/3] BlueZ: Support vendor HCI packets
@ 2026-08-31  5:39 Zijun Hu
  2026-08-31  5:39 ` [PATCH BlueZ v2 1/3] doc/hci-protocol: Fix missing & on mtu argument in BT_RCVMTU example Zijun Hu
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Zijun Hu @ 2026-08-31  5:39 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz
  Cc: Zijun Hu, linux-bluetooth, linux-kernel

This series adds userspace support for vendor HCI packets, which use
0xff as their packet type, complementing the kernel change here:

https://lore.kernel.org/all/20260830-btusb_qcc2072-v2-2-5c0e0c9dd98b@oss.qualcomm.com

All commits are straightforward.

---
Changes in v2:
- Rename BT_RCV_VENDOR_PKT to BT_RECV_VENDOR_PKT
- Improve the commit title and message 
- Link to v1: https://patch.msgid.link/20260719-vendor_hci-v1-0-df2ac5a50117@oss.qualcomm.com

---
Zijun Hu (3):
      doc/hci-protocol: Fix missing & on mtu argument in BT_RCVMTU example
      doc/hci-protocol: Add BT_RECV_VENDOR_PKT socket option for HCI_CHANNEL_USER
      monitor: Support vendor HCI packets

 doc/btsnoop-protocol.rst |  8 ++++++++
 doc/hci-protocol.rst     | 20 +++++++++++++++++++-
 monitor/analyze.c        | 23 +++++++++++++++++++++++
 monitor/packet.c         | 26 ++++++++++++++++++++++++++
 monitor/packet.h         |  2 ++
 src/shared/btsnoop.h     |  2 ++
 6 files changed, 80 insertions(+), 1 deletion(-)
---
base-commit: e8141342284be2a52e16565b96b513ebe1297d84
change-id: 20260719-vendor_hci-188fc539d7a8

Best regards,
--  
Zijun Hu <zijun.hu@oss.qualcomm.com>


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH BlueZ v2 1/3] doc/hci-protocol: Fix missing & on mtu argument in BT_RCVMTU example
  2026-08-31  5:39 [PATCH BlueZ v2 0/3] BlueZ: Support vendor HCI packets Zijun Hu
@ 2026-08-31  5:39 ` Zijun Hu
  2026-08-31  8:05   ` BlueZ: Support vendor HCI packets bluez.test.bot
  2026-08-31  5:39 ` [PATCH BlueZ v2 2/3] doc/hci-protocol: Add BT_RECV_VENDOR_PKT socket option for HCI_CHANNEL_USER Zijun Hu
  2026-08-31  5:39 ` [PATCH BlueZ v2 3/3] monitor: Support vendor HCI packets Zijun Hu
  2 siblings, 1 reply; 6+ messages in thread
From: Zijun Hu @ 2026-08-31  5:39 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz
  Cc: Zijun Hu, linux-bluetooth, linux-kernel

getsockopt() requires a pointer argument, but mtu was passed by value.

Fix by using &mtu instead of mtu.

---
Changes since previous version:
- Improve the commit title and message
---
 doc/hci-protocol.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/hci-protocol.rst b/doc/hci-protocol.rst
index f28684655842..db10b35df736 100644
--- a/doc/hci-protocol.rst
+++ b/doc/hci-protocol.rst
@@ -129,17 +129,17 @@ Example:
 
 .. code-block::
 
     uint16_t mtu;
     socklen_t len;
     int err;
 
     len = sizeof(mtu);
-    err = getsockopt(sock, SOL_BLUETOOTH, BT_RCVMTU, mtu, &len);
+    err = getsockopt(sock, SOL_BLUETOOTH, BT_RCVMTU, &mtu, &len);
 
 RESOURCES
 =========
 
 http://www.bluez.org
 
 REPORTING BUGS
 ==============

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH BlueZ v2 2/3] doc/hci-protocol: Add BT_RECV_VENDOR_PKT socket option for HCI_CHANNEL_USER
  2026-08-31  5:39 [PATCH BlueZ v2 0/3] BlueZ: Support vendor HCI packets Zijun Hu
  2026-08-31  5:39 ` [PATCH BlueZ v2 1/3] doc/hci-protocol: Fix missing & on mtu argument in BT_RCVMTU example Zijun Hu
@ 2026-08-31  5:39 ` Zijun Hu
  2026-08-31  5:39 ` [PATCH BlueZ v2 3/3] monitor: Support vendor HCI packets Zijun Hu
  2 siblings, 0 replies; 6+ messages in thread
From: Zijun Hu @ 2026-08-31  5:39 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz
  Cc: Zijun Hu, linux-bluetooth, linux-kernel

BT_RECV_VENDOR_PKT controls receiving vendor HCI packets over
HCI_CHANNEL_USER.

Disabled by default to avoid regressions for existing applications.

---
Changes since previous version:
- Rename BT_RCV_VENDOR_PKT to BT_RECV_VENDOR_PKT
- Change @enable type from int to uint32_t
- Improve the commit title and message
---
 doc/hci-protocol.rst | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/doc/hci-protocol.rst b/doc/hci-protocol.rst
index db10b35df736..3cb5ce09bb2d 100644
--- a/doc/hci-protocol.rst
+++ b/doc/hci-protocol.rst
@@ -131,16 +131,34 @@ Example:
 
     uint16_t mtu;
     socklen_t len;
     int err;
 
     len = sizeof(mtu);
     err = getsockopt(sock, SOL_BLUETOOTH, BT_RCVMTU, &mtu, &len);
 
+BT_RECV_VENDOR_PKT (since Linux 7.3)
+------------------------------------
+
+Control receiving vendor HCI packets, requires hci_channel to be set to
+HCI_CHANNEL_USER.
+
+Default is disabled.
+
+Example:
+
+.. code-block::
+
+    uint32_t enable = 1;
+    int err;
+
+    err = setsockopt(fd, SOL_BLUETOOTH, BT_RECV_VENDOR_PKT, &enable,
+                      sizeof(enable));
+
 RESOURCES
 =========
 
 http://www.bluez.org
 
 REPORTING BUGS
 ==============
 

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH BlueZ v2 3/3] monitor: Support vendor HCI packets
  2026-08-31  5:39 [PATCH BlueZ v2 0/3] BlueZ: Support vendor HCI packets Zijun Hu
  2026-08-31  5:39 ` [PATCH BlueZ v2 1/3] doc/hci-protocol: Fix missing & on mtu argument in BT_RCVMTU example Zijun Hu
  2026-08-31  5:39 ` [PATCH BlueZ v2 2/3] doc/hci-protocol: Add BT_RECV_VENDOR_PKT socket option for HCI_CHANNEL_USER Zijun Hu
@ 2026-08-31  5:39 ` Zijun Hu
  2026-08-31 14:52   ` Luiz Augusto von Dentz
  2 siblings, 1 reply; 6+ messages in thread
From: Zijun Hu @ 2026-08-31  5:39 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz
  Cc: Zijun Hu, linux-bluetooth, linux-kernel

Vendor HCI packets have 0xff as packet type.

Support them in tool btmon.

---
Changes since previous version:
- Rename COLOR_VENDOR_HCI to COLOR_HCI_VENDOR
- Rename packet_vendor_hci() to packet_hci_vendor()
- Improve the commit title and message
---
 doc/btsnoop-protocol.rst |  8 ++++++++
 monitor/analyze.c        | 23 +++++++++++++++++++++++
 monitor/packet.c         | 26 ++++++++++++++++++++++++++
 monitor/packet.h         |  2 ++
 src/shared/btsnoop.h     |  2 ++
 5 files changed, 61 insertions(+)

diff --git a/doc/btsnoop-protocol.rst b/doc/btsnoop-protocol.rst
index a875db63a9dd..81cd8fdc71ae 100644
--- a/doc/btsnoop-protocol.rst
+++ b/doc/btsnoop-protocol.rst
@@ -111,16 +111,24 @@ values match the definitions in ``src/shared/btsnoop.h``.
    * - BTSNOOP_OPCODE_ISO_TX_PKT
      - 18
      - 0x0012
      - Outgoing ISO packet
    * - BTSNOOP_OPCODE_ISO_RX_PKT
      - 19
      - 0x0013
      - Incoming ISO packet
+   * - BTSNOOP_OPCODE_VENDOR_TX_PKT
+     - 22
+     - 0x0016
+     - Outgoing vendor HCI packet
+   * - BTSNOOP_OPCODE_VENDOR_RX_PKT
+     - 23
+     - 0x0017
+     - Incoming vendor HCI packet
 
 New Index
 ---------
 
 Code: 0x0000
 
 Parameters:
 
diff --git a/monitor/analyze.c b/monitor/analyze.c
index de9c23603a21..59e8ac819272 100644
--- a/monitor/analyze.c
+++ b/monitor/analyze.c
@@ -39,16 +39,17 @@ struct hci_dev {
 	struct timeval time_added;
 	struct timeval time_removed;
 	unsigned long num_hci;
 	unsigned long num_cmd;
 	unsigned long num_evt;
 	unsigned long num_acl;
 	unsigned long num_sco;
 	unsigned long num_iso;
+	unsigned long vendor_hci;
 	unsigned long vendor_diag;
 	unsigned long system_note;
 	unsigned long user_log;
 	unsigned long ctrl_msg;
 	unsigned long unknown;
 	uint16_t manufacturer;
 	struct queue *conn_list;
 };
@@ -460,16 +461,17 @@ static void dev_destroy(void *data)
 	printf("\n");
 
 
 	printf("  %lu commands\n", dev->num_cmd);
 	printf("  %lu events\n", dev->num_evt);
 	printf("  %lu ACL packets\n", dev->num_acl);
 	printf("  %lu SCO packets\n", dev->num_sco);
 	printf("  %lu ISO packets\n", dev->num_iso);
+	printf("  %lu vendor HCI packets\n", dev->vendor_hci);
 	printf("  %lu vendor diagnostics\n", dev->vendor_diag);
 	printf("  %lu system notes\n", dev->system_note);
 	printf("  %lu user logs\n", dev->user_log);
 	printf("  %lu control messages \n", dev->ctrl_msg);
 	printf("  %lu unknown opcodes\n", dev->unknown);
 	queue_destroy(dev->conn_list, conn_destroy);
 	printf("\n");
 
@@ -1357,16 +1359,29 @@ static void iso_pkt(struct timeval *tv, uint16_t index, bool out,
 
 	if (out) {
 		conn_pkt_tx(conn, tv, size - sizeof(*hdr), NULL);
 	} else {
 		conn_pkt_rx(conn, tv, size - sizeof(*hdr), NULL);
 	}
 }
 
+static void vendor_hci_pkt(struct timeval *tv, uint16_t index, bool out,
+					const void *data, uint16_t size)
+{
+	struct hci_dev *dev;
+
+	dev = dev_lookup(index);
+	if (!dev)
+		return;
+
+	dev->num_hci++;
+	dev->vendor_hci++;
+}
+
 static void unknown_opcode(struct timeval *tv, uint16_t index,
 					const void *data, uint16_t size)
 {
 	struct hci_dev *dev;
 
 	dev = dev_lookup(index);
 	if (!dev)
 		return;
@@ -1463,16 +1478,24 @@ void analyze_trace(const char *path)
 		case BTSNOOP_OPCODE_ISO_TX_PKT:
 			num_frames++;
 			iso_pkt(&tv, index, true, buf, pktlen);
 			break;
 		case BTSNOOP_OPCODE_ISO_RX_PKT:
 			num_frames++;
 			iso_pkt(&tv, index, false, buf, pktlen);
 			break;
+		case BTSNOOP_OPCODE_VENDOR_TX_PKT:
+			num_frames++;
+			vendor_hci_pkt(&tv, index, true, buf, pktlen);
+			break;
+		case BTSNOOP_OPCODE_VENDOR_RX_PKT:
+			num_frames++;
+			vendor_hci_pkt(&tv, index, false, buf, pktlen);
+			break;
 		default:
 			unknown_opcode(&tv, index, buf, pktlen);
 			break;
 		}
 
 		num_packets++;
 	}
 
diff --git a/monitor/packet.c b/monitor/packet.c
index 0d3b23cc3fb7..7adcf64a3631 100644
--- a/monitor/packet.c
+++ b/monitor/packet.c
@@ -67,16 +67,17 @@
 
 #define COLOR_HCI_COMMAND		COLOR_BLUE
 #define COLOR_HCI_COMMAND_UNKNOWN	COLOR_WHITE_BG
 #define COLOR_HCI_EVENT			COLOR_MAGENTA
 #define COLOR_HCI_EVENT_UNKNOWN		COLOR_WHITE_BG
 #define COLOR_HCI_ACLDATA		COLOR_CYAN
 #define COLOR_HCI_SCODATA		COLOR_YELLOW
 #define COLOR_HCI_ISODATA		COLOR_YELLOW
+#define COLOR_HCI_VENDOR		COLOR_GREEN
 
 #define COLOR_UNKNOWN_ERROR		COLOR_WHITE_BG
 #define COLOR_UNKNOWN_FEATURE_BIT	COLOR_WHITE_BG
 #define COLOR_UNKNOWN_COMMAND_BIT	COLOR_WHITE_BG
 #define COLOR_UNKNOWN_EVENT_MASK	COLOR_WHITE_BG
 #define COLOR_UNKNOWN_LE_STATES		COLOR_WHITE_BG
 #define COLOR_UNKNOWN_SERVICE_CLASS	COLOR_WHITE_BG
 #define COLOR_UNKNOWN_PKT_TYPE_BIT	COLOR_WHITE_BG
@@ -4523,16 +4524,22 @@ void packet_monitor(struct timeval *tv, struct ucred *cred,
 		packet_hci_scodata(tv, cred, index, true, data, size);
 		break;
 	case BTSNOOP_OPCODE_ISO_TX_PKT:
 		packet_hci_isodata(tv, cred, index, false, data, size);
 		break;
 	case BTSNOOP_OPCODE_ISO_RX_PKT:
 		packet_hci_isodata(tv, cred, index, true, data, size);
 		break;
+	case BTSNOOP_OPCODE_VENDOR_TX_PKT:
+		packet_hci_vendor(tv, cred, index, false, data, size);
+		break;
+	case BTSNOOP_OPCODE_VENDOR_RX_PKT:
+		packet_hci_vendor(tv, cred, index, true, data, size);
+		break;
 	case BTSNOOP_OPCODE_OPEN_INDEX:
 		if (index < MAX_INDEX)
 			addr2str(index_list[index].bdaddr, str);
 		else
 			sprintf(str, "00:00:00:00:00:00");
 
 		packet_open_index(tv, index, str);
 		break;
@@ -14650,16 +14657,35 @@ malformed:
 		print_packet(tv, cred, '*', index, NULL, COLOR_ERROR,
 				"Malformed ISO Data RX packet", NULL, NULL);
 	else
 		print_packet(tv, cred, '*', index, NULL, COLOR_ERROR,
 				"Malformed ISO Data TX packet", NULL, NULL);
 	packet_hexdump(data, size);
 }
 
+void packet_hci_vendor(struct timeval *tv, struct ucred *cred, uint16_t index,
+				bool in, const void *data, uint16_t size)
+{
+	char extra_str[16];
+
+	if (index >= MAX_INDEX) {
+		print_field("Invalid index (%d).", index);
+		return;
+	}
+
+	index_list[index].frame++;
+
+	sprintf(extra_str, "(len %d)", size);
+	print_packet(tv, cred, in ? '>' : '<', index, NULL, COLOR_HCI_VENDOR,
+				"Vendor HCI Packet", NULL, extra_str);
+
+	packet_hexdump(data, size);
+}
+
 void packet_ctrl_open(struct timeval *tv, struct ucred *cred, uint16_t index,
 					const void *data, uint16_t size)
 {
 	uint32_t cookie;
 	uint16_t format;
 	char channel[11];
 
 	if (size < 6) {
diff --git a/monitor/packet.h b/monitor/packet.h
index 73a86f64b242..8c519eca61c1 100644
--- a/monitor/packet.h
+++ b/monitor/packet.h
@@ -130,16 +130,18 @@ void packet_hci_command(struct timeval *tv, struct ucred *cred, uint16_t index,
 void packet_hci_event(struct timeval *tv, struct ucred *cred, uint16_t index,
 					const void *data, uint16_t size);
 void packet_hci_acldata(struct timeval *tv, struct ucred *cred, uint16_t index,
 				bool in, const void *data, uint16_t size);
 void packet_hci_scodata(struct timeval *tv, struct ucred *cred, uint16_t index,
 				bool in, const void *data, uint16_t size);
 void packet_hci_isodata(struct timeval *tv, struct ucred *cred, uint16_t index,
 				bool in, const void *data, uint16_t size);
+void packet_hci_vendor(struct timeval *tv, struct ucred *cred, uint16_t index,
+				bool in, const void *data, uint16_t size);
 
 void packet_ctrl_open(struct timeval *tv, struct ucred *cred, uint16_t index,
 					const void *data, uint16_t size);
 void packet_ctrl_close(struct timeval *tv, struct ucred *cred, uint16_t index,
 					const void *data, uint16_t size);
 void packet_ctrl_command(struct timeval *tv, struct ucred *cred, uint16_t index,
 					const void *data, uint16_t size);
 void packet_ctrl_event(struct timeval *tv, struct ucred *cred, uint16_t index,
diff --git a/src/shared/btsnoop.h b/src/shared/btsnoop.h
index c24755d56729..efa87a8f2971 100644
--- a/src/shared/btsnoop.h
+++ b/src/shared/btsnoop.h
@@ -37,16 +37,18 @@
 #define BTSNOOP_OPCODE_SYSTEM_NOTE	12
 #define BTSNOOP_OPCODE_USER_LOGGING	13
 #define BTSNOOP_OPCODE_CTRL_OPEN	14
 #define BTSNOOP_OPCODE_CTRL_CLOSE	15
 #define BTSNOOP_OPCODE_CTRL_COMMAND	16
 #define BTSNOOP_OPCODE_CTRL_EVENT	17
 #define BTSNOOP_OPCODE_ISO_TX_PKT	18
 #define BTSNOOP_OPCODE_ISO_RX_PKT	19
+#define BTSNOOP_OPCODE_VENDOR_TX_PKT	22
+#define BTSNOOP_OPCODE_VENDOR_RX_PKT	23
 
 #define BTSNOOP_MAX_PACKET_SIZE		(1486 + 4)
 
 #define BTSNOOP_TYPE_PRIMARY	0
 #define BTSNOOP_TYPE_AMP	1
 
 #define BTSNOOP_BUS_VIRTUAL	0
 #define BTSNOOP_BUS_USB		1

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* RE: BlueZ: Support vendor HCI packets
  2026-08-31  5:39 ` [PATCH BlueZ v2 1/3] doc/hci-protocol: Fix missing & on mtu argument in BT_RCVMTU example Zijun Hu
@ 2026-08-31  8:05   ` bluez.test.bot
  0 siblings, 0 replies; 6+ messages in thread
From: bluez.test.bot @ 2026-08-31  8:05 UTC (permalink / raw)
  To: linux-bluetooth, zijun.hu

[-- Attachment #1: Type: text/plain, Size: 1837 bytes --]

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

---Test result---

Test Summary:
CheckPatch                    PASS      2.55 seconds
GitLint                       FAIL      2.95 seconds
BuildEll                      PASS      20.61 seconds
BluezMake                     PASS      590.58 seconds
MakeCheck                     PASS      19.55 seconds
MakeDistcheck                 PASS      167.40 seconds
CheckValgrind                 PASS      249.65 seconds
CheckSmatch                   WARNING   336.70 seconds
bluezmakeextell               PASS      102.99 seconds
IncrementalBuild              PASS      626.78 seconds
ScanBuild                     PASS      970.59 seconds

Details
##############################
Test: GitLint - FAIL
Desc: Run gitlint
Output:
[BlueZ,v2,1/3] doc/hci-protocol: Fix missing & on mtu argument in BT_RCVMTU example

1: T1 Title exceeds max length (83>80): "[BlueZ,v2,1/3] doc/hci-protocol: Fix missing & on mtu argument in BT_RCVMTU example"
[BlueZ,v2,2/3] doc/hci-protocol: Add BT_RECV_VENDOR_PKT socket option for HCI_CHANNEL_USER

1: T1 Title exceeds max length (90>80): "[BlueZ,v2,2/3] doc/hci-protocol: Add BT_RECV_VENDOR_PKT socket option for HCI_CHANNEL_USER"
##############################
Test: CheckSmatch - WARNING
Desc: Run smatch tool with source
Output:
monitor/packet.c:2003:26: warning: Variable length array is used.monitor/packet.c: note: in included file:monitor/bt.h:3924:52: warning: array of flexible structuresmonitor/bt.h:3912:40: warning: array of flexible structures


https://github.com/bluez/bluez/pull/2459

---
Regards,
Linux Bluetooth


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH BlueZ v2 3/3] monitor: Support vendor HCI packets
  2026-08-31  5:39 ` [PATCH BlueZ v2 3/3] monitor: Support vendor HCI packets Zijun Hu
@ 2026-08-31 14:52   ` Luiz Augusto von Dentz
  0 siblings, 0 replies; 6+ messages in thread
From: Luiz Augusto von Dentz @ 2026-08-31 14:52 UTC (permalink / raw)
  To: Zijun Hu; +Cc: Marcel Holtmann, Zijun Hu, linux-bluetooth, linux-kernel

Hi Zijun,

On Mon, Aug 31, 2026 at 1:39 AM Zijun Hu <zijun.hu@oss.qualcomm.com> wrote:
>
> Vendor HCI packets have 0xff as packet type.
>
> Support them in tool btmon.
>
> ---
> Changes since previous version:
> - Rename COLOR_VENDOR_HCI to COLOR_HCI_VENDOR
> - Rename packet_vendor_hci() to packet_hci_vendor()
> - Improve the commit title and message
> ---
>  doc/btsnoop-protocol.rst |  8 ++++++++
>  monitor/analyze.c        | 23 +++++++++++++++++++++++
>  monitor/packet.c         | 26 ++++++++++++++++++++++++++
>  monitor/packet.h         |  2 ++
>  src/shared/btsnoop.h     |  2 ++
>  5 files changed, 61 insertions(+)
>
> diff --git a/doc/btsnoop-protocol.rst b/doc/btsnoop-protocol.rst
> index a875db63a9dd..81cd8fdc71ae 100644
> --- a/doc/btsnoop-protocol.rst
> +++ b/doc/btsnoop-protocol.rst
> @@ -111,16 +111,24 @@ values match the definitions in ``src/shared/btsnoop.h``.
>     * - BTSNOOP_OPCODE_ISO_TX_PKT
>       - 18
>       - 0x0012
>       - Outgoing ISO packet
>     * - BTSNOOP_OPCODE_ISO_RX_PKT
>       - 19
>       - 0x0013
>       - Incoming ISO packet
> +   * - BTSNOOP_OPCODE_VENDOR_TX_PKT
> +     - 22
> +     - 0x0016
> +     - Outgoing vendor HCI packet
> +   * - BTSNOOP_OPCODE_VENDOR_RX_PKT
> +     - 23
> +     - 0x0017
> +     - Incoming vendor HCI packet
>
>  New Index
>  ---------
>
>  Code: 0x0000
>
>  Parameters:
>
> diff --git a/monitor/analyze.c b/monitor/analyze.c
> index de9c23603a21..59e8ac819272 100644
> --- a/monitor/analyze.c
> +++ b/monitor/analyze.c
> @@ -39,16 +39,17 @@ struct hci_dev {
>         struct timeval time_added;
>         struct timeval time_removed;
>         unsigned long num_hci;
>         unsigned long num_cmd;
>         unsigned long num_evt;
>         unsigned long num_acl;
>         unsigned long num_sco;
>         unsigned long num_iso;
> +       unsigned long vendor_hci;
>         unsigned long vendor_diag;
>         unsigned long system_note;
>         unsigned long user_log;
>         unsigned long ctrl_msg;
>         unsigned long unknown;
>         uint16_t manufacturer;
>         struct queue *conn_list;
>  };
> @@ -460,16 +461,17 @@ static void dev_destroy(void *data)
>         printf("\n");
>
>
>         printf("  %lu commands\n", dev->num_cmd);
>         printf("  %lu events\n", dev->num_evt);
>         printf("  %lu ACL packets\n", dev->num_acl);
>         printf("  %lu SCO packets\n", dev->num_sco);
>         printf("  %lu ISO packets\n", dev->num_iso);
> +       printf("  %lu vendor HCI packets\n", dev->vendor_hci);
>         printf("  %lu vendor diagnostics\n", dev->vendor_diag);
>         printf("  %lu system notes\n", dev->system_note);
>         printf("  %lu user logs\n", dev->user_log);
>         printf("  %lu control messages \n", dev->ctrl_msg);
>         printf("  %lu unknown opcodes\n", dev->unknown);
>         queue_destroy(dev->conn_list, conn_destroy);
>         printf("\n");
>
> @@ -1357,16 +1359,29 @@ static void iso_pkt(struct timeval *tv, uint16_t index, bool out,
>
>         if (out) {
>                 conn_pkt_tx(conn, tv, size - sizeof(*hdr), NULL);
>         } else {
>                 conn_pkt_rx(conn, tv, size - sizeof(*hdr), NULL);
>         }
>  }
>
> +static void vendor_hci_pkt(struct timeval *tv, uint16_t index, bool out,
> +                                       const void *data, uint16_t size)
> +{
> +       struct hci_dev *dev;
> +
> +       dev = dev_lookup(index);
> +       if (!dev)
> +               return;
> +
> +       dev->num_hci++;
> +       dev->vendor_hci++;
> +}
> +
>  static void unknown_opcode(struct timeval *tv, uint16_t index,
>                                         const void *data, uint16_t size)
>  {
>         struct hci_dev *dev;
>
>         dev = dev_lookup(index);
>         if (!dev)
>                 return;
> @@ -1463,16 +1478,24 @@ void analyze_trace(const char *path)
>                 case BTSNOOP_OPCODE_ISO_TX_PKT:
>                         num_frames++;
>                         iso_pkt(&tv, index, true, buf, pktlen);
>                         break;
>                 case BTSNOOP_OPCODE_ISO_RX_PKT:
>                         num_frames++;
>                         iso_pkt(&tv, index, false, buf, pktlen);
>                         break;
> +               case BTSNOOP_OPCODE_VENDOR_TX_PKT:
> +                       num_frames++;
> +                       vendor_hci_pkt(&tv, index, true, buf, pktlen);
> +                       break;
> +               case BTSNOOP_OPCODE_VENDOR_RX_PKT:
> +                       num_frames++;
> +                       vendor_hci_pkt(&tv, index, false, buf, pktlen);
> +                       break;
>                 default:
>                         unknown_opcode(&tv, index, buf, pktlen);
>                         break;
>                 }
>
>                 num_packets++;
>         }
>
> diff --git a/monitor/packet.c b/monitor/packet.c
> index 0d3b23cc3fb7..7adcf64a3631 100644
> --- a/monitor/packet.c
> +++ b/monitor/packet.c
> @@ -67,16 +67,17 @@
>
>  #define COLOR_HCI_COMMAND              COLOR_BLUE
>  #define COLOR_HCI_COMMAND_UNKNOWN      COLOR_WHITE_BG
>  #define COLOR_HCI_EVENT                        COLOR_MAGENTA
>  #define COLOR_HCI_EVENT_UNKNOWN                COLOR_WHITE_BG
>  #define COLOR_HCI_ACLDATA              COLOR_CYAN
>  #define COLOR_HCI_SCODATA              COLOR_YELLOW
>  #define COLOR_HCI_ISODATA              COLOR_YELLOW
> +#define COLOR_HCI_VENDOR               COLOR_GREEN
>
>  #define COLOR_UNKNOWN_ERROR            COLOR_WHITE_BG
>  #define COLOR_UNKNOWN_FEATURE_BIT      COLOR_WHITE_BG
>  #define COLOR_UNKNOWN_COMMAND_BIT      COLOR_WHITE_BG
>  #define COLOR_UNKNOWN_EVENT_MASK       COLOR_WHITE_BG
>  #define COLOR_UNKNOWN_LE_STATES                COLOR_WHITE_BG
>  #define COLOR_UNKNOWN_SERVICE_CLASS    COLOR_WHITE_BG
>  #define COLOR_UNKNOWN_PKT_TYPE_BIT     COLOR_WHITE_BG
> @@ -4523,16 +4524,22 @@ void packet_monitor(struct timeval *tv, struct ucred *cred,
>                 packet_hci_scodata(tv, cred, index, true, data, size);
>                 break;
>         case BTSNOOP_OPCODE_ISO_TX_PKT:
>                 packet_hci_isodata(tv, cred, index, false, data, size);
>                 break;
>         case BTSNOOP_OPCODE_ISO_RX_PKT:
>                 packet_hci_isodata(tv, cred, index, true, data, size);
>                 break;
> +       case BTSNOOP_OPCODE_VENDOR_TX_PKT:
> +               packet_hci_vendor(tv, cred, index, false, data, size);
> +               break;
> +       case BTSNOOP_OPCODE_VENDOR_RX_PKT:
> +               packet_hci_vendor(tv, cred, index, true, data, size);
> +               break;
>         case BTSNOOP_OPCODE_OPEN_INDEX:
>                 if (index < MAX_INDEX)
>                         addr2str(index_list[index].bdaddr, str);
>                 else
>                         sprintf(str, "00:00:00:00:00:00");
>
>                 packet_open_index(tv, index, str);
>                 break;
> @@ -14650,16 +14657,35 @@ malformed:
>                 print_packet(tv, cred, '*', index, NULL, COLOR_ERROR,
>                                 "Malformed ISO Data RX packet", NULL, NULL);
>         else
>                 print_packet(tv, cred, '*', index, NULL, COLOR_ERROR,
>                                 "Malformed ISO Data TX packet", NULL, NULL);
>         packet_hexdump(data, size);
>  }
>
> +void packet_hci_vendor(struct timeval *tv, struct ucred *cred, uint16_t index,
> +                               bool in, const void *data, uint16_t size)
> +{
> +       char extra_str[16];
> +
> +       if (index >= MAX_INDEX) {
> +               print_field("Invalid index (%d).", index);
> +               return;
> +       }
> +
> +       index_list[index].frame++;
> +
> +       sprintf(extra_str, "(len %d)", size);
> +       print_packet(tv, cred, in ? '>' : '<', index, NULL, COLOR_HCI_VENDOR,
> +                               "Vendor HCI Packet", NULL, extra_str);
> +
> +       packet_hexdump(data, size);
> +}

There is already support for vendor traffic:

static const struct vendor_ocf *current_vendor_ocf(uint16_t ocf)
{
uint16_t manufacturer, msft_opcode;

if (index_current < MAX_INDEX) {
manufacturer = index_list[index_current].manufacturer;
msft_opcode = index_list[index_current].msft_opcode;
} else {
manufacturer = fallback_manufacturer;
msft_opcode = BT_HCI_CMD_NOP;
}

if (msft_opcode != BT_HCI_CMD_NOP &&
cmd_opcode_ocf(msft_opcode) == ocf)
return msft_vendor_ocf();

switch (manufacturer) {
case COMPANY_ID_INTEL:
return intel_vendor_ocf(ocf);
case COMPANY_ID_BROADCOM:
return broadcom_vendor_ocf(ocf);
}

return NULL;
}

static const struct vendor_evt *current_vendor_evt(const void *data,
uint8_t size, int *consumed_size)
{
uint16_t manufacturer;
uint8_t evt = *((const uint8_t *) data);

if (msft_event_prefix_match(data, size)) {
*consumed_size = index_list[index_current].msft_evt_len;
return msft_vendor_evt();
}

/* A regular vendor event consumes 1 byte. */
*consumed_size = 1;

if (index_current < MAX_INDEX)
manufacturer = index_list[index_current].manufacturer;
else
manufacturer = fallback_manufacturer;

switch (manufacturer) {
case COMPANY_ID_INTEL:
return intel_vendor_evt(data, consumed_size);
case COMPANY_ID_BROADCOM:
return broadcom_vendor_evt(evt);
}

return NULL;
}

So this not only fails to use the manufacturer info to hook into its
own dedicated file but it makes the vendor packets completely opaque
by just hexdumping their content.

>  void packet_ctrl_open(struct timeval *tv, struct ucred *cred, uint16_t index,
>                                         const void *data, uint16_t size)
>  {
>         uint32_t cookie;
>         uint16_t format;
>         char channel[11];
>
>         if (size < 6) {
> diff --git a/monitor/packet.h b/monitor/packet.h
> index 73a86f64b242..8c519eca61c1 100644
> --- a/monitor/packet.h
> +++ b/monitor/packet.h
> @@ -130,16 +130,18 @@ void packet_hci_command(struct timeval *tv, struct ucred *cred, uint16_t index,
>  void packet_hci_event(struct timeval *tv, struct ucred *cred, uint16_t index,
>                                         const void *data, uint16_t size);
>  void packet_hci_acldata(struct timeval *tv, struct ucred *cred, uint16_t index,
>                                 bool in, const void *data, uint16_t size);
>  void packet_hci_scodata(struct timeval *tv, struct ucred *cred, uint16_t index,
>                                 bool in, const void *data, uint16_t size);
>  void packet_hci_isodata(struct timeval *tv, struct ucred *cred, uint16_t index,
>                                 bool in, const void *data, uint16_t size);
> +void packet_hci_vendor(struct timeval *tv, struct ucred *cred, uint16_t index,
> +                               bool in, const void *data, uint16_t size);
>
>  void packet_ctrl_open(struct timeval *tv, struct ucred *cred, uint16_t index,
>                                         const void *data, uint16_t size);
>  void packet_ctrl_close(struct timeval *tv, struct ucred *cred, uint16_t index,
>                                         const void *data, uint16_t size);
>  void packet_ctrl_command(struct timeval *tv, struct ucred *cred, uint16_t index,
>                                         const void *data, uint16_t size);
>  void packet_ctrl_event(struct timeval *tv, struct ucred *cred, uint16_t index,
> diff --git a/src/shared/btsnoop.h b/src/shared/btsnoop.h
> index c24755d56729..efa87a8f2971 100644
> --- a/src/shared/btsnoop.h
> +++ b/src/shared/btsnoop.h
> @@ -37,16 +37,18 @@
>  #define BTSNOOP_OPCODE_SYSTEM_NOTE     12
>  #define BTSNOOP_OPCODE_USER_LOGGING    13
>  #define BTSNOOP_OPCODE_CTRL_OPEN       14
>  #define BTSNOOP_OPCODE_CTRL_CLOSE      15
>  #define BTSNOOP_OPCODE_CTRL_COMMAND    16
>  #define BTSNOOP_OPCODE_CTRL_EVENT      17
>  #define BTSNOOP_OPCODE_ISO_TX_PKT      18
>  #define BTSNOOP_OPCODE_ISO_RX_PKT      19
> +#define BTSNOOP_OPCODE_VENDOR_TX_PKT   22
> +#define BTSNOOP_OPCODE_VENDOR_RX_PKT   23
>
>  #define BTSNOOP_MAX_PACKET_SIZE                (1486 + 4)
>
>  #define BTSNOOP_TYPE_PRIMARY   0
>  #define BTSNOOP_TYPE_AMP       1
>
>  #define BTSNOOP_BUS_VIRTUAL    0
>  #define BTSNOOP_BUS_USB                1
>
> --
> 2.34.1
>


-- 
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-08-31 14:52 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-31  5:39 [PATCH BlueZ v2 0/3] BlueZ: Support vendor HCI packets Zijun Hu
2026-08-31  5:39 ` [PATCH BlueZ v2 1/3] doc/hci-protocol: Fix missing & on mtu argument in BT_RCVMTU example Zijun Hu
2026-08-31  8:05   ` BlueZ: Support vendor HCI packets bluez.test.bot
2026-08-31  5:39 ` [PATCH BlueZ v2 2/3] doc/hci-protocol: Add BT_RECV_VENDOR_PKT socket option for HCI_CHANNEL_USER Zijun Hu
2026-08-31  5:39 ` [PATCH BlueZ v2 3/3] monitor: Support vendor HCI packets Zijun Hu
2026-08-31 14:52   ` Luiz Augusto von Dentz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox