Some devices (Toyota Car Audio), will not perfomance general AVRCP
initial action like get capabilities or register for any notification
when receiving AVRCP profile version 1.5. Create black list for these
devices so we can reply AVRCP 1.4 when we are in higher AVRCP version.
Bug:
154780267
Test: manaul
Change-Id: If6c9453ad1f844d255fade63afad828b185b7fdf
// The public address of these devices are same as the Random address in ADV.
// Then will get name by LE_Create_connection, actually fails,
// but will block pairing.
- INTEROP_DISABLE_NAME_REQUEST
+ INTEROP_DISABLE_NAME_REQUEST,
+
+ // Respond AVRCP profile version only 1.4 for some device.
+ INTEROP_AVRCP_1_4_ONLY
} interop_feature_t;
// Check if a given |addr| matches a known interoperability workaround as
// for skip name request,
// because BR/EDR address and ADV random address are the same
{{{0xd4, 0x7a, 0xe2, 0, 0, 0}}, 3, INTEROP_DISABLE_NAME_REQUEST},
+
+ // Toyota Car Audio
+ {{{0x00, 0x17, 0x53, 0, 0, 0}}, 3, INTEROP_AVRCP_1_4_ONLY},
};
typedef struct {
CASE_RETURN_STR(INTEROP_DISABLE_ROLE_SWITCH)
CASE_RETURN_STR(INTEROP_HID_HOST_LIMIT_SNIFF_INTERVAL)
CASE_RETURN_STR(INTEROP_DISABLE_NAME_REQUEST)
+ CASE_RETURN_STR(INTEROP_AVRCP_1_4_ONLY)
}
return "UNKNOWN";
#include "bt_common.h"
#include "bt_types.h"
+#include "avrc_defs.h"
+#include "device/include/interop.h"
#include "osi/include/osi.h"
#include "sdp_api.h"
#include "sdpint.h"
tSDP_RECORD* p_rec;
tSDP_ATTR_SEQ attr_seq, attr_seq_sav;
tSDP_ATTRIBUTE* p_attr;
+ tSDP_ATTRIBUTE attr_sav;
bool maxxed_out = false, is_cont = false;
uint8_t* p_seq_start;
uint16_t seq_len, attr_len;
attr_seq.attr_entry[xx].end);
if (p_attr) {
+ // Check if the attribute contain AVRCP profile description list
+ uint16_t avrcp_version = sdpu_is_avrcp_profile_description_list(p_attr);
+ if (avrcp_version > AVRC_REV_1_4 &&
+ interop_match_addr(INTEROP_AVRCP_1_4_ONLY,
+ &(p_ccb->device_address))) {
+ SDP_TRACE_DEBUG(
+ "%s, device=%s is only accept AVRCP 1.4, reply AVRCP 1.4 "
+ "instead.",
+ __func__, p_ccb->device_address.ToString().c_str());
+ memcpy(&attr_sav, p_attr, sizeof(tSDP_ATTRIBUTE));
+ attr_sav.value_ptr[attr_sav.len - 1] = 0x04;
+ p_attr = &attr_sav;
+ }
/* Check if attribute fits. Assume 3-byte value type/length */
rem_len = max_list_len - (int16_t)(p_rsp - &p_ccb->rsp_list[0]);
/* Send the buffer through L2CAP */
L2CA_DataWrite(p_ccb->connection_id, p_buf);
}
-
#endif /* SDP_SERVER_ENABLED == TRUE */
#include "bt_types.h"
#include "btif_config.h"
+#include "avrc_defs.h"
#include "sdp_api.h"
#include "sdpint.h"
osi_free(p_attr_buff);
return p_out;
}
+/*******************************************************************************
+ *
+ * Function sdpu_is_avrcp_profile_description_list
+ *
+ * Description This function is to check if attirbute contain AVRCP profile
+ * description list
+ *
+ * p_attr: attibute to be check
+ *
+ * Returns AVRCP profile version if matched, else 0
+ *
+ ******************************************************************************/
+uint16_t sdpu_is_avrcp_profile_description_list(tSDP_ATTRIBUTE* p_attr) {
+ if (p_attr->id != ATTR_ID_BT_PROFILE_DESC_LIST || p_attr->len != 8) {
+ return 0;
+ }
+
+ uint8_t* p_uuid = p_attr->value_ptr + 3;
+ // Check if AVRCP profile UUID
+ if (p_uuid[0] != 0x11 || p_uuid[1] != 0xe) {
+ return 0;
+ }
+ uint8_t p_version = *(p_uuid + 4);
+ switch (p_version) {
+ case 0x0:
+ return AVRC_REV_1_0;
+ case 0x3:
+ return AVRC_REV_1_3;
+ case 0x4:
+ return AVRC_REV_1_4;
+ case 0x5:
+ return AVRC_REV_1_5;
+ case 0x6:
+ return AVRC_REV_1_6;
+ default:
+ return 0;
+ }
+}
extern uint8_t* sdpu_build_partial_attrib_entry(uint8_t* p_out,
tSDP_ATTRIBUTE* p_attr,
uint16_t len, uint16_t* offset);
+extern uint16_t sdpu_is_avrcp_profile_description_list(tSDP_ATTRIBUTE* p_attr);
/* Functions provided by sdp_db.cc
*/