diff --git a/components/bt/host/bluedroid/bta/av/bta_av_act.c b/components/bt/host/bluedroid/bta/av/bta_av_act.c index 2d8df0599ee..c2397b6e04f 100644 --- a/components/bt/host/bluedroid/bta/av/bta_av_act.c +++ b/components/bt/host/bluedroid/bta/av/bta_av_act.c @@ -1564,6 +1564,48 @@ static UINT16 bta_av_extra_tg_cover_art_l2cap_psm(void) #endif /* BTA_AV_CA_INCLUDED */ +/******************************************************************************* +** +** Function bta_av_mask_peer_rc_categories +** +** Description Keep only SDP Supported Features bits defined for the +** advertised AVRCP profile version (AVRCP 1.6.3 Table 8.1/8.2). +** Category 1-4: 1.0+; TG App Settings / Group Navigation: 1.3+; +** Browsing / TG Multiple Players: 1.4+; Cover Art: 1.6+. +** +** Returns version-valid Supported Features bitmap +** +*******************************************************************************/ +static UINT16 bta_av_mask_peer_rc_categories(UINT16 service_uuid, UINT16 version, + UINT16 categories) +{ + UINT16 mask = AVRC_SUPF_CT_CAT1 | AVRC_SUPF_CT_CAT2 | + AVRC_SUPF_CT_CAT3 | AVRC_SUPF_CT_CAT4; + BOOLEAN is_tg = (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET); + + if (version >= AVRC_REV_1_3 && is_tg) { + mask |= (AVRC_SUPF_TG_APP_SETTINGS | AVRC_SUPF_TG_GROUP_NAVI); + } + + if (version >= AVRC_REV_1_4) { + mask |= AVRC_SUPF_CT_BROWSE; + if (is_tg) { + mask |= AVRC_SUPF_TG_MULTI_PLAYER; + } + } + + if (version >= AVRC_REV_1_6) { + if (is_tg) { + mask |= AVRC_SUPF_TG_COVER_ART; + } else { + mask |= (AVRC_SUPF_CT_COVER_ART_GIP | AVRC_SUPF_CT_COVER_ART_GI | + AVRC_SUPF_CT_COVER_ART_GLT); + } + } + + return (UINT16)(categories & mask); +} + /******************************************************************************* ** ** Function bta_av_check_peer_rc_features @@ -1605,34 +1647,41 @@ tBTA_AV_FEAT bta_av_check_peer_rc_features (UINT16 service_uuid, UINT16 *rc_feat /* get profile version (if failure, version parameter is not updated) */ SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_AV_REMOTE_CONTROL, &peer_rc_version); APPL_TRACE_DEBUG("peer_rc_version 0x%x", peer_rc_version); - - if (peer_rc_version >= AVRC_REV_1_3) { - peer_features |= (BTA_AV_FEAT_VENDOR | BTA_AV_FEAT_METADATA); - } - - if (peer_rc_version >= AVRC_REV_1_4) { - peer_features |= (BTA_AV_FEAT_ADV_CTRL); - /* get supported categories */ - if ((p_attr = SDP_FindAttributeInRec(p_rec, - ATTR_ID_SUPPORTED_FEATURES)) != NULL) { - categories = p_attr->attr_value.v.u16; - if (categories & AVRC_SUPF_CT_BROWSE) { - peer_features |= (BTA_AV_FEAT_BROWSE); - } - if ((service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET) && (categories & AVRC_SUPF_TG_COVER_ART)) { - /* remote target support cover art */ - peer_features |= BTA_AV_FEAT_COVER_ART; - } - } - } } + + /* Supported Features is Mandatory since AVRCP 1.0 (Table 8.1 / 8.2) */ + if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_FEATURES)) != NULL) { + categories = p_attr->attr_value.v.u16; + } + } + + categories = bta_av_mask_peer_rc_categories(service_uuid, peer_rc_version, categories); + + /* AVRCP 1.3: Metadata Transfer / Vendor Unique (Table 3.1 items 10-15) */ + if (peer_rc_version >= AVRC_REV_1_3) { + peer_features |= (BTA_AV_FEAT_VENDOR | BTA_AV_FEAT_METADATA); + } + + /* AVRCP 1.4: Advanced Control and Browsing (Table 3.1 / Table 8.x bit 6) */ + if (peer_rc_version >= AVRC_REV_1_4) { + peer_features |= BTA_AV_FEAT_ADV_CTRL; + if (categories & AVRC_SUPF_CT_BROWSE) { + peer_features |= BTA_AV_FEAT_BROWSE; + } + } + + /* AVRCP 1.6: Cover Art (Table 8.2 bit 8, TG only) */ + if ((peer_rc_version >= AVRC_REV_1_6) && + (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET) && + (categories & AVRC_SUPF_TG_COVER_ART)) { + peer_features |= BTA_AV_FEAT_COVER_ART; } if (rc_features) { *rc_features = categories; } - APPL_TRACE_DEBUG("peer_features:x%x, rc:x%x", peer_features, categories); + APPL_TRACE_DEBUG("peer_features:x%x, rc:x%x ver:x%x", peer_features, categories, peer_rc_version); return peer_features; }