Loading system/bta/gatt/bta_gattc_act.cc +157 −54 Original line number Diff line number Diff line Loading @@ -138,6 +138,20 @@ void bta_gattc_disable() { return; } if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { if (!bta_gattc_cb.cl_rcb_map.empty()) { bta_gattc_cb.state = BTA_GATTC_STATE_DISABLING; } // An entry can be erased during deregister, use a copied collection std::vector<tGATT_IF> gatt_ifs; for (auto& [gatt_if, p_rcb] : bta_gattc_cb.cl_rcb_map) { gatt_ifs.push_back(gatt_if); } for (auto& gatt_if : gatt_ifs) { bta_gattc_deregister(bta_gattc_cb.cl_rcb_map[gatt_if].get()); } } else { for (i = 0; i < BTA_GATTC_CL_MAX; i++) { if (!bta_gattc_cb.cl_rcb[i].in_use) { continue; Loading @@ -146,6 +160,7 @@ void bta_gattc_disable() { bta_gattc_cb.state = BTA_GATTC_STATE_DISABLING; bta_gattc_deregister(&bta_gattc_cb.cl_rcb[i]); } } /* no registered apps, indicate disable completed */ if (bta_gattc_cb.state != BTA_GATTC_STATE_DISABLING) { Loading Loading @@ -177,7 +192,29 @@ void bta_gattc_register(const Uuid& app_uuid, tBTA_GATTC_CBACK* p_cback, BtaAppR log::debug("GATTC module not enabled, enabling it"); bta_gattc_enable(); } /* todo need to check duplicate uuid */ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { tGATT_IF client_if = GATT_Register(app_uuid, "GattClient", &bta_gattc_cl_cback, eatt_support); if (client_if == 0) { log::error("Register with GATT stack failed"); status = GATT_ERROR; } else { auto p_rcb = std::make_unique<tBTA_GATTC_RCB>(); p_rcb->in_use = true; p_rcb->p_cback = p_cback; p_rcb->app_uuid = app_uuid; p_rcb->client_if = client_if; bta_gattc_cb.cl_rcb_map.emplace(client_if, std::move(p_rcb)); log::debug( "Registered GATT client interface {} with uuid={}, starting it on " "main thread", client_if, app_uuid.ToString()); do_in_main_thread(base::BindOnce(&bta_gattc_start_if, client_if)); status = GATT_SUCCESS; } } else { for (uint8_t i = 0; i < BTA_GATTC_CL_MAX; i++) { if (!bta_gattc_cb.cl_rcb[i].in_use) { bta_gattc_cb.cl_rcb[i].client_if = Loading @@ -193,7 +230,9 @@ void bta_gattc_register(const Uuid& app_uuid, tBTA_GATTC_CBACK* p_cback, BtaAppR /* BTA use the same client interface as BTE GATT statck */ client_if = bta_gattc_cb.cl_rcb[i].client_if; log::debug("Registered GATT client interface {} with uuid={}, starting it on main thread", log::debug( "Registered GATT client interface {} with uuid={}, starting it on " "main thread", client_if, app_uuid.ToString()); do_in_main_thread(base::BindOnce(&bta_gattc_start_if, client_if)); Loading @@ -203,6 +242,7 @@ void bta_gattc_register(const Uuid& app_uuid, tBTA_GATTC_CBACK* p_cback, BtaAppR } } } } if (!cb.is_null()) { cb.Run(client_if, status); Loading Loading @@ -254,6 +294,23 @@ void bta_gattc_deregister(tBTA_GATTC_RCB* p_clreg) { } /* close all CLCB related to this app */ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { for (auto& p_clcb : bta_gattc_cb.clcb_set) { if (p_clcb->p_rcb != p_clreg) { continue; } p_clreg->dereg_pending = true; tBTA_GATTC_DATA gattc_data = { .hdr = { .event = BTA_GATTC_API_CLOSE_EVT, .layer_specific = p_clcb->bta_conn_id, }, }; bta_gattc_close(p_clcb.get(), &gattc_data); } } else { for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++) { if (!bta_gattc_cb.clcb[i].in_use || (bta_gattc_cb.clcb[i].p_rcb != p_clreg)) { continue; Loading @@ -267,6 +324,7 @@ void bta_gattc_deregister(tBTA_GATTC_RCB* p_clreg) { bta_gattc_close(&bta_gattc_cb.clcb[i], (tBTA_GATTC_DATA*)&buf); } } } /** process connect API request */ void bta_gattc_process_api_open(const tBTA_GATTC_DATA* p_msg) { Loading Loading @@ -686,6 +744,15 @@ void bta_gattc_close(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { /** when a SRCB finished discovery, tell all related clcb */ void bta_gattc_reset_discover_st(tBTA_GATTC_SERV* p_srcb, tGATT_STATUS status) { if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { for (auto& p_clcb : bta_gattc_cb.clcb_set) { if (p_clcb->p_srcb != p_srcb) { continue; } p_clcb->status = status; bta_gattc_sm_execute(p_clcb.get(), BTA_GATTC_DISCOVER_CMPL_EVT, NULL); } } else { for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++) { if (bta_gattc_cb.clcb[i].p_srcb == p_srcb) { bta_gattc_cb.clcb[i].status = status; Loading @@ -693,6 +760,7 @@ void bta_gattc_reset_discover_st(tBTA_GATTC_SERV* p_srcb, tGATT_STATUS status) { } } } } /** close a GATTC connection while in discovery state */ void bta_gattc_disc_close(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { Loading @@ -718,6 +786,16 @@ void bta_gattc_disc_close(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data /** when a SRCB start discovery, tell all related clcb and set the state */ static void bta_gattc_set_discover_st(tBTA_GATTC_SERV* p_srcb) { if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { for (auto& p_clcb : bta_gattc_cb.clcb_set) { if (p_clcb->p_srcb != p_srcb) { continue; } p_clcb->status = GATT_SUCCESS; p_clcb->state = BTA_GATTC_DISCOVER_ST; p_clcb->request_during_discovery = BTA_GATTC_DISCOVER_REQ_NONE; } } else { for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++) { if (bta_gattc_cb.clcb[i].p_srcb == p_srcb) { bta_gattc_cb.clcb[i].status = GATT_SUCCESS; Loading @@ -726,6 +804,7 @@ static void bta_gattc_set_discover_st(tBTA_GATTC_SERV* p_srcb) { } } } } /** process service change in discovery state, mark up the auto update flag and * set status to be discovery cancel for current discovery. Loading Loading @@ -1344,7 +1423,13 @@ static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB* p_clreg) { memset(&cb_data, 0, sizeof(tBTA_GATTC)); GATT_Deregister(p_clreg->client_if); if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { if (bta_gattc_cb.cl_rcb_map.erase(p_clreg->client_if) == 0) { log::warn("deregistered unknown rcb client_if={}", p_clreg->client_if); } } else { memset(p_clreg, 0, sizeof(tBTA_GATTC_RCB)); } cb_data.reg_oper.client_if = client_if; cb_data.reg_oper.status = GATT_SUCCESS; Loading Loading @@ -1406,12 +1491,21 @@ void bta_gattc_process_api_refresh(const RawAddress& remote_bda) { if (p_srvc_cb->connected && p_srvc_cb->num_clcb != 0) { bool found = false; tBTA_GATTC_CLCB* p_clcb = &bta_gattc_cb.clcb[0]; if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { for (auto& p_clcb_i : bta_gattc_cb.clcb_set) { if (p_clcb_i->p_srcb == p_srvc_cb) { found = true; break; } } } else { for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++, p_clcb++) { if (p_clcb->in_use && p_clcb->p_srcb == p_srvc_cb) { found = true; break; } } } if (found) { bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL); return; Loading Loading @@ -1469,6 +1563,14 @@ static bool bta_gattc_process_srvc_chg_ind(uint16_t conn_id, tBTA_GATTC_RCB* p_c /* not an opened connection; or connection busy */ /* search for first available clcb and start discovery */ if (p_clcb == NULL || (p_clcb && p_clcb->p_q_cmd != NULL)) { if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { for (auto& p_clcb_i : bta_gattc_cb.clcb_set) { if (p_clcb_i->p_srcb == p_srcb && p_clcb_i->p_q_cmd == NULL) { p_clcb = p_clcb_i.get(); break; } } } else { for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++) { if (bta_gattc_cb.clcb[i].in_use && bta_gattc_cb.clcb[i].p_srcb == p_srcb && bta_gattc_cb.clcb[i].p_q_cmd == NULL) { Loading @@ -1477,6 +1579,7 @@ static bool bta_gattc_process_srvc_chg_ind(uint16_t conn_id, tBTA_GATTC_RCB* p_c } } } } /* send confirmation here if this is an indication, it should always be */ if (GATTC_SendHandleValueConfirm(conn_id, p_notify->cid) != GATT_SUCCESS) { log::warn("Unable to send GATT client handle value confirmation conn_id:{} cid:{}", conn_id, Loading system/bta/gatt/bta_gattc_int.h +2 −0 Original line number Diff line number Diff line Loading @@ -344,8 +344,10 @@ typedef struct { tBTA_GATTC_CONN conn_track[GATT_MAX_PHY_CHANNEL]; tBTA_GATTC_BG_TCK bg_track[BTA_GATTC_KNOWN_SR_MAX]; tBTA_GATTC_RCB cl_rcb[BTA_GATTC_CL_MAX]; std::unordered_map<tGATT_IF, std::unique_ptr<tBTA_GATTC_RCB>> cl_rcb_map; tBTA_GATTC_CLCB clcb[BTA_GATTC_CLCB_MAX]; std::unordered_set<std::unique_ptr<tBTA_GATTC_CLCB>> clcb_set; tBTA_GATTC_SERV known_server[BTA_GATTC_KNOWN_SR_MAX]; } tBTA_GATTC_CB; Loading system/bta/gatt/bta_gattc_utils.cc +164 −75 Original line number Diff line number Diff line Loading @@ -58,6 +58,14 @@ static uint8_t ble_acceptlist_size() { * ******************************************************************************/ tBTA_GATTC_RCB* bta_gattc_cl_get_regcb(uint8_t client_if) { if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { auto it = bta_gattc_cb.cl_rcb_map.find(client_if); if (it == bta_gattc_cb.cl_rcb_map.end()) { return NULL; } else { return it->second.get(); } } else { uint8_t i = 0; tBTA_GATTC_RCB* p_clrcb = &bta_gattc_cb.cl_rcb[0]; Loading @@ -68,6 +76,7 @@ tBTA_GATTC_RCB* bta_gattc_cl_get_regcb(uint8_t client_if) { } return NULL; } } /******************************************************************************* * * Function bta_gattc_num_reg_app Loading @@ -78,6 +87,9 @@ tBTA_GATTC_RCB* bta_gattc_cl_get_regcb(uint8_t client_if) { * ******************************************************************************/ uint8_t bta_gattc_num_reg_app(void) { if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { return (uint8_t)bta_gattc_cb.cl_rcb_map.size(); } else { uint8_t i = 0, j = 0; for (i = 0; i < BTA_GATTC_CL_MAX; i++) { Loading @@ -87,6 +99,7 @@ uint8_t bta_gattc_num_reg_app(void) { } return j; } } /******************************************************************************* * * Function bta_gattc_find_clcb_by_cif Loading @@ -98,14 +111,23 @@ uint8_t bta_gattc_num_reg_app(void) { ******************************************************************************/ tBTA_GATTC_CLCB* bta_gattc_find_clcb_by_cif(uint8_t client_if, const RawAddress& remote_bda, tBT_TRANSPORT transport) { if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { for (auto& p_clcb : bta_gattc_cb.clcb_set) { if (p_clcb->in_use && p_clcb->p_rcb->client_if == client_if && p_clcb->transport == transport && p_clcb->bda == remote_bda) { return p_clcb.get(); } } } else { tBTA_GATTC_CLCB* p_clcb = &bta_gattc_cb.clcb[0]; for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++, p_clcb++) { if (p_clcb->in_use && p_clcb->p_rcb->client_if == client_if && p_clcb->transport == transport && p_clcb->bda == remote_bda) { if (p_clcb->in_use && p_clcb->p_rcb->client_if == client_if && p_clcb->transport == transport && p_clcb->bda == remote_bda) { return p_clcb; } } } return NULL; } /******************************************************************************* Loading @@ -118,6 +140,13 @@ tBTA_GATTC_CLCB* bta_gattc_find_clcb_by_cif(uint8_t client_if, const RawAddress& * ******************************************************************************/ tBTA_GATTC_CLCB* bta_gattc_find_clcb_by_conn_id(uint16_t conn_id) { if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { for (auto& p_clcb : bta_gattc_cb.clcb_set) { if (p_clcb->bta_conn_id == conn_id) { return p_clcb.get(); } } } else { tBTA_GATTC_CLCB* p_clcb = &bta_gattc_cb.clcb[0]; for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++, p_clcb++) { Loading @@ -125,6 +154,7 @@ tBTA_GATTC_CLCB* bta_gattc_find_clcb_by_conn_id(uint16_t conn_id) { return p_clcb; } } } return NULL; } Loading @@ -141,6 +171,32 @@ tBTA_GATTC_CLCB* bta_gattc_clcb_alloc(tGATT_IF client_if, const RawAddress& remo tBT_TRANSPORT transport) { tBTA_GATTC_CLCB* p_clcb = NULL; if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { auto [p_clcb_i, b] = bta_gattc_cb.clcb_set.emplace(std::make_unique<tBTA_GATTC_CLCB>()); p_clcb = p_clcb_i->get(); p_clcb->in_use = true; p_clcb->status = GATT_SUCCESS; p_clcb->transport = transport; p_clcb->bda = remote_bda; p_clcb->p_q_cmd = NULL; p_clcb->p_rcb = bta_gattc_cl_get_regcb(client_if); p_clcb->p_srcb = bta_gattc_find_srcb(remote_bda); if (p_clcb->p_srcb == NULL) { p_clcb->p_srcb = bta_gattc_srcb_alloc(remote_bda); } if (p_clcb->p_rcb != NULL && p_clcb->p_srcb != NULL) { p_clcb->p_srcb->num_clcb++; p_clcb->p_rcb->num_clcb++; } else { /* release this clcb if clcb or srcb allocation failed */ bta_gattc_cb.clcb_set.erase(p_clcb_i); p_clcb = NULL; } } else { for (int i_clcb = 0; i_clcb < BTA_GATTC_CLCB_MAX; i_clcb++) { if (!bta_gattc_cb.clcb[i_clcb].in_use) { #if (BTA_GATT_DEBUG == TRUE) Loading Loading @@ -171,6 +227,7 @@ tBTA_GATTC_CLCB* bta_gattc_clcb_alloc(tGATT_IF client_if, const RawAddress& remo break; } } } return p_clcb; } /******************************************************************************* Loading Loading @@ -259,6 +316,14 @@ void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB* p_clcb) { /* Clear p_clcb. Some of the fields are already reset e.g. p_q_cmd_queue and * p_q_cmd. */ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { for (auto& p_clcb_i : bta_gattc_cb.clcb_set) { if (p_clcb_i.get() == p_clcb) { bta_gattc_cb.clcb_set.erase(p_clcb_i); break; } } } else { p_clcb->bta_conn_id = 0; p_clcb->bda = {}; p_clcb->transport = BT_TRANSPORT_AUTO; Loading @@ -271,6 +336,7 @@ void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB* p_clcb) { p_clcb->state = BTA_GATTC_IDLE_ST; p_clcb->status = GATT_SUCCESS; } } /******************************************************************************* * Loading Loading @@ -842,6 +908,15 @@ void bta_gatt_client_dump(int fd) { stream << " -- used: " << entry_count << "\n"; entry_count = 0; if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { stream << " ->cl_rcb (dynamic)\n"; for (auto& [i, p_cl_rcb] : bta_gattc_cb.cl_rcb_map) { entry_count++; stream << " client_if: " << +p_cl_rcb->client_if << " app uuids: " << p_cl_rcb->app_uuid << " clcb_num: " << +p_cl_rcb->num_clcb; stream << "\n"; } } else { stream << " ->cl_rcb (BTA_GATTC_CL_MAX=" << BTA_GATTC_CL_MAX << ")\n"; for (int i = 0; i < BTA_GATTC_CL_MAX; i++) { tBTA_GATTC_RCB* p_cl_rcb = &bta_gattc_cb.cl_rcb[i]; Loading @@ -853,9 +928,22 @@ void bta_gatt_client_dump(int fd) { << " clcb_num: " << +p_cl_rcb->num_clcb; stream << "\n"; } } stream << " -- used: " << entry_count << "\n"; entry_count = 0; if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { stream << " ->clcb (dynamic)\n"; for (auto& p_clcb : bta_gattc_cb.clcb_set) { entry_count++; stream << " conn_id: " << loghex(p_clcb->bta_conn_id) << " address: " << ADDRESS_TO_LOGGABLE_STR(p_clcb->bda) << " transport: " << bt_transport_text(p_clcb->transport) << " state: " << bta_clcb_state_text(p_clcb->state); stream << "\n"; } } else { stream << " ->clcb (BTA_GATTC_CLCB_MAX=" << BTA_GATTC_CLCB_MAX << ")\n"; for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++) { tBTA_GATTC_CLCB* p_clcb = &bta_gattc_cb.clcb[i]; Loading @@ -869,6 +957,7 @@ void bta_gatt_client_dump(int fd) { << " state: " << bta_clcb_state_text(p_clcb->state); stream << "\n"; } } stream << " -- used: " << entry_count << "\n"; entry_count = 0; Loading Loading
system/bta/gatt/bta_gattc_act.cc +157 −54 Original line number Diff line number Diff line Loading @@ -138,6 +138,20 @@ void bta_gattc_disable() { return; } if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { if (!bta_gattc_cb.cl_rcb_map.empty()) { bta_gattc_cb.state = BTA_GATTC_STATE_DISABLING; } // An entry can be erased during deregister, use a copied collection std::vector<tGATT_IF> gatt_ifs; for (auto& [gatt_if, p_rcb] : bta_gattc_cb.cl_rcb_map) { gatt_ifs.push_back(gatt_if); } for (auto& gatt_if : gatt_ifs) { bta_gattc_deregister(bta_gattc_cb.cl_rcb_map[gatt_if].get()); } } else { for (i = 0; i < BTA_GATTC_CL_MAX; i++) { if (!bta_gattc_cb.cl_rcb[i].in_use) { continue; Loading @@ -146,6 +160,7 @@ void bta_gattc_disable() { bta_gattc_cb.state = BTA_GATTC_STATE_DISABLING; bta_gattc_deregister(&bta_gattc_cb.cl_rcb[i]); } } /* no registered apps, indicate disable completed */ if (bta_gattc_cb.state != BTA_GATTC_STATE_DISABLING) { Loading Loading @@ -177,7 +192,29 @@ void bta_gattc_register(const Uuid& app_uuid, tBTA_GATTC_CBACK* p_cback, BtaAppR log::debug("GATTC module not enabled, enabling it"); bta_gattc_enable(); } /* todo need to check duplicate uuid */ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { tGATT_IF client_if = GATT_Register(app_uuid, "GattClient", &bta_gattc_cl_cback, eatt_support); if (client_if == 0) { log::error("Register with GATT stack failed"); status = GATT_ERROR; } else { auto p_rcb = std::make_unique<tBTA_GATTC_RCB>(); p_rcb->in_use = true; p_rcb->p_cback = p_cback; p_rcb->app_uuid = app_uuid; p_rcb->client_if = client_if; bta_gattc_cb.cl_rcb_map.emplace(client_if, std::move(p_rcb)); log::debug( "Registered GATT client interface {} with uuid={}, starting it on " "main thread", client_if, app_uuid.ToString()); do_in_main_thread(base::BindOnce(&bta_gattc_start_if, client_if)); status = GATT_SUCCESS; } } else { for (uint8_t i = 0; i < BTA_GATTC_CL_MAX; i++) { if (!bta_gattc_cb.cl_rcb[i].in_use) { bta_gattc_cb.cl_rcb[i].client_if = Loading @@ -193,7 +230,9 @@ void bta_gattc_register(const Uuid& app_uuid, tBTA_GATTC_CBACK* p_cback, BtaAppR /* BTA use the same client interface as BTE GATT statck */ client_if = bta_gattc_cb.cl_rcb[i].client_if; log::debug("Registered GATT client interface {} with uuid={}, starting it on main thread", log::debug( "Registered GATT client interface {} with uuid={}, starting it on " "main thread", client_if, app_uuid.ToString()); do_in_main_thread(base::BindOnce(&bta_gattc_start_if, client_if)); Loading @@ -203,6 +242,7 @@ void bta_gattc_register(const Uuid& app_uuid, tBTA_GATTC_CBACK* p_cback, BtaAppR } } } } if (!cb.is_null()) { cb.Run(client_if, status); Loading Loading @@ -254,6 +294,23 @@ void bta_gattc_deregister(tBTA_GATTC_RCB* p_clreg) { } /* close all CLCB related to this app */ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { for (auto& p_clcb : bta_gattc_cb.clcb_set) { if (p_clcb->p_rcb != p_clreg) { continue; } p_clreg->dereg_pending = true; tBTA_GATTC_DATA gattc_data = { .hdr = { .event = BTA_GATTC_API_CLOSE_EVT, .layer_specific = p_clcb->bta_conn_id, }, }; bta_gattc_close(p_clcb.get(), &gattc_data); } } else { for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++) { if (!bta_gattc_cb.clcb[i].in_use || (bta_gattc_cb.clcb[i].p_rcb != p_clreg)) { continue; Loading @@ -267,6 +324,7 @@ void bta_gattc_deregister(tBTA_GATTC_RCB* p_clreg) { bta_gattc_close(&bta_gattc_cb.clcb[i], (tBTA_GATTC_DATA*)&buf); } } } /** process connect API request */ void bta_gattc_process_api_open(const tBTA_GATTC_DATA* p_msg) { Loading Loading @@ -686,6 +744,15 @@ void bta_gattc_close(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { /** when a SRCB finished discovery, tell all related clcb */ void bta_gattc_reset_discover_st(tBTA_GATTC_SERV* p_srcb, tGATT_STATUS status) { if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { for (auto& p_clcb : bta_gattc_cb.clcb_set) { if (p_clcb->p_srcb != p_srcb) { continue; } p_clcb->status = status; bta_gattc_sm_execute(p_clcb.get(), BTA_GATTC_DISCOVER_CMPL_EVT, NULL); } } else { for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++) { if (bta_gattc_cb.clcb[i].p_srcb == p_srcb) { bta_gattc_cb.clcb[i].status = status; Loading @@ -693,6 +760,7 @@ void bta_gattc_reset_discover_st(tBTA_GATTC_SERV* p_srcb, tGATT_STATUS status) { } } } } /** close a GATTC connection while in discovery state */ void bta_gattc_disc_close(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { Loading @@ -718,6 +786,16 @@ void bta_gattc_disc_close(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data /** when a SRCB start discovery, tell all related clcb and set the state */ static void bta_gattc_set_discover_st(tBTA_GATTC_SERV* p_srcb) { if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { for (auto& p_clcb : bta_gattc_cb.clcb_set) { if (p_clcb->p_srcb != p_srcb) { continue; } p_clcb->status = GATT_SUCCESS; p_clcb->state = BTA_GATTC_DISCOVER_ST; p_clcb->request_during_discovery = BTA_GATTC_DISCOVER_REQ_NONE; } } else { for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++) { if (bta_gattc_cb.clcb[i].p_srcb == p_srcb) { bta_gattc_cb.clcb[i].status = GATT_SUCCESS; Loading @@ -726,6 +804,7 @@ static void bta_gattc_set_discover_st(tBTA_GATTC_SERV* p_srcb) { } } } } /** process service change in discovery state, mark up the auto update flag and * set status to be discovery cancel for current discovery. Loading Loading @@ -1344,7 +1423,13 @@ static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB* p_clreg) { memset(&cb_data, 0, sizeof(tBTA_GATTC)); GATT_Deregister(p_clreg->client_if); if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { if (bta_gattc_cb.cl_rcb_map.erase(p_clreg->client_if) == 0) { log::warn("deregistered unknown rcb client_if={}", p_clreg->client_if); } } else { memset(p_clreg, 0, sizeof(tBTA_GATTC_RCB)); } cb_data.reg_oper.client_if = client_if; cb_data.reg_oper.status = GATT_SUCCESS; Loading Loading @@ -1406,12 +1491,21 @@ void bta_gattc_process_api_refresh(const RawAddress& remote_bda) { if (p_srvc_cb->connected && p_srvc_cb->num_clcb != 0) { bool found = false; tBTA_GATTC_CLCB* p_clcb = &bta_gattc_cb.clcb[0]; if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { for (auto& p_clcb_i : bta_gattc_cb.clcb_set) { if (p_clcb_i->p_srcb == p_srvc_cb) { found = true; break; } } } else { for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++, p_clcb++) { if (p_clcb->in_use && p_clcb->p_srcb == p_srvc_cb) { found = true; break; } } } if (found) { bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL); return; Loading Loading @@ -1469,6 +1563,14 @@ static bool bta_gattc_process_srvc_chg_ind(uint16_t conn_id, tBTA_GATTC_RCB* p_c /* not an opened connection; or connection busy */ /* search for first available clcb and start discovery */ if (p_clcb == NULL || (p_clcb && p_clcb->p_q_cmd != NULL)) { if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { for (auto& p_clcb_i : bta_gattc_cb.clcb_set) { if (p_clcb_i->p_srcb == p_srcb && p_clcb_i->p_q_cmd == NULL) { p_clcb = p_clcb_i.get(); break; } } } else { for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++) { if (bta_gattc_cb.clcb[i].in_use && bta_gattc_cb.clcb[i].p_srcb == p_srcb && bta_gattc_cb.clcb[i].p_q_cmd == NULL) { Loading @@ -1477,6 +1579,7 @@ static bool bta_gattc_process_srvc_chg_ind(uint16_t conn_id, tBTA_GATTC_RCB* p_c } } } } /* send confirmation here if this is an indication, it should always be */ if (GATTC_SendHandleValueConfirm(conn_id, p_notify->cid) != GATT_SUCCESS) { log::warn("Unable to send GATT client handle value confirmation conn_id:{} cid:{}", conn_id, Loading
system/bta/gatt/bta_gattc_int.h +2 −0 Original line number Diff line number Diff line Loading @@ -344,8 +344,10 @@ typedef struct { tBTA_GATTC_CONN conn_track[GATT_MAX_PHY_CHANNEL]; tBTA_GATTC_BG_TCK bg_track[BTA_GATTC_KNOWN_SR_MAX]; tBTA_GATTC_RCB cl_rcb[BTA_GATTC_CL_MAX]; std::unordered_map<tGATT_IF, std::unique_ptr<tBTA_GATTC_RCB>> cl_rcb_map; tBTA_GATTC_CLCB clcb[BTA_GATTC_CLCB_MAX]; std::unordered_set<std::unique_ptr<tBTA_GATTC_CLCB>> clcb_set; tBTA_GATTC_SERV known_server[BTA_GATTC_KNOWN_SR_MAX]; } tBTA_GATTC_CB; Loading
system/bta/gatt/bta_gattc_utils.cc +164 −75 Original line number Diff line number Diff line Loading @@ -58,6 +58,14 @@ static uint8_t ble_acceptlist_size() { * ******************************************************************************/ tBTA_GATTC_RCB* bta_gattc_cl_get_regcb(uint8_t client_if) { if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { auto it = bta_gattc_cb.cl_rcb_map.find(client_if); if (it == bta_gattc_cb.cl_rcb_map.end()) { return NULL; } else { return it->second.get(); } } else { uint8_t i = 0; tBTA_GATTC_RCB* p_clrcb = &bta_gattc_cb.cl_rcb[0]; Loading @@ -68,6 +76,7 @@ tBTA_GATTC_RCB* bta_gattc_cl_get_regcb(uint8_t client_if) { } return NULL; } } /******************************************************************************* * * Function bta_gattc_num_reg_app Loading @@ -78,6 +87,9 @@ tBTA_GATTC_RCB* bta_gattc_cl_get_regcb(uint8_t client_if) { * ******************************************************************************/ uint8_t bta_gattc_num_reg_app(void) { if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { return (uint8_t)bta_gattc_cb.cl_rcb_map.size(); } else { uint8_t i = 0, j = 0; for (i = 0; i < BTA_GATTC_CL_MAX; i++) { Loading @@ -87,6 +99,7 @@ uint8_t bta_gattc_num_reg_app(void) { } return j; } } /******************************************************************************* * * Function bta_gattc_find_clcb_by_cif Loading @@ -98,14 +111,23 @@ uint8_t bta_gattc_num_reg_app(void) { ******************************************************************************/ tBTA_GATTC_CLCB* bta_gattc_find_clcb_by_cif(uint8_t client_if, const RawAddress& remote_bda, tBT_TRANSPORT transport) { if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { for (auto& p_clcb : bta_gattc_cb.clcb_set) { if (p_clcb->in_use && p_clcb->p_rcb->client_if == client_if && p_clcb->transport == transport && p_clcb->bda == remote_bda) { return p_clcb.get(); } } } else { tBTA_GATTC_CLCB* p_clcb = &bta_gattc_cb.clcb[0]; for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++, p_clcb++) { if (p_clcb->in_use && p_clcb->p_rcb->client_if == client_if && p_clcb->transport == transport && p_clcb->bda == remote_bda) { if (p_clcb->in_use && p_clcb->p_rcb->client_if == client_if && p_clcb->transport == transport && p_clcb->bda == remote_bda) { return p_clcb; } } } return NULL; } /******************************************************************************* Loading @@ -118,6 +140,13 @@ tBTA_GATTC_CLCB* bta_gattc_find_clcb_by_cif(uint8_t client_if, const RawAddress& * ******************************************************************************/ tBTA_GATTC_CLCB* bta_gattc_find_clcb_by_conn_id(uint16_t conn_id) { if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { for (auto& p_clcb : bta_gattc_cb.clcb_set) { if (p_clcb->bta_conn_id == conn_id) { return p_clcb.get(); } } } else { tBTA_GATTC_CLCB* p_clcb = &bta_gattc_cb.clcb[0]; for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++, p_clcb++) { Loading @@ -125,6 +154,7 @@ tBTA_GATTC_CLCB* bta_gattc_find_clcb_by_conn_id(uint16_t conn_id) { return p_clcb; } } } return NULL; } Loading @@ -141,6 +171,32 @@ tBTA_GATTC_CLCB* bta_gattc_clcb_alloc(tGATT_IF client_if, const RawAddress& remo tBT_TRANSPORT transport) { tBTA_GATTC_CLCB* p_clcb = NULL; if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { auto [p_clcb_i, b] = bta_gattc_cb.clcb_set.emplace(std::make_unique<tBTA_GATTC_CLCB>()); p_clcb = p_clcb_i->get(); p_clcb->in_use = true; p_clcb->status = GATT_SUCCESS; p_clcb->transport = transport; p_clcb->bda = remote_bda; p_clcb->p_q_cmd = NULL; p_clcb->p_rcb = bta_gattc_cl_get_regcb(client_if); p_clcb->p_srcb = bta_gattc_find_srcb(remote_bda); if (p_clcb->p_srcb == NULL) { p_clcb->p_srcb = bta_gattc_srcb_alloc(remote_bda); } if (p_clcb->p_rcb != NULL && p_clcb->p_srcb != NULL) { p_clcb->p_srcb->num_clcb++; p_clcb->p_rcb->num_clcb++; } else { /* release this clcb if clcb or srcb allocation failed */ bta_gattc_cb.clcb_set.erase(p_clcb_i); p_clcb = NULL; } } else { for (int i_clcb = 0; i_clcb < BTA_GATTC_CLCB_MAX; i_clcb++) { if (!bta_gattc_cb.clcb[i_clcb].in_use) { #if (BTA_GATT_DEBUG == TRUE) Loading Loading @@ -171,6 +227,7 @@ tBTA_GATTC_CLCB* bta_gattc_clcb_alloc(tGATT_IF client_if, const RawAddress& remo break; } } } return p_clcb; } /******************************************************************************* Loading Loading @@ -259,6 +316,14 @@ void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB* p_clcb) { /* Clear p_clcb. Some of the fields are already reset e.g. p_q_cmd_queue and * p_q_cmd. */ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { for (auto& p_clcb_i : bta_gattc_cb.clcb_set) { if (p_clcb_i.get() == p_clcb) { bta_gattc_cb.clcb_set.erase(p_clcb_i); break; } } } else { p_clcb->bta_conn_id = 0; p_clcb->bda = {}; p_clcb->transport = BT_TRANSPORT_AUTO; Loading @@ -271,6 +336,7 @@ void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB* p_clcb) { p_clcb->state = BTA_GATTC_IDLE_ST; p_clcb->status = GATT_SUCCESS; } } /******************************************************************************* * Loading Loading @@ -842,6 +908,15 @@ void bta_gatt_client_dump(int fd) { stream << " -- used: " << entry_count << "\n"; entry_count = 0; if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { stream << " ->cl_rcb (dynamic)\n"; for (auto& [i, p_cl_rcb] : bta_gattc_cb.cl_rcb_map) { entry_count++; stream << " client_if: " << +p_cl_rcb->client_if << " app uuids: " << p_cl_rcb->app_uuid << " clcb_num: " << +p_cl_rcb->num_clcb; stream << "\n"; } } else { stream << " ->cl_rcb (BTA_GATTC_CL_MAX=" << BTA_GATTC_CL_MAX << ")\n"; for (int i = 0; i < BTA_GATTC_CL_MAX; i++) { tBTA_GATTC_RCB* p_cl_rcb = &bta_gattc_cb.cl_rcb[i]; Loading @@ -853,9 +928,22 @@ void bta_gatt_client_dump(int fd) { << " clcb_num: " << +p_cl_rcb->num_clcb; stream << "\n"; } } stream << " -- used: " << entry_count << "\n"; entry_count = 0; if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) { stream << " ->clcb (dynamic)\n"; for (auto& p_clcb : bta_gattc_cb.clcb_set) { entry_count++; stream << " conn_id: " << loghex(p_clcb->bta_conn_id) << " address: " << ADDRESS_TO_LOGGABLE_STR(p_clcb->bda) << " transport: " << bt_transport_text(p_clcb->transport) << " state: " << bta_clcb_state_text(p_clcb->state); stream << "\n"; } } else { stream << " ->clcb (BTA_GATTC_CLCB_MAX=" << BTA_GATTC_CLCB_MAX << ")\n"; for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++) { tBTA_GATTC_CLCB* p_clcb = &bta_gattc_cb.clcb[i]; Loading @@ -869,6 +957,7 @@ void bta_gatt_client_dump(int fd) { << " state: " << bta_clcb_state_text(p_clcb->state); stream << "\n"; } } stream << " -- used: " << entry_count << "\n"; entry_count = 0; Loading