From 111c7db93f613a09022d44639517a94be04ab300 Mon Sep 17 00:00:00 2001 From: Stanley Tng Date: Tue, 22 May 2018 18:15:42 -0700 Subject: [PATCH] Increase LE connection interval with bonded Hearing Aids When there are bonded Hearing Aids device, increase the minimum LE Connection Interval to reduce the audio noises on the devices. Bug: 80079923 Test: Manual test with RAT mouse and HA devices Change-Id: I589bc574ef7ff3754a149e30fb3c0a685ce27823 --- bta/dm/bta_dm_act.cc | 5 ++++ bta/hearing_aid/hearing_aid.cc | 13 +++++++++ bta/hh/bta_hh_le.cc | 12 ++------ bta/include/bta_hearing_aid_api.h | 2 ++ stack/include/btm_ble_api_types.h | 6 ++++ stack/include/l2c_api.h | 3 ++ stack/l2cap/l2c_ble.cc | 58 +++++++++++++++++++++++++++------------ 7 files changed, 72 insertions(+), 27 deletions(-) diff --git a/bta/dm/bta_dm_act.cc b/bta/dm/bta_dm_act.cc index d497c4ff1..a78a94440 100644 --- a/bta/dm/bta_dm_act.cc +++ b/bta/dm/bta_dm_act.cc @@ -3967,6 +3967,9 @@ void bta_dm_ble_set_conn_params(const RawAddress& bd_addr, uint16_t conn_int_min, uint16_t conn_int_max, uint16_t slave_latency, uint16_t supervision_tout) { + L2CA_AdjustConnectionIntervals(&conn_int_min, &conn_int_max, + BTM_BLE_CONN_INT_MIN); + BTM_BleSetPrefConnParams(bd_addr, conn_int_min, conn_int_max, slave_latency, supervision_tout); } @@ -3982,6 +3985,8 @@ void bta_dm_ble_update_conn_params(const RawAddress& bd_addr, uint16_t min_int, uint16_t max_int, uint16_t latency, uint16_t timeout, uint16_t min_ce_len, uint16_t max_ce_len) { + L2CA_AdjustConnectionIntervals(&min_int, &max_int, BTM_BLE_CONN_INT_MIN); + if (!L2CA_UpdateBleConnParams(bd_addr, min_int, max_int, latency, timeout, min_ce_len, max_ce_len)) { APPL_TRACE_ERROR("Update connection parameters failed!"); diff --git a/bta/hearing_aid/hearing_aid.cc b/bta/hearing_aid/hearing_aid.cc index 144dc99d5..87795422d 100644 --- a/bta/hearing_aid/hearing_aid.cc +++ b/bta/hearing_aid/hearing_aid.cc @@ -235,6 +235,8 @@ class HearingDevices { return false; } + size_t size() { return (devices.size()); } + std::vector devices; }; @@ -298,6 +300,8 @@ class HearingAidImpl : public HearingAid { callbacks->OnDeviceAvailable(capabilities, hiSyncId, address); } + int GetDeviceCount() { return (hearingDevices.size()); } + void OnGattConnected(tGATT_STATUS status, uint16_t conn_id, tGATT_IF client_if, RawAddress address, tBTA_TRANSPORT transport, uint16_t mtu) { @@ -1189,6 +1193,15 @@ void HearingAid::AddFromStorage(const RawAddress& address, uint16_t psm, render_delay, preparation_delay, is_white_listed); }; +int HearingAid::GetDeviceCount() { + if (!instance) { + LOG(INFO) << __func__ << ": Not initialized yet"; + return 0; + } + + return (instance->GetDeviceCount()); +} + void HearingAid::CleanUp() { // Must stop audio source to make sure it doesn't call any of callbacks on our // soon to be null instance diff --git a/bta/hh/bta_hh_le.cc b/bta/hh/bta_hh_le.cc index 7c79a0054..adeb957d7 100644 --- a/bta/hh/bta_hh_le.cc +++ b/bta/hh/bta_hh_le.cc @@ -1354,16 +1354,8 @@ void read_pref_conn_params_cb(uint16_t conn_id, tGATT_STATUS status, // Make sure both min, and max are bigger than 11.25ms, lower values can // introduce audio issues if A2DP is also active. - if (min_interval < BTM_BLE_CONN_INT_MIN_LIMIT) { - APPL_TRACE_DEBUG("%s: requested min_interval=%d too small. Set to %d", - __func__, min_interval, BTM_BLE_CONN_INT_MIN_LIMIT); - min_interval = BTM_BLE_CONN_INT_MIN_LIMIT; - } - if (max_interval < BTM_BLE_CONN_INT_MIN_LIMIT) { - APPL_TRACE_DEBUG("%s: requested max_interval=%d too small. Set to %d", - __func__, max_interval, BTM_BLE_CONN_INT_MIN_LIMIT); - max_interval = BTM_BLE_CONN_INT_MIN_LIMIT; - } + L2CA_AdjustConnectionIntervals(&min_interval, &max_interval, + BTM_BLE_CONN_INT_MIN_LIMIT); // If the device has no preferred connection timeout, use the default. if (timeout == BTM_BLE_CONN_PARAM_UNDEF) timeout = BTM_BLE_CONN_TIMEOUT_DEF; diff --git a/bta/include/bta_hearing_aid_api.h b/bta/include/bta_hearing_aid_api.h index 6b94722bf..96ad7e67c 100644 --- a/bta/include/bta_hearing_aid_api.h +++ b/bta/include/bta_hearing_aid_api.h @@ -49,6 +49,8 @@ class HearingAid { uint16_t render_delay, uint16_t preparation_delay, uint16_t is_white_listed); + static int GetDeviceCount(); + virtual void Connect(const RawAddress& address) = 0; virtual void Disconnect(const RawAddress& address) = 0; virtual void SetVolume(int8_t volume) = 0; diff --git a/stack/include/btm_ble_api_types.h b/stack/include/btm_ble_api_types.h index 36b24af5f..327a2e695 100644 --- a/stack/include/btm_ble_api_types.h +++ b/stack/include/btm_ble_api_types.h @@ -197,6 +197,12 @@ typedef uint8_t tBTM_BLE_SFP; #define BTM_BLE_CONN_INT_MIN_LIMIT 0x0009 #endif +/* minimum acceptable connection interval when there is bonded Hearing Aid + * device */ +#ifndef BTM_BLE_CONN_INT_MIN_HEARINGAID +#define BTM_BLE_CONN_INT_MIN_HEARINGAID 0x0010 +#endif + #define BTM_BLE_DIR_CONN_FALLBACK_UNDIR 1 #define BTM_BLE_DIR_CONN_FALLBACK_NO_ADV 2 diff --git a/stack/include/l2c_api.h b/stack/include/l2c_api.h index 83c6845fb..88121af5e 100644 --- a/stack/include/l2c_api.h +++ b/stack/include/l2c_api.h @@ -1280,4 +1280,7 @@ extern uint8_t L2CA_GetBleConnRole(const RawAddress& bd_addr); extern uint16_t L2CA_GetDisconnectReason(const RawAddress& remote_bda, tBT_TRANSPORT transport); +extern void L2CA_AdjustConnectionIntervals(uint16_t* min_interval, + uint16_t* max_interval, + uint16_t floor_interval); #endif /* L2C_API_H */ diff --git a/stack/l2cap/l2c_ble.cc b/stack/l2cap/l2c_ble.cc index e3bfc5240..c82d3cf1e 100644 --- a/stack/l2cap/l2c_ble.cc +++ b/stack/l2cap/l2c_ble.cc @@ -27,6 +27,7 @@ #include #include "bt_target.h" #include "bt_utils.h" +#include "bta_hearing_aid_api.h" #include "btm_int.h" #include "btu.h" #include "device/include/controller.h" @@ -490,6 +491,10 @@ static void l2cble_start_conn_update(tL2C_LCB* p_lcb) { p_lcb->min_interval > BTM_BLE_CONN_INT_MIN) { /* use 7.5 ms as fast connection parameter, 0 slave latency */ min_conn_int = max_conn_int = BTM_BLE_CONN_INT_MIN; + + L2CA_AdjustConnectionIntervals(&min_conn_int, &max_conn_int, + BTM_BLE_CONN_INT_MIN); + slave_latency = BTM_BLE_CONN_SLAVE_LATENCY_DEF; supervision_tout = BTM_BLE_CONN_TIMEOUT_DEF; @@ -627,23 +632,8 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { STREAM_TO_UINT16(timeout, p); /* 0x000A - 0x0C80 */ /* If we are a master, the slave wants to update the parameters */ if (p_lcb->link_role == HCI_ROLE_MASTER) { - if (min_interval < BTM_BLE_CONN_INT_MIN_LIMIT) { - L2CAP_TRACE_DEBUG( - "%s: requested min_interval=%d too small. Set to %d", __func__, - min_interval, BTM_BLE_CONN_INT_MIN_LIMIT); - min_interval = BTM_BLE_CONN_INT_MIN_LIMIT; - } - - // While this could result in connection parameters that fall - // outside fo the range requested, this will allow the connection - // to remain established. - // In other words, this is a workaround for certain peripherals. - if (max_interval < BTM_BLE_CONN_INT_MIN_LIMIT) { - L2CAP_TRACE_DEBUG( - "%s: requested max_interval=%d too small. Set to %d", __func__, - max_interval, BTM_BLE_CONN_INT_MIN_LIMIT); - max_interval = BTM_BLE_CONN_INT_MIN_LIMIT; - } + L2CA_AdjustConnectionIntervals(&min_interval, &max_interval, + BTM_BLE_CONN_INT_MIN_LIMIT); if (min_interval < BTM_BLE_CONN_INT_MIN || min_interval > BTM_BLE_CONN_INT_MAX || @@ -1458,3 +1448,37 @@ bool l2ble_sec_access_req(const RawAddress& bd_addr, uint16_t psm, return status; } + +/* This function is called to adjust the connection intervals based on various + * constraints. For example, when there is at least one Hearing Aid device + * bonded, the minimum interval is raised. On return, min_interval and + * max_interval are updated. */ +void L2CA_AdjustConnectionIntervals(uint16_t* min_interval, + uint16_t* max_interval, + uint16_t floor_interval) { + uint16_t phone_min_interval = floor_interval; + + if (HearingAid::GetDeviceCount() > 0) { + // When there are bonded Hearing Aid devices, we will constrained this + // minimum interval. + phone_min_interval = BTM_BLE_CONN_INT_MIN_HEARINGAID; + L2CAP_TRACE_DEBUG("%s: Have Hearing Aids. Min. interval is set to %d", + __func__, phone_min_interval); + } + + if (*min_interval < phone_min_interval) { + L2CAP_TRACE_DEBUG("%s: requested min_interval=%d too small. Set to %d", + __func__, *min_interval, phone_min_interval); + *min_interval = phone_min_interval; + } + + // While this could result in connection parameters that fall + // outside fo the range requested, this will allow the connection + // to remain established. + // In other words, this is a workaround for certain peripherals. + if (*max_interval < phone_min_interval) { + L2CAP_TRACE_DEBUG("%s: requested max_interval=%d too small. Set to %d", + __func__, *max_interval, phone_min_interval); + *max_interval = phone_min_interval; + } +} -- 2.11.0