Browse Source

fix SPP open with wrong remote bd_addr

liqigan 4 years ago
parent
commit
cccd22a080

+ 2 - 2
components/bt/host/bluedroid/bta/hf_ag/bta_ag_act.c

@@ -491,14 +491,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 */

+ 2 - 2
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);
     }
 

+ 23 - 14
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");

+ 10 - 1
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);
 
 /*******************************************************************************

+ 4 - 4
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);
     }
 

+ 13 - 3
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 {