Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8ecf897b authored by zzy's avatar zzy Committed by Matthew Xie
Browse files

Fixed issue that failed to update rfc credit to peer when host can not handle...

Fixed issue that failed to update rfc credit to peer when host can not handle the incoming packets fast enough

Bug 10233699: Bluetooth sockets block indefinitely on read(...)
parent 3ca5a639
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -867,7 +867,10 @@ static BOOLEAN flush_incoming_que_on_wr_signal(rfc_slot_t* rs)

    //app is ready to receive data, tell stack to start the data flow
    //fix me: need a jv flow control api to serialize the call in stack
    PORT_FlowControl(rs->rfc_port_handle, TRUE);
    APPL_TRACE_DEBUG3("enable data flow, rfc_handle:0x%x, rfc_port_handle:0x%x, user_id:%d",
                        rs->rfc_handle, rs->rfc_port_handle, rs->id);
    extern int PORT_FlowControl_MaxCredit(UINT16 handle, BOOLEAN enable);
    PORT_FlowControl_MaxCredit(rs->rfc_port_handle, TRUE);
    return TRUE;
}
void btsock_rfc_signaled(int fd, int flags, uint32_t user_id)
+79 −0
Original line number Diff line number Diff line
@@ -845,6 +845,85 @@ int PORT_FlowControl (UINT16 handle, BOOLEAN enable)
    }
    return (PORT_SUCCESS);
}
/*******************************************************************************
**
** Function         PORT_FlowControl_MaxCredit
**
** Description      This function directs a specified connection to pass
**                  flow control message to the peer device.  Enable flag passed
**                  shows if port can accept more data. It also sends max credit
**                  when data flow enabled
**
** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
**                  enable     - enables data flow
**
*******************************************************************************/

int PORT_FlowControl_MaxCredit (UINT16 handle, BOOLEAN enable)
{
    tPORT      *p_port;
    BOOLEAN    old_fc;
    UINT32     events;

    RFCOMM_TRACE_API2 ("PORT_FlowControl() handle:%d enable: %d", handle, enable);

    /* 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, p_port->credit_rx);
        }
    }
    else
    {
        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))
    {
        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);
}


/*******************************************************************************