Loading system/bta/gatt/bta_gattc_act.cc +12 −5 Original line number Diff line number Diff line Loading @@ -716,7 +716,7 @@ void bta_gattc_restart_discover(tBTA_GATTC_CLCB* p_clcb, /** Configure MTU size on the GATT connection */ void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { if (!bta_gattc_enqueue(p_clcb, p_data)) return; if (bta_gattc_enqueue(p_clcb, p_data) == ENQUEUED_FOR_LATER) return; tGATT_STATUS status = GATTC_ConfigureMTU(p_clcb->bta_conn_id, p_data->api_mtu.mtu); Loading @@ -728,6 +728,7 @@ void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_CONFIG, status, NULL); bta_gattc_continue(p_clcb); } } Loading Loading @@ -860,6 +861,8 @@ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB* p_clcb, * referenced by p_clcb->p_q_cmd */ if (p_q_cmd != p_clcb->p_q_cmd) osi_free_and_reset((void**)&p_q_cmd); } else { bta_gattc_continue(p_clcb); } if (p_clcb->p_rcb->p_cback) { Loading @@ -871,7 +874,7 @@ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB* p_clcb, /** Read an attribute */ void bta_gattc_read(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { if (!bta_gattc_enqueue(p_clcb, p_data)) return; if (bta_gattc_enqueue(p_clcb, p_data) == ENQUEUED_FOR_LATER) return; tGATT_STATUS status; if (p_data->api_read.handle != 0) { Loading @@ -898,13 +901,14 @@ void bta_gattc_read(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status, NULL); bta_gattc_continue(p_clcb); } } /** read multiple */ void bta_gattc_read_multi(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { if (!bta_gattc_enqueue(p_clcb, p_data)) return; if (bta_gattc_enqueue(p_clcb, p_data) == ENQUEUED_FOR_LATER) return; tGATT_READ_PARAM read_param; memset(&read_param, 0, sizeof(tGATT_READ_PARAM)); Loading @@ -923,12 +927,13 @@ void bta_gattc_read_multi(tBTA_GATTC_CLCB* p_clcb, bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status, NULL); bta_gattc_continue(p_clcb); } } /** Write an attribute */ void bta_gattc_write(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { if (!bta_gattc_enqueue(p_clcb, p_data)) return; if (bta_gattc_enqueue(p_clcb, p_data) == ENQUEUED_FOR_LATER) return; tGATT_STATUS status = GATT_SUCCESS; tGATT_VALUE attr; Loading @@ -952,12 +957,13 @@ void bta_gattc_write(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_WRITE, status, NULL); bta_gattc_continue(p_clcb); } } /** send execute write */ void bta_gattc_execute(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { if (!bta_gattc_enqueue(p_clcb, p_data)) return; if (bta_gattc_enqueue(p_clcb, p_data) == ENQUEUED_FOR_LATER) return; tGATT_STATUS status = GATTC_ExecuteWrite(p_clcb->bta_conn_id, p_data->api_exec.is_execute); Loading @@ -967,6 +973,7 @@ void bta_gattc_execute(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_EXE_WRITE, status, NULL); bta_gattc_continue(p_clcb); } } Loading system/bta/gatt/bta_gattc_int.h +12 −2 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #define BTA_GATTC_INT_H #include <cstdint> #include <deque> #include "bt_target.h" // Must be first to define build configuration #include "bta/gatt/database.h" Loading Loading @@ -254,6 +255,7 @@ typedef struct { tBTA_GATTC_RCB* p_rcb; /* pointer to the registration CB */ tBTA_GATTC_SERV* p_srcb; /* server cache CB */ const tBTA_GATTC_DATA* p_q_cmd; /* command in queue waiting for execution */ std::deque<const tBTA_GATTC_DATA*> p_q_cmd_queue; // request during discover state #define BTA_GATTC_DISCOVER_REQ_NONE 0 Loading Loading @@ -423,8 +425,16 @@ extern tBTA_GATTC_SERV* bta_gattc_find_scb_by_cid(uint16_t conn_id); extern tBTA_GATTC_CLCB* bta_gattc_find_int_conn_clcb(tBTA_GATTC_DATA* p_msg); extern tBTA_GATTC_CLCB* bta_gattc_find_int_disconn_clcb(tBTA_GATTC_DATA* p_msg); extern bool bta_gattc_enqueue(tBTA_GATTC_CLCB* p_clcb, enum BtaEnqueuedResult_t { ENQUEUED_READY_TO_SEND, ENQUEUED_FOR_LATER, }; extern BtaEnqueuedResult_t bta_gattc_enqueue(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data); extern bool bta_gattc_is_data_queued(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data); extern void bta_gattc_continue(tBTA_GATTC_CLCB* p_clcb); extern bool bta_gattc_check_notif_registry(tBTA_GATTC_RCB* p_clreg, tBTA_GATTC_SERV* p_srcb, Loading system/bta/gatt/bta_gattc_main.cc +1 −1 Original line number Diff line number Diff line Loading @@ -328,7 +328,7 @@ bool bta_gattc_sm_execute(tBTA_GATTC_CLCB* p_clcb, uint16_t event, action = state_table[event][i]; if (action != BTA_GATTC_IGNORE) { (*bta_gattc_action[action])(p_clcb, p_data); if (p_clcb->p_q_cmd == p_data) { if (bta_gattc_is_data_queued(p_clcb, p_data)) { /* buffer is queued, don't free in the bta dispatcher. * we free it ourselves when a completion event is received. */ Loading system/bta/gatt/bta_gattc_utils.cc +62 −9 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ #define LOG_TAG "bt_bta_gattc" #include <base/logging.h> #include <cstdint> #include "bt_target.h" // Must be first to define build configuration Loading @@ -31,12 +33,11 @@ #include "device/include/controller.h" #include "gd/common/init_flags.h" #include "osi/include/allocator.h" #include "osi/include/log.h" #include "types/bt_transport.h" #include "types/hci_role.h" #include "types/raw_address.h" #include <base/logging.h> static uint8_t ble_acceptlist_size() { const controller_t* controller = controller_get_interface(); if (!controller->supports_ble()) { Loading Loading @@ -218,10 +219,29 @@ void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB* p_clcb) { p_srcb->gatt_database.Clear(); } while (!p_clcb->p_q_cmd_queue.empty()) { auto p_q_cmd = p_clcb->p_q_cmd_queue.front(); p_clcb->p_q_cmd_queue.pop_front(); osi_free_and_reset((void**)&p_q_cmd); } if (p_clcb->p_q_cmd != NULL) { osi_free_and_reset((void**)&p_clcb->p_q_cmd); } memset(p_clcb, 0, sizeof(tBTA_GATTC_CLCB)); /* Clear p_clcb. Some of the fields are already reset e.g. p_q_cmd_queue and * p_q_cmd. */ p_clcb->bta_conn_id = 0; p_clcb->bda = {}; p_clcb->transport = 0; p_clcb->p_rcb = NULL; p_clcb->p_srcb = NULL; p_clcb->request_during_discovery = 0; p_clcb->auto_update = 0; p_clcb->disc_active = 0; p_clcb->in_use = 0; p_clcb->state = BTA_GATTC_IDLE_ST; p_clcb->status = GATT_SUCCESS; } /******************************************************************************* Loading Loading @@ -318,24 +338,57 @@ tBTA_GATTC_SERV* bta_gattc_srcb_alloc(const RawAddress& bda) { } return p_tcb; } void bta_gattc_continue(tBTA_GATTC_CLCB* p_clcb) { if (p_clcb->p_q_cmd != NULL) { LOG_INFO("Already scheduled another request for conn_id = 0x%04x", p_clcb->bta_conn_id); return; } if (p_clcb->p_q_cmd_queue.empty()) { LOG_INFO("Nothing to do for conn_id = 0x%04x", p_clcb->bta_conn_id); return; } const tBTA_GATTC_DATA* p_q_cmd = p_clcb->p_q_cmd_queue.front(); p_clcb->p_q_cmd_queue.pop_front(); bta_gattc_sm_execute(p_clcb, p_q_cmd->hdr.event, p_q_cmd); } bool bta_gattc_is_data_queued(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { if (p_clcb->p_q_cmd == p_data) { return true; } auto it = std::find(p_clcb->p_q_cmd_queue.begin(), p_clcb->p_q_cmd_queue.end(), p_data); return it != p_clcb->p_q_cmd_queue.end(); } /******************************************************************************* * * Function bta_gattc_enqueue * * Description enqueue a client request in clcb. * * Returns success or failure. * Returns BtaEnqueuedResult_t * ******************************************************************************/ bool bta_gattc_enqueue(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { BtaEnqueuedResult_t bta_gattc_enqueue(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { if (p_clcb->p_q_cmd == NULL) { p_clcb->p_q_cmd = p_data; return true; return ENQUEUED_READY_TO_SEND; } LOG(ERROR) << __func__ << ": already has a pending command"; /* skip the callback now. ----- need to send callback ? */ return false; LOG_INFO( "Already has a pending command to executer. Queuing for later %s conn " "id=0x%04x", p_clcb->bda.ToString().c_str(), p_clcb->bta_conn_id); p_clcb->p_q_cmd_queue.push_back(p_data); return ENQUEUED_FOR_LATER; } /******************************************************************************* Loading Loading
system/bta/gatt/bta_gattc_act.cc +12 −5 Original line number Diff line number Diff line Loading @@ -716,7 +716,7 @@ void bta_gattc_restart_discover(tBTA_GATTC_CLCB* p_clcb, /** Configure MTU size on the GATT connection */ void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { if (!bta_gattc_enqueue(p_clcb, p_data)) return; if (bta_gattc_enqueue(p_clcb, p_data) == ENQUEUED_FOR_LATER) return; tGATT_STATUS status = GATTC_ConfigureMTU(p_clcb->bta_conn_id, p_data->api_mtu.mtu); Loading @@ -728,6 +728,7 @@ void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_CONFIG, status, NULL); bta_gattc_continue(p_clcb); } } Loading Loading @@ -860,6 +861,8 @@ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB* p_clcb, * referenced by p_clcb->p_q_cmd */ if (p_q_cmd != p_clcb->p_q_cmd) osi_free_and_reset((void**)&p_q_cmd); } else { bta_gattc_continue(p_clcb); } if (p_clcb->p_rcb->p_cback) { Loading @@ -871,7 +874,7 @@ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB* p_clcb, /** Read an attribute */ void bta_gattc_read(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { if (!bta_gattc_enqueue(p_clcb, p_data)) return; if (bta_gattc_enqueue(p_clcb, p_data) == ENQUEUED_FOR_LATER) return; tGATT_STATUS status; if (p_data->api_read.handle != 0) { Loading @@ -898,13 +901,14 @@ void bta_gattc_read(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status, NULL); bta_gattc_continue(p_clcb); } } /** read multiple */ void bta_gattc_read_multi(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { if (!bta_gattc_enqueue(p_clcb, p_data)) return; if (bta_gattc_enqueue(p_clcb, p_data) == ENQUEUED_FOR_LATER) return; tGATT_READ_PARAM read_param; memset(&read_param, 0, sizeof(tGATT_READ_PARAM)); Loading @@ -923,12 +927,13 @@ void bta_gattc_read_multi(tBTA_GATTC_CLCB* p_clcb, bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status, NULL); bta_gattc_continue(p_clcb); } } /** Write an attribute */ void bta_gattc_write(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { if (!bta_gattc_enqueue(p_clcb, p_data)) return; if (bta_gattc_enqueue(p_clcb, p_data) == ENQUEUED_FOR_LATER) return; tGATT_STATUS status = GATT_SUCCESS; tGATT_VALUE attr; Loading @@ -952,12 +957,13 @@ void bta_gattc_write(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_WRITE, status, NULL); bta_gattc_continue(p_clcb); } } /** send execute write */ void bta_gattc_execute(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { if (!bta_gattc_enqueue(p_clcb, p_data)) return; if (bta_gattc_enqueue(p_clcb, p_data) == ENQUEUED_FOR_LATER) return; tGATT_STATUS status = GATTC_ExecuteWrite(p_clcb->bta_conn_id, p_data->api_exec.is_execute); Loading @@ -967,6 +973,7 @@ void bta_gattc_execute(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_EXE_WRITE, status, NULL); bta_gattc_continue(p_clcb); } } Loading
system/bta/gatt/bta_gattc_int.h +12 −2 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #define BTA_GATTC_INT_H #include <cstdint> #include <deque> #include "bt_target.h" // Must be first to define build configuration #include "bta/gatt/database.h" Loading Loading @@ -254,6 +255,7 @@ typedef struct { tBTA_GATTC_RCB* p_rcb; /* pointer to the registration CB */ tBTA_GATTC_SERV* p_srcb; /* server cache CB */ const tBTA_GATTC_DATA* p_q_cmd; /* command in queue waiting for execution */ std::deque<const tBTA_GATTC_DATA*> p_q_cmd_queue; // request during discover state #define BTA_GATTC_DISCOVER_REQ_NONE 0 Loading Loading @@ -423,8 +425,16 @@ extern tBTA_GATTC_SERV* bta_gattc_find_scb_by_cid(uint16_t conn_id); extern tBTA_GATTC_CLCB* bta_gattc_find_int_conn_clcb(tBTA_GATTC_DATA* p_msg); extern tBTA_GATTC_CLCB* bta_gattc_find_int_disconn_clcb(tBTA_GATTC_DATA* p_msg); extern bool bta_gattc_enqueue(tBTA_GATTC_CLCB* p_clcb, enum BtaEnqueuedResult_t { ENQUEUED_READY_TO_SEND, ENQUEUED_FOR_LATER, }; extern BtaEnqueuedResult_t bta_gattc_enqueue(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data); extern bool bta_gattc_is_data_queued(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data); extern void bta_gattc_continue(tBTA_GATTC_CLCB* p_clcb); extern bool bta_gattc_check_notif_registry(tBTA_GATTC_RCB* p_clreg, tBTA_GATTC_SERV* p_srcb, Loading
system/bta/gatt/bta_gattc_main.cc +1 −1 Original line number Diff line number Diff line Loading @@ -328,7 +328,7 @@ bool bta_gattc_sm_execute(tBTA_GATTC_CLCB* p_clcb, uint16_t event, action = state_table[event][i]; if (action != BTA_GATTC_IGNORE) { (*bta_gattc_action[action])(p_clcb, p_data); if (p_clcb->p_q_cmd == p_data) { if (bta_gattc_is_data_queued(p_clcb, p_data)) { /* buffer is queued, don't free in the bta dispatcher. * we free it ourselves when a completion event is received. */ Loading
system/bta/gatt/bta_gattc_utils.cc +62 −9 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ #define LOG_TAG "bt_bta_gattc" #include <base/logging.h> #include <cstdint> #include "bt_target.h" // Must be first to define build configuration Loading @@ -31,12 +33,11 @@ #include "device/include/controller.h" #include "gd/common/init_flags.h" #include "osi/include/allocator.h" #include "osi/include/log.h" #include "types/bt_transport.h" #include "types/hci_role.h" #include "types/raw_address.h" #include <base/logging.h> static uint8_t ble_acceptlist_size() { const controller_t* controller = controller_get_interface(); if (!controller->supports_ble()) { Loading Loading @@ -218,10 +219,29 @@ void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB* p_clcb) { p_srcb->gatt_database.Clear(); } while (!p_clcb->p_q_cmd_queue.empty()) { auto p_q_cmd = p_clcb->p_q_cmd_queue.front(); p_clcb->p_q_cmd_queue.pop_front(); osi_free_and_reset((void**)&p_q_cmd); } if (p_clcb->p_q_cmd != NULL) { osi_free_and_reset((void**)&p_clcb->p_q_cmd); } memset(p_clcb, 0, sizeof(tBTA_GATTC_CLCB)); /* Clear p_clcb. Some of the fields are already reset e.g. p_q_cmd_queue and * p_q_cmd. */ p_clcb->bta_conn_id = 0; p_clcb->bda = {}; p_clcb->transport = 0; p_clcb->p_rcb = NULL; p_clcb->p_srcb = NULL; p_clcb->request_during_discovery = 0; p_clcb->auto_update = 0; p_clcb->disc_active = 0; p_clcb->in_use = 0; p_clcb->state = BTA_GATTC_IDLE_ST; p_clcb->status = GATT_SUCCESS; } /******************************************************************************* Loading Loading @@ -318,24 +338,57 @@ tBTA_GATTC_SERV* bta_gattc_srcb_alloc(const RawAddress& bda) { } return p_tcb; } void bta_gattc_continue(tBTA_GATTC_CLCB* p_clcb) { if (p_clcb->p_q_cmd != NULL) { LOG_INFO("Already scheduled another request for conn_id = 0x%04x", p_clcb->bta_conn_id); return; } if (p_clcb->p_q_cmd_queue.empty()) { LOG_INFO("Nothing to do for conn_id = 0x%04x", p_clcb->bta_conn_id); return; } const tBTA_GATTC_DATA* p_q_cmd = p_clcb->p_q_cmd_queue.front(); p_clcb->p_q_cmd_queue.pop_front(); bta_gattc_sm_execute(p_clcb, p_q_cmd->hdr.event, p_q_cmd); } bool bta_gattc_is_data_queued(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { if (p_clcb->p_q_cmd == p_data) { return true; } auto it = std::find(p_clcb->p_q_cmd_queue.begin(), p_clcb->p_q_cmd_queue.end(), p_data); return it != p_clcb->p_q_cmd_queue.end(); } /******************************************************************************* * * Function bta_gattc_enqueue * * Description enqueue a client request in clcb. * * Returns success or failure. * Returns BtaEnqueuedResult_t * ******************************************************************************/ bool bta_gattc_enqueue(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { BtaEnqueuedResult_t bta_gattc_enqueue(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { if (p_clcb->p_q_cmd == NULL) { p_clcb->p_q_cmd = p_data; return true; return ENQUEUED_READY_TO_SEND; } LOG(ERROR) << __func__ << ": already has a pending command"; /* skip the callback now. ----- need to send callback ? */ return false; LOG_INFO( "Already has a pending command to executer. Queuing for later %s conn " "id=0x%04x", p_clcb->bda.ToString().c_str(), p_clcb->bta_conn_id); p_clcb->p_q_cmd_queue.push_back(p_data); return ENQUEUED_FOR_LATER; } /******************************************************************************* Loading