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);
}
Exemple #2
0
/*******************************************************************************
**
** Function         port_rfc_closed
**
** Description      This function when RFCOMM side of port is closed
**
*******************************************************************************/
void port_rfc_closed (tPORT *p_port, UINT8 res)
{
    UINT8     old_signals;
    UINT32    events = 0;
    tRFC_MCB *p_mcb = p_port->rfc.p_mcb;

    if ((p_port->state == PORT_STATE_OPENING) && (p_port->is_server)) {
        /* The servr side has not been informed that connection is up, ignore */
        RFCOMM_TRACE_EVENT ("port_rfc_closed in OPENING state ignored");

        rfc_port_timer_stop (p_port);
        p_port->rfc.state = RFC_STATE_CLOSED;

        if (p_mcb) {
            p_mcb->port_inx[p_port->dlci] = 0;

            /* If there are no more ports opened on this MCB release it */
            rfc_check_mcb_active (p_mcb);
            p_port->rfc.p_mcb = NULL;
        }

        /* Need to restore DLCI to listening state
         * if the server was on the initiating RFC
         */
        p_port->dlci &= 0xfe;

        return;
    }

    if ((p_port->state != PORT_STATE_CLOSING) && (p_port->state != PORT_STATE_CLOSED)) {
        p_port->line_status |= LINE_STATUS_FAILED;

        old_signals = p_port->peer_ctrl.modem_signal;

        p_port->peer_ctrl.modem_signal &= ~(PORT_DTRDSR_ON | PORT_CTSRTS_ON | PORT_DCD_ON);

        events |= port_get_signal_changes (p_port, old_signals, p_port->peer_ctrl.modem_signal);

        if (p_port->ev_mask & PORT_EV_CONNECT_ERR) {
            events |= PORT_EV_CONNECT_ERR;
        }
    }
    RFCOMM_TRACE_EVENT ("port_rfc_closed state:%d sending events:%x", p_port->state, events);

    if ((p_port->p_callback != NULL) && events) {
        p_port->p_callback (events, p_port->inx);
    }

    if (p_port->p_mgmt_callback) {
        p_port->p_mgmt_callback (res, p_port->inx);
    }

    p_port->rfc.state = RFC_STATE_CLOSED;

    RFCOMM_TRACE_WARNING ("%s RFCOMM connection in state %d closed: %s (res: %d)",
                          __func__, p_port->state, PORT_GetResultString(res), res);

    port_release_port (p_port);
}
Exemple #3
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);
    }
}
Exemple #4
0
/*******************************************************************************
**
** Function         port_start_close
**
** Description      This function is called in the BTU_TASK context to
**                  release DLC
**
** Returns          void
**
*******************************************************************************/
void port_start_close (tPORT *p_port)
{
    tRFC_MCB *p_mcb = p_port->rfc.p_mcb;
    UINT8  old_signals;
    UINT32 events = 0;

    /* At first indicate to the user that signals on the connection were dropped */
    p_port->line_status |= LINE_STATUS_FAILED;
    old_signals = p_port->peer_ctrl.modem_signal;

    p_port->peer_ctrl.modem_signal &= ~(PORT_DTRDSR_ON | PORT_CTSRTS_ON | PORT_DCD_ON);

    events |= port_get_signal_changes (p_port, old_signals, p_port->peer_ctrl.modem_signal);

    if (p_port->ev_mask & PORT_EV_CONNECT_ERR) {
        events |= PORT_EV_CONNECT_ERR;
    }

    if (p_port->ev_mask & PORT_EV_ERR) {
        events |= PORT_EV_ERR;
    }

    if ((p_port->p_callback != NULL) && events) {
        p_port->p_callback (events, p_port->inx);
    }


    /* Check if RFCOMM side has been closed while the message was queued */
    if ((p_mcb == NULL) || (p_port->rfc.state == RFC_STATE_CLOSED)) {
        /* Call management callback function before calling port_release_port() to clear tPort */
        if (p_port->p_mgmt_callback) {
            p_port->p_mgmt_callback (PORT_CLOSED, p_port->inx);
        }

        port_release_port (p_port);
    } else {
        RFCOMM_DlcReleaseReq (p_mcb, p_port->dlci);
    }
}