Exemple #1
0
/*******************************************************************************
**
** Function         port_open_continue
**
** Description      This function is called after security manager completes
**                  required security checks.
**
** Returns          void
**
*******************************************************************************/
int port_open_continue (tPORT *p_port)
{
    tRFC_MCB *p_mcb;

    RFCOMM_TRACE_EVENT ("port_open_continue, p_port:%p", p_port);

    /* Check if multiplexer channel has already been established */
    if ((p_mcb = rfc_alloc_multiplexer_channel (p_port->bd_addr, TRUE)) == NULL) {
        RFCOMM_TRACE_WARNING ("port_open_continue no mx channel");
        port_release_port (p_port);
        return (PORT_NO_RESOURCES);
    }

    p_port->rfc.p_mcb = p_mcb;

    p_mcb->port_inx[p_port->dlci] = p_port->inx;

    /* Connection is up and we know local and remote features, select MTU */
    port_select_mtu (p_port);

    if (p_mcb->state == RFC_MX_STATE_CONNECTED) {
        RFCOMM_ParNegReq (p_mcb, p_port->dlci, p_port->mtu);
    } else if ((p_mcb->state == RFC_MX_STATE_IDLE)
               || (p_mcb->state == RFC_MX_STATE_DISC_WAIT_UA)) {
        /* In RFC_MX_STATE_IDLE state, MX state machine will create connection           */
        /* In RFC_MX_STATE_DISC_WAIT_UA state, MX state machine will recreate connection */
        /*    after disconnecting is completed                                           */
        RFCOMM_StartReq (p_mcb);
    } else {
        /* MX state machine ignores RFC_MX_EVENT_START_REQ in these states */
        /* When it enters RFC_MX_STATE_CONNECTED, it will check any openning ports */
        RFCOMM_TRACE_DEBUG ("port_open_continue: mx state(%d) mx channel is openning", p_mcb->state);
    }
    return (PORT_SUCCESS);
}
/*******************************************************************************
**
** Function         RFCOMM_ConnectInd
**
** Description      This is a callback function called by L2CAP when
**                  L2CA_ConnectInd received.  Allocate multiplexer control block
**                  and dispatch the event to it.
**
*******************************************************************************/
void RFCOMM_ConnectInd (BD_ADDR bd_addr, UINT16 lcid, UINT16 psm, UINT8 id)
{
    tRFC_MCB *p_mcb = rfc_alloc_multiplexer_channel(bd_addr, FALSE);
    UNUSED(psm);

    if ((p_mcb)&&(p_mcb->state != RFC_MX_STATE_IDLE))
    {
        /* if this is collision case */
        if ((p_mcb->is_initiator)&&(p_mcb->state == RFC_MX_STATE_WAIT_CONN_CNF))
        {
            p_mcb->pending_lcid = lcid;
            p_mcb->pending_id   = id;

            /* wait random timeout (2 - 12) to resolve collision */
            /* if peer gives up then local device rejects incoming connection and continues as initiator */
            /* if timeout, local device disconnects outgoing connection and continues as acceptor */
            RFCOMM_TRACE_DEBUG ("RFCOMM_ConnectInd start timer for collision, initiator's LCID(0x%x), acceptor's LCID(0x%x)",
                                  p_mcb->lcid, p_mcb->pending_lcid);

            rfc_timer_start(p_mcb, (UINT16)(GKI_get_tick_count()%10 + 2));
            return;
        }
        else
        {
            /* we cannot accept connection request from peer at this state */
            /* don't update lcid */
            p_mcb = NULL;
        }
    }
    else
    {
        /* store mcb even if null */
        rfc_save_lcid_mcb (p_mcb, lcid);
    }

    if (p_mcb == NULL)
    {
        L2CA_ConnectRsp (bd_addr, id, lcid, L2CAP_CONN_NO_RESOURCES, 0);
        return;
    }
    p_mcb->lcid     = lcid;

    rfc_mx_sm_execute (p_mcb, RFC_MX_EVENT_CONN_IND, &id);
}