mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
fix(bt/bluedroid): Fixed SPP connection failure
The connection failure is caused by the BTU and application layer status being out of sync.
This commit is contained in:
parent
7cbee80fb9
commit
05d196938d
@ -847,7 +847,7 @@ extern tBTA_JV_STATUS BTA_JvRfcommConnect(tBTA_SEC sec_mask,
|
||||
** BTA_JV_FAILURE, otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern tBTA_JV_STATUS BTA_JvRfcommClose(UINT32 handle, tBTA_JV_RFCOMM_CBACK *p_cback, void *user_data);
|
||||
extern tBTA_JV_STATUS BTA_JvRfcommClose(UINT32 handle, void *user_data);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
|
@ -294,11 +294,10 @@ tBTA_JV_RFC_CB *bta_jv_rfc_port_to_cb(UINT16 port_handle)
|
||||
return p_cb;
|
||||
}
|
||||
|
||||
static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pcb, BOOLEAN close_server)
|
||||
static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pcb, BOOLEAN close_server, BOOLEAN close_pending)
|
||||
{
|
||||
tBTA_JV_STATUS status = BTA_JV_SUCCESS;
|
||||
BOOLEAN remove_server = FALSE;
|
||||
int close_pending = 0;
|
||||
|
||||
UINT8 used = 0, i, listen = 0;
|
||||
tPORT_STATE port_state;
|
||||
@ -321,11 +320,11 @@ static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pc
|
||||
switch (p_pcb->state) {
|
||||
case BTA_JV_ST_CL_CLOSING:
|
||||
case BTA_JV_ST_SR_CLOSING:
|
||||
APPL_TRACE_WARNING("bta_jv_free_sr_rfc_cb: return on closing, port state:%d, "
|
||||
APPL_TRACE_DEBUG("bta_jv_free_sr_rfc_cb: return on closing, port state:%d, "
|
||||
"scn:%d, p_pcb:%p, user_data:%p", p_pcb->state, p_cb->scn, p_pcb,
|
||||
p_pcb->user_data);
|
||||
status = BTA_JV_FAILURE;
|
||||
return status;
|
||||
break;
|
||||
case BTA_JV_ST_CL_OPEN:
|
||||
case BTA_JV_ST_CL_OPENING:
|
||||
APPL_TRACE_DEBUG("bta_jv_free_sr_rfc_cb: state: %d, scn:%d,"
|
||||
@ -1729,6 +1728,7 @@ static void bta_jv_port_mgmt_cl_cback(UINT32 code, UINT16 port_handle, void* dat
|
||||
UINT16 lcid;
|
||||
tBTA_JV_RFCOMM_CBACK *p_cback; /* the callback function */
|
||||
tPORT_MGMT_CL_CALLBACK_ARG *p_mgmt_cb_arg = (tPORT_MGMT_CL_CALLBACK_ARG *)data;
|
||||
void *user_data = NULL;
|
||||
|
||||
APPL_TRACE_DEBUG( "bta_jv_port_mgmt_cl_cback:code:%d, port_handle%d", code, port_handle);
|
||||
if (NULL == p_cb || NULL == p_cb->p_cback) {
|
||||
@ -1758,13 +1758,14 @@ static void bta_jv_port_mgmt_cl_cback(UINT32 code, UINT16 port_handle, void* dat
|
||||
evt_data.rfc_close.async = FALSE;
|
||||
evt_data.rfc_close.status = BTA_JV_SUCCESS;
|
||||
}
|
||||
//p_pcb->state = BTA_JV_ST_NONE;
|
||||
//p_pcb->cong = FALSE;
|
||||
p_cback = p_cb->p_cback;
|
||||
p_cback(BTA_JV_RFCOMM_CLOSE_EVT, &evt_data, p_pcb->user_data);
|
||||
//bta_jv_free_rfc_cb(p_cb, p_pcb);
|
||||
}
|
||||
user_data = p_pcb->user_data;
|
||||
|
||||
// To free up resources.
|
||||
p_pcb->state = BTA_JV_ST_CL_CLOSING;
|
||||
bta_jv_free_rfc_cb(p_cb, p_pcb, FALSE, FALSE);
|
||||
p_cback(BTA_JV_RFCOMM_CLOSE_EVT, &evt_data, user_data);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -1937,7 +1938,6 @@ void bta_jv_rfcomm_close(tBTA_JV_MSG *p_data)
|
||||
tBTA_JV_API_RFCOMM_CLOSE *cc = &(p_data->rfcomm_close);
|
||||
tBTA_JV_RFC_CB *p_cb = NULL;
|
||||
tBTA_JV_PCB *p_pcb = NULL;
|
||||
tBTA_JV evt_data = {0};
|
||||
APPL_TRACE_DEBUG("%s, rfc handle:%d",__func__, cc->handle);
|
||||
if (!cc->handle) {
|
||||
APPL_TRACE_ERROR("%s, rfc handle is null", __func__);
|
||||
@ -1948,20 +1948,9 @@ void bta_jv_rfcomm_close(tBTA_JV_MSG *p_data)
|
||||
if (!find_rfc_pcb(user_data, &p_cb, &p_pcb)) {
|
||||
return;
|
||||
}
|
||||
if(cc->p_cback) {
|
||||
evt_data.rfc_close.status = BTA_JV_SUCCESS;
|
||||
evt_data.rfc_close.port_status = PORT_LOCAL_CLOSED;
|
||||
evt_data.rfc_close.handle = cc->handle;
|
||||
evt_data.rfc_close.async = TRUE;
|
||||
if (p_pcb && (p_pcb->state == BTA_JV_ST_SR_LISTEN ||
|
||||
p_pcb->state == BTA_JV_ST_SR_OPEN ||
|
||||
p_pcb->state == BTA_JV_ST_CL_OPEN ||
|
||||
p_pcb->state == BTA_JV_ST_CL_OPENING)) {
|
||||
evt_data.rfc_close.async = FALSE;
|
||||
}
|
||||
cc->p_cback(BTA_JV_RFCOMM_CLOSE_EVT, (tBTA_JV *)&evt_data, user_data);
|
||||
}
|
||||
bta_jv_free_rfc_cb(p_cb, p_pcb, FALSE);
|
||||
|
||||
bta_jv_free_rfc_cb(p_cb, p_pcb, FALSE, TRUE);
|
||||
|
||||
APPL_TRACE_DEBUG("%s: sec id in use:%d, rfc_cb in use:%d",__func__,
|
||||
get_sec_id_used(), get_rfc_cb_used());
|
||||
}
|
||||
@ -2062,7 +2051,7 @@ static void bta_jv_port_mgmt_sr_cback(UINT32 code, UINT16 port_handle, void *dat
|
||||
APPL_TRACE_ERROR("create new listen port, but upper layer reject connection");
|
||||
p_pcb_new_listen->user_data = NULL;
|
||||
p_pcb->state = BTA_JV_ST_SR_LISTEN;
|
||||
bta_jv_free_rfc_cb(p_cb, p_pcb_new_listen, FALSE);
|
||||
bta_jv_free_rfc_cb(p_cb, p_pcb_new_listen, FALSE, FALSE);
|
||||
if (p_mgmt_cb_arg) {
|
||||
p_mgmt_cb_arg->accept = FALSE;
|
||||
}
|
||||
@ -2102,10 +2091,11 @@ static void bta_jv_port_mgmt_sr_cback(UINT32 code, UINT16 port_handle, void *dat
|
||||
evt_data.rfc_close.async = FALSE;
|
||||
evt_data.rfc_close.status = BTA_JV_SUCCESS;
|
||||
}
|
||||
//p_pcb->state = BTA_JV_ST_NONE;
|
||||
p_cback(BTA_JV_RFCOMM_CLOSE_EVT, &evt_data, user_data);
|
||||
//bta_jv_free_rfc_cb(p_cb, p_pcb);
|
||||
|
||||
// To free up resources.
|
||||
p_pcb->state = BTA_JV_ST_SR_CLOSING;
|
||||
bta_jv_free_rfc_cb(p_cb, p_pcb, FALSE, FALSE);
|
||||
p_cback(BTA_JV_RFCOMM_CLOSE_EVT, &evt_data, user_data);
|
||||
APPL_TRACE_DEBUG("PORT_CLOSED after BTA_JV_RFCOMM_CLOSE_EVT: curr_sess:%d, max_sess:%d",
|
||||
p_cb->curr_sess, p_cb->max_sess);
|
||||
}
|
||||
@ -2339,7 +2329,7 @@ void bta_jv_rfcomm_stop_server(tBTA_JV_MSG *p_data)
|
||||
}
|
||||
APPL_TRACE_DEBUG("bta_jv_rfcomm_stop_server: p_pcb:%p, p_pcb->port_handle:%d",
|
||||
p_pcb, p_pcb->port_handle);
|
||||
bta_jv_free_rfc_cb(p_cb, p_pcb, TRUE);
|
||||
bta_jv_free_rfc_cb(p_cb, p_pcb, TRUE, FALSE);
|
||||
APPL_TRACE_DEBUG("bta_jv_rfcomm_stop_server: sec id in use:%d, rfc_cb in use:%d",
|
||||
get_sec_id_used(), get_rfc_cb_used());
|
||||
}
|
||||
|
@ -939,7 +939,7 @@ tBTA_JV_STATUS BTA_JvRfcommConnect(tBTA_SEC sec_mask,
|
||||
** BTA_JV_FAILURE, otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_JV_STATUS BTA_JvRfcommClose(UINT32 handle, tBTA_JV_RFCOMM_CBACK *p_cback, void *user_data)
|
||||
tBTA_JV_STATUS BTA_JvRfcommClose(UINT32 handle, void *user_data)
|
||||
{
|
||||
tBTA_JV_STATUS status = BTA_JV_FAILURE;
|
||||
tBTA_JV_API_RFCOMM_CLOSE *p_msg;
|
||||
@ -954,7 +954,6 @@ tBTA_JV_STATUS BTA_JvRfcommClose(UINT32 handle, tBTA_JV_RFCOMM_CBACK *p_cback, v
|
||||
p_msg->handle = handle;
|
||||
p_msg->p_cb = &bta_jv_cb.rfc_cb[hi];
|
||||
p_msg->p_pcb = &bta_jv_cb.port_cb[p_msg->p_cb->rfc_hdl[si] - 1];
|
||||
p_msg->p_cback = p_cback;
|
||||
p_msg->user_data = user_data;
|
||||
bta_sys_sendmsg(p_msg);
|
||||
status = BTA_JV_SUCCESS;
|
||||
|
@ -340,7 +340,6 @@ typedef struct {
|
||||
UINT32 handle;
|
||||
tBTA_JV_RFC_CB *p_cb;
|
||||
tBTA_JV_PCB *p_pcb;
|
||||
tBTA_JV_RFCOMM_CBACK *p_cback;
|
||||
void *user_data;
|
||||
} tBTA_JV_API_RFCOMM_CLOSE;
|
||||
#endif /* BTA_JV_RFCOMM_INCLUDED */
|
||||
|
@ -424,19 +424,6 @@ static void *btc_spp_rfcomm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *u
|
||||
slot->rfc_port_handle = BTA_JvRfcommGetPortHdl(p_data->rfc_open.handle);
|
||||
BTA_JvSetPmProfile(p_data->rfc_open.handle, BTA_JV_PM_ID_1, BTA_JV_CONN_OPEN);
|
||||
break;
|
||||
case BTA_JV_RFCOMM_CLOSE_EVT:
|
||||
slot = spp_find_slot_by_id(id);
|
||||
if (!slot) {
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event);
|
||||
p_data->rfc_close.status = ESP_SPP_NO_CONNECTION;
|
||||
break;
|
||||
}
|
||||
if (slot->rfc_handle && p_data->rfc_close.port_status != PORT_LOCAL_CLOSED) {
|
||||
BTA_JvRfcommClose(slot->rfc_handle, NULL, (void *)slot->id);
|
||||
}
|
||||
p_data->rfc_close.status = BTA_JV_SUCCESS;
|
||||
p_data->rfc_close.user_data = (void *)(uintptr_t)slot->id;
|
||||
break;
|
||||
case BTA_JV_RFCOMM_DATA_IND_EVT:
|
||||
break;
|
||||
case BTA_JV_FREE_SCN_EVT:
|
||||
@ -608,8 +595,7 @@ static void btc_spp_uninit(void)
|
||||
// first, remove all connection
|
||||
for (size_t i = 1; i <= MAX_RFC_PORTS; i++) {
|
||||
if (spp_local_param.spp_slots[i] != NULL && !spp_local_param.spp_slots[i]->is_server) {
|
||||
BTA_JvRfcommClose(spp_local_param.spp_slots[i]->rfc_handle, (tBTA_JV_RFCOMM_CBACK *)btc_spp_rfcomm_inter_cb,
|
||||
(void *)spp_local_param.spp_slots[i]->id);
|
||||
BTA_JvRfcommClose(spp_local_param.spp_slots[i]->rfc_handle, (void *)spp_local_param.spp_slots[i]->id);
|
||||
}
|
||||
}
|
||||
// second, remove all server
|
||||
@ -727,7 +713,7 @@ static void btc_spp_disconnect(btc_spp_args_t *arg)
|
||||
ret = ESP_SPP_NO_CONNECTION;
|
||||
break;
|
||||
}
|
||||
BTA_JvRfcommClose(arg->disconnect.handle, (tBTA_JV_RFCOMM_CBACK *)btc_spp_rfcomm_inter_cb, (void *)slot->id);
|
||||
BTA_JvRfcommClose(arg->disconnect.handle, (void *)slot->id);
|
||||
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
|
||||
} while(0);
|
||||
|
||||
@ -835,9 +821,7 @@ static void btc_spp_stop_srv(btc_spp_args_t *arg)
|
||||
if (spp_local_param.spp_slots[i] != NULL && !spp_local_param.spp_slots[i]->is_server &&
|
||||
spp_local_param.spp_slots[i]->sdp_handle > 0 &&
|
||||
spp_local_param.spp_slots[i]->scn == srv_scn_arr[j]) {
|
||||
BTA_JvRfcommClose(spp_local_param.spp_slots[i]->rfc_handle,
|
||||
(tBTA_JV_RFCOMM_CBACK *)btc_spp_rfcomm_inter_cb,
|
||||
(void *)spp_local_param.spp_slots[i]->id);
|
||||
BTA_JvRfcommClose(spp_local_param.spp_slots[i]->rfc_handle, (void *)spp_local_param.spp_slots[i]->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1175,28 +1159,27 @@ void btc_spp_cb_handler(btc_msg_t *msg)
|
||||
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
|
||||
break;
|
||||
case BTA_JV_RFCOMM_CLOSE_EVT:
|
||||
param.close.status = p_data->rfc_close.status;
|
||||
param.close.status = BTA_JV_SUCCESS;
|
||||
param.close.port_status = p_data->rfc_close.port_status;
|
||||
param.close.handle = p_data->rfc_close.handle;
|
||||
param.close.async = p_data->rfc_close.async;
|
||||
if (spp_local_param.spp_mode == ESP_SPP_MODE_CB) {
|
||||
btc_spp_cb_to_app(ESP_SPP_CLOSE_EVT, ¶m);
|
||||
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
|
||||
uint32_t id = (uintptr_t)p_data->rfc_close.user_data;
|
||||
slot = spp_find_slot_by_id(id);
|
||||
slot = spp_find_slot_by_handle(p_data->rfc_close.handle);
|
||||
if (!slot) {
|
||||
param.close.status = ESP_SPP_NO_CONNECTION;
|
||||
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event);
|
||||
break;
|
||||
}
|
||||
spp_free_slot(slot);
|
||||
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
|
||||
btc_spp_cb_to_app(ESP_SPP_CLOSE_EVT, ¶m);
|
||||
} else {
|
||||
bool need_call = true;
|
||||
do {
|
||||
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
|
||||
uint32_t id = (uintptr_t)p_data->rfc_close.user_data;
|
||||
slot = spp_find_slot_by_id(id);
|
||||
slot = spp_find_slot_by_handle(p_data->rfc_close.handle);
|
||||
if (!slot) {
|
||||
param.close.status = ESP_SPP_NO_CONNECTION;
|
||||
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
|
||||
|
Loading…
Reference in New Issue
Block a user