Exemplo n.º 1
0
/*******************************************************************************
**
** Function         rfc_mx_conf_cnf
**
** Description      This function handles L2CA_ConfigCnf message from the
**                  L2CAP.  If result is not success tell upper layer that
**                  start has not been accepted.  If initiator send SABME
**                  on DLCI 0.  T1 is still running.
**
*******************************************************************************/
static void rfc_mx_conf_cnf (tRFC_MCB *p_mcb, tL2CAP_CFG_INFO *p_cfg)
{
    RFCOMM_TRACE_EVENT2 ("rfc_mx_conf_cnf p_cfg:%08x res:%d ", p_cfg, (p_cfg) ? p_cfg->result : 0);

    if (p_cfg->result != L2CAP_CFG_OK)
    {
        if (p_mcb->is_initiator)
        {
            PORT_StartCnf (p_mcb, p_cfg->result);
            L2CA_DisconnectReq (p_mcb->lcid);
        }
        rfc_release_multiplexer_channel (p_mcb);
        return;
    }

    p_mcb->local_cfg_sent = TRUE;
    if ((p_mcb->state == RFC_MX_STATE_CONFIGURE) && p_mcb->peer_cfg_rcvd)
    {
        if (p_mcb->is_initiator)
        {
            p_mcb->state = RFC_MX_STATE_SABME_WAIT_UA;
            rfc_send_sabme (p_mcb, RFCOMM_MX_DLCI);
            rfc_timer_start (p_mcb, RFC_T1_TIMEOUT);
        }
        else
        {
            p_mcb->state = RFC_MX_STATE_WAIT_SABME;
            rfc_timer_start (p_mcb, RFC_T2_TIMEOUT);
        }
    }
}
Exemplo n.º 2
0
/*******************************************************************************
**
** Function         PORT_StartCnf
**
** Description      This function is called from the RFCOMM layer when
**                  establishing of the multiplexer channel is completed.
**                  Continue establishing of the connection for all ports that
**                  are in the OPENING state
**
*******************************************************************************/
void PORT_StartCnf (tRFC_MCB *p_mcb, UINT16 result)
{
    tPORT   *p_port;
    int     i;
    BOOLEAN no_ports_up = TRUE;

    RFCOMM_TRACE_EVENT ("PORT_StartCnf result:%d", result);

    p_port = &rfc_cb.port.port[0];
    for (i = 0; i < MAX_RFC_PORTS; i++, p_port++)
    {
        if (p_port->rfc.p_mcb == p_mcb)
        {
            no_ports_up = FALSE;

            if (result == RFCOMM_SUCCESS)
                RFCOMM_ParNegReq (p_mcb, p_port->dlci, p_port->mtu);
            else
            {
                RFCOMM_TRACE_WARNING ("PORT_StartCnf failed result:%d", result);

                /* Warning: result is also set to 4 when l2cap connection
                   fails due to l2cap connect cnf (no_resources) */
                if( result == HCI_ERR_PAGE_TIMEOUT )
                    p_port->error = PORT_PAGE_TIMEOUT;
                else
                    p_port->error = PORT_START_FAILED;

                rfc_release_multiplexer_channel (p_mcb);
                p_port->rfc.p_mcb = NULL;

                /* Send event to the application */
                if (p_port->p_callback && (p_port->ev_mask & PORT_EV_CONNECT_ERR))
                    (p_port->p_callback)(PORT_EV_CONNECT_ERR, p_port->inx);

                if (p_port->p_mgmt_callback)
                    p_port->p_mgmt_callback (PORT_START_FAILED, p_port->inx);

                port_release_port (p_port);
            }
        }
    }

    /* There can be a situation when after starting connection, user closes the */
    /* port, we can catch it here to close multiplexor channel */
    if (no_ports_up)
    {
        rfc_check_mcb_active (p_mcb);
    }
}
Exemplo n.º 3
0
/*******************************************************************************
**
** Function         PORT_CloseInd
**
** Description      This function is called from the RFCOMM layer when
**                  multiplexer connection is released.
**
*******************************************************************************/
void PORT_CloseInd (tRFC_MCB *p_mcb)
{
    tPORT  *p_port;
    int    i;

    RFCOMM_TRACE_EVENT ("PORT_CloseInd");

    p_port = &rfc_cb.port.port[0];
    for (i = 0; i < MAX_RFC_PORTS; i++, p_port++) {
        if (p_port->rfc.p_mcb == p_mcb) {
            port_rfc_closed (p_port, PORT_PEER_CONNECTION_FAILED);
        }
    }
    rfc_release_multiplexer_channel (p_mcb);
}
Exemplo n.º 4
0
/*******************************************************************************
**
** Function         rfc_mx_sm_state_disc_wait_ua
**
** Description      This function handles events when the multiplexer sent
**                  DISC and is waiting for UA reply.
**
** Returns          void
**
*******************************************************************************/
void rfc_mx_sm_state_disc_wait_ua (tRFC_MCB *p_mcb, UINT16 event, void *p_data)
{
    BT_HDR *p_buf;

    RFCOMM_TRACE_EVENT1 ("rfc_mx_sm_state_disc_wait_ua - evt:%d", event);
    switch (event)
    {
    case RFC_EVENT_UA:
    case RFC_EVENT_DM:
    case RFC_EVENT_TIMEOUT:
        L2CA_DisconnectReq (p_mcb->lcid);

        if (p_mcb->restart_required)
        {
            /* Start Request was received while disconnecting.  Execute it again */
            if ((p_mcb->lcid = L2CA_ConnectReq (BT_PSM_RFCOMM, p_mcb->bd_addr)) == 0)
            {
                PORT_StartCnf (p_mcb, RFCOMM_ERROR);
                return;
            }
            /* Save entry for quicker access to mcb based on the LCID */
            rfc_save_lcid_mcb (p_mcb, p_mcb->lcid);

            /* clean up before reuse it */
            while ((p_buf = (BT_HDR *)GKI_dequeue(&p_mcb->cmd_q)) != NULL)
                GKI_freebuf(p_buf);

            rfc_timer_start (p_mcb, RFC_MCB_INIT_INACT_TIMER);

            p_mcb->is_initiator     = TRUE;
            p_mcb->restart_required = FALSE;
            p_mcb->local_cfg_sent   = FALSE;
            p_mcb->peer_cfg_rcvd    = FALSE;

            p_mcb->state = RFC_MX_STATE_WAIT_CONN_CNF;
            return;
        }
        rfc_release_multiplexer_channel (p_mcb);
        return;

    case RFC_EVENT_DISC:
        rfc_send_ua (p_mcb, RFCOMM_MX_DLCI);
        return;

    case RFC_EVENT_UIH:
        GKI_freebuf (p_data);
        rfc_send_dm (p_mcb, RFCOMM_MX_DLCI, FALSE);
        return;

    case RFC_MX_EVENT_START_REQ:
        p_mcb->restart_required = TRUE;
        return;

    case RFC_MX_EVENT_DISC_IND:
        p_mcb->state = RFC_MX_STATE_IDLE;
        PORT_CloseInd (p_mcb);
        return;

    case RFC_MX_EVENT_CLOSE_REQ:
        return;

    case RFC_MX_EVENT_QOS_VIOLATION_IND:
        break;
    }
    RFCOMM_TRACE_EVENT2 ("RFCOMM MX ignored - evt:%d in state:%d", event, p_mcb->state);
}