Re: [Bluez PATCH v3] audio/avrcp: Fix media player passthrough bitmask

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Archie,

On Thu, May 28, 2020 at 10:31 PM Archie Pusaka <apusaka@xxxxxxxxxx> wrote:
>
> From: Archie Pusaka <apusaka@xxxxxxxxxxxx>
>
> 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@xxxxxxxxxxxx>
> ---
>
> 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



[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux