move flow control to btc layer

defer free slot in btc layer when receive BTA_JV_RFCOMM_CLOSE_EVT
This commit is contained in:
liqigan
2020-08-20 13:19:22 +08:00
parent eff892933c
commit 14f48d35bd
12 changed files with 314 additions and 80 deletions

View File

@@ -899,6 +899,77 @@ int PORT_FlowControl_MaxCredit (UINT16 handle, BOOLEAN enable)
}
#endif
/*******************************************************************************
**
** Function PORT_FlowControl_GiveCredit
**
** Description This function gives specified credits to the peer
**
** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
** enable - enables data flow
** credits_given - credits to give
**
*******************************************************************************/
int PORT_FlowControl_GiveCredit (UINT16 handle, BOOLEAN enable, UINT16 credits_given)
{
tPORT *p_port;
BOOLEAN old_fc;
UINT32 events;
RFCOMM_TRACE_DEBUG("%s handle:%d enable: %d, cred %d", __func__, handle, enable, credits_given);
/* Check if handle is valid to avoid crashing */
if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
return (PORT_BAD_HANDLE);
}
p_port = &rfc_cb.port.port[handle - 1];
if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
return (PORT_NOT_OPENED);
}
if (!p_port->rfc.p_mcb) {
return (PORT_NOT_OPENED);
}
p_port->rx.user_fc = !enable;
if (p_port->rfc.p_mcb->flow == PORT_FC_CREDIT) {
if (!p_port->rx.user_fc) {
port_flow_control_peer(p_port, TRUE, credits_given);
}
} else {
assert(0); // karl: temporarily not allowed
old_fc = p_port->local_ctrl.fc;
/* FC is set if user is set or peer is set */
p_port->local_ctrl.fc = (p_port->rx.user_fc | p_port->rx.peer_fc);
if (p_port->local_ctrl.fc != old_fc) {
port_start_control (p_port);
}
}
/* Need to take care of the case when we could not deliver events */
/* to the application because we were flow controlled */
if (enable && (p_port->rx.queue_size != 0)) {
assert(0); // karl: temporarily not allowed
events = PORT_EV_RXCHAR;
if (p_port->rx_flag_ev_pending) {
p_port->rx_flag_ev_pending = FALSE;
events |= PORT_EV_RXFLAG;
}
events &= p_port->ev_mask;
if (p_port->p_callback && events) {
p_port->p_callback (events, p_port->inx);
}
}
return (PORT_SUCCESS);
}
/*******************************************************************************
**
** Function PORT_GetModemStatus

View File

@@ -826,7 +826,8 @@ void PORT_DataInd (tRFC_MCB *p_mcb, UINT8 dlci, BT_HDR *p_buf)
/* Another packet is delivered to user. Send credits to peer if required */
if (p_port->p_data_co_callback(p_port->inx, (UINT8 *)p_buf, -1, DATA_CO_CALLBACK_TYPE_INCOMING)) {
port_flow_control_peer(p_port, TRUE, 1);
// do nothing, flow control credits will be given upon upper-layer request;
// port_flow_control_peer(p_port, TRUE, 1);
} else {
port_flow_control_peer(p_port, FALSE, 0);
}

View File

@@ -210,17 +210,17 @@ void port_release_port (tPORT *p_port)
osi_mutex_global_lock();
RFCOMM_TRACE_DEBUG("port_release_port, p_port:%p", p_port);
if (p_port->rx.queue) {
if (p_port->rx.queue != NULL) {
while ((p_buf = (BT_HDR *)fixed_queue_dequeue(p_port->rx.queue, 0)) != NULL) {
osi_free (p_buf);
osi_free(p_buf);
}
}
p_port->rx.queue_size = 0;
if (p_port->tx.queue) {
if (p_port->tx.queue != NULL) {
while ((p_buf = (BT_HDR *)fixed_queue_dequeue(p_port->tx.queue, 0)) != NULL) {
osi_free (p_buf);
}
osi_free(p_buf);
}
}
p_port->tx.queue_size = 0;
@@ -514,10 +514,12 @@ void port_flow_control_peer(tPORT *p_port, BOOLEAN enable, UINT16 count)
&& (p_port->credit_rx_max > p_port->credit_rx)) {
rfc_send_credit(p_port->rfc.p_mcb, p_port->dlci,
(UINT8) (p_port->credit_rx_max - p_port->credit_rx));
RFCOMM_TRACE_DEBUG("send credit: max %d, rx %d, count %d", p_port->credit_rx_max, p_port->credit_rx, count);
p_port->credit_rx = p_port->credit_rx_max;
p_port->rx.peer_fc = FALSE;
} else {
RFCOMM_TRACE_DEBUG("credit: max %d, rx %d, low %d", p_port->credit_rx_max, p_port->credit_rx, p_port->credit_rx_low);
}
}
/* else want to disable flow from peer */