All of lore.kernel.org
 help / color / mirror / Atom feed
* [Bluez PATCH v3] audio/avrcp: Fix media player passthrough bitmask
@ 2020-05-29  5:31 Archie Pusaka
  2020-06-04 21:26 ` Luiz Augusto von Dentz
  0 siblings, 1 reply; 2+ messages in thread
From: Archie Pusaka @ 2020-05-29  5:31 UTC (permalink / raw)
  To: linux-bluetooth, Luiz Augusto von Dentz; +Cc: Michael Sun, Archie Pusaka

From: Archie Pusaka <apusaka@chromium.org>

Adjust the values of the passthrough bitmask with the declared
keys in avctp.c:key_map, according to section 6.10.2.1 of the
AVRCP specification.

Signed-off-by: Archie Pusaka <apusaka@chromium.org>
---

Changes in v3:
- Use table to map the passthrough bitmask instead of hardcoding

Changes in v2:
- Fix the mix-up between the first 4 and the last 4 bits of each
octet

 profiles/audio/avctp.c | 11 +++++
 profiles/audio/avctp.h | 11 +++++
 profiles/audio/avrcp.c | 93 ++++++++++++++++++++++++++++++++++++++----
 3 files changed, 108 insertions(+), 7 deletions(-)

diff --git a/profiles/audio/avctp.c b/profiles/audio/avctp.c
index 058b44a8b..7307eaa9e 100644
--- a/profiles/audio/avctp.c
+++ b/profiles/audio/avctp.c
@@ -2222,3 +2222,14 @@ bool avctp_is_initiator(struct avctp *session)
 {
 	return session->initiator;
 }
+
+bool avctp_supports_avc(uint8_t avc)
+{
+	int i;
+
+	for (i = 0; key_map[i].name != NULL; i++) {
+		if (key_map[i].avc == avc)
+			return true;
+	}
+	return false;
+}
diff --git a/profiles/audio/avctp.h b/profiles/audio/avctp.h
index 68a273561..c3cd49d88 100644
--- a/profiles/audio/avctp.h
+++ b/profiles/audio/avctp.h
@@ -54,7 +54,12 @@
 #define AVC_DOWN			0x02
 #define AVC_LEFT			0x03
 #define AVC_RIGHT			0x04
+#define AVC_RIGHT_UP			0x05
+#define AVC_RIGHT_DOWN			0x06
+#define AVC_LEFT_UP			0x07
+#define AVC_LEFT_DOWN			0x08
 #define AVC_ROOT_MENU			0x09
+#define AVC_SETUP_MENU			0x0a
 #define AVC_CONTENTS_MENU		0x0b
 #define AVC_FAVORITE_MENU		0x0c
 #define AVC_EXIT			0x0d
@@ -72,9 +77,11 @@
 #define AVC_9				0x29
 #define AVC_DOT				0x2a
 #define AVC_ENTER			0x2b
+#define AVC_CLEAR			0x2c
 #define AVC_CHANNEL_UP			0x30
 #define AVC_CHANNEL_DOWN		0x31
 #define AVC_CHANNEL_PREVIOUS		0x32
+#define AVC_SOUND_SELECT		0x33
 #define AVC_INPUT_SELECT		0x34
 #define AVC_INFO			0x35
 #define AVC_HELP			0x36
@@ -95,6 +102,8 @@
 #define AVC_FORWARD			0x4b
 #define AVC_BACKWARD			0x4c
 #define AVC_LIST			0x4d
+#define AVC_ANGLE			0x50
+#define AVC_SUBPICTURE			0x51
 #define AVC_F1				0x71
 #define AVC_F2				0x72
 #define AVC_F3				0x73
@@ -108,6 +117,7 @@
 #define AVC_GREEN			0x7b
 #define AVC_BLUE			0x7c
 #define AVC_YELLOW			0x7c
+#define AVC_VENDOR_UNIQUE		0x7e
 
 struct avctp;
 
@@ -183,3 +193,4 @@ int avctp_send_vendordep_req(struct avctp *session, uint8_t code,
 int avctp_send_browsing_req(struct avctp *session,
 				uint8_t *operands, size_t operand_count,
 				avctp_browsing_rsp_cb func, void *user_data);
+bool avctp_supports_avc(uint8_t avc);
diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 773ccdb60..fa97a3a89 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -293,15 +293,75 @@ struct control_pdu_handler {
 							uint8_t transaction);
 };
 
+static struct {
+	uint8_t feature_bit;
+	uint8_t avc;
+} passthrough_map[] = {
+	{ 0, AVC_SELECT },
+	{ 1, AVC_UP },
+	{ 2, AVC_DOWN },
+	{ 3, AVC_LEFT },
+	{ 4, AVC_RIGHT },
+	{ 5, AVC_RIGHT_UP },
+	{ 6, AVC_RIGHT_DOWN },
+	{ 7, AVC_LEFT_UP },
+	{ 8, AVC_LEFT_DOWN },
+	{ 9, AVC_ROOT_MENU },
+	{ 10, AVC_SETUP_MENU },
+	{ 11, AVC_CONTENTS_MENU },
+	{ 12, AVC_FAVORITE_MENU },
+	{ 13, AVC_EXIT },
+	{ 14, AVC_0 },
+	{ 15, AVC_1 },
+	{ 16, AVC_2 },
+	{ 17, AVC_3 },
+	{ 18, AVC_4 },
+	{ 19, AVC_5 },
+	{ 20, AVC_6 },
+	{ 21, AVC_7 },
+	{ 22, AVC_8 },
+	{ 23, AVC_9 },
+	{ 24, AVC_DOT },
+	{ 25, AVC_ENTER },
+	{ 26, AVC_CLEAR },
+	{ 27, AVC_CHANNEL_UP },
+	{ 28, AVC_CHANNEL_DOWN },
+	{ 29, AVC_CHANNEL_PREVIOUS },
+	{ 30, AVC_SOUND_SELECT },
+	{ 31, AVC_INPUT_SELECT },
+	{ 32, AVC_INFO },
+	{ 33, AVC_HELP },
+	{ 34, AVC_PAGE_UP },
+	{ 35, AVC_PAGE_DOWN },
+	{ 36, AVC_POWER },
+	{ 37, AVC_VOLUME_UP },
+	{ 38, AVC_VOLUME_DOWN },
+	{ 39, AVC_MUTE },
+	{ 40, AVC_PLAY },
+	{ 41, AVC_STOP },
+	{ 42, AVC_PAUSE },
+	{ 43, AVC_RECORD },
+	{ 44, AVC_REWIND },
+	{ 45, AVC_FAST_FORWARD },
+	{ 46, AVC_EJECT },
+	{ 47, AVC_FORWARD },
+	{ 48, AVC_BACKWARD },
+	{ 49, AVC_ANGLE },
+	{ 50, AVC_SUBPICTURE },
+	{ 51, AVC_F1 },
+	{ 52, AVC_F2 },
+	{ 53, AVC_F3 },
+	{ 54, AVC_F4 },
+	{ 55, AVC_F5 },
+	{ 56, AVC_VENDOR_UNIQUE },
+	{ 0xff, 0xff }
+};
+
 static GSList *servers = NULL;
 static unsigned int avctp_id = 0;
 
-/* Default feature bit mask for media player as per avctp.c:key_map */
-static const uint8_t features[16] = {
-				0xF8, 0xBF, 0xFF, 0xBF, 0x1F,
-				0xFB, 0x3F, 0x60, 0x00, 0x00,
-				0x00, 0x00, 0x00, 0x00, 0x00,
-				0x00 };
+/* Default feature bit mask for media player */
+static uint8_t default_features[16];
 
 /* Company IDs supported by this device */
 static uint32_t company_ids[] = {
@@ -490,6 +550,22 @@ static sdp_record_t *avrcp_tg_record(void)
 	return record;
 }
 
+static void populate_default_features(void)
+{
+	int i;
+
+	for (i = 0; passthrough_map[i].feature_bit != 0xff; i++) {
+		if (avctp_supports_avc(passthrough_map[i].avc)) {
+			uint8_t bit = passthrough_map[i].feature_bit;
+
+			default_features[bit >> 3] |= (1 << (bit & 7));
+		}
+	}
+
+	/* supports at least AVRCP 1.4 */
+	default_features[7] |= (1 << 2);
+}
+
 static unsigned int attr_get_max_val(uint8_t attr)
 {
 	switch (attr) {
@@ -1913,7 +1989,8 @@ static void avrcp_handle_media_player_list(struct avrcp *session,
 		item->subtype = htonl(0x01); /* Audio Book */
 		item->status = player_get_status(player);
 		/* Assign Default Feature Bit Mask */
-		memcpy(&item->features, &features, sizeof(features));
+		memcpy(&item->features, &default_features,
+					sizeof(default_features));
 
 		item->charset = htons(AVRCP_CHARSET_UTF8);
 
@@ -4578,6 +4655,8 @@ static int avrcp_init(void)
 	btd_profile_register(&avrcp_controller_profile);
 	btd_profile_register(&avrcp_target_profile);
 
+	populate_default_features();
+
 	return 0;
 }
 
-- 
2.27.0.rc2.251.g90737beb825-goog


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

* Re: [Bluez PATCH v3] audio/avrcp: Fix media player passthrough bitmask
  2020-05-29  5:31 [Bluez PATCH v3] audio/avrcp: Fix media player passthrough bitmask Archie Pusaka
@ 2020-06-04 21:26 ` Luiz Augusto von Dentz
  0 siblings, 0 replies; 2+ messages in thread
From: Luiz Augusto von Dentz @ 2020-06-04 21:26 UTC (permalink / raw)
  To: Archie Pusaka; +Cc: linux-bluetooth, Michael Sun, Archie Pusaka

Hi Archie,

On Thu, May 28, 2020 at 10:31 PM Archie Pusaka <apusaka@google.com> wrote:
>
> From: Archie Pusaka <apusaka@chromium.org>
>
> Adjust the values of the passthrough bitmask with the declared
> keys in avctp.c:key_map, according to section 6.10.2.1 of the
> AVRCP specification.
>
> Signed-off-by: Archie Pusaka <apusaka@chromium.org>
> ---
>
> Changes in v3:
> - Use table to map the passthrough bitmask instead of hardcoding
>
> Changes in v2:
> - Fix the mix-up between the first 4 and the last 4 bits of each
> octet
>
>  profiles/audio/avctp.c | 11 +++++
>  profiles/audio/avctp.h | 11 +++++
>  profiles/audio/avrcp.c | 93 ++++++++++++++++++++++++++++++++++++++----
>  3 files changed, 108 insertions(+), 7 deletions(-)
>
> diff --git a/profiles/audio/avctp.c b/profiles/audio/avctp.c
> index 058b44a8b..7307eaa9e 100644
> --- a/profiles/audio/avctp.c
> +++ b/profiles/audio/avctp.c
> @@ -2222,3 +2222,14 @@ bool avctp_is_initiator(struct avctp *session)
>  {
>         return session->initiator;
>  }
> +
> +bool avctp_supports_avc(uint8_t avc)
> +{
> +       int i;
> +
> +       for (i = 0; key_map[i].name != NULL; i++) {
> +               if (key_map[i].avc == avc)
> +                       return true;
> +       }
> +       return false;
> +}
> diff --git a/profiles/audio/avctp.h b/profiles/audio/avctp.h
> index 68a273561..c3cd49d88 100644
> --- a/profiles/audio/avctp.h
> +++ b/profiles/audio/avctp.h
> @@ -54,7 +54,12 @@
>  #define AVC_DOWN                       0x02
>  #define AVC_LEFT                       0x03
>  #define AVC_RIGHT                      0x04
> +#define AVC_RIGHT_UP                   0x05
> +#define AVC_RIGHT_DOWN                 0x06
> +#define AVC_LEFT_UP                    0x07
> +#define AVC_LEFT_DOWN                  0x08
>  #define AVC_ROOT_MENU                  0x09
> +#define AVC_SETUP_MENU                 0x0a
>  #define AVC_CONTENTS_MENU              0x0b
>  #define AVC_FAVORITE_MENU              0x0c
>  #define AVC_EXIT                       0x0d
> @@ -72,9 +77,11 @@
>  #define AVC_9                          0x29
>  #define AVC_DOT                                0x2a
>  #define AVC_ENTER                      0x2b
> +#define AVC_CLEAR                      0x2c
>  #define AVC_CHANNEL_UP                 0x30
>  #define AVC_CHANNEL_DOWN               0x31
>  #define AVC_CHANNEL_PREVIOUS           0x32
> +#define AVC_SOUND_SELECT               0x33
>  #define AVC_INPUT_SELECT               0x34
>  #define AVC_INFO                       0x35
>  #define AVC_HELP                       0x36
> @@ -95,6 +102,8 @@
>  #define AVC_FORWARD                    0x4b
>  #define AVC_BACKWARD                   0x4c
>  #define AVC_LIST                       0x4d
> +#define AVC_ANGLE                      0x50
> +#define AVC_SUBPICTURE                 0x51
>  #define AVC_F1                         0x71
>  #define AVC_F2                         0x72
>  #define AVC_F3                         0x73
> @@ -108,6 +117,7 @@
>  #define AVC_GREEN                      0x7b
>  #define AVC_BLUE                       0x7c
>  #define AVC_YELLOW                     0x7c
> +#define AVC_VENDOR_UNIQUE              0x7e
>
>  struct avctp;
>
> @@ -183,3 +193,4 @@ int avctp_send_vendordep_req(struct avctp *session, uint8_t code,
>  int avctp_send_browsing_req(struct avctp *session,
>                                 uint8_t *operands, size_t operand_count,
>                                 avctp_browsing_rsp_cb func, void *user_data);
> +bool avctp_supports_avc(uint8_t avc);
> diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
> index 773ccdb60..fa97a3a89 100644
> --- a/profiles/audio/avrcp.c
> +++ b/profiles/audio/avrcp.c
> @@ -293,15 +293,75 @@ struct control_pdu_handler {
>                                                         uint8_t transaction);
>  };
>
> +static struct {
> +       uint8_t feature_bit;
> +       uint8_t avc;
> +} passthrough_map[] = {
> +       { 0, AVC_SELECT },
> +       { 1, AVC_UP },
> +       { 2, AVC_DOWN },
> +       { 3, AVC_LEFT },
> +       { 4, AVC_RIGHT },
> +       { 5, AVC_RIGHT_UP },
> +       { 6, AVC_RIGHT_DOWN },
> +       { 7, AVC_LEFT_UP },
> +       { 8, AVC_LEFT_DOWN },
> +       { 9, AVC_ROOT_MENU },
> +       { 10, AVC_SETUP_MENU },
> +       { 11, AVC_CONTENTS_MENU },
> +       { 12, AVC_FAVORITE_MENU },
> +       { 13, AVC_EXIT },
> +       { 14, AVC_0 },
> +       { 15, AVC_1 },
> +       { 16, AVC_2 },
> +       { 17, AVC_3 },
> +       { 18, AVC_4 },
> +       { 19, AVC_5 },
> +       { 20, AVC_6 },
> +       { 21, AVC_7 },
> +       { 22, AVC_8 },
> +       { 23, AVC_9 },
> +       { 24, AVC_DOT },
> +       { 25, AVC_ENTER },
> +       { 26, AVC_CLEAR },
> +       { 27, AVC_CHANNEL_UP },
> +       { 28, AVC_CHANNEL_DOWN },
> +       { 29, AVC_CHANNEL_PREVIOUS },
> +       { 30, AVC_SOUND_SELECT },
> +       { 31, AVC_INPUT_SELECT },
> +       { 32, AVC_INFO },
> +       { 33, AVC_HELP },
> +       { 34, AVC_PAGE_UP },
> +       { 35, AVC_PAGE_DOWN },
> +       { 36, AVC_POWER },
> +       { 37, AVC_VOLUME_UP },
> +       { 38, AVC_VOLUME_DOWN },
> +       { 39, AVC_MUTE },
> +       { 40, AVC_PLAY },
> +       { 41, AVC_STOP },
> +       { 42, AVC_PAUSE },
> +       { 43, AVC_RECORD },
> +       { 44, AVC_REWIND },
> +       { 45, AVC_FAST_FORWARD },
> +       { 46, AVC_EJECT },
> +       { 47, AVC_FORWARD },
> +       { 48, AVC_BACKWARD },
> +       { 49, AVC_ANGLE },
> +       { 50, AVC_SUBPICTURE },
> +       { 51, AVC_F1 },
> +       { 52, AVC_F2 },
> +       { 53, AVC_F3 },
> +       { 54, AVC_F4 },
> +       { 55, AVC_F5 },
> +       { 56, AVC_VENDOR_UNIQUE },
> +       { 0xff, 0xff }
> +};
> +
>  static GSList *servers = NULL;
>  static unsigned int avctp_id = 0;
>
> -/* Default feature bit mask for media player as per avctp.c:key_map */
> -static const uint8_t features[16] = {
> -                               0xF8, 0xBF, 0xFF, 0xBF, 0x1F,
> -                               0xFB, 0x3F, 0x60, 0x00, 0x00,
> -                               0x00, 0x00, 0x00, 0x00, 0x00,
> -                               0x00 };
> +/* Default feature bit mask for media player */
> +static uint8_t default_features[16];
>
>  /* Company IDs supported by this device */
>  static uint32_t company_ids[] = {
> @@ -490,6 +550,22 @@ static sdp_record_t *avrcp_tg_record(void)
>         return record;
>  }
>
> +static void populate_default_features(void)
> +{
> +       int i;
> +
> +       for (i = 0; passthrough_map[i].feature_bit != 0xff; i++) {
> +               if (avctp_supports_avc(passthrough_map[i].avc)) {
> +                       uint8_t bit = passthrough_map[i].feature_bit;
> +
> +                       default_features[bit >> 3] |= (1 << (bit & 7));
> +               }
> +       }
> +
> +       /* supports at least AVRCP 1.4 */
> +       default_features[7] |= (1 << 2);
> +}
> +
>  static unsigned int attr_get_max_val(uint8_t attr)
>  {
>         switch (attr) {
> @@ -1913,7 +1989,8 @@ static void avrcp_handle_media_player_list(struct avrcp *session,
>                 item->subtype = htonl(0x01); /* Audio Book */
>                 item->status = player_get_status(player);
>                 /* Assign Default Feature Bit Mask */
> -               memcpy(&item->features, &features, sizeof(features));
> +               memcpy(&item->features, &default_features,
> +                                       sizeof(default_features));
>
>                 item->charset = htons(AVRCP_CHARSET_UTF8);
>
> @@ -4578,6 +4655,8 @@ static int avrcp_init(void)
>         btd_profile_register(&avrcp_controller_profile);
>         btd_profile_register(&avrcp_target_profile);
>
> +       populate_default_features();
> +
>         return 0;
>  }
>
> --
> 2.27.0.rc2.251.g90737beb825-goog

Applied, thanks.

-- 
Luiz Augusto von Dentz

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

end of thread, other threads:[~2020-06-04 21:26 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-29  5:31 [Bluez PATCH v3] audio/avrcp: Fix media player passthrough bitmask Archie Pusaka
2020-06-04 21:26 ` Luiz Augusto von Dentz

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.