Merge branch 'bugfix/hfp_ag_cannot_init_conn_v4.4' into 'release/v4.4'

bt: Fixed the index out of bounds of hfp_ag BTC control block (v4.4)

See merge request espressif/esp-idf!22873
pull/11147/head
Wang Meng Yang 2023-03-23 10:50:57 +08:00
commit 7894f032f6
1 zmienionych plików z 71 dodań i 93 usunięć

Wyświetl plik

@ -39,7 +39,7 @@
** Constants & Macros
************************************************************************************/
/* Max HF Clients Supported From App */
static UINT16 btc_max_hf_clients = 1;
static UINT16 btc_max_hf_clients = BTC_HF_NUM_CB;
/* HF Param Definition */
#if HFP_DYNAMIC_MEMORY == FALSE
static hf_local_param_t hf_local_param[BTC_HF_NUM_CB];
@ -78,27 +78,31 @@ static hf_local_param_t *hf_local_param;
#endif
BOOLEAN btc_conf_hf_force_wbs = BTC_HF_WBS_PREFERRED;
#define CHECK_HF_INIT() do { \
if (! hf_local_param[idx].btc_hf_cb.initialized) { \
BTIF_TRACE_WARNING("CHECK_HF_INIT: %s: HF AG not initialized", __FUNCTION__);\
return BT_STATUS_NOT_READY; \
} \
else\
{\
BTIF_TRACE_EVENT("CHECK_HF_INIT: %s", __FUNCTION__);\
}\
#define CHECK_HF_INIT(idx) \
do { \
if ((idx < 0) || (idx >= BTC_HF_NUM_CB)) { \
return BT_STATUS_FAIL; \
} \
if (!hf_local_param[idx].btc_hf_cb.initialized) { \
BTIF_TRACE_WARNING("CHECK_HF_INIT: %s: HF AG not initialized", __FUNCTION__); \
return BT_STATUS_NOT_READY; \
} else { \
BTIF_TRACE_EVENT("CHECK_HF_INIT: %s", __FUNCTION__); \
} \
} while (0)
#define CHECK_HF_SLC_CONNECTED() do { \
if (! hf_local_param[idx].btc_hf_cb.initialized || \
hf_local_param[idx].btc_hf_cb.connection_state != ESP_HF_CONNECTION_STATE_SLC_CONNECTED) { \
BTIF_TRACE_WARNING("CHECK_HF_INIT: %s: HF AG not initialized", __FUNCTION__);\
return BT_STATUS_NOT_READY; \
} \
else\
{\
BTIF_TRACE_EVENT("CHECK_HF_INIT: %s", __FUNCTION__);\
}\
#define CHECK_HF_SLC_CONNECTED(idx) \
do { \
if ((idx < 0) || (idx >= BTC_HF_NUM_CB)) { \
return BT_STATUS_FAIL; \
} \
if (!hf_local_param[idx].btc_hf_cb.initialized || \
hf_local_param[idx].btc_hf_cb.connection_state != ESP_HF_CONNECTION_STATE_SLC_CONNECTED) { \
BTIF_TRACE_WARNING("CHECK_HF_SLC_CONNECTED: %s: HF AG SLC not connected", __FUNCTION__); \
return BT_STATUS_NOT_READY; \
} else { \
BTIF_TRACE_EVENT("CHECK_HF_SLC_CONNECTED: %s", __FUNCTION__); \
} \
} while (0)
@ -122,12 +126,22 @@ static int btc_hf_idx_by_bdaddr(bt_bdaddr_t *bd_addr)
return BTC_HF_INVALID_IDX;
}
static BOOLEAN is_connected(bt_bdaddr_t *bd_addr)
static int btc_hf_find_free_idx(void)
{
int idx = btc_hf_idx_by_bdaddr(bd_addr);
if (((hf_local_param[idx].btc_hf_cb.connection_state == ESP_HF_CONNECTION_STATE_CONNECTED) ||
(hf_local_param[idx].btc_hf_cb.connection_state == ESP_HF_CONNECTION_STATE_SLC_CONNECTED)) &&
((bd_addr == NULL) || (bdcmp(bd_addr->address,hf_local_param[idx].btc_hf_cb.connected_bda.address) == 0))) {
for (int idx = 0; idx < btc_max_hf_clients; ++idx) {
if (hf_local_param[idx].btc_hf_cb.initialized &&
hf_local_param[idx].btc_hf_cb.connection_state == ESP_HF_CONNECTION_STATE_DISCONNECTED) {
return idx;
}
}
return BTC_HF_INVALID_IDX;
}
static BOOLEAN is_connected(int idx, bt_bdaddr_t *bd_addr)
{
if ((bdcmp(bd_addr->address,hf_local_param[idx].btc_hf_cb.connected_bda.address) == 0) &&
((hf_local_param[idx].btc_hf_cb.connection_state == ESP_HF_CONNECTION_STATE_CONNECTED) ||
(hf_local_param[idx].btc_hf_cb.connection_state == ESP_HF_CONNECTION_STATE_SLC_CONNECTED))) {
return TRUE;
}
return FALSE;
@ -340,13 +354,13 @@ void btc_hf_deinit(bt_bdaddr_t *bd_addr)
static bt_status_t connect_init(bt_bdaddr_t *bd_addr, uint16_t uuid)
{
int idx = btc_hf_idx_by_bdaddr(bd_addr);
CHECK_HF_INIT();
if (idx == btc_max_hf_clients) {
int idx = btc_hf_find_free_idx();
if (idx == BTC_HF_INVALID_IDX) {
return BT_STATUS_BUSY;
}
if (!is_connected(bd_addr)) {
if (!is_connected(idx, bd_addr)) {
hf_local_param[idx].btc_hf_cb.connection_state = ESP_HF_CONNECTION_STATE_CONNECTING;
bdcpy(hf_local_param[idx].btc_hf_cb.connected_bda.address, bd_addr->address);
BTA_AgOpen(hf_local_param[idx].btc_hf_cb.handle, hf_local_param[idx].btc_hf_cb.connected_bda.address, BTC_HF_SECURITY, BTC_HF_SERVICES);
@ -362,13 +376,13 @@ bt_status_t btc_hf_connect(bt_bdaddr_t *bd_addr)
bt_status_t btc_hf_disconnect(bt_bdaddr_t *bd_addr)
{
int idx = btc_hf_idx_by_bdaddr(bd_addr);
CHECK_HF_INIT();
if ((idx < 0) || (idx >= BTC_HF_NUM_CB)) {
BTC_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
return BT_STATUS_FAIL;
}
if (is_connected(bd_addr) && (idx != BTC_HF_INVALID_IDX)) {
if (is_connected(idx, bd_addr)) {
BTA_AgClose(hf_local_param[idx].btc_hf_cb.handle);
return BT_STATUS_SUCCESS;
}
@ -378,13 +392,9 @@ bt_status_t btc_hf_disconnect(bt_bdaddr_t *bd_addr)
bt_status_t btc_hf_connect_audio(bt_bdaddr_t *bd_addr)
{
int idx = btc_hf_idx_by_bdaddr(bd_addr);
CHECK_HF_SLC_CONNECTED();
if ((idx < 0) || (idx >= BTC_HF_NUM_CB)) {
BTC_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
return BT_STATUS_FAIL;
}
CHECK_HF_SLC_CONNECTED(idx);
if (is_connected(bd_addr) && (idx != BTC_HF_INVALID_IDX)) {
if (is_connected(idx, bd_addr)) {
BTA_AgAudioOpen(hf_local_param[idx].btc_hf_cb.handle);
/* Inform the application that the audio connection has been initiated successfully */
do {
@ -402,13 +412,9 @@ bt_status_t btc_hf_connect_audio(bt_bdaddr_t *bd_addr)
bt_status_t btc_hf_disconnect_audio(bt_bdaddr_t *bd_addr)
{
int idx = btc_hf_idx_by_bdaddr(bd_addr);
CHECK_HF_SLC_CONNECTED();
if ((idx < 0) || (idx >= BTC_HF_NUM_CB)) {
BTC_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
return BT_STATUS_FAIL;
}
CHECK_HF_SLC_CONNECTED(idx);
if (is_connected(bd_addr) && (idx != BTC_HF_INVALID_IDX)) {
if (is_connected(idx, bd_addr)) {
BTA_AgAudioClose(hf_local_param[idx].btc_hf_cb.handle);
return BT_STATUS_SUCCESS;
}
@ -422,13 +428,9 @@ bt_status_t btc_hf_disconnect_audio(bt_bdaddr_t *bd_addr)
static bt_status_t btc_hf_vra(bt_bdaddr_t *bd_addr, esp_hf_vr_state_t value)
{
int idx = btc_hf_idx_by_bdaddr(bd_addr);
CHECK_HF_SLC_CONNECTED();
if ((idx < 0) || (idx >= BTC_HF_NUM_CB)) {
BTC_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
return BT_STATUS_FAIL;
}
CHECK_HF_SLC_CONNECTED(idx);
if (is_connected(bd_addr) && (idx != BTC_HF_INVALID_IDX)) {
if (is_connected(idx, bd_addr)) {
if (hf_local_param[idx].btc_hf_cb.peer_feat & BTA_AG_PEER_FEAT_VREC) {
tBTA_AG_RES_DATA ag_res;
memset(&ag_res, 0, sizeof(ag_res));
@ -445,15 +447,11 @@ static bt_status_t btc_hf_vra(bt_bdaddr_t *bd_addr, esp_hf_vr_state_t value)
static bt_status_t btc_hf_volume_control(bt_bdaddr_t *bd_addr, esp_hf_volume_type_t type, int volume)
{
int idx = btc_hf_idx_by_bdaddr(bd_addr);
CHECK_HF_SLC_CONNECTED();
if ((idx < 0) || (idx >= BTC_HF_NUM_CB)) {
BTC_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
return BT_STATUS_FAIL;
}
CHECK_HF_SLC_CONNECTED(idx);
tBTA_AG_RES_DATA ag_res;
memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
if (is_connected(bd_addr) && (idx != BTC_HF_INVALID_IDX)) {
if (is_connected(idx, bd_addr)) {
ag_res.num = volume;
BTA_AgResult(hf_local_param[idx].btc_hf_cb.handle, (type == ESP_HF_VOLUME_TYPE_SPK) ? BTA_AG_SPK_RES : BTA_AG_MIC_RES, &ag_res);
return BT_STATUS_SUCCESS;
@ -465,13 +463,9 @@ static bt_status_t btc_hf_volume_control(bt_bdaddr_t *bd_addr, esp_hf_volume_typ
static bt_status_t btc_hf_unat_response(bt_bdaddr_t *bd_addr, const char *unat)
{
int idx = btc_hf_idx_by_bdaddr(bd_addr);
CHECK_HF_INIT();
if ((idx < 0) || (idx >= BTC_HF_NUM_CB)) {
BTC_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
return BT_STATUS_FAIL;
}
CHECK_HF_INIT(idx);
if (is_connected(bd_addr) && (idx != BTC_HF_INVALID_IDX))
if (is_connected(idx, bd_addr))
{
tBTA_AG_RES_DATA ag_res;
/* Format the response and send */
@ -493,13 +487,9 @@ static bt_status_t btc_hf_unat_response(bt_bdaddr_t *bd_addr, const char *unat)
static bt_status_t btc_hf_cmee_response(bt_bdaddr_t *bd_addr, esp_hf_at_response_code_t response_code, esp_hf_cme_err_t error_code)
{
int idx = btc_hf_idx_by_bdaddr(bd_addr);
CHECK_HF_INIT();
if ((idx < 0) || (idx >= BTC_HF_NUM_CB)) {
BTC_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
return BT_STATUS_FAIL;
}
CHECK_HF_INIT(idx);
if (is_connected(bd_addr) && (idx != BTC_HF_INVALID_IDX)) {
if (is_connected(idx, bd_addr)) {
tBTA_AG_RES_DATA ag_res;
memset(&ag_res, 0, sizeof(ag_res));
if (response_code == ESP_HF_AT_RESPONSE_CODE_OK) {
@ -521,8 +511,8 @@ static bt_status_t btc_hf_indchange_notification(bt_bdaddr_t *bd_addr,
esp_hf_network_state_t ntk_state, int signal)
{
int idx = btc_hf_idx_by_bdaddr(bd_addr);
CHECK_HF_INIT();
if (is_connected(bd_addr)) {
CHECK_HF_INIT(idx);
if (is_connected(idx, bd_addr)) {
/* Send all indicators to BTA.
* BTA will make sure no duplicates are sent out*/
send_indicator_update(BTA_AG_IND_CALL, call_state);
@ -542,13 +532,9 @@ static bt_status_t btc_hf_cind_response(bt_bdaddr_t *bd_addr,
esp_hf_call_held_status_t call_held_status)
{
int idx = btc_hf_idx_by_bdaddr(bd_addr);
CHECK_HF_INIT();
if ((idx < 0) || (idx >= BTC_HF_NUM_CB)) {
BTC_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
return BT_STATUS_FAIL;
}
CHECK_HF_INIT(idx);
if (is_connected(bd_addr) && (idx != BTC_HF_INVALID_IDX)) {
if (is_connected(idx, bd_addr)) {
tBTA_AG_RES_DATA ag_res;
memset(&ag_res, 0, sizeof (ag_res));
sprintf(ag_res.str, "%d,%d,%d,%d,%d,%d,%d",
@ -570,13 +556,9 @@ static bt_status_t btc_hf_cind_response(bt_bdaddr_t *bd_addr,
static bt_status_t btc_hf_cops_response(bt_bdaddr_t *bd_addr, const char *name)
{
int idx = btc_hf_idx_by_bdaddr(bd_addr);
CHECK_HF_SLC_CONNECTED();
if ((idx < 0) || (idx >= BTC_HF_NUM_CB)) {
BTC_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
return BT_STATUS_FAIL;
}
CHECK_HF_SLC_CONNECTED(idx);
if (is_connected(bd_addr) && (idx != BTC_HF_INVALID_IDX)) {
if (is_connected(idx, bd_addr)) {
tBTA_AG_RES_DATA ag_res;
memset (&ag_res, 0, sizeof (ag_res));
/* Format the response */
@ -595,13 +577,9 @@ static bt_status_t btc_hf_clcc_response(bt_bdaddr_t *bd_addr, int index, esp_hf_
const char *number, esp_hf_call_addr_type_t type)
{
int idx = btc_hf_idx_by_bdaddr(bd_addr);
CHECK_HF_SLC_CONNECTED();
if ((idx < 0) || (idx >= BTC_HF_NUM_CB)) {
BTC_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
return BT_STATUS_FAIL;
}
CHECK_HF_SLC_CONNECTED(idx);
if (is_connected(bd_addr) && (idx != BTC_HF_INVALID_IDX)) {
if (is_connected(idx, bd_addr)) {
tBTA_AG_RES_DATA ag_res;
memset (&ag_res, 0, sizeof (ag_res));
if (index == 0) {
@ -628,9 +606,9 @@ static bt_status_t btc_hf_clcc_response(bt_bdaddr_t *bd_addr, int index, esp_hf_
static bt_status_t btc_hf_cnum_response(bt_bdaddr_t *bd_addr, const char *number, esp_hf_subscriber_service_type_t type)
{
int idx = btc_hf_idx_by_bdaddr(bd_addr);
CHECK_HF_SLC_CONNECTED();
CHECK_HF_SLC_CONNECTED(idx);
if (is_connected(bd_addr) && (idx != BTC_HF_INVALID_IDX)) {
if (is_connected(idx, bd_addr)) {
tBTA_AG_RES_DATA ag_res;
memset(&ag_res, 0, sizeof (ag_res));
BTC_TRACE_EVENT("cnum_response: number = %s, type = %d", number, type);
@ -650,9 +628,9 @@ static bt_status_t btc_hf_cnum_response(bt_bdaddr_t *bd_addr, const char *number
static bt_status_t btc_hf_inband_ring(bt_bdaddr_t *bd_addr, esp_hf_in_band_ring_state_t state)
{
int idx = btc_hf_idx_by_bdaddr(bd_addr);
CHECK_HF_SLC_CONNECTED();
CHECK_HF_SLC_CONNECTED(idx);
if (is_connected(bd_addr) && (idx != BTC_HF_INVALID_IDX)) {
if (is_connected(idx, bd_addr)) {
tBTA_AG_RES_DATA ag_res;
memset (&ag_res, 0, sizeof (ag_res));
ag_res.state = state;
@ -681,7 +659,7 @@ static bt_status_t btc_hf_phone_state_update(bt_bdaddr_t *bd_addr,int num_active
}
BTC_TRACE_DEBUG("phone_state_change: idx = %d", idx);
CHECK_HF_SLC_CONNECTED();
CHECK_HF_SLC_CONNECTED(idx);
BTC_TRACE_DEBUG("phone_state_change: num_active=%d [prev: %d] num_held=%d[prev: %d] call =%s [prev: %s] call_setup=%s [prev: %s]",
num_active, hf_local_param[idx].btc_hf_cb.num_active,
num_held, hf_local_param[idx].btc_hf_cb.num_held,
@ -888,7 +866,7 @@ bt_status_t btc_hf_ci_sco_data(void)
bt_status_t status = BT_STATUS_SUCCESS;
#if (BTM_SCO_HCI_INCLUDED == TRUE)
int idx = btc_hf_latest_connected_idx();
CHECK_HF_SLC_CONNECTED();
CHECK_HF_SLC_CONNECTED(idx);
if (idx != BTC_HF_INVALID_IDX) {
BTA_AgCiData(hf_local_param[idx].btc_hf_cb.handle);