All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/22] Add AVDTP/A2DP decoding to btmon
@ 2015-11-14 13:44 Andrzej Kaczmarek
  2015-11-14 13:44 ` [PATCH 01/22] monitor/l2cap: Add channel sequence number Andrzej Kaczmarek
                   ` (22 more replies)
  0 siblings, 23 replies; 29+ messages in thread
From: Andrzej Kaczmarek @ 2015-11-14 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

Hi,

Here's series of patches which adds decoding of AVDTP signalling channel
and A2DP codec capabilities information. Few things are missing:
- no fragmentation support
- some rarely used capabilities are not decoded
- ATRAC capabilities are not decoded

Other that above, pretty much everything should be decoded.

And some sample output from decoder:

< ACL Data TX: Handle 256 flags 0x00 dlen 6
      Channel: 1602 len 2 [PSM 25 mode 0] {chan 2}
      AVDTP: Discover (0x01) Command: type 0x00 label 6 nosp 0
> ACL Data RX: Handle 256 flags 0x02 dlen 14
      Channel: 66 len 10 [PSM 25 mode 0] {chan 2}
      AVDTP: Discover (0x01) Response Accept: type 0x00 label 6 nosp 0
        ACP SEID 1
          Media Type: Audio
          SEP Type: SRC
          In use: No
        ACP SEID 5
          Media Type: Audio
          SEP Type: SRC
          In use: No
        ACP SEID 3
          Media Type: Audio
          SEP Type: SRC
          In use: No
        ACP SEID 2
          Media Type: Audio
          SEP Type: SRC
          In use: No


< ACL Data TX: Handle 256 flags 0x00 dlen 7
      Channel: 1602 len 3 [PSM 25 mode 0] {chan 2}
      AVDTP: Get Capabilities (0x02) Command: type 0x00 label 9 nosp 0
        ACP SEID: 3
> ACL Data RX: Handle 256 flags 0x02 dlen 23
      Channel: 66 len 19 [PSM 25 mode 0] {chan 2}
      AVDTP: Get Capabilities (0x02) Response Accept: type 0x00 label 9 nosp 0
        Service Category: Media Transport
        Service Category: Media Codec
          Media Type: Audio
          Media Codec: Non-A2DP
            Vendor ID: 0x0000004f (APT Licensing Ltd.)
            Vendor Specific Codec ID: 0x0001 (aptX)
              Frequency: 0x30
                44100
                48000
              Channel Mode: 0x02
                Stereo
        Service Category: Content Protection
          Content Protection Type: SCMS-T


< ACL Data TX: Handle 256 flags 0x00 dlen 18
      Channel: 1602 len 14 [PSM 25 mode 0] {chan 2}
      AVDTP: Set Configuration (0x03) Command: type 0x00 label 11 nosp 0
        ACP SEID: 1
        INT SEID: 1
        Service Category: Media Transport
        Service Category: Media Codec
          Media Type: Audio
          Media Codec: SBC
            Frequency: 0x20
              44100
            Channel Mode: 0x01
              Joint Channel
            Block Length: 0x10
              16
            Subbands: 0x04
              8
            Allocation Method: 0x01
              Loudness
            Minimum Bitpool: 2
            Maximum Bitpool: 53
> ACL Data RX: Handle 256 flags 0x02 dlen 6
      Channel: 66 len 2 [PSM 25 mode 0] {chan 2}
      AVDTP: Set Configuration (0x03) Response Accept: type 0x00 label 11 nosp 0

> ACL Data RX: Handle 256 flags 0x02 dlen 6
      Channel: 66 len 2 [PSM 25 mode 0] {chan 2}
      AVDTP: Open (0x06) Response Accept: type 0x00 label 12 nosp 0


< ACL Data TX: Handle 256 flags 0x00 dlen 7
      Channel: 1602 len 3 [PSM 25 mode 0] {chan 2}
      AVDTP: Start (0x07) Command: type 0x00 label 13 nosp 0
        ACP SEID: 1
> ACL Data RX: Handle 256 flags 0x02 dlen 6
      Channel: 66 len 2 [PSM 25 mode 0] {chan 2}
      AVDTP: Start (0x07) Response Accept: type 0x00 label 13 nosp 0



Andrzej Kaczmarek (22):
  monitor/l2cap: Add channel sequence number
  monitor/avdtp: Add basic decoding of AVDTP signalling
  monitor/avdtp: Decode AVDTP_DISCOVER
  monitor/avdtp: Decode AVDTP_GET_CAPABILITIES
  monitor/avdtp: Decode AVDTP_SET_CONFIGURATION
  monitor/avdtp: Decode AVDTP_GET_CONFIGURATION
  monitor/avdtp: Decode AVDTP_RECONFIGURE
  monitor/avdtp: Decode AVDTP_OPEN
  monitor/avdtp: Decode AVDTP_START
  monitor/avdtp: Decode AVDTP_CLOSE
  monitor/avdtp: Decode AVDTP_SUSPEND
  monitor/avdtp: Decode AVDTP_ABORT
  monitor/avdtp: Decode AVDTP_SECURITY_CONTROL
  monitor/avdtp: Decode AVDTP_GET_ALL_CAPABILITIES
  monitor/avdtp: Decode AVDTP_DELAYREPORT
  monitor/avdtp: Decode basic Media Codec capabilities
  monitor/avdtp: Decode basic Content Protection capabilities
  monitor/a2dp: Decode SBC capabilities
  monitor/a2dp: Decode MPEG-1,2 capabilities
  monitor/a2dp: Decode AAC capabilities
  monitor/a2dp: Decode aptX capabilities
  monitor/a2dp: Decode LDAC capabilities

 Makefile.tools     |   2 +
 android/Android.mk |   2 +
 monitor/a2dp.c     | 420 +++++++++++++++++++++++++++
 monitor/a2dp.h     |  24 ++
 monitor/avdtp.c    | 819 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 monitor/avdtp.h    |  24 ++
 monitor/l2cap.c    |  48 +++-
 monitor/l2cap.h    |   1 +
 8 files changed, 1327 insertions(+), 13 deletions(-)
 create mode 100644 monitor/a2dp.c
 create mode 100644 monitor/a2dp.h
 create mode 100644 monitor/avdtp.c
 create mode 100644 monitor/avdtp.h

-- 
2.6.2


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

* [PATCH 01/22] monitor/l2cap: Add channel sequence number
  2015-11-14 13:44 [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Andrzej Kaczmarek
@ 2015-11-14 13:44 ` Andrzej Kaczmarek
  2015-11-14 13:44 ` [PATCH 02/22] monitor/avdtp: Add basic decoding of AVDTP signalling Andrzej Kaczmarek
                   ` (21 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Andrzej Kaczmarek @ 2015-11-14 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

This patch adds sequence number to channels structure which determines
order in which channels for the same PSM were created. It will be used
for protocols like AVDTP where there is single PSM used for multiple
channels and order it which they were created is important.
---
 monitor/l2cap.c | 44 +++++++++++++++++++++++++++++++-------------
 monitor/l2cap.h |  1 +
 2 files changed, 32 insertions(+), 13 deletions(-)

diff --git a/monitor/l2cap.c b/monitor/l2cap.c
index 894c741..de86e64 100644
--- a/monitor/l2cap.c
+++ b/monitor/l2cap.c
@@ -99,6 +99,7 @@ struct chan_data {
 	uint8_t  ctrlid;
 	uint8_t  mode;
 	uint8_t  ext_ctrl;
+	uint8_t  seq_num;
 };
 
 static struct chan_data chan_list[MAX_CHAN];
@@ -107,10 +108,13 @@ static void assign_scid(const struct l2cap_frame *frame,
 				uint16_t scid, uint16_t psm, uint8_t ctrlid)
 {
 	int i, n = -1;
+	uint8_t seq_num = 1;
 
 	for (i = 0; i < MAX_CHAN; i++) {
-		if (n < 0 && chan_list[i].handle == 0x0000)
+		if (n < 0 && chan_list[i].handle == 0x0000) {
 			n = i;
+			continue;
+		}
 
 		if (chan_list[i].index != frame->index)
 			continue;
@@ -118,15 +122,16 @@ static void assign_scid(const struct l2cap_frame *frame,
 		if (chan_list[i].handle != frame->handle)
 			continue;
 
+		if (chan_list[i].psm == psm)
+			seq_num++;
+
 		if (frame->in) {
 			if (chan_list[i].dcid == scid) {
 				n = i;
-				break;
 			}
 		} else {
 			if (chan_list[i].scid == scid) {
 				n = i;
-				break;
 			}
 		}
 	}
@@ -147,6 +152,8 @@ static void assign_scid(const struct l2cap_frame *frame,
 	chan_list[n].psm = psm;
 	chan_list[n].ctrlid = ctrlid;
 	chan_list[n].mode = 0;
+
+	chan_list[n].seq_num = seq_num;
 }
 
 static void release_scid(const struct l2cap_frame *frame, uint16_t scid)
@@ -301,6 +308,16 @@ static uint16_t get_chan(const struct l2cap_frame *frame)
 	return i;
 }
 
+static uint8_t get_seq_num(const struct l2cap_frame *frame)
+{
+	int i = get_chan_data_index(frame);
+
+	if (i < 0)
+		return 0;
+
+	return chan_list[i].seq_num;
+}
+
 static void assign_ext_ctrl(const struct l2cap_frame *frame,
 					uint8_t ext_ctrl, uint16_t dcid)
 {
@@ -1384,16 +1401,17 @@ static void l2cap_frame_init(struct l2cap_frame *frame, uint16_t index, bool in,
 				uint16_t handle, uint8_t ident,
 				uint16_t cid, const void *data, uint16_t size)
 {
-	frame->index  = index;
-	frame->in     = in;
-	frame->handle = handle;
-	frame->ident  = ident;
-	frame->cid    = cid;
-	frame->data   = data;
-	frame->size   = size;
-	frame->psm    = get_psm(frame);
-	frame->mode   = get_mode(frame);
-	frame->chan   = get_chan(frame);
+	frame->index   = index;
+	frame->in      = in;
+	frame->handle  = handle;
+	frame->ident   = ident;
+	frame->cid     = cid;
+	frame->data    = data;
+	frame->size    = size;
+	frame->psm     = get_psm(frame);
+	frame->mode    = get_mode(frame);
+	frame->chan    = get_chan(frame);
+	frame->seq_num = get_seq_num(frame);
 }
 
 static void bredr_sig_packet(uint16_t index, bool in, uint16_t handle,
diff --git a/monitor/l2cap.h b/monitor/l2cap.h
index 0364454..813c793 100644
--- a/monitor/l2cap.h
+++ b/monitor/l2cap.h
@@ -34,6 +34,7 @@ struct l2cap_frame {
 	uint16_t psm;
 	uint16_t chan;
 	uint8_t mode;
+	uint8_t seq_num;
 	const void *data;
 	uint16_t size;
 };
-- 
2.6.2


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

* [PATCH 02/22] monitor/avdtp: Add basic decoding of AVDTP signalling
  2015-11-14 13:44 [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Andrzej Kaczmarek
  2015-11-14 13:44 ` [PATCH 01/22] monitor/l2cap: Add channel sequence number Andrzej Kaczmarek
@ 2015-11-14 13:44 ` Andrzej Kaczmarek
  2015-11-14 13:44 ` [PATCH 03/22] monitor/avdtp: Decode AVDTP_DISCOVER Andrzej Kaczmarek
                   ` (20 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Andrzej Kaczmarek @ 2015-11-14 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

---
 Makefile.tools     |   1 +
 android/Android.mk |   1 +
 monitor/avdtp.c    | 176 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 monitor/avdtp.h    |  24 ++++++++
 monitor/l2cap.c    |   4 ++
 5 files changed, 206 insertions(+)
 create mode 100644 monitor/avdtp.c
 create mode 100644 monitor/avdtp.h

diff --git a/Makefile.tools b/Makefile.tools
index d849bd9..387917e 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -27,6 +27,7 @@ monitor_btmon_SOURCES = monitor/main.c monitor/bt.h \
 				monitor/l2cap.h monitor/l2cap.c \
 				monitor/sdp.h monitor/sdp.c \
 				monitor/avctp.h monitor/avctp.c \
+				monitor/avdtp.h monitor/avdtp.c \
 				monitor/rfcomm.h monitor/rfcomm.c \
 				monitor/bnep.h monitor/bnep.c \
 				monitor/uuid.h monitor/uuid.c \
diff --git a/android/Android.mk b/android/Android.mk
index 694a94e..fa1188b 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -339,6 +339,7 @@ LOCAL_SRC_FILES := \
 	bluez/monitor/packet.c \
 	bluez/monitor/l2cap.c \
 	bluez/monitor/avctp.c \
+	bluez/monitor/avdtp.c \
 	bluez/monitor/rfcomm.c \
 	bluez/monitor/bnep.c \
 	bluez/monitor/uuid.c \
diff --git a/monitor/avdtp.c b/monitor/avdtp.c
new file mode 100644
index 0000000..209bbab
--- /dev/null
+++ b/monitor/avdtp.c
@@ -0,0 +1,176 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2015  Andrzej Kaczmarek <andrzej.kaczmarek@codecoup.pl>
+ *
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "lib/bluetooth.h"
+
+#include "src/shared/util.h"
+#include "bt.h"
+#include "packet.h"
+#include "display.h"
+#include "l2cap.h"
+#include "avdtp.h"
+
+/* Signal Identifiers */
+#define AVDTP_DISCOVER			0x01
+#define AVDTP_GET_CAPABILITIES		0x02
+#define AVDTP_SET_CONFIGURATION		0x03
+#define AVDTP_GET_CONFIGURATION		0x04
+#define AVDTP_RECONFIGURE		0x05
+#define AVDTP_OPEN			0x06
+#define AVDTP_START			0x07
+#define AVDTP_CLOSE			0x08
+#define AVDTP_SUSPEND			0x09
+#define AVDTP_ABORT			0x0a
+#define AVDTP_SECURITY_CONTROL		0x0b
+#define AVDTP_GET_ALL_CAPABILITIES	0x0c
+#define AVDTP_DELAYREPORT		0x0d
+
+struct avdtp_frame {
+	uint8_t hdr;
+	struct l2cap_frame l2cap_frame;
+};
+
+static const char *msgtype2str(uint8_t msgtype)
+{
+	switch (msgtype) {
+	case 0:
+		return "Command";
+	case 1:
+		return "General Reject";
+	case 2:
+		return "Response Accept";
+	case 3:
+		return "Response Reject";
+	}
+
+	return "";
+}
+
+static const char *sigid2str(uint8_t sigid)
+{
+	switch (sigid) {
+	case AVDTP_DISCOVER:
+		return "Discover";
+	case AVDTP_GET_CAPABILITIES:
+		return "Get Capabilities";
+	case AVDTP_SET_CONFIGURATION:
+		return "Set Configuration";
+	case AVDTP_GET_CONFIGURATION:
+		return "Get Configuration";
+	case AVDTP_RECONFIGURE:
+		return "Reconfigure";
+	case AVDTP_OPEN:
+		return "Open";
+	case AVDTP_START:
+		return "Start";
+	case AVDTP_CLOSE:
+		return "Close";
+	case AVDTP_SUSPEND:
+		return "Suspend";
+	case AVDTP_ABORT:
+		return "Abort";
+	case AVDTP_SECURITY_CONTROL:
+		return "Security Control";
+	case AVDTP_GET_ALL_CAPABILITIES:
+		return "Get All Capabilities";
+	case AVDTP_DELAYREPORT:
+		return "Delay Report";
+	default:
+		return "Reserved";
+	}
+}
+
+static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
+{
+	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
+	const char *pdu_color;
+	uint8_t hdr;
+	uint8_t nosp = 0;
+	uint8_t sigid;
+
+	if (frame->in)
+		pdu_color = COLOR_MAGENTA;
+	else
+		pdu_color = COLOR_BLUE;
+
+	if (!l2cap_frame_get_u8(frame, &hdr))
+		return false;
+
+	avdtp_frame->hdr = hdr;
+
+	/* Continue Packet || End Packet */
+	if (((hdr & 0x0c) == 0x08) || ((hdr & 0x0c) == 0x0c)) {
+		/* TODO: handle fragmentation */
+		packet_hexdump(frame->data, frame->size);
+		return true;
+	}
+
+	/* Start Packet */
+	if ((hdr & 0x0c) == 0x04) {
+		if (!l2cap_frame_get_u8(frame, &nosp))
+			return false;
+	}
+
+	if (!l2cap_frame_get_u8(frame, &sigid))
+		return false;
+
+	sigid &= 0x3f;
+
+	print_indent(6, pdu_color, "AVDTP: ", sigid2str(sigid), COLOR_OFF,
+				" (0x%02x) %s: type 0x%02x label %d nosp %d",
+				sigid, msgtype2str(hdr & 0x03),
+				hdr & 0x0c, hdr >> 4, nosp);
+
+	packet_hexdump(frame->data, frame->size);
+	return true;
+}
+
+void avdtp_packet(const struct l2cap_frame *frame)
+{
+	struct avdtp_frame avdtp_frame;
+	bool ret;
+
+	l2cap_frame_pull(&avdtp_frame.l2cap_frame, frame, 0);
+
+	switch (frame->seq_num) {
+	case 1:
+		ret = avdtp_signalling_packet(&avdtp_frame);
+		break;
+	default:
+		packet_hexdump(frame->data, frame->size);
+		return;
+	}
+
+	if (!ret) {
+		print_text(COLOR_ERROR, "PDU malformed");
+		packet_hexdump(frame->data, frame->size);
+	}
+}
diff --git a/monitor/avdtp.h b/monitor/avdtp.h
new file mode 100644
index 0000000..f77d82e
--- /dev/null
+++ b/monitor/avdtp.h
@@ -0,0 +1,24 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2015  Andrzej Kaczmarek <andrzej.kaczmarek@codecoup.pl>
+ *
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+void avdtp_packet(const struct l2cap_frame *frame);
diff --git a/monitor/l2cap.c b/monitor/l2cap.c
index de86e64..ba8feb7 100644
--- a/monitor/l2cap.c
+++ b/monitor/l2cap.c
@@ -42,6 +42,7 @@
 #include "keys.h"
 #include "sdp.h"
 #include "avctp.h"
+#include "avdtp.h"
 #include "rfcomm.h"
 #include "bnep.h"
 
@@ -3098,6 +3099,9 @@ static void l2cap_frame(uint16_t index, bool in, uint16_t handle,
 		case 0x001B:
 			avctp_packet(&frame);
 			break;
+		case 0x0019:
+			avdtp_packet(&frame);
+			break;
 		default:
 			packet_hexdump(data, size);
 			break;
-- 
2.6.2


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

* [PATCH 03/22] monitor/avdtp: Decode AVDTP_DISCOVER
  2015-11-14 13:44 [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Andrzej Kaczmarek
  2015-11-14 13:44 ` [PATCH 01/22] monitor/l2cap: Add channel sequence number Andrzej Kaczmarek
  2015-11-14 13:44 ` [PATCH 02/22] monitor/avdtp: Add basic decoding of AVDTP signalling Andrzej Kaczmarek
@ 2015-11-14 13:44 ` Andrzej Kaczmarek
  2015-11-14 13:44 ` [PATCH 04/22] monitor/avdtp: Decode AVDTP_GET_CAPABILITIES Andrzej Kaczmarek
                   ` (19 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Andrzej Kaczmarek @ 2015-11-14 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

---
 monitor/avdtp.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 131 insertions(+), 2 deletions(-)

diff --git a/monitor/avdtp.c b/monitor/avdtp.c
index 209bbab..f851107 100644
--- a/monitor/avdtp.c
+++ b/monitor/avdtp.c
@@ -108,6 +108,114 @@ static const char *sigid2str(uint8_t sigid)
 	}
 }
 
+static const char *error2str(uint8_t error)
+{
+	switch (error) {
+	case 0x01:
+		return "BAD_HEADER_FORMAT";
+	case 0x11:
+		return "BAD_LENGTH";
+	case 0x12:
+		return "BAD_ACP_SEID";
+	case 0x13:
+		return "SEP_IN_USE";
+	case 0x14:
+		return "SEP_NOT_IN_USER";
+	case 0x17:
+		return "BAD_SERV_CATEGORY";
+	case 0x18:
+		return "BAD_PAYLOAD_FORMAT";
+	case 0x19:
+		return "NOT_SUPPORTED_COMMAND";
+	case 0x1a:
+		return "INVALID_CAPABILITIES";
+	case 0x22:
+		return "BAD_RECOVERY_TYPE";
+	case 0x23:
+		return "BAD_MEDIA_TRANSPORT_FORMAT";
+	case 0x25:
+		return "BAD_RECOVERY_FORMAT";
+	case 0x26:
+		return "BAD_ROHC_FORMAT";
+	case 0x27:
+		return "BAD_CP_FORMAT";
+	case 0x28:
+		return "BAD_MULTIPLEXING_FORMAT";
+	case 0x29:
+		return "UNSUPPORTED_CONFIGURATION";
+	case 0x31:
+		return "BAD_STATE";
+	default:
+		return "Unknown";
+	}
+}
+
+static const char *mediatype2str(uint8_t media_type)
+{
+	switch (media_type) {
+	case 0x00:
+		return "Audio";
+	case 0x01:
+		return "Video";
+	case 0x02:
+		return "Multimedia";
+	default:
+		return "Reserver";
+	}
+}
+
+static bool avdtp_reject_common(struct avdtp_frame *avdtp_frame)
+{
+	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
+	uint8_t error;
+
+	if (!l2cap_frame_get_u8(frame, &error))
+		return false;
+
+	print_field("Error code: %s (0x%02x)", error2str(error), error);
+
+	return true;
+}
+
+static bool avdtp_discover(struct avdtp_frame *avdtp_frame)
+{
+	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
+
+	if (avdtp_frame->hdr & 0x01)
+		goto reject;
+
+	if (avdtp_frame->hdr & 0x02)
+		goto response;
+
+	/* no extra parameters */
+	return true;
+
+reject:
+	return avdtp_reject_common(avdtp_frame);
+
+response:
+	for (;;) {
+		uint8_t seid;
+		uint8_t info;
+
+		if (!l2cap_frame_get_u8(frame, &seid))
+			break;
+
+		if (!l2cap_frame_get_u8(frame, &info))
+			return false;
+
+		print_field("ACP SEID %d", seid >> 2);
+		print_field("%*cMedia Type: %s", 2, ' ',
+						mediatype2str(info >> 4));
+		print_field("%*cSEP Type: %s", 2, ' ',
+						info & 0x04 ? "SNK" : "SRC");
+		print_field("%*cIn use: %s", 2, ' ',
+						seid & 0x02 ? "Yes" : "No");
+	}
+
+	return true;
+}
+
 static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
 {
 	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
@@ -115,6 +223,7 @@ static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
 	uint8_t hdr;
 	uint8_t nosp = 0;
 	uint8_t sigid;
+	bool ret;
 
 	if (frame->in)
 		pdu_color = COLOR_MAGENTA;
@@ -149,8 +258,28 @@ static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
 				sigid, msgtype2str(hdr & 0x03),
 				hdr & 0x0c, hdr >> 4, nosp);
 
-	packet_hexdump(frame->data, frame->size);
-	return true;
+	/* Start Packet */
+	if ((hdr & 0x0c) == 0x04) {
+		/* TODO: handle fragmentation */
+		packet_hexdump(frame->data, frame->size);
+		return true;
+	}
+
+	/* General Reject */
+	if ((hdr & 0x03) == 0x03)
+		return true;
+
+	switch (sigid) {
+	case AVDTP_DISCOVER:
+		ret = avdtp_discover(avdtp_frame);
+		break;
+	default:
+		packet_hexdump(frame->data, frame->size);
+		ret = true;
+		break;
+	}
+
+	return ret;
 }
 
 void avdtp_packet(const struct l2cap_frame *frame)
-- 
2.6.2


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

* [PATCH 04/22] monitor/avdtp: Decode AVDTP_GET_CAPABILITIES
  2015-11-14 13:44 [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Andrzej Kaczmarek
                   ` (2 preceding siblings ...)
  2015-11-14 13:44 ` [PATCH 03/22] monitor/avdtp: Decode AVDTP_DISCOVER Andrzej Kaczmarek
@ 2015-11-14 13:44 ` Andrzej Kaczmarek
  2015-11-14 13:44 ` [PATCH 05/22] monitor/avdtp: Decode AVDTP_SET_CONFIGURATION Andrzej Kaczmarek
                   ` (18 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Andrzej Kaczmarek @ 2015-11-14 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

---
 monitor/avdtp.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 92 insertions(+)

diff --git a/monitor/avdtp.c b/monitor/avdtp.c
index f851107..cae704a 100644
--- a/monitor/avdtp.c
+++ b/monitor/avdtp.c
@@ -53,6 +53,16 @@
 #define AVDTP_GET_ALL_CAPABILITIES	0x0c
 #define AVDTP_DELAYREPORT		0x0d
 
+/* Service Categories */
+#define AVDTP_MEDIA_TRANSPORT		0x01
+#define AVDTP_REPORTING			0x02
+#define AVDTP_RECOVERY			0x03
+#define AVDTP_CONTENT_PROTECTION	0x04
+#define AVDTP_HEADER_COMPRESSION	0x05
+#define AVDTP_MULTIPLEXING		0x06
+#define AVDTP_MEDIA_CODEC		0x07
+#define AVDTP_DELAY_REPORTING		0x08
+
 struct avdtp_frame {
 	uint8_t hdr;
 	struct l2cap_frame l2cap_frame;
@@ -164,6 +174,30 @@ static const char *mediatype2str(uint8_t media_type)
 	}
 }
 
+static const char *servicecat2str(uint8_t service_cat)
+{
+	switch (service_cat) {
+	case AVDTP_MEDIA_TRANSPORT:
+		return "Media Transport";
+	case AVDTP_REPORTING:
+		return "Reporting";
+	case AVDTP_RECOVERY:
+		return "Recovery";
+	case AVDTP_CONTENT_PROTECTION:
+		return "Content Protection";
+	case AVDTP_HEADER_COMPRESSION:
+		return "Header Compression";
+	case AVDTP_MULTIPLEXING:
+		return "Multiplexing";
+	case AVDTP_MEDIA_CODEC:
+		return "Media Codec";
+	case AVDTP_DELAY_REPORTING:
+		return "Delay Reporting";
+	default:
+		return "Reserved";
+	}
+}
+
 static bool avdtp_reject_common(struct avdtp_frame *avdtp_frame)
 {
 	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
@@ -177,6 +211,36 @@ static bool avdtp_reject_common(struct avdtp_frame *avdtp_frame)
 	return true;
 }
 
+static bool decode_capabilities(struct avdtp_frame *avdtp_frame)
+{
+	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
+
+	for (;;) {
+		uint8_t service_cat;
+		uint8_t losc;
+
+		if (!l2cap_frame_get_u8(frame, &service_cat))
+			break;
+
+		if (!l2cap_frame_get_u8(frame, &losc))
+			return false;
+
+		print_field("Service Category: %s",
+						servicecat2str(service_cat));
+
+		if (frame->size < losc)
+			return false;
+
+		/* TODO: decode service capabilities */
+
+		packet_hexdump(frame->data, losc);
+
+		l2cap_frame_pull(frame, frame, losc);
+	}
+
+	return true;
+}
+
 static bool avdtp_discover(struct avdtp_frame *avdtp_frame)
 {
 	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
@@ -216,6 +280,31 @@ response:
 	return true;
 }
 
+static bool avdtp_get_capabilities(struct avdtp_frame *avdtp_frame)
+{
+	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
+	uint8_t seid;
+
+	if (avdtp_frame->hdr & 0x01)
+		goto reject;
+
+	if (avdtp_frame->hdr & 0x02)
+		goto response;
+
+	if (!l2cap_frame_get_u8(frame, &seid))
+		return false;
+
+	print_field("ACP SEID: %d", seid >> 2);
+
+	return true;
+
+reject:
+	return avdtp_reject_common(avdtp_frame);
+
+response:
+	return decode_capabilities(avdtp_frame);
+}
+
 static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
 {
 	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
@@ -273,6 +362,9 @@ static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
 	case AVDTP_DISCOVER:
 		ret = avdtp_discover(avdtp_frame);
 		break;
+	case AVDTP_GET_CAPABILITIES:
+		ret = avdtp_get_capabilities(avdtp_frame);
+		break;
 	default:
 		packet_hexdump(frame->data, frame->size);
 		ret = true;
-- 
2.6.2


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

* [PATCH 05/22] monitor/avdtp: Decode AVDTP_SET_CONFIGURATION
  2015-11-14 13:44 [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Andrzej Kaczmarek
                   ` (3 preceding siblings ...)
  2015-11-14 13:44 ` [PATCH 04/22] monitor/avdtp: Decode AVDTP_GET_CAPABILITIES Andrzej Kaczmarek
@ 2015-11-14 13:44 ` Andrzej Kaczmarek
  2015-11-14 13:44 ` [PATCH 06/22] monitor/avdtp: Decode AVDTP_GET_CONFIGURATION Andrzej Kaczmarek
                   ` (17 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Andrzej Kaczmarek @ 2015-11-14 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

---
 monitor/avdtp.c | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/monitor/avdtp.c b/monitor/avdtp.c
index cae704a..f38d359 100644
--- a/monitor/avdtp.c
+++ b/monitor/avdtp.c
@@ -305,6 +305,42 @@ response:
 	return decode_capabilities(avdtp_frame);
 }
 
+static bool avdtp_set_configuration(struct avdtp_frame *avdtp_frame)
+{
+	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
+	uint8_t acp_seid, int_seid;
+	uint8_t service_cat;
+
+	if (avdtp_frame->hdr & 0x01)
+		goto reject;
+
+	if (avdtp_frame->hdr & 0x02)
+		goto response;
+
+	if (!l2cap_frame_get_u8(frame, &acp_seid))
+		return false;
+
+	if (!l2cap_frame_get_u8(frame, &int_seid))
+		return false;
+
+	print_field("ACP SEID: %d", acp_seid >> 2);
+	print_field("INT SEID: %d", int_seid >> 2);
+
+	return decode_capabilities(avdtp_frame);
+
+reject:
+	if (!l2cap_frame_get_u8(frame, &service_cat))
+		return false;
+
+	print_field("Service Category: %s", servicecat2str(service_cat));
+
+	return avdtp_reject_common(avdtp_frame);
+
+response:
+	/* no extra parameters */
+	return true;
+}
+
 static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
 {
 	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
@@ -365,6 +401,9 @@ static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
 	case AVDTP_GET_CAPABILITIES:
 		ret = avdtp_get_capabilities(avdtp_frame);
 		break;
+	case AVDTP_SET_CONFIGURATION:
+		ret = avdtp_set_configuration(avdtp_frame);
+		break;
 	default:
 		packet_hexdump(frame->data, frame->size);
 		ret = true;
-- 
2.6.2


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

* [PATCH 06/22] monitor/avdtp: Decode AVDTP_GET_CONFIGURATION
  2015-11-14 13:44 [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Andrzej Kaczmarek
                   ` (4 preceding siblings ...)
  2015-11-14 13:44 ` [PATCH 05/22] monitor/avdtp: Decode AVDTP_SET_CONFIGURATION Andrzej Kaczmarek
@ 2015-11-14 13:44 ` Andrzej Kaczmarek
  2015-11-14 13:44 ` [PATCH 07/22] monitor/avdtp: Decode AVDTP_RECONFIGURE Andrzej Kaczmarek
                   ` (16 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Andrzej Kaczmarek @ 2015-11-14 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

---
 monitor/avdtp.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/monitor/avdtp.c b/monitor/avdtp.c
index f38d359..89c5eb7 100644
--- a/monitor/avdtp.c
+++ b/monitor/avdtp.c
@@ -341,6 +341,31 @@ response:
 	return true;
 }
 
+static bool avdtp_get_configuration(struct avdtp_frame *avdtp_frame)
+{
+	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
+	uint8_t seid;
+
+	if (avdtp_frame->hdr & 0x01)
+		goto reject;
+
+	if (avdtp_frame->hdr & 0x02)
+		goto response;
+
+	if (!l2cap_frame_get_u8(frame, &seid))
+		return false;
+
+	print_field("ACP SEID: %d", seid >> 2);
+
+	return decode_capabilities(avdtp_frame);
+
+reject:
+	return avdtp_reject_common(avdtp_frame);
+
+response:
+	return decode_capabilities(avdtp_frame);
+}
+
 static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
 {
 	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
@@ -404,6 +429,9 @@ static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
 	case AVDTP_SET_CONFIGURATION:
 		ret = avdtp_set_configuration(avdtp_frame);
 		break;
+	case AVDTP_GET_CONFIGURATION:
+		ret = avdtp_get_configuration(avdtp_frame);
+		break;
 	default:
 		packet_hexdump(frame->data, frame->size);
 		ret = true;
-- 
2.6.2


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

* [PATCH 07/22] monitor/avdtp: Decode AVDTP_RECONFIGURE
  2015-11-14 13:44 [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Andrzej Kaczmarek
                   ` (5 preceding siblings ...)
  2015-11-14 13:44 ` [PATCH 06/22] monitor/avdtp: Decode AVDTP_GET_CONFIGURATION Andrzej Kaczmarek
@ 2015-11-14 13:44 ` Andrzej Kaczmarek
  2015-11-14 13:44 ` [PATCH 08/22] monitor/avdtp: Decode AVDTP_OPEN Andrzej Kaczmarek
                   ` (15 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Andrzej Kaczmarek @ 2015-11-14 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

---
 monitor/avdtp.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/monitor/avdtp.c b/monitor/avdtp.c
index 89c5eb7..9c28c64 100644
--- a/monitor/avdtp.c
+++ b/monitor/avdtp.c
@@ -366,6 +366,38 @@ response:
 	return decode_capabilities(avdtp_frame);
 }
 
+static bool avdtp_reconfigure(struct avdtp_frame *avdtp_frame)
+{
+	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
+	uint8_t seid;
+	uint8_t service_cat;
+
+	if (avdtp_frame->hdr & 0x01)
+		goto reject;
+
+	if (avdtp_frame->hdr & 0x02)
+		goto response;
+
+	if (!l2cap_frame_get_u8(frame, &seid))
+		return false;
+
+	print_field("ACP SEID: %d", seid >> 2);
+
+	return decode_capabilities(avdtp_frame);
+
+reject:
+	if (!l2cap_frame_get_u8(frame, &service_cat))
+		return false;
+
+	print_field("Service Category: %s", servicecat2str(service_cat));
+
+	return avdtp_reject_common(avdtp_frame);
+
+response:
+	/* no extra parameters */
+	return true;
+}
+
 static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
 {
 	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
@@ -432,6 +464,9 @@ static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
 	case AVDTP_GET_CONFIGURATION:
 		ret = avdtp_get_configuration(avdtp_frame);
 		break;
+	case AVDTP_RECONFIGURE:
+		ret = avdtp_reconfigure(avdtp_frame);
+		break;
 	default:
 		packet_hexdump(frame->data, frame->size);
 		ret = true;
-- 
2.6.2


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

* [PATCH 08/22] monitor/avdtp: Decode AVDTP_OPEN
  2015-11-14 13:44 [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Andrzej Kaczmarek
                   ` (6 preceding siblings ...)
  2015-11-14 13:44 ` [PATCH 07/22] monitor/avdtp: Decode AVDTP_RECONFIGURE Andrzej Kaczmarek
@ 2015-11-14 13:44 ` Andrzej Kaczmarek
  2015-11-14 13:44 ` [PATCH 09/22] monitor/avdtp: Decode AVDTP_START Andrzej Kaczmarek
                   ` (14 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Andrzej Kaczmarek @ 2015-11-14 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

---
 monitor/avdtp.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/monitor/avdtp.c b/monitor/avdtp.c
index 9c28c64..f44da2a 100644
--- a/monitor/avdtp.c
+++ b/monitor/avdtp.c
@@ -398,6 +398,32 @@ response:
 	return true;
 }
 
+static bool avdtp_open(struct avdtp_frame *avdtp_frame)
+{
+	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
+	uint8_t seid;
+
+	if (avdtp_frame->hdr & 0x01)
+		goto reject;
+
+	if (avdtp_frame->hdr & 0x02)
+		goto response;
+
+	if (!l2cap_frame_get_u8(frame, &seid))
+		return false;
+
+	print_field("ACP SEID: %d", seid >> 2);
+
+	return true;
+
+reject:
+	return avdtp_reject_common(avdtp_frame);
+
+response:
+	/* no extra parameters */
+	return true;
+}
+
 static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
 {
 	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
@@ -467,6 +493,9 @@ static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
 	case AVDTP_RECONFIGURE:
 		ret = avdtp_reconfigure(avdtp_frame);
 		break;
+	case AVDTP_OPEN:
+		ret = avdtp_open(avdtp_frame);
+		break;
 	default:
 		packet_hexdump(frame->data, frame->size);
 		ret = true;
-- 
2.6.2


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

* [PATCH 09/22] monitor/avdtp: Decode AVDTP_START
  2015-11-14 13:44 [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Andrzej Kaczmarek
                   ` (7 preceding siblings ...)
  2015-11-14 13:44 ` [PATCH 08/22] monitor/avdtp: Decode AVDTP_OPEN Andrzej Kaczmarek
@ 2015-11-14 13:44 ` Andrzej Kaczmarek
  2015-11-14 13:44 ` [PATCH 10/22] monitor/avdtp: Decode AVDTP_CLOSE Andrzej Kaczmarek
                   ` (13 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Andrzej Kaczmarek @ 2015-11-14 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

---
 monitor/avdtp.c | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/monitor/avdtp.c b/monitor/avdtp.c
index f44da2a..8641f9a 100644
--- a/monitor/avdtp.c
+++ b/monitor/avdtp.c
@@ -424,6 +424,44 @@ response:
 	return true;
 }
 
+static bool avdtp_start(struct avdtp_frame *avdtp_frame)
+{
+	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
+	uint8_t seid;
+
+	if (avdtp_frame->hdr & 0x01)
+		goto reject;
+
+	if (avdtp_frame->hdr & 0x02)
+		goto response;
+
+	if (!l2cap_frame_get_u8(frame, &seid))
+		return false;
+
+	print_field("ACP SEID: %d", seid >> 2);
+
+	for (;;) {
+		if (!l2cap_frame_get_u8(frame, &seid))
+			break;
+
+		print_field("ACP SEID: %d", seid >> 2);
+	}
+
+	return true;
+
+reject:
+	if (!l2cap_frame_get_u8(frame, &seid))
+		return false;
+
+	print_field("ACP SEID: %d", seid >> 2);
+
+	return avdtp_reject_common(avdtp_frame);
+
+response:
+	/* no extra parameters */
+	return true;
+}
+
 static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
 {
 	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
@@ -496,6 +534,9 @@ static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
 	case AVDTP_OPEN:
 		ret = avdtp_open(avdtp_frame);
 		break;
+	case AVDTP_START:
+		ret = avdtp_start(avdtp_frame);
+		break;
 	default:
 		packet_hexdump(frame->data, frame->size);
 		ret = true;
-- 
2.6.2


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

* [PATCH 10/22] monitor/avdtp: Decode AVDTP_CLOSE
  2015-11-14 13:44 [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Andrzej Kaczmarek
                   ` (8 preceding siblings ...)
  2015-11-14 13:44 ` [PATCH 09/22] monitor/avdtp: Decode AVDTP_START Andrzej Kaczmarek
@ 2015-11-14 13:44 ` Andrzej Kaczmarek
  2015-11-14 13:44 ` [PATCH 11/22] monitor/avdtp: Decode AVDTP_SUSPEND Andrzej Kaczmarek
                   ` (12 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Andrzej Kaczmarek @ 2015-11-14 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

---
 monitor/avdtp.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/monitor/avdtp.c b/monitor/avdtp.c
index 8641f9a..e065d8b 100644
--- a/monitor/avdtp.c
+++ b/monitor/avdtp.c
@@ -462,6 +462,32 @@ response:
 	return true;
 }
 
+static bool avdtp_close(struct avdtp_frame *avdtp_frame)
+{
+	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
+	uint8_t seid;
+
+	if (avdtp_frame->hdr & 0x01)
+		goto reject;
+
+	if (avdtp_frame->hdr & 0x02)
+		goto response;
+
+	if (!l2cap_frame_get_u8(frame, &seid))
+		return false;
+
+	print_field("ACP SEID: %d", seid >> 2);
+
+	return true;
+
+reject:
+	return avdtp_reject_common(avdtp_frame);
+
+response:
+	/* no extra parameters */
+	return true;
+}
+
 static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
 {
 	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
@@ -537,6 +563,9 @@ static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
 	case AVDTP_START:
 		ret = avdtp_start(avdtp_frame);
 		break;
+	case AVDTP_CLOSE:
+		ret = avdtp_close(avdtp_frame);
+		break;
 	default:
 		packet_hexdump(frame->data, frame->size);
 		ret = true;
-- 
2.6.2


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

* [PATCH 11/22] monitor/avdtp: Decode AVDTP_SUSPEND
  2015-11-14 13:44 [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Andrzej Kaczmarek
                   ` (9 preceding siblings ...)
  2015-11-14 13:44 ` [PATCH 10/22] monitor/avdtp: Decode AVDTP_CLOSE Andrzej Kaczmarek
@ 2015-11-14 13:44 ` Andrzej Kaczmarek
  2015-11-14 13:44 ` [PATCH 12/22] monitor/avdtp: Decode AVDTP_ABORT Andrzej Kaczmarek
                   ` (11 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Andrzej Kaczmarek @ 2015-11-14 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

---
 monitor/avdtp.c | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/monitor/avdtp.c b/monitor/avdtp.c
index e065d8b..e48e507 100644
--- a/monitor/avdtp.c
+++ b/monitor/avdtp.c
@@ -488,6 +488,44 @@ response:
 	return true;
 }
 
+static bool avdtp_suspend(struct avdtp_frame *avdtp_frame)
+{
+	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
+	uint8_t seid;
+
+	if (avdtp_frame->hdr & 0x01)
+		goto reject;
+
+	if (avdtp_frame->hdr & 0x02)
+		goto response;
+
+	if (!l2cap_frame_get_u8(frame, &seid))
+		return false;
+
+	print_field("ACP SEID: %d", seid >> 2);
+
+	for (;;) {
+		if (!l2cap_frame_get_u8(frame, &seid))
+			break;
+
+		print_field("ACP SEID: %d", seid >> 2);
+	}
+
+	return true;
+
+reject:
+	if (!l2cap_frame_get_u8(frame, &seid))
+		return false;
+
+	print_field("ACP SEID: %d", seid >> 2);
+
+	return avdtp_reject_common(avdtp_frame);
+
+response:
+	/* no extra parameters */
+	return true;
+}
+
 static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
 {
 	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
@@ -566,6 +604,9 @@ static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
 	case AVDTP_CLOSE:
 		ret = avdtp_close(avdtp_frame);
 		break;
+	case AVDTP_SUSPEND:
+		ret = avdtp_suspend(avdtp_frame);
+		break;
 	default:
 		packet_hexdump(frame->data, frame->size);
 		ret = true;
-- 
2.6.2


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

* [PATCH 12/22] monitor/avdtp: Decode AVDTP_ABORT
  2015-11-14 13:44 [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Andrzej Kaczmarek
                   ` (10 preceding siblings ...)
  2015-11-14 13:44 ` [PATCH 11/22] monitor/avdtp: Decode AVDTP_SUSPEND Andrzej Kaczmarek
@ 2015-11-14 13:44 ` Andrzej Kaczmarek
  2015-11-14 13:44 ` [PATCH 13/22] monitor/avdtp: Decode AVDTP_SECURITY_CONTROL Andrzej Kaczmarek
                   ` (10 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Andrzej Kaczmarek @ 2015-11-14 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

---
 monitor/avdtp.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/monitor/avdtp.c b/monitor/avdtp.c
index e48e507..bd91265 100644
--- a/monitor/avdtp.c
+++ b/monitor/avdtp.c
@@ -526,6 +526,26 @@ response:
 	return true;
 }
 
+static bool avdtp_abort(struct avdtp_frame *avdtp_frame)
+{
+	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
+	uint8_t seid;
+
+	if (avdtp_frame->hdr & 0x02)
+		goto response;
+
+	if (!l2cap_frame_get_u8(frame, &seid))
+		return false;
+
+	print_field("ACP SEID: %d", seid >> 2);
+
+	return true;
+
+response:
+	/* no extra parameters */
+	return true;
+}
+
 static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
 {
 	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
@@ -607,6 +627,9 @@ static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
 	case AVDTP_SUSPEND:
 		ret = avdtp_suspend(avdtp_frame);
 		break;
+	case AVDTP_ABORT:
+		ret = avdtp_abort(avdtp_frame);
+		break;
 	default:
 		packet_hexdump(frame->data, frame->size);
 		ret = true;
-- 
2.6.2


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

* [PATCH 13/22] monitor/avdtp: Decode AVDTP_SECURITY_CONTROL
  2015-11-14 13:44 [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Andrzej Kaczmarek
                   ` (11 preceding siblings ...)
  2015-11-14 13:44 ` [PATCH 12/22] monitor/avdtp: Decode AVDTP_ABORT Andrzej Kaczmarek
@ 2015-11-14 13:44 ` Andrzej Kaczmarek
  2015-11-14 13:44 ` [PATCH 14/22] monitor/avdtp: Decode AVDTP_GET_ALL_CAPABILITIES Andrzej Kaczmarek
                   ` (9 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Andrzej Kaczmarek @ 2015-11-14 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

---
 monitor/avdtp.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/monitor/avdtp.c b/monitor/avdtp.c
index bd91265..ecd55de 100644
--- a/monitor/avdtp.c
+++ b/monitor/avdtp.c
@@ -546,6 +546,33 @@ response:
 	return true;
 }
 
+static bool avdtp_security_control(struct avdtp_frame *avdtp_frame)
+{
+	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
+	uint8_t seid;
+
+	if (avdtp_frame->hdr & 0x01)
+		goto reject;
+
+	if (avdtp_frame->hdr & 0x02)
+		goto response;
+
+	if (!l2cap_frame_get_u8(frame, &seid))
+		return false;
+
+	print_field("ACP SEID: %d", seid >> 2);
+
+	packet_hexdump(frame->data, frame->size);
+	return true;
+
+reject:
+	return avdtp_reject_common(avdtp_frame);
+
+response:
+	packet_hexdump(frame->data, frame->size);
+	return true;
+}
+
 static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
 {
 	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
@@ -630,6 +657,9 @@ static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
 	case AVDTP_ABORT:
 		ret = avdtp_abort(avdtp_frame);
 		break;
+	case AVDTP_SECURITY_CONTROL:
+		ret = avdtp_security_control(avdtp_frame);
+		break;
 	default:
 		packet_hexdump(frame->data, frame->size);
 		ret = true;
-- 
2.6.2


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

* [PATCH 14/22] monitor/avdtp: Decode AVDTP_GET_ALL_CAPABILITIES
  2015-11-14 13:44 [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Andrzej Kaczmarek
                   ` (12 preceding siblings ...)
  2015-11-14 13:44 ` [PATCH 13/22] monitor/avdtp: Decode AVDTP_SECURITY_CONTROL Andrzej Kaczmarek
@ 2015-11-14 13:44 ` Andrzej Kaczmarek
  2015-11-14 13:44 ` [PATCH 15/22] monitor/avdtp: Decode AVDTP_DELAYREPORT Andrzej Kaczmarek
                   ` (8 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Andrzej Kaczmarek @ 2015-11-14 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

---
 monitor/avdtp.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/monitor/avdtp.c b/monitor/avdtp.c
index ecd55de..a44fd1a 100644
--- a/monitor/avdtp.c
+++ b/monitor/avdtp.c
@@ -631,6 +631,7 @@ static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
 		ret = avdtp_discover(avdtp_frame);
 		break;
 	case AVDTP_GET_CAPABILITIES:
+	case AVDTP_GET_ALL_CAPABILITIES:
 		ret = avdtp_get_capabilities(avdtp_frame);
 		break;
 	case AVDTP_SET_CONFIGURATION:
-- 
2.6.2


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

* [PATCH 15/22] monitor/avdtp: Decode AVDTP_DELAYREPORT
  2015-11-14 13:44 [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Andrzej Kaczmarek
                   ` (13 preceding siblings ...)
  2015-11-14 13:44 ` [PATCH 14/22] monitor/avdtp: Decode AVDTP_GET_ALL_CAPABILITIES Andrzej Kaczmarek
@ 2015-11-14 13:44 ` Andrzej Kaczmarek
  2015-11-14 13:44 ` [PATCH 16/22] monitor/avdtp: Decode basic Media Codec capabilities Andrzej Kaczmarek
                   ` (7 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Andrzej Kaczmarek @ 2015-11-14 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

---
 monitor/avdtp.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/monitor/avdtp.c b/monitor/avdtp.c
index a44fd1a..e5bc13e 100644
--- a/monitor/avdtp.c
+++ b/monitor/avdtp.c
@@ -573,6 +573,37 @@ response:
 	return true;
 }
 
+static bool avdtp_delayreport(struct avdtp_frame *avdtp_frame)
+{
+	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
+	uint8_t seid;
+	uint16_t delay;
+
+	if (avdtp_frame->hdr & 0x01)
+		goto reject;
+
+	if (avdtp_frame->hdr & 0x02)
+		goto response;
+
+	if (!l2cap_frame_get_u8(frame, &seid))
+		return false;
+
+	if (!l2cap_frame_get_be16(frame, &delay))
+		return false;
+
+	print_field("ACP SEID: %d", seid >> 2);
+	print_field("Delay: %d.%dms", delay / 10, delay % 10);
+
+	return true;
+
+reject:
+	return avdtp_reject_common(avdtp_frame);
+
+response:
+	/* no extra parameters */
+	return true;
+}
+
 static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
 {
 	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
@@ -661,6 +692,9 @@ static bool avdtp_signalling_packet(struct avdtp_frame *avdtp_frame)
 	case AVDTP_SECURITY_CONTROL:
 		ret = avdtp_security_control(avdtp_frame);
 		break;
+	case AVDTP_DELAYREPORT:
+		ret = avdtp_delayreport(avdtp_frame);
+		break;
 	default:
 		packet_hexdump(frame->data, frame->size);
 		ret = true;
-- 
2.6.2


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

* [PATCH 16/22] monitor/avdtp: Decode basic Media Codec capabilities
  2015-11-14 13:44 [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Andrzej Kaczmarek
                   ` (14 preceding siblings ...)
  2015-11-14 13:44 ` [PATCH 15/22] monitor/avdtp: Decode AVDTP_DELAYREPORT Andrzej Kaczmarek
@ 2015-11-14 13:44 ` Andrzej Kaczmarek
  2015-11-14 13:44 ` [PATCH 17/22] monitor/avdtp: Decode basic Content Protection capabilities Andrzej Kaczmarek
                   ` (6 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Andrzej Kaczmarek @ 2015-11-14 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

---
 monitor/avdtp.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 62 insertions(+), 4 deletions(-)

diff --git a/monitor/avdtp.c b/monitor/avdtp.c
index e5bc13e..003134f 100644
--- a/monitor/avdtp.c
+++ b/monitor/avdtp.c
@@ -174,6 +174,24 @@ static const char *mediatype2str(uint8_t media_type)
 	}
 }
 
+static const char *mediacodec2str(uint8_t codec)
+{
+	switch (codec) {
+	case 0x00:
+		return "SBC";
+	case 0x01:
+		return "MPEG-1,2 Audio";
+	case 0x02:
+		return "MPEG-2,4 AAC";
+	case 0x04:
+		return "ATRAC Family";
+	case 0xff:
+		return "Non-A2DP";
+	default:
+		return "Reserved";
+	}
+}
+
 static const char *servicecat2str(uint8_t service_cat)
 {
 	switch (service_cat) {
@@ -211,6 +229,34 @@ static bool avdtp_reject_common(struct avdtp_frame *avdtp_frame)
 	return true;
 }
 
+static bool service_media_codec(struct avdtp_frame *avdtp_frame, uint8_t losc)
+{
+	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
+	uint8_t type = 0;
+	uint8_t codec = 0;
+
+	if (losc < 2)
+		return false;
+
+	l2cap_frame_get_u8(frame, &type);
+	l2cap_frame_get_u8(frame, &codec);
+
+	losc -= 2;
+
+	print_field("%*cMedia Type: %s", 2, ' ',
+					mediatype2str(type >> 4));
+
+	print_field("%*cMedia Codec: %s", 2, ' ',
+					mediacodec2str(codec));
+
+	/* TODO: decode codec specific information */
+
+	packet_hexdump(frame->data, losc);
+	l2cap_frame_pull(frame, frame, losc);
+
+	return true;
+}
+
 static bool decode_capabilities(struct avdtp_frame *avdtp_frame)
 {
 	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
@@ -231,11 +277,23 @@ static bool decode_capabilities(struct avdtp_frame *avdtp_frame)
 		if (frame->size < losc)
 			return false;
 
-		/* TODO: decode service capabilities */
-
-		packet_hexdump(frame->data, losc);
+		switch (service_cat) {
+		case AVDTP_MEDIA_CODEC:
+			if (!service_media_codec(avdtp_frame, losc))
+				return false;
+			break;
+		case AVDTP_MEDIA_TRANSPORT:
+		case AVDTP_REPORTING:
+		case AVDTP_RECOVERY:
+		case AVDTP_CONTENT_PROTECTION:
+		case AVDTP_HEADER_COMPRESSION:
+		case AVDTP_MULTIPLEXING:
+		case AVDTP_DELAY_REPORTING:
+		default:
+			packet_hexdump(frame->data, losc);
+			l2cap_frame_pull(frame, frame, losc);
+		}
 
-		l2cap_frame_pull(frame, frame, losc);
 	}
 
 	return true;
-- 
2.6.2


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

* [PATCH 17/22] monitor/avdtp: Decode basic Content Protection capabilities
  2015-11-14 13:44 [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Andrzej Kaczmarek
                   ` (15 preceding siblings ...)
  2015-11-14 13:44 ` [PATCH 16/22] monitor/avdtp: Decode basic Media Codec capabilities Andrzej Kaczmarek
@ 2015-11-14 13:44 ` Andrzej Kaczmarek
  2015-11-14 13:44 ` [PATCH 18/22] monitor/a2dp: Decode SBC capabilities Andrzej Kaczmarek
                   ` (5 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Andrzej Kaczmarek @ 2015-11-14 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

---
 monitor/avdtp.c | 40 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 39 insertions(+), 1 deletion(-)

diff --git a/monitor/avdtp.c b/monitor/avdtp.c
index 003134f..e216a1b 100644
--- a/monitor/avdtp.c
+++ b/monitor/avdtp.c
@@ -192,6 +192,18 @@ static const char *mediacodec2str(uint8_t codec)
 	}
 }
 
+static const char *cptype2str(uint8_t cp)
+{
+	switch (cp) {
+	case 0x0001:
+		return "DTCP";
+	case 0x0002:
+		return "SCMS-T";
+	default:
+		return "Reserved";
+	}
+}
+
 static const char *servicecat2str(uint8_t service_cat)
 {
 	switch (service_cat) {
@@ -229,6 +241,29 @@ static bool avdtp_reject_common(struct avdtp_frame *avdtp_frame)
 	return true;
 }
 
+static bool service_content_protection(struct avdtp_frame *avdtp_frame,
+								uint8_t losc)
+{
+	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
+	uint16_t type = 0;
+
+	if (losc < 2)
+		return false;
+
+	if (!l2cap_frame_get_le16(frame, &type))
+		return false;
+
+	losc -= 2;
+
+	print_field("%*cContent Protection Type: %s", 2, ' ', cptype2str(type));
+
+	/* TODO: decode protection specific information */
+
+	l2cap_frame_pull(frame, frame, losc);
+
+	return true;
+}
+
 static bool service_media_codec(struct avdtp_frame *avdtp_frame, uint8_t losc)
 {
 	struct l2cap_frame *frame = &avdtp_frame->l2cap_frame;
@@ -278,6 +313,10 @@ static bool decode_capabilities(struct avdtp_frame *avdtp_frame)
 			return false;
 
 		switch (service_cat) {
+		case AVDTP_CONTENT_PROTECTION:
+			if (!service_content_protection(avdtp_frame, losc))
+				return false;
+			break;
 		case AVDTP_MEDIA_CODEC:
 			if (!service_media_codec(avdtp_frame, losc))
 				return false;
@@ -285,7 +324,6 @@ static bool decode_capabilities(struct avdtp_frame *avdtp_frame)
 		case AVDTP_MEDIA_TRANSPORT:
 		case AVDTP_REPORTING:
 		case AVDTP_RECOVERY:
-		case AVDTP_CONTENT_PROTECTION:
 		case AVDTP_HEADER_COMPRESSION:
 		case AVDTP_MULTIPLEXING:
 		case AVDTP_DELAY_REPORTING:
-- 
2.6.2


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

* [PATCH 18/22] monitor/a2dp: Decode SBC capabilities
  2015-11-14 13:44 [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Andrzej Kaczmarek
                   ` (16 preceding siblings ...)
  2015-11-14 13:44 ` [PATCH 17/22] monitor/avdtp: Decode basic Content Protection capabilities Andrzej Kaczmarek
@ 2015-11-14 13:44 ` Andrzej Kaczmarek
  2015-11-14 13:44 ` [PATCH 19/22] monitor/a2dp: Decode MPEG-1,2 capabilities Andrzej Kaczmarek
                   ` (4 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Andrzej Kaczmarek @ 2015-11-14 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

---
 Makefile.tools     |   1 +
 android/Android.mk |   1 +
 monitor/a2dp.c     | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 monitor/a2dp.h     |  24 +++++++++
 monitor/avdtp.c    |   8 +--
 5 files changed, 178 insertions(+), 6 deletions(-)
 create mode 100644 monitor/a2dp.c
 create mode 100644 monitor/a2dp.h

diff --git a/Makefile.tools b/Makefile.tools
index 387917e..46cdb53 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -28,6 +28,7 @@ monitor_btmon_SOURCES = monitor/main.c monitor/bt.h \
 				monitor/sdp.h monitor/sdp.c \
 				monitor/avctp.h monitor/avctp.c \
 				monitor/avdtp.h monitor/avdtp.c \
+				monitor/a2dp.h monitor/a2dp.c \
 				monitor/rfcomm.h monitor/rfcomm.c \
 				monitor/bnep.h monitor/bnep.c \
 				monitor/uuid.h monitor/uuid.c \
diff --git a/android/Android.mk b/android/Android.mk
index fa1188b..38ef4aa 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -340,6 +340,7 @@ LOCAL_SRC_FILES := \
 	bluez/monitor/l2cap.c \
 	bluez/monitor/avctp.c \
 	bluez/monitor/avdtp.c \
+	bluez/monitor/a2dp.c \
 	bluez/monitor/rfcomm.c \
 	bluez/monitor/bnep.c \
 	bluez/monitor/uuid.c \
diff --git a/monitor/a2dp.c b/monitor/a2dp.c
new file mode 100644
index 0000000..60ebe94
--- /dev/null
+++ b/monitor/a2dp.c
@@ -0,0 +1,150 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2015  Andrzej Kaczmarek <andrzej.kaczmarek@codecoup.pl>
+ *
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "lib/bluetooth.h"
+
+#include "src/shared/util.h"
+#include "bt.h"
+#include "packet.h"
+#include "display.h"
+#include "l2cap.h"
+#include "a2dp.h"
+
+#define BASE_INDENT	4
+
+/* Codec Types */
+#define A2DP_CODEC_SBC		0x00
+#define A2DP_CODEC_MPEG12	0x01
+#define A2DP_CODEC_MPEG24	0x02
+#define A2DP_CODEC_ATRAC	0x04
+#define A2DP_CODEC_VENDOR	0xff
+
+struct bit_desc {
+	uint8_t bit;
+	const char *str;
+};
+
+static const struct bit_desc sbc_frequency_table[] = {
+	{  7, "16000" },
+	{  6, "32000" },
+	{  5, "44100" },
+	{  4, "48000" },
+	{ }
+};
+
+static const struct bit_desc sbc_channel_mode_table[] = {
+	{  3, "Mono" },
+	{  2, "Dual Channel" },
+	{  1, "Stereo" },
+	{  0, "Joint Channel" },
+	{ }
+};
+
+static const struct bit_desc sbc_blocklen_table[] = {
+	{  7, "4" },
+	{  6, "8" },
+	{  5, "12" },
+	{  4, "16" },
+	{ }
+};
+
+static const struct bit_desc sbc_subbands_table[] = {
+	{  3, "4" },
+	{  2, "8" },
+	{ }
+};
+
+static const struct bit_desc sbc_allocation_table[] = {
+	{  1, "SNR" },
+	{  0, "Loudness" },
+	{ }
+};
+
+static void print_bit_table(uint8_t indent, uint32_t value,
+						const struct bit_desc *table)
+{
+	int i;
+
+	for (i = 0; table[i].str; i++) {
+		if (value & (1 << table[i].bit))
+			print_field("%*c%s", indent + 2, ' ', table[i].str);
+	}
+}
+
+static bool codec_sbc(uint8_t losc, struct l2cap_frame *frame)
+{
+	uint8_t cap = 0;
+
+	if (losc != 4)
+		return false;
+
+	l2cap_frame_get_u8(frame, &cap);
+
+	print_field("%*cFrequency: 0x%02x", BASE_INDENT, ' ', cap & 0xf0);
+	print_bit_table(BASE_INDENT, cap & 0xf0, sbc_frequency_table);
+
+	print_field("%*cChannel Mode: 0x%02x", BASE_INDENT, ' ', cap & 0x0f);
+	print_bit_table(BASE_INDENT, cap & 0x0f, sbc_channel_mode_table);
+
+	l2cap_frame_get_u8(frame, &cap);
+
+	print_field("%*cBlock Length: 0x%02x", BASE_INDENT, ' ', cap & 0xf0);
+	print_bit_table(BASE_INDENT, cap & 0xf0, sbc_blocklen_table);
+
+	print_field("%*cSubbands: 0x%02x", BASE_INDENT, ' ', cap & 0x0c);
+	print_bit_table(BASE_INDENT, cap & 0x0c, sbc_subbands_table);
+
+	print_field("%*cAllocation Method: 0x%02x", BASE_INDENT, ' ',
+								cap & 0x03);
+	print_bit_table(BASE_INDENT, cap & 0x03, sbc_allocation_table);
+
+	l2cap_frame_get_u8(frame, &cap);
+
+	print_field("%*cMinimum Bitpool: %d", BASE_INDENT, ' ', cap);
+
+	l2cap_frame_get_u8(frame, &cap);
+
+	print_field("%*cMaximum Bitpool: %d", BASE_INDENT, ' ', cap);
+
+	return true;
+}
+
+bool a2dp_codec_caps(uint8_t codec, uint8_t losc, struct l2cap_frame *frame)
+{
+	switch (codec) {
+	case A2DP_CODEC_SBC:
+		return codec_sbc(losc, frame);
+	default:
+		packet_hexdump(frame->data, losc);
+		l2cap_frame_pull(frame, frame, losc);
+		return true;
+	}
+}
diff --git a/monitor/a2dp.h b/monitor/a2dp.h
new file mode 100644
index 0000000..4376ab2
--- /dev/null
+++ b/monitor/a2dp.h
@@ -0,0 +1,24 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2015  Andrzej Kaczmarek <andrzej.kaczmarek@codecoup.pl>
+ *
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+bool a2dp_codec_caps(uint8_t codec, uint8_t losc, struct l2cap_frame *frame);
diff --git a/monitor/avdtp.c b/monitor/avdtp.c
index e216a1b..061b3f6 100644
--- a/monitor/avdtp.c
+++ b/monitor/avdtp.c
@@ -37,6 +37,7 @@
 #include "display.h"
 #include "l2cap.h"
 #include "avdtp.h"
+#include "a2dp.h"
 
 /* Signal Identifiers */
 #define AVDTP_DISCOVER			0x01
@@ -284,12 +285,7 @@ static bool service_media_codec(struct avdtp_frame *avdtp_frame, uint8_t losc)
 	print_field("%*cMedia Codec: %s", 2, ' ',
 					mediacodec2str(codec));
 
-	/* TODO: decode codec specific information */
-
-	packet_hexdump(frame->data, losc);
-	l2cap_frame_pull(frame, frame, losc);
-
-	return true;
+	return a2dp_codec_caps(codec, losc, frame);
 }
 
 static bool decode_capabilities(struct avdtp_frame *avdtp_frame)
-- 
2.6.2


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

* [PATCH 19/22] monitor/a2dp: Decode MPEG-1,2 capabilities
  2015-11-14 13:44 [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Andrzej Kaczmarek
                   ` (17 preceding siblings ...)
  2015-11-14 13:44 ` [PATCH 18/22] monitor/a2dp: Decode SBC capabilities Andrzej Kaczmarek
@ 2015-11-14 13:44 ` Andrzej Kaczmarek
  2015-11-14 13:44 ` [PATCH 20/22] monitor/a2dp: Decode AAC capabilities Andrzej Kaczmarek
                   ` (3 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Andrzej Kaczmarek @ 2015-11-14 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

---
 monitor/a2dp.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 94 insertions(+)

diff --git a/monitor/a2dp.c b/monitor/a2dp.c
index 60ebe94..10eca42 100644
--- a/monitor/a2dp.c
+++ b/monitor/a2dp.c
@@ -88,6 +88,50 @@ static const struct bit_desc sbc_allocation_table[] = {
 	{ }
 };
 
+static const struct bit_desc mpeg12_layer_table[] = {
+	{  7, "Layer I (mp1)" },
+	{  6, "Layer II (mp2)" },
+	{  5, "Layer III (mp3)" },
+	{ }
+};
+
+static const struct bit_desc mpeg12_channel_mode_table[] = {
+	{  3, "Mono" },
+	{  2, "Dual Channel" },
+	{  1, "Stereo" },
+	{  0, "Joint Channel" },
+	{ }
+};
+
+static const struct bit_desc mpeg12_frequency_table[] = {
+	{  5, "16000" },
+	{  4, "22050" },
+	{  3, "24000" },
+	{  2, "32000" },
+	{  1, "44100" },
+	{  0, "48000" },
+	{ }
+};
+
+static const struct bit_desc mpeg12_bitrate_table[] = {
+	{ 14, "1110" },
+	{ 13, "1101" },
+	{ 12, "1100" },
+	{ 11, "1011" },
+	{ 10, "1010" },
+	{  9, "1001" },
+	{  8, "1000" },
+	{  7, "0111" },
+	{  6, "0110" },
+	{  5, "0101" },
+	{  4, "0100" },
+	{  3, "0011" },
+	{  2, "0010" },
+	{  1, "0001" },
+	{  0, "0000" },
+	{ }
+};
+
 static void print_bit_table(uint8_t indent, uint32_t value,
 						const struct bit_desc *table)
 {
@@ -137,11 +181,61 @@ static bool codec_sbc(uint8_t losc, struct l2cap_frame *frame)
 	return true;
 }
 
+static bool codec_mpeg12(uint8_t losc, struct l2cap_frame *frame)
+{
+	uint16_t cap = 0;
+	uint8_t layer;
+	uint8_t chan;
+	uint8_t freq;
+	uint16_t bitrate;
+	bool crc, mpf, vbr;
+
+	if (losc != 4)
+		return false;
+
+	l2cap_frame_get_be16(frame, &cap);
+
+	layer = (cap >> 8) & 0xe0;
+	crc = cap & 0x1000;
+	chan = (cap >> 8) & 0x0f;
+	mpf = cap & 0x0040;
+	freq = cap & 0x003f;
+
+	l2cap_frame_get_be16(frame, &cap);
+
+	vbr = cap & 0x8000;
+	bitrate = cap & 0x7fff;
+
+	print_field("%*cLayer: 0x%02x", BASE_INDENT, ' ', layer);
+	print_bit_table(BASE_INDENT, layer, mpeg12_layer_table);
+
+	print_field("%*cCRC: %s", BASE_INDENT, ' ', crc ? "Yes" : "No");
+
+	print_field("%*cChannel Mode: 0x%02x", BASE_INDENT, ' ', chan);
+	print_bit_table(BASE_INDENT, chan, mpeg12_channel_mode_table);
+
+	print_field("%*cMedia Payload Format: %s", BASE_INDENT, ' ',
+					mpf ? "RFC-2250 RFC-3119" : "RFC-2250");
+
+	print_field("%*cFrequency: 0x%02x", BASE_INDENT, ' ', freq);
+	print_bit_table(BASE_INDENT, freq, mpeg12_frequency_table);
+
+	print_field("%*cBitrate: 0x%04x", BASE_INDENT, ' ', bitrate);
+	if (!vbr)
+		print_bit_table(BASE_INDENT, freq, mpeg12_bitrate_table);
+
+	print_field("%*cVBR: %s", BASE_INDENT, ' ', vbr ? "Yes" : "No");
+
+	return true;
+}
+
 bool a2dp_codec_caps(uint8_t codec, uint8_t losc, struct l2cap_frame *frame)
 {
 	switch (codec) {
 	case A2DP_CODEC_SBC:
 		return codec_sbc(losc, frame);
+	case A2DP_CODEC_MPEG12:
+		return codec_mpeg12(losc, frame);
 	default:
 		packet_hexdump(frame->data, losc);
 		l2cap_frame_pull(frame, frame, losc);
-- 
2.6.2


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

* [PATCH 20/22] monitor/a2dp: Decode AAC capabilities
  2015-11-14 13:44 [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Andrzej Kaczmarek
                   ` (18 preceding siblings ...)
  2015-11-14 13:44 ` [PATCH 19/22] monitor/a2dp: Decode MPEG-1,2 capabilities Andrzej Kaczmarek
@ 2015-11-14 13:44 ` Andrzej Kaczmarek
  2015-11-14 13:44 ` [PATCH 21/22] monitor/a2dp: Decode aptX capabilities Andrzej Kaczmarek
                   ` (2 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Andrzej Kaczmarek @ 2015-11-14 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

---
 monitor/a2dp.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/monitor/a2dp.c b/monitor/a2dp.c
index 10eca42..b6b01ee 100644
--- a/monitor/a2dp.c
+++ b/monitor/a2dp.c
@@ -132,6 +132,40 @@ static const struct bit_desc mpeg12_bitrate_table[] = {
 	{ }
 };
 
+static const struct bit_desc aac_object_type_table[] = {
+	{  7, "MPEG-2 AAC LC" },
+	{  6, "MPEG-4 AAC LC" },
+	{  5, "MPEG-4 AAC LTP" },
+	{  4, "MPEG-4 AAC scalable" },
+	{  3, "RFA (b3)" },
+	{  2, "RFA (b2)" },
+	{  1, "RFA (b1)" },
+	{  0, "RFA (b0)" },
+	{ }
+};
+
+static const struct bit_desc aac_frequency_table[] = {
+	{ 15, "8000" },
+	{ 14, "11025" },
+	{ 13, "12000" },
+	{ 12, "16000" },
+	{ 11, "22050" },
+	{ 10, "24000" },
+	{  9, "32000" },
+	{  8, "44100" },
+	{  7, "48000" },
+	{  6, "64000" },
+	{  5, "88200" },
+	{  4, "96000" },
+	{ }
+};
+
+static const struct bit_desc aac_channels_table[] = {
+	{  3, "1" },
+	{  2, "2" },
+	{ }
+};
+
 static void print_bit_table(uint8_t indent, uint32_t value,
 						const struct bit_desc *table)
 {
@@ -229,6 +263,49 @@ static bool codec_mpeg12(uint8_t losc, struct l2cap_frame *frame)
 	return true;
 }
 
+static bool codec_aac(uint8_t losc, struct l2cap_frame *frame)
+{
+	uint16_t cap = 0;
+	uint8_t type;
+	uint16_t freq;
+	uint8_t chan;
+	uint32_t bitrate;
+	bool vbr;
+
+	if (losc != 6)
+		return false;
+
+	l2cap_frame_get_be16(frame, &cap);
+
+	type = cap >> 8;
+	freq = cap << 8;
+
+	l2cap_frame_get_be16(frame, &cap);
+
+	freq |= (cap >> 8) & 0xf0;
+	chan = (cap >> 8) & 0x0c;
+	bitrate = (cap << 16) & 0x7f0000;
+	vbr = cap & 0x0080;
+
+	l2cap_frame_get_be16(frame, &cap);
+
+	bitrate |= cap;
+
+	print_field("%*cObject Type: 0x%02x", BASE_INDENT, ' ', type);
+	print_bit_table(BASE_INDENT, type, aac_object_type_table);
+
+	print_field("%*cFrequency: 0x%02x", BASE_INDENT, ' ', freq);
+	print_bit_table(BASE_INDENT, freq, aac_frequency_table);
+
+	print_field("%*cChannels: 0x%02x", BASE_INDENT, ' ', chan);
+	print_bit_table(BASE_INDENT, chan, aac_channels_table);
+
+	print_field("%*cBitrate: %ubps", BASE_INDENT, ' ', bitrate);
+	print_field("%*cVBR: %s", BASE_INDENT, ' ', vbr ? "Yes" : "No");
+
+	return true;
+}
+
 bool a2dp_codec_caps(uint8_t codec, uint8_t losc, struct l2cap_frame *frame)
 {
 	switch (codec) {
@@ -236,6 +313,8 @@ bool a2dp_codec_caps(uint8_t codec, uint8_t losc, struct l2cap_frame *frame)
 		return codec_sbc(losc, frame);
 	case A2DP_CODEC_MPEG12:
 		return codec_mpeg12(losc, frame);
+	case A2DP_CODEC_MPEG24:
+		return codec_aac(losc, frame);
 	default:
 		packet_hexdump(frame->data, losc);
 		l2cap_frame_pull(frame, frame, losc);
-- 
2.6.2


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

* [PATCH 21/22] monitor/a2dp: Decode aptX capabilities
  2015-11-14 13:44 [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Andrzej Kaczmarek
                   ` (19 preceding siblings ...)
  2015-11-14 13:44 ` [PATCH 20/22] monitor/a2dp: Decode AAC capabilities Andrzej Kaczmarek
@ 2015-11-14 13:44 ` Andrzej Kaczmarek
  2015-11-14 13:44 ` [PATCH 22/22] monitor/a2dp: Decode LDAC capabilities Andrzej Kaczmarek
  2015-11-17  8:33 ` [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Luiz Augusto von Dentz
  22 siblings, 0 replies; 29+ messages in thread
From: Andrzej Kaczmarek @ 2015-11-14 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

---
 monitor/a2dp.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 77 insertions(+)

diff --git a/monitor/a2dp.c b/monitor/a2dp.c
index b6b01ee..ab93097 100644
--- a/monitor/a2dp.c
+++ b/monitor/a2dp.c
@@ -47,6 +47,10 @@
 #define A2DP_CODEC_ATRAC	0x04
 #define A2DP_CODEC_VENDOR	0xff
 
+/* Vendor Specific A2DP Codecs */
+#define APTX_VENDOR_ID		0x0000004f
+#define APTX_CODEC_ID		0x0001
+
 struct bit_desc {
 	uint8_t bit;
 	const char *str;
@@ -166,6 +170,20 @@ static const struct bit_desc aac_channels_table[] = {
 	{ }
 };
 
+static const struct bit_desc aptx_frequency_table[] = {
+	{  7, "16000" },
+	{  6, "32000" },
+	{  5, "44100" },
+	{  4, "48000" },
+	{ }
+};
+
+static const struct bit_desc aptx_channel_mode_table[] = {
+	{  0, "Mono" },
+	{  1, "Stereo" },
+	{ }
+};
+
 static void print_bit_table(uint8_t indent, uint32_t value,
 						const struct bit_desc *table)
 {
@@ -177,6 +195,14 @@ static void print_bit_table(uint8_t indent, uint32_t value,
 	}
 }
 
+static const char *vndcodec2str(uint32_t vendor_id, uint16_t codec_id)
+{
+	if (vendor_id == APTX_VENDOR_ID && codec_id == APTX_CODEC_ID)
+		return "aptX";
+
+	return "Unknown";
+}
+
 static bool codec_sbc(uint8_t losc, struct l2cap_frame *frame)
 {
 	uint8_t cap = 0;
@@ -306,6 +332,55 @@ static bool codec_aac(uint8_t losc, struct l2cap_frame *frame)
 	return true;
 }
 
+static bool codec_vendor_aptx(uint8_t losc, struct l2cap_frame *frame)
+{
+	uint8_t cap = 0;
+
+	if (losc != 1)
+		return false;
+
+	l2cap_frame_get_u8(frame, &cap);
+
+	print_field("%*cFrequency: 0x%02x", BASE_INDENT + 2, ' ', cap & 0xf0);
+	print_bit_table(BASE_INDENT + 2, cap & 0xf0, aptx_frequency_table);
+
+	print_field("%*cChannel Mode: 0x%02x", BASE_INDENT + 2, ' ',
+								cap & 0x0f);
+	print_bit_table(BASE_INDENT + 2, cap & 0x0f, aptx_channel_mode_table);
+
+	return true;
+}
+
+static bool codec_vendor(uint8_t losc, struct l2cap_frame *frame)
+{
+	uint32_t vendor_id = 0;
+	uint16_t codec_id = 0;
+
+	if (losc < 6)
+		return false;
+
+	l2cap_frame_get_le32(frame, &vendor_id);
+	l2cap_frame_get_le16(frame, &codec_id);
+
+	losc -= 6;
+
+	print_field("%*cVendor ID: 0x%08x (%s)", BASE_INDENT, ' ', vendor_id,
+						bt_compidtostr(vendor_id));
+
+	print_field("%*cVendor Specific Codec ID: 0x%04x (%s)",
+					BASE_INDENT, ' ', codec_id,
+					vndcodec2str(vendor_id, codec_id));
+
+	if (vendor_id == APTX_VENDOR_ID && codec_id == APTX_CODEC_ID) {
+		codec_vendor_aptx(losc, frame);
+	} else {
+		packet_hexdump(frame->data, losc);
+		l2cap_frame_pull(frame, frame, losc);
+	}
+
+	return true;
+}
+
 bool a2dp_codec_caps(uint8_t codec, uint8_t losc, struct l2cap_frame *frame)
 {
 	switch (codec) {
@@ -315,6 +390,8 @@ bool a2dp_codec_caps(uint8_t codec, uint8_t losc, struct l2cap_frame *frame)
 		return codec_mpeg12(losc, frame);
 	case A2DP_CODEC_MPEG24:
 		return codec_aac(losc, frame);
+	case A2DP_CODEC_VENDOR:
+		return codec_vendor(losc, frame);
 	default:
 		packet_hexdump(frame->data, losc);
 		l2cap_frame_pull(frame, frame, losc);
-- 
2.6.2


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

* [PATCH 22/22] monitor/a2dp: Decode LDAC capabilities
  2015-11-14 13:44 [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Andrzej Kaczmarek
                   ` (20 preceding siblings ...)
  2015-11-14 13:44 ` [PATCH 21/22] monitor/a2dp: Decode aptX capabilities Andrzej Kaczmarek
@ 2015-11-14 13:44 ` Andrzej Kaczmarek
  2015-11-17  8:33 ` [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Luiz Augusto von Dentz
  22 siblings, 0 replies; 29+ messages in thread
From: Andrzej Kaczmarek @ 2015-11-14 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

---
 monitor/a2dp.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/monitor/a2dp.c b/monitor/a2dp.c
index ab93097..86ae39d 100644
--- a/monitor/a2dp.c
+++ b/monitor/a2dp.c
@@ -50,6 +50,8 @@
 /* Vendor Specific A2DP Codecs */
 #define APTX_VENDOR_ID		0x0000004f
 #define APTX_CODEC_ID		0x0001
+#define LDAC_VENDOR_ID		0x0000012d
+#define LDAC_CODEC_ID		0x00aa
 
 struct bit_desc {
 	uint8_t bit;
@@ -199,6 +201,8 @@ static const char *vndcodec2str(uint32_t vendor_id, uint16_t codec_id)
 {
 	if (vendor_id == APTX_VENDOR_ID && codec_id == APTX_CODEC_ID)
 		return "aptX";
+	else if (vendor_id == LDAC_VENDOR_ID && codec_id == LDAC_CODEC_ID)
+		return "LDAC";
 
 	return "Unknown";
 }
@@ -351,6 +355,20 @@ static bool codec_vendor_aptx(uint8_t losc, struct l2cap_frame *frame)
 	return true;
 }
 
+static bool codec_vendor_ldac(uint8_t losc, struct l2cap_frame *frame)
+{
+	uint16_t cap = 0;
+
+	if (losc != 2)
+		return false;
+
+	l2cap_frame_get_le16(frame, &cap);
+
+	print_field("%*cUnknown: 0x%04x", BASE_INDENT + 2, ' ', cap);
+
+	return true;
+}
+
 static bool codec_vendor(uint8_t losc, struct l2cap_frame *frame)
 {
 	uint32_t vendor_id = 0;
@@ -373,6 +391,8 @@ static bool codec_vendor(uint8_t losc, struct l2cap_frame *frame)
 
 	if (vendor_id == APTX_VENDOR_ID && codec_id == APTX_CODEC_ID) {
 		codec_vendor_aptx(losc, frame);
+	} else if (vendor_id == LDAC_VENDOR_ID && codec_id == LDAC_CODEC_ID) {
+		codec_vendor_ldac(losc, frame);
 	} else {
 		packet_hexdump(frame->data, losc);
 		l2cap_frame_pull(frame, frame, losc);
-- 
2.6.2


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

* Re: [PATCH 00/22] Add AVDTP/A2DP decoding to btmon
  2015-11-14 13:44 [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Andrzej Kaczmarek
                   ` (21 preceding siblings ...)
  2015-11-14 13:44 ` [PATCH 22/22] monitor/a2dp: Decode LDAC capabilities Andrzej Kaczmarek
@ 2015-11-17  8:33 ` Luiz Augusto von Dentz
  2015-11-17  8:40   ` Marcel Holtmann
  2015-11-17  9:06   ` Andrzej Kaczmarek
  22 siblings, 2 replies; 29+ messages in thread
From: Luiz Augusto von Dentz @ 2015-11-17  8:33 UTC (permalink / raw)
  To: Andrzej Kaczmarek; +Cc: linux-bluetooth

Hi Andrzej,

On Sat, Nov 14, 2015 at 3:44 PM, Andrzej Kaczmarek
<andrzej.kaczmarek@codecoup.pl> wrote:
> Hi,
>
> Here's series of patches which adds decoding of AVDTP signalling channel
> and A2DP codec capabilities information. Few things are missing:
> - no fragmentation support
> - some rarely used capabilities are not decoded
> - ATRAC capabilities are not decoded
>
> Other that above, pretty much everything should be decoded.
>
> And some sample output from decoder:
>
> < ACL Data TX: Handle 256 flags 0x00 dlen 6
>       Channel: 1602 len 2 [PSM 25 mode 0] {chan 2}
>       AVDTP: Discover (0x01) Command: type 0x00 label 6 nosp 0
>> ACL Data RX: Handle 256 flags 0x02 dlen 14
>       Channel: 66 len 10 [PSM 25 mode 0] {chan 2}
>       AVDTP: Discover (0x01) Response Accept: type 0x00 label 6 nosp 0
>         ACP SEID 1
>           Media Type: Audio
>           SEP Type: SRC
>           In use: No
>         ACP SEID 5
>           Media Type: Audio
>           SEP Type: SRC
>           In use: No
>         ACP SEID 3
>           Media Type: Audio
>           SEP Type: SRC
>           In use: No
>         ACP SEID 2
>           Media Type: Audio
>           SEP Type: SRC
>           In use: No

I guess we can add it In use flag only when set.

>
>
> < ACL Data TX: Handle 256 flags 0x00 dlen 7
>       Channel: 1602 len 3 [PSM 25 mode 0] {chan 2}
>       AVDTP: Get Capabilities (0x02) Command: type 0x00 label 9 nosp 0
>         ACP SEID: 3
>> ACL Data RX: Handle 256 flags 0x02 dlen 23
>       Channel: 66 len 19 [PSM 25 mode 0] {chan 2}
>       AVDTP: Get Capabilities (0x02) Response Accept: type 0x00 label 9 nosp 0
>         Service Category: Media Transport
>         Service Category: Media Codec
>           Media Type: Audio
>           Media Codec: Non-A2DP
>             Vendor ID: 0x0000004f (APT Licensing Ltd.)
>             Vendor Specific Codec ID: 0x0001 (aptX)
>               Frequency: 0x30
>                 44100
>                 48000
>               Channel Mode: 0x02
>                 Stereo
>         Service Category: Content Protection
>           Content Protection Type: SCMS-T
>
>
> < ACL Data TX: Handle 256 flags 0x00 dlen 18
>       Channel: 1602 len 14 [PSM 25 mode 0] {chan 2}
>       AVDTP: Set Configuration (0x03) Command: type 0x00 label 11 nosp 0
>         ACP SEID: 1
>         INT SEID: 1
>         Service Category: Media Transport
>         Service Category: Media Codec
>           Media Type: Audio
>           Media Codec: SBC
>             Frequency: 0x20
>               44100
>             Channel Mode: 0x01
>               Joint Channel
>             Block Length: 0x10
>               16
>             Subbands: 0x04
>               8
>             Allocation Method: 0x01
>               Loudness
>             Minimum Bitpool: 2
>             Maximum Bitpool: 53

Id got with a range instead of 2 field e.g. Bitpool: 2-53. Actually
overall Id make this more compact instead of having another line for
the decoded value just input in the same line with the hex value in
parenthesis.

>> ACL Data RX: Handle 256 flags 0x02 dlen 6
>       Channel: 66 len 2 [PSM 25 mode 0] {chan 2}
>       AVDTP: Set Configuration (0x03) Response Accept: type 0x00 label 11 nosp 0
>
>> ACL Data RX: Handle 256 flags 0x02 dlen 6
>       Channel: 66 len 2 [PSM 25 mode 0] {chan 2}
>       AVDTP: Open (0x06) Response Accept: type 0x00 label 12 nosp 0
>
>
> < ACL Data TX: Handle 256 flags 0x00 dlen 7
>       Channel: 1602 len 3 [PSM 25 mode 0] {chan 2}
>       AVDTP: Start (0x07) Command: type 0x00 label 13 nosp 0
>         ACP SEID: 1
>> ACL Data RX: Handle 256 flags 0x02 dlen 6
>       Channel: 66 len 2 [PSM 25 mode 0] {chan 2}
>       AVDTP: Start (0x07) Response Accept: type 0x00 label 13 nosp 0

Would you be able to include the output above into the patch that
introduce it? I think it is a bit better to see the formatting each
patch is introducing and then have proper comments to them.

>
>
> Andrzej Kaczmarek (22):
>   monitor/l2cap: Add channel sequence number
>   monitor/avdtp: Add basic decoding of AVDTP signalling
>   monitor/avdtp: Decode AVDTP_DISCOVER
>   monitor/avdtp: Decode AVDTP_GET_CAPABILITIES
>   monitor/avdtp: Decode AVDTP_SET_CONFIGURATION
>   monitor/avdtp: Decode AVDTP_GET_CONFIGURATION
>   monitor/avdtp: Decode AVDTP_RECONFIGURE
>   monitor/avdtp: Decode AVDTP_OPEN
>   monitor/avdtp: Decode AVDTP_START
>   monitor/avdtp: Decode AVDTP_CLOSE
>   monitor/avdtp: Decode AVDTP_SUSPEND
>   monitor/avdtp: Decode AVDTP_ABORT
>   monitor/avdtp: Decode AVDTP_SECURITY_CONTROL
>   monitor/avdtp: Decode AVDTP_GET_ALL_CAPABILITIES
>   monitor/avdtp: Decode AVDTP_DELAYREPORT
>   monitor/avdtp: Decode basic Media Codec capabilities
>   monitor/avdtp: Decode basic Content Protection capabilities
>   monitor/a2dp: Decode SBC capabilities
>   monitor/a2dp: Decode MPEG-1,2 capabilities
>   monitor/a2dp: Decode AAC capabilities
>   monitor/a2dp: Decode aptX capabilities
>   monitor/a2dp: Decode LDAC capabilities
>
>  Makefile.tools     |   2 +
>  android/Android.mk |   2 +
>  monitor/a2dp.c     | 420 +++++++++++++++++++++++++++
>  monitor/a2dp.h     |  24 ++
>  monitor/avdtp.c    | 819 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  monitor/avdtp.h    |  24 ++
>  monitor/l2cap.c    |  48 +++-
>  monitor/l2cap.h    |   1 +
>  8 files changed, 1327 insertions(+), 13 deletions(-)
>  create mode 100644 monitor/a2dp.c
>  create mode 100644 monitor/a2dp.h
>  create mode 100644 monitor/avdtp.c
>  create mode 100644 monitor/avdtp.h
>
> --
> 2.6.2
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Luiz Augusto von Dentz

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

* Re: [PATCH 00/22] Add AVDTP/A2DP decoding to btmon
  2015-11-17  8:33 ` [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Luiz Augusto von Dentz
@ 2015-11-17  8:40   ` Marcel Holtmann
  2015-11-17  9:11     ` Andrzej Kaczmarek
  2015-11-17  9:06   ` Andrzej Kaczmarek
  1 sibling, 1 reply; 29+ messages in thread
From: Marcel Holtmann @ 2015-11-17  8:40 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: Andrzej Kaczmarek, linux-bluetooth

Hi Luiz,

>> Here's series of patches which adds decoding of AVDTP signalling channel
>> and A2DP codec capabilities information. Few things are missing:
>> - no fragmentation support
>> - some rarely used capabilities are not decoded
>> - ATRAC capabilities are not decoded
>> 
>> Other that above, pretty much everything should be decoded.
>> 
>> And some sample output from decoder:
>> 
>> < ACL Data TX: Handle 256 flags 0x00 dlen 6
>>      Channel: 1602 len 2 [PSM 25 mode 0] {chan 2}
>>      AVDTP: Discover (0x01) Command: type 0x00 label 6 nosp 0
>>> ACL Data RX: Handle 256 flags 0x02 dlen 14
>>      Channel: 66 len 10 [PSM 25 mode 0] {chan 2}
>>      AVDTP: Discover (0x01) Response Accept: type 0x00 label 6 nosp 0
>>        ACP SEID 1
>>          Media Type: Audio
>>          SEP Type: SRC
>>          In use: No
>>        ACP SEID 5
>>          Media Type: Audio
>>          SEP Type: SRC
>>          In use: No
>>        ACP SEID 3
>>          Media Type: Audio
>>          SEP Type: SRC
>>          In use: No
>>        ACP SEID 2
>>          Media Type: Audio
>>          SEP Type: SRC
>>          In use: No
> 
> I guess we can add it In use flag only when set.

actually btmon is suppose to decode and not be smart about when to show things. So lets really do print all parameters and not leave them out because they are unset.

>> < ACL Data TX: Handle 256 flags 0x00 dlen 7
>>      Channel: 1602 len 3 [PSM 25 mode 0] {chan 2}
>>      AVDTP: Get Capabilities (0x02) Command: type 0x00 label 9 nosp 0
>>        ACP SEID: 3
>>> ACL Data RX: Handle 256 flags 0x02 dlen 23
>>      Channel: 66 len 19 [PSM 25 mode 0] {chan 2}
>>      AVDTP: Get Capabilities (0x02) Response Accept: type 0x00 label 9 nosp 0
>>        Service Category: Media Transport
>>        Service Category: Media Codec
>>          Media Type: Audio
>>          Media Codec: Non-A2DP
>>            Vendor ID: 0x0000004f (APT Licensing Ltd.)
>>            Vendor Specific Codec ID: 0x0001 (aptX)
>>              Frequency: 0x30
>>                44100
>>                48000
>>              Channel Mode: 0x02
>>                Stereo
>>        Service Category: Content Protection
>>          Content Protection Type: SCMS-T
>> 
>> 
>> < ACL Data TX: Handle 256 flags 0x00 dlen 18
>>      Channel: 1602 len 14 [PSM 25 mode 0] {chan 2}
>>      AVDTP: Set Configuration (0x03) Command: type 0x00 label 11 nosp 0
>>        ACP SEID: 1
>>        INT SEID: 1
>>        Service Category: Media Transport
>>        Service Category: Media Codec
>>          Media Type: Audio
>>          Media Codec: SBC
>>            Frequency: 0x20
>>              44100
>>            Channel Mode: 0x01
>>              Joint Channel
>>            Block Length: 0x10
>>              16
>>            Subbands: 0x04
>>              8
>>            Allocation Method: 0x01
>>              Loudness
>>            Minimum Bitpool: 2
>>            Maximum Bitpool: 53
> 
> Id got with a range instead of 2 field e.g. Bitpool: 2-53. Actually
> overall Id make this more compact instead of having another line for
> the decoded value just input in the same line with the hex value in
> parenthesis.

Actually the problem is not the bit pool. It is the others. It should be like this:

	Frequency: 44100 (0x20(	
	Block length: 16 (0x10)
	Allocation method: Loudness (0x01)

And please follow the styles I have introduced in the HCI portion and not make up new stuff. I actually want the strings to primary and also show the raw values.

> 
>>> ACL Data RX: Handle 256 flags 0x02 dlen 6
>>      Channel: 66 len 2 [PSM 25 mode 0] {chan 2}
>>      AVDTP: Set Configuration (0x03) Response Accept: type 0x00 label 11 nosp 0
>> 
>>> ACL Data RX: Handle 256 flags 0x02 dlen 6
>>      Channel: 66 len 2 [PSM 25 mode 0] {chan 2}
>>      AVDTP: Open (0x06) Response Accept: type 0x00 label 12 nosp 0
>> 
>> 
>> < ACL Data TX: Handle 256 flags 0x00 dlen 7
>>      Channel: 1602 len 3 [PSM 25 mode 0] {chan 2}
>>      AVDTP: Start (0x07) Command: type 0x00 label 13 nosp 0
>>        ACP SEID: 1
>>> ACL Data RX: Handle 256 flags 0x02 dlen 6
>>      Channel: 66 len 2 [PSM 25 mode 0] {chan 2}
>>      AVDTP: Start (0x07) Response Accept: type 0x00 label 13 nosp 0
> 
> Would you be able to include the output above into the patch that
> introduce it? I think it is a bit better to see the formatting each
> patch is introducing and then have proper comments to them.

Why are we falling back into trying to cramp all stuff into a single line. btmon is verbose on purpose. Deal with i.

Regards

Marcel


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

* Re: [PATCH 00/22] Add AVDTP/A2DP decoding to btmon
  2015-11-17  8:33 ` [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Luiz Augusto von Dentz
  2015-11-17  8:40   ` Marcel Holtmann
@ 2015-11-17  9:06   ` Andrzej Kaczmarek
  1 sibling, 0 replies; 29+ messages in thread
From: Andrzej Kaczmarek @ 2015-11-17  9:06 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth

Hi Luiz,

On Tue, Nov 17, 2015 at 9:33 AM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> Hi Andrzej,
>
> On Sat, Nov 14, 2015 at 3:44 PM, Andrzej Kaczmarek
> <andrzej.kaczmarek@codecoup.pl> wrote:
>> Hi,
>>
>> Here's series of patches which adds decoding of AVDTP signalling channel
>> and A2DP codec capabilities information. Few things are missing:
>> - no fragmentation support
>> - some rarely used capabilities are not decoded
>> - ATRAC capabilities are not decoded
>>
>> Other that above, pretty much everything should be decoded.
>>
>> And some sample output from decoder:
>>
>> < ACL Data TX: Handle 256 flags 0x00 dlen 6
>>       Channel: 1602 len 2 [PSM 25 mode 0] {chan 2}
>>       AVDTP: Discover (0x01) Command: type 0x00 label 6 nosp 0
>>> ACL Data RX: Handle 256 flags 0x02 dlen 14
>>       Channel: 66 len 10 [PSM 25 mode 0] {chan 2}
>>       AVDTP: Discover (0x01) Response Accept: type 0x00 label 6 nosp 0
>>         ACP SEID 1
>>           Media Type: Audio
>>           SEP Type: SRC
>>           In use: No
>>         ACP SEID 5
>>           Media Type: Audio
>>           SEP Type: SRC
>>           In use: No
>>         ACP SEID 3
>>           Media Type: Audio
>>           SEP Type: SRC
>>           In use: No
>>         ACP SEID 2
>>           Media Type: Audio
>>           SEP Type: SRC
>>           In use: No
>
> I guess we can add it In use flag only when set.
>
>>
>>
>> < ACL Data TX: Handle 256 flags 0x00 dlen 7
>>       Channel: 1602 len 3 [PSM 25 mode 0] {chan 2}
>>       AVDTP: Get Capabilities (0x02) Command: type 0x00 label 9 nosp 0
>>         ACP SEID: 3
>>> ACL Data RX: Handle 256 flags 0x02 dlen 23
>>       Channel: 66 len 19 [PSM 25 mode 0] {chan 2}
>>       AVDTP: Get Capabilities (0x02) Response Accept: type 0x00 label 9 nosp 0
>>         Service Category: Media Transport
>>         Service Category: Media Codec
>>           Media Type: Audio
>>           Media Codec: Non-A2DP
>>             Vendor ID: 0x0000004f (APT Licensing Ltd.)
>>             Vendor Specific Codec ID: 0x0001 (aptX)
>>               Frequency: 0x30
>>                 44100
>>                 48000
>>               Channel Mode: 0x02
>>                 Stereo
>>         Service Category: Content Protection
>>           Content Protection Type: SCMS-T
>>
>>
>> < ACL Data TX: Handle 256 flags 0x00 dlen 18
>>       Channel: 1602 len 14 [PSM 25 mode 0] {chan 2}
>>       AVDTP: Set Configuration (0x03) Command: type 0x00 label 11 nosp 0
>>         ACP SEID: 1
>>         INT SEID: 1
>>         Service Category: Media Transport
>>         Service Category: Media Codec
>>           Media Type: Audio
>>           Media Codec: SBC
>>             Frequency: 0x20
>>               44100
>>             Channel Mode: 0x01
>>               Joint Channel
>>             Block Length: 0x10
>>               16
>>             Subbands: 0x04
>>               8
>>             Allocation Method: 0x01
>>               Loudness
>>             Minimum Bitpool: 2
>>             Maximum Bitpool: 53
>
> Id got with a range instead of 2 field e.g. Bitpool: 2-53. Actually
> overall Id make this more compact instead of having another line for
> the decoded value just input in the same line with the hex value in
> parenthesis.
>
>>> ACL Data RX: Handle 256 flags 0x02 dlen 6
>>       Channel: 66 len 2 [PSM 25 mode 0] {chan 2}
>>       AVDTP: Set Configuration (0x03) Response Accept: type 0x00 label 11 nosp 0
>>
>>> ACL Data RX: Handle 256 flags 0x02 dlen 6
>>       Channel: 66 len 2 [PSM 25 mode 0] {chan 2}
>>       AVDTP: Open (0x06) Response Accept: type 0x00 label 12 nosp 0
>>
>>
>> < ACL Data TX: Handle 256 flags 0x00 dlen 7
>>       Channel: 1602 len 3 [PSM 25 mode 0] {chan 2}
>>       AVDTP: Start (0x07) Command: type 0x00 label 13 nosp 0
>>         ACP SEID: 1
>>> ACL Data RX: Handle 256 flags 0x02 dlen 6
>>       Channel: 66 len 2 [PSM 25 mode 0] {chan 2}
>>       AVDTP: Start (0x07) Response Accept: type 0x00 label 13 nosp 0
>
> Would you be able to include the output above into the patch that
> introduce it? I think it is a bit better to see the formatting each
> patch is introducing and then have proper comments to them.

Sure, I'll do this in v2.

For the other comments I'll go with Marcel''s suggestions.

BR,
Andrzej

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

* Re: [PATCH 00/22] Add AVDTP/A2DP decoding to btmon
  2015-11-17  8:40   ` Marcel Holtmann
@ 2015-11-17  9:11     ` Andrzej Kaczmarek
  2015-11-17 14:06       ` Luiz Augusto von Dentz
  0 siblings, 1 reply; 29+ messages in thread
From: Andrzej Kaczmarek @ 2015-11-17  9:11 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: Luiz Augusto von Dentz, linux-bluetooth

Hi Marcel,

On Tue, Nov 17, 2015 at 9:40 AM, Marcel Holtmann <marcel@holtmann.org> wrote:
> Hi Luiz,
>
>>> Here's series of patches which adds decoding of AVDTP signalling channel
>>> and A2DP codec capabilities information. Few things are missing:
>>> - no fragmentation support
>>> - some rarely used capabilities are not decoded
>>> - ATRAC capabilities are not decoded
>>>
>>> Other that above, pretty much everything should be decoded.
>>>
>>> And some sample output from decoder:
>>>
>>> < ACL Data TX: Handle 256 flags 0x00 dlen 6
>>>      Channel: 1602 len 2 [PSM 25 mode 0] {chan 2}
>>>      AVDTP: Discover (0x01) Command: type 0x00 label 6 nosp 0
>>>> ACL Data RX: Handle 256 flags 0x02 dlen 14
>>>      Channel: 66 len 10 [PSM 25 mode 0] {chan 2}
>>>      AVDTP: Discover (0x01) Response Accept: type 0x00 label 6 nosp 0
>>>        ACP SEID 1
>>>          Media Type: Audio
>>>          SEP Type: SRC
>>>          In use: No
>>>        ACP SEID 5
>>>          Media Type: Audio
>>>          SEP Type: SRC
>>>          In use: No
>>>        ACP SEID 3
>>>          Media Type: Audio
>>>          SEP Type: SRC
>>>          In use: No
>>>        ACP SEID 2
>>>          Media Type: Audio
>>>          SEP Type: SRC
>>>          In use: No
>>
>> I guess we can add it In use flag only when set.
>
> actually btmon is suppose to decode and not be smart about when to show things. So lets really do print all parameters and not leave them out because they are unset.
>
>>> < ACL Data TX: Handle 256 flags 0x00 dlen 7
>>>      Channel: 1602 len 3 [PSM 25 mode 0] {chan 2}
>>>      AVDTP: Get Capabilities (0x02) Command: type 0x00 label 9 nosp 0
>>>        ACP SEID: 3
>>>> ACL Data RX: Handle 256 flags 0x02 dlen 23
>>>      Channel: 66 len 19 [PSM 25 mode 0] {chan 2}
>>>      AVDTP: Get Capabilities (0x02) Response Accept: type 0x00 label 9 nosp 0
>>>        Service Category: Media Transport
>>>        Service Category: Media Codec
>>>          Media Type: Audio
>>>          Media Codec: Non-A2DP
>>>            Vendor ID: 0x0000004f (APT Licensing Ltd.)
>>>            Vendor Specific Codec ID: 0x0001 (aptX)
>>>              Frequency: 0x30
>>>                44100
>>>                48000
>>>              Channel Mode: 0x02
>>>                Stereo
>>>        Service Category: Content Protection
>>>          Content Protection Type: SCMS-T
>>>
>>>
>>> < ACL Data TX: Handle 256 flags 0x00 dlen 18
>>>      Channel: 1602 len 14 [PSM 25 mode 0] {chan 2}
>>>      AVDTP: Set Configuration (0x03) Command: type 0x00 label 11 nosp 0
>>>        ACP SEID: 1
>>>        INT SEID: 1
>>>        Service Category: Media Transport
>>>        Service Category: Media Codec
>>>          Media Type: Audio
>>>          Media Codec: SBC
>>>            Frequency: 0x20
>>>              44100
>>>            Channel Mode: 0x01
>>>              Joint Channel
>>>            Block Length: 0x10
>>>              16
>>>            Subbands: 0x04
>>>              8
>>>            Allocation Method: 0x01
>>>              Loudness
>>>            Minimum Bitpool: 2
>>>            Maximum Bitpool: 53
>>
>> Id got with a range instead of 2 field e.g. Bitpool: 2-53. Actually
>> overall Id make this more compact instead of having another line for
>> the decoded value just input in the same line with the hex value in
>> parenthesis.
>
> Actually the problem is not the bit pool. It is the others. It should be like this:
>
>         Frequency: 44100 (0x20(
>         Block length: 16 (0x10)
>         Allocation method: Loudness (0x01)
>
> And please follow the styles I have introduced in the HCI portion and not make up new stuff. I actually want the strings to primary and also show the raw values.

Ok, I'll fix it.

>
>>
>>>> ACL Data RX: Handle 256 flags 0x02 dlen 6
>>>      Channel: 66 len 2 [PSM 25 mode 0] {chan 2}
>>>      AVDTP: Set Configuration (0x03) Response Accept: type 0x00 label 11 nosp 0
>>>
>>>> ACL Data RX: Handle 256 flags 0x02 dlen 6
>>>      Channel: 66 len 2 [PSM 25 mode 0] {chan 2}
>>>      AVDTP: Open (0x06) Response Accept: type 0x00 label 12 nosp 0
>>>
>>>
>>> < ACL Data TX: Handle 256 flags 0x00 dlen 7
>>>      Channel: 1602 len 3 [PSM 25 mode 0] {chan 2}
>>>      AVDTP: Start (0x07) Command: type 0x00 label 13 nosp 0
>>>        ACP SEID: 1
>>>> ACL Data RX: Handle 256 flags 0x02 dlen 6
>>>      Channel: 66 len 2 [PSM 25 mode 0] {chan 2}
>>>      AVDTP: Start (0x07) Response Accept: type 0x00 label 13 nosp 0
>>
>> Would you be able to include the output above into the patch that
>> introduce it? I think it is a bit better to see the formatting each
>> patch is introducing and then have proper comments to them.
>
> Why are we falling back into trying to cramp all stuff into a single line. btmon is verbose on purpose. Deal with i.

You mean the" AVDTP: Start ..." line? I wasn't sure which protocol to
follow here so "AVDTP: Start" is what you have in HCI and L2CAP
(protocol + command), then "Response Accept" is what AVRCP does. And
the other parameters from frame header are used the same in all
protocols actually. For decoding of AVDTP Transport headers I planned
to make it "AVDTP Media: <codec>".

Any other idea how this should look like?

BR,
Andrzej

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

* Re: [PATCH 00/22] Add AVDTP/A2DP decoding to btmon
  2015-11-17  9:11     ` Andrzej Kaczmarek
@ 2015-11-17 14:06       ` Luiz Augusto von Dentz
  2015-11-17 21:22         ` Andrzej Kaczmarek
  0 siblings, 1 reply; 29+ messages in thread
From: Luiz Augusto von Dentz @ 2015-11-17 14:06 UTC (permalink / raw)
  To: Andrzej Kaczmarek; +Cc: Marcel Holtmann, linux-bluetooth

Hi Andrzej,

On Tue, Nov 17, 2015 at 11:11 AM, Andrzej Kaczmarek
<andrzej.kaczmarek@codecoup.pl> wrote:
> Hi Marcel,
>
> On Tue, Nov 17, 2015 at 9:40 AM, Marcel Holtmann <marcel@holtmann.org> wrote:
>> Hi Luiz,
>>
>>>> Here's series of patches which adds decoding of AVDTP signalling channel
>>>> and A2DP codec capabilities information. Few things are missing:
>>>> - no fragmentation support
>>>> - some rarely used capabilities are not decoded
>>>> - ATRAC capabilities are not decoded
>>>>
>>>> Other that above, pretty much everything should be decoded.
>>>>
>>>> And some sample output from decoder:
>>>>
>>>> < ACL Data TX: Handle 256 flags 0x00 dlen 6
>>>>      Channel: 1602 len 2 [PSM 25 mode 0] {chan 2}
>>>>      AVDTP: Discover (0x01) Command: type 0x00 label 6 nosp 0
>>>>> ACL Data RX: Handle 256 flags 0x02 dlen 14
>>>>      Channel: 66 len 10 [PSM 25 mode 0] {chan 2}
>>>>      AVDTP: Discover (0x01) Response Accept: type 0x00 label 6 nosp 0
>>>>        ACP SEID 1
>>>>          Media Type: Audio
>>>>          SEP Type: SRC
>>>>          In use: No
>>>>        ACP SEID 5
>>>>          Media Type: Audio
>>>>          SEP Type: SRC
>>>>          In use: No
>>>>        ACP SEID 3
>>>>          Media Type: Audio
>>>>          SEP Type: SRC
>>>>          In use: No
>>>>        ACP SEID 2
>>>>          Media Type: Audio
>>>>          SEP Type: SRC
>>>>          In use: No
>>>
>>> I guess we can add it In use flag only when set.
>>
>> actually btmon is suppose to decode and not be smart about when to show things. So lets really do print all parameters and not leave them out because they are unset.
>>
>>>> < ACL Data TX: Handle 256 flags 0x00 dlen 7
>>>>      Channel: 1602 len 3 [PSM 25 mode 0] {chan 2}
>>>>      AVDTP: Get Capabilities (0x02) Command: type 0x00 label 9 nosp 0
>>>>        ACP SEID: 3
>>>>> ACL Data RX: Handle 256 flags 0x02 dlen 23
>>>>      Channel: 66 len 19 [PSM 25 mode 0] {chan 2}
>>>>      AVDTP: Get Capabilities (0x02) Response Accept: type 0x00 label 9 nosp 0
>>>>        Service Category: Media Transport
>>>>        Service Category: Media Codec
>>>>          Media Type: Audio
>>>>          Media Codec: Non-A2DP
>>>>            Vendor ID: 0x0000004f (APT Licensing Ltd.)
>>>>            Vendor Specific Codec ID: 0x0001 (aptX)
>>>>              Frequency: 0x30
>>>>                44100
>>>>                48000
>>>>              Channel Mode: 0x02
>>>>                Stereo
>>>>        Service Category: Content Protection
>>>>          Content Protection Type: SCMS-T
>>>>
>>>>
>>>> < ACL Data TX: Handle 256 flags 0x00 dlen 18
>>>>      Channel: 1602 len 14 [PSM 25 mode 0] {chan 2}
>>>>      AVDTP: Set Configuration (0x03) Command: type 0x00 label 11 nosp 0
>>>>        ACP SEID: 1
>>>>        INT SEID: 1
>>>>        Service Category: Media Transport
>>>>        Service Category: Media Codec
>>>>          Media Type: Audio
>>>>          Media Codec: SBC
>>>>            Frequency: 0x20
>>>>              44100
>>>>            Channel Mode: 0x01
>>>>              Joint Channel
>>>>            Block Length: 0x10
>>>>              16
>>>>            Subbands: 0x04
>>>>              8
>>>>            Allocation Method: 0x01
>>>>              Loudness
>>>>            Minimum Bitpool: 2
>>>>            Maximum Bitpool: 53
>>>
>>> Id got with a range instead of 2 field e.g. Bitpool: 2-53. Actually
>>> overall Id make this more compact instead of having another line for
>>> the decoded value just input in the same line with the hex value in
>>> parenthesis.
>>
>> Actually the problem is not the bit pool. It is the others. It should be like this:
>>
>>         Frequency: 44100 (0x20(
>>         Block length: 16 (0x10)
>>         Allocation method: Loudness (0x01)
>>
>> And please follow the styles I have introduced in the HCI portion and not make up new stuff. I actually want the strings to primary and also show the raw values.
>
> Ok, I'll fix it.
>
>>
>>>
>>>>> ACL Data RX: Handle 256 flags 0x02 dlen 6
>>>>      Channel: 66 len 2 [PSM 25 mode 0] {chan 2}
>>>>      AVDTP: Set Configuration (0x03) Response Accept: type 0x00 label 11 nosp 0
>>>>
>>>>> ACL Data RX: Handle 256 flags 0x02 dlen 6
>>>>      Channel: 66 len 2 [PSM 25 mode 0] {chan 2}
>>>>      AVDTP: Open (0x06) Response Accept: type 0x00 label 12 nosp 0
>>>>
>>>>
>>>> < ACL Data TX: Handle 256 flags 0x00 dlen 7
>>>>      Channel: 1602 len 3 [PSM 25 mode 0] {chan 2}
>>>>      AVDTP: Start (0x07) Command: type 0x00 label 13 nosp 0
>>>>        ACP SEID: 1
>>>>> ACL Data RX: Handle 256 flags 0x02 dlen 6
>>>>      Channel: 66 len 2 [PSM 25 mode 0] {chan 2}
>>>>      AVDTP: Start (0x07) Response Accept: type 0x00 label 13 nosp 0
>>>
>>> Would you be able to include the output above into the patch that
>>> introduce it? I think it is a bit better to see the formatting each
>>> patch is introducing and then have proper comments to them.
>>
>> Why are we falling back into trying to cramp all stuff into a single line. btmon is verbose on purpose. Deal with i.
>
> You mean the" AVDTP: Start ..." line? I wasn't sure which protocol to
> follow here so "AVDTP: Start" is what you have in HCI and L2CAP
> (protocol + command), then "Response Accept" is what AVRCP does. And
> the other parameters from frame header are used the same in all
> protocols actually. For decoding of AVDTP Transport headers I planned
> to make it "AVDTP Media: <codec>".
>
> Any other idea how this should look like?

I assumed it is a common practice to decode the headers in a single line:

L2CAP: Configure Response (0x05) ident 14 len 6
SDP: Service Search Attribute Request (0x06) tid 0 len 25
AVCTP Control: Response: type 0x00 label 7 PID 0x110e

But the format is not very strict, at least not up to now, so perhaps
we should always follow decode string (raw hex) when decoding fields
that means AVCTP line about should be:

AVCTP Control: Response (code) type 0x00 label 7 PID 0x110e

I guess for the media it would be fine to have AVDTP Media as the
header but I wonder how you will be able to detect the codec? Or are
you planning to decode the RTP headers?

Btw, we could perhaps have an option to discard audio packets or make
them 0 length if we want to keep the timestamps, or maybe have this by
default since it makes the traces much smaller and reconstructing the
audio stream is something btmon will probably never do although it
seems wireshark has support to do it Ive never seen it working.

-- 
Luiz Augusto von Dentz

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

* Re: [PATCH 00/22] Add AVDTP/A2DP decoding to btmon
  2015-11-17 14:06       ` Luiz Augusto von Dentz
@ 2015-11-17 21:22         ` Andrzej Kaczmarek
  0 siblings, 0 replies; 29+ messages in thread
From: Andrzej Kaczmarek @ 2015-11-17 21:22 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: Marcel Holtmann, linux-bluetooth

Hi Luiz,

On Tue, Nov 17, 2015 at 3:06 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> Hi Andrzej,
>
> On Tue, Nov 17, 2015 at 11:11 AM, Andrzej Kaczmarek
> <andrzej.kaczmarek@codecoup.pl> wrote:
>> Hi Marcel,
>>
>> On Tue, Nov 17, 2015 at 9:40 AM, Marcel Holtmann <marcel@holtmann.org> wrote:
>>> Hi Luiz,
>>>
>>>>> Here's series of patches which adds decoding of AVDTP signalling channel
>>>>> and A2DP codec capabilities information. Few things are missing:
>>>>> - no fragmentation support
>>>>> - some rarely used capabilities are not decoded
>>>>> - ATRAC capabilities are not decoded
>>>>>
>>>>> Other that above, pretty much everything should be decoded.
>>>>>
>>>>> And some sample output from decoder:
>>>>>
>>>>> < ACL Data TX: Handle 256 flags 0x00 dlen 6
>>>>>      Channel: 1602 len 2 [PSM 25 mode 0] {chan 2}
>>>>>      AVDTP: Discover (0x01) Command: type 0x00 label 6 nosp 0
>>>>>> ACL Data RX: Handle 256 flags 0x02 dlen 14
>>>>>      Channel: 66 len 10 [PSM 25 mode 0] {chan 2}
>>>>>      AVDTP: Discover (0x01) Response Accept: type 0x00 label 6 nosp 0
>>>>>        ACP SEID 1
>>>>>          Media Type: Audio
>>>>>          SEP Type: SRC
>>>>>          In use: No
>>>>>        ACP SEID 5
>>>>>          Media Type: Audio
>>>>>          SEP Type: SRC
>>>>>          In use: No
>>>>>        ACP SEID 3
>>>>>          Media Type: Audio
>>>>>          SEP Type: SRC
>>>>>          In use: No
>>>>>        ACP SEID 2
>>>>>          Media Type: Audio
>>>>>          SEP Type: SRC
>>>>>          In use: No
>>>>
>>>> I guess we can add it In use flag only when set.
>>>
>>> actually btmon is suppose to decode and not be smart about when to show things. So lets really do print all parameters and not leave them out because they are unset.
>>>
>>>>> < ACL Data TX: Handle 256 flags 0x00 dlen 7
>>>>>      Channel: 1602 len 3 [PSM 25 mode 0] {chan 2}
>>>>>      AVDTP: Get Capabilities (0x02) Command: type 0x00 label 9 nosp 0
>>>>>        ACP SEID: 3
>>>>>> ACL Data RX: Handle 256 flags 0x02 dlen 23
>>>>>      Channel: 66 len 19 [PSM 25 mode 0] {chan 2}
>>>>>      AVDTP: Get Capabilities (0x02) Response Accept: type 0x00 label 9 nosp 0
>>>>>        Service Category: Media Transport
>>>>>        Service Category: Media Codec
>>>>>          Media Type: Audio
>>>>>          Media Codec: Non-A2DP
>>>>>            Vendor ID: 0x0000004f (APT Licensing Ltd.)
>>>>>            Vendor Specific Codec ID: 0x0001 (aptX)
>>>>>              Frequency: 0x30
>>>>>                44100
>>>>>                48000
>>>>>              Channel Mode: 0x02
>>>>>                Stereo
>>>>>        Service Category: Content Protection
>>>>>          Content Protection Type: SCMS-T
>>>>>
>>>>>
>>>>> < ACL Data TX: Handle 256 flags 0x00 dlen 18
>>>>>      Channel: 1602 len 14 [PSM 25 mode 0] {chan 2}
>>>>>      AVDTP: Set Configuration (0x03) Command: type 0x00 label 11 nosp 0
>>>>>        ACP SEID: 1
>>>>>        INT SEID: 1
>>>>>        Service Category: Media Transport
>>>>>        Service Category: Media Codec
>>>>>          Media Type: Audio
>>>>>          Media Codec: SBC
>>>>>            Frequency: 0x20
>>>>>              44100
>>>>>            Channel Mode: 0x01
>>>>>              Joint Channel
>>>>>            Block Length: 0x10
>>>>>              16
>>>>>            Subbands: 0x04
>>>>>              8
>>>>>            Allocation Method: 0x01
>>>>>              Loudness
>>>>>            Minimum Bitpool: 2
>>>>>            Maximum Bitpool: 53
>>>>
>>>> Id got with a range instead of 2 field e.g. Bitpool: 2-53. Actually
>>>> overall Id make this more compact instead of having another line for
>>>> the decoded value just input in the same line with the hex value in
>>>> parenthesis.
>>>
>>> Actually the problem is not the bit pool. It is the others. It should be like this:
>>>
>>>         Frequency: 44100 (0x20(
>>>         Block length: 16 (0x10)
>>>         Allocation method: Loudness (0x01)
>>>
>>> And please follow the styles I have introduced in the HCI portion and not make up new stuff. I actually want the strings to primary and also show the raw values.
>>
>> Ok, I'll fix it.
>>
>>>
>>>>
>>>>>> ACL Data RX: Handle 256 flags 0x02 dlen 6
>>>>>      Channel: 66 len 2 [PSM 25 mode 0] {chan 2}
>>>>>      AVDTP: Set Configuration (0x03) Response Accept: type 0x00 label 11 nosp 0
>>>>>
>>>>>> ACL Data RX: Handle 256 flags 0x02 dlen 6
>>>>>      Channel: 66 len 2 [PSM 25 mode 0] {chan 2}
>>>>>      AVDTP: Open (0x06) Response Accept: type 0x00 label 12 nosp 0
>>>>>
>>>>>
>>>>> < ACL Data TX: Handle 256 flags 0x00 dlen 7
>>>>>      Channel: 1602 len 3 [PSM 25 mode 0] {chan 2}
>>>>>      AVDTP: Start (0x07) Command: type 0x00 label 13 nosp 0
>>>>>        ACP SEID: 1
>>>>>> ACL Data RX: Handle 256 flags 0x02 dlen 6
>>>>>      Channel: 66 len 2 [PSM 25 mode 0] {chan 2}
>>>>>      AVDTP: Start (0x07) Response Accept: type 0x00 label 13 nosp 0
>>>>
>>>> Would you be able to include the output above into the patch that
>>>> introduce it? I think it is a bit better to see the formatting each
>>>> patch is introducing and then have proper comments to them.
>>>
>>> Why are we falling back into trying to cramp all stuff into a single line. btmon is verbose on purpose. Deal with i.
>>
>> You mean the" AVDTP: Start ..." line? I wasn't sure which protocol to
>> follow here so "AVDTP: Start" is what you have in HCI and L2CAP
>> (protocol + command), then "Response Accept" is what AVRCP does. And
>> the other parameters from frame header are used the same in all
>> protocols actually. For decoding of AVDTP Transport headers I planned
>> to make it "AVDTP Media: <codec>".
>>
>> Any other idea how this should look like?
>
> I assumed it is a common practice to decode the headers in a single line:
>
> L2CAP: Configure Response (0x05) ident 14 len 6
> SDP: Service Search Attribute Request (0x06) tid 0 len 25
> AVCTP Control: Response: type 0x00 label 7 PID 0x110e
>
> But the format is not very strict, at least not up to now, so perhaps
> we should always follow decode string (raw hex) when decoding fields
> that means AVCTP line about should be:
>
> AVCTP Control: Response (code) type 0x00 label 7 PID 0x110e
>
> I guess for the media it would be fine to have AVDTP Media as the
> header but I wonder how you will be able to detect the codec? Or are
> you planning to decode the RTP headers?

I plan to add simple tracking for streams by storing (some)
information from AVDTP_SET_CONFIGURATION - this way I can identify
contents of transport channel and try to decode relevant headers. I
don't want to just decode RTP since IIRC aptX does not use RTP header
so this would not work properly.

> Btw, we could perhaps have an option to discard audio packets or make
> them 0 length if we want to keep the timestamps, or maybe have this by
> default since it makes the traces much smaller and reconstructing the
> audio stream is something btmon will probably never do although it
> seems wireshark has support to do it Ive never seen it working.

I guess for now we can add option similar to -S (dump SCO traffic),
i.e. do not dump media data by default and enable on request. Perhaps
-M (--media)?

BR,
Andrzej

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

end of thread, other threads:[~2015-11-17 21:22 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-14 13:44 [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Andrzej Kaczmarek
2015-11-14 13:44 ` [PATCH 01/22] monitor/l2cap: Add channel sequence number Andrzej Kaczmarek
2015-11-14 13:44 ` [PATCH 02/22] monitor/avdtp: Add basic decoding of AVDTP signalling Andrzej Kaczmarek
2015-11-14 13:44 ` [PATCH 03/22] monitor/avdtp: Decode AVDTP_DISCOVER Andrzej Kaczmarek
2015-11-14 13:44 ` [PATCH 04/22] monitor/avdtp: Decode AVDTP_GET_CAPABILITIES Andrzej Kaczmarek
2015-11-14 13:44 ` [PATCH 05/22] monitor/avdtp: Decode AVDTP_SET_CONFIGURATION Andrzej Kaczmarek
2015-11-14 13:44 ` [PATCH 06/22] monitor/avdtp: Decode AVDTP_GET_CONFIGURATION Andrzej Kaczmarek
2015-11-14 13:44 ` [PATCH 07/22] monitor/avdtp: Decode AVDTP_RECONFIGURE Andrzej Kaczmarek
2015-11-14 13:44 ` [PATCH 08/22] monitor/avdtp: Decode AVDTP_OPEN Andrzej Kaczmarek
2015-11-14 13:44 ` [PATCH 09/22] monitor/avdtp: Decode AVDTP_START Andrzej Kaczmarek
2015-11-14 13:44 ` [PATCH 10/22] monitor/avdtp: Decode AVDTP_CLOSE Andrzej Kaczmarek
2015-11-14 13:44 ` [PATCH 11/22] monitor/avdtp: Decode AVDTP_SUSPEND Andrzej Kaczmarek
2015-11-14 13:44 ` [PATCH 12/22] monitor/avdtp: Decode AVDTP_ABORT Andrzej Kaczmarek
2015-11-14 13:44 ` [PATCH 13/22] monitor/avdtp: Decode AVDTP_SECURITY_CONTROL Andrzej Kaczmarek
2015-11-14 13:44 ` [PATCH 14/22] monitor/avdtp: Decode AVDTP_GET_ALL_CAPABILITIES Andrzej Kaczmarek
2015-11-14 13:44 ` [PATCH 15/22] monitor/avdtp: Decode AVDTP_DELAYREPORT Andrzej Kaczmarek
2015-11-14 13:44 ` [PATCH 16/22] monitor/avdtp: Decode basic Media Codec capabilities Andrzej Kaczmarek
2015-11-14 13:44 ` [PATCH 17/22] monitor/avdtp: Decode basic Content Protection capabilities Andrzej Kaczmarek
2015-11-14 13:44 ` [PATCH 18/22] monitor/a2dp: Decode SBC capabilities Andrzej Kaczmarek
2015-11-14 13:44 ` [PATCH 19/22] monitor/a2dp: Decode MPEG-1,2 capabilities Andrzej Kaczmarek
2015-11-14 13:44 ` [PATCH 20/22] monitor/a2dp: Decode AAC capabilities Andrzej Kaczmarek
2015-11-14 13:44 ` [PATCH 21/22] monitor/a2dp: Decode aptX capabilities Andrzej Kaczmarek
2015-11-14 13:44 ` [PATCH 22/22] monitor/a2dp: Decode LDAC capabilities Andrzej Kaczmarek
2015-11-17  8:33 ` [PATCH 00/22] Add AVDTP/A2DP decoding to btmon Luiz Augusto von Dentz
2015-11-17  8:40   ` Marcel Holtmann
2015-11-17  9:11     ` Andrzej Kaczmarek
2015-11-17 14:06       ` Luiz Augusto von Dentz
2015-11-17 21:22         ` Andrzej Kaczmarek
2015-11-17  9:06   ` Andrzej Kaczmarek

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.