* [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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).