Linux-Bluetooth Archive on lore.kernel.org
 help / Atom feed
* [PATCH 00/10] A2DP: Fix endianity and define new A2DP codecs
@ 2018-12-19 16:50 Pali Rohár
  2018-12-19 16:51 ` [PATCH 01/10] avinfo: Fix buffer overflow when parsing broken/malicious data Pali Rohár
                   ` (11 more replies)
  0 siblings, 12 replies; 26+ messages in thread
From: Pali Rohár @ 2018-12-19 16:50 UTC (permalink / raw)
  To: linux-bluetooth

This patch series try to fix endianity problems in a2dp-codecs.h file,
then fixes parsing MPEG bit rate values, extend a2dp-codecs.h file for
new A2DP codecs FastStream, aptX Low Latency, aptX HD and finally adds
support for parsing information about FastStream, aptX Low Latency,
aptX HD and LDAC codecs in avinfo utility.

Pali Rohár (10):
  avinfo: Fix buffer overflow when parsing broken/malicious data
  avinfo: Show Vendor Specific Data
  a2dp-codecs: Add SBC prefix for MIN/MAX_BITPOOL constants
  a2dp-codecs: Fix codec id for ATRAC
  a2dp-codecs & avinfo: Fix parsing MPEG bit rate values
  a2dp-codecs: Define a2dp_vendor_codec_t struct in endian neutral way
  a2dp-codecs: Add needed includes and properly check for endian macros
  a2dp-codecs: Properly define macros and struct for LDAC codec
  a2dp-codecs: Add macros and structures for FastStream, aptX Low
    Latency and aptX HD codecs
  avinfo: Parse information about A2DP codecs: FastStream, aptX Low
    Latency, aptX HD and LDAC

 android/a2dp.c               |   8 +-
 android/avdtp.c              |   4 +-
 android/hal-audio-aptx.c     |  15 +-
 android/hal-audio-sbc.c      |  12 +-
 profiles/audio/a2dp-codecs.h | 256 ++++++++++++++++++++++++++----
 profiles/audio/a2dp.c        |   8 +-
 tools/avinfo.c               | 362 ++++++++++++++++++++++++++++++++++++-------
 7 files changed, 551 insertions(+), 114 deletions(-)

-- 
2.11.0


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

* [PATCH 01/10] avinfo: Fix buffer overflow when parsing broken/malicious data
  2018-12-19 16:50 [PATCH 00/10] A2DP: Fix endianity and define new A2DP codecs Pali Rohár
@ 2018-12-19 16:51 ` Pali Rohár
  2018-12-19 16:51 ` [PATCH 02/10] avinfo: Show Vendor Specific Data Pali Rohár
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2018-12-19 16:51 UTC (permalink / raw)
  To: linux-bluetooth

---
 tools/avinfo.c | 89 +++++++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 69 insertions(+), 20 deletions(-)

diff --git a/tools/avinfo.c b/tools/avinfo.c
index 31c4e106e..a7a61b881 100644
--- a/tools/avinfo.c
+++ b/tools/avinfo.c
@@ -167,10 +167,15 @@ struct avdtp_content_protection_capability {
 	uint8_t data[0];
 } __attribute__ ((packed));
 
-static void print_aptx(a2dp_aptx_t *aptx)
+static void print_aptx(a2dp_aptx_t *aptx, uint8_t size)
 {
 	printf("\t\tVendor Specific Value (aptX)");
 
+	if (size < sizeof(*aptx)) {
+		printf(" (broken)\n");
+		return;
+	}
+
 	printf("\n\t\t\tFrequencies: ");
 	if (aptx->frequency & APTX_SAMPLING_FREQ_16000)
 		printf("16kHz ");
@@ -190,20 +195,34 @@ static void print_aptx(a2dp_aptx_t *aptx)
 	printf("\n");
 }
 
-static void print_ldac(a2dp_ldac_t *ldac)
+static void print_ldac(a2dp_ldac_t *ldac, uint8_t size)
 {
 	printf("\t\tVendor Specific Value (LDAC)");
 
+	if (size < sizeof(*ldac)) {
+		printf(" (broken)\n");
+		return;
+	}
+
 	printf("\n\t\t\tUnknown: %02x %02x", ldac->unknown[0],
 							ldac->unknown[1]);
 
 	printf("\n");
 }
 
-static void print_vendor(a2dp_vendor_codec_t *vendor)
+static void print_vendor(a2dp_vendor_codec_t *vendor, uint8_t size)
 {
-	uint32_t vendor_id = btohl(vendor->vendor_id);
-	uint16_t codec_id = btohs(vendor->codec_id);
+	uint32_t vendor_id;
+	uint16_t codec_id;
+	uint8_t i;
+
+	if (size < sizeof(*vendor)) {
+		printf("\tMedia Codec: Vendor Specific A2DP Codec (broken)");
+		return;
+	}
+
+	vendor_id = btohl(vendor->vendor_id);
+	codec_id = btohs(vendor->codec_id);
 
 	printf("\tMedia Codec: Vendor Specific A2DP Codec");
 
@@ -212,15 +231,22 @@ static void print_vendor(a2dp_vendor_codec_t *vendor)
 	printf("\n\t\tVendor Specific Codec ID 0x%04x\n", codec_id);
 
 	if (vendor_id == APTX_VENDOR_ID && codec_id == APTX_CODEC_ID)
-		print_aptx((void *) vendor);
+		print_aptx((void *) vendor, size);
 	else if (vendor_id == LDAC_VENDOR_ID && codec_id == LDAC_CODEC_ID)
-		print_ldac((void *) vendor);
+		print_ldac((void *) vendor, size);
 }
 
-static void print_mpeg24(a2dp_aac_t *aac)
+static void print_mpeg24(a2dp_aac_t *aac, uint8_t size)
 {
-	unsigned freq = AAC_GET_FREQUENCY(*aac);
-	unsigned bitrate = AAC_GET_BITRATE(*aac);
+	unsigned freq, bitrate;
+
+	if (size < sizeof(*aac)) {
+		printf("\tMedia Codec: MPEG24 (broken)\n");
+		return;
+	}
+
+	freq = AAC_GET_FREQUENCY(*aac);
+	bitrate = AAC_GET_BITRATE(*aac);
 
 	printf("\tMedia Codec: MPEG24\n\t\tObject Types: ");
 
@@ -270,8 +296,13 @@ static void print_mpeg24(a2dp_aac_t *aac)
 	printf("\n\t\tVBR: %s", aac->vbr ? "Yes\n" : "No\n");
 }
 
-static void print_mpeg12(a2dp_mpeg_t *mpeg)
+static void print_mpeg12(a2dp_mpeg_t *mpeg, uint8_t size)
 {
+	if (size < sizeof(*mpeg)) {
+		printf("\tMedia Codec: MPEG12 (broken)\n");
+		return;
+	}
+
 	printf("\tMedia Codec: MPEG12\n\t\tChannel Modes: ");
 
 	if (mpeg->channel_mode & MPEG_CHANNEL_MODE_MONO)
@@ -351,8 +382,13 @@ static void print_mpeg12(a2dp_mpeg_t *mpeg)
 		printf("RFC-2250\n");
 }
 
-static void print_sbc(a2dp_sbc_t *sbc)
+static void print_sbc(a2dp_sbc_t *sbc, uint8_t size)
 {
+	if (size < sizeof(*sbc)) {
+		printf("\tMedia Codec: SBC (broken)\n");
+		return;
+	}
+
 	printf("\tMedia Codec: SBC\n\t\tChannel Modes: ");
 
 	if (sbc->channel_mode & SBC_CHANNEL_MODE_MONO)
@@ -394,20 +430,25 @@ static void print_sbc(a2dp_sbc_t *sbc)
 				sbc->min_bitpool, sbc->max_bitpool);
 }
 
-static void print_media_codec(struct avdtp_media_codec_capability *cap)
+static void print_media_codec(struct avdtp_media_codec_capability *cap, uint8_t size)
 {
+	if (size < sizeof(*cap)) {
+		printf("\tMedia Codec: Unknown (broken)\n");
+		return;
+	}
+
 	switch (cap->media_codec_type) {
 	case A2DP_CODEC_SBC:
-		print_sbc((void *) cap->data);
+		print_sbc((void *) cap->data, size - 2);
 		break;
 	case A2DP_CODEC_MPEG12:
-		print_mpeg12((void *) cap->data);
+		print_mpeg12((void *) cap->data, size - 2);
 		break;
 	case A2DP_CODEC_MPEG24:
-		print_mpeg24((void *) cap->data);
+		print_mpeg24((void *) cap->data, size - 2);
 		break;
 	case A2DP_CODEC_VENDOR:
-		print_vendor((void *) cap->data);
+		print_vendor((void *) cap->data, size - 2);
 		break;
 	default:
 		printf("\tMedia Codec: Unknown\n");
@@ -415,10 +456,16 @@ static void print_media_codec(struct avdtp_media_codec_capability *cap)
 }
 
 static void print_content_protection(
-				struct avdtp_content_protection_capability *cap)
+				struct avdtp_content_protection_capability *cap,
+				uint8_t size)
 {
 	printf("\tContent Protection: ");
 
+	if (size < sizeof(*cap)) {
+		printf("Unknown (broken)\n");
+		return;
+	}
+
 	switch (btohs(cap->content_protection_type)) {
 	case AVDTP_CONTENT_PROTECTION_TYPE_DTCP:
 		printf("DTCP");
@@ -452,13 +499,15 @@ static void print_caps(void *data, int size)
 		case AVDTP_REPORTING:
 		case AVDTP_RECOVERY:
 		case AVDTP_MULTIPLEXING:
+		default:
 			/* FIXME: Add proper functions */
+			printf("\tUnknown category: %d\n", cap->category);
 			break;
 		case AVDTP_MEDIA_CODEC:
-			print_media_codec((void *) cap->data);
+			print_media_codec((void *) cap->data, cap->length);
 			break;
 		case AVDTP_CONTENT_PROTECTION:
-			print_content_protection((void *) cap->data);
+			print_content_protection((void *) cap->data, cap->length);
 			break;
 		}
 
-- 
2.11.0


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

* [PATCH 02/10] avinfo: Show Vendor Specific Data
  2018-12-19 16:50 [PATCH 00/10] A2DP: Fix endianity and define new A2DP codecs Pali Rohár
  2018-12-19 16:51 ` [PATCH 01/10] avinfo: Fix buffer overflow when parsing broken/malicious data Pali Rohár
@ 2018-12-19 16:51 ` Pali Rohár
  2018-12-19 16:51 ` [PATCH 03/10] a2dp-codecs: Add SBC prefix for MIN/MAX_BITPOOL constants Pali Rohár
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2018-12-19 16:51 UTC (permalink / raw)
  To: linux-bluetooth

---
 tools/avinfo.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/tools/avinfo.c b/tools/avinfo.c
index a7a61b881..1f7c68d4b 100644
--- a/tools/avinfo.c
+++ b/tools/avinfo.c
@@ -228,7 +228,12 @@ static void print_vendor(a2dp_vendor_codec_t *vendor, uint8_t size)
 
 	printf("\n\t\tVendor ID 0x%08x", vendor_id);
 
-	printf("\n\t\tVendor Specific Codec ID 0x%04x\n", codec_id);
+	printf("\n\t\tVendor Specific Codec ID 0x%04x", codec_id);
+
+	printf("\n\t\tVendor Specific Data:");
+	for (i = 6; i < size; ++i)
+		printf(" 0x%.02x", ((unsigned char *)vendor)[i]);
+	printf("\n");
 
 	if (vendor_id == APTX_VENDOR_ID && codec_id == APTX_CODEC_ID)
 		print_aptx((void *) vendor, size);
-- 
2.11.0


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

* [PATCH 03/10] a2dp-codecs: Add SBC prefix for MIN/MAX_BITPOOL constants
  2018-12-19 16:50 [PATCH 00/10] A2DP: Fix endianity and define new A2DP codecs Pali Rohár
  2018-12-19 16:51 ` [PATCH 01/10] avinfo: Fix buffer overflow when parsing broken/malicious data Pali Rohár
  2018-12-19 16:51 ` [PATCH 02/10] avinfo: Show Vendor Specific Data Pali Rohár
@ 2018-12-19 16:51 ` Pali Rohár
  2018-12-19 16:51 ` [PATCH 04/10] a2dp-codecs: Fix codec id for ATRAC Pali Rohár
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2018-12-19 16:51 UTC (permalink / raw)
  To: linux-bluetooth

Those two constants are SBC codec specific.
---
 android/hal-audio-sbc.c      | 12 ++++++------
 profiles/audio/a2dp-codecs.h |  4 ++--
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/android/hal-audio-sbc.c b/android/hal-audio-sbc.c
index 9da9575f5..80e271ed6 100644
--- a/android/hal-audio-sbc.c
+++ b/android/hal-audio-sbc.c
@@ -91,8 +91,8 @@ static const a2dp_sbc_t sbc_presets[] = {
 					SBC_ALLOCATION_LOUDNESS,
 		.block_length = SBC_BLOCK_LENGTH_4 | SBC_BLOCK_LENGTH_8 |
 				SBC_BLOCK_LENGTH_12 | SBC_BLOCK_LENGTH_16,
-		.min_bitpool = MIN_BITPOOL,
-		.max_bitpool = MAX_BITPOOL
+		.min_bitpool = SBC_MIN_BITPOOL,
+		.max_bitpool = SBC_MAX_BITPOOL
 	},
 	{
 		.frequency = SBC_SAMPLING_FREQ_44100,
@@ -100,8 +100,8 @@ static const a2dp_sbc_t sbc_presets[] = {
 		.subbands = SBC_SUBBANDS_8,
 		.allocation_method = SBC_ALLOCATION_LOUDNESS,
 		.block_length = SBC_BLOCK_LENGTH_16,
-		.min_bitpool = MIN_BITPOOL,
-		.max_bitpool = MAX_BITPOOL
+		.min_bitpool = SBC_MIN_BITPOOL,
+		.max_bitpool = SBC_MAX_BITPOOL
 	},
 	{
 		.frequency = SBC_SAMPLING_FREQ_48000,
@@ -109,8 +109,8 @@ static const a2dp_sbc_t sbc_presets[] = {
 		.subbands = SBC_SUBBANDS_8,
 		.allocation_method = SBC_ALLOCATION_LOUDNESS,
 		.block_length = SBC_BLOCK_LENGTH_16,
-		.min_bitpool = MIN_BITPOOL,
-		.max_bitpool = MAX_BITPOOL
+		.min_bitpool = SBC_MIN_BITPOOL,
+		.max_bitpool = SBC_MAX_BITPOOL
 	},
 };
 
diff --git a/profiles/audio/a2dp-codecs.h b/profiles/audio/a2dp-codecs.h
index 4fb5c0cc9..205491939 100644
--- a/profiles/audio/a2dp-codecs.h
+++ b/profiles/audio/a2dp-codecs.h
@@ -49,8 +49,8 @@
 #define SBC_ALLOCATION_SNR		(1 << 1)
 #define SBC_ALLOCATION_LOUDNESS		1
 
-#define MAX_BITPOOL 64
-#define MIN_BITPOOL 2
+#define SBC_MAX_BITPOOL			64
+#define SBC_MIN_BITPOOL			2
 
 #define MPEG_CHANNEL_MODE_MONO		(1 << 3)
 #define MPEG_CHANNEL_MODE_DUAL_CHANNEL	(1 << 2)
-- 
2.11.0


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

* [PATCH 04/10] a2dp-codecs: Fix codec id for ATRAC
  2018-12-19 16:50 [PATCH 00/10] A2DP: Fix endianity and define new A2DP codecs Pali Rohár
                   ` (2 preceding siblings ...)
  2018-12-19 16:51 ` [PATCH 03/10] a2dp-codecs: Add SBC prefix for MIN/MAX_BITPOOL constants Pali Rohár
@ 2018-12-19 16:51 ` Pali Rohár
  2018-12-19 16:51 ` [PATCH 05/10] a2dp-codecs & avinfo: Fix parsing MPEG bit rate values Pali Rohár
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2018-12-19 16:51 UTC (permalink / raw)
  To: linux-bluetooth

According to Bluetooth Assigned Numbers for Audio/Video, ATRAC has codec id 0x04.
See: https://www.bluetooth.com/specifications/assigned-numbers/audio-video
---
 profiles/audio/a2dp-codecs.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/profiles/audio/a2dp-codecs.h b/profiles/audio/a2dp-codecs.h
index 205491939..25959902c 100644
--- a/profiles/audio/a2dp-codecs.h
+++ b/profiles/audio/a2dp-codecs.h
@@ -25,7 +25,7 @@
 #define A2DP_CODEC_SBC			0x00
 #define A2DP_CODEC_MPEG12		0x01
 #define A2DP_CODEC_MPEG24		0x02
-#define A2DP_CODEC_ATRAC		0x03
+#define A2DP_CODEC_ATRAC		0x04
 #define A2DP_CODEC_VENDOR		0xFF
 
 #define SBC_SAMPLING_FREQ_16000		(1 << 3)
-- 
2.11.0


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

* [PATCH 05/10] a2dp-codecs & avinfo: Fix parsing MPEG bit rate values
  2018-12-19 16:50 [PATCH 00/10] A2DP: Fix endianity and define new A2DP codecs Pali Rohár
                   ` (3 preceding siblings ...)
  2018-12-19 16:51 ` [PATCH 04/10] a2dp-codecs: Fix codec id for ATRAC Pali Rohár
@ 2018-12-19 16:51 ` Pali Rohár
  2018-12-19 16:51 ` [PATCH 06/10] a2dp-codecs: Define a2dp_vendor_codec_t struct in endian neutral way Pali Rohár
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2018-12-19 16:51 UTC (permalink / raw)
  To: linux-bluetooth

Redefine bitrate field in a2dp_mpeg_t struct in endian neutral way and
separate vbr field according to A2DP specification. Define new macros
MPEG_GET_BITRATE() and MPEG_SET_BITRATE() for manipulating with bitrate
like for a2dp_aac_t struct.

And fix meaning of bitrate field. According to A2DP specification, it is
bitrate index, not bitrate itself. According to MPEG specification, each
MPEG layer have different bitrates for bitrate indexes. Therefore define
correctly bitrates for Layers 1, 2 and 3.

This fixes problems with parsing bitrate field in a2dp_mpeg_t struct as it
was broken due to endianity and it was broken for Layer 1 and 2 as bitrate
definitions was for Layer 3.
---
 profiles/audio/a2dp-codecs.h |  89 ++++++++++++++++++++++------
 tools/avinfo.c               | 135 ++++++++++++++++++++++++++++++++-----------
 2 files changed, 172 insertions(+), 52 deletions(-)

diff --git a/profiles/audio/a2dp-codecs.h b/profiles/audio/a2dp-codecs.h
index 25959902c..64a09796d 100644
--- a/profiles/audio/a2dp-codecs.h
+++ b/profiles/audio/a2dp-codecs.h
@@ -68,22 +68,71 @@
 #define MPEG_SAMPLING_FREQ_44100	(1 << 1)
 #define MPEG_SAMPLING_FREQ_48000	1
 
-#define MPEG_BIT_RATE_VBR		0x8000
-#define MPEG_BIT_RATE_320000		0x4000
-#define MPEG_BIT_RATE_256000		0x2000
-#define MPEG_BIT_RATE_224000		0x1000
-#define MPEG_BIT_RATE_192000		0x0800
-#define MPEG_BIT_RATE_160000		0x0400
-#define MPEG_BIT_RATE_128000		0x0200
-#define MPEG_BIT_RATE_112000		0x0100
-#define MPEG_BIT_RATE_96000		0x0080
-#define MPEG_BIT_RATE_80000		0x0040
-#define MPEG_BIT_RATE_64000		0x0020
-#define MPEG_BIT_RATE_56000		0x0010
-#define MPEG_BIT_RATE_48000		0x0008
-#define MPEG_BIT_RATE_40000		0x0004
-#define MPEG_BIT_RATE_32000		0x0002
-#define MPEG_BIT_RATE_FREE		0x0001
+#define MPEG_BIT_RATE_INDEX_0		(1 << 0)
+#define MPEG_BIT_RATE_INDEX_1		(1 << 1)
+#define MPEG_BIT_RATE_INDEX_2		(1 << 2)
+#define MPEG_BIT_RATE_INDEX_3		(1 << 3)
+#define MPEG_BIT_RATE_INDEX_4		(1 << 4)
+#define MPEG_BIT_RATE_INDEX_5		(1 << 5)
+#define MPEG_BIT_RATE_INDEX_6		(1 << 6)
+#define MPEG_BIT_RATE_INDEX_7		(1 << 7)
+#define MPEG_BIT_RATE_INDEX_8		(1 << 8)
+#define MPEG_BIT_RATE_INDEX_9		(1 << 9)
+#define MPEG_BIT_RATE_INDEX_10		(1 << 10)
+#define MPEG_BIT_RATE_INDEX_11		(1 << 11)
+#define MPEG_BIT_RATE_INDEX_12		(1 << 12)
+#define MPEG_BIT_RATE_INDEX_13		(1 << 13)
+#define MPEG_BIT_RATE_INDEX_14		(1 << 14)
+
+#define MPEG_MP1_BIT_RATE_32000		MPEG_BIT_RATE_INDEX_1
+#define MPEG_MP1_BIT_RATE_64000		MPEG_BIT_RATE_INDEX_2
+#define MPEG_MP1_BIT_RATE_96000		MPEG_BIT_RATE_INDEX_3
+#define MPEG_MP1_BIT_RATE_128000	MPEG_BIT_RATE_INDEX_4
+#define MPEG_MP1_BIT_RATE_160000	MPEG_BIT_RATE_INDEX_5
+#define MPEG_MP1_BIT_RATE_192000	MPEG_BIT_RATE_INDEX_6
+#define MPEG_MP1_BIT_RATE_224000	MPEG_BIT_RATE_INDEX_7
+#define MPEG_MP1_BIT_RATE_256000	MPEG_BIT_RATE_INDEX_8
+#define MPEG_MP1_BIT_RATE_288000	MPEG_BIT_RATE_INDEX_9
+#define MPEG_MP1_BIT_RATE_320000	MPEG_BIT_RATE_INDEX_10
+#define MPEG_MP1_BIT_RATE_352000	MPEG_BIT_RATE_INDEX_11
+#define MPEG_MP1_BIT_RATE_384000	MPEG_BIT_RATE_INDEX_12
+#define MPEG_MP1_BIT_RATE_416000	MPEG_BIT_RATE_INDEX_13
+#define MPEG_MP1_BIT_RATE_448000	MPEG_BIT_RATE_INDEX_14
+
+#define MPEG_MP2_BIT_RATE_32000		MPEG_BIT_RATE_INDEX_1
+#define MPEG_MP2_BIT_RATE_48000		MPEG_BIT_RATE_INDEX_2
+#define MPEG_MP2_BIT_RATE_56000		MPEG_BIT_RATE_INDEX_3
+#define MPEG_MP2_BIT_RATE_64000		MPEG_BIT_RATE_INDEX_4
+#define MPEG_MP2_BIT_RATE_80000		MPEG_BIT_RATE_INDEX_5
+#define MPEG_MP2_BIT_RATE_96000		MPEG_BIT_RATE_INDEX_6
+#define MPEG_MP2_BIT_RATE_112000	MPEG_BIT_RATE_INDEX_7
+#define MPEG_MP2_BIT_RATE_128000	MPEG_BIT_RATE_INDEX_8
+#define MPEG_MP2_BIT_RATE_160000	MPEG_BIT_RATE_INDEX_9
+#define MPEG_MP2_BIT_RATE_192000	MPEG_BIT_RATE_INDEX_10
+#define MPEG_MP2_BIT_RATE_224000	MPEG_BIT_RATE_INDEX_11
+#define MPEG_MP2_BIT_RATE_256000	MPEG_BIT_RATE_INDEX_12
+#define MPEG_MP2_BIT_RATE_320000	MPEG_BIT_RATE_INDEX_13
+#define MPEG_MP2_BIT_RATE_384000	MPEG_BIT_RATE_INDEX_14
+
+#define MPEG_MP3_BIT_RATE_32000		MPEG_BIT_RATE_INDEX_1
+#define MPEG_MP3_BIT_RATE_40000		MPEG_BIT_RATE_INDEX_2
+#define MPEG_MP3_BIT_RATE_48000		MPEG_BIT_RATE_INDEX_3
+#define MPEG_MP3_BIT_RATE_56000		MPEG_BIT_RATE_INDEX_4
+#define MPEG_MP3_BIT_RATE_64000		MPEG_BIT_RATE_INDEX_5
+#define MPEG_MP3_BIT_RATE_80000		MPEG_BIT_RATE_INDEX_6
+#define MPEG_MP3_BIT_RATE_96000		MPEG_BIT_RATE_INDEX_7
+#define MPEG_MP3_BIT_RATE_112000	MPEG_BIT_RATE_INDEX_8
+#define MPEG_MP3_BIT_RATE_128000	MPEG_BIT_RATE_INDEX_9
+#define MPEG_MP3_BIT_RATE_160000	MPEG_BIT_RATE_INDEX_10
+#define MPEG_MP3_BIT_RATE_192000	MPEG_BIT_RATE_INDEX_11
+#define MPEG_MP3_BIT_RATE_224000	MPEG_BIT_RATE_INDEX_12
+#define MPEG_MP3_BIT_RATE_256000	MPEG_BIT_RATE_INDEX_13
+#define MPEG_MP3_BIT_RATE_320000	MPEG_BIT_RATE_INDEX_14
+
+#define MPEG_BIT_RATE_FREE		MPEG_BIT_RATE_INDEX_0
+
+#define MPEG_GET_BITRATE(a) ((uint16_t)(a).bitrate1 << 8 | (a).bitrate2)
+#define MPEG_SET_BITRATE(a, b) do { (a).bitrate1 = ((b) >> 8) & 0x7f; (a).bitrate2 = (b) & 0xff; } while (0)
 
 #define AAC_OBJECT_TYPE_MPEG2_AAC_LC	0x80
 #define AAC_OBJECT_TYPE_MPEG4_AAC_LC	0x40
@@ -168,7 +217,9 @@ typedef struct {
 	uint8_t frequency:6;
 	uint8_t mpf:1;
 	uint8_t rfa:1;
-	uint16_t bitrate;
+	uint8_t bitrate1:7;
+	uint8_t vbr:1;
+	uint8_t bitrate2;
 } __attribute__ ((packed)) a2dp_mpeg_t;
 
 typedef struct {
@@ -213,7 +264,9 @@ typedef struct {
 	uint8_t rfa:1;
 	uint8_t mpf:1;
 	uint8_t frequency:6;
-	uint16_t bitrate;
+	uint8_t vbr:1;
+	uint8_t bitrate1:7;
+	uint8_t bitrate2;
 } __attribute__ ((packed)) a2dp_mpeg_t;
 
 typedef struct {
diff --git a/tools/avinfo.c b/tools/avinfo.c
index 1f7c68d4b..ca0f12067 100644
--- a/tools/avinfo.c
+++ b/tools/avinfo.c
@@ -303,11 +303,15 @@ static void print_mpeg24(a2dp_aac_t *aac, uint8_t size)
 
 static void print_mpeg12(a2dp_mpeg_t *mpeg, uint8_t size)
 {
+	uint16_t bitrate;
+
 	if (size < sizeof(*mpeg)) {
 		printf("\tMedia Codec: MPEG12 (broken)\n");
 		return;
 	}
 
+	bitrate = MPEG_GET_BITRATE(*mpeg);
+
 	printf("\tMedia Codec: MPEG12\n\t\tChannel Modes: ");
 
 	if (mpeg->channel_mode & MPEG_CHANNEL_MODE_MONO)
@@ -343,42 +347,105 @@ static void print_mpeg12(a2dp_mpeg_t *mpeg, uint8_t size)
 	if (mpeg->layer & MPEG_LAYER_MP3)
 		printf("3 ");
 
-	printf("\n\t\tBit Rate: ");
-	if (mpeg->bitrate & MPEG_BIT_RATE_FREE)
-		printf("Free format");
-	else {
-		if (mpeg->bitrate & MPEG_BIT_RATE_32000)
-			printf("32kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_40000)
-			printf("40kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_48000)
-			printf("48kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_56000)
-			printf("56kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_64000)
-			printf("64kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_80000)
-			printf("80kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_96000)
-			printf("96kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_112000)
-			printf("112kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_128000)
-			printf("128kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_160000)
-			printf("160kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_192000)
-			printf("192kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_224000)
-			printf("224kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_256000)
-			printf("256kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_320000)
-			printf("320kbps ");
+	if (bitrate & MPEG_BIT_RATE_FREE) {
+		printf("\n\t\tBit Rate: Free format");
+	} else {
+		if (mpeg->layer & MPEG_LAYER_MP1) {
+			printf("\n\t\tLayer 1 Bit Rate: ");
+			if (bitrate & MPEG_MP1_BIT_RATE_32000)
+				printf("32kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_64000)
+				printf("64kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_96000)
+				printf("96kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_128000)
+				printf("128kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_160000)
+				printf("160kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_192000)
+				printf("192kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_224000)
+				printf("224kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_256000)
+				printf("256kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_320000)
+				printf("320kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_352000)
+				printf("352kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_384000)
+				printf("384kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_416000)
+				printf("416kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_448000)
+				printf("448kbps ");
+		}
+
+		if (mpeg->layer & MPEG_LAYER_MP2) {
+			printf("\n\t\tLayer 2 Bit Rate: ");
+			if (bitrate & MPEG_MP2_BIT_RATE_32000)
+				printf("32kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_48000)
+				printf("48kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_56000)
+				printf("56kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_64000)
+				printf("64kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_80000)
+				printf("80kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_96000)
+				printf("96kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_112000)
+				printf("112kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_128000)
+				printf("128kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_160000)
+				printf("160kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_192000)
+				printf("192kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_224000)
+				printf("224kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_256000)
+				printf("256kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_320000)
+				printf("320kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_384000)
+				printf("384kbps ");
+		}
+
+		if (mpeg->layer & MPEG_LAYER_MP3) {
+			printf("\n\t\tLayer 3 Bit Rate: ");
+			if (bitrate & MPEG_MP3_BIT_RATE_32000)
+				printf("32kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_40000)
+				printf("40kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_48000)
+				printf("48kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_56000)
+				printf("56kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_64000)
+				printf("64kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_80000)
+				printf("80kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_96000)
+				printf("96kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_112000)
+				printf("112kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_128000)
+				printf("128kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_160000)
+				printf("160kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_192000)
+				printf("192kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_224000)
+				printf("224kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_256000)
+				printf("256kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_320000)
+				printf("320kbps ");
+		}
 	}
 
-	printf("\n\t\tVBR: %s", mpeg->bitrate & MPEG_BIT_RATE_VBR ? "Yes" :
-		"No");
+	printf("\n\t\tVBR: %s", mpeg->vbr ? "Yes" : "No");
 
 	printf("\n\t\tPayload Format: ");
 	if (mpeg->mpf)
-- 
2.11.0


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

* [PATCH 06/10] a2dp-codecs: Define a2dp_vendor_codec_t struct in endian neutral way
  2018-12-19 16:50 [PATCH 00/10] A2DP: Fix endianity and define new A2DP codecs Pali Rohár
                   ` (4 preceding siblings ...)
  2018-12-19 16:51 ` [PATCH 05/10] a2dp-codecs & avinfo: Fix parsing MPEG bit rate values Pali Rohár
@ 2018-12-19 16:51 ` Pali Rohár
  2018-12-19 16:51 ` [PATCH 07/10] a2dp-codecs: Add needed includes and properly check for endian macros Pali Rohár
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2018-12-19 16:51 UTC (permalink / raw)
  To: linux-bluetooth

And define new macros A2DP_GET_VENDOR_ID(), A2DP_GET_CODEC_ID() and
A2DP_SET_VENDOR_ID_CODEC_ID() for easily filling a2dp_vendor_codec_t
struct.
---
 android/a2dp.c               |  8 ++++----
 android/avdtp.c              |  4 ++--
 android/hal-audio-aptx.c     | 15 +++------------
 profiles/audio/a2dp-codecs.h | 19 +++++++++++++++++--
 profiles/audio/a2dp.c        |  8 ++++----
 tools/avinfo.c               |  4 ++--
 6 files changed, 32 insertions(+), 26 deletions(-)

diff --git a/android/a2dp.c b/android/a2dp.c
index f21904208..8bcdfd20f 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -417,8 +417,8 @@ static int check_capabilities(struct a2dp_preset *preset,
 								preset->len);
 	case A2DP_CODEC_VENDOR:
 		vndcodec = (void *) codec->data;
-		if (btohl(vndcodec->vendor_id) == APTX_VENDOR_ID &&
-				btohs(vndcodec->codec_id) == APTX_CODEC_ID)
+		if (A2DP_GET_VENDOR_ID(*vndcodec) == APTX_VENDOR_ID &&
+				A2DP_GET_CODEC_ID(*vndcodec) == APTX_CODEC_ID)
 			return aptx_check_config(codec->data, codec_len,
 						preset->data, preset->len);
 		return -EINVAL;
@@ -1344,8 +1344,8 @@ static uint8_t register_endpoint(const uint8_t *uuid, uint8_t codec,
 		a2dp_vendor_codec_t *vndcodec = (void *) endpoint->caps->data;
 
 		avdtp_sep_set_vendor_codec(endpoint->sep,
-						btohl(vndcodec->vendor_id),
-						btohs(vndcodec->codec_id));
+						A2DP_GET_VENDOR_ID(*vndcodec),
+						A2DP_GET_CODEC_ID(*vndcodec));
 	}
 
 	endpoints = g_slist_append(endpoints, endpoint);
diff --git a/android/avdtp.c b/android/avdtp.c
index 34caf3db5..88fbef85a 100644
--- a/android/avdtp.c
+++ b/android/avdtp.c
@@ -1103,10 +1103,10 @@ struct avdtp_remote_sep *avdtp_find_remote_sep(struct avdtp *session,
 			a2dp_vendor_codec_t *vndcodec =
 						(void *) codec_data->data;
 
-			if (btohl(vndcodec->vendor_id) != lsep->vndcodec_vendor)
+			if (A2DP_GET_VENDOR_ID(*vndcodec) != lsep->vndcodec_vendor)
 				continue;
 
-			if (btohs(vndcodec->codec_id) != lsep->vndcodec_codec)
+			if (A2DP_GET_CODEC_ID(*vndcodec) != lsep->vndcodec_codec)
 				continue;
 		}
 
diff --git a/android/hal-audio-aptx.c b/android/hal-audio-aptx.c
index bff2331a9..3453b49a4 100644
--- a/android/hal-audio-aptx.c
+++ b/android/hal-audio-aptx.c
@@ -37,27 +37,18 @@ struct aptx_data {
 
 static const a2dp_aptx_t aptx_presets[] = {
 	{
-		.info = {
-			.vendor_id = APTX_VENDOR_ID,
-			.codec_id = APTX_CODEC_ID,
-		},
+		.info = A2DP_SET_VENDOR_ID_CODEC_ID(APTX_VENDOR_ID, APTX_CODEC_ID),
 		.frequency = APTX_SAMPLING_FREQ_44100 |
 						APTX_SAMPLING_FREQ_48000,
 		.channel_mode = APTX_CHANNEL_MODE_STEREO,
 	},
 	{
-		.info = {
-			.vendor_id = APTX_VENDOR_ID,
-			.codec_id = APTX_CODEC_ID,
-		},
+		.info = A2DP_SET_VENDOR_ID_CODEC_ID(APTX_VENDOR_ID, APTX_CODEC_ID),
 		.frequency = APTX_SAMPLING_FREQ_48000,
 		.channel_mode = APTX_CHANNEL_MODE_STEREO,
 	},
 	{
-		.info = {
-			.vendor_id = APTX_VENDOR_ID,
-			.codec_id = APTX_CODEC_ID,
-		},
+		.info = A2DP_SET_VENDOR_ID_CODEC_ID(APTX_VENDOR_ID, APTX_CODEC_ID),
 		.frequency = APTX_SAMPLING_FREQ_44100,
 		.channel_mode = APTX_CHANNEL_MODE_STEREO,
 	},
diff --git a/profiles/audio/a2dp-codecs.h b/profiles/audio/a2dp-codecs.h
index 64a09796d..43a5eef97 100644
--- a/profiles/audio/a2dp-codecs.h
+++ b/profiles/audio/a2dp-codecs.h
@@ -194,10 +194,25 @@
 #define LDAC_CODEC_ID			0x00aa
 
 typedef struct {
-	uint32_t vendor_id;
-	uint16_t codec_id;
+	uint8_t vendor_id4;
+	uint8_t vendor_id3;
+	uint8_t vendor_id2;
+	uint8_t vendor_id1;
+	uint8_t codec_id2;
+	uint8_t codec_id1;
 } __attribute__ ((packed)) a2dp_vendor_codec_t;
 
+#define A2DP_GET_VENDOR_ID(a) ((a).vendor_id4 | (((uint32_t)(a).vendor_id3) << 8) | (((uint32_t)(a).vendor_id2) << 16) | (((uint32_t)(a).vendor_id1) << 24))
+#define A2DP_GET_CODEC_ID(a) ((a).codec_id2 | (((uint16_t)(a).codec_id1) << 8))
+#define A2DP_SET_VENDOR_ID_CODEC_ID(v, c) ((a2dp_vendor_codec_t){ \
+		.vendor_id4 = (((v) >>  0) & 0xff), \
+		.vendor_id3 = (((v) >>  8) & 0xff), \
+		.vendor_id2 = (((v) >> 16) & 0xff), \
+		.vendor_id1 = (((v) >> 24) & 0xff), \
+		.codec_id2 = (((c) >> 0) & 0xff), \
+		.codec_id1 = (((c) >> 8) & 0xff), \
+	})
+
 #if __BYTE_ORDER == __LITTLE_ENDIAN
 
 typedef struct {
diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index fc98bb264..5bf596a2b 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
@@ -523,14 +523,14 @@ static gboolean endpoint_match_codec_ind(struct avdtp *session,
 	local_codec = (a2dp_vendor_codec_t *) capabilities;
 	remote_codec = (a2dp_vendor_codec_t *) codec->data;
 
-	if (remote_codec->vendor_id != local_codec->vendor_id)
+	if (A2DP_GET_VENDOR_ID(*remote_codec) != A2DP_GET_VENDOR_ID(*local_codec))
 		return FALSE;
 
-	if (remote_codec->codec_id != local_codec->codec_id)
+	if (A2DP_GET_CODEC_ID(*remote_codec) != A2DP_GET_CODEC_ID(*local_codec))
 		return FALSE;
 
-	DBG("vendor 0x%08x codec 0x%04x", btohl(remote_codec->vendor_id),
-						btohs(remote_codec->codec_id));
+	DBG("vendor 0x%08x codec 0x%04x", A2DP_GET_VENDOR_ID(*remote_codec),
+						A2DP_GET_CODEC_ID(*remote_codec));
 	return TRUE;
 }
 
diff --git a/tools/avinfo.c b/tools/avinfo.c
index ca0f12067..f09085c93 100644
--- a/tools/avinfo.c
+++ b/tools/avinfo.c
@@ -221,8 +221,8 @@ static void print_vendor(a2dp_vendor_codec_t *vendor, uint8_t size)
 		return;
 	}
 
-	vendor_id = btohl(vendor->vendor_id);
-	codec_id = btohs(vendor->codec_id);
+	vendor_id = A2DP_GET_VENDOR_ID(*vendor);
+	codec_id = A2DP_GET_CODEC_ID(*vendor);
 
 	printf("\tMedia Codec: Vendor Specific A2DP Codec");
 
-- 
2.11.0


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

* [PATCH 07/10] a2dp-codecs: Add needed includes and properly check for endian macros
  2018-12-19 16:50 [PATCH 00/10] A2DP: Fix endianity and define new A2DP codecs Pali Rohár
                   ` (5 preceding siblings ...)
  2018-12-19 16:51 ` [PATCH 06/10] a2dp-codecs: Define a2dp_vendor_codec_t struct in endian neutral way Pali Rohár
@ 2018-12-19 16:51 ` Pali Rohár
  2018-12-19 16:51 ` [PATCH 08/10] a2dp-codecs: Properly define macros and struct for LDAC codec Pali Rohár
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2018-12-19 16:51 UTC (permalink / raw)
  To: linux-bluetooth

Without stdint.h type uint8_t cannot be used.

And without endian.h macros __BYTE_ORDER, __LITTLE_ENDIAN and __BIG_ENDIAN
are not defined.

When both __BYTE_ORDER and __LITTLE_ENDIAN macros are not defined, then
condition #if __BYTE_ORDER == __LITTLE_ENDIAN is true.
---
 profiles/audio/a2dp-codecs.h | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/profiles/audio/a2dp-codecs.h b/profiles/audio/a2dp-codecs.h
index 43a5eef97..327901eac 100644
--- a/profiles/audio/a2dp-codecs.h
+++ b/profiles/audio/a2dp-codecs.h
@@ -22,6 +22,9 @@
  *
  */
 
+#include <endian.h>
+#include <stdint.h>
+
 #define A2DP_CODEC_SBC			0x00
 #define A2DP_CODEC_MPEG12		0x01
 #define A2DP_CODEC_MPEG24		0x02
@@ -213,7 +216,7 @@ typedef struct {
 		.codec_id1 = (((c) >> 8) & 0xff), \
 	})
 
-#if __BYTE_ORDER == __LITTLE_ENDIAN
+#if defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN
 
 typedef struct {
 	uint8_t channel_mode:4;
@@ -260,7 +263,7 @@ typedef struct {
 	uint8_t unknown[2];
 } __attribute__ ((packed)) a2dp_ldac_t;
 
-#elif __BYTE_ORDER == __BIG_ENDIAN
+#elif defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN
 
 typedef struct {
 	uint8_t frequency:4;
-- 
2.11.0


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

* [PATCH 08/10] a2dp-codecs: Properly define macros and struct for LDAC codec
  2018-12-19 16:50 [PATCH 00/10] A2DP: Fix endianity and define new A2DP codecs Pali Rohár
                   ` (6 preceding siblings ...)
  2018-12-19 16:51 ` [PATCH 07/10] a2dp-codecs: Add needed includes and properly check for endian macros Pali Rohár
@ 2018-12-19 16:51 ` Pali Rohár
  2018-12-19 16:51 ` [PATCH 09/10] a2dp-codecs: Add macros and structures for FastStream, aptX Low Latency and aptX HD codecs Pali Rohár
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2018-12-19 16:51 UTC (permalink / raw)
  To: linux-bluetooth

---
 profiles/audio/a2dp-codecs.h | 27 +++++++++++++++++----------
 tools/avinfo.c               |  3 +--
 2 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/profiles/audio/a2dp-codecs.h b/profiles/audio/a2dp-codecs.h
index 327901eac..9f47755cb 100644
--- a/profiles/audio/a2dp-codecs.h
+++ b/profiles/audio/a2dp-codecs.h
@@ -196,6 +196,17 @@
 #define LDAC_VENDOR_ID			0x0000012d
 #define LDAC_CODEC_ID			0x00aa
 
+#define LDAC_SAMPLING_FREQ_44100	0x20
+#define LDAC_SAMPLING_FREQ_48000	0x10
+#define LDAC_SAMPLING_FREQ_88200	0x08
+#define LDAC_SAMPLING_FREQ_96000	0x04
+#define LDAC_SAMPLING_FREQ_176400	0x02
+#define LDAC_SAMPLING_FREQ_192000	0x01
+
+#define LDAC_CHANNEL_MODE_MONO		0x04
+#define LDAC_CHANNEL_MODE_DUAL		0x02
+#define LDAC_CHANNEL_MODE_STEREO	0x01
+
 typedef struct {
 	uint8_t vendor_id4;
 	uint8_t vendor_id3;
@@ -216,6 +227,12 @@ typedef struct {
 		.codec_id1 = (((c) >> 8) & 0xff), \
 	})
 
+typedef struct {
+	a2dp_vendor_codec_t info;
+	uint8_t frequency;
+	uint8_t channel_mode;
+} __attribute__ ((packed)) a2dp_ldac_t;
+
 #if defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN
 
 typedef struct {
@@ -258,11 +275,6 @@ typedef struct {
 	uint8_t frequency:4;
 } __attribute__ ((packed)) a2dp_aptx_t;
 
-typedef struct {
-	a2dp_vendor_codec_t info;
-	uint8_t unknown[2];
-} __attribute__ ((packed)) a2dp_ldac_t;
-
 #elif defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN
 
 typedef struct {
@@ -305,11 +317,6 @@ typedef struct {
 	uint8_t channel_mode:4;
 } __attribute__ ((packed)) a2dp_aptx_t;
 
-typedef struct {
-	a2dp_vendor_codec_t info;
-	uint8_t unknown[2];
-} __attribute__ ((packed)) a2dp_ldac_t;
-
 #else
 #error "Unknown byte order"
 #endif
diff --git a/tools/avinfo.c b/tools/avinfo.c
index f09085c93..78da0d5d2 100644
--- a/tools/avinfo.c
+++ b/tools/avinfo.c
@@ -204,8 +204,7 @@ static void print_ldac(a2dp_ldac_t *ldac, uint8_t size)
 		return;
 	}
 
-	printf("\n\t\t\tUnknown: %02x %02x", ldac->unknown[0],
-							ldac->unknown[1]);
+	printf("\n\t\t\tUnknown: %02x %02x", ldac->frequency, ldac->channel_mode);
 
 	printf("\n");
 }
-- 
2.11.0


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

* [PATCH 09/10] a2dp-codecs: Add macros and structures for FastStream, aptX Low Latency and aptX HD codecs
  2018-12-19 16:50 [PATCH 00/10] A2DP: Fix endianity and define new A2DP codecs Pali Rohár
                   ` (7 preceding siblings ...)
  2018-12-19 16:51 ` [PATCH 08/10] a2dp-codecs: Properly define macros and struct for LDAC codec Pali Rohár
@ 2018-12-19 16:51 ` Pali Rohár
  2018-12-19 16:51 ` [PATCH 10/10] avinfo: Parse information about A2DP codecs: FastStream, aptX Low Latency, aptX HD and LDAC Pali Rohár
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2018-12-19 16:51 UTC (permalink / raw)
  To: linux-bluetooth

---
 profiles/audio/a2dp-codecs.h | 120 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 120 insertions(+)

diff --git a/profiles/audio/a2dp-codecs.h b/profiles/audio/a2dp-codecs.h
index 9f47755cb..d4a393668 100644
--- a/profiles/audio/a2dp-codecs.h
+++ b/profiles/audio/a2dp-codecs.h
@@ -4,6 +4,7 @@
  *
  *  Copyright (C) 2006-2010  Nokia Corporation
  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2018       Pali Rohár <pali.rohar@gmail.com>
  *
  *
  *  This library is free software; you can redistribute it and/or
@@ -193,6 +194,59 @@
 #define APTX_SAMPLING_FREQ_44100	0x02
 #define APTX_SAMPLING_FREQ_48000	0x01
 
+#define FASTSTREAM_VENDOR_ID		0x0000000a
+#define FASTSTREAM_CODEC_ID		0x0001
+
+#define FASTSTREAM_DIRECTION_SINK	0x1
+#define FASTSTREAM_DIRECTION_SOURCE	0x2
+
+#define FASTSTREAM_SINK_SAMPLING_FREQ_44100	0x2
+#define FASTSTREAM_SINK_SAMPLING_FREQ_48000	0x1
+
+#define FASTSTREAM_SOURCE_SAMPLING_FREQ_16000	0x2
+
+#define APTX_LL_VENDOR_ID		0x0000000a
+#define APTX_LL_CODEC_ID		0x0002
+
+#define APTX_LL_CHANNEL_MODE_MONO	0x01
+#define APTX_LL_CHANNEL_MODE_STEREO	0x02
+
+#define APTX_LL_SAMPLING_FREQ_16000	0x08
+#define APTX_LL_SAMPLING_FREQ_32000	0x04
+#define APTX_LL_SAMPLING_FREQ_44100	0x02
+#define APTX_LL_SAMPLING_FREQ_48000	0x01
+
+/* Default parameters for aptX Low Latency encoder */
+
+/* Target codec buffer level = 180 */
+#define APTX_LL_TARGET_LEVEL2	0xb4
+#define APTX_LL_TARGET_LEVEL1	0x00
+
+/* Initial codec buffer level = 360 */
+#define APTX_LL_INITIAL_LEVEL2	0x68
+#define APTX_LL_INITIAL_LEVEL1	0x01
+
+/* SRA max rate 0.005 * 10000 = 50 */
+#define APTX_LL_SRA_MAX_RATE		0x32
+
+/* SRA averaging time = 1s */
+#define APTX_LL_SRA_AVG_TIME		0x01
+
+/* Good working codec buffer level = 180 */
+#define APTX_LL_GOOD_WORKING_LEVEL2	0xB4
+#define APTX_LL_GOOD_WORKING_LEVEL1	0x00
+
+#define APTX_HD_VENDOR_ID		0x000000D7
+#define APTX_HD_CODEC_ID		0x0024
+
+#define APTX_HD_CHANNEL_MODE_MONO	0x1
+#define APTX_HD_CHANNEL_MODE_STEREO	0x2
+
+#define APTX_HD_SAMPLING_FREQ_16000	0x8
+#define APTX_HD_SAMPLING_FREQ_32000	0x4
+#define APTX_HD_SAMPLING_FREQ_44100	0x2
+#define APTX_HD_SAMPLING_FREQ_48000	0x1
+
 #define LDAC_VENDOR_ID			0x0000012d
 #define LDAC_CODEC_ID			0x00aa
 
@@ -228,6 +282,18 @@ typedef struct {
 	})
 
 typedef struct {
+	uint8_t reserved;
+	uint8_t target_level2;
+	uint8_t target_level1;
+	uint8_t initial_level2;
+	uint8_t initial_level1;
+	uint8_t sra_max_rate;
+	uint8_t sra_avg_time;
+	uint8_t good_working_level2;
+	uint8_t good_working_level1;
+} __attribute__ ((packed)) a2dp_aptx_ll_new_caps_t;
+
+typedef struct {
 	a2dp_vendor_codec_t info;
 	uint8_t frequency;
 	uint8_t channel_mode;
@@ -275,6 +341,33 @@ typedef struct {
 	uint8_t frequency:4;
 } __attribute__ ((packed)) a2dp_aptx_t;
 
+typedef struct {
+	a2dp_vendor_codec_t info;
+	uint8_t direction;
+	uint8_t sink_frequency:4;
+	uint8_t source_frequency:4;
+} __attribute__ ((packed)) a2dp_faststream_t;
+
+typedef struct {
+	a2dp_vendor_codec_t info;
+	uint8_t channel_mode:4;
+	uint8_t frequency:4;
+	uint8_t bidirect_link:1;
+	uint8_t has_new_caps:1;
+	uint8_t reserved:6;
+	a2dp_aptx_ll_new_caps_t new_caps[0];
+} __attribute__ ((packed)) a2dp_aptx_ll_t;
+
+typedef struct {
+	a2dp_vendor_codec_t info;
+	uint8_t channel_mode:4;
+	uint8_t frequency:4;
+	uint8_t reserved0;
+	uint8_t reserved1;
+	uint8_t reserved2;
+	uint8_t reserved3;
+} __attribute__ ((packed)) a2dp_aptx_hd_t;
+
 #elif defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN
 
 typedef struct {
@@ -317,6 +410,33 @@ typedef struct {
 	uint8_t channel_mode:4;
 } __attribute__ ((packed)) a2dp_aptx_t;
 
+typedef struct {
+	a2dp_vendor_codec_t info;
+	uint8_t direction;
+	uint8_t source_frequency:4;
+	uint8_t sink_frequency:4;
+} __attribute__ ((packed)) a2dp_faststream_t;
+
+typedef struct {
+	a2dp_vendor_codec_t info;
+	uint8_t frequency:4;
+	uint8_t channel_mode:4;
+	uint8_t reserved:6;
+	uint8_t has_new_caps:1;
+	uint8_t bidirect_link:1;
+	a2dp_aptx_ll_new_caps_t new_caps[0];
+} __attribute__ ((packed)) a2dp_aptx_ll_t;
+
+typedef struct {
+	a2dp_vendor_codec_t info;
+	uint8_t frequency:4;
+	uint8_t channel_mode:4;
+	uint8_t reserved0;
+	uint8_t reserved1;
+	uint8_t reserved2;
+	uint8_t reserved3;
+} __attribute__ ((packed)) a2dp_aptx_hd_t;
+
 #else
 #error "Unknown byte order"
 #endif
-- 
2.11.0


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

* [PATCH 10/10] avinfo: Parse information about A2DP codecs: FastStream, aptX Low Latency, aptX HD and LDAC
  2018-12-19 16:50 [PATCH 00/10] A2DP: Fix endianity and define new A2DP codecs Pali Rohár
                   ` (8 preceding siblings ...)
  2018-12-19 16:51 ` [PATCH 09/10] a2dp-codecs: Add macros and structures for FastStream, aptX Low Latency and aptX HD codecs Pali Rohár
@ 2018-12-19 16:51 ` Pali Rohár
  2018-12-22 22:54 ` [PATCH 00/10] A2DP: Fix endianity and define new A2DP codecs Luiz Augusto von Dentz
  2018-12-23 10:40 ` [PATCH v2 " Pali Rohár
  11 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2018-12-19 16:51 UTC (permalink / raw)
  To: linux-bluetooth

---
 tools/avinfo.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 129 insertions(+), 1 deletion(-)

diff --git a/tools/avinfo.c b/tools/avinfo.c
index 78da0d5d2..9c05eb889 100644
--- a/tools/avinfo.c
+++ b/tools/avinfo.c
@@ -4,6 +4,7 @@
  *
  *  Copyright (C) 2006-2010  Nokia Corporation
  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2018       Pali Rohár <pali.rohar@gmail.com>
  *
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -195,6 +196,107 @@ static void print_aptx(a2dp_aptx_t *aptx, uint8_t size)
 	printf("\n");
 }
 
+static void print_faststream(a2dp_faststream_t *faststream, uint8_t size)
+{
+	printf("\t\tVendor Specific Value (FastStream)");
+
+	if (size < sizeof(*faststream)) {
+		printf(" (broken)\n");
+		return;
+	}
+
+	printf("\n\t\t\tDirections: ");
+	if (faststream->direction & FASTSTREAM_DIRECTION_SINK)
+		printf("sink ");
+	if (faststream->direction & FASTSTREAM_DIRECTION_SOURCE)
+		printf("source ");
+
+	if (faststream->direction & FASTSTREAM_DIRECTION_SINK) {
+		printf("\n\t\t\tSink Frequencies: ");
+		if (faststream->sink_frequency & FASTSTREAM_SINK_SAMPLING_FREQ_44100)
+			printf("44.1kHz ");
+		if (faststream->sink_frequency & FASTSTREAM_SINK_SAMPLING_FREQ_48000)
+			printf("48kHz ");
+	}
+
+	if (faststream->direction & FASTSTREAM_DIRECTION_SOURCE) {
+		printf("\n\t\t\tSource Frequencies: ");
+		if (faststream->source_frequency & FASTSTREAM_SOURCE_SAMPLING_FREQ_16000)
+			printf("16kHz ");
+	}
+
+	printf("\n");
+}
+
+static void print_aptx_ll(a2dp_aptx_ll_t *aptx_ll, uint8_t size)
+{
+	a2dp_aptx_ll_new_caps_t *aptx_ll_new;
+
+	printf("\t\tVendor Specific Value (aptX Low Latency)");
+
+	if (size < sizeof(*aptx_ll)) {
+		printf(" (broken)\n");
+		return;
+	}
+
+	printf("\n\t\t\tFrequencies: ");
+	if (aptx_ll->frequency & APTX_LL_SAMPLING_FREQ_16000)
+		printf("16kHz ");
+	if (aptx_ll->frequency & APTX_LL_SAMPLING_FREQ_32000)
+		printf("32kHz ");
+	if (aptx_ll->frequency & APTX_LL_SAMPLING_FREQ_44100)
+		printf("44.1kHz ");
+	if (aptx_ll->frequency & APTX_LL_SAMPLING_FREQ_48000)
+		printf("48kHz ");
+
+	printf("\n\t\t\tChannel modes: ");
+	if (aptx_ll->channel_mode & APTX_LL_CHANNEL_MODE_MONO)
+		printf("Mono ");
+	if (aptx_ll->channel_mode & APTX_LL_CHANNEL_MODE_STEREO)
+		printf("Stereo ");
+
+	printf("\n\t\tBidirectional link: %s", aptx_ll->bidirect_link ? "Yes" : "No");
+
+	aptx_ll_new = &aptx_ll->new_caps[0];
+	if (aptx_ll->has_new_caps && size >= sizeof(*aptx_ll) + sizeof(*aptx_ll_new)) {
+		printf("\n\t\tTarget codec buffer level: %u", (unsigned)aptx_ll_new->target_level2 | ((unsigned)(aptx_ll_new->target_level1) << 8));
+		printf("\n\t\tInitial codec buffer level: %u", (unsigned)aptx_ll_new->initial_level2 | ((unsigned)(aptx_ll_new->initial_level1) << 8));
+		printf("\n\t\tSRA max rate: %g", aptx_ll_new->sra_max_rate / 10000.0);
+		printf("\n\t\tSRA averaging time: %us", (unsigned)aptx_ll_new->sra_avg_time);
+		printf("\n\t\tGood working codec buffer level: %u", (unsigned)aptx_ll_new->good_working_level2 | ((unsigned)(aptx_ll_new->good_working_level1) << 8));
+	}
+
+	printf("\n");
+}
+
+static void print_aptx_hd(a2dp_aptx_hd_t *aptx_hd, uint8_t size)
+{
+	printf("\t\tVendor Specific Value (aptX HD)");
+
+	if (size < sizeof(*aptx_hd)) {
+		printf(" (broken)\n");
+		return;
+	}
+
+	printf("\n\t\t\tFrequencies: ");
+	if (aptx_hd->frequency & APTX_HD_SAMPLING_FREQ_16000)
+		printf("16kHz ");
+	if (aptx_hd->frequency & APTX_HD_SAMPLING_FREQ_32000)
+		printf("32kHz ");
+	if (aptx_hd->frequency & APTX_HD_SAMPLING_FREQ_44100)
+		printf("44.1kHz ");
+	if (aptx_hd->frequency & APTX_HD_SAMPLING_FREQ_48000)
+		printf("48kHz ");
+
+	printf("\n\t\t\tChannel modes: ");
+	if (aptx_hd->channel_mode & APTX_HD_CHANNEL_MODE_MONO)
+		printf("Mono ");
+	if (aptx_hd->channel_mode & APTX_HD_CHANNEL_MODE_STEREO)
+		printf("Stereo ");
+
+	printf("\n");
+}
+
 static void print_ldac(a2dp_ldac_t *ldac, uint8_t size)
 {
 	printf("\t\tVendor Specific Value (LDAC)");
@@ -204,7 +306,27 @@ static void print_ldac(a2dp_ldac_t *ldac, uint8_t size)
 		return;
 	}
 
-	printf("\n\t\t\tUnknown: %02x %02x", ldac->frequency, ldac->channel_mode);
+	printf("\n\t\t\tFrequencies: ");
+	if (ldac->frequency & LDAC_SAMPLING_FREQ_44100)
+		printf("44.1kHz ");
+	if (ldac->frequency & LDAC_SAMPLING_FREQ_48000)
+		printf("48kHz ");
+	if (ldac->frequency & LDAC_SAMPLING_FREQ_88200)
+		printf("88.2kHz ");
+	if (ldac->frequency & LDAC_SAMPLING_FREQ_96000)
+		printf("96kHz ");
+	if (ldac->frequency & LDAC_SAMPLING_FREQ_176400)
+		printf("176.4kHz ");
+	if (ldac->frequency & LDAC_SAMPLING_FREQ_192000)
+		printf("192kHz ");
+
+	printf("\n\t\t\tChannel modes: ");
+	if (ldac->channel_mode & LDAC_CHANNEL_MODE_MONO)
+		printf("Mono ");
+	if (ldac->channel_mode & LDAC_CHANNEL_MODE_DUAL)
+		printf("Dual ");
+	if (ldac->channel_mode & LDAC_CHANNEL_MODE_STEREO)
+		printf("Stereo ");
 
 	printf("\n");
 }
@@ -236,6 +358,12 @@ static void print_vendor(a2dp_vendor_codec_t *vendor, uint8_t size)
 
 	if (vendor_id == APTX_VENDOR_ID && codec_id == APTX_CODEC_ID)
 		print_aptx((void *) vendor, size);
+	else if (vendor_id == FASTSTREAM_VENDOR_ID && codec_id == FASTSTREAM_CODEC_ID)
+		print_faststream((void *) vendor, size);
+	else if (vendor_id == APTX_LL_VENDOR_ID && codec_id == APTX_LL_CODEC_ID)
+		print_aptx_ll((void *) vendor, size);
+	else if (vendor_id == APTX_HD_VENDOR_ID && codec_id == APTX_HD_CODEC_ID)
+		print_aptx_hd((void *) vendor, size);
 	else if (vendor_id == LDAC_VENDOR_ID && codec_id == LDAC_CODEC_ID)
 		print_ldac((void *) vendor, size);
 }
-- 
2.11.0


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

* Re: [PATCH 00/10] A2DP: Fix endianity and define new A2DP codecs
  2018-12-19 16:50 [PATCH 00/10] A2DP: Fix endianity and define new A2DP codecs Pali Rohár
                   ` (9 preceding siblings ...)
  2018-12-19 16:51 ` [PATCH 10/10] avinfo: Parse information about A2DP codecs: FastStream, aptX Low Latency, aptX HD and LDAC Pali Rohár
@ 2018-12-22 22:54 ` Luiz Augusto von Dentz
  2018-12-23  9:30   ` Pali Rohár
  2018-12-23 10:40 ` [PATCH v2 " Pali Rohár
  11 siblings, 1 reply; 26+ messages in thread
From: Luiz Augusto von Dentz @ 2018-12-22 22:54 UTC (permalink / raw)
  To: Pali Rohár; +Cc: linux-bluetooth

Hi Pali,

On Wed, Dec 19, 2018 at 5:17 PM Pali Rohár <pali.rohar@gmail.com> wrote:
>
> This patch series try to fix endianity problems in a2dp-codecs.h file,
> then fixes parsing MPEG bit rate values, extend a2dp-codecs.h file for
> new A2DP codecs FastStream, aptX Low Latency, aptX HD and finally adds
> support for parsing information about FastStream, aptX Low Latency,
> aptX HD and LDAC codecs in avinfo utility.
>
> Pali Rohár (10):
>   avinfo: Fix buffer overflow when parsing broken/malicious data
>   avinfo: Show Vendor Specific Data
>   a2dp-codecs: Add SBC prefix for MIN/MAX_BITPOOL constants
>   a2dp-codecs: Fix codec id for ATRAC
>   a2dp-codecs & avinfo: Fix parsing MPEG bit rate values
>   a2dp-codecs: Define a2dp_vendor_codec_t struct in endian neutral way
>   a2dp-codecs: Add needed includes and properly check for endian macros
>   a2dp-codecs: Properly define macros and struct for LDAC codec
>   a2dp-codecs: Add macros and structures for FastStream, aptX Low
>     Latency and aptX HD codecs
>   avinfo: Parse information about A2DP codecs: FastStream, aptX Low
>     Latency, aptX HD and LDAC
>
>  android/a2dp.c               |   8 +-
>  android/avdtp.c              |   4 +-
>  android/hal-audio-aptx.c     |  15 +-
>  android/hal-audio-sbc.c      |  12 +-
>  profiles/audio/a2dp-codecs.h | 256 ++++++++++++++++++++++++++----
>  profiles/audio/a2dp.c        |   8 +-
>  tools/avinfo.c               | 362 ++++++++++++++++++++++++++++++++++++-------
>  7 files changed, 551 insertions(+), 114 deletions(-)
>
> --
> 2.11.0

gitlint: checking commit message...
3: B6 Body message is missing
-----------------------------------------------
gitlint: \033[31mYour commit message contains the above violations.\033[0m

Please add description to the commit messages. Also there seems to be
several problems with codying style like the following:

Applying: avinfo: Fix buffer overflow when parsing broken/malicious data
WARNING:UNSPECIFIED_INT: Prefer 'unsigned int' to bare use of 'unsigned'
#77: FILE: tools/avinfo.c:241:
+    unsigned freq, bitrate;

WARNING:LONG_LINE: line over 80 characters
#124: FILE: tools/avinfo.c:433:
+static void print_media_codec(struct avdtp_media_codec_capability
*cap, uint8_t size)

WARNING:LONG_LINE: line over 80 characters
#182: FILE: tools/avinfo.c:510:
+            print_content_protection((void *) cap->data, cap->length);

total: 0 errors, 3 warnings, 173 lines checked




-- 
Luiz Augusto von Dentz

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

* Re: [PATCH 00/10] A2DP: Fix endianity and define new A2DP codecs
  2018-12-22 22:54 ` [PATCH 00/10] A2DP: Fix endianity and define new A2DP codecs Luiz Augusto von Dentz
@ 2018-12-23  9:30   ` Pali Rohár
  0 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2018-12-23  9:30 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth

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

On Saturday 22 December 2018 19:54:48 Luiz Augusto von Dentz wrote:
> Hi Pali,
> 
> On Wed, Dec 19, 2018 at 5:17 PM Pali Rohár <pali.rohar@gmail.com> wrote:
> >
> > This patch series try to fix endianity problems in a2dp-codecs.h file,
> > then fixes parsing MPEG bit rate values, extend a2dp-codecs.h file for
> > new A2DP codecs FastStream, aptX Low Latency, aptX HD and finally adds
> > support for parsing information about FastStream, aptX Low Latency,
> > aptX HD and LDAC codecs in avinfo utility.
> >
> > Pali Rohár (10):
> >   avinfo: Fix buffer overflow when parsing broken/malicious data
> >   avinfo: Show Vendor Specific Data
> >   a2dp-codecs: Add SBC prefix for MIN/MAX_BITPOOL constants
> >   a2dp-codecs: Fix codec id for ATRAC
> >   a2dp-codecs & avinfo: Fix parsing MPEG bit rate values
> >   a2dp-codecs: Define a2dp_vendor_codec_t struct in endian neutral way
> >   a2dp-codecs: Add needed includes and properly check for endian macros
> >   a2dp-codecs: Properly define macros and struct for LDAC codec
> >   a2dp-codecs: Add macros and structures for FastStream, aptX Low
> >     Latency and aptX HD codecs
> >   avinfo: Parse information about A2DP codecs: FastStream, aptX Low
> >     Latency, aptX HD and LDAC
> >
> >  android/a2dp.c               |   8 +-
> >  android/avdtp.c              |   4 +-
> >  android/hal-audio-aptx.c     |  15 +-
> >  android/hal-audio-sbc.c      |  12 +-
> >  profiles/audio/a2dp-codecs.h | 256 ++++++++++++++++++++++++++----
> >  profiles/audio/a2dp.c        |   8 +-
> >  tools/avinfo.c               | 362 ++++++++++++++++++++++++++++++++++++-------
> >  7 files changed, 551 insertions(+), 114 deletions(-)
> >
> > --
> > 2.11.0
> 
> gitlint: checking commit message...
> 3: B6 Body message is missing
> -----------------------------------------------
> gitlint: \033[31mYour commit message contains the above violations.\033[0m
> 
> Please add description to the commit messages.

What should I put into those commit messages? I think that those changes
without commit body are such small, that commit title describes them.+

> Also there seems to be
> several problems with codying style like the following:
> 
> Applying: avinfo: Fix buffer overflow when parsing broken/malicious data
> WARNING:UNSPECIFIED_INT: Prefer 'unsigned int' to bare use of 'unsigned'
> #77: FILE: tools/avinfo.c:241:
> +    unsigned freq, bitrate;
> 
> WARNING:LONG_LINE: line over 80 characters
> #124: FILE: tools/avinfo.c:433:
> +static void print_media_codec(struct avdtp_media_codec_capability
> *cap, uint8_t size)
> 
> WARNING:LONG_LINE: line over 80 characters
> #182: FILE: tools/avinfo.c:510:
> +            print_content_protection((void *) cap->data, cap->length);
> 
> total: 0 errors, 3 warnings, 173 lines checked

Ok, I will fix them.

-- 
Pali Rohár
pali.rohar@gmail.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

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

* [PATCH v2 00/10] A2DP: Fix endianity and define new A2DP codecs
  2018-12-19 16:50 [PATCH 00/10] A2DP: Fix endianity and define new A2DP codecs Pali Rohár
                   ` (10 preceding siblings ...)
  2018-12-22 22:54 ` [PATCH 00/10] A2DP: Fix endianity and define new A2DP codecs Luiz Augusto von Dentz
@ 2018-12-23 10:40 ` " Pali Rohár
  2018-12-23 10:40   ` [PATCH v2 01/10] avinfo: Fix buffer overflow when parsing broken/malicious data Pali Rohár
                     ` (10 more replies)
  11 siblings, 11 replies; 26+ messages in thread
From: Pali Rohár @ 2018-12-23 10:40 UTC (permalink / raw)
  To: linux-bluetooth

This patch series try to fix endianity problems in a2dp-codecs.h file,
then fixes parsing MPEG bit rate values, extend a2dp-codecs.h file for
new A2DP codecs FastStream, aptX Low Latency, aptX HD and finally adds
support for parsing information about FastStream, aptX Low Latency,
aptX HD and LDAC codecs in avinfo utility.

Changes since v1:
* Fix style issues

Pali Rohár (10):
  avinfo: Fix buffer overflow when parsing broken/malicious data
  avinfo: Show Vendor Specific Data
  a2dp-codecs: Add SBC prefix for MIN/MAX_BITPOOL constants
  a2dp-codecs: Fix codec id for ATRAC
  a2dp-codecs & avinfo: Fix parsing MPEG bit rate values
  a2dp-codecs: Define a2dp_vendor_codec_t struct in endian neutral way
  a2dp-codecs: Add needed includes and properly check for endian macros
  a2dp-codecs: Properly define macros and struct for LDAC codec
  a2dp-codecs: Add macros and structures for new codecs
  avinfo: Parse new A2DP codecs

 android/a2dp.c               |   8 +-
 android/avdtp.c              |   6 +-
 android/hal-audio-aptx.c     |  18 +-
 android/hal-audio-sbc.c      |  12 +-
 profiles/audio/a2dp-codecs.h | 267 ++++++++++++++++++++++++++----
 profiles/audio/a2dp.c        |   9 +-
 tools/avinfo.c               | 380 ++++++++++++++++++++++++++++++++++++-------
 7 files changed, 586 insertions(+), 114 deletions(-)

-- 
2.11.0


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

* [PATCH v2 01/10] avinfo: Fix buffer overflow when parsing broken/malicious data
  2018-12-23 10:40 ` [PATCH v2 " Pali Rohár
@ 2018-12-23 10:40   ` Pali Rohár
  2018-12-23 10:40   ` [PATCH v2 02/10] avinfo: Show Vendor Specific Data Pali Rohár
                     ` (9 subsequent siblings)
  10 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2018-12-23 10:40 UTC (permalink / raw)
  To: linux-bluetooth

Check size of buffer prior casting it to struct.
---
 tools/avinfo.c | 92 +++++++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 72 insertions(+), 20 deletions(-)

diff --git a/tools/avinfo.c b/tools/avinfo.c
index 31c4e106e..3f6cdbc0e 100644
--- a/tools/avinfo.c
+++ b/tools/avinfo.c
@@ -167,10 +167,15 @@ struct avdtp_content_protection_capability {
 	uint8_t data[0];
 } __attribute__ ((packed));
 
-static void print_aptx(a2dp_aptx_t *aptx)
+static void print_aptx(a2dp_aptx_t *aptx, uint8_t size)
 {
 	printf("\t\tVendor Specific Value (aptX)");
 
+	if (size < sizeof(*aptx)) {
+		printf(" (broken)\n");
+		return;
+	}
+
 	printf("\n\t\t\tFrequencies: ");
 	if (aptx->frequency & APTX_SAMPLING_FREQ_16000)
 		printf("16kHz ");
@@ -190,20 +195,34 @@ static void print_aptx(a2dp_aptx_t *aptx)
 	printf("\n");
 }
 
-static void print_ldac(a2dp_ldac_t *ldac)
+static void print_ldac(a2dp_ldac_t *ldac, uint8_t size)
 {
 	printf("\t\tVendor Specific Value (LDAC)");
 
+	if (size < sizeof(*ldac)) {
+		printf(" (broken)\n");
+		return;
+	}
+
 	printf("\n\t\t\tUnknown: %02x %02x", ldac->unknown[0],
 							ldac->unknown[1]);
 
 	printf("\n");
 }
 
-static void print_vendor(a2dp_vendor_codec_t *vendor)
+static void print_vendor(a2dp_vendor_codec_t *vendor, uint8_t size)
 {
-	uint32_t vendor_id = btohl(vendor->vendor_id);
-	uint16_t codec_id = btohs(vendor->codec_id);
+	uint32_t vendor_id;
+	uint16_t codec_id;
+	uint8_t i;
+
+	if (size < sizeof(*vendor)) {
+		printf("\tMedia Codec: Vendor Specific A2DP Codec (broken)");
+		return;
+	}
+
+	vendor_id = btohl(vendor->vendor_id);
+	codec_id = btohs(vendor->codec_id);
 
 	printf("\tMedia Codec: Vendor Specific A2DP Codec");
 
@@ -212,15 +231,22 @@ static void print_vendor(a2dp_vendor_codec_t *vendor)
 	printf("\n\t\tVendor Specific Codec ID 0x%04x\n", codec_id);
 
 	if (vendor_id == APTX_VENDOR_ID && codec_id == APTX_CODEC_ID)
-		print_aptx((void *) vendor);
+		print_aptx((void *) vendor, size);
 	else if (vendor_id == LDAC_VENDOR_ID && codec_id == LDAC_CODEC_ID)
-		print_ldac((void *) vendor);
+		print_ldac((void *) vendor, size);
 }
 
-static void print_mpeg24(a2dp_aac_t *aac)
+static void print_mpeg24(a2dp_aac_t *aac, uint8_t size)
 {
-	unsigned freq = AAC_GET_FREQUENCY(*aac);
-	unsigned bitrate = AAC_GET_BITRATE(*aac);
+	unsigned int freq, bitrate;
+
+	if (size < sizeof(*aac)) {
+		printf("\tMedia Codec: MPEG24 (broken)\n");
+		return;
+	}
+
+	freq = AAC_GET_FREQUENCY(*aac);
+	bitrate = AAC_GET_BITRATE(*aac);
 
 	printf("\tMedia Codec: MPEG24\n\t\tObject Types: ");
 
@@ -270,8 +296,13 @@ static void print_mpeg24(a2dp_aac_t *aac)
 	printf("\n\t\tVBR: %s", aac->vbr ? "Yes\n" : "No\n");
 }
 
-static void print_mpeg12(a2dp_mpeg_t *mpeg)
+static void print_mpeg12(a2dp_mpeg_t *mpeg, uint8_t size)
 {
+	if (size < sizeof(*mpeg)) {
+		printf("\tMedia Codec: MPEG12 (broken)\n");
+		return;
+	}
+
 	printf("\tMedia Codec: MPEG12\n\t\tChannel Modes: ");
 
 	if (mpeg->channel_mode & MPEG_CHANNEL_MODE_MONO)
@@ -351,8 +382,13 @@ static void print_mpeg12(a2dp_mpeg_t *mpeg)
 		printf("RFC-2250\n");
 }
 
-static void print_sbc(a2dp_sbc_t *sbc)
+static void print_sbc(a2dp_sbc_t *sbc, uint8_t size)
 {
+	if (size < sizeof(*sbc)) {
+		printf("\tMedia Codec: SBC (broken)\n");
+		return;
+	}
+
 	printf("\tMedia Codec: SBC\n\t\tChannel Modes: ");
 
 	if (sbc->channel_mode & SBC_CHANNEL_MODE_MONO)
@@ -394,20 +430,27 @@ static void print_sbc(a2dp_sbc_t *sbc)
 				sbc->min_bitpool, sbc->max_bitpool);
 }
 
-static void print_media_codec(struct avdtp_media_codec_capability *cap)
+static void print_media_codec(
+			struct avdtp_media_codec_capability *cap,
+			uint8_t size)
 {
+	if (size < sizeof(*cap)) {
+		printf("\tMedia Codec: Unknown (broken)\n");
+		return;
+	}
+
 	switch (cap->media_codec_type) {
 	case A2DP_CODEC_SBC:
-		print_sbc((void *) cap->data);
+		print_sbc((void *) cap->data, size - 2);
 		break;
 	case A2DP_CODEC_MPEG12:
-		print_mpeg12((void *) cap->data);
+		print_mpeg12((void *) cap->data, size - 2);
 		break;
 	case A2DP_CODEC_MPEG24:
-		print_mpeg24((void *) cap->data);
+		print_mpeg24((void *) cap->data, size - 2);
 		break;
 	case A2DP_CODEC_VENDOR:
-		print_vendor((void *) cap->data);
+		print_vendor((void *) cap->data, size - 2);
 		break;
 	default:
 		printf("\tMedia Codec: Unknown\n");
@@ -415,10 +458,16 @@ static void print_media_codec(struct avdtp_media_codec_capability *cap)
 }
 
 static void print_content_protection(
-				struct avdtp_content_protection_capability *cap)
+				struct avdtp_content_protection_capability *cap,
+				uint8_t size)
 {
 	printf("\tContent Protection: ");
 
+	if (size < sizeof(*cap)) {
+		printf("Unknown (broken)\n");
+		return;
+	}
+
 	switch (btohs(cap->content_protection_type)) {
 	case AVDTP_CONTENT_PROTECTION_TYPE_DTCP:
 		printf("DTCP");
@@ -452,13 +501,16 @@ static void print_caps(void *data, int size)
 		case AVDTP_REPORTING:
 		case AVDTP_RECOVERY:
 		case AVDTP_MULTIPLEXING:
+		default:
 			/* FIXME: Add proper functions */
+			printf("\tUnknown category: %d\n", cap->category);
 			break;
 		case AVDTP_MEDIA_CODEC:
-			print_media_codec((void *) cap->data);
+			print_media_codec((void *) cap->data, cap->length);
 			break;
 		case AVDTP_CONTENT_PROTECTION:
-			print_content_protection((void *) cap->data);
+			print_content_protection((void *) cap->data,
+						cap->length);
 			break;
 		}
 
-- 
2.11.0


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

* [PATCH v2 02/10] avinfo: Show Vendor Specific Data
  2018-12-23 10:40 ` [PATCH v2 " Pali Rohár
  2018-12-23 10:40   ` [PATCH v2 01/10] avinfo: Fix buffer overflow when parsing broken/malicious data Pali Rohár
@ 2018-12-23 10:40   ` Pali Rohár
  2018-12-23 10:40   ` [PATCH v2 03/10] a2dp-codecs: Add SBC prefix for MIN/MAX_BITPOOL constants Pali Rohár
                     ` (8 subsequent siblings)
  10 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2018-12-23 10:40 UTC (permalink / raw)
  To: linux-bluetooth

---
 tools/avinfo.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/tools/avinfo.c b/tools/avinfo.c
index 3f6cdbc0e..b79446825 100644
--- a/tools/avinfo.c
+++ b/tools/avinfo.c
@@ -228,7 +228,12 @@ static void print_vendor(a2dp_vendor_codec_t *vendor, uint8_t size)
 
 	printf("\n\t\tVendor ID 0x%08x", vendor_id);
 
-	printf("\n\t\tVendor Specific Codec ID 0x%04x\n", codec_id);
+	printf("\n\t\tVendor Specific Codec ID 0x%04x", codec_id);
+
+	printf("\n\t\tVendor Specific Data:");
+	for (i = 6; i < size; ++i)
+		printf(" 0x%.02x", ((unsigned char *)vendor)[i]);
+	printf("\n");
 
 	if (vendor_id == APTX_VENDOR_ID && codec_id == APTX_CODEC_ID)
 		print_aptx((void *) vendor, size);
-- 
2.11.0


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

* [PATCH v2 03/10] a2dp-codecs: Add SBC prefix for MIN/MAX_BITPOOL constants
  2018-12-23 10:40 ` [PATCH v2 " Pali Rohár
  2018-12-23 10:40   ` [PATCH v2 01/10] avinfo: Fix buffer overflow when parsing broken/malicious data Pali Rohár
  2018-12-23 10:40   ` [PATCH v2 02/10] avinfo: Show Vendor Specific Data Pali Rohár
@ 2018-12-23 10:40   ` Pali Rohár
  2018-12-23 10:40   ` [PATCH v2 04/10] a2dp-codecs: Fix codec id for ATRAC Pali Rohár
                     ` (7 subsequent siblings)
  10 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2018-12-23 10:40 UTC (permalink / raw)
  To: linux-bluetooth

Those two constants are SBC codec specific.
---
 android/hal-audio-sbc.c      | 12 ++++++------
 profiles/audio/a2dp-codecs.h |  4 ++--
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/android/hal-audio-sbc.c b/android/hal-audio-sbc.c
index 9da9575f5..80e271ed6 100644
--- a/android/hal-audio-sbc.c
+++ b/android/hal-audio-sbc.c
@@ -91,8 +91,8 @@ static const a2dp_sbc_t sbc_presets[] = {
 					SBC_ALLOCATION_LOUDNESS,
 		.block_length = SBC_BLOCK_LENGTH_4 | SBC_BLOCK_LENGTH_8 |
 				SBC_BLOCK_LENGTH_12 | SBC_BLOCK_LENGTH_16,
-		.min_bitpool = MIN_BITPOOL,
-		.max_bitpool = MAX_BITPOOL
+		.min_bitpool = SBC_MIN_BITPOOL,
+		.max_bitpool = SBC_MAX_BITPOOL
 	},
 	{
 		.frequency = SBC_SAMPLING_FREQ_44100,
@@ -100,8 +100,8 @@ static const a2dp_sbc_t sbc_presets[] = {
 		.subbands = SBC_SUBBANDS_8,
 		.allocation_method = SBC_ALLOCATION_LOUDNESS,
 		.block_length = SBC_BLOCK_LENGTH_16,
-		.min_bitpool = MIN_BITPOOL,
-		.max_bitpool = MAX_BITPOOL
+		.min_bitpool = SBC_MIN_BITPOOL,
+		.max_bitpool = SBC_MAX_BITPOOL
 	},
 	{
 		.frequency = SBC_SAMPLING_FREQ_48000,
@@ -109,8 +109,8 @@ static const a2dp_sbc_t sbc_presets[] = {
 		.subbands = SBC_SUBBANDS_8,
 		.allocation_method = SBC_ALLOCATION_LOUDNESS,
 		.block_length = SBC_BLOCK_LENGTH_16,
-		.min_bitpool = MIN_BITPOOL,
-		.max_bitpool = MAX_BITPOOL
+		.min_bitpool = SBC_MIN_BITPOOL,
+		.max_bitpool = SBC_MAX_BITPOOL
 	},
 };
 
diff --git a/profiles/audio/a2dp-codecs.h b/profiles/audio/a2dp-codecs.h
index 4fb5c0cc9..205491939 100644
--- a/profiles/audio/a2dp-codecs.h
+++ b/profiles/audio/a2dp-codecs.h
@@ -49,8 +49,8 @@
 #define SBC_ALLOCATION_SNR		(1 << 1)
 #define SBC_ALLOCATION_LOUDNESS		1
 
-#define MAX_BITPOOL 64
-#define MIN_BITPOOL 2
+#define SBC_MAX_BITPOOL			64
+#define SBC_MIN_BITPOOL			2
 
 #define MPEG_CHANNEL_MODE_MONO		(1 << 3)
 #define MPEG_CHANNEL_MODE_DUAL_CHANNEL	(1 << 2)
-- 
2.11.0


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

* [PATCH v2 04/10] a2dp-codecs: Fix codec id for ATRAC
  2018-12-23 10:40 ` [PATCH v2 " Pali Rohár
                     ` (2 preceding siblings ...)
  2018-12-23 10:40   ` [PATCH v2 03/10] a2dp-codecs: Add SBC prefix for MIN/MAX_BITPOOL constants Pali Rohár
@ 2018-12-23 10:40   ` Pali Rohár
  2018-12-23 10:40   ` [PATCH v2 05/10] a2dp-codecs & avinfo: Fix parsing MPEG bit rate values Pali Rohár
                     ` (6 subsequent siblings)
  10 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2018-12-23 10:40 UTC (permalink / raw)
  To: linux-bluetooth

According to Bluetooth Assigned Numbers for Audio/Video ATRAC has codec id 0x04.
See: https://www.bluetooth.com/specifications/assigned-numbers/audio-video
---
 profiles/audio/a2dp-codecs.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/profiles/audio/a2dp-codecs.h b/profiles/audio/a2dp-codecs.h
index 205491939..25959902c 100644
--- a/profiles/audio/a2dp-codecs.h
+++ b/profiles/audio/a2dp-codecs.h
@@ -25,7 +25,7 @@
 #define A2DP_CODEC_SBC			0x00
 #define A2DP_CODEC_MPEG12		0x01
 #define A2DP_CODEC_MPEG24		0x02
-#define A2DP_CODEC_ATRAC		0x03
+#define A2DP_CODEC_ATRAC		0x04
 #define A2DP_CODEC_VENDOR		0xFF
 
 #define SBC_SAMPLING_FREQ_16000		(1 << 3)
-- 
2.11.0


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

* [PATCH v2 05/10] a2dp-codecs & avinfo: Fix parsing MPEG bit rate values
  2018-12-23 10:40 ` [PATCH v2 " Pali Rohár
                     ` (3 preceding siblings ...)
  2018-12-23 10:40   ` [PATCH v2 04/10] a2dp-codecs: Fix codec id for ATRAC Pali Rohár
@ 2018-12-23 10:40   ` Pali Rohár
  2018-12-23 10:40   ` [PATCH v2 06/10] a2dp-codecs: Define a2dp_vendor_codec_t struct in endian neutral way Pali Rohár
                     ` (5 subsequent siblings)
  10 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2018-12-23 10:40 UTC (permalink / raw)
  To: linux-bluetooth

Redefine bitrate field in a2dp_mpeg_t struct in endian neutral way and
separate vbr field according to A2DP specification. Define new macros
MPEG_GET_BITRATE() and MPEG_SET_BITRATE() for manipulating with bitrate
like for a2dp_aac_t struct.

And fix meaning of bitrate field. According to A2DP specification, it is
bitrate index, not bitrate itself. According to MPEG specification, each
MPEG layer have different bitrates for bitrate indexes. Therefore define
correctly bitrates for Layers 1, 2 and 3.

This fixes problems with parsing bitrate field in a2dp_mpeg_t struct as it
was broken due to endianity and it was broken for Layer 1 and 2 as bitrate
definitions was for Layer 3.
---
 profiles/audio/a2dp-codecs.h |  93 +++++++++++++++++++++++------
 tools/avinfo.c               | 135 ++++++++++++++++++++++++++++++++-----------
 2 files changed, 176 insertions(+), 52 deletions(-)

diff --git a/profiles/audio/a2dp-codecs.h b/profiles/audio/a2dp-codecs.h
index 25959902c..47030bcc1 100644
--- a/profiles/audio/a2dp-codecs.h
+++ b/profiles/audio/a2dp-codecs.h
@@ -68,22 +68,75 @@
 #define MPEG_SAMPLING_FREQ_44100	(1 << 1)
 #define MPEG_SAMPLING_FREQ_48000	1
 
-#define MPEG_BIT_RATE_VBR		0x8000
-#define MPEG_BIT_RATE_320000		0x4000
-#define MPEG_BIT_RATE_256000		0x2000
-#define MPEG_BIT_RATE_224000		0x1000
-#define MPEG_BIT_RATE_192000		0x0800
-#define MPEG_BIT_RATE_160000		0x0400
-#define MPEG_BIT_RATE_128000		0x0200
-#define MPEG_BIT_RATE_112000		0x0100
-#define MPEG_BIT_RATE_96000		0x0080
-#define MPEG_BIT_RATE_80000		0x0040
-#define MPEG_BIT_RATE_64000		0x0020
-#define MPEG_BIT_RATE_56000		0x0010
-#define MPEG_BIT_RATE_48000		0x0008
-#define MPEG_BIT_RATE_40000		0x0004
-#define MPEG_BIT_RATE_32000		0x0002
-#define MPEG_BIT_RATE_FREE		0x0001
+#define MPEG_BIT_RATE_INDEX_0		(1 << 0)
+#define MPEG_BIT_RATE_INDEX_1		(1 << 1)
+#define MPEG_BIT_RATE_INDEX_2		(1 << 2)
+#define MPEG_BIT_RATE_INDEX_3		(1 << 3)
+#define MPEG_BIT_RATE_INDEX_4		(1 << 4)
+#define MPEG_BIT_RATE_INDEX_5		(1 << 5)
+#define MPEG_BIT_RATE_INDEX_6		(1 << 6)
+#define MPEG_BIT_RATE_INDEX_7		(1 << 7)
+#define MPEG_BIT_RATE_INDEX_8		(1 << 8)
+#define MPEG_BIT_RATE_INDEX_9		(1 << 9)
+#define MPEG_BIT_RATE_INDEX_10		(1 << 10)
+#define MPEG_BIT_RATE_INDEX_11		(1 << 11)
+#define MPEG_BIT_RATE_INDEX_12		(1 << 12)
+#define MPEG_BIT_RATE_INDEX_13		(1 << 13)
+#define MPEG_BIT_RATE_INDEX_14		(1 << 14)
+
+#define MPEG_MP1_BIT_RATE_32000		MPEG_BIT_RATE_INDEX_1
+#define MPEG_MP1_BIT_RATE_64000		MPEG_BIT_RATE_INDEX_2
+#define MPEG_MP1_BIT_RATE_96000		MPEG_BIT_RATE_INDEX_3
+#define MPEG_MP1_BIT_RATE_128000	MPEG_BIT_RATE_INDEX_4
+#define MPEG_MP1_BIT_RATE_160000	MPEG_BIT_RATE_INDEX_5
+#define MPEG_MP1_BIT_RATE_192000	MPEG_BIT_RATE_INDEX_6
+#define MPEG_MP1_BIT_RATE_224000	MPEG_BIT_RATE_INDEX_7
+#define MPEG_MP1_BIT_RATE_256000	MPEG_BIT_RATE_INDEX_8
+#define MPEG_MP1_BIT_RATE_288000	MPEG_BIT_RATE_INDEX_9
+#define MPEG_MP1_BIT_RATE_320000	MPEG_BIT_RATE_INDEX_10
+#define MPEG_MP1_BIT_RATE_352000	MPEG_BIT_RATE_INDEX_11
+#define MPEG_MP1_BIT_RATE_384000	MPEG_BIT_RATE_INDEX_12
+#define MPEG_MP1_BIT_RATE_416000	MPEG_BIT_RATE_INDEX_13
+#define MPEG_MP1_BIT_RATE_448000	MPEG_BIT_RATE_INDEX_14
+
+#define MPEG_MP2_BIT_RATE_32000		MPEG_BIT_RATE_INDEX_1
+#define MPEG_MP2_BIT_RATE_48000		MPEG_BIT_RATE_INDEX_2
+#define MPEG_MP2_BIT_RATE_56000		MPEG_BIT_RATE_INDEX_3
+#define MPEG_MP2_BIT_RATE_64000		MPEG_BIT_RATE_INDEX_4
+#define MPEG_MP2_BIT_RATE_80000		MPEG_BIT_RATE_INDEX_5
+#define MPEG_MP2_BIT_RATE_96000		MPEG_BIT_RATE_INDEX_6
+#define MPEG_MP2_BIT_RATE_112000	MPEG_BIT_RATE_INDEX_7
+#define MPEG_MP2_BIT_RATE_128000	MPEG_BIT_RATE_INDEX_8
+#define MPEG_MP2_BIT_RATE_160000	MPEG_BIT_RATE_INDEX_9
+#define MPEG_MP2_BIT_RATE_192000	MPEG_BIT_RATE_INDEX_10
+#define MPEG_MP2_BIT_RATE_224000	MPEG_BIT_RATE_INDEX_11
+#define MPEG_MP2_BIT_RATE_256000	MPEG_BIT_RATE_INDEX_12
+#define MPEG_MP2_BIT_RATE_320000	MPEG_BIT_RATE_INDEX_13
+#define MPEG_MP2_BIT_RATE_384000	MPEG_BIT_RATE_INDEX_14
+
+#define MPEG_MP3_BIT_RATE_32000		MPEG_BIT_RATE_INDEX_1
+#define MPEG_MP3_BIT_RATE_40000		MPEG_BIT_RATE_INDEX_2
+#define MPEG_MP3_BIT_RATE_48000		MPEG_BIT_RATE_INDEX_3
+#define MPEG_MP3_BIT_RATE_56000		MPEG_BIT_RATE_INDEX_4
+#define MPEG_MP3_BIT_RATE_64000		MPEG_BIT_RATE_INDEX_5
+#define MPEG_MP3_BIT_RATE_80000		MPEG_BIT_RATE_INDEX_6
+#define MPEG_MP3_BIT_RATE_96000		MPEG_BIT_RATE_INDEX_7
+#define MPEG_MP3_BIT_RATE_112000	MPEG_BIT_RATE_INDEX_8
+#define MPEG_MP3_BIT_RATE_128000	MPEG_BIT_RATE_INDEX_9
+#define MPEG_MP3_BIT_RATE_160000	MPEG_BIT_RATE_INDEX_10
+#define MPEG_MP3_BIT_RATE_192000	MPEG_BIT_RATE_INDEX_11
+#define MPEG_MP3_BIT_RATE_224000	MPEG_BIT_RATE_INDEX_12
+#define MPEG_MP3_BIT_RATE_256000	MPEG_BIT_RATE_INDEX_13
+#define MPEG_MP3_BIT_RATE_320000	MPEG_BIT_RATE_INDEX_14
+
+#define MPEG_BIT_RATE_FREE		MPEG_BIT_RATE_INDEX_0
+
+#define MPEG_GET_BITRATE(a) ((uint16_t)(a).bitrate1 << 8 | (a).bitrate2)
+#define MPEG_SET_BITRATE(a, b) \
+	do { \
+		(a).bitrate1 = ((b) >> 8) & 0x7f; \
+		(a).bitrate2 = (b) & 0xff; \
+	} while (0)
 
 #define AAC_OBJECT_TYPE_MPEG2_AAC_LC	0x80
 #define AAC_OBJECT_TYPE_MPEG4_AAC_LC	0x40
@@ -168,7 +221,9 @@ typedef struct {
 	uint8_t frequency:6;
 	uint8_t mpf:1;
 	uint8_t rfa:1;
-	uint16_t bitrate;
+	uint8_t bitrate1:7;
+	uint8_t vbr:1;
+	uint8_t bitrate2;
 } __attribute__ ((packed)) a2dp_mpeg_t;
 
 typedef struct {
@@ -213,7 +268,9 @@ typedef struct {
 	uint8_t rfa:1;
 	uint8_t mpf:1;
 	uint8_t frequency:6;
-	uint16_t bitrate;
+	uint8_t vbr:1;
+	uint8_t bitrate1:7;
+	uint8_t bitrate2;
 } __attribute__ ((packed)) a2dp_mpeg_t;
 
 typedef struct {
diff --git a/tools/avinfo.c b/tools/avinfo.c
index b79446825..bb80cf583 100644
--- a/tools/avinfo.c
+++ b/tools/avinfo.c
@@ -303,11 +303,15 @@ static void print_mpeg24(a2dp_aac_t *aac, uint8_t size)
 
 static void print_mpeg12(a2dp_mpeg_t *mpeg, uint8_t size)
 {
+	uint16_t bitrate;
+
 	if (size < sizeof(*mpeg)) {
 		printf("\tMedia Codec: MPEG12 (broken)\n");
 		return;
 	}
 
+	bitrate = MPEG_GET_BITRATE(*mpeg);
+
 	printf("\tMedia Codec: MPEG12\n\t\tChannel Modes: ");
 
 	if (mpeg->channel_mode & MPEG_CHANNEL_MODE_MONO)
@@ -343,42 +347,105 @@ static void print_mpeg12(a2dp_mpeg_t *mpeg, uint8_t size)
 	if (mpeg->layer & MPEG_LAYER_MP3)
 		printf("3 ");
 
-	printf("\n\t\tBit Rate: ");
-	if (mpeg->bitrate & MPEG_BIT_RATE_FREE)
-		printf("Free format");
-	else {
-		if (mpeg->bitrate & MPEG_BIT_RATE_32000)
-			printf("32kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_40000)
-			printf("40kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_48000)
-			printf("48kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_56000)
-			printf("56kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_64000)
-			printf("64kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_80000)
-			printf("80kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_96000)
-			printf("96kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_112000)
-			printf("112kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_128000)
-			printf("128kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_160000)
-			printf("160kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_192000)
-			printf("192kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_224000)
-			printf("224kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_256000)
-			printf("256kbps ");
-		if (mpeg->bitrate & MPEG_BIT_RATE_320000)
-			printf("320kbps ");
+	if (bitrate & MPEG_BIT_RATE_FREE) {
+		printf("\n\t\tBit Rate: Free format");
+	} else {
+		if (mpeg->layer & MPEG_LAYER_MP1) {
+			printf("\n\t\tLayer 1 Bit Rate: ");
+			if (bitrate & MPEG_MP1_BIT_RATE_32000)
+				printf("32kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_64000)
+				printf("64kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_96000)
+				printf("96kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_128000)
+				printf("128kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_160000)
+				printf("160kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_192000)
+				printf("192kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_224000)
+				printf("224kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_256000)
+				printf("256kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_320000)
+				printf("320kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_352000)
+				printf("352kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_384000)
+				printf("384kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_416000)
+				printf("416kbps ");
+			if (bitrate & MPEG_MP1_BIT_RATE_448000)
+				printf("448kbps ");
+		}
+
+		if (mpeg->layer & MPEG_LAYER_MP2) {
+			printf("\n\t\tLayer 2 Bit Rate: ");
+			if (bitrate & MPEG_MP2_BIT_RATE_32000)
+				printf("32kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_48000)
+				printf("48kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_56000)
+				printf("56kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_64000)
+				printf("64kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_80000)
+				printf("80kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_96000)
+				printf("96kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_112000)
+				printf("112kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_128000)
+				printf("128kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_160000)
+				printf("160kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_192000)
+				printf("192kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_224000)
+				printf("224kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_256000)
+				printf("256kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_320000)
+				printf("320kbps ");
+			if (bitrate & MPEG_MP2_BIT_RATE_384000)
+				printf("384kbps ");
+		}
+
+		if (mpeg->layer & MPEG_LAYER_MP3) {
+			printf("\n\t\tLayer 3 Bit Rate: ");
+			if (bitrate & MPEG_MP3_BIT_RATE_32000)
+				printf("32kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_40000)
+				printf("40kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_48000)
+				printf("48kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_56000)
+				printf("56kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_64000)
+				printf("64kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_80000)
+				printf("80kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_96000)
+				printf("96kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_112000)
+				printf("112kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_128000)
+				printf("128kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_160000)
+				printf("160kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_192000)
+				printf("192kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_224000)
+				printf("224kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_256000)
+				printf("256kbps ");
+			if (bitrate & MPEG_MP3_BIT_RATE_320000)
+				printf("320kbps ");
+		}
 	}
 
-	printf("\n\t\tVBR: %s", mpeg->bitrate & MPEG_BIT_RATE_VBR ? "Yes" :
-		"No");
+	printf("\n\t\tVBR: %s", mpeg->vbr ? "Yes" : "No");
 
 	printf("\n\t\tPayload Format: ");
 	if (mpeg->mpf)
-- 
2.11.0


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

* [PATCH v2 06/10] a2dp-codecs: Define a2dp_vendor_codec_t struct in endian neutral way
  2018-12-23 10:40 ` [PATCH v2 " Pali Rohár
                     ` (4 preceding siblings ...)
  2018-12-23 10:40   ` [PATCH v2 05/10] a2dp-codecs & avinfo: Fix parsing MPEG bit rate values Pali Rohár
@ 2018-12-23 10:40   ` Pali Rohár
  2018-12-23 10:40   ` [PATCH v2 07/10] a2dp-codecs: Add needed includes and properly check for endian macros Pali Rohár
                     ` (4 subsequent siblings)
  10 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2018-12-23 10:40 UTC (permalink / raw)
  To: linux-bluetooth

And define new macros A2DP_GET_VENDOR_ID(), A2DP_GET_CODEC_ID() and
A2DP_SET_VENDOR_ID_CODEC_ID() for easily filling a2dp_vendor_codec_t
struct.
---
 android/a2dp.c               |  8 ++++----
 android/avdtp.c              |  6 ++++--
 android/hal-audio-aptx.c     | 18 ++++++------------
 profiles/audio/a2dp-codecs.h | 24 ++++++++++++++++++++++--
 profiles/audio/a2dp.c        |  9 +++++----
 tools/avinfo.c               |  4 ++--
 6 files changed, 43 insertions(+), 26 deletions(-)

diff --git a/android/a2dp.c b/android/a2dp.c
index f21904208..8bcdfd20f 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -417,8 +417,8 @@ static int check_capabilities(struct a2dp_preset *preset,
 								preset->len);
 	case A2DP_CODEC_VENDOR:
 		vndcodec = (void *) codec->data;
-		if (btohl(vndcodec->vendor_id) == APTX_VENDOR_ID &&
-				btohs(vndcodec->codec_id) == APTX_CODEC_ID)
+		if (A2DP_GET_VENDOR_ID(*vndcodec) == APTX_VENDOR_ID &&
+				A2DP_GET_CODEC_ID(*vndcodec) == APTX_CODEC_ID)
 			return aptx_check_config(codec->data, codec_len,
 						preset->data, preset->len);
 		return -EINVAL;
@@ -1344,8 +1344,8 @@ static uint8_t register_endpoint(const uint8_t *uuid, uint8_t codec,
 		a2dp_vendor_codec_t *vndcodec = (void *) endpoint->caps->data;
 
 		avdtp_sep_set_vendor_codec(endpoint->sep,
-						btohl(vndcodec->vendor_id),
-						btohs(vndcodec->codec_id));
+						A2DP_GET_VENDOR_ID(*vndcodec),
+						A2DP_GET_CODEC_ID(*vndcodec));
 	}
 
 	endpoints = g_slist_append(endpoints, endpoint);
diff --git a/android/avdtp.c b/android/avdtp.c
index 34caf3db5..7fb8cb731 100644
--- a/android/avdtp.c
+++ b/android/avdtp.c
@@ -1103,10 +1103,12 @@ struct avdtp_remote_sep *avdtp_find_remote_sep(struct avdtp *session,
 			a2dp_vendor_codec_t *vndcodec =
 						(void *) codec_data->data;
 
-			if (btohl(vndcodec->vendor_id) != lsep->vndcodec_vendor)
+			if (A2DP_GET_VENDOR_ID(*vndcodec) !=
+					lsep->vndcodec_vendor)
 				continue;
 
-			if (btohs(vndcodec->codec_id) != lsep->vndcodec_codec)
+			if (A2DP_GET_CODEC_ID(*vndcodec) !=
+					lsep->vndcodec_codec)
 				continue;
 		}
 
diff --git a/android/hal-audio-aptx.c b/android/hal-audio-aptx.c
index bff2331a9..4e364fc65 100644
--- a/android/hal-audio-aptx.c
+++ b/android/hal-audio-aptx.c
@@ -37,27 +37,21 @@ struct aptx_data {
 
 static const a2dp_aptx_t aptx_presets[] = {
 	{
-		.info = {
-			.vendor_id = APTX_VENDOR_ID,
-			.codec_id = APTX_CODEC_ID,
-		},
+		.info =
+		    A2DP_SET_VENDOR_ID_CODEC_ID(APTX_VENDOR_ID, APTX_CODEC_ID),
 		.frequency = APTX_SAMPLING_FREQ_44100 |
 						APTX_SAMPLING_FREQ_48000,
 		.channel_mode = APTX_CHANNEL_MODE_STEREO,
 	},
 	{
-		.info = {
-			.vendor_id = APTX_VENDOR_ID,
-			.codec_id = APTX_CODEC_ID,
-		},
+		.info =
+		    A2DP_SET_VENDOR_ID_CODEC_ID(APTX_VENDOR_ID, APTX_CODEC_ID),
 		.frequency = APTX_SAMPLING_FREQ_48000,
 		.channel_mode = APTX_CHANNEL_MODE_STEREO,
 	},
 	{
-		.info = {
-			.vendor_id = APTX_VENDOR_ID,
-			.codec_id = APTX_CODEC_ID,
-		},
+		.info =
+		    A2DP_SET_VENDOR_ID_CODEC_ID(APTX_VENDOR_ID, APTX_CODEC_ID),
 		.frequency = APTX_SAMPLING_FREQ_44100,
 		.channel_mode = APTX_CHANNEL_MODE_STEREO,
 	},
diff --git a/profiles/audio/a2dp-codecs.h b/profiles/audio/a2dp-codecs.h
index 47030bcc1..a310efe49 100644
--- a/profiles/audio/a2dp-codecs.h
+++ b/profiles/audio/a2dp-codecs.h
@@ -198,10 +198,30 @@
 #define LDAC_CODEC_ID			0x00aa
 
 typedef struct {
-	uint32_t vendor_id;
-	uint16_t codec_id;
+	uint8_t vendor_id4;
+	uint8_t vendor_id3;
+	uint8_t vendor_id2;
+	uint8_t vendor_id1;
+	uint8_t codec_id2;
+	uint8_t codec_id1;
 } __attribute__ ((packed)) a2dp_vendor_codec_t;
 
+#define A2DP_GET_VENDOR_ID(a) ( \
+		(((uint32_t)(a).vendor_id4) <<  0) | \
+		(((uint32_t)(a).vendor_id3) <<  8) | \
+		(((uint32_t)(a).vendor_id2) << 16) | \
+		(((uint32_t)(a).vendor_id1) << 24) \
+	)
+#define A2DP_GET_CODEC_ID(a) ((a).codec_id2 | (((uint16_t)(a).codec_id1) << 8))
+#define A2DP_SET_VENDOR_ID_CODEC_ID(v, c) ((a2dp_vendor_codec_t){ \
+		.vendor_id4 = (((v) >>  0) & 0xff), \
+		.vendor_id3 = (((v) >>  8) & 0xff), \
+		.vendor_id2 = (((v) >> 16) & 0xff), \
+		.vendor_id1 = (((v) >> 24) & 0xff), \
+		.codec_id2 = (((c) >> 0) & 0xff), \
+		.codec_id1 = (((c) >> 8) & 0xff), \
+	})
+
 #if __BYTE_ORDER == __LITTLE_ENDIAN
 
 typedef struct {
diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index fc98bb264..344459332 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
@@ -523,14 +523,15 @@ static gboolean endpoint_match_codec_ind(struct avdtp *session,
 	local_codec = (a2dp_vendor_codec_t *) capabilities;
 	remote_codec = (a2dp_vendor_codec_t *) codec->data;
 
-	if (remote_codec->vendor_id != local_codec->vendor_id)
+	if (A2DP_GET_VENDOR_ID(*remote_codec) !=
+			A2DP_GET_VENDOR_ID(*local_codec))
 		return FALSE;
 
-	if (remote_codec->codec_id != local_codec->codec_id)
+	if (A2DP_GET_CODEC_ID(*remote_codec) != A2DP_GET_CODEC_ID(*local_codec))
 		return FALSE;
 
-	DBG("vendor 0x%08x codec 0x%04x", btohl(remote_codec->vendor_id),
-						btohs(remote_codec->codec_id));
+	DBG("vendor 0x%08x codec 0x%04x", A2DP_GET_VENDOR_ID(*remote_codec),
+					A2DP_GET_CODEC_ID(*remote_codec));
 	return TRUE;
 }
 
diff --git a/tools/avinfo.c b/tools/avinfo.c
index bb80cf583..9a07e675d 100644
--- a/tools/avinfo.c
+++ b/tools/avinfo.c
@@ -221,8 +221,8 @@ static void print_vendor(a2dp_vendor_codec_t *vendor, uint8_t size)
 		return;
 	}
 
-	vendor_id = btohl(vendor->vendor_id);
-	codec_id = btohs(vendor->codec_id);
+	vendor_id = A2DP_GET_VENDOR_ID(*vendor);
+	codec_id = A2DP_GET_CODEC_ID(*vendor);
 
 	printf("\tMedia Codec: Vendor Specific A2DP Codec");
 
-- 
2.11.0


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

* [PATCH v2 07/10] a2dp-codecs: Add needed includes and properly check for endian macros
  2018-12-23 10:40 ` [PATCH v2 " Pali Rohár
                     ` (5 preceding siblings ...)
  2018-12-23 10:40   ` [PATCH v2 06/10] a2dp-codecs: Define a2dp_vendor_codec_t struct in endian neutral way Pali Rohár
@ 2018-12-23 10:40   ` Pali Rohár
  2018-12-23 10:40   ` [PATCH v2 08/10] a2dp-codecs: Properly define macros and struct for LDAC codec Pali Rohár
                     ` (3 subsequent siblings)
  10 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2018-12-23 10:40 UTC (permalink / raw)
  To: linux-bluetooth

Without stdint.h type uint8_t cannot be used.

And without endian.h macros __BYTE_ORDER, __LITTLE_ENDIAN and __BIG_ENDIAN
are not defined.

When both __BYTE_ORDER and __LITTLE_ENDIAN macros are not defined, then
condition #if __BYTE_ORDER == __LITTLE_ENDIAN is true.
---
 profiles/audio/a2dp-codecs.h | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/profiles/audio/a2dp-codecs.h b/profiles/audio/a2dp-codecs.h
index a310efe49..649e2411b 100644
--- a/profiles/audio/a2dp-codecs.h
+++ b/profiles/audio/a2dp-codecs.h
@@ -22,6 +22,9 @@
  *
  */
 
+#include <endian.h>
+#include <stdint.h>
+
 #define A2DP_CODEC_SBC			0x00
 #define A2DP_CODEC_MPEG12		0x01
 #define A2DP_CODEC_MPEG24		0x02
@@ -222,7 +225,8 @@ typedef struct {
 		.codec_id1 = (((c) >> 8) & 0xff), \
 	})
 
-#if __BYTE_ORDER == __LITTLE_ENDIAN
+#if defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \
+	__BYTE_ORDER == __LITTLE_ENDIAN
 
 typedef struct {
 	uint8_t channel_mode:4;
@@ -269,7 +273,8 @@ typedef struct {
 	uint8_t unknown[2];
 } __attribute__ ((packed)) a2dp_ldac_t;
 
-#elif __BYTE_ORDER == __BIG_ENDIAN
+#elif defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \
+	__BYTE_ORDER == __BIG_ENDIAN
 
 typedef struct {
 	uint8_t frequency:4;
-- 
2.11.0


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

* [PATCH v2 08/10] a2dp-codecs: Properly define macros and struct for LDAC codec
  2018-12-23 10:40 ` [PATCH v2 " Pali Rohár
                     ` (6 preceding siblings ...)
  2018-12-23 10:40   ` [PATCH v2 07/10] a2dp-codecs: Add needed includes and properly check for endian macros Pali Rohár
@ 2018-12-23 10:40   ` Pali Rohár
  2018-12-23 10:40   ` [PATCH v2 09/10] a2dp-codecs: Add macros and structures for new codecs Pali Rohár
                     ` (2 subsequent siblings)
  10 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2018-12-23 10:40 UTC (permalink / raw)
  To: linux-bluetooth

---
 profiles/audio/a2dp-codecs.h | 27 +++++++++++++++++----------
 tools/avinfo.c               |  4 ++--
 2 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/profiles/audio/a2dp-codecs.h b/profiles/audio/a2dp-codecs.h
index 649e2411b..6f667d3aa 100644
--- a/profiles/audio/a2dp-codecs.h
+++ b/profiles/audio/a2dp-codecs.h
@@ -200,6 +200,17 @@
 #define LDAC_VENDOR_ID			0x0000012d
 #define LDAC_CODEC_ID			0x00aa
 
+#define LDAC_SAMPLING_FREQ_44100	0x20
+#define LDAC_SAMPLING_FREQ_48000	0x10
+#define LDAC_SAMPLING_FREQ_88200	0x08
+#define LDAC_SAMPLING_FREQ_96000	0x04
+#define LDAC_SAMPLING_FREQ_176400	0x02
+#define LDAC_SAMPLING_FREQ_192000	0x01
+
+#define LDAC_CHANNEL_MODE_MONO		0x04
+#define LDAC_CHANNEL_MODE_DUAL		0x02
+#define LDAC_CHANNEL_MODE_STEREO	0x01
+
 typedef struct {
 	uint8_t vendor_id4;
 	uint8_t vendor_id3;
@@ -225,6 +236,12 @@ typedef struct {
 		.codec_id1 = (((c) >> 8) & 0xff), \
 	})
 
+typedef struct {
+	a2dp_vendor_codec_t info;
+	uint8_t frequency;
+	uint8_t channel_mode;
+} __attribute__ ((packed)) a2dp_ldac_t;
+
 #if defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \
 	__BYTE_ORDER == __LITTLE_ENDIAN
 
@@ -268,11 +285,6 @@ typedef struct {
 	uint8_t frequency:4;
 } __attribute__ ((packed)) a2dp_aptx_t;
 
-typedef struct {
-	a2dp_vendor_codec_t info;
-	uint8_t unknown[2];
-} __attribute__ ((packed)) a2dp_ldac_t;
-
 #elif defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \
 	__BYTE_ORDER == __BIG_ENDIAN
 
@@ -316,11 +328,6 @@ typedef struct {
 	uint8_t channel_mode:4;
 } __attribute__ ((packed)) a2dp_aptx_t;
 
-typedef struct {
-	a2dp_vendor_codec_t info;
-	uint8_t unknown[2];
-} __attribute__ ((packed)) a2dp_ldac_t;
-
 #else
 #error "Unknown byte order"
 #endif
diff --git a/tools/avinfo.c b/tools/avinfo.c
index 9a07e675d..9d5c4e511 100644
--- a/tools/avinfo.c
+++ b/tools/avinfo.c
@@ -204,8 +204,8 @@ static void print_ldac(a2dp_ldac_t *ldac, uint8_t size)
 		return;
 	}
 
-	printf("\n\t\t\tUnknown: %02x %02x", ldac->unknown[0],
-							ldac->unknown[1]);
+	printf("\n\t\t\tUnknown: %02x %02x", ldac->frequency,
+							ldac->channel_mode);
 
 	printf("\n");
 }
-- 
2.11.0


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

* [PATCH v2 09/10] a2dp-codecs: Add macros and structures for new codecs
  2018-12-23 10:40 ` [PATCH v2 " Pali Rohár
                     ` (7 preceding siblings ...)
  2018-12-23 10:40   ` [PATCH v2 08/10] a2dp-codecs: Properly define macros and struct for LDAC codec Pali Rohár
@ 2018-12-23 10:40   ` Pali Rohár
  2018-12-23 10:40   ` [PATCH v2 10/10] avinfo: Parse new A2DP codecs Pali Rohár
  2018-12-28 18:23   ` [PATCH v2 00/10] A2DP: Fix endianity and define " Luiz Augusto von Dentz
  10 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2018-12-23 10:40 UTC (permalink / raw)
  To: linux-bluetooth

Add additional codecs: FastStream, aptX Low Latency and aptX HD codecs.
---
 profiles/audio/a2dp-codecs.h | 120 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 120 insertions(+)

diff --git a/profiles/audio/a2dp-codecs.h b/profiles/audio/a2dp-codecs.h
index 6f667d3aa..0bdd29110 100644
--- a/profiles/audio/a2dp-codecs.h
+++ b/profiles/audio/a2dp-codecs.h
@@ -4,6 +4,7 @@
  *
  *  Copyright (C) 2006-2010  Nokia Corporation
  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2018       Pali Rohár <pali.rohar@gmail.com>
  *
  *
  *  This library is free software; you can redistribute it and/or
@@ -197,6 +198,59 @@
 #define APTX_SAMPLING_FREQ_44100	0x02
 #define APTX_SAMPLING_FREQ_48000	0x01
 
+#define FASTSTREAM_VENDOR_ID		0x0000000a
+#define FASTSTREAM_CODEC_ID		0x0001
+
+#define FASTSTREAM_DIRECTION_SINK	0x1
+#define FASTSTREAM_DIRECTION_SOURCE	0x2
+
+#define FASTSTREAM_SINK_SAMPLING_FREQ_44100	0x2
+#define FASTSTREAM_SINK_SAMPLING_FREQ_48000	0x1
+
+#define FASTSTREAM_SOURCE_SAMPLING_FREQ_16000	0x2
+
+#define APTX_LL_VENDOR_ID		0x0000000a
+#define APTX_LL_CODEC_ID		0x0002
+
+#define APTX_LL_CHANNEL_MODE_MONO	0x01
+#define APTX_LL_CHANNEL_MODE_STEREO	0x02
+
+#define APTX_LL_SAMPLING_FREQ_16000	0x08
+#define APTX_LL_SAMPLING_FREQ_32000	0x04
+#define APTX_LL_SAMPLING_FREQ_44100	0x02
+#define APTX_LL_SAMPLING_FREQ_48000	0x01
+
+/* Default parameters for aptX Low Latency encoder */
+
+/* Target codec buffer level = 180 */
+#define APTX_LL_TARGET_LEVEL2	0xb4
+#define APTX_LL_TARGET_LEVEL1	0x00
+
+/* Initial codec buffer level = 360 */
+#define APTX_LL_INITIAL_LEVEL2	0x68
+#define APTX_LL_INITIAL_LEVEL1	0x01
+
+/* SRA max rate 0.005 * 10000 = 50 */
+#define APTX_LL_SRA_MAX_RATE		0x32
+
+/* SRA averaging time = 1s */
+#define APTX_LL_SRA_AVG_TIME		0x01
+
+/* Good working codec buffer level = 180 */
+#define APTX_LL_GOOD_WORKING_LEVEL2	0xB4
+#define APTX_LL_GOOD_WORKING_LEVEL1	0x00
+
+#define APTX_HD_VENDOR_ID		0x000000D7
+#define APTX_HD_CODEC_ID		0x0024
+
+#define APTX_HD_CHANNEL_MODE_MONO	0x1
+#define APTX_HD_CHANNEL_MODE_STEREO	0x2
+
+#define APTX_HD_SAMPLING_FREQ_16000	0x8
+#define APTX_HD_SAMPLING_FREQ_32000	0x4
+#define APTX_HD_SAMPLING_FREQ_44100	0x2
+#define APTX_HD_SAMPLING_FREQ_48000	0x1
+
 #define LDAC_VENDOR_ID			0x0000012d
 #define LDAC_CODEC_ID			0x00aa
 
@@ -237,6 +291,18 @@ typedef struct {
 	})
 
 typedef struct {
+	uint8_t reserved;
+	uint8_t target_level2;
+	uint8_t target_level1;
+	uint8_t initial_level2;
+	uint8_t initial_level1;
+	uint8_t sra_max_rate;
+	uint8_t sra_avg_time;
+	uint8_t good_working_level2;
+	uint8_t good_working_level1;
+} __attribute__ ((packed)) a2dp_aptx_ll_new_caps_t;
+
+typedef struct {
 	a2dp_vendor_codec_t info;
 	uint8_t frequency;
 	uint8_t channel_mode;
@@ -285,6 +351,33 @@ typedef struct {
 	uint8_t frequency:4;
 } __attribute__ ((packed)) a2dp_aptx_t;
 
+typedef struct {
+	a2dp_vendor_codec_t info;
+	uint8_t direction;
+	uint8_t sink_frequency:4;
+	uint8_t source_frequency:4;
+} __attribute__ ((packed)) a2dp_faststream_t;
+
+typedef struct {
+	a2dp_vendor_codec_t info;
+	uint8_t channel_mode:4;
+	uint8_t frequency:4;
+	uint8_t bidirect_link:1;
+	uint8_t has_new_caps:1;
+	uint8_t reserved:6;
+	a2dp_aptx_ll_new_caps_t new_caps[0];
+} __attribute__ ((packed)) a2dp_aptx_ll_t;
+
+typedef struct {
+	a2dp_vendor_codec_t info;
+	uint8_t channel_mode:4;
+	uint8_t frequency:4;
+	uint8_t reserved0;
+	uint8_t reserved1;
+	uint8_t reserved2;
+	uint8_t reserved3;
+} __attribute__ ((packed)) a2dp_aptx_hd_t;
+
 #elif defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \
 	__BYTE_ORDER == __BIG_ENDIAN
 
@@ -328,6 +421,33 @@ typedef struct {
 	uint8_t channel_mode:4;
 } __attribute__ ((packed)) a2dp_aptx_t;
 
+typedef struct {
+	a2dp_vendor_codec_t info;
+	uint8_t direction;
+	uint8_t source_frequency:4;
+	uint8_t sink_frequency:4;
+} __attribute__ ((packed)) a2dp_faststream_t;
+
+typedef struct {
+	a2dp_vendor_codec_t info;
+	uint8_t frequency:4;
+	uint8_t channel_mode:4;
+	uint8_t reserved:6;
+	uint8_t has_new_caps:1;
+	uint8_t bidirect_link:1;
+	a2dp_aptx_ll_new_caps_t new_caps[0];
+} __attribute__ ((packed)) a2dp_aptx_ll_t;
+
+typedef struct {
+	a2dp_vendor_codec_t info;
+	uint8_t frequency:4;
+	uint8_t channel_mode:4;
+	uint8_t reserved0;
+	uint8_t reserved1;
+	uint8_t reserved2;
+	uint8_t reserved3;
+} __attribute__ ((packed)) a2dp_aptx_hd_t;
+
 #else
 #error "Unknown byte order"
 #endif
-- 
2.11.0


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

* [PATCH v2 10/10] avinfo: Parse new A2DP codecs
  2018-12-23 10:40 ` [PATCH v2 " Pali Rohár
                     ` (8 preceding siblings ...)
  2018-12-23 10:40   ` [PATCH v2 09/10] a2dp-codecs: Add macros and structures for new codecs Pali Rohár
@ 2018-12-23 10:40   ` Pali Rohár
  2018-12-28 18:23   ` [PATCH v2 00/10] A2DP: Fix endianity and define " Luiz Augusto von Dentz
  10 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2018-12-23 10:40 UTC (permalink / raw)
  To: linux-bluetooth

Parse information about additional A2DP codecs: FastStream, aptX Low
Latency, aptX HD and LDAC.
---
 tools/avinfo.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 144 insertions(+), 2 deletions(-)

diff --git a/tools/avinfo.c b/tools/avinfo.c
index 9d5c4e511..4f25f116c 100644
--- a/tools/avinfo.c
+++ b/tools/avinfo.c
@@ -4,6 +4,7 @@
  *
  *  Copyright (C) 2006-2010  Nokia Corporation
  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2018       Pali Rohár <pali.rohar@gmail.com>
  *
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -195,6 +196,121 @@ static void print_aptx(a2dp_aptx_t *aptx, uint8_t size)
 	printf("\n");
 }
 
+static void print_faststream(a2dp_faststream_t *faststream, uint8_t size)
+{
+	printf("\t\tVendor Specific Value (FastStream)");
+
+	if (size < sizeof(*faststream)) {
+		printf(" (broken)\n");
+		return;
+	}
+
+	printf("\n\t\t\tDirections: ");
+	if (faststream->direction & FASTSTREAM_DIRECTION_SINK)
+		printf("sink ");
+	if (faststream->direction & FASTSTREAM_DIRECTION_SOURCE)
+		printf("source ");
+
+	if (faststream->direction & FASTSTREAM_DIRECTION_SINK) {
+		printf("\n\t\t\tSink Frequencies: ");
+		if (faststream->sink_frequency &
+				FASTSTREAM_SINK_SAMPLING_FREQ_44100)
+			printf("44.1kHz ");
+		if (faststream->sink_frequency &
+				FASTSTREAM_SINK_SAMPLING_FREQ_48000)
+			printf("48kHz ");
+	}
+
+	if (faststream->direction & FASTSTREAM_DIRECTION_SOURCE) {
+		printf("\n\t\t\tSource Frequencies: ");
+		if (faststream->source_frequency &
+				FASTSTREAM_SOURCE_SAMPLING_FREQ_16000)
+			printf("16kHz ");
+	}
+
+	printf("\n");
+}
+
+static void print_aptx_ll(a2dp_aptx_ll_t *aptx_ll, uint8_t size)
+{
+	a2dp_aptx_ll_new_caps_t *aptx_ll_new;
+
+	printf("\t\tVendor Specific Value (aptX Low Latency)");
+
+	if (size < sizeof(*aptx_ll)) {
+		printf(" (broken)\n");
+		return;
+	}
+
+	printf("\n\t\t\tFrequencies: ");
+	if (aptx_ll->frequency & APTX_LL_SAMPLING_FREQ_16000)
+		printf("16kHz ");
+	if (aptx_ll->frequency & APTX_LL_SAMPLING_FREQ_32000)
+		printf("32kHz ");
+	if (aptx_ll->frequency & APTX_LL_SAMPLING_FREQ_44100)
+		printf("44.1kHz ");
+	if (aptx_ll->frequency & APTX_LL_SAMPLING_FREQ_48000)
+		printf("48kHz ");
+
+	printf("\n\t\t\tChannel modes: ");
+	if (aptx_ll->channel_mode & APTX_LL_CHANNEL_MODE_MONO)
+		printf("Mono ");
+	if (aptx_ll->channel_mode & APTX_LL_CHANNEL_MODE_STEREO)
+		printf("Stereo ");
+
+	printf("\n\t\tBidirectional link: %s",
+			aptx_ll->bidirect_link ? "Yes" : "No");
+
+	aptx_ll_new = &aptx_ll->new_caps[0];
+	if (aptx_ll->has_new_caps &&
+	    size >= sizeof(*aptx_ll) + sizeof(*aptx_ll_new)) {
+		printf("\n\t\tTarget codec buffer level: %u",
+			(unsigned int)aptx_ll_new->target_level2 |
+			((unsigned int)(aptx_ll_new->target_level1) << 8));
+		printf("\n\t\tInitial codec buffer level: %u",
+			(unsigned int)aptx_ll_new->initial_level2 |
+			((unsigned int)(aptx_ll_new->initial_level1) << 8));
+		printf("\n\t\tSRA max rate: %g",
+			aptx_ll_new->sra_max_rate / 10000.0);
+		printf("\n\t\tSRA averaging time: %us",
+			(unsigned int)aptx_ll_new->sra_avg_time);
+		printf("\n\t\tGood working codec buffer level: %u",
+			(unsigned int)aptx_ll_new->good_working_level2 |
+			((unsigned int)(aptx_ll_new->good_working_level1) << 8)
+			);
+	}
+
+	printf("\n");
+}
+
+static void print_aptx_hd(a2dp_aptx_hd_t *aptx_hd, uint8_t size)
+{
+	printf("\t\tVendor Specific Value (aptX HD)");
+
+	if (size < sizeof(*aptx_hd)) {
+		printf(" (broken)\n");
+		return;
+	}
+
+	printf("\n\t\t\tFrequencies: ");
+	if (aptx_hd->frequency & APTX_HD_SAMPLING_FREQ_16000)
+		printf("16kHz ");
+	if (aptx_hd->frequency & APTX_HD_SAMPLING_FREQ_32000)
+		printf("32kHz ");
+	if (aptx_hd->frequency & APTX_HD_SAMPLING_FREQ_44100)
+		printf("44.1kHz ");
+	if (aptx_hd->frequency & APTX_HD_SAMPLING_FREQ_48000)
+		printf("48kHz ");
+
+	printf("\n\t\t\tChannel modes: ");
+	if (aptx_hd->channel_mode & APTX_HD_CHANNEL_MODE_MONO)
+		printf("Mono ");
+	if (aptx_hd->channel_mode & APTX_HD_CHANNEL_MODE_STEREO)
+		printf("Stereo ");
+
+	printf("\n");
+}
+
 static void print_ldac(a2dp_ldac_t *ldac, uint8_t size)
 {
 	printf("\t\tVendor Specific Value (LDAC)");
@@ -204,8 +320,27 @@ static void print_ldac(a2dp_ldac_t *ldac, uint8_t size)
 		return;
 	}
 
-	printf("\n\t\t\tUnknown: %02x %02x", ldac->frequency,
-							ldac->channel_mode);
+	printf("\n\t\t\tFrequencies: ");
+	if (ldac->frequency & LDAC_SAMPLING_FREQ_44100)
+		printf("44.1kHz ");
+	if (ldac->frequency & LDAC_SAMPLING_FREQ_48000)
+		printf("48kHz ");
+	if (ldac->frequency & LDAC_SAMPLING_FREQ_88200)
+		printf("88.2kHz ");
+	if (ldac->frequency & LDAC_SAMPLING_FREQ_96000)
+		printf("96kHz ");
+	if (ldac->frequency & LDAC_SAMPLING_FREQ_176400)
+		printf("176.4kHz ");
+	if (ldac->frequency & LDAC_SAMPLING_FREQ_192000)
+		printf("192kHz ");
+
+	printf("\n\t\t\tChannel modes: ");
+	if (ldac->channel_mode & LDAC_CHANNEL_MODE_MONO)
+		printf("Mono ");
+	if (ldac->channel_mode & LDAC_CHANNEL_MODE_DUAL)
+		printf("Dual ");
+	if (ldac->channel_mode & LDAC_CHANNEL_MODE_STEREO)
+		printf("Stereo ");
 
 	printf("\n");
 }
@@ -237,6 +372,13 @@ static void print_vendor(a2dp_vendor_codec_t *vendor, uint8_t size)
 
 	if (vendor_id == APTX_VENDOR_ID && codec_id == APTX_CODEC_ID)
 		print_aptx((void *) vendor, size);
+	else if (vendor_id == FASTSTREAM_VENDOR_ID &&
+			codec_id == FASTSTREAM_CODEC_ID)
+		print_faststream((void *) vendor, size);
+	else if (vendor_id == APTX_LL_VENDOR_ID && codec_id == APTX_LL_CODEC_ID)
+		print_aptx_ll((void *) vendor, size);
+	else if (vendor_id == APTX_HD_VENDOR_ID && codec_id == APTX_HD_CODEC_ID)
+		print_aptx_hd((void *) vendor, size);
 	else if (vendor_id == LDAC_VENDOR_ID && codec_id == LDAC_CODEC_ID)
 		print_ldac((void *) vendor, size);
 }
-- 
2.11.0


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

* Re: [PATCH v2 00/10] A2DP: Fix endianity and define new A2DP codecs
  2018-12-23 10:40 ` [PATCH v2 " Pali Rohár
                     ` (9 preceding siblings ...)
  2018-12-23 10:40   ` [PATCH v2 10/10] avinfo: Parse new A2DP codecs Pali Rohár
@ 2018-12-28 18:23   ` " Luiz Augusto von Dentz
  2018-12-28 18:59     ` Pali Rohár
  10 siblings, 1 reply; 26+ messages in thread
From: Luiz Augusto von Dentz @ 2018-12-28 18:23 UTC (permalink / raw)
  To: Pali Rohár; +Cc: linux-bluetooth

Hi Pali,

On Sun, Dec 23, 2018 at 1:43 PM Pali Rohár <pali.rohar@gmail.com> wrote:
>
> This patch series try to fix endianity problems in a2dp-codecs.h file,
> then fixes parsing MPEG bit rate values, extend a2dp-codecs.h file for
> new A2DP codecs FastStream, aptX Low Latency, aptX HD and finally adds
> support for parsing information about FastStream, aptX Low Latency,
> aptX HD and LDAC codecs in avinfo utility.
>
> Changes since v1:
> * Fix style issues
>
> Pali Rohár (10):
>   avinfo: Fix buffer overflow when parsing broken/malicious data
>   avinfo: Show Vendor Specific Data
>   a2dp-codecs: Add SBC prefix for MIN/MAX_BITPOOL constants
>   a2dp-codecs: Fix codec id for ATRAC
>   a2dp-codecs & avinfo: Fix parsing MPEG bit rate values
>   a2dp-codecs: Define a2dp_vendor_codec_t struct in endian neutral way
>   a2dp-codecs: Add needed includes and properly check for endian macros
>   a2dp-codecs: Properly define macros and struct for LDAC codec
>   a2dp-codecs: Add macros and structures for new codecs
>   avinfo: Parse new A2DP codecs
>
>  android/a2dp.c               |   8 +-
>  android/avdtp.c              |   6 +-
>  android/hal-audio-aptx.c     |  18 +-
>  android/hal-audio-sbc.c      |  12 +-
>  profiles/audio/a2dp-codecs.h | 267 ++++++++++++++++++++++++++----
>  profiles/audio/a2dp.c        |   9 +-
>  tools/avinfo.c               | 380 ++++++++++++++++++++++++++++++++++++-------
>  7 files changed, 586 insertions(+), 114 deletions(-)
>
> --
> 2.11.0

Applies, thanks. Note that I had to fix some patches since they didn't
compile when applying one by one.


-- 
Luiz Augusto von Dentz

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

* Re: [PATCH v2 00/10] A2DP: Fix endianity and define new A2DP codecs
  2018-12-28 18:23   ` [PATCH v2 00/10] A2DP: Fix endianity and define " Luiz Augusto von Dentz
@ 2018-12-28 18:59     ` Pali Rohár
  0 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2018-12-28 18:59 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth

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

On Friday 28 December 2018 15:23:53 Luiz Augusto von Dentz wrote:
> Hi Pali,
> 
> On Sun, Dec 23, 2018 at 1:43 PM Pali Rohár <pali.rohar@gmail.com> wrote:
> >
> > This patch series try to fix endianity problems in a2dp-codecs.h file,
> > then fixes parsing MPEG bit rate values, extend a2dp-codecs.h file for
> > new A2DP codecs FastStream, aptX Low Latency, aptX HD and finally adds
> > support for parsing information about FastStream, aptX Low Latency,
> > aptX HD and LDAC codecs in avinfo utility.
> >
> > Changes since v1:
> > * Fix style issues
> >
> > Pali Rohár (10):
> >   avinfo: Fix buffer overflow when parsing broken/malicious data
> >   avinfo: Show Vendor Specific Data
> >   a2dp-codecs: Add SBC prefix for MIN/MAX_BITPOOL constants
> >   a2dp-codecs: Fix codec id for ATRAC
> >   a2dp-codecs & avinfo: Fix parsing MPEG bit rate values
> >   a2dp-codecs: Define a2dp_vendor_codec_t struct in endian neutral way
> >   a2dp-codecs: Add needed includes and properly check for endian macros
> >   a2dp-codecs: Properly define macros and struct for LDAC codec
> >   a2dp-codecs: Add macros and structures for new codecs
> >   avinfo: Parse new A2DP codecs
> >
> >  android/a2dp.c               |   8 +-
> >  android/avdtp.c              |   6 +-
> >  android/hal-audio-aptx.c     |  18 +-
> >  android/hal-audio-sbc.c      |  12 +-
> >  profiles/audio/a2dp-codecs.h | 267 ++++++++++++++++++++++++++----
> >  profiles/audio/a2dp.c        |   9 +-
> >  tools/avinfo.c               | 380 ++++++++++++++++++++++++++++++++++++-------
> >  7 files changed, 586 insertions(+), 114 deletions(-)
> >
> > --
> > 2.11.0
> 
> Applies, thanks. Note that I had to fix some patches since they didn't
> compile when applying one by one.

Ok.

-- 
Pali Rohár
pali.rohar@gmail.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

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

end of thread, back to index

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-19 16:50 [PATCH 00/10] A2DP: Fix endianity and define new A2DP codecs Pali Rohár
2018-12-19 16:51 ` [PATCH 01/10] avinfo: Fix buffer overflow when parsing broken/malicious data Pali Rohár
2018-12-19 16:51 ` [PATCH 02/10] avinfo: Show Vendor Specific Data Pali Rohár
2018-12-19 16:51 ` [PATCH 03/10] a2dp-codecs: Add SBC prefix for MIN/MAX_BITPOOL constants Pali Rohár
2018-12-19 16:51 ` [PATCH 04/10] a2dp-codecs: Fix codec id for ATRAC Pali Rohár
2018-12-19 16:51 ` [PATCH 05/10] a2dp-codecs & avinfo: Fix parsing MPEG bit rate values Pali Rohár
2018-12-19 16:51 ` [PATCH 06/10] a2dp-codecs: Define a2dp_vendor_codec_t struct in endian neutral way Pali Rohár
2018-12-19 16:51 ` [PATCH 07/10] a2dp-codecs: Add needed includes and properly check for endian macros Pali Rohár
2018-12-19 16:51 ` [PATCH 08/10] a2dp-codecs: Properly define macros and struct for LDAC codec Pali Rohár
2018-12-19 16:51 ` [PATCH 09/10] a2dp-codecs: Add macros and structures for FastStream, aptX Low Latency and aptX HD codecs Pali Rohár
2018-12-19 16:51 ` [PATCH 10/10] avinfo: Parse information about A2DP codecs: FastStream, aptX Low Latency, aptX HD and LDAC Pali Rohár
2018-12-22 22:54 ` [PATCH 00/10] A2DP: Fix endianity and define new A2DP codecs Luiz Augusto von Dentz
2018-12-23  9:30   ` Pali Rohár
2018-12-23 10:40 ` [PATCH v2 " Pali Rohár
2018-12-23 10:40   ` [PATCH v2 01/10] avinfo: Fix buffer overflow when parsing broken/malicious data Pali Rohár
2018-12-23 10:40   ` [PATCH v2 02/10] avinfo: Show Vendor Specific Data Pali Rohár
2018-12-23 10:40   ` [PATCH v2 03/10] a2dp-codecs: Add SBC prefix for MIN/MAX_BITPOOL constants Pali Rohár
2018-12-23 10:40   ` [PATCH v2 04/10] a2dp-codecs: Fix codec id for ATRAC Pali Rohár
2018-12-23 10:40   ` [PATCH v2 05/10] a2dp-codecs & avinfo: Fix parsing MPEG bit rate values Pali Rohár
2018-12-23 10:40   ` [PATCH v2 06/10] a2dp-codecs: Define a2dp_vendor_codec_t struct in endian neutral way Pali Rohár
2018-12-23 10:40   ` [PATCH v2 07/10] a2dp-codecs: Add needed includes and properly check for endian macros Pali Rohár
2018-12-23 10:40   ` [PATCH v2 08/10] a2dp-codecs: Properly define macros and struct for LDAC codec Pali Rohár
2018-12-23 10:40   ` [PATCH v2 09/10] a2dp-codecs: Add macros and structures for new codecs Pali Rohár
2018-12-23 10:40   ` [PATCH v2 10/10] avinfo: Parse new A2DP codecs Pali Rohár
2018-12-28 18:23   ` [PATCH v2 00/10] A2DP: Fix endianity and define " Luiz Augusto von Dentz
2018-12-28 18:59     ` Pali Rohár

Linux-Bluetooth Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-bluetooth/0 linux-bluetooth/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-bluetooth linux-bluetooth/ https://lore.kernel.org/linux-bluetooth \
		linux-bluetooth@vger.kernel.org linux-bluetooth@archiver.kernel.org
	public-inbox-index linux-bluetooth


Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-bluetooth


AGPL code for this site: git clone https://public-inbox.org/ public-inbox