mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-10-30 20:51:41 +00:00 
			
		
		
		
	fix SPP server bugs when the BTC layer can not allocate a slot for the listen port
This commit is contained in:
		| @@ -47,9 +47,9 @@ void bta_ag_port_cback_1(UINT32 code, UINT16 port_handle); | |||||||
| void bta_ag_port_cback_2(UINT32 code, UINT16 port_handle); | void bta_ag_port_cback_2(UINT32 code, UINT16 port_handle); | ||||||
| void bta_ag_port_cback_3(UINT32 code, UINT16 port_handle); | void bta_ag_port_cback_3(UINT32 code, UINT16 port_handle); | ||||||
|  |  | ||||||
| void bta_ag_mgmt_cback_1(UINT32 code, UINT16 port_handle); | void bta_ag_mgmt_cback_1(UINT32 code, UINT16 port_handle, void* data); | ||||||
| void bta_ag_mgmt_cback_2(UINT32 code, UINT16 port_handle); | void bta_ag_mgmt_cback_2(UINT32 code, UINT16 port_handle, void* data); | ||||||
| void bta_ag_mgmt_cback_3(UINT32 code, UINT16 port_handle); | void bta_ag_mgmt_cback_3(UINT32 code, UINT16 port_handle, void* data); | ||||||
|  |  | ||||||
| int bta_ag_data_cback_1(UINT16 port_handle, void *p_data, UINT16 len); | int bta_ag_data_cback_1(UINT16 port_handle, void *p_data, UINT16 len); | ||||||
| int bta_ag_data_cback_2(UINT16 port_handle, void *p_data, UINT16 len); | int bta_ag_data_cback_2(UINT16 port_handle, void *p_data, UINT16 len); | ||||||
| @@ -64,7 +64,8 @@ const tBTA_AG_PORT_CBACK bta_ag_port_cback_tbl[] = | |||||||
|     bta_ag_port_cback_3 |     bta_ag_port_cback_3 | ||||||
| }; | }; | ||||||
|  |  | ||||||
| const tBTA_AG_PORT_CBACK bta_ag_mgmt_cback_tbl[] = | typedef tPORT_MGMT_CALLBACK *tBTA_AG_MGMT_CBACK; | ||||||
|  | const tBTA_AG_MGMT_CBACK bta_ag_mgmt_cback_tbl[] = | ||||||
| { | { | ||||||
|     bta_ag_mgmt_cback_1, |     bta_ag_mgmt_cback_1, | ||||||
|     bta_ag_mgmt_cback_2, |     bta_ag_mgmt_cback_2, | ||||||
| @@ -206,9 +207,9 @@ static int bta_ag_data_cback(UINT16 port_handle, void *p_data, UINT16 len, UINT1 | |||||||
| ** Returns          void | ** Returns          void | ||||||
| ** | ** | ||||||
| *******************************************************************************/ | *******************************************************************************/ | ||||||
| void bta_ag_mgmt_cback_1(UINT32 code, UINT16 handle) {bta_ag_mgmt_cback(code, handle, 1);} | void bta_ag_mgmt_cback_1(UINT32 code, UINT16 handle, void* data) {bta_ag_mgmt_cback(code, handle, 1);} | ||||||
| void bta_ag_mgmt_cback_2(UINT32 code, UINT16 handle) {bta_ag_mgmt_cback(code, handle, 2);} | void bta_ag_mgmt_cback_2(UINT32 code, UINT16 handle, void* data) {bta_ag_mgmt_cback(code, handle, 2);} | ||||||
| void bta_ag_mgmt_cback_3(UINT32 code, UINT16 handle) {bta_ag_mgmt_cback(code, handle, 3);} | void bta_ag_mgmt_cback_3(UINT32 code, UINT16 handle, void* data) {bta_ag_mgmt_cback(code, handle, 3);} | ||||||
| void bta_ag_port_cback_1(UINT32 code, UINT16 handle) {bta_ag_port_cback(code, handle, 1);} | void bta_ag_port_cback_1(UINT32 code, UINT16 handle) {bta_ag_port_cback(code, handle, 1);} | ||||||
| void bta_ag_port_cback_2(UINT32 code, UINT16 handle) {bta_ag_port_cback(code, handle, 2);} | void bta_ag_port_cback_2(UINT32 code, UINT16 handle) {bta_ag_port_cback(code, handle, 2);} | ||||||
| void bta_ag_port_cback_3(UINT32 code, UINT16 handle) {bta_ag_port_cback(code, handle, 3);} | void bta_ag_port_cback_3(UINT32 code, UINT16 handle) {bta_ag_port_cback(code, handle, 3);} | ||||||
|   | |||||||
| @@ -70,7 +70,7 @@ static void bta_hf_client_port_cback(UINT32 code, UINT16 port_handle) | |||||||
| ** Returns          void | ** Returns          void | ||||||
| ** | ** | ||||||
| *******************************************************************************/ | *******************************************************************************/ | ||||||
| static void bta_hf_client_mgmt_cback(UINT32 code, UINT16 port_handle) | static void bta_hf_client_mgmt_cback(UINT32 code, UINT16 port_handle, void* data) | ||||||
| { | { | ||||||
|     tBTA_HF_CLIENT_RFC     *p_buf; |     tBTA_HF_CLIENT_RFC     *p_buf; | ||||||
|     UINT16                  event; |     UINT16                  event; | ||||||
|   | |||||||
| @@ -299,6 +299,7 @@ typedef struct { | |||||||
|     UINT32          port_status; /* PORT status */ |     UINT32          port_status; /* PORT status */ | ||||||
|     UINT32          handle;      /* The connection handle */ |     UINT32          handle;      /* The connection handle */ | ||||||
|     BOOLEAN         async;       /* FALSE, if local initiates disconnect */ |     BOOLEAN         async;       /* FALSE, if local initiates disconnect */ | ||||||
|  |     void *          user_data;   /* piggyback caller's private data */ | ||||||
| } tBTA_JV_RFCOMM_CLOSE; | } tBTA_JV_RFCOMM_CLOSE; | ||||||
|  |  | ||||||
| /* data associated with BTA_JV_RFCOMM_START_EVT */ | /* data associated with BTA_JV_RFCOMM_START_EVT */ | ||||||
|   | |||||||
| @@ -115,7 +115,7 @@ static void bta_jv_pm_state_change(tBTA_JV_PM_CB *p_cb, const tBTA_JV_CONN_STATE | |||||||
| tBTA_JV_STATUS bta_jv_set_pm_conn_state(tBTA_JV_PM_CB *p_cb, const tBTA_JV_CONN_STATE new_st); | tBTA_JV_STATUS bta_jv_set_pm_conn_state(tBTA_JV_PM_CB *p_cb, const tBTA_JV_CONN_STATE new_st); | ||||||
|  |  | ||||||
| static int find_rfc_pcb(void *user_data, tBTA_JV_RFC_CB **cb, tBTA_JV_PCB **pcb); | static int find_rfc_pcb(void *user_data, tBTA_JV_RFC_CB **cb, tBTA_JV_PCB **pcb); | ||||||
| static void bta_jv_port_mgmt_sr_cback(UINT32 code, UINT16 port_handle); | static void bta_jv_port_mgmt_sr_cback(UINT32 code, UINT16 port_handle, void* data); | ||||||
| static void bta_jv_port_event_sr_cback(UINT32 code, UINT16 port_handle); | static void bta_jv_port_event_sr_cback(UINT32 code, UINT16 port_handle); | ||||||
| static int bta_jv_port_data_co_cback(UINT16 port_handle, UINT8 *buf, UINT16 len, int type); | static int bta_jv_port_data_co_cback(UINT16 port_handle, UINT8 *buf, UINT16 len, int type); | ||||||
| /******************************************************************************* | /******************************************************************************* | ||||||
| @@ -285,7 +285,7 @@ tBTA_JV_RFC_CB *bta_jv_rfc_port_to_cb(UINT16 port_handle) | |||||||
|     return p_cb; |     return p_cb; | ||||||
| } | } | ||||||
|  |  | ||||||
| static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pcb) | static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pcb, BOOLEAN close_server) | ||||||
| { | { | ||||||
|     tBTA_JV_STATUS status = BTA_JV_SUCCESS; |     tBTA_JV_STATUS status = BTA_JV_SUCCESS; | ||||||
|     BOOLEAN remove_server = FALSE; |     BOOLEAN remove_server = FALSE; | ||||||
| @@ -295,7 +295,7 @@ static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pc | |||||||
|     tPORT_STATE port_state; |     tPORT_STATE port_state; | ||||||
|     UINT32 event_mask = BTA_JV_RFC_EV_MASK; |     UINT32 event_mask = BTA_JV_RFC_EV_MASK; | ||||||
|     UINT32 scn_num = (UINT32)p_cb->scn; |     UINT32 scn_num = (UINT32)p_cb->scn; | ||||||
|     tBTA_JV evt_data; |     tBTA_JV evt_data = {0}; | ||||||
|  |  | ||||||
|     if (!p_cb || !p_pcb) { |     if (!p_cb || !p_pcb) { | ||||||
|         APPL_TRACE_ERROR("bta_jv_free_sr_rfc_cb, p_cb or p_pcb cannot be null"); |         APPL_TRACE_ERROR("bta_jv_free_sr_rfc_cb, p_cb or p_pcb cannot be null"); | ||||||
| @@ -373,10 +373,8 @@ static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pc | |||||||
|         p_pcb->handle = 0; |         p_pcb->handle = 0; | ||||||
|         p_cb->curr_sess--; |         p_cb->curr_sess--; | ||||||
|  |  | ||||||
|         if ((p_cb->max_sess > 1) && |         /* only needs a listening port when has a server */ | ||||||
|             (p_cb->scn != 0) && |         if (!close_server && (p_cb->max_sess > 1) && (p_cb->scn != 0)) { | ||||||
|             (p_cb->curr_sess == p_cb->max_sess - 1)) { |  | ||||||
|  |  | ||||||
|             for (i = 0; i < p_cb->max_sess; i++) { |             for (i = 0; i < p_cb->max_sess; i++) { | ||||||
|                 if (p_cb->rfc_hdl[i] != 0) { |                 if (p_cb->rfc_hdl[i] != 0) { | ||||||
|                     p_pcb = &bta_jv_cb.port_cb[p_cb->rfc_hdl[i] - 1]; |                     p_pcb = &bta_jv_cb.port_cb[p_cb->rfc_hdl[i] - 1]; | ||||||
| @@ -386,8 +384,8 @@ static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pc | |||||||
|                     used++; |                     used++; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             APPL_TRACE_DEBUG("%s max_sess=%d used:%d curr_sess:%d, listen:%d si:%d", |             APPL_TRACE_DEBUG("%s max_sess=%d used:%d curr_sess:%d, listen:%d si:%d", __func__, p_cb->max_sess, used, | ||||||
|                              __func__, p_cb->max_sess, used, p_cb->curr_sess, listen, si); |                              p_cb->curr_sess, listen, si); | ||||||
|             if (used < p_cb->max_sess && |             if (used < p_cb->max_sess && | ||||||
|                 listen == 0 && |                 listen == 0 && | ||||||
|                 0 <= si && |                 0 <= si && | ||||||
| @@ -430,9 +428,6 @@ static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pc | |||||||
|             p_cb->handle = 0; |             p_cb->handle = 0; | ||||||
|             p_cb->curr_sess = -1; |             p_cb->curr_sess = -1; | ||||||
|         } |         } | ||||||
|         if (remove_server) { |  | ||||||
|             bta_jv_free_sec_id(&p_cb->sec_id); |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|     return status; |     return status; | ||||||
| } | } | ||||||
| @@ -1205,7 +1200,7 @@ void bta_jv_delete_record(tBTA_JV_MSG *p_data) | |||||||
| static void bta_jv_l2cap_client_cback(UINT16 gap_handle, UINT16 event) | static void bta_jv_l2cap_client_cback(UINT16 gap_handle, UINT16 event) | ||||||
| { | { | ||||||
|     tBTA_JV_L2C_CB  *p_cb = &bta_jv_cb.l2c_cb[gap_handle]; |     tBTA_JV_L2C_CB  *p_cb = &bta_jv_cb.l2c_cb[gap_handle]; | ||||||
|     tBTA_JV     evt_data; |     tBTA_JV evt_data = {0}; | ||||||
|  |  | ||||||
|     if (gap_handle >= BTA_JV_MAX_L2C_CONN && !p_cb->p_cback) { |     if (gap_handle >= BTA_JV_MAX_L2C_CONN && !p_cb->p_cback) { | ||||||
|         return; |         return; | ||||||
| @@ -1360,7 +1355,7 @@ void bta_jv_l2cap_close(tBTA_JV_MSG *p_data) | |||||||
| static void bta_jv_l2cap_server_cback(UINT16 gap_handle, UINT16 event) | static void bta_jv_l2cap_server_cback(UINT16 gap_handle, UINT16 event) | ||||||
| { | { | ||||||
|     tBTA_JV_L2C_CB  *p_cb = &bta_jv_cb.l2c_cb[gap_handle]; |     tBTA_JV_L2C_CB  *p_cb = &bta_jv_cb.l2c_cb[gap_handle]; | ||||||
|     tBTA_JV evt_data; |     tBTA_JV evt_data = {0}; | ||||||
|     tBTA_JV_L2CAP_CBACK *p_cback; |     tBTA_JV_L2CAP_CBACK *p_cback; | ||||||
|     void *user_data; |     void *user_data; | ||||||
|  |  | ||||||
| @@ -1666,11 +1661,11 @@ static int bta_jv_port_data_co_cback(UINT16 port_handle, UINT8 *buf, UINT16 len, | |||||||
| ** Returns      void | ** Returns      void | ||||||
| ** | ** | ||||||
| *******************************************************************************/ | *******************************************************************************/ | ||||||
| static void bta_jv_port_mgmt_cl_cback(UINT32 code, UINT16 port_handle) | static void bta_jv_port_mgmt_cl_cback(UINT32 code, UINT16 port_handle, void* data) | ||||||
| { | { | ||||||
|     tBTA_JV_RFC_CB  *p_cb = bta_jv_rfc_port_to_cb(port_handle); |     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_PCB     *p_pcb = bta_jv_rfc_port_to_pcb(port_handle); | ||||||
|     tBTA_JV evt_data; |     tBTA_JV evt_data = {0}; | ||||||
|     BD_ADDR rem_bda; |     BD_ADDR rem_bda; | ||||||
|     UINT16 lcid; |     UINT16 lcid; | ||||||
|     tBTA_JV_RFCOMM_CBACK *p_cback;  /* the callback function */ |     tBTA_JV_RFCOMM_CBACK *p_cback;  /* the callback function */ | ||||||
| @@ -1722,7 +1717,7 @@ static void bta_jv_port_event_cl_cback(UINT32 code, UINT16 port_handle) | |||||||
| { | { | ||||||
|     tBTA_JV_RFC_CB  *p_cb = bta_jv_rfc_port_to_cb(port_handle); |     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_PCB     *p_pcb = bta_jv_rfc_port_to_pcb(port_handle); | ||||||
|     tBTA_JV evt_data; |     tBTA_JV evt_data = {0}; | ||||||
|  |  | ||||||
|     APPL_TRACE_DEBUG( "bta_jv_port_event_cl_cback:%d", port_handle); |     APPL_TRACE_DEBUG( "bta_jv_port_event_cl_cback:%d", port_handle); | ||||||
|     if (NULL == p_cb || NULL == p_cb->p_cback) { |     if (NULL == p_cb || NULL == p_cb->p_cback) { | ||||||
| @@ -1863,7 +1858,7 @@ void bta_jv_rfcomm_close(tBTA_JV_MSG *p_data) | |||||||
|     tBTA_JV_API_RFCOMM_CLOSE *cc = &(p_data->rfcomm_close); |     tBTA_JV_API_RFCOMM_CLOSE *cc = &(p_data->rfcomm_close); | ||||||
|     tBTA_JV_RFC_CB           *p_cb = NULL; |     tBTA_JV_RFC_CB           *p_cb = NULL; | ||||||
|     tBTA_JV_PCB              *p_pcb = NULL; |     tBTA_JV_PCB              *p_pcb = NULL; | ||||||
|     tBTA_JV                   evt_data; |     tBTA_JV                  evt_data = {0}; | ||||||
|     APPL_TRACE_DEBUG("%s, rfc handle:%d",__func__, cc->handle); |     APPL_TRACE_DEBUG("%s, rfc handle:%d",__func__, cc->handle); | ||||||
|     if (!cc->handle) { |     if (!cc->handle) { | ||||||
|         APPL_TRACE_ERROR("%s, rfc handle is null", __func__); |         APPL_TRACE_ERROR("%s, rfc handle is null", __func__); | ||||||
| @@ -1887,7 +1882,7 @@ void bta_jv_rfcomm_close(tBTA_JV_MSG *p_data) | |||||||
|         } |         } | ||||||
|         cc->p_cback(BTA_JV_RFCOMM_CLOSE_EVT, (tBTA_JV *)&evt_data, user_data); |         cc->p_cback(BTA_JV_RFCOMM_CLOSE_EVT, (tBTA_JV *)&evt_data, user_data); | ||||||
|     } |     } | ||||||
|     bta_jv_free_rfc_cb(p_cb, p_pcb); |     bta_jv_free_rfc_cb(p_cb, p_pcb, FALSE); | ||||||
|     APPL_TRACE_DEBUG("%s: sec id in use:%d, rfc_cb in use:%d",__func__, |     APPL_TRACE_DEBUG("%s: sec id in use:%d, rfc_cb in use:%d",__func__, | ||||||
|                      get_sec_id_used(), get_rfc_cb_used()); |                      get_sec_id_used(), get_rfc_cb_used()); | ||||||
| } | } | ||||||
| @@ -1930,39 +1925,80 @@ static UINT8 __attribute__((unused)) bta_jv_get_num_rfc_listen(tBTA_JV_RFC_CB *p | |||||||
| ** Returns      void | ** Returns      void | ||||||
| ** | ** | ||||||
| *******************************************************************************/ | *******************************************************************************/ | ||||||
| static void bta_jv_port_mgmt_sr_cback(UINT32 code, UINT16 port_handle) | static void bta_jv_port_mgmt_sr_cback(UINT32 code, UINT16 port_handle, void *data) | ||||||
| { | { | ||||||
|     tBTA_JV_PCB     *p_pcb = bta_jv_rfc_port_to_pcb(port_handle); |     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_RFC_CB  *p_cb = bta_jv_rfc_port_to_cb(port_handle); | ||||||
|     tBTA_JV evt_data; |     tBTA_JV evt_data = {0}; | ||||||
|     BD_ADDR rem_bda; |     BD_ADDR rem_bda; | ||||||
|     UINT16 lcid; |     UINT16 lcid; | ||||||
|  |     BOOLEAN *accept = (BOOLEAN *)data; | ||||||
|  |     void *user_data = NULL; | ||||||
|  |     void *new_user_data = NULL; | ||||||
|  |  | ||||||
|     // APPL_TRACE_DEBUG("bta_jv_port_mgmt_sr_cback, code:0x%x, port_handle:%d", code, (uint16_t)port_handle); |     // 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) { |     if (NULL == p_cb || NULL == p_cb->p_cback) { | ||||||
|         // APPL_TRACE_ERROR("bta_jv_port_mgmt_sr_cback, p_cb:%p, p_cb->p_cback%p", |         // APPL_TRACE_ERROR("bta_jv_port_mgmt_sr_cback, p_cb:%p, p_cb->p_cback%p", | ||||||
|         // p_cb, p_cb ? p_cb->p_cback : NULL); |         // p_cb, p_cb ? p_cb->p_cback : NULL); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     void *user_data = p_pcb->user_data; |     user_data = p_pcb->user_data; | ||||||
|     // APPL_TRACE_DEBUG( "bta_jv_port_mgmt_sr_cback code=%p port_handle:0x%x handle:0x%x, p_pcb:%p, user:%p", |     // 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); |     // code, port_handle, p_cb->handle, p_pcb, p_pcb->user_data); | ||||||
|  |  | ||||||
|     PORT_CheckConnection(port_handle, rem_bda, &lcid); |     PORT_CheckConnection(port_handle, rem_bda, &lcid); | ||||||
|     int failed = TRUE; |     int failed = TRUE; | ||||||
|     if (code == PORT_SUCCESS) { |     if (code == PORT_SUCCESS) { | ||||||
|  |         failed = FALSE; | ||||||
|  |         /* accept the connection defaulted */ | ||||||
|  |         if (accept) { | ||||||
|  |             *accept = TRUE; | ||||||
|  |         } | ||||||
|         evt_data.rfc_srv_open.handle = p_pcb->handle; |         evt_data.rfc_srv_open.handle = p_pcb->handle; | ||||||
|         evt_data.rfc_srv_open.status = BTA_JV_SUCCESS; |         evt_data.rfc_srv_open.status = BTA_JV_SUCCESS; | ||||||
|         bdcpy(evt_data.rfc_srv_open.rem_bda, rem_bda); |         bdcpy(evt_data.rfc_srv_open.rem_bda, rem_bda); | ||||||
|         tBTA_JV_PCB *p_pcb_new_listen  = bta_jv_add_rfc_port(p_cb, p_pcb); |         tBTA_JV_PCB *p_pcb_new_listen  = bta_jv_add_rfc_port(p_cb, p_pcb); | ||||||
|         if (p_pcb_new_listen) { |         if (p_pcb_new_listen) { | ||||||
|             evt_data.rfc_srv_open.new_listen_handle = p_pcb_new_listen->handle; |             evt_data.rfc_srv_open.new_listen_handle = p_pcb_new_listen->handle; | ||||||
|             p_pcb_new_listen->user_data = p_cb->p_cback(BTA_JV_RFCOMM_SRV_OPEN_EVT, &evt_data, user_data); |             new_user_data = p_cb->p_cback(BTA_JV_RFCOMM_SRV_OPEN_EVT, &evt_data, user_data); | ||||||
|             APPL_TRACE_DEBUG("PORT_SUCCESS: curr_sess:%d, max_sess:%d", p_cb->curr_sess, p_cb->max_sess); |             if (new_user_data) { | ||||||
|             failed = FALSE; |                 p_pcb_new_listen->user_data = new_user_data; | ||||||
|  |                 APPL_TRACE_DEBUG("PORT_SUCCESS: curr_sess:%d, max_sess:%d", p_cb->curr_sess, | ||||||
|  |                                  p_cb->max_sess); | ||||||
|             } else { |             } else { | ||||||
|  |                 /** | ||||||
|  |                  * new_user_data is NULL, which means the upper layer runs out of slot source. | ||||||
|  |                  * Tells the caller to reject this connection. | ||||||
|  |                  */ | ||||||
|  |                 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); | ||||||
|  |                 if (accept) { | ||||||
|  |                     *accept = FALSE; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             evt_data.rfc_srv_open.new_listen_handle = 0; | ||||||
|  |             new_user_data = p_cb->p_cback(BTA_JV_RFCOMM_SRV_OPEN_EVT, &evt_data, user_data); | ||||||
|  |             if (new_user_data) { | ||||||
|  |                 APPL_TRACE_DEBUG("PORT_SUCCESS: curr_sess:%d, max_sess:%d", p_cb->curr_sess, | ||||||
|  |                                  p_cb->max_sess); | ||||||
|  |             } else { | ||||||
|  |                 /** | ||||||
|  |                  * new_user_data is NULL, which means the upper layer runs out of slot source. | ||||||
|  |                  * Tells the caller to reject this connection. | ||||||
|  |                  */ | ||||||
|  |                 APPL_TRACE_ERROR("no listen port, and upper layer reject connection"); | ||||||
|  |                 p_pcb->state = BTA_JV_ST_SR_LISTEN; | ||||||
|  |                 if (accept) { | ||||||
|  |                     *accept = FALSE; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|             APPL_TRACE_ERROR("bta_jv_add_rfc_port failed to create new listen port"); |             APPL_TRACE_ERROR("bta_jv_add_rfc_port failed to create new listen port"); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (failed) { |     if (failed) { | ||||||
|         evt_data.rfc_close.handle = p_pcb->handle; |         evt_data.rfc_close.handle = p_pcb->handle; | ||||||
|         evt_data.rfc_close.status = BTA_JV_FAILURE; |         evt_data.rfc_close.status = BTA_JV_FAILURE; | ||||||
| @@ -1999,7 +2035,7 @@ static void bta_jv_port_event_sr_cback(UINT32 code, UINT16 port_handle) | |||||||
| { | { | ||||||
|     tBTA_JV_PCB     *p_pcb = bta_jv_rfc_port_to_pcb(port_handle); |     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_RFC_CB  *p_cb = bta_jv_rfc_port_to_cb(port_handle); | ||||||
|     tBTA_JV evt_data; |     tBTA_JV evt_data = {0}; | ||||||
|  |  | ||||||
|     if (NULL == p_cb || NULL == p_cb->p_cback) { |     if (NULL == p_cb || NULL == p_cb->p_cback) { | ||||||
|         return; |         return; | ||||||
| @@ -2067,6 +2103,7 @@ static tBTA_JV_PCB *bta_jv_add_rfc_port(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pcb | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         p_pcb = NULL; | ||||||
|         APPL_TRACE_DEBUG("bta_jv_add_rfc_port max_sess=%d used:%d curr_sess:%d, listen:%d si:%d", |         APPL_TRACE_DEBUG("bta_jv_add_rfc_port max_sess=%d used:%d curr_sess:%d, listen:%d si:%d", | ||||||
|                          p_cb->max_sess, used, p_cb->curr_sess, listen, si); |                          p_cb->max_sess, used, p_cb->curr_sess, listen, si); | ||||||
|         if (used < p_cb->max_sess && listen == 1 && si) { |         if (used < p_cb->max_sess && listen == 1 && si) { | ||||||
| @@ -2094,7 +2131,6 @@ static tBTA_JV_PCB *bta_jv_add_rfc_port(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pcb | |||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             /* avoid p_pcb always points to the last element of rfc_hdl */ |             /* avoid p_pcb always points to the last element of rfc_hdl */ | ||||||
|             p_pcb = p_pcb_open; |  | ||||||
|             APPL_TRACE_ERROR("bta_jv_add_rfc_port, cannot create new rfc listen port"); |             APPL_TRACE_ERROR("bta_jv_add_rfc_port, cannot create new rfc listen port"); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -2214,7 +2250,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", |     APPL_TRACE_DEBUG("bta_jv_rfcomm_stop_server: p_pcb:%p, p_pcb->port_handle:%d", | ||||||
|                      p_pcb, p_pcb->port_handle); |                      p_pcb, p_pcb->port_handle); | ||||||
|     bta_jv_free_rfc_cb(p_cb, p_pcb); |     bta_jv_free_rfc_cb(p_cb, p_pcb, TRUE); | ||||||
|     APPL_TRACE_DEBUG("bta_jv_rfcomm_stop_server: sec id in use:%d, rfc_cb in use:%d", |     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()); |                      get_sec_id_used(), get_rfc_cb_used()); | ||||||
| } | } | ||||||
| @@ -2750,7 +2786,7 @@ static void fcchan_conn_chng_cbk(UINT16 chan, BD_ADDR bd_addr, BOOLEAN connected | |||||||
|  |  | ||||||
| static void fcchan_data_cbk(UINT16 chan, BD_ADDR bd_addr, BT_HDR *p_buf) | static void fcchan_data_cbk(UINT16 chan, BD_ADDR bd_addr, BT_HDR *p_buf) | ||||||
| { | { | ||||||
|     tBTA_JV evt_data; |     tBTA_JV evt_data = {0}; | ||||||
|     // tBTA_JV evt_open; |     // tBTA_JV evt_open; | ||||||
|     struct fc_channel *tc; |     struct fc_channel *tc; | ||||||
|     struct fc_client *t = NULL; |     struct fc_client *t = NULL; | ||||||
|   | |||||||
| @@ -1,16 +1,8 @@ | |||||||
| // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD | /* | ||||||
| // |  * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD | ||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); |  * | ||||||
| // you may not use this file except in compliance with the License. |  * SPDX-License-Identifier: Apache-2.0 | ||||||
| // You may obtain a copy of the License at |  */ | ||||||
|  |  | ||||||
| //     http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
| // |  | ||||||
| // Unless required by applicable law or agreed to in writing, software |  | ||||||
| // distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
| // See the License for the specific language governing permissions and |  | ||||||
| // limitations under the License. |  | ||||||
|  |  | ||||||
| #include <string.h> | #include <string.h> | ||||||
|  |  | ||||||
| @@ -55,8 +47,9 @@ typedef struct { | |||||||
| } slot_data_t; | } slot_data_t; | ||||||
|  |  | ||||||
| typedef struct { | typedef struct { | ||||||
|     uint8_t serial; |  | ||||||
|     bool connected; |     bool connected; | ||||||
|  |     bool is_server; | ||||||
|  |     uint8_t serial; | ||||||
|     uint8_t scn; |     uint8_t scn; | ||||||
|     uint8_t max_session; |     uint8_t max_session; | ||||||
|     uint32_t id; |     uint32_t id; | ||||||
| @@ -137,29 +130,39 @@ static spp_slot_t *spp_malloc_slot(void) | |||||||
|             (*slot)->sdp_handle = 0; |             (*slot)->sdp_handle = 0; | ||||||
|             (*slot)->rfc_handle = 0; |             (*slot)->rfc_handle = 0; | ||||||
|             (*slot)->rfc_port_handle = 0; |             (*slot)->rfc_port_handle = 0; | ||||||
|             (*slot)->connected = FALSE; |             (*slot)->fd = -1; | ||||||
|  |             (*slot)->connected = false; | ||||||
|  |             (*slot)->is_server = false; | ||||||
|             (*slot)->write_data = NULL; |             (*slot)->write_data = NULL; | ||||||
|             (*slot)->close_alarm = NULL; |             (*slot)->close_alarm = NULL; | ||||||
|  |             /* clear the old event bits */ | ||||||
|  |             if (spp_local_param.tx_event_group) { | ||||||
|  |                 xEventGroupClearBits(spp_local_param.tx_event_group, SLOT_WRITE_BIT(i) | SLOT_CLOSE_BIT(i)); | ||||||
|  |             } | ||||||
|  |  | ||||||
|             if (init_slot_data(&(*slot)->rx, QUEUE_SIZE_MAX)) { |             if (init_slot_data(&(*slot)->rx, QUEUE_SIZE_MAX)) { | ||||||
|                 BTC_TRACE_ERROR("%s unable to malloc rx queue!", __func__); |                 BTC_TRACE_ERROR("%s unable to malloc rx queue!", __func__); | ||||||
|                 err_no = 1; |                 err_no = 1; | ||||||
|                 break; |                 goto err; | ||||||
|             } |             } | ||||||
|             if (init_slot_data(&(*slot)->tx, SLOT_TX_QUEUE_SIZE)) { |             if (init_slot_data(&(*slot)->tx, SLOT_TX_QUEUE_SIZE)) { | ||||||
|                 BTC_TRACE_ERROR("%s unable to malloc tx queue!", __func__); |                 BTC_TRACE_ERROR("%s unable to malloc tx queue!", __func__); | ||||||
|                 err_no = 2; |                 err_no = 2; | ||||||
|                 break; |                 goto err; | ||||||
|             } |             } | ||||||
|             if (spp_local_param.spp_mode == ESP_SPP_MODE_VFS) { |             if (spp_local_param.spp_mode == ESP_SPP_MODE_VFS) { | ||||||
|                 if (esp_vfs_register_fd(spp_local_param.spp_vfs_id, &(*slot)->fd) != ESP_OK) { |                 if (esp_vfs_register_fd(spp_local_param.spp_vfs_id, &(*slot)->fd) != ESP_OK) { | ||||||
|                     BTC_TRACE_ERROR("%s unable to register fd!", __func__); |                     BTC_TRACE_ERROR("%s unable to register fd!", __func__); | ||||||
|                     err_no = 3; |                     err_no = 3; | ||||||
|                     break; |                     goto err; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             return (*slot); |             return (*slot); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     return NULL; | ||||||
|  | err: | ||||||
|     switch (err_no) { |     switch (err_no) { | ||||||
|         case 3: |         case 3: | ||||||
|             free_slot_data(&(*slot)->tx); |             free_slot_data(&(*slot)->tx); | ||||||
| @@ -177,9 +180,11 @@ static spp_slot_t *spp_malloc_slot(void) | |||||||
|  |  | ||||||
| static spp_slot_t *spp_find_slot_by_id(uint32_t id) | static spp_slot_t *spp_find_slot_by_id(uint32_t id) | ||||||
| { | { | ||||||
|  |     spp_slot_t *slot = NULL; | ||||||
|     for (size_t i = 1; i <= MAX_RFC_PORTS; i++) { |     for (size_t i = 1; i <= MAX_RFC_PORTS; i++) { | ||||||
|         if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->id == id) { |         slot = spp_local_param.spp_slots[i]; | ||||||
|             return spp_local_param.spp_slots[i]; |         if (slot != NULL && slot->id == id) { | ||||||
|  |             return slot; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     return NULL; |     return NULL; | ||||||
| @@ -187,9 +192,11 @@ static spp_slot_t *spp_find_slot_by_id(uint32_t id) | |||||||
|  |  | ||||||
| static spp_slot_t *spp_find_slot_by_handle(uint32_t handle) | static spp_slot_t *spp_find_slot_by_handle(uint32_t handle) | ||||||
| { | { | ||||||
|  |     spp_slot_t *slot = NULL; | ||||||
|     for (size_t i = 1; i <= MAX_RFC_PORTS; i++) { |     for (size_t i = 1; i <= MAX_RFC_PORTS; i++) { | ||||||
|         if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->rfc_handle == handle) { |         slot = spp_local_param.spp_slots[i]; | ||||||
|             return spp_local_param.spp_slots[i]; |         if (slot != NULL && slot->rfc_handle == handle) { | ||||||
|  |             return slot; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     return NULL; |     return NULL; | ||||||
| @@ -197,9 +204,11 @@ static spp_slot_t *spp_find_slot_by_handle(uint32_t handle) | |||||||
|  |  | ||||||
| static spp_slot_t *spp_find_slot_by_fd(int fd) | static spp_slot_t *spp_find_slot_by_fd(int fd) | ||||||
| { | { | ||||||
|  |     spp_slot_t *slot = NULL; | ||||||
|     for (size_t i = 1; i <= MAX_RFC_PORTS; i++) { |     for (size_t i = 1; i <= MAX_RFC_PORTS; i++) { | ||||||
|         if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->fd == fd) { |         slot = spp_local_param.spp_slots[i]; | ||||||
|             return spp_local_param.spp_slots[i]; |         if (slot != NULL && slot->fd == fd) { | ||||||
|  |             return slot; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     return NULL; |     return NULL; | ||||||
| @@ -207,9 +216,11 @@ static spp_slot_t *spp_find_slot_by_fd(int fd) | |||||||
|  |  | ||||||
| static spp_slot_t *spp_find_slot_by_scn(uint32_t scn) | static spp_slot_t *spp_find_slot_by_scn(uint32_t scn) | ||||||
| { | { | ||||||
|  |     spp_slot_t *slot = NULL; | ||||||
|     for (size_t i = 1; i <= MAX_RFC_PORTS; i++) { |     for (size_t i = 1; i <= MAX_RFC_PORTS; i++) { | ||||||
|         if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->scn == (uint8_t)scn) { |         slot = spp_local_param.spp_slots[i]; | ||||||
|             return spp_local_param.spp_slots[i]; |         if (slot != NULL && slot->is_server && slot->scn == (uint8_t)scn) { | ||||||
|  |             return slot; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     return NULL; |     return NULL; | ||||||
| @@ -277,9 +288,9 @@ static void *btc_spp_rfcomm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *u | |||||||
|     bt_status_t status; |     bt_status_t status; | ||||||
|     btc_msg_t msg; |     btc_msg_t msg; | ||||||
|     void *new_user_data = NULL; |     void *new_user_data = NULL; | ||||||
|  |     uint32_t id = (uintptr_t)user_data, id_temp = 0; | ||||||
|     uint32_t id = (uintptr_t)user_data; |  | ||||||
|     spp_slot_t *slot = NULL, *slot_new = NULL; |     spp_slot_t *slot = NULL, *slot_new = NULL; | ||||||
|  |  | ||||||
|     if (!is_spp_init()) { |     if (!is_spp_init()) { | ||||||
|         BTC_TRACE_WARNING("%s SPP have been deinit, incoming events ignore!\n", __func__); |         BTC_TRACE_WARNING("%s SPP have been deinit, incoming events ignore!\n", __func__); | ||||||
|         return new_user_data; |         return new_user_data; | ||||||
| @@ -289,7 +300,7 @@ static void *btc_spp_rfcomm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *u | |||||||
|     case BTA_JV_RFCOMM_START_EVT: |     case BTA_JV_RFCOMM_START_EVT: | ||||||
|         slot = spp_find_slot_by_id(id); |         slot = spp_find_slot_by_id(id); | ||||||
|         if (!slot) { |         if (!slot) { | ||||||
|             BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); |             BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); | ||||||
|             p_data->rfc_start.status = ESP_SPP_NO_CONNECTION; |             p_data->rfc_start.status = ESP_SPP_NO_CONNECTION; | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
| @@ -299,42 +310,52 @@ static void *btc_spp_rfcomm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *u | |||||||
|     case BTA_JV_RFCOMM_SRV_OPEN_EVT: |     case BTA_JV_RFCOMM_SRV_OPEN_EVT: | ||||||
|         slot = p_data->rfc_srv_open.handle ? spp_find_slot_by_id(id) : spp_find_slot_by_scn((uint32_t)user_data); |         slot = p_data->rfc_srv_open.handle ? spp_find_slot_by_id(id) : spp_find_slot_by_scn((uint32_t)user_data); | ||||||
|         if (!slot) { |         if (!slot) { | ||||||
|             BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); |             BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); | ||||||
|             p_data->rfc_srv_open.status = ESP_SPP_NO_CONNECTION; |             p_data->rfc_srv_open.status = ESP_SPP_NO_CONNECTION; | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (p_data->rfc_srv_open.handle) { |         if (!p_data->rfc_srv_open.handle) { | ||||||
|             new_user_data = (void *)(uintptr_t)slot->id; |             /* match with the exist server solt */ | ||||||
|             memcpy(slot->addr, p_data->rfc_srv_open.rem_bda, ESP_BD_ADDR_LEN); |             slot->rfc_handle = p_data->rfc_srv_open.new_listen_handle; | ||||||
|             slot->connected = TRUE; |             slot->rfc_port_handle = BTA_JvRfcommGetPortHdl(slot->rfc_handle); | ||||||
|             slot->rfc_handle = p_data->rfc_srv_open.handle; |         } else { | ||||||
|             slot->rfc_port_handle = BTA_JvRfcommGetPortHdl(p_data->rfc_srv_open.handle); |  | ||||||
|             BTA_JvSetPmProfile(p_data->rfc_srv_open.handle, BTA_JV_PM_ALL, BTA_JV_CONN_OPEN); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (p_data->rfc_srv_open.handle != p_data->rfc_srv_open.new_listen_handle) { |  | ||||||
|             slot_new = spp_malloc_slot(); |             slot_new = spp_malloc_slot(); | ||||||
|             if (!slot_new) { |             if (!slot_new) { | ||||||
|                 BTC_TRACE_ERROR("%s unable to malloc RFCOMM slot!", __func__); |                 BTC_TRACE_ERROR("%s unable to malloc RFCOMM slot!", __func__); | ||||||
|                 p_data->rfc_srv_open.status = ESP_SPP_NO_RESOURCE; |                 p_data->rfc_srv_open.status = ESP_SPP_NO_RESOURCE; | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|             new_user_data = (void *)(uintptr_t)slot_new->id; |             slot_new->connected = true; | ||||||
|             slot_new->security = slot->security; |             slot_new->security = slot->security; | ||||||
|             slot_new->role = slot->role; |             slot_new->role = slot->role; | ||||||
|             slot_new->scn = slot->scn; |             slot_new->scn = slot->scn; | ||||||
|             slot_new->max_session = slot->max_session; |             slot_new->max_session = slot->max_session; | ||||||
|             strcpy(slot_new->service_name, slot->service_name); |             strcpy(slot_new->service_name, slot->service_name); | ||||||
|             slot_new->sdp_handle = slot->sdp_handle; |             slot_new->sdp_handle = slot->sdp_handle; | ||||||
|             slot_new->rfc_handle = p_data->rfc_srv_open.new_listen_handle; |             slot_new->rfc_handle = p_data->rfc_srv_open.handle; | ||||||
|             slot_new->rfc_port_handle = BTA_JvRfcommGetPortHdl(p_data->rfc_srv_open.new_listen_handle); |             slot_new->rfc_port_handle = BTA_JvRfcommGetPortHdl(slot_new->rfc_handle); | ||||||
|  |             BTA_JvSetPmProfile(p_data->rfc_srv_open.handle, BTA_JV_PM_ALL, BTA_JV_CONN_OPEN); | ||||||
|  |  | ||||||
|  |             if (p_data->rfc_srv_open.new_listen_handle) { | ||||||
|  |                 slot->rfc_handle = p_data->rfc_srv_open.new_listen_handle; | ||||||
|  |                 slot->rfc_port_handle = BTA_JvRfcommGetPortHdl(slot->rfc_handle); | ||||||
|  |             } else { | ||||||
|  |                 /* means lower layer can alloc port */ | ||||||
|  |                 slot->rfc_handle = 0; | ||||||
|  |                 slot->rfc_port_handle = 0; | ||||||
|             } |             } | ||||||
|  |             /* swap slot id */ | ||||||
|  |             id_temp = slot->id; | ||||||
|  |             slot->id = slot_new->id; | ||||||
|  |             slot_new->id = id_temp; | ||||||
|  |         } | ||||||
|  |         new_user_data = (void *)(uintptr_t)slot->id; | ||||||
|         break; |         break; | ||||||
|     case BTA_JV_RFCOMM_OPEN_EVT: |     case BTA_JV_RFCOMM_OPEN_EVT: | ||||||
|         slot = spp_find_slot_by_id(id); |         slot = spp_find_slot_by_id(id); | ||||||
|         if (!slot) { |         if (!slot) { | ||||||
|             BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); |             BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); | ||||||
|             p_data->rfc_open.status = ESP_SPP_NO_CONNECTION; |             p_data->rfc_open.status = ESP_SPP_NO_CONNECTION; | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
| @@ -346,7 +367,7 @@ static void *btc_spp_rfcomm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *u | |||||||
|     case BTA_JV_RFCOMM_CLOSE_EVT: |     case BTA_JV_RFCOMM_CLOSE_EVT: | ||||||
|         slot = spp_find_slot_by_id(id); |         slot = spp_find_slot_by_id(id); | ||||||
|         if (!slot) { |         if (!slot) { | ||||||
|             BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); |             BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); | ||||||
|             p_data->rfc_close.status = ESP_SPP_NO_CONNECTION; |             p_data->rfc_close.status = ESP_SPP_NO_CONNECTION; | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
| @@ -354,6 +375,7 @@ static void *btc_spp_rfcomm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *u | |||||||
|             BTA_JvRfcommClose(slot->rfc_handle, NULL, (void *)slot->id); |             BTA_JvRfcommClose(slot->rfc_handle, NULL, (void *)slot->id); | ||||||
|         } |         } | ||||||
|         p_data->rfc_close.status = BTA_JV_SUCCESS; |         p_data->rfc_close.status = BTA_JV_SUCCESS; | ||||||
|  |         p_data->rfc_close.user_data = (void *)(uintptr_t)slot->id; | ||||||
|         break; |         break; | ||||||
|     case BTA_JV_RFCOMM_DATA_IND_EVT: |     case BTA_JV_RFCOMM_DATA_IND_EVT: | ||||||
|         break; |         break; | ||||||
| @@ -364,7 +386,7 @@ static void *btc_spp_rfcomm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *u | |||||||
|             if (slot) { |             if (slot) { | ||||||
|                 spp_free_slot(slot); |                 spp_free_slot(slot); | ||||||
|             } else { |             } else { | ||||||
|                 BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); |                 BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); | ||||||
|                 p_data->free_scn.status = ESP_SPP_NO_CONNECTION; |                 p_data->free_scn.status = ESP_SPP_NO_CONNECTION; | ||||||
|             } |             } | ||||||
|             osi_free(user_data); |             osi_free(user_data); | ||||||
| @@ -401,7 +423,7 @@ static void btc_spp_dm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_d | |||||||
|         slot = spp_find_slot_by_id(id); |         slot = spp_find_slot_by_id(id); | ||||||
|         if (!slot) { |         if (!slot) { | ||||||
|             osi_mutex_unlock(&spp_local_param.spp_slot_mutex); |             osi_mutex_unlock(&spp_local_param.spp_slot_mutex); | ||||||
|             BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); |             BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|         if (p_data->scn == 0) { |         if (p_data->scn == 0) { | ||||||
| @@ -421,7 +443,7 @@ static void btc_spp_dm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_d | |||||||
|         slot = spp_find_slot_by_id(id); |         slot = spp_find_slot_by_id(id); | ||||||
|         if (!slot) { |         if (!slot) { | ||||||
|             osi_mutex_unlock(&spp_local_param.spp_slot_mutex); |             osi_mutex_unlock(&spp_local_param.spp_slot_mutex); | ||||||
|             BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); |             BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|         if (p_data->create_rec.status == BTA_JV_SUCCESS) { |         if (p_data->create_rec.status == BTA_JV_SUCCESS) { | ||||||
| @@ -510,14 +532,14 @@ static void btc_spp_uninit(void) | |||||||
|         osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT); |         osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT); | ||||||
|         // first, remove all connection |         // first, remove all connection | ||||||
|         for (size_t i = 1; i <= MAX_RFC_PORTS; i++) { |         for (size_t i = 1; i <= MAX_RFC_PORTS; i++) { | ||||||
|             if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->connected) { |             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, |                 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); |                                   (void *)spp_local_param.spp_slots[i]->id); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         // second, remove all server |         // second, remove all server | ||||||
|         for (size_t i = 1; i <= MAX_RFC_PORTS; i++) { |         for (size_t i = 1; i <= MAX_RFC_PORTS; i++) { | ||||||
|             if (spp_local_param.spp_slots[i] != NULL && !spp_local_param.spp_slots[i]->connected) { |             if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->is_server) { | ||||||
|                 if (spp_local_param.spp_slots[i]->sdp_handle > 0) { |                 if (spp_local_param.spp_slots[i]->sdp_handle > 0) { | ||||||
|                     BTA_JvDeleteRecord(spp_local_param.spp_slots[i]->sdp_handle); |                     BTA_JvDeleteRecord(spp_local_param.spp_slots[i]->sdp_handle); | ||||||
|                 } |                 } | ||||||
| @@ -669,6 +691,10 @@ static void btc_spp_start_srv(btc_spp_args_t *arg) | |||||||
|             ret = ESP_SPP_NO_RESOURCE; |             ret = ESP_SPP_NO_RESOURCE; | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|  |         /** | ||||||
|  |          * make this slot become a listening slot | ||||||
|  |          */ | ||||||
|  |         slot->is_server = true; | ||||||
|         slot->security = arg->start_srv.sec_mask; |         slot->security = arg->start_srv.sec_mask; | ||||||
|         slot->role = arg->start_srv.role; |         slot->role = arg->start_srv.role; | ||||||
|         slot->scn = arg->start_srv.local_scn; |         slot->scn = arg->start_srv.local_scn; | ||||||
| @@ -738,7 +764,7 @@ static void btc_spp_stop_srv(btc_spp_args_t *arg) | |||||||
|         // [2] remove all local related connection |         // [2] remove all local related connection | ||||||
|         for (j = 0; j < srv_cnt; j++) { |         for (j = 0; j < srv_cnt; j++) { | ||||||
|             for (i = 1; i <= MAX_RFC_PORTS; i++) { |             for (i = 1; i <= MAX_RFC_PORTS; i++) { | ||||||
|                 if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->connected && |                 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]->sdp_handle > 0 && | ||||||
|                     spp_local_param.spp_slots[i]->scn == srv_scn_arr[j]) { |                     spp_local_param.spp_slots[i]->scn == srv_scn_arr[j]) { | ||||||
|                     BTA_JvRfcommClose(spp_local_param.spp_slots[i]->rfc_handle, |                     BTA_JvRfcommClose(spp_local_param.spp_slots[i]->rfc_handle, | ||||||
| @@ -751,7 +777,7 @@ static void btc_spp_stop_srv(btc_spp_args_t *arg) | |||||||
|         // [3] remove all server |         // [3] remove all server | ||||||
|         for (j = 0; j < srv_cnt; j++) { |         for (j = 0; j < srv_cnt; j++) { | ||||||
|             for (i = 1; i <= MAX_RFC_PORTS; i++) { |             for (i = 1; i <= MAX_RFC_PORTS; i++) { | ||||||
|                 if (spp_local_param.spp_slots[i] != NULL && !spp_local_param.spp_slots[i]->connected && |                 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]->sdp_handle > 0 && | ||||||
|                     spp_local_param.spp_slots[i]->scn == srv_scn_arr[j]) { |                     spp_local_param.spp_slots[i]->scn == srv_scn_arr[j]) { | ||||||
|                     if (spp_local_param.spp_slots[i]->sdp_handle > 0) { |                     if (spp_local_param.spp_slots[i]->sdp_handle > 0) { | ||||||
| @@ -933,7 +959,9 @@ void btc_spp_cb_handler(btc_msg_t *msg) | |||||||
|     tBTA_JV *p_data = (tBTA_JV *)msg->arg; |     tBTA_JV *p_data = (tBTA_JV *)msg->arg; | ||||||
|     spp_slot_t *slot = NULL; |     spp_slot_t *slot = NULL; | ||||||
|     uint8_t serial = 0; |     uint8_t serial = 0; | ||||||
|     switch (msg->act) { |     uint8_t event = msg->act; | ||||||
|  |  | ||||||
|  |     switch (event) { | ||||||
|     case BTA_JV_ENABLE_EVT: |     case BTA_JV_ENABLE_EVT: | ||||||
|         param.init.status = p_data->status; |         param.init.status = p_data->status; | ||||||
|         btc_spp_cb_to_app(ESP_SPP_INIT_EVT, ¶m); |         btc_spp_cb_to_app(ESP_SPP_INIT_EVT, ¶m); | ||||||
| @@ -960,12 +988,14 @@ void btc_spp_cb_handler(btc_msg_t *msg) | |||||||
|                 slot = spp_find_slot_by_handle(p_data->rfc_open.handle); |                 slot = spp_find_slot_by_handle(p_data->rfc_open.handle); | ||||||
|                 if (!slot) { |                 if (!slot) { | ||||||
|                     osi_mutex_unlock(&spp_local_param.spp_slot_mutex); |                     osi_mutex_unlock(&spp_local_param.spp_slot_mutex); | ||||||
|                     BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); |                     BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); | ||||||
|                     param.open.status = ESP_SPP_NO_CONNECTION; |                     param.open.status = ESP_SPP_NO_CONNECTION; | ||||||
|                     break; |                     break; | ||||||
|                 } |                 } | ||||||
|                 param.open.fd = slot->fd; |                 param.open.fd = slot->fd; | ||||||
|                 osi_mutex_unlock(&spp_local_param.spp_slot_mutex); |                 osi_mutex_unlock(&spp_local_param.spp_slot_mutex); | ||||||
|  |             } else { | ||||||
|  |                 param.open.fd = -1; | ||||||
|             } |             } | ||||||
|             param.open.status = p_data->rfc_open.status; |             param.open.status = p_data->rfc_open.status; | ||||||
|         } while (0); |         } while (0); | ||||||
| @@ -989,12 +1019,14 @@ void btc_spp_cb_handler(btc_msg_t *msg) | |||||||
|                     slot = spp_find_slot_by_handle(p_data->rfc_srv_open.handle); |                     slot = spp_find_slot_by_handle(p_data->rfc_srv_open.handle); | ||||||
|                     if (!slot) { |                     if (!slot) { | ||||||
|                         osi_mutex_unlock(&spp_local_param.spp_slot_mutex); |                         osi_mutex_unlock(&spp_local_param.spp_slot_mutex); | ||||||
|                         BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); |                         BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); | ||||||
|                         param.srv_open.status = ESP_SPP_NO_CONNECTION; |                         param.srv_open.status = ESP_SPP_NO_CONNECTION; | ||||||
|                         break; |                         break; | ||||||
|                     } |                     } | ||||||
|                     param.srv_open.fd = slot->fd; |                     param.srv_open.fd = slot->fd; | ||||||
|                     osi_mutex_unlock(&spp_local_param.spp_slot_mutex); |                     osi_mutex_unlock(&spp_local_param.spp_slot_mutex); | ||||||
|  |                 } else { | ||||||
|  |                     param.srv_open.fd = -1; | ||||||
|                 } |                 } | ||||||
|                 param.srv_open.status = p_data->rfc_srv_open.status; |                 param.srv_open.status = p_data->rfc_srv_open.status; | ||||||
|             } while (0); |             } while (0); | ||||||
| @@ -1065,10 +1097,11 @@ void btc_spp_cb_handler(btc_msg_t *msg) | |||||||
|         if (spp_local_param.spp_mode == ESP_SPP_MODE_CB) { |         if (spp_local_param.spp_mode == ESP_SPP_MODE_CB) { | ||||||
|             btc_spp_cb_to_app(ESP_SPP_CLOSE_EVT, ¶m); |             btc_spp_cb_to_app(ESP_SPP_CLOSE_EVT, ¶m); | ||||||
|             osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT); |             osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT); | ||||||
|             slot = spp_find_slot_by_handle(p_data->rfc_close.handle); |             uint32_t id = (uintptr_t)p_data->rfc_close.user_data; | ||||||
|  |             slot = spp_find_slot_by_id(id); | ||||||
|             if (!slot) { |             if (!slot) { | ||||||
|                 osi_mutex_unlock(&spp_local_param.spp_slot_mutex); |                 osi_mutex_unlock(&spp_local_param.spp_slot_mutex); | ||||||
|                 BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); |                 BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|             spp_free_slot(slot); |             spp_free_slot(slot); | ||||||
| @@ -1077,11 +1110,12 @@ void btc_spp_cb_handler(btc_msg_t *msg) | |||||||
|             bool need_call = true; |             bool need_call = true; | ||||||
|             do { |             do { | ||||||
|                 osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT); |                 osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT); | ||||||
|                 slot = spp_find_slot_by_handle(p_data->rfc_close.handle); |                 uint32_t id = (uintptr_t)p_data->rfc_close.user_data; | ||||||
|  |                 slot = spp_find_slot_by_id(id); | ||||||
|                 if (!slot) { |                 if (!slot) { | ||||||
|                     param.close.status = ESP_SPP_NO_CONNECTION; |                     param.close.status = ESP_SPP_NO_CONNECTION; | ||||||
|                     osi_mutex_unlock(&spp_local_param.spp_slot_mutex); |                     osi_mutex_unlock(&spp_local_param.spp_slot_mutex); | ||||||
|                     BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); |                     BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); | ||||||
|                     break; |                     break; | ||||||
|                 } |                 } | ||||||
|                 // if rx still has data, delay free slot |                 // if rx still has data, delay free slot | ||||||
| @@ -1110,8 +1144,8 @@ void btc_spp_cb_handler(btc_msg_t *msg) | |||||||
|                         BTC_TRACE_ERROR("%s set slot close_alarm failed!", __func__); |                         BTC_TRACE_ERROR("%s set slot close_alarm failed!", __func__); | ||||||
|                         break; |                         break; | ||||||
|                     } |                     } | ||||||
|                     BTC_TRACE_WARNING("%s slot rx data will be discard in %d seconds!", __func__, |                     BTC_TRACE_WARNING("%s slot rx data will be discard in %d milliseconds!", | ||||||
|                                       VFS_CLOSE_TIMEOUT / 1000); |                                       __func__, VFS_CLOSE_TIMEOUT); | ||||||
|                     slot->connected = false; |                     slot->connected = false; | ||||||
|                     need_call = false; |                     need_call = false; | ||||||
|                 } |                 } | ||||||
| @@ -1137,7 +1171,7 @@ void btc_spp_cb_handler(btc_msg_t *msg) | |||||||
|             slot = spp_find_slot_by_handle(p_data->rfc_cong.handle); |             slot = spp_find_slot_by_handle(p_data->rfc_cong.handle); | ||||||
|             if (!slot) { |             if (!slot) { | ||||||
|                 osi_mutex_unlock(&spp_local_param.spp_slot_mutex); |                 osi_mutex_unlock(&spp_local_param.spp_slot_mutex); | ||||||
|                 BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); |                 BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|             if (!p_data->rfc_cong.cong) { |             if (!p_data->rfc_cong.cong) { | ||||||
| @@ -1159,7 +1193,7 @@ void btc_spp_cb_handler(btc_msg_t *msg) | |||||||
|             slot = spp_find_slot_by_handle(p_data->data_ind.handle); |             slot = spp_find_slot_by_handle(p_data->data_ind.handle); | ||||||
|             if (!slot) { |             if (!slot) { | ||||||
|                 osi_mutex_unlock(&spp_local_param.spp_slot_mutex); |                 osi_mutex_unlock(&spp_local_param.spp_slot_mutex); | ||||||
|                 BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); |                 BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|             serial = slot->serial; |             serial = slot->serial; | ||||||
| @@ -1416,7 +1450,7 @@ static ssize_t spp_vfs_read(int fd, void * dst, size_t size) | |||||||
|     slot = spp_find_slot_by_fd(fd); |     slot = spp_find_slot_by_fd(fd); | ||||||
|     if (!slot) { |     if (!slot) { | ||||||
|         osi_mutex_unlock(&spp_local_param.spp_slot_mutex); |         osi_mutex_unlock(&spp_local_param.spp_slot_mutex); | ||||||
|         BTC_TRACE_ERROR("%s unable to find RFCOMM slot!\n", __func__); |         BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__); | ||||||
|         errno = ENOENT; |         errno = ENOENT; | ||||||
|         return -1; |         return -1; | ||||||
|     } |     } | ||||||
| @@ -1441,6 +1475,14 @@ static ssize_t spp_vfs_read(int fd, void * dst, size_t size) | |||||||
|                     break; |                     break; | ||||||
|                 } |                 } | ||||||
|             } else { |             } else { | ||||||
|  |                 /** | ||||||
|  |                  * If close_alarm is not NULL, it means that we have received the BTA_JV_RFCOMM_CLOSE_EVT. | ||||||
|  |                  * And we can trigger close_alarm immediately. | ||||||
|  |                  */ | ||||||
|  |                 if (slot->close_alarm && osi_alarm_is_active(slot->close_alarm)) { | ||||||
|  |                     osi_alarm_cancel(slot->close_alarm); | ||||||
|  |                     osi_alarm_set(slot->close_alarm, 0); | ||||||
|  |                 } | ||||||
|                 osi_mutex_unlock(&spp_local_param.spp_slot_mutex); |                 osi_mutex_unlock(&spp_local_param.spp_slot_mutex); | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|   | |||||||
| @@ -105,6 +105,8 @@ typedef int  (tPORT_DATA_CO_CALLBACK) (UINT16 port_handle, UINT8 *p_buf, UINT16 | |||||||
|  |  | ||||||
| typedef void (tPORT_CALLBACK) (UINT32 code, UINT16 port_handle); | typedef void (tPORT_CALLBACK) (UINT32 code, UINT16 port_handle); | ||||||
|  |  | ||||||
|  | typedef void (tPORT_MGMT_CALLBACK) (UINT32 code, UINT16 port_handle, void* data); | ||||||
|  |  | ||||||
| /* | /* | ||||||
| ** Define events that registered application can receive in the callback | ** Define events that registered application can receive in the callback | ||||||
| */ | */ | ||||||
| @@ -219,7 +221,7 @@ extern "C" | |||||||
| extern int RFCOMM_CreateConnection (UINT16 uuid, UINT8 scn, | extern int RFCOMM_CreateConnection (UINT16 uuid, UINT8 scn, | ||||||
|                                     BOOLEAN is_server, UINT16 mtu, |                                     BOOLEAN is_server, UINT16 mtu, | ||||||
|                                     BD_ADDR bd_addr, UINT16 *p_handle, |                                     BD_ADDR bd_addr, UINT16 *p_handle, | ||||||
|                                     tPORT_CALLBACK *p_mgmt_cb); |                                     tPORT_MGMT_CALLBACK *p_mgmt_cb); | ||||||
|  |  | ||||||
|  |  | ||||||
| /******************************************************************************* | /******************************************************************************* | ||||||
|   | |||||||
| @@ -188,7 +188,7 @@ struct t_port_info { | |||||||
|  |  | ||||||
|     UINT32      ev_mask;                    /* Event mask for the callback */ |     UINT32      ev_mask;                    /* Event mask for the callback */ | ||||||
|     tPORT_CALLBACK      *p_callback;        /* Pointer to users callback function */ |     tPORT_CALLBACK      *p_callback;        /* Pointer to users callback function */ | ||||||
|     tPORT_CALLBACK      *p_mgmt_callback;   /* Callback function to receive connection up/down */ |     tPORT_MGMT_CALLBACK *p_mgmt_callback;   /* Callback function to receive connection up/down */ | ||||||
|     tPORT_DATA_CALLBACK *p_data_callback;   /* Callback function to receive data indications */ |     tPORT_DATA_CALLBACK *p_data_callback;   /* Callback function to receive data indications */ | ||||||
|     tPORT_DATA_CO_CALLBACK *p_data_co_callback;   /* Callback function with callouts and flowctrl */ |     tPORT_DATA_CO_CALLBACK *p_data_co_callback;   /* Callback function with callouts and flowctrl */ | ||||||
|     UINT16      credit_tx;                  /* Flow control credits for tx path */ |     UINT16      credit_tx;                  /* Flow control credits for tx path */ | ||||||
|   | |||||||
| @@ -103,7 +103,7 @@ static const char *result_code_strings[] = { | |||||||
| *******************************************************************************/ | *******************************************************************************/ | ||||||
| int RFCOMM_CreateConnection (UINT16 uuid, UINT8 scn, BOOLEAN is_server, | int RFCOMM_CreateConnection (UINT16 uuid, UINT8 scn, BOOLEAN is_server, | ||||||
|                              UINT16 mtu, BD_ADDR bd_addr, UINT16 *p_handle, |                              UINT16 mtu, BD_ADDR bd_addr, UINT16 *p_handle, | ||||||
|                              tPORT_CALLBACK *p_mgmt_cb) |                              tPORT_MGMT_CALLBACK *p_mgmt_cb) | ||||||
| { | { | ||||||
|     tPORT      *p_port; |     tPORT      *p_port; | ||||||
|     int        i; |     int        i; | ||||||
|   | |||||||
| @@ -175,7 +175,7 @@ void port_start_close (tPORT *p_port) | |||||||
|     if ((p_mcb == NULL) || (p_port->rfc.state == RFC_STATE_CLOSED)) { |     if ((p_mcb == NULL) || (p_port->rfc.state == RFC_STATE_CLOSED)) { | ||||||
|         /* Call management callback function before calling port_release_port() to clear tPort */ |         /* Call management callback function before calling port_release_port() to clear tPort */ | ||||||
|         if (p_port->p_mgmt_callback) { |         if (p_port->p_mgmt_callback) { | ||||||
|             p_port->p_mgmt_callback (PORT_CLOSED, p_port->inx); |             p_port->p_mgmt_callback (PORT_CLOSED, p_port->inx, NULL); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         port_release_port (p_port); |         port_release_port (p_port); | ||||||
| @@ -230,7 +230,7 @@ void PORT_StartCnf (tRFC_MCB *p_mcb, UINT16 result) | |||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 if (p_port->p_mgmt_callback) { |                 if (p_port->p_mgmt_callback) { | ||||||
|                     p_port->p_mgmt_callback (PORT_START_FAILED, p_port->inx); |                     p_port->p_mgmt_callback (PORT_START_FAILED, p_port->inx, NULL); | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 port_release_port (p_port); |                 port_release_port (p_port); | ||||||
| @@ -427,6 +427,7 @@ 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) | void PORT_DlcEstablishInd (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu) | ||||||
| { | { | ||||||
|     tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci); |     tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci); | ||||||
|  |     BOOLEAN accept = true; | ||||||
|  |  | ||||||
|     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:%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", |     RFCOMM_TRACE_DEBUG ("PORT_DlcEstablishInd p_mcb addr:%02x:%02x:%02x:%02x:%02x:%02x", | ||||||
| @@ -451,7 +452,7 @@ void PORT_DlcEstablishInd (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu) | |||||||
|     /* If there was an inactivity timer running for MCB stop it */ |     /* If there was an inactivity timer running for MCB stop it */ | ||||||
|     rfc_timer_stop (p_mcb); |     rfc_timer_stop (p_mcb); | ||||||
|  |  | ||||||
|     RFCOMM_DlcEstablishRsp (p_mcb, dlci, p_port->mtu, RFCOMM_SUCCESS); |     // RFCOMM_DlcEstablishRsp (p_mcb, dlci, p_port->mtu, RFCOMM_SUCCESS); | ||||||
|  |  | ||||||
|     /* This is the server side.  If application wants to know when connection */ |     /* This is the server side.  If application wants to know when connection */ | ||||||
|     /* is established, thats the place */ |     /* is established, thats the place */ | ||||||
| @@ -460,10 +461,15 @@ void PORT_DlcEstablishInd (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu) | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (p_port->p_mgmt_callback) { |     if (p_port->p_mgmt_callback) { | ||||||
|         p_port->p_mgmt_callback (PORT_SUCCESS, p_port->inx); |         p_port->p_mgmt_callback (PORT_SUCCESS, p_port->inx, &accept); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     if (accept) { | ||||||
|  |         RFCOMM_DlcEstablishRsp(p_mcb, dlci, p_port->mtu, RFCOMM_SUCCESS); | ||||||
|         p_port->state = PORT_STATE_OPENED; |         p_port->state = PORT_STATE_OPENED; | ||||||
|  |     } else { | ||||||
|  |         RFCOMM_DlcEstablishRsp(p_mcb, dlci, 0, RFCOMM_LOW_RESOURCES); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -506,7 +512,7 @@ void PORT_DlcEstablishCnf (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu, UINT16 resul | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (p_port->p_mgmt_callback) { |     if (p_port->p_mgmt_callback) { | ||||||
|         p_port->p_mgmt_callback (PORT_SUCCESS, p_port->inx); |         p_port->p_mgmt_callback (PORT_SUCCESS, p_port->inx, NULL); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     p_port->state = PORT_STATE_OPENED; |     p_port->state = PORT_STATE_OPENED; | ||||||
| @@ -1063,14 +1069,15 @@ void port_rfc_closed (tPORT *p_port, UINT8 res) | |||||||
|         p_port->p_callback (events, p_port->inx); |         p_port->p_callback (events, p_port->inx); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (p_port->p_mgmt_callback) { |     if (p_port->p_mgmt_callback && !(p_port->state == PORT_STATE_CLOSED && p_port->is_server)) { | ||||||
|         p_port->p_mgmt_callback (res, p_port->inx); |         p_port->p_mgmt_callback(res, p_port->inx, NULL); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     p_port->rfc.state = RFC_STATE_CLOSED; |     p_port->rfc.state = RFC_STATE_CLOSED; | ||||||
|  |  | ||||||
|     RFCOMM_TRACE_WARNING ("%s RFCOMM connection in state %d closed: %s (res: %d)", |     RFCOMM_TRACE_WARNING("%s RFCOMM connection in server:%d state %d closed: %s (res: %d)", | ||||||
|                           __func__, p_port->state, PORT_GetResultString(res), res); |                          __func__, p_port->is_server, p_port->state, PORT_GetResultString(res), | ||||||
|  |                          res); | ||||||
|  |  | ||||||
|     port_release_port (p_port); |     port_release_port (p_port); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -69,6 +69,8 @@ static void rfc_mx_conf_cnf (tRFC_MCB *p_mcb, tL2CAP_CFG_INFO *p_cfg); | |||||||
| *******************************************************************************/ | *******************************************************************************/ | ||||||
| void rfc_mx_sm_execute (tRFC_MCB *p_mcb, UINT16 event, void *p_data) | void rfc_mx_sm_execute (tRFC_MCB *p_mcb, UINT16 event, void *p_data) | ||||||
| { | { | ||||||
|  |     RFCOMM_TRACE_DEBUG("%s st:%d, evt:%d\n", __func__, p_mcb->state, event); | ||||||
|  |  | ||||||
|     switch (p_mcb->state) { |     switch (p_mcb->state) { | ||||||
|     case RFC_MX_STATE_IDLE: |     case RFC_MX_STATE_IDLE: | ||||||
|         rfc_mx_sm_state_idle (p_mcb, event, p_data); |         rfc_mx_sm_state_idle (p_mcb, event, p_data); | ||||||
|   | |||||||
| @@ -62,6 +62,8 @@ static void rfc_set_port_state(tPORT_STATE *port_pars, MX_FRAME *p_frame); | |||||||
| *******************************************************************************/ | *******************************************************************************/ | ||||||
| void rfc_port_sm_execute (tPORT *p_port, UINT16 event, void *p_data) | void rfc_port_sm_execute (tPORT *p_port, UINT16 event, void *p_data) | ||||||
| { | { | ||||||
|  |     RFCOMM_TRACE_DEBUG("%s st:%d, evt:%d\n", __func__, p_port->rfc.state, event); | ||||||
|  |  | ||||||
|     if (!p_port) { |     if (!p_port) { | ||||||
|         RFCOMM_TRACE_WARNING ("NULL port event %d", event); |         RFCOMM_TRACE_WARNING ("NULL port event %d", event); | ||||||
|         return; |         return; | ||||||
| @@ -296,6 +298,11 @@ void rfc_port_sm_term_wait_sec_check (tPORT *p_port, UINT16 event, void *p_data) | |||||||
|         if (*((UINT8 *)p_data) != RFCOMM_SUCCESS) { |         if (*((UINT8 *)p_data) != RFCOMM_SUCCESS) { | ||||||
|             if (p_port->rfc.p_mcb) { |             if (p_port->rfc.p_mcb) { | ||||||
|                 rfc_send_dm (p_port->rfc.p_mcb, p_port->dlci, TRUE); |                 rfc_send_dm (p_port->rfc.p_mcb, p_port->dlci, TRUE); | ||||||
|  |                 if (*((UINT8 *)p_data) == RFCOMM_LOW_RESOURCES) { | ||||||
|  |                     port_rfc_closed(p_port, PORT_NO_RESOURCES); | ||||||
|  |                 } else { | ||||||
|  |                     port_rfc_closed(p_port, PORT_UNKNOWN_ERROR); | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             rfc_send_ua (p_port->rfc.p_mcb, p_port->dlci); |             rfc_send_ua (p_port->rfc.p_mcb, p_port->dlci); | ||||||
|   | |||||||
| @@ -201,7 +201,6 @@ void osi_free_fun(void *p){ | |||||||
| *******************************************************************************/ | *******************************************************************************/ | ||||||
| void rfc_release_multiplexer_channel (tRFC_MCB *p_mcb) | void rfc_release_multiplexer_channel (tRFC_MCB *p_mcb) | ||||||
| { | { | ||||||
|  |  | ||||||
|     rfc_timer_free (p_mcb); |     rfc_timer_free (p_mcb); | ||||||
|  |  | ||||||
|     fixed_queue_free(p_mcb->cmd_q, osi_free_fun); |     fixed_queue_free(p_mcb->cmd_q, osi_free_fun); | ||||||
|   | |||||||
| @@ -462,7 +462,6 @@ components/bt/host/bluedroid/btc/profile/std/include/dis_api.h | |||||||
| components/bt/host/bluedroid/btc/profile/std/include/srvc_api.h | components/bt/host/bluedroid/btc/profile/std/include/srvc_api.h | ||||||
| components/bt/host/bluedroid/btc/profile/std/smp/esp_app_sec.c | components/bt/host/bluedroid/btc/profile/std/smp/esp_app_sec.c | ||||||
| components/bt/host/bluedroid/btc/profile/std/smp/include/esp_sec_api.h | components/bt/host/bluedroid/btc/profile/std/smp/include/esp_sec_api.h | ||||||
| components/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c |  | ||||||
| components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h | components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h | ||||||
| components/bt/host/bluedroid/common/include/common/bt_common_types.h | components/bt/host/bluedroid/common/include/common/bt_common_types.h | ||||||
| components/bt/host/bluedroid/common/include/common/bt_defs.h | components/bt/host/bluedroid/common/include/common/bt_defs.h | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 liqigan
					liqigan