* [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.