From: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
To: linux-bluetooth@vger.kernel.org
Subject: [PATCH BlueZ v1 09/10] monitor: Reference the request frame on SDP, AVDTP and AVCTP responses
Date: Wed, 9 Sep 2026 14:28:39 -0400 [thread overview]
Message-ID: <20260909182840.1289776-10-luiz.dentz@gmail.com> (raw)
In-Reply-To: <20260909182840.1289776-1-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
SDP pairs a request with its response through the transaction identifier,
and responses use the request PDU plus one with an Error Response able to
answer any request. AVDTP and AVCTP both pair a command with its response
through the transaction label:
SDP: Service Search Request (0x02) tid 5 len 8
SDP: Service Search Response (0x03) tid 5 len 5 #8 (12.400 msec)
AVCTP Control: Command: type 0x00 label 7 PID 0x110e
AVCTP Control: Response: type 0x00 label 7 PID 0x110e #12 (23.100 msec)
These all run on dynamically allocated channels, which is what the channel
keyed matching was needed for.
The model wrote the matching, which the author reviewed and verified
against a trace carrying all three over separate channels.
Assisted-by: opencode:claude-opus-5
---
monitor/avctp.c | 24 ++++++++++++++++++++++--
monitor/avdtp.c | 24 ++++++++++++++++++++++--
monitor/sdp.c | 21 ++++++++++++++++++++-
3 files changed, 64 insertions(+), 5 deletions(-)
diff --git a/monitor/avctp.c b/monitor/avctp.c
index 0db352f18ffd..75afaca8342f 100644
--- a/monitor/avctp.c
+++ b/monitor/avctp.c
@@ -2512,6 +2512,8 @@ void avctp_packet(const struct l2cap_frame *frame)
struct l2cap_frame *l2cap_frame;
struct avctp_frame avctp_frame;
const char *pdu_color;
+ char req_str[32];
+ uint16_t key;
l2cap_frame_pull(&avctp_frame.l2cap_frame, frame, 0);
@@ -2529,12 +2531,30 @@ void avctp_packet(const struct l2cap_frame *frame)
else
pdu_color = COLOR_BLUE;
+ /*
+ * A command is answered by a response carrying the same transaction
+ * label, which is what pairs the two.
+ */
+ key = l2cap_chan_key(frame->index, frame->in, frame->handle,
+ frame->cid);
+ req_str[0] = '\0';
+ if (avctp_frame.hdr & 0x02)
+ packet_req_str(frame->handle, key, PACKET_PROTO_AVCTP,
+ avctp_frame.hdr >> 4,
+ (struct timeval *)&frame->tv,
+ req_str, sizeof(req_str));
+ else
+ packet_req_add(frame->handle, key, PACKET_PROTO_AVCTP,
+ avctp_frame.hdr >> 4,
+ (struct timeval *)&frame->tv, frame->num);
+
print_indent(6, pdu_color, "AVCTP", "", COLOR_OFF,
- " %s: %s: type 0x%02x label %d PID 0x%04x",
+ " %s: %s: type 0x%02x label %d PID 0x%04x%s%s",
frame->psm == 23 ? "Control" : "Browsing",
avctp_frame.hdr & 0x02 ? "Response" : "Command",
avctp_frame.hdr & 0x0c, avctp_frame.hdr >> 4,
- avctp_frame.pid);
+ avctp_frame.pid,
+ req_str[0] ? " " : "", req_str);
if (avctp_frame.pid == 0x110e || avctp_frame.pid == 0x110c)
avrcp_packet(&avctp_frame);
diff --git a/monitor/avdtp.c b/monitor/avdtp.c
index d1eb15356602..9d0016d6bc56 100644
--- a/monitor/avdtp.c
+++ b/monitor/avdtp.c
@@ -667,6 +667,8 @@ static bool avdtp_delayreport(struct avdtp_frame *avdtp_frame)
static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
{
+ char req_str[32];
+ uint16_t key;
struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
const char *pdu_color;
uint8_t hdr;
@@ -703,10 +705,28 @@ static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
avdtp_frame->sig_id = sig_id;
+ /*
+ * A command is answered by a response accept or reject carrying the
+ * same transaction label, which is what pairs the two.
+ */
+ key = l2cap_chan_key(frame->index, frame->in, frame->handle,
+ frame->cid);
+ req_str[0] = '\0';
+ if ((hdr & 0x03) == 0x00)
+ packet_req_add(frame->handle, key, PACKET_PROTO_AVDTP,
+ hdr >> 4, (struct timeval *)&frame->tv,
+ frame->num);
+ else
+ packet_req_str(frame->handle, key, PACKET_PROTO_AVDTP,
+ hdr >> 4, (struct timeval *)&frame->tv,
+ req_str, sizeof(req_str));
+
print_indent(6, pdu_color, "AVDTP: ", sigid2str(sig_id), COLOR_OFF,
- " (0x%02x) %s (0x%02x) type 0x%02x label %d nosp %d",
+ " (0x%02x) %s (0x%02x) type 0x%02x label %d nosp %d"
+ "%s%s",
sig_id, msgtype2str(hdr & 0x03), hdr & 0x03,
- hdr & 0x0c, hdr >> 4, nosp);
+ hdr & 0x0c, hdr >> 4, nosp,
+ req_str[0] ? " " : "", req_str);
/* Start Packet */
if ((hdr & 0x0c) == 0x04) {
diff --git a/monitor/sdp.c b/monitor/sdp.c
index 9f97ba4bbea0..ce06b73ec59f 100644
--- a/monitor/sdp.c
+++ b/monitor/sdp.c
@@ -713,6 +713,8 @@ static const struct sdp_data sdp_table[] = {
void sdp_packet(const struct l2cap_frame *frame)
{
+ char req_str[32];
+ uint16_t key;
uint8_t pdu;
uint16_t tid, plen;
struct l2cap_frame sdp_frame;
@@ -758,8 +760,25 @@ void sdp_packet(const struct l2cap_frame *frame)
pdu_str = "Unknown";
}
+ /*
+ * SDP responses use the request PDU plus one, and an Error Response
+ * may answer any request. The transaction identifier pairs them.
+ */
+ key = l2cap_chan_key(frame->index, frame->in, frame->handle,
+ frame->cid);
+ req_str[0] = '\0';
+ if (pdu == 0x02 || pdu == 0x04 || pdu == 0x06)
+ packet_req_add(frame->handle, key, PACKET_PROTO_SDP,
+ tid, (struct timeval *)&frame->tv,
+ frame->num);
+ else if (pdu == 0x01 || pdu == 0x03 || pdu == 0x05 || pdu == 0x07)
+ packet_req_str(frame->handle, key, PACKET_PROTO_SDP,
+ tid, (struct timeval *)&frame->tv,
+ req_str, sizeof(req_str));
+
print_indent(6, pdu_color, "SDP: ", pdu_str, COLOR_OFF,
- " (0x%2.2x) tid %d len %d", pdu, tid, plen);
+ " (0x%2.2x) tid %d len %d%s%s", pdu, tid, plen,
+ req_str[0] ? " " : "", req_str);
tid_info = get_tid(tid, frame->chan);
--
2.55.0
next prev parent reply other threads:[~2026-09-09 18:28 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-09 18:28 [PATCH BlueZ v1 00/10] monitor: Reference request frames on responses Luiz Augusto von Dentz
2026-09-09 18:28 ` [PATCH BlueZ v1 01/10] monitor: Reference the request frame on command responses Luiz Augusto von Dentz
2026-09-10 17:43 ` monitor: Reference request frames on responses bluez.test.bot
2026-09-09 18:28 ` [PATCH BlueZ v1 02/10] doc/btmon: Document the request reference on command responses Luiz Augusto von Dentz
2026-09-09 18:28 ` [PATCH BlueZ v1 03/10] monitor: Resolve commands completed by a later event Luiz Augusto von Dentz
2026-09-09 18:28 ` [PATCH BlueZ v1 04/10] doc/btmon: Document the deferred command references Luiz Augusto von Dentz
2026-09-09 18:28 ` [PATCH BlueZ v1 05/10] monitor: Report command latency in analyze mode Luiz Augusto von Dentz
2026-09-09 18:28 ` [PATCH BlueZ v1 06/10] doc/btmon: Document the command latency statistics Luiz Augusto von Dentz
2026-09-09 18:28 ` [PATCH BlueZ v1 07/10] monitor: Add request tracking for the protocols above HCI Luiz Augusto von Dentz
2026-09-09 18:28 ` [PATCH BlueZ v1 08/10] monitor/att: Reference the request frame on responses Luiz Augusto von Dentz
2026-09-09 18:28 ` Luiz Augusto von Dentz [this message]
2026-09-09 18:28 ` [PATCH BlueZ v1 10/10] doc/btmon: Document the protocol request references Luiz Augusto von Dentz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260909182840.1289776-10-luiz.dentz@gmail.com \
--to=luiz.dentz@gmail.com \
--cc=linux-bluetooth@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.