diff --git a/components/bt/host/bluedroid/bta/hf_ag/bta_ag_act.c b/components/bt/host/bluedroid/bta/hf_ag/bta_ag_act.c index 5313cfd61b..cedeb2e397 100644 --- a/components/bt/host/bluedroid/bta/hf_ag/bta_ag_act.c +++ b/components/bt/host/bluedroid/bta/hf_ag/bta_ag_act.c @@ -494,14 +494,14 @@ void bta_ag_rfc_acp_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data) UINT16 lcid; int i; tBTA_AG_SCB *ag_scb, *other_scb; - BD_ADDR dev_addr; + BD_ADDR dev_addr = {0}; int status; /* set role */ p_scb->role = BTA_AG_ACP; APPL_TRACE_DEBUG ("bta_ag_rfc_acp_open: serv_handle0 = %d serv_handle1 = %d", p_scb->serv_handle[0], p_scb->serv_handle[1]); /* get bd addr of peer */ - if (PORT_SUCCESS != (status=PORT_CheckConnection(p_data->rfc.port_handle, dev_addr, &lcid))) { + if (PORT_SUCCESS != (status = PORT_CheckConnection(p_data->rfc.port_handle, FALSE, dev_addr, &lcid))) { APPL_TRACE_DEBUG ("bta_ag_rfc_acp_open error PORT_CheckConnection returned status %d", status); } /* Collision Handling */ diff --git a/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_act.c b/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_act.c index 3adaad23ee..0e0c43addf 100644 --- a/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_act.c +++ b/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_act.c @@ -267,7 +267,7 @@ void bta_hf_client_rfc_open(tBTA_HF_CLIENT_DATA *p_data) void bta_hf_client_rfc_acp_open(tBTA_HF_CLIENT_DATA *p_data) { UINT16 lcid; - BD_ADDR dev_addr; + BD_ADDR dev_addr = {0}; int status; /* set role */ @@ -277,7 +277,7 @@ void bta_hf_client_rfc_acp_open(tBTA_HF_CLIENT_DATA *p_data) bta_hf_client_cb.scb.serv_handle, p_data->rfc.port_handle); /* get bd addr of peer */ - if (PORT_SUCCESS != (status = PORT_CheckConnection(p_data->rfc.port_handle, dev_addr, &lcid))) { + if (PORT_SUCCESS != (status = PORT_CheckConnection(p_data->rfc.port_handle, FALSE, dev_addr, &lcid))) { APPL_TRACE_DEBUG ("bta_hf_client_rfc_acp_open error PORT_CheckConnection returned status %d", status); } diff --git a/components/bt/host/bluedroid/bta/jv/bta_jv_act.c b/components/bt/host/bluedroid/bta/jv/bta_jv_act.c index e5e6f8d204..d7d345baa9 100644 --- a/components/bt/host/bluedroid/bta/jv/bta_jv_act.c +++ b/components/bt/host/bluedroid/bta/jv/bta_jv_act.c @@ -587,8 +587,8 @@ static tBTA_JV_PM_CB *bta_jv_alloc_set_pm_profile_cb(UINT32 jv_handle, tBTA_JV_P for (j = 0; j < BTA_JV_MAX_RFC_CONN; j++) { if (jv_handle == bta_jv_cb.port_cb[j].handle) { pp_cb = &bta_jv_cb.port_cb[j].p_pm_cb; - if (PORT_SUCCESS != PORT_CheckConnection( - bta_jv_cb.port_cb[j].port_handle, peer_bd_addr, NULL)) { + if (PORT_SUCCESS != + PORT_CheckConnection(bta_jv_cb.port_cb[j].port_handle, FALSE, peer_bd_addr, NULL)) { i = BTA_JV_PM_MAX_NUM; } break; @@ -1666,7 +1666,7 @@ static void bta_jv_port_mgmt_cl_cback(UINT32 code, UINT16 port_handle, void* dat tBTA_JV_RFC_CB *p_cb = bta_jv_rfc_port_to_cb(port_handle); tBTA_JV_PCB *p_pcb = bta_jv_rfc_port_to_pcb(port_handle); tBTA_JV evt_data = {0}; - BD_ADDR rem_bda; + BD_ADDR rem_bda = {0}; UINT16 lcid; tBTA_JV_RFCOMM_CBACK *p_cback; /* the callback function */ @@ -1678,7 +1678,7 @@ static void bta_jv_port_mgmt_cl_cback(UINT32 code, UINT16 port_handle, void* dat APPL_TRACE_DEBUG( "bta_jv_port_mgmt_cl_cback code=%d port_handle:%d handle:%d", code, port_handle, p_cb->handle); - PORT_CheckConnection(port_handle, rem_bda, &lcid); + PORT_CheckConnection(port_handle, FALSE, rem_bda, &lcid); if (code == PORT_SUCCESS) { evt_data.rfc_open.handle = p_pcb->handle; @@ -1930,11 +1930,13 @@ static void bta_jv_port_mgmt_sr_cback(UINT32 code, UINT16 port_handle, void *dat tBTA_JV_PCB *p_pcb = bta_jv_rfc_port_to_pcb(port_handle); tBTA_JV_RFC_CB *p_cb = bta_jv_rfc_port_to_cb(port_handle); tBTA_JV evt_data = {0}; - BD_ADDR rem_bda; + BD_ADDR rem_bda = {0}; UINT16 lcid; - BOOLEAN *accept = (BOOLEAN *)data; + tPORT_MGMT_SR_CALLBACK_ARG *p_mgmt_cb_arg = (tPORT_MGMT_SR_CALLBACK_ARG *)data; void *user_data = NULL; void *new_user_data = NULL; + int status; + int failed = TRUE; // APPL_TRACE_DEBUG("bta_jv_port_mgmt_sr_cback, code:0x%x, port_handle:%d", code, (uint16_t)port_handle); if (NULL == p_cb || NULL == p_cb->p_cback) { @@ -1946,13 +1948,20 @@ static void bta_jv_port_mgmt_sr_cback(UINT32 code, UINT16 port_handle, void *dat // APPL_TRACE_DEBUG( "bta_jv_port_mgmt_sr_cback code=%p port_handle:0x%x handle:0x%x, p_pcb:%p, user:%p", // code, port_handle, p_cb->handle, p_pcb, p_pcb->user_data); - PORT_CheckConnection(port_handle, rem_bda, &lcid); - int failed = TRUE; + if (p_mgmt_cb_arg) { + if ((status = PORT_CheckConnection(port_handle, p_mgmt_cb_arg->ignore_rfc_state, rem_bda, &lcid)) != + PORT_SUCCESS) { + APPL_TRACE_WARNING("PORT_CheckConnection status:%d", status); + } + } else { + PORT_CheckConnection(port_handle, FALSE, rem_bda, &lcid); + } + if (code == PORT_SUCCESS) { failed = FALSE; /* accept the connection defaulted */ - if (accept) { - *accept = TRUE; + if (p_mgmt_cb_arg) { + p_mgmt_cb_arg->accept = TRUE; } evt_data.rfc_srv_open.handle = p_pcb->handle; evt_data.rfc_srv_open.status = BTA_JV_SUCCESS; @@ -1974,8 +1983,8 @@ static void bta_jv_port_mgmt_sr_cback(UINT32 code, UINT16 port_handle, void *dat 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); - if (accept) { - *accept = FALSE; + if (p_mgmt_cb_arg) { + p_mgmt_cb_arg->accept = FALSE; } } } else { @@ -1991,8 +2000,8 @@ static void bta_jv_port_mgmt_sr_cback(UINT32 code, UINT16 port_handle, void *dat */ APPL_TRACE_ERROR("no listen port, and upper layer reject connection"); p_pcb->state = BTA_JV_ST_SR_LISTEN; - if (accept) { - *accept = FALSE; + if (p_mgmt_cb_arg) { + p_mgmt_cb_arg->accept = FALSE; } } APPL_TRACE_ERROR("bta_jv_add_rfc_port failed to create new listen port"); diff --git a/components/bt/host/bluedroid/stack/include/stack/port_api.h b/components/bt/host/bluedroid/stack/include/stack/port_api.h index cf63477fb3..fb9e7574ba 100644 --- a/components/bt/host/bluedroid/stack/include/stack/port_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/port_api.h @@ -107,6 +107,14 @@ typedef void (tPORT_CALLBACK) (UINT32 code, UINT16 port_handle); typedef void (tPORT_MGMT_CALLBACK) (UINT32 code, UINT16 port_handle, void* data); +/** + * Define the server port manage callback function argument + */ +typedef struct { + BOOLEAN accept; /* If upper layer accepts the incoming connection */ + BOOLEAN ignore_rfc_state; /* If need to ignore rfc state for PORT_CheckConnection */ +} tPORT_MGMT_SR_CALLBACK_ARG; + /* ** Define events that registered application can receive in the callback */ @@ -312,11 +320,12 @@ extern int PORT_SetEventMask (UINT16 port_handle, UINT32 mask); ** by handle is up and running ** ** Parameters: handle - Handle of the port returned in the Open +** ignore_rfc_state - If need to ignore rfc state ** bd_addr - OUT bd_addr of the peer ** p_lcid - OUT L2CAP's LCID ** *******************************************************************************/ -extern int PORT_CheckConnection (UINT16 handle, BD_ADDR bd_addr, +extern int PORT_CheckConnection (UINT16 handle, BOOLEAN ignore_rfc_state, BD_ADDR bd_addr, UINT16 *p_lcid); /******************************************************************************* diff --git a/components/bt/host/bluedroid/stack/rfcomm/port_api.c b/components/bt/host/bluedroid/stack/rfcomm/port_api.c index eaf9d560c2..99d469c96b 100644 --- a/components/bt/host/bluedroid/stack/rfcomm/port_api.c +++ b/components/bt/host/bluedroid/stack/rfcomm/port_api.c @@ -464,11 +464,12 @@ int PORT_SetEventMask (UINT16 port_handle, UINT32 mask) ** by handle is up and running ** ** Parameters: handle - Handle returned in the RFCOMM_CreateConnection +** ignore_rfc_state - If need to ignore rfc state ** bd_addr - OUT bd_addr of the peer ** p_lcid - OUT L2CAP's LCID ** *******************************************************************************/ -int PORT_CheckConnection (UINT16 handle, BD_ADDR bd_addr, UINT16 *p_lcid) +int PORT_CheckConnection(UINT16 handle, BOOLEAN ignore_rfc_state, BD_ADDR bd_addr, UINT16 *p_lcid) { tPORT *p_port; @@ -485,9 +486,8 @@ int PORT_CheckConnection (UINT16 handle, BD_ADDR bd_addr, UINT16 *p_lcid) return (PORT_NOT_OPENED); } - if (!p_port->rfc.p_mcb - || !p_port->rfc.p_mcb->peer_ready - || (p_port->rfc.state != RFC_STATE_OPENED)) { + if (!p_port->rfc.p_mcb || !p_port->rfc.p_mcb->peer_ready || + (!ignore_rfc_state ? (p_port->rfc.state != RFC_STATE_OPENED) : false)) { return (PORT_LINE_ERR); } diff --git a/components/bt/host/bluedroid/stack/rfcomm/port_rfc.c b/components/bt/host/bluedroid/stack/rfcomm/port_rfc.c index 46e92d94d7..ddcef1bb7c 100644 --- a/components/bt/host/bluedroid/stack/rfcomm/port_rfc.c +++ b/components/bt/host/bluedroid/stack/rfcomm/port_rfc.c @@ -427,7 +427,10 @@ void PORT_ParNegCnf (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu, UINT8 cl, UINT8 k) void PORT_DlcEstablishInd (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu) { tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci); - BOOLEAN accept = true; + tPORT_MGMT_SR_CALLBACK_ARG mgmt_cb_arg = { + .accept = TRUE, + .ignore_rfc_state = FALSE, + }; RFCOMM_TRACE_DEBUG ("PORT_DlcEstablishInd p_mcb:%p, dlci:%d mtu:%di, p_port:%p", p_mcb, dlci, mtu, p_port); RFCOMM_TRACE_DEBUG ("PORT_DlcEstablishInd p_mcb addr:%02x:%02x:%02x:%02x:%02x:%02x", @@ -461,10 +464,17 @@ void PORT_DlcEstablishInd (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu) } if (p_port->p_mgmt_callback) { - p_port->p_mgmt_callback (PORT_SUCCESS, p_port->inx, &accept); + /** + * @note + * 1. The manage callback function may change the value of accept in mgmt_cb_arg. + * 2. Use mgmt_cb_arg.ignore_rfc_state to work around the issue caused by sending + * RFCOMM establish response after the manage callback function. + */ + mgmt_cb_arg.ignore_rfc_state = TRUE; + p_port->p_mgmt_callback (PORT_SUCCESS, p_port->inx, &mgmt_cb_arg); } - if (accept) { + if (mgmt_cb_arg.accept) { RFCOMM_DlcEstablishRsp(p_mcb, dlci, p_port->mtu, RFCOMM_SUCCESS); p_port->state = PORT_STATE_OPENED; } else {