audio/avrcp: Fix media player passthrough bitmask
authorArchie Pusaka <apusaka@chromium.org>
Fri, 29 May 2020 05:31:04 +0000 (13:31 +0800)
committerAyush Garg <ayush.garg@samsung.com>
Mon, 12 Apr 2021 09:00:49 +0000 (14:30 +0530)
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: Anuj Jain <anuj01.jain@samsung.com>
Signed-off-by: Ayush Garg <ayush.garg@samsung.com>
profiles/audio/avctp.c
profiles/audio/avctp.h
profiles/audio/avrcp.c

index e816013..0d54f19 100644 (file)
@@ -2379,3 +2379,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;
+}
index 80fb9d1..f1c760c 100755 (executable)
 #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
 #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
 #define AVC_FORWARD                    0x4b
 #define AVC_BACKWARD                   0x4c
 #define AVC_LIST                       0x4d
+#define AVC_ANGLE                      0x50
+#define AVC_SUBPICTURE                 0x51
 
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
 #define AVC_ABS_VOLUME         0x50
 #define AVC_GREEN                      0x7b
 #define AVC_BLUE                       0x7c
 #define AVC_YELLOW                     0x7c
+#define AVC_VENDOR_UNIQUE              0x7e
 
 struct avctp;
 
@@ -194,3 +204,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);
index 6782487..1533c12 100644 (file)
@@ -300,6 +300,70 @@ 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;
 
@@ -312,12 +376,8 @@ static uint16_t adapter_avrcp_ct_ver = 0;
 #endif
 #endif
 
-/* 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[] = {
@@ -551,6 +611,22 @@ static sdp_record_t *avrcp_tg_record(void)
 }
 #endif
 
+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) {
@@ -2107,7 +2183,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);
 
@@ -5199,6 +5276,8 @@ static int avrcp_init(void)
        btd_profile_register(&avrcp_controller_profile);
        btd_profile_register(&avrcp_target_profile);
 
+       populate_default_features();
+
        return 0;
 }