#include "bt_utils.h"
#include "bta_av_int.h"
#include "btif/include/btif_av_co.h"
+#include "btif/include/btif_storage.h"
+#include "device/include/interop.h"
#include "l2c_api.h"
#include "l2cdefs.h"
#include "osi/include/osi.h"
uint8_t err_code = p_data->str_msg.msg.hdr.err_code;
APPL_TRACE_DEBUG("%s: err_code = %d", __func__, err_code);
- if (err_code) {
+
+ // Disable AVDTP RECONFIGURE for blacklisted devices
+ bool disable_avdtp_reconfigure = false;
+ {
+ char remote_name[BTM_MAX_REM_BD_NAME_LEN] = "";
+ bt_bdaddr_t bd_addr;
+ for (int i = 0; i < 6; i++) bd_addr.address[i] = p_scb->peer_addr[i];
+ if (btif_storage_get_stored_remote_name(bd_addr, remote_name)) {
+ if (interop_match_name(INTEROP_DISABLE_AVDTP_RECONFIGURE, remote_name) ||
+ interop_match_addr(INTEROP_DISABLE_AVDTP_RECONFIGURE,
+ (const bt_bdaddr_t*)&p_scb->peer_addr)) {
+ APPL_TRACE_DEBUG(
+ "%s: disable AVDTP RECONFIGURE: interop matched "
+ "name %s address %02x:%02x:%02x:%02x:%02x:%02x",
+ __func__, remote_name, p_scb->peer_addr[0], p_scb->peer_addr[1],
+ p_scb->peer_addr[2], p_scb->peer_addr[3], p_scb->peer_addr[4],
+ p_scb->peer_addr[5]);
+ disable_avdtp_reconfigure = true;
+ }
+ }
+ }
+
+ if ((err_code != 0) || disable_avdtp_reconfigure) {
APPL_TRACE_ERROR("%s: reconfig rejected, try close", __func__);
/* Disable reconfiguration feature only with explicit rejection(not with
* timeout) */
- if (err_code != AVDT_ERR_TIMEOUT) {
+ if ((err_code != AVDT_ERR_TIMEOUT) || disable_avdtp_reconfigure) {
p_scb->recfg_sup = false;
}
/* started flag is false when reconfigure command is sent */
bt_status_t btif_storage_remove_hidd(bt_bdaddr_t* remote_bd_addr);
+// Gets the device name for a given Bluetooth address |bd_addr|.
+// The device name (if found) is stored in |name|.
+// Returns true if the device name is found, othervise false.
+// Note: |name| should point to a buffer that can store string of length
+// |BTM_MAX_REM_BD_NAME_LEN|.
+bool btif_storage_get_stored_remote_name(const bt_bdaddr_t& bd_addr,
+ char* name);
+
/******************************************************************************
* Exported for unit tests
*****************************************************************************/
return BT_STATUS_SUCCESS;
}
+
+// Get the name of a device from btif for interop database matching.
+bool btif_storage_get_stored_remote_name(const bt_bdaddr_t& bd_addr,
+ char* name) {
+ bt_property_t property;
+ property.type = BT_PROPERTY_BDNAME;
+ property.len = BTM_MAX_REM_BD_NAME_LEN;
+ property.val = name;
+
+ return (btif_storage_get_remote_device_property(
+ const_cast<bt_bdaddr_t*>(&bd_addr), &property) ==
+ BT_STATUS_SUCCESS);
+}
// Do not send service changed indications (GATT client).
// This should be removed after the characteristic is implmeented b/62088395.
INTEROP_GATTC_NO_SERVICE_CHANGED_IND,
+
+ // Do not use AVDTP RECONFIGURE when reconfiguring A2DP streams.
+ // Some A2DP Sink devices report SUCCESS to the AVDTP RECONFIGURE command,
+ // but fail to play the reconfigured audio stream.
+ INTEROP_DISABLE_AVDTP_RECONFIGURE,
} interop_feature_t;
// Check if a given |addr| matches a known interoperability workaround as
// Kinivo BTC-450 - volume is erratic when using Absolute Volume
{{{0x00, 0x18, 0x91, 0, 0, 0}}, 3, INTEROP_DISABLE_ABSOLUTE_VOLUME},
+
+ // Kenwood KMM-BT518HD - no audio when A2DP codec sample rate is changed
+ {{{0x00, 0x1d, 0x86, 0, 0, 0}}, 3, INTEROP_DISABLE_AVDTP_RECONFIGURE},
};
typedef struct {
// Pixel C Keyboard doesn't respond to service changed indications.
{"Pixel C Keyboard", 16, INTEROP_GATTC_NO_SERVICE_CHANGED_IND},
+
+ // Kenwood KMM-BT518HD - no audio when A2DP codec sample rate is changed
+ {"KMM-BT51*HD", 11, INTEROP_DISABLE_AVDTP_RECONFIGURE},
};
CASE_RETURN_STR(INTEROP_2MBPS_LINK_ONLY)
CASE_RETURN_STR(INTEROP_HID_PREF_CONN_SUP_TIMEOUT_3S)
CASE_RETURN_STR(INTEROP_GATTC_NO_SERVICE_CHANGED_IND)
+ CASE_RETURN_STR(INTEROP_DISABLE_AVDTP_RECONFIGURE)
}
return "UNKNOWN";
}
}
-// Get the name of a device from btif for interop database matching.
-static bool get_stored_remote_name(BD_ADDR bda, char* name) {
- bt_bdaddr_t bd_addr;
- for (int i = 0; i < 6; i++) bd_addr.address[i] = bda[i];
-
- bt_property_t property;
- property.type = BT_PROPERTY_BDNAME;
- property.len = BTM_MAX_REM_BD_NAME_LEN;
- property.val = name;
-
- return (btif_storage_get_remote_device_property(&bd_addr, &property) ==
- BT_STATUS_SUCCESS);
-}
-
/*******************************************************************************
*
* Function gatt_proc_srv_chg
// Some LE GATT clients don't respond to service changed indications.
char remote_name[BTM_MAX_REM_BD_NAME_LEN] = "";
- if (send_indication && get_stored_remote_name(bda, remote_name)) {
+ bt_bdaddr_t bd_addr;
+ for (int i = 0; i < 6; i++) bd_addr.address[i] = bda[i];
+ if (send_indication &&
+ btif_storage_get_stored_remote_name(bd_addr, remote_name)) {
if (interop_match_name(INTEROP_GATTC_NO_SERVICE_CHANGED_IND,
remote_name)) {
GATT_TRACE_DEBUG("discard srv chg - interop matched %s", remote_name);