From 63d4caf308807e67b4f3206405310af8ff13f376 Mon Sep 17 00:00:00 2001 From: Hansong Zhang Date: Fri, 22 Jan 2021 14:47:44 -0800 Subject: [PATCH] BTM_PM refactor Move the PM database to btm_pm so we can get rid of some dependency on ACL. Test: cert/run Tag: #gd-refactor Bug: 141555841 Change-Id: I21701a708d4e4915b7d119c4e48698275c96ff78 --- main/shim/acl.cc | 4 - main/shim/l2c_api.cc | 2 + stack/acl/acl.h | 47 +++---- stack/acl/btm_acl.cc | 49 +------- stack/acl/btm_pm.cc | 286 +++++++++++++++++------------------------- stack/include/acl_api.h | 2 - stack/include/btm_api.h | 6 + stack/include/btm_api_types.h | 10 +- 8 files changed, 144 insertions(+), 262 deletions(-) diff --git a/main/shim/acl.cc b/main/shim/acl.cc index 24650a1d3..034e26dc8 100644 --- a/main/shim/acl.cc +++ b/main/shim/acl.cc @@ -692,7 +692,6 @@ void DumpsysAcl(int fd) { for (int i = 0; i < MAX_L2CAP_LINKS; i++) { const tACL_CONN& acl_conn = acl_cb.acl_db[i]; - const tBTM_PM_MCB& btm_pm_mcb = acl_cb.pm_mode_db[i]; if (!acl_conn.in_use) continue; LOG_DUMPSYS(fd, " peer_le_features valid:%s data:%s", @@ -728,10 +727,7 @@ void DumpsysAcl(int fd) { ticks_to_seconds(acl_conn.link_super_tout)); LOG_DUMPSYS(fd, " pkt_types_mask:0x%04x", acl_conn.pkt_types_mask); LOG_DUMPSYS(fd, " disconnect_reason:0x%02x", acl_conn.disconnect_reason); - LOG_DUMPSYS(fd, " chg_ind:%s", (btm_pm_mcb.chg_ind) ? "true" : "false"); LOG_DUMPSYS(fd, " role:%s", RoleText(acl_conn.link_role).c_str()); - LOG_DUMPSYS(fd, " power_mode_state:%s", - power_mode_state_text(btm_pm_mcb.State()).c_str()); } } #undef DUMPSYS_TAG diff --git a/main/shim/l2c_api.cc b/main/shim/l2c_api.cc index 20ba08a69..c0befca40 100644 --- a/main/shim/l2c_api.cc +++ b/main/shim/l2c_api.cc @@ -443,6 +443,7 @@ class SecurityListenerShim uint16_t handle = interface->GetAclHandle(); address_to_handle_[bda] = handle; btm_sec_connected(bda, handle, HCI_SUCCESS, 0); + BTM_PM_OnConnected(handle, bda); BTA_dm_acl_up(bda, BT_TRANSPORT_BR_EDR); address_to_interface_[bda] = std::move(interface); } @@ -461,6 +462,7 @@ class SecurityListenerShim address_to_interface_.erase(bda); btm_sec_disconnected(handle, HCI_ERR_PEER_USER); BTA_dm_acl_down(bda, BT_TRANSPORT_BR_EDR); + BTM_PM_OnDisconnected(handle); } void OnEncryptionChange(bluetooth::hci::Address remote, diff --git a/stack/acl/acl.h b/stack/acl/acl.h index 649bec841..a2df9aaeb 100644 --- a/stack/acl/acl.h +++ b/stack/acl/acl.h @@ -152,32 +152,22 @@ typedef struct { uint8_t role; /* HCI_ROLE_CENTRAL or HCI_ROLE_PERIPHERAL */ } tBTM_ROLE_SWITCH_CMPL; -typedef struct { - bool chg_ind; +struct tBTM_PM_MCB { + bool chg_ind = false; tBTM_PM_PWR_MD req_mode[BTM_MAX_PM_RECORDS + 1]; tBTM_PM_PWR_MD set_mode; - - private: - friend tBTM_STATUS BTM_SetPowerMode(uint8_t pm_id, - const RawAddress& remote_bda, - const tBTM_PM_PWR_MD* p_mode); - friend tBTM_STATUS BTM_SetSsrParams(const RawAddress& remote_bda, - uint16_t max_lat, uint16_t min_rmt_to, - uint16_t min_loc_to); - friend void btm_pm_proc_cmd_status(tHCI_STATUS status); - friend void btm_pm_proc_mode_change(tHCI_STATUS hci_status, - uint16_t hci_handle, tHCI_MODE mode, - uint16_t interval); - tBTM_PM_STATE state; - - public: - tBTM_PM_STATE State() const { return state; } - uint16_t interval; - uint16_t max_lat; - uint16_t min_loc_to; - uint16_t min_rmt_to; - void Init() { state = BTM_PM_ST_ACTIVE; } -} tBTM_PM_MCB; + tBTM_PM_STATE state = BTM_PM_ST_ACTIVE; // 0 + uint16_t interval = 0; + uint16_t max_lat = 0; + uint16_t min_loc_to = 0; + uint16_t min_rmt_to = 0; + void Init(RawAddress bda, uint16_t handle) { + bda_ = bda; + handle_ = handle; + } + RawAddress bda_; + uint16_t handle_; +}; struct sACL_CONN { BD_FEATURES peer_le_features; @@ -388,8 +378,6 @@ struct controller_t; ****************************************************/ struct sACL_CB { private: - friend int btm_pm_find_acl_ind(const RawAddress& remote_bda); - friend tBTM_PM_MCB* acl_power_mode_from_handle(uint16_t hci_handle); friend tBTM_STATUS BTM_SetPowerMode(uint8_t pm_id, const RawAddress& remote_bda, const tBTM_PM_PWR_MD* p_mode); @@ -399,7 +387,6 @@ struct sACL_CB { friend uint16_t BTM_GetNumAclLinks(void); friend uint16_t acl_get_supported_packet_types(); friend uint8_t btm_handle_to_acl_index(uint16_t hci_handle); - friend void acl_initialize_power_mode(const tACL_CONN& p_acl); friend void acl_set_disconnect_reason(tHCI_STATUS acl_disc_reason); friend void btm_acl_created(const RawAddress& bda, uint16_t hci_handle, uint8_t link_role, tBT_TRANSPORT transport); @@ -416,18 +403,12 @@ struct sACL_CB { friend void DumpsysAcl(int fd); friend struct StackAclBtmAcl; - friend struct StackAclBtmPm; tACL_CONN acl_db[MAX_L2CAP_LINKS]; - tBTM_PM_MCB pm_mode_db[MAX_L2CAP_LINKS]; tBTM_ROLE_SWITCH_CMPL switch_role_ref_data; uint16_t btm_acl_pkt_types_supported; uint16_t btm_def_link_policy; tHCI_STATUS acl_disc_reason; - uint8_t pm_pend_link; - - public: - bool is_power_mode_pending() const { return pm_pend_link != MAX_L2CAP_LINKS; } public: tHCI_STATUS get_disconnect_reason() const { return acl_disc_reason; } diff --git a/stack/acl/btm_acl.cc b/stack/acl/btm_acl.cc index 3c67e080c..d6e42d247 100644 --- a/stack/acl/btm_acl.cc +++ b/stack/acl/btm_acl.cc @@ -342,23 +342,6 @@ void btm_acl_process_sca_cmpl_pkt(uint8_t len, uint8_t* data) { p_acl->sca = sca; } -/******************************************************************************* - * - * Function btm_acl_created - * - * Description This function is called by L2CAP when an ACL connection - * is created. - * - * Returns void - * - ******************************************************************************/ -void acl_initialize_power_mode(const tACL_CONN& p_acl) { - tBTM_PM_MCB* p_db = - &btm_cb.acl_cb_.pm_mode_db[btm_handle_to_acl_index(p_acl.hci_handle)]; - memset(p_db, 0, sizeof(tBTM_PM_MCB)); - p_db->Init(); -} - tACL_CONN* StackAclBtmAcl::acl_allocate_connection() { tACL_CONN* p_acl = &btm_cb.acl_cb_.acl_db[0]; for (uint8_t xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_acl++) { @@ -401,7 +384,7 @@ void btm_acl_created(const RawAddress& bda, uint16_t hci_handle, p_acl->transport = transport; p_acl->switch_role_failed_attempts = 0; p_acl->reset_switch_role(); - acl_initialize_power_mode(*p_acl); + BTM_PM_OnConnected(hci_handle, bda); LOG_DEBUG( "Created new ACL connection peer:%s role:%s handle:0x%04x transport:%s", @@ -465,6 +448,7 @@ void btm_acl_removed(uint16_t handle) { p_acl->in_use = false; NotifyAclLinkDown(*p_acl); p_acl->Reset(); + BTM_PM_OnDisconnected(handle); } /******************************************************************************* @@ -2381,35 +2365,6 @@ const RawAddress acl_address_from_handle(uint16_t handle) { return p_acl->remote_addr; } -tBTM_PM_MCB* acl_power_mode_from_handle(uint16_t hci_handle) { - uint8_t index = btm_handle_to_acl_index(hci_handle); - if (index >= MAX_L2CAP_LINKS) { - return nullptr; - } - return &btm_cb.acl_cb_.pm_mode_db[index]; -} - -/******************************************************************************* - * - * Function btm_pm_find_acl_ind - * - * Description This function initializes the control block of an ACL link. - * It is called when an ACL connection is created. - * - * Returns void - * - ******************************************************************************/ -int btm_pm_find_acl_ind(const RawAddress& remote_bda) { - tACL_CONN* p = &btm_cb.acl_cb_.acl_db[0]; - uint8_t xx; - - for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p++) { - if (p->in_use && p->remote_addr == remote_bda && p->is_transport_br_edr()) - break; - } - return xx; -} - /******************************************************************************* * * Function btm_ble_refresh_local_resolvable_private_addr diff --git a/stack/acl/btm_pm.cc b/stack/acl/btm_pm.cc index 4ea305ff9..129faeb61 100644 --- a/stack/acl/btm_pm.cc +++ b/stack/acl/btm_pm.cc @@ -32,6 +32,7 @@ #include #include +#include #include "bt_target.h" #include "device/include/controller.h" @@ -45,7 +46,6 @@ #include "stack/include/btm_api.h" #include "stack/include/btm_api_types.h" #include "stack/include/btm_status.h" -#include "stack/include/l2cap_hci_link_interface.h" #include "types/raw_address.h" void l2c_OnHciModeChangeSendPendingPackets(RawAddress remote); @@ -53,15 +53,19 @@ void btm_sco_chk_pend_unpark(tHCI_STATUS status, uint16_t handle); extern tBTM_CB btm_cb; -struct StackAclBtmPm { - tBTM_STATUS btm_pm_snd_md_req(tACL_CONN& p_acl, uint8_t pm_id, int link_ind, - const tBTM_PM_PWR_MD* p_mode); - tBTM_PM_MCB* btm_pm_get_power_manager_from_address(const RawAddress& bda); - tBTM_PM_MCB* btm_pm_get_power_manager_from_handle(uint16_t handle); -}; - namespace { -StackAclBtmPm internal_; +uint16_t pm_pend_link = 0; + +std::unordered_map pm_mode_db; + +tBTM_PM_MCB* btm_pm_get_power_manager_from_address(const RawAddress& bda) { + for (auto& entry : pm_mode_db) { + if (entry.second.bda_ == bda) { + return &entry.second; + } + } + return nullptr; +} constexpr char kBtmLogTag[] = "ACL"; } @@ -75,10 +79,8 @@ constexpr char kBtmLogTag[] = "ACL"; #define BTM_PM_GET_MD2 2 #define BTM_PM_GET_COMP 3 -uint8_t btm_handle_to_acl_index(uint16_t hci_handle); tACL_CONN* acl_get_connection_from_address(const RawAddress& bd_addr, tBT_TRANSPORT transport); -tACL_CONN* acl_get_connection_from_handle(uint16_t handle); const uint8_t btm_pm_md_comp_matrix[BTM_PM_NUM_SET_MODES * BTM_PM_NUM_SET_MODES] = { @@ -88,16 +90,21 @@ const uint8_t BTM_PM_GET_MD1, BTM_PM_GET_MD2, BTM_PM_GET_COMP}; -static void send_sniff_subrating(const tACL_CONN& p_acl, uint16_t max_lat, - uint16_t min_rmt_to, uint16_t min_loc_to) { - btsnd_hcic_sniff_sub_rate(p_acl.hci_handle, max_lat, min_rmt_to, min_loc_to); - BTM_LogHistory(kBtmLogTag, p_acl.remote_addr, "Sniff subrating", +static void send_sniff_subrating(uint16_t handle, const RawAddress& addr, + uint16_t max_lat, uint16_t min_rmt_to, + uint16_t min_loc_to) { + btsnd_hcic_sniff_sub_rate(handle, max_lat, min_rmt_to, min_loc_to); + BTM_LogHistory(kBtmLogTag, addr, "Sniff subrating", base::StringPrintf( "max_latency:%.2f peer_timeout:%.2f local_timeout:%.2f", ticks_to_seconds(max_lat), ticks_to_seconds(min_rmt_to), ticks_to_seconds(min_loc_to))); } +static tBTM_STATUS btm_pm_snd_md_req(uint16_t handle, uint8_t pm_id, + int link_ind, + const tBTM_PM_PWR_MD* p_mode); + /*****************************************************************************/ /* P U B L I C F U N C T I O N S */ /*****************************************************************************/ @@ -114,8 +121,6 @@ static void send_sniff_subrating(const tACL_CONN& p_acl, uint16_t max_lat, ******************************************************************************/ tBTM_STATUS BTM_PmRegister(uint8_t mask, uint8_t* p_pm_id, tBTM_PM_STATUS_CBACK* p_cb) { - int xx; - if (bluetooth::shim::is_gd_link_policy_enabled()) { ASSERT(p_pm_id != nullptr); ASSERT(p_cb != nullptr); @@ -138,7 +143,7 @@ tBTM_STATUS BTM_PmRegister(uint8_t mask, uint8_t* p_pm_id, return BTM_SUCCESS; } - for (xx = 0; xx < BTM_MAX_PM_RECORDS; xx++) { + for (int xx = 0; xx < BTM_MAX_PM_RECORDS; xx++) { /* find an unused entry */ if (btm_cb.acl_cb_.pm_reg_db[xx].mask == BTM_PM_REC_NOT_USED) { /* if register for notification, should provide callback routine */ @@ -155,6 +160,13 @@ tBTM_STATUS BTM_PmRegister(uint8_t mask, uint8_t* p_pm_id, return BTM_NO_RESOURCES; } +void BTM_PM_OnConnected(uint16_t handle, const RawAddress& remote_bda) { + pm_mode_db[handle] = {}; + pm_mode_db[handle].Init(remote_bda, handle); +} + +void BTM_PM_OnDisconnected(uint16_t handle) { pm_mode_db.erase(handle); } + /******************************************************************************* * * Function BTM_SetPowerMode @@ -174,7 +186,7 @@ tBTM_STATUS BTM_SetPowerMode(uint8_t pm_id, const RawAddress& remote_bda, if (!p_mode) { LOG_ERROR("pm_id: %u, p_mode is null for %s", unsigned(pm_id), - remote_bda.ToString().c_str()); + PRIVATE_ADDRESS(remote_bda)); return BTM_ILLEGAL_VALUE; } @@ -203,14 +215,13 @@ tBTM_STATUS BTM_SetPowerMode(uint8_t pm_id, const RawAddress& remote_bda, return bluetooth::shim::BTM_SetPowerMode(*p_acl, power_mode_request); } - int acl_ind = btm_pm_find_acl_ind(remote_bda); - if (acl_ind == MAX_L2CAP_LINKS) { - LOG_ERROR("br_edr acl addr:%s is unknown", PRIVATE_ADDRESS(remote_bda)); - return BTM_UNKNOWN_ADDR; - } - // per ACL link - tBTM_PM_MCB* p_cb = &(btm_cb.acl_cb_.pm_mode_db[acl_ind]); + uint16_t handle = p_acl->Handle(); + auto* p_cb = btm_pm_get_power_manager_from_address(remote_bda); + if (p_cb == nullptr) { + LOG_WARN("Unable to find acl for %s", PRIVATE_ADDRESS(remote_bda)); + return false; + } if (mode != BTM_PM_MD_ACTIVE) { const controller_t* controller = controller_get_interface(); @@ -248,9 +259,7 @@ tBTM_STATUS BTM_SetPowerMode(uint8_t pm_id, const RawAddress& remote_bda, /* update mode database */ if (((pm_id != BTM_PM_SET_ONLY_ID) && (btm_cb.acl_cb_.pm_reg_db[pm_id].mask & BTM_PM_REG_SET)) || - ((pm_id == BTM_PM_SET_ONLY_ID) && - (btm_cb.acl_cb_.pm_pend_link != MAX_L2CAP_LINKS))) { - LOG_VERBOSE("saving cmd acl_ind %d temp_pm_id %d", acl_ind, temp_pm_id); + ((pm_id == BTM_PM_SET_ONLY_ID) && (pm_pend_link != 0))) { /* Make sure mask is set to BTM_PM_REG_SET */ btm_cb.acl_cb_.pm_reg_db[temp_pm_id].mask |= BTM_PM_REG_SET; *(&p_cb->req_mode[temp_pm_id]) = *p_mode; @@ -259,14 +268,13 @@ tBTM_STATUS BTM_SetPowerMode(uint8_t pm_id, const RawAddress& remote_bda, /* if mode == hold or pending, return */ if ((p_cb->state == BTM_PM_STS_HOLD) || (p_cb->state == BTM_PM_STS_PENDING) || - (btm_cb.acl_cb_.pm_pend_link != MAX_L2CAP_LINKS)) { + (pm_pend_link != 0)) { LOG_INFO( "Current power mode is hold or pending status or pending links" - " state:%s[%hhu] pm_pending_link:%hhu", - power_mode_state_text(p_cb->state).c_str(), p_cb->state, - btm_cb.acl_cb_.pm_pend_link); + " state:%s[%hhu] pm_pending_link:%hu", + power_mode_state_text(p_cb->state).c_str(), p_cb->state, pm_pend_link); /* command pending */ - if (acl_ind != btm_cb.acl_cb_.pm_pend_link) { + if (handle != pm_pend_link) { p_cb->state |= BTM_PM_STORED_MASK; LOG_INFO("Setting stored bitmask for peer:%s", PRIVATE_ADDRESS(remote_bda)); @@ -279,7 +287,7 @@ tBTM_STATUS BTM_SetPowerMode(uint8_t pm_id, const RawAddress& remote_bda, PRIVATE_ADDRESS(remote_bda), power_mode_state_text(p_cb->state).c_str(), p_cb->state, power_mode_text(p_mode->mode).c_str(), p_mode->mode); - return internal_.btm_pm_snd_md_req(*p_acl, pm_id, acl_ind, p_mode); + return btm_pm_snd_md_req(p_cb->handle_, pm_id, p_cb->handle_, p_mode); } bool BTM_SetLinkPolicyActiveMode(const RawAddress& remote_bda) { @@ -301,13 +309,12 @@ bool BTM_ReadPowerMode(const RawAddress& remote_bda, tBTM_PM_MODE* p_mode) { LOG_ERROR("power mode is nullptr"); return false; } - tBTM_PM_MCB* p_mcb = - internal_.btm_pm_get_power_manager_from_address(remote_bda); + tBTM_PM_MCB* p_mcb = btm_pm_get_power_manager_from_address(remote_bda); if (p_mcb == nullptr) { LOG_WARN("Unknown device:%s", PRIVATE_ADDRESS(remote_bda)); return false; } - *p_mode = static_cast(p_mcb->State()); + *p_mode = static_cast(p_mcb->state); return true; } @@ -331,16 +338,13 @@ bool BTM_ReadPowerMode(const RawAddress& remote_bda, tBTM_PM_MODE* p_mode) { ******************************************************************************/ tBTM_STATUS BTM_SetSsrParams(const RawAddress& remote_bda, uint16_t max_lat, uint16_t min_rmt_to, uint16_t min_loc_to) { - int acl_ind = btm_pm_find_acl_ind(remote_bda); - if (acl_ind == MAX_L2CAP_LINKS) return (BTM_UNKNOWN_ADDR); - - tBTM_PM_MCB* p_cb = &btm_cb.acl_cb_.pm_mode_db[acl_ind]; tACL_CONN* p_acl = acl_get_connection_from_address(remote_bda, BT_TRANSPORT_BR_EDR); - if (p_acl == nullptr) { + if (p_acl == nullptr || pm_mode_db.count(p_acl->Handle()) == 0) { LOG_WARN("Unable to find acl for peer:%s", PRIVATE_ADDRESS(remote_bda)); return BTM_UNKNOWN_ADDR; } + tBTM_PM_MCB* p_cb = &pm_mode_db[p_acl->Handle()]; if (bluetooth::shim::is_gd_link_policy_enabled()) { return bluetooth::shim::BTM_SetSsrParams(*p_acl, max_lat, min_rmt_to, @@ -352,13 +356,13 @@ tBTM_STATUS BTM_SetSsrParams(const RawAddress& remote_bda, uint16_t max_lat, "Set sniff subrating state:%s[%d] max_latency:0x%04x " "min_remote_timeout:0x%04x" " min_local_timeout:0x%04x", - power_mode_state_text(btm_cb.acl_cb_.pm_mode_db[acl_ind].state).c_str(), - btm_cb.acl_cb_.pm_mode_db[acl_ind].state, max_lat, min_rmt_to, - min_loc_to); - send_sniff_subrating(*p_acl, max_lat, min_rmt_to, min_loc_to); + power_mode_state_text(p_cb->state).c_str(), p_cb->state, max_lat, + min_rmt_to, min_loc_to); + send_sniff_subrating(p_acl->Handle(), remote_bda, max_lat, min_rmt_to, + min_loc_to); return BTM_SUCCESS; } - LOG_INFO("pm_mode_db state: %d", btm_cb.acl_cb_.pm_mode_db[acl_ind].state); + LOG_INFO("pm_mode_db state: %d", p_cb->state); p_cb->max_lat = max_lat; p_cb->min_rmt_to = min_rmt_to; p_cb->min_loc_to = min_loc_to; @@ -390,13 +394,13 @@ void btm_pm_reset(void) { btm_cb.acl_cb_.pm_reg_db[xx].mask = BTM_PM_REC_NOT_USED; } - if (cb != NULL && btm_cb.acl_cb_.pm_pend_link < MAX_L2CAP_LINKS) { - const RawAddress raw_address = - btm_cb.acl_cb_.acl_db[btm_cb.acl_cb_.pm_pend_link].remote_addr; + if (cb != NULL && pm_pend_link != 0) { + const RawAddress raw_address = pm_mode_db[pm_pend_link].bda_; (*cb)(raw_address, BTM_PM_STS_ERROR, BTM_DEV_RESET, HCI_SUCCESS); } /* no command pending */ - btm_cb.acl_cb_.pm_pend_link = MAX_L2CAP_LINKS; + pm_pend_link = 0; + pm_mode_db.clear(); LOG_INFO("reset pm"); } @@ -516,7 +520,7 @@ static tBTM_PM_MODE btm_pm_get_set_mode(uint8_t pm_id, tBTM_PM_MCB* p_cb, if (p_md == NULL) { if (p_mode) *p_res = *((tBTM_PM_PWR_MD*)p_mode); - else /* p_mode is NULL when internal_.btm_pm_snd_md_req is called from + else /* p_mode is NULL when btm_pm_snd_md_req is called from btm_pm_proc_mode_change */ return BTM_PM_MD_ACTIVE; } else { @@ -537,12 +541,14 @@ static tBTM_PM_MODE btm_pm_get_set_mode(uint8_t pm_id, tBTM_PM_MCB* p_cb, * Returns tBTM_STATUS *, bool *p_chg_ind ******************************************************************************/ -tBTM_STATUS StackAclBtmPm::btm_pm_snd_md_req(tACL_CONN& p_acl, uint8_t pm_id, - int link_ind, - const tBTM_PM_PWR_MD* p_mode) { +static tBTM_STATUS btm_pm_snd_md_req(uint16_t handle, uint8_t pm_id, + int link_ind, + const tBTM_PM_PWR_MD* p_mode) { + ASSERT_LOG(pm_mode_db.count(handle) != 0, + "Unable to find active acl for handle %d", handle); tBTM_PM_PWR_MD md_res; tBTM_PM_MODE mode; - tBTM_PM_MCB* p_cb = &btm_cb.acl_cb_.pm_mode_db[link_ind]; + tBTM_PM_MCB* p_cb = &pm_mode_db[handle]; bool chg_ind = false; mode = btm_pm_get_set_mode(pm_id, p_cb, p_mode, &md_res); @@ -550,7 +556,7 @@ tBTM_STATUS StackAclBtmPm::btm_pm_snd_md_req(tACL_CONN& p_acl, uint8_t pm_id, LOG_DEBUG("Found controller in mode:%s", power_mode_text(mode).c_str()); - if (p_cb->State() == mode) { + if (p_cb->state == mode) { LOG_INFO( "Link already in requested mode pm_id:%hhu link_ind:%d mode:%s[%hhu]", pm_id, link_ind, power_mode_text(mode).c_str(), mode); @@ -567,7 +573,7 @@ tBTM_STATUS StackAclBtmPm::btm_pm_snd_md_req(tACL_CONN& p_acl, uint8_t pm_id, p_cb->chg_ind = chg_ind; /* cannot go directly from current mode to resulting mode. */ - if (mode != BTM_PM_MD_ACTIVE && p_cb->State() != BTM_PM_MD_ACTIVE) { + if (mode != BTM_PM_MD_ACTIVE && p_cb->state != BTM_PM_MD_ACTIVE) { LOG_DEBUG("Power mode change delay required"); p_cb->chg_ind = true; /* needs to wake, then sleep */ } @@ -577,69 +583,63 @@ tBTM_STATUS StackAclBtmPm::btm_pm_snd_md_req(tACL_CONN& p_acl, uint8_t pm_id, md_res.mode = BTM_PM_MD_ACTIVE; } else if (BTM_PM_MD_SNIFF == md_res.mode && p_cb->max_lat) { LOG_DEBUG("Sending sniff subrating to controller"); - send_sniff_subrating(btm_cb.acl_cb_.acl_db[link_ind], p_cb->max_lat, - p_cb->min_rmt_to, p_cb->min_loc_to); + send_sniff_subrating(handle, p_cb->bda_, p_cb->max_lat, p_cb->min_rmt_to, + p_cb->min_loc_to); p_cb->max_lat = 0; } /* Default is failure */ - btm_cb.acl_cb_.pm_pend_link = MAX_L2CAP_LINKS; + pm_pend_link = 0; /* send the appropriate HCI command */ btm_cb.acl_cb_.pm_pend_id = pm_id; LOG_INFO("Switching from %s[0x%02x] to %s[0x%02x]", - power_mode_state_text(p_cb->State()).c_str(), p_cb->State(), + power_mode_state_text(p_cb->state).c_str(), p_cb->state, power_mode_state_text(md_res.mode).c_str(), md_res.mode); - BTM_LogHistory( - kBtmLogTag, btm_cb.acl_cb_.acl_db[link_ind].remote_addr, - "Power mode change", - base::StringPrintf( - "%s[0x%02x] ==> %s[0x%02x]", - power_mode_state_text(p_cb->State()).c_str(), p_cb->State(), - power_mode_state_text(md_res.mode).c_str(), md_res.mode)); + BTM_LogHistory(kBtmLogTag, p_cb->bda_, "Power mode change", + base::StringPrintf( + "%s[0x%02x] ==> %s[0x%02x]", + power_mode_state_text(p_cb->state).c_str(), p_cb->state, + power_mode_state_text(md_res.mode).c_str(), md_res.mode)); switch (md_res.mode) { case BTM_PM_MD_ACTIVE: - switch (p_cb->State()) { + switch (p_cb->state) { case BTM_PM_MD_SNIFF: - btsnd_hcic_exit_sniff_mode( - btm_cb.acl_cb_.acl_db[link_ind].hci_handle); - btm_cb.acl_cb_.pm_pend_link = link_ind; + btsnd_hcic_exit_sniff_mode(handle); + pm_pend_link = handle; break; case BTM_PM_MD_PARK: - btsnd_hcic_exit_park_mode(btm_cb.acl_cb_.acl_db[link_ind].hci_handle); - btm_cb.acl_cb_.pm_pend_link = link_ind; + btsnd_hcic_exit_park_mode(handle); + pm_pend_link = handle; break; default: - /* Failure btm_cb.acl_cb_.pm_pend_link = MAX_L2CAP_LINKS */ + /* Failure pm_pend_link = MAX_L2CAP_LINKS */ break; } break; case BTM_PM_MD_HOLD: - btsnd_hcic_hold_mode(btm_cb.acl_cb_.acl_db[link_ind].hci_handle, - md_res.max, md_res.min); - btm_cb.acl_cb_.pm_pend_link = link_ind; + btsnd_hcic_hold_mode(handle, md_res.max, md_res.min); + pm_pend_link = handle; break; case BTM_PM_MD_SNIFF: - btsnd_hcic_sniff_mode(btm_cb.acl_cb_.acl_db[link_ind].hci_handle, - md_res.max, md_res.min, md_res.attempt, + btsnd_hcic_sniff_mode(handle, md_res.max, md_res.min, md_res.attempt, md_res.timeout); - btm_cb.acl_cb_.pm_pend_link = link_ind; + pm_pend_link = handle; break; case BTM_PM_MD_PARK: - btsnd_hcic_park_mode(btm_cb.acl_cb_.acl_db[link_ind].hci_handle, - md_res.max, md_res.min); - btm_cb.acl_cb_.pm_pend_link = link_ind; + btsnd_hcic_park_mode(handle, md_res.max, md_res.min); + pm_pend_link = handle; break; default: - /* Failure btm_cb.acl_cb_.pm_pend_link = MAX_L2CAP_LINKS */ + /* Failure pm_pend_link = MAX_L2CAP_LINKS */ break; } - if (btm_cb.acl_cb_.pm_pend_link == MAX_L2CAP_LINKS) { + if (pm_pend_link == 0) { /* the command was not sent */ LOG_ERROR("pm_pending_link maxed out"); return (BTM_NO_RESOURCES); @@ -648,20 +648,6 @@ tBTM_STATUS StackAclBtmPm::btm_pm_snd_md_req(tACL_CONN& p_acl, uint8_t pm_id, return BTM_CMD_STARTED; } -tBTM_PM_MCB* StackAclBtmPm::btm_pm_get_power_manager_from_address( - const RawAddress& bda) { - int acl_index = btm_pm_find_acl_ind(bda); - if (acl_index == MAX_L2CAP_LINKS) return nullptr; - return &(btm_cb.acl_cb_.pm_mode_db[acl_index]); -} - -tBTM_PM_MCB* StackAclBtmPm::btm_pm_get_power_manager_from_handle( - uint16_t handle) { - int xx = btm_handle_to_acl_index(handle); - if (xx >= MAX_L2CAP_LINKS) return nullptr; - return &(btm_cb.acl_cb_.pm_mode_db[xx]); -} - /******************************************************************************* * * Function btm_pm_proc_cmd_status @@ -675,12 +661,12 @@ tBTM_PM_MCB* StackAclBtmPm::btm_pm_get_power_manager_from_handle( * ******************************************************************************/ void btm_pm_proc_cmd_status(tHCI_STATUS status) { - if (btm_cb.acl_cb_.pm_pend_link == MAX_L2CAP_LINKS) { + if (pm_pend_link == 0 || pm_mode_db.count(pm_pend_link) == 0) { LOG_ERROR("There are no links pending power mode changes"); return; } - tBTM_PM_MCB* p_cb = &btm_cb.acl_cb_.pm_mode_db[btm_cb.acl_cb_.pm_pend_link]; + tBTM_PM_MCB* p_cb = &pm_mode_db[pm_pend_link]; // if the command was not successful. Stay in the same state tBTM_PM_STATUS pm_status = BTM_PM_STS_ERROR; @@ -693,8 +679,7 @@ void btm_pm_proc_cmd_status(tHCI_STATUS status) { if ((btm_cb.acl_cb_.pm_pend_id != BTM_PM_SET_ONLY_ID) && (btm_cb.acl_cb_.pm_reg_db[btm_cb.acl_cb_.pm_pend_id].mask & BTM_PM_REG_NOTIF)) { - const RawAddress bd_addr = - btm_cb.acl_cb_.acl_db[btm_cb.acl_cb_.pm_pend_link].remote_addr; + const RawAddress bd_addr = pm_mode_db[pm_pend_link].bda_; LOG_DEBUG("Notifying callback that link power mode is complete peer:%s", PRIVATE_ADDRESS(bd_addr)); (*btm_cb.acl_cb_.pm_reg_db[btm_cb.acl_cb_.pm_pend_id].cback)( @@ -703,27 +688,15 @@ void btm_pm_proc_cmd_status(tHCI_STATUS status) { LOG_INFO("Clearing pending power mode link state:%s", power_mode_state_text(p_cb->state).c_str()); - btm_cb.acl_cb_.pm_pend_link = MAX_L2CAP_LINKS; - - /******************************************************************************* - * - * Function btm_pm_check_stored - * - * Description This function is called when an HCI command status event - * occurs to check if there's any PM command issued while - * waiting for HCI command status. - * - * Returns none. - * - ******************************************************************************/ - int xx; - for (xx = 0; xx < MAX_L2CAP_LINKS; xx++) { - if (btm_cb.acl_cb_.pm_mode_db[xx].state & BTM_PM_STORED_MASK) { - btm_cb.acl_cb_.pm_mode_db[xx].state &= ~BTM_PM_STORED_MASK; + pm_pend_link = 0; + + for (auto& entry : pm_mode_db) { + if (entry.second.state & BTM_PM_STORED_MASK) { + entry.second.state &= ~BTM_PM_STORED_MASK; LOG_DEBUG("Found another link requiring power mode change:%s", - PRIVATE_ADDRESS(btm_cb.acl_cb_.acl_db[xx].remote_addr)); - internal_.btm_pm_snd_md_req(btm_cb.acl_cb_.acl_db[xx], BTM_PM_SET_ONLY_ID, - xx, NULL); + PRIVATE_ADDRESS(entry.second.bda_)); + btm_pm_snd_md_req(entry.second.handle_, BTM_PM_SET_ONLY_ID, + entry.second.handle_, NULL); break; } } @@ -749,35 +722,14 @@ void btm_pm_proc_cmd_status(tHCI_STATUS status) { void btm_pm_proc_mode_change(tHCI_STATUS hci_status, uint16_t hci_handle, tHCI_MODE hci_mode, uint16_t interval) { tBTM_PM_STATUS mode = static_cast(hci_mode); - - LOG_DEBUG( - "On power mode changed complete status:%s handle:0x%04x" - " mode:%s interval:%hu", - hci_error_code_text(hci_status).c_str(), hci_handle, - hci_mode_text(hci_mode).c_str(), interval); - - int xx, yy, zz; tBTM_PM_STATE old_state; - tACL_CONN* p_acl = acl_get_connection_from_handle(hci_handle); - if (p_acl == nullptr) { - LOG_WARN("Unable to find acl"); - return; - } - - /* get the index to acl_db */ - xx = btm_handle_to_acl_index(hci_handle); - if (xx >= MAX_L2CAP_LINKS) return; - - const RawAddress bd_addr = acl_address_from_handle(hci_handle); - /* update control block */ - tBTM_PM_MCB* p_cb = - internal_.btm_pm_get_power_manager_from_handle(hci_handle); - if (p_cb == nullptr) { - LOG_WARN("Unable to find active acl"); + if (pm_mode_db.count(hci_handle) == 0) { + LOG_WARN("Unable to find active acl for handle %d", hci_handle); return; } + tBTM_PM_MCB* p_cb = &pm_mode_db[hci_handle]; old_state = p_cb->state; p_cb->state = mode; @@ -788,11 +740,11 @@ void btm_pm_proc_mode_change(tHCI_STATUS hci_status, uint16_t hci_handle, power_mode_state_text(p_cb->state).c_str(), p_cb->state); if ((p_cb->state == BTM_PM_ST_ACTIVE) || (p_cb->state == BTM_PM_ST_SNIFF)) { - l2c_OnHciModeChangeSendPendingPackets(bd_addr); + l2c_OnHciModeChangeSendPendingPackets(p_cb->bda_); } /* notify registered parties */ - for (yy = 0; yy <= BTM_MAX_PM_RECORDS; yy++) { + for (int yy = 0; yy <= BTM_MAX_PM_RECORDS; yy++) { /* set req_mode HOLD mode->ACTIVE */ if ((mode == BTM_PM_MD_ACTIVE) && (p_cb->req_mode[yy].mode == BTM_PM_MD_HOLD)) @@ -801,23 +753,21 @@ void btm_pm_proc_mode_change(tHCI_STATUS hci_status, uint16_t hci_handle, /* new request has been made. - post a message to BTU task */ if (old_state & BTM_PM_STORED_MASK) { - LOG_VERBOSE("Sending stored req: %d", xx); - internal_.btm_pm_snd_md_req(*p_acl, BTM_PM_SET_ONLY_ID, xx, NULL); + btm_pm_snd_md_req(hci_handle, BTM_PM_SET_ONLY_ID, hci_handle, NULL); } else { - for (zz = 0; zz < MAX_L2CAP_LINKS; zz++) { - if (btm_cb.acl_cb_.pm_mode_db[zz].chg_ind) { - LOG_VERBOSE("Sending PM req :%d", zz); - internal_.btm_pm_snd_md_req(btm_cb.acl_cb_.acl_db[zz], - BTM_PM_SET_ONLY_ID, zz, NULL); + for (auto& entry : pm_mode_db) { + if (entry.second.chg_ind) { + btm_pm_snd_md_req(entry.second.handle_, BTM_PM_SET_ONLY_ID, + entry.second.handle_, NULL); break; } } } /* notify registered parties */ - for (yy = 0; yy < BTM_MAX_PM_RECORDS; yy++) { + for (int yy = 0; yy < BTM_MAX_PM_RECORDS; yy++) { if (btm_cb.acl_cb_.pm_reg_db[yy].mask & BTM_PM_REG_NOTIF) { - (*btm_cb.acl_cb_.pm_reg_db[yy].cback)(bd_addr, mode, interval, + (*btm_cb.acl_cb_.pm_reg_db[yy].cback)(p_cb->bda_, mode, interval, hci_status); } } @@ -840,17 +790,12 @@ void btm_pm_proc_mode_change(tHCI_STATUS hci_status, uint16_t hci_handle, ******************************************************************************/ void process_ssr_event(tHCI_STATUS status, uint16_t handle, UNUSED_ATTR uint16_t max_tx_lat, uint16_t max_rx_lat) { - const RawAddress bd_addr = acl_address_from_handle(handle); - if (bd_addr == RawAddress::kEmpty) { - LOG_WARN("Received sniff subrating event with no active ACL"); - return; - } - - tBTM_PM_MCB* p_cb = internal_.btm_pm_get_power_manager_from_handle(handle); - if (p_cb == nullptr) { + if (pm_mode_db.count(handle) == 0) { LOG_WARN("Received sniff subrating event with no active ACL"); return; } + tBTM_PM_MCB* p_cb = &pm_mode_db[handle]; + auto bd_addr = p_cb->bda_; bool use_ssr = true; if (p_cb->interval == max_rx_lat) { @@ -918,8 +863,7 @@ bool btm_pm_device_in_active_or_sniff_mode(void) { * mode*/ /* Covers active and sniff modes */ - if (BTM_GetNumAclLinks() > 0) { - BTM_TRACE_DEBUG("%s - ACL links: %d", __func__, BTM_GetNumAclLinks()); + if (!pm_mode_db.empty()) { return true; } diff --git a/stack/include/acl_api.h b/stack/include/acl_api.h index 528a9bbe7..a6356789f 100644 --- a/stack/include/acl_api.h +++ b/stack/include/acl_api.h @@ -238,8 +238,6 @@ void BTM_ReadConnectionAddr(const RawAddress& remote_bda, bool BTM_IsBleConnection(uint16_t hci_handle); const RawAddress acl_address_from_handle(uint16_t hci_handle); -tBTM_PM_MCB* acl_power_mode_from_handle(uint16_t hci_handle); -int btm_pm_find_acl_ind(const RawAddress& remote_bda); void btm_ble_refresh_local_resolvable_private_addr( const RawAddress& pseudo_addr, const RawAddress& local_rpa); diff --git a/stack/include/btm_api.h b/stack/include/btm_api.h index e38214bc3..008f87033 100644 --- a/stack/include/btm_api.h +++ b/stack/include/btm_api.h @@ -695,6 +695,12 @@ char* BTM_SecReadDevName(const RawAddress& bd_addr); tBTM_STATUS BTM_PmRegister(uint8_t mask, uint8_t* p_pm_id, tBTM_PM_STATUS_CBACK* p_cb); +// Notified by ACL that a new link is connected +void BTM_PM_OnConnected(uint16_t handle, const RawAddress& remote_bda); + +// Notified by ACL that a link is disconnected +void BTM_PM_OnDisconnected(uint16_t handle); + /******************************************************************************* * * Function BTM_SetPowerMode diff --git a/stack/include/btm_api_types.h b/stack/include/btm_api_types.h index e5ffe4122..54ebb1996 100644 --- a/stack/include/btm_api_types.h +++ b/stack/include/btm_api_types.h @@ -975,11 +975,11 @@ typedef enum : uint8_t { * Power Manager Types ************************/ typedef struct { - uint16_t max; - uint16_t min; - uint16_t attempt; - uint16_t timeout; - tBTM_PM_MODE mode; + uint16_t max = 0; + uint16_t min = 0; + uint16_t attempt = 0; + uint16_t timeout = 0; + tBTM_PM_MODE mode = BTM_PM_MD_ACTIVE; // 0 } tBTM_PM_PWR_MD; /************************************* -- 2.11.0