コード例 #1
0
ファイル: rfc_mx_fsm.c プロジェクト: Abocer/android-4.2_r1
/*******************************************************************************
**
** Function         rfc_mx_sm_state_wait_sabme
**
** Description      This function handles events when the multiplexer is
**                  waiting for SABME on the acceptor side after configuration
**
** Returns          void
**
*******************************************************************************/
void rfc_mx_sm_state_wait_sabme (tRFC_MCB *p_mcb, UINT16 event, void *p_data)
{
    RFCOMM_TRACE_EVENT1 ("rfc_mx_sm_state_wait_sabme - evt:%d", event);
    switch (event)
    {
    case RFC_MX_EVENT_DISC_IND:
        p_mcb->state = RFC_MX_STATE_IDLE;
        PORT_CloseInd (p_mcb);
        return;

    case RFC_EVENT_SABME:
        /* if we gave up outgoing connection request */
        if (p_mcb->pending_lcid)
        {
            p_mcb->pending_lcid = 0;

            rfc_send_ua (p_mcb, RFCOMM_MX_DLCI);

            rfc_timer_stop (p_mcb);
            p_mcb->state      = RFC_MX_STATE_CONNECTED;
            p_mcb->peer_ready = TRUE;

            /* MX channel collision has been resolved, continue to open ports */
            PORT_StartCnf (p_mcb, RFCOMM_SUCCESS);
        }
        else
        {
            rfc_timer_stop (p_mcb);
            PORT_StartInd (p_mcb);
        }
        return;

    case RFC_MX_EVENT_START_RSP:
        if (*((UINT16 *)p_data) != RFCOMM_SUCCESS)
            rfc_send_dm (p_mcb, RFCOMM_MX_DLCI, TRUE);
        else
        {
            rfc_send_ua (p_mcb, RFCOMM_MX_DLCI);

            p_mcb->state      = RFC_MX_STATE_CONNECTED;
            p_mcb->peer_ready = TRUE;
        }
        return;

    case RFC_MX_EVENT_CONF_IND: /* workaround: we don't support reconfig */
    case RFC_MX_EVENT_CONF_CNF: /* workaround: we don't support reconfig */
    case RFC_EVENT_TIMEOUT:
        p_mcb->state = RFC_MX_STATE_IDLE;
        L2CA_DisconnectReq (p_mcb->lcid);

        PORT_CloseInd (p_mcb);
        return;
    }
    RFCOMM_TRACE_EVENT2 ("RFCOMM MX ignored - evt:%d in state:%d", event, p_mcb->state);
}
コード例 #2
0
ファイル: rfc_mx_fsm.c プロジェクト: Abocer/android-4.2_r1
/*******************************************************************************
**
** Function         rfc_mx_sm_sabme_wait_ua
**
** Description      This function handles events when the multiplexer sent
**                  SABME and is waiting for UA reply.
**
** Returns          void
**
*******************************************************************************/
void rfc_mx_sm_sabme_wait_ua (tRFC_MCB *p_mcb, UINT16 event, void *p_data)
{
    RFCOMM_TRACE_EVENT1 ("rfc_mx_sm_sabme_wait_ua - evt:%d", event);
    switch (event)
    {
    case RFC_MX_EVENT_START_REQ:
    case RFC_MX_EVENT_CONN_CNF:
        RFCOMM_TRACE_ERROR2 ("Mx error state %d event %d", p_mcb->state, event);
        return;

    /* workaround: we don't support reconfig */
    /* commented out until we support reconfig
    case RFC_MX_EVENT_CONF_IND:
        rfc_mx_conf_ind (p_mcb, (tL2CAP_CFG_INFO *)p_data);
        return;

    case RFC_MX_EVENT_CONF_CNF:
        rfc_mx_conf_cnf (p_mcb, (tL2CAP_CFG_INFO *)p_data);
        return;
    */

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

    case RFC_EVENT_UA:
        rfc_timer_stop (p_mcb);

        p_mcb->state      = RFC_MX_STATE_CONNECTED;
        p_mcb->peer_ready = TRUE;

        PORT_StartCnf (p_mcb, RFCOMM_SUCCESS);
        return;

    case RFC_EVENT_DM:
        rfc_timer_stop (p_mcb);
        /* Case falls through */

    case RFC_MX_EVENT_CONF_IND: /* workaround: we don't support reconfig */
    case RFC_MX_EVENT_CONF_CNF: /* workaround: we don't support reconfig */
    case RFC_EVENT_TIMEOUT:
        p_mcb->state = RFC_MX_STATE_IDLE;
        L2CA_DisconnectReq (p_mcb->lcid);

        PORT_StartCnf (p_mcb, RFCOMM_ERROR);
        return;
    }
    RFCOMM_TRACE_EVENT2 ("RFCOMM MX ignored - evt:%d in state:%d", event, p_mcb->state);
}
コード例 #3
0
ファイル: rfc_port_fsm.c プロジェクト: morrey/bt_bcm
/*******************************************************************************
**
** Function         rfc_port_sm_state_closed
**
** Description      This function handles events when the port is in
**                  CLOSED state. This state exists when port is
**                  being initially established.
**
** Returns          void
**
*******************************************************************************/
void rfc_port_sm_state_closed (tPORT *p_port, UINT16 event, void *p_data)
{
    switch (event)
    {
    case RFC_EVENT_OPEN:
        p_port->rfc.state = RFC_STATE_ORIG_WAIT_SEC_CHECK;
        btm_sec_mx_access_request (p_port->rfc.p_mcb->bd_addr, BT_PSM_RFCOMM, TRUE,
                                   BTM_SEC_PROTO_RFCOMM, (UINT32)(p_port->dlci / 2),
                                   &rfc_sec_check_complete, p_port);
        return;

    case RFC_EVENT_CLOSE:
        break;

    case RFC_EVENT_CLEAR:
        return;

    case RFC_EVENT_DATA:
        GKI_freebuf (p_data);
        break;

    case RFC_EVENT_SABME:
        /* make sure the multiplexer disconnect timer is not running (reconnect case) */
        rfc_timer_stop(p_port->rfc.p_mcb );

        /* Open will be continued after security checks are passed */
        p_port->rfc.state = RFC_STATE_TERM_WAIT_SEC_CHECK;
        btm_sec_mx_access_request (p_port->rfc.p_mcb->bd_addr, BT_PSM_RFCOMM, FALSE,
                                   BTM_SEC_PROTO_RFCOMM, (UINT32)(p_port->dlci / 2),
                                   &rfc_sec_check_complete, p_port);
        return;

    case RFC_EVENT_UA:
        return;

    case RFC_EVENT_DM:
        rfc_port_closed (p_port);
        return;

    case RFC_EVENT_UIH:
        GKI_freebuf (p_data);
        rfc_send_dm (p_port->rfc.p_mcb, p_port->dlci, FALSE);
        return;

    case RFC_EVENT_DISC:
        rfc_send_dm (p_port->rfc.p_mcb, p_port->dlci, FALSE);
        return;

    case RFC_EVENT_TIMEOUT:
        Port_TimeOutCloseMux( p_port->rfc.p_mcb ) ;
        RFCOMM_TRACE_ERROR ("Port error state %d event %d", p_port->rfc.state, event);
        return;
    }

    RFCOMM_TRACE_WARNING ("Port state closed Event ignored %d", event);
    return;
}
コード例 #4
0
ファイル: rfc_utils.c プロジェクト: danathughes/esp-idf
/*******************************************************************************
**
** Function         rfc_alloc_multiplexer_channel
**
** Description      This function returns existing or new control block for
**                  the BD_ADDR.
**
*******************************************************************************/
tRFC_MCB *rfc_alloc_multiplexer_channel (BD_ADDR bd_addr, BOOLEAN is_initiator)
{
    int i, j;
    tRFC_MCB *p_mcb = NULL;
    RFCOMM_TRACE_DEBUG("rfc_alloc_multiplexer_channel: bd_addr:%02x:%02x:%02x:%02x:%02x:%02x",
                       bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);
    RFCOMM_TRACE_DEBUG("rfc_alloc_multiplexer_channel:is_initiator:%d", is_initiator);

    for (i = 0; i < MAX_BD_CONNECTIONS; i++) {
        RFCOMM_TRACE_DEBUG("rfc_alloc_multiplexer_channel rfc_cb.port.rfc_mcb[%d].state:%d",
                           i, rfc_cb.port.rfc_mcb[i].state);
        RFCOMM_TRACE_DEBUG("(rfc_cb.port.rfc_mcb[i].bd_addr:%02x:%02x:%02x:%02x:%02x:%02x",
                           rfc_cb.port.rfc_mcb[i].bd_addr[0], rfc_cb.port.rfc_mcb[i].bd_addr[1],
                           rfc_cb.port.rfc_mcb[i].bd_addr[2], rfc_cb.port.rfc_mcb[i].bd_addr[3],
                           rfc_cb.port.rfc_mcb[i].bd_addr[4], rfc_cb.port.rfc_mcb[i].bd_addr[5]);

        if ((rfc_cb.port.rfc_mcb[i].state != RFC_MX_STATE_IDLE)
                && (!memcmp (rfc_cb.port.rfc_mcb[i].bd_addr, bd_addr, BD_ADDR_LEN))) {
            /* Multiplexer channel found do not change anything */
            /* If there was an inactivity timer running stop it now */
            if (rfc_cb.port.rfc_mcb[i].state == RFC_MX_STATE_CONNECTED) {
                rfc_timer_stop (&rfc_cb.port.rfc_mcb[i]);
            }
            RFCOMM_TRACE_DEBUG("rfc_alloc_multiplexer_channel:is_initiator:%d, found, state:%d, p_mcb:%p",
                               is_initiator, rfc_cb.port.rfc_mcb[i].state, &rfc_cb.port.rfc_mcb[i]);
            return (&rfc_cb.port.rfc_mcb[i]);
        }
    }

    /* connection with bd_addr does not exist */
    for (i = 0, j = rfc_cb.rfc.last_mux + 1; i < MAX_BD_CONNECTIONS; i++, j++) {
        if (j >= MAX_BD_CONNECTIONS) {
            j = 0;
        }

        p_mcb = &rfc_cb.port.rfc_mcb[j];
        if (rfc_cb.port.rfc_mcb[j].state == RFC_MX_STATE_IDLE) {
            /* New multiplexer control block */
            fixed_queue_free(p_mcb->cmd_q, NULL);
            memset (p_mcb, 0, sizeof (tRFC_MCB));
            memcpy (p_mcb->bd_addr, bd_addr, BD_ADDR_LEN);
            RFCOMM_TRACE_DEBUG("rfc_alloc_multiplexer_channel:is_initiator:%d, create new p_mcb:%p, index:%d",
                               is_initiator, &rfc_cb.port.rfc_mcb[j], j);

            p_mcb->cmd_q = fixed_queue_new(SIZE_MAX);

            p_mcb->is_initiator = is_initiator;

            rfc_timer_start (p_mcb, RFC_MCB_INIT_INACT_TIMER);

            rfc_cb.rfc.last_mux = (UINT8) j;
            return (p_mcb);
        }
    }
    return (NULL);
}
コード例 #5
0
ファイル: rfc_utils.c プロジェクト: danathughes/esp-idf
/*******************************************************************************
**
** Function         rfc_release_multiplexer_channel
**
** Description      This function returns existing or new control block for
**                  the BD_ADDR.
**
*******************************************************************************/
void rfc_release_multiplexer_channel (tRFC_MCB *p_mcb)
{

    rfc_timer_stop (p_mcb);

    fixed_queue_free(p_mcb->cmd_q, osi_free_fun);

    memset (p_mcb, 0, sizeof (tRFC_MCB));
    p_mcb->state = RFC_MX_STATE_IDLE;
}
コード例 #6
0
/*******************************************************************************
**
** Function         PORT_DlcEstablishCnf
**
** Description      This function is called from the RFCOMM layer when peer
**                  acknowledges establish procedure (SABME/UA).  Send reply
**                  to the user and set state to OPENED if result was
**                  successfull.
**
*******************************************************************************/
void PORT_DlcEstablishCnf (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu, UINT16 result)
{
    tPORT  *p_port = port_find_mcb_dlci_port (p_mcb, dlci);

    RFCOMM_TRACE_EVENT ("PORT_DlcEstablishCnf dlci:%d mtu:%d result:%d", dlci, mtu, result);

    if (!p_port) {
        return;
    }

    if (result != RFCOMM_SUCCESS) {
        p_port->error = PORT_START_FAILED;
        port_rfc_closed (p_port, PORT_START_FAILED);
        return;
    }

    /* If L2CAP's mtu less then RFCOMM's take it */
    if (mtu && (mtu < p_port->peer_mtu)) {
        p_port->peer_mtu = mtu;
    }

    /* If there was an inactivity timer running for MCB stop it */
    rfc_timer_stop (p_mcb);

    if (p_port->p_callback && (p_port->ev_mask & PORT_EV_CONNECTED)) {
        (p_port->p_callback)(PORT_EV_CONNECTED, p_port->inx);
    }

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

    p_port->state = PORT_STATE_OPENED;

    /* RPN is required only if we want to tell DTE how the port should be opened */
    if ((p_port->uuid == UUID_SERVCLASS_DIALUP_NETWORKING)
            || (p_port->uuid == UUID_SERVCLASS_FAX)) {
        RFCOMM_PortNegReq (p_port->rfc.p_mcb, p_port->dlci, NULL);
    } else {
        RFCOMM_ControlReq (p_port->rfc.p_mcb, p_port->dlci, &p_port->local_ctrl);
    }
}
コード例 #7
0
/*******************************************************************************
**
** Function         PORT_DlcEstablishInd
**
** Description      This function is called from the RFCOMM layer when peer
**                  device wants to establish a new DLC.  If this is not the
**                  first message in the establishment procedure port_handle
**                  has a handle to the port control block otherwise the control
**                  block should be found based on the muliplexer channel and
**                  dlci.  The block should be allocated allocated before
**                  meaning that application already made open.
**
*******************************************************************************/
void PORT_DlcEstablishInd (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu)
{
    tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci);

    RFCOMM_TRACE_DEBUG ("PORT_DlcEstablishInd p_mcb:%p, dlci:%d mtu:%di, p_port:%p", p_mcb, dlci, mtu, p_port);
    RFCOMM_TRACE_DEBUG ("PORT_DlcEstablishInd p_mcb addr:%02x:%02x:%02x:%02x:%02x:%02x",
                        p_mcb->bd_addr[0], p_mcb->bd_addr[1], p_mcb->bd_addr[2],
                        p_mcb->bd_addr[3], p_mcb->bd_addr[4], p_mcb->bd_addr[5]);

    if (!p_port) {
        /* This can be a first request for this port */
        p_port = port_find_dlci_port (dlci);
        if (!p_port) {
            RFCOMM_DlcEstablishRsp (p_mcb, dlci, 0, RFCOMM_ERROR);
            return;
        }
        p_mcb->port_inx[dlci] = p_port->inx;
    }

    /* If L2CAP's mtu less then RFCOMM's take it */
    if (mtu && (mtu < p_port->peer_mtu)) {
        p_port->peer_mtu = mtu;
    }

    /* If there was an inactivity timer running for MCB stop it */
    rfc_timer_stop (p_mcb);

    RFCOMM_DlcEstablishRsp (p_mcb, dlci, p_port->mtu, RFCOMM_SUCCESS);

    /* This is the server side.  If application wants to know when connection */
    /* is established, thats the place */
    if (p_port->p_callback && (p_port->ev_mask & PORT_EV_CONNECTED)) {
        (p_port->p_callback)(PORT_EV_CONNECTED, p_port->inx);
    }

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

    p_port->state = PORT_STATE_OPENED;
}