示例#1
0
文件: hidh_conn.c 项目: morrey/bt_bcm
/*******************************************************************************
**
** Function         hidh_conn_disconnect
**
** Description      This function disconnects a connection.
**
** Returns          TRUE if disconnect started, FALSE if already disconnected
**
*******************************************************************************/
tHID_STATUS hidh_conn_disconnect (UINT8 dhandle)
{
    tHID_CONN *p_hcon = &hh_cb.devices[dhandle].conn;

    HIDH_TRACE_EVENT ("HID-Host disconnect");

    if ((p_hcon->ctrl_cid != 0) || (p_hcon->intr_cid != 0))
    {
        p_hcon->conn_state = HID_CONN_STATE_DISCONNECTING;

        /* Set l2cap idle timeout to 0 (so ACL link is disconnected
         * immediately after last channel is closed) */
        L2CA_SetIdleTimeoutByBdAddr(hh_cb.devices[dhandle].addr, 0, BT_TRANSPORT_BR_EDR);
        /* Disconnect both interrupt and control channels */
        if (p_hcon->intr_cid)
            L2CA_DisconnectReq (p_hcon->intr_cid);
        else if (p_hcon->ctrl_cid)
            L2CA_DisconnectReq (p_hcon->ctrl_cid);
    }
    else
    {
        p_hcon->conn_state = HID_CONN_STATE_UNUSED;
    }

    return (HID_SUCCESS);
}
示例#2
0
文件: avct_l2c.c 项目: tve/esp-idf
/*******************************************************************************
**
** Function         avct_l2c_config_cfm_cback
**
** Description      This is the L2CAP config confirm callback function.
**
**
** Returns          void
**
*******************************************************************************/
void avct_l2c_config_cfm_cback(UINT16 lcid, tL2CAP_CFG_INFO *p_cfg)
{
    tAVCT_LCB       *p_lcb;

    /* look up lcb for this channel */
    if ((p_lcb = avct_lcb_by_lcid(lcid)) != NULL) {
        AVCT_TRACE_DEBUG("avct_l2c_config_cfm_cback: 0x%x, ch_state: %d, res: %d",
                         lcid, p_lcb->ch_state, p_cfg->result);
        /* if in correct state */
        if (p_lcb->ch_state == AVCT_CH_CFG) {
            /* if result successful */
            if (p_cfg->result == L2CAP_CFG_OK) {
                /* update flags */
                p_lcb->ch_flags |= AVCT_L2C_CFG_CFM_DONE;

                /* if configuration complete */
                if (p_lcb->ch_flags & AVCT_L2C_CFG_IND_DONE) {
                    p_lcb->ch_state = AVCT_CH_OPEN;
                    avct_lcb_event(p_lcb, AVCT_LCB_LL_OPEN_EVT, NULL);
                }
            }
            /* else failure */
            else {
                AVCT_TRACE_DEBUG("ERROR avct_l2c_config_cfm_cback L2CA_DisconnectReq %d ", p_lcb->ch_state);
                /* store result value */
                p_lcb->ch_result = p_cfg->result;

                /* Send L2CAP disconnect req */
                L2CA_DisconnectReq(lcid);
            }
        }
        AVCT_TRACE_DEBUG("ch_state cfc: %d ", p_lcb->ch_state);
    }
}
/*******************************************************************************
**
** Function         mca_ccb_do_disconn
**
** Description      This function closes a control channel.
**
** Returns          void.
**
*******************************************************************************/
void mca_ccb_do_disconn (tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
{
    UNUSED(p_data);

    mca_dcb_close_by_mdl_id (p_ccb, MCA_ALL_MDL_ID);
    L2CA_DisconnectReq(p_ccb->lcid);
}
示例#4
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);
        }
    }
}
示例#5
0
/*******************************************************************************
**
** Function         rfc_mx_sm_state_connected
**
** Description      This function handles events when the multiplexer is
**                  in the CONNECTED state
**
** Returns          void
**
*******************************************************************************/
void rfc_mx_sm_state_connected (tRFC_MCB *p_mcb, UINT16 event, void *p_data)
{
    RFCOMM_TRACE_EVENT1 ("rfc_mx_sm_state_connected - evt:%d", event);

    switch (event)
    {
    case RFC_EVENT_TIMEOUT:
    case RFC_MX_EVENT_CLOSE_REQ:
        rfc_timer_start (p_mcb, RFC_DISC_TIMEOUT);
        p_mcb->state = RFC_MX_STATE_DISC_WAIT_UA;
        rfc_send_disc (p_mcb, RFCOMM_MX_DLCI);
        return;

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

    case RFC_EVENT_DISC:
        /* Reply with UA.  If initiator bring down L2CAP connection */
        /* If server wait for some time if client decide to reinitiate channel */
        rfc_send_ua (p_mcb, RFCOMM_MX_DLCI);
        if (p_mcb->is_initiator)
        {
            L2CA_DisconnectReq (p_mcb->lcid);
        }
        /* notify all ports that connection is gone */
        PORT_CloseInd (p_mcb);
        return;
    }
    RFCOMM_TRACE_EVENT2 ("RFCOMM MX ignored - evt:%d in state:%d", event, p_mcb->state);
}
示例#6
0
/*******************************************************************************
**
** Function         rfc_mx_sm_state_configure
**
** Description      This function handles events when the multiplexer in the
**                  configuration state.
**
** Returns          void
**
*******************************************************************************/
void rfc_mx_sm_state_configure (tRFC_MCB *p_mcb, UINT16 event, void *p_data)
{
    RFCOMM_TRACE_EVENT1 ("rfc_mx_sm_state_configure - 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;

    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_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);
}
示例#7
0
/*******************************************************************************
**
** Function         avdt_sec_check_complete_orig
**
** Description      The function called when Security Manager finishes
**                  verification of the service side connection
**
** Returns          void
**
*******************************************************************************/
static void avdt_sec_check_complete_orig (BD_ADDR bd_addr, tBT_TRANSPORT trasnport,
        void *p_ref_data, UINT8 res)
{
    tAVDT_CCB       *p_ccb = NULL;
    tL2CAP_CFG_INFO cfg;
    tAVDT_TC_TBL    *p_tbl;
    UNUSED(p_ref_data);

    AVDT_TRACE_DEBUG("avdt_sec_check_complete_orig res: %d\n", res);
    if (bd_addr) {
        p_ccb = avdt_ccb_by_bd(bd_addr);
    }
    p_tbl = avdt_ad_tc_tbl_by_st(AVDT_CHAN_SIG, p_ccb, AVDT_AD_ST_SEC_INT);
    if (p_tbl == NULL) {
        return;
    }

    if ( res == BTM_SUCCESS ) {
        /* set channel state */
        p_tbl->state = AVDT_AD_ST_CFG;

        /* Send L2CAP config req */
        memset(&cfg, 0, sizeof(tL2CAP_CFG_INFO));
        cfg.mtu_present = TRUE;
        cfg.mtu = p_tbl->my_mtu;
        cfg.flush_to_present = TRUE;
        cfg.flush_to = p_tbl->my_flush_to;
        L2CA_ConfigReq(p_tbl->lcid, &cfg);
    } else {
        L2CA_DisconnectReq (p_tbl->lcid);
        avdt_ad_tc_close_ind(p_tbl, L2CAP_CONN_SECURITY_BLOCK);
    }
}
/*******************************************************************************
**
** Function         mca_l2c_config_cfm_cback
**
** Description      This is the L2CAP config confirm callback function.
**
**
** Returns          void
**
*******************************************************************************/
void mca_l2c_config_cfm_cback(UINT16 lcid, tL2CAP_CFG_INFO *p_cfg)
{
    tMCA_TC_TBL    *p_tbl;

    /* look up info for this channel */
    if ((p_tbl = mca_tc_tbl_by_lcid(lcid)) != NULL)
    {
        /* if in correct state */
        if (p_tbl->state == MCA_TC_ST_CFG)
        {
            /* if result successful */
            if (p_cfg->result == L2CAP_CONN_OK)
            {
                /* update cfg_flags */
                p_tbl->cfg_flags |= MCA_L2C_CFG_CFM_DONE;

                /* if configuration complete */
                if (p_tbl->cfg_flags & MCA_L2C_CFG_IND_DONE)
                {
                    mca_tc_open_ind(p_tbl);
                }
            }
            /* else failure */
            else
            {
                /* Send L2CAP disconnect req */
                L2CA_DisconnectReq(lcid);
            }
        }
    }
}
示例#9
0
// add by stanley : 2006-0719
void L2CA_TesterDisconnect(U8 cid)
{
    L2capDisconnectRequest parms;
    if(cid == 0x00)
        parms.cid = L2CAPTS(cid);
    else
        parms.cid = cid;
    bt_trace(TRACE_GROUP_1,L2CAP_TESTER_DISCONN_REQ);
    L2CA_DisconnectReq(&parms);
}
示例#10
0
/*******************************************************************************
**
** 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);
}
示例#11
0
/*******************************************************************************
**
** Function         mca_dcb_do_disconn
**
** Description      This function closes a data channel.
**
** Returns          void.
**
*******************************************************************************/
void mca_dcb_do_disconn (tMCA_DCB *p_dcb, tMCA_DCB_EVT *p_data)
{
    tMCA_CLOSE  close;
    UNUSED(p_data);

    if ((p_dcb->lcid == 0) || (L2CA_DisconnectReq(p_dcb->lcid) == FALSE))
    {
        close.param  = MCA_INT;
        close.reason = L2CAP_DISC_OK;
        close.lcid   = 0;
        mca_dcb_event(p_dcb, MCA_DCB_TC_CLOSE_EVT, (tMCA_DCB_EVT *) &close);
    }
}
示例#12
0
/*******************************************************************************
**
** 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);
}
/*******************************************************************************
**
** Function         hidh_conn_disconnect
**
** Description      This function disconnects a connection.
**
** Returns          TRUE if disconnect started, FALSE if already disconnected
**
*******************************************************************************/
tHID_STATUS hidh_conn_disconnect (UINT8 dhandle)
{
    tHID_CONN *p_hcon = &hh_cb.devices[dhandle].conn;

    HIDH_TRACE_EVENT0 ("HID-Host disconnect");

    if ((p_hcon->ctrl_cid != 0) || (p_hcon->intr_cid != 0))
    {
        p_hcon->conn_state = HID_CONN_STATE_DISCONNECTING;

        /* Disconnect both interrupt and control channels */
        if (p_hcon->intr_cid)
            L2CA_DisconnectReq (p_hcon->intr_cid);

        if (p_hcon->ctrl_cid)
            L2CA_DisconnectReq (p_hcon->ctrl_cid);
    }
    else
    {
        p_hcon->conn_state = HID_CONN_STATE_UNUSED;
    }

    return (HID_SUCCESS);
}
/*******************************************************************************
**
** Function         sdp_conn_timeout
**
** Description      This function processes a timeout. Currently, we simply send
**                  a disconnect request to L2CAP.
**
** Returns          void
**
*******************************************************************************/
void sdp_conn_timeout (tCONN_CB*p_ccb)
{
    SDP_TRACE_EVENT2 ("SDP - CCB timeout in state: %d  CID: 0x%x",
                      p_ccb->con_state, p_ccb->connection_id);

    L2CA_DisconnectReq (p_ccb->connection_id);
#if SDP_CLIENT_ENABLED == TRUE
    /* Tell the user if he has a callback */
    if (p_ccb->p_cb)
        (*p_ccb->p_cb) (SDP_CONN_FAILED);
    else if (p_ccb->p_cb2)
        (*p_ccb->p_cb2) (SDP_CONN_FAILED, p_ccb->user_data);
#endif
    sdpu_release_ccb (p_ccb);
}
示例#15
0
/*******************************************************************************
**
** Function         gatt_l2cif_config_cfm_cback
**
** Description      This is the L2CAP config confirm callback function.
**
**
** Returns          void
**
*******************************************************************************/
void gatt_l2cif_config_cfm_cback(UINT16 lcid, tL2CAP_CFG_INFO *p_cfg)
{
    tGATT_TCB       *p_tcb;
    tGATTS_SRV_CHG  *p_srv_chg_clt=NULL;

    /* look up clcb for this channel */
    if ((p_tcb = gatt_find_tcb_by_cid(lcid)) != NULL)
    {
        /* if in correct state */
        if ( gatt_get_ch_state(p_tcb) == GATT_CH_CFG)
        {
            /* if result successful */
            if (p_cfg->result == L2CAP_CFG_OK)
            {
                /* update flags */
                p_tcb->ch_flags |= GATT_L2C_CFG_CFM_DONE;

                /* if configuration complete */
                if (p_tcb->ch_flags & GATT_L2C_CFG_IND_DONE)
                {
                    gatt_set_ch_state(p_tcb, GATT_CH_OPEN);

                    if ((p_srv_chg_clt = gatt_is_bda_in_the_srv_chg_clt_list(p_tcb->peer_bda)) != NULL)
                    {
                        gatt_chk_srv_chg(p_srv_chg_clt);
                    }
                    else
                    {
                        if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda))
                            gatt_add_a_bonded_dev_for_srv_chg(p_tcb->peer_bda);
                    }

                    /* send callback */
                    gatt_send_conn_cback(p_tcb);
                }
            }
            /* else failure */
            else
            {
                /* Send L2CAP disconnect req */
                L2CA_DisconnectReq(lcid);
            }
        }
    }
}
示例#16
0
文件: avct_l2c.c 项目: tve/esp-idf
/*******************************************************************************
**
** Function         avct_l2c_connect_cfm_cback
**
** Description      This is the L2CAP connect confirm callback function.
**
**
** Returns          void
**
*******************************************************************************/
void avct_l2c_connect_cfm_cback(UINT16 lcid, UINT16 result)
{
    tAVCT_LCB       *p_lcb;
    tL2CAP_CFG_INFO cfg;

    /* look up lcb for this channel */
    if ((p_lcb = avct_lcb_by_lcid(lcid)) != NULL) {
        AVCT_TRACE_DEBUG("avct_l2c_connect_cfm_cback lcid:0x%x result: %d ch_state: %d, conflict_lcid:0x%x",
                         lcid, result, p_lcb->ch_state, p_lcb->conflict_lcid);
        /* if in correct state */
        if (p_lcb->ch_state == AVCT_CH_CONN) {
            /* if result successful */
            if (result == L2CAP_CONN_OK) {
                /* set channel state */
                p_lcb->ch_state = AVCT_CH_CFG;

                /* Send L2CAP config req */
                memset(&cfg, 0, sizeof(tL2CAP_CFG_INFO));
                cfg.mtu_present = TRUE;
                cfg.mtu = avct_cb.mtu;
                L2CA_ConfigReq(lcid, &cfg);
                AVCT_TRACE_DEBUG("avct_l2c snd Cfg Req");
            }
            /* else failure */
            else {
                AVCT_TRACE_DEBUG("avct_l2c_connect_cfm_cback conflict_lcid:0x%x", p_lcb->conflict_lcid);
                if (p_lcb->conflict_lcid == lcid) {
                    p_lcb->conflict_lcid = 0;
                } else {
                    avct_lcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, (tAVCT_LCB_EVT *) &result);
                }
            }
        } else if (p_lcb->conflict_lcid == lcid) {
            /* we must be in AVCT_CH_CFG state for the ch_lcid channel */
            AVCT_TRACE_DEBUG("avct_l2c_connect_cfm_cback ch_state: %d, conflict_lcid:0x%x", p_lcb->ch_state, p_lcb->conflict_lcid);
            if (result == L2CAP_CONN_OK) {
                /* just in case the peer also accepts our connection - Send L2CAP disconnect req */
                L2CA_DisconnectReq(lcid);
            }
            p_lcb->conflict_lcid = 0;
        }
        AVCT_TRACE_DEBUG("ch_state cnc: %d ", p_lcb->ch_state);
    }
}
示例#17
0
/*******************************************************************************
**
** Function         gatt_l2c_connect_cfm_cback
**
** Description      This is the L2CAP connect confirm callback function.
**
**
** Returns          void
**
*******************************************************************************/
static void gatt_l2cif_connect_cfm_cback(UINT16 lcid, UINT16 result)
{
    tGATT_TCB       *p_tcb;
    tL2CAP_CFG_INFO cfg;

    /* look up clcb for this channel */
    if ((p_tcb = gatt_find_tcb_by_cid(lcid)) != NULL)
    {
        GATT_TRACE_DEBUG("gatt_l2c_connect_cfm_cback result: %d ch_state: %d, lcid:0x%x", result, gatt_get_ch_state(p_tcb), p_tcb->att_lcid);

        /* if in correct state */
        if (gatt_get_ch_state(p_tcb) == GATT_CH_CONN)
        {
            /* if result successful */
            if (result == L2CAP_CONN_OK)
            {
                /* set channel state */
                gatt_set_ch_state(p_tcb, GATT_CH_CFG);

                /* Send L2CAP config req */
                memset(&cfg, 0, sizeof(tL2CAP_CFG_INFO));
                cfg.mtu_present = TRUE;
                cfg.mtu = GATT_MAX_MTU_SIZE;
                L2CA_ConfigReq(lcid, &cfg);
            }
            /* else initiating connection failure */
            else
            {
                gatt_cleanup_upon_disc(p_tcb->peer_bda, result, GATT_TRANSPORT_BR_EDR);
            }
        }
        else /* wrong state, disconnect it */
        {
            if (result == L2CAP_CONN_OK)
            {
                /* just in case the peer also accepts our connection - Send L2CAP disconnect req */
                L2CA_DisconnectReq(lcid);
            }
        }
    }
}
/*******************************************************************************
**
** Function         mca_sec_check_complete_orig
**
** Description      The function called when Security Manager finishes
**                  verification of the service side connection
**
** Returns          void
**
*******************************************************************************/
static void mca_sec_check_complete_orig (BD_ADDR bd_addr, void *p_ref_data, UINT8 res)
{
    tMCA_TC_TBL     *p_tbl = (tMCA_TC_TBL *)p_ref_data;
    tL2CAP_CFG_INFO cfg;

    MCA_TRACE_DEBUG1("mca_sec_check_complete_orig res: %d", res);

    if ( res == BTM_SUCCESS )
    {
        /* set channel state */
        p_tbl->state = MCA_TC_ST_CFG;

        /* Send L2CAP config req */
        mca_set_cfg_by_tbl (&cfg, p_tbl);
        L2CA_ConfigReq(p_tbl->lcid, &cfg);
    }
    else
    {
        L2CA_DisconnectReq (p_tbl->lcid);
        mca_tc_close_ind(p_tbl, L2CAP_CONN_SECURITY_BLOCK);
    }
}
/*******************************************************************************
**
** Function         gatt_disconnect
**
** Description      This function is called to disconnect to an ATT device.
**
** Parameter        rem_bda: remote device address to disconnect from.
**
** Returns          TRUE: if connection found and to be disconnected; otherwise
**                  return FALSE.
**
*******************************************************************************/
BOOLEAN gatt_disconnect (BD_ADDR rem_bda)
{
    tGATT_TCB           *p_tcb = gatt_find_tcb_by_addr(rem_bda);
    BOOLEAN             ret = FALSE;
    tGATT_CH_STATE      ch_state;
    GATT_TRACE_DEBUG0 ("gatt_disconnect ");

    if (p_tcb != NULL)
    {
        ret = TRUE;
        if ( (ch_state = gatt_get_ch_state(p_tcb)) != GATT_CH_CLOSING )
        {
            if (p_tcb->att_lcid == L2CAP_ATT_CID)
            {
                if (ch_state == GATT_CH_OPEN)
                {
                    /* only LCB exist between remote device and local */
                    ret = L2CA_RemoveFixedChnl (L2CAP_ATT_CID, rem_bda);
                }
                else
                {
                    gatt_set_ch_state(p_tcb, GATT_CH_CLOSING);
                    ret = L2CA_CancelBleConnectReq (rem_bda);
                }
            }
            else
            {
                ret = L2CA_DisconnectReq(p_tcb->att_lcid);
            }
        }
        else
        {
            GATT_TRACE_DEBUG0 ("gatt_disconnect already in closing state");
        }
    }

    return ret;
}
示例#20
0
文件: hidh_conn.c 项目: morrey/bt_bcm
/*******************************************************************************
**
** Function         hidh_l2cif_disconnect_cfm
**
** Description      This function handles a disconnect confirm event from L2CAP.
**
** Returns          void
**
*******************************************************************************/
static void hidh_l2cif_disconnect_cfm (UINT16 l2cap_cid, UINT16 result)
{
    UINT8 dhandle;
    tHID_CONN    *p_hcon = NULL;
    UNUSED(result);

    /* Find CCB based on CID */
    if( (dhandle = find_conn_by_cid(l2cap_cid)) < HID_HOST_MAX_DEVICES )
        p_hcon = &hh_cb.devices[dhandle].conn;

    if (p_hcon == NULL)
    {
        HIDH_TRACE_WARNING ("HID-Host Rcvd L2CAP disc cfm, unknown CID: 0x%x", l2cap_cid);
        return;
    }

    HIDH_TRACE_EVENT ("HID-Host Rcvd L2CAP disc cfm, CID: 0x%x", l2cap_cid);

    if (l2cap_cid == p_hcon->ctrl_cid)
        p_hcon->ctrl_cid = 0;
    else
    {
        p_hcon->intr_cid = 0;
        if (p_hcon->ctrl_cid)
        {
            HIDH_TRACE_EVENT ("HID-Host Initiating L2CAP Ctrl disconnection");
            L2CA_DisconnectReq (p_hcon->ctrl_cid);
        }
    }

    if ((p_hcon->ctrl_cid == 0) && (p_hcon->intr_cid == 0))
    {
        hh_cb.devices[dhandle].state = HID_DEV_NO_CONN;
        p_hcon->conn_state = HID_CONN_STATE_UNUSED;
        HIDH_TRACE_EVENT ("HID-Host: disconnect cfm, reason = %d", p_hcon->disc_reason);
        hh_cb.callback( dhandle, hh_cb.devices[dhandle].addr, HID_HDEV_EVT_CLOSE, p_hcon->disc_reason, NULL ) ;
    }
}
示例#21
0
文件: avdt_ad.c 项目: Exchizz/esp-idf
/*******************************************************************************
**
** Function         avdt_ad_close_req
**
** Description      This function is called by a CCB or SCB to close a
**                  transport channel.  The function looks up the LCID for the
**                  channel and calls L2CA_DisconnectReq().
**
**
** Returns          Nothing.
**
*******************************************************************************/
void avdt_ad_close_req(UINT8 type, tAVDT_CCB *p_ccb, tAVDT_SCB *p_scb)
{
    UINT8           tcid;
    tAVDT_TC_TBL    *p_tbl;

    p_tbl = avdt_ad_tc_tbl_by_type(type, p_ccb, p_scb);
    AVDT_TRACE_DEBUG("avdt_ad_close_req state: %d\n", p_tbl->state);

    switch (p_tbl->state) {
    case AVDT_AD_ST_UNUSED:
        /* probably for reporting */
        break;
    case AVDT_AD_ST_ACP:
        /* if we're listening on this channel, send ourselves a close ind */
        avdt_ad_tc_close_ind(p_tbl, 0);
        break;
    default:
        /* get tcid from type, scb */
        tcid = avdt_ad_type_to_tcid(type, p_scb);

        /* call l2cap disconnect req */
        L2CA_DisconnectReq(avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][tcid].lcid);
    }
}
static BOOLEAN L2cap_DisconnectReq (UINT16 cid)
{
    BTIF_TRACE_DEBUG("L2cap_DisconnectReq:: cid=%d", cid);
    return L2CA_DisconnectReq(cid);
}
示例#23
0
/*******************************************************************************
**
** Function         rfc_mx_sm_state_wait_conn_cnf
**
** Description      This function handles events when the multiplexer is
**                  waiting for Connection Confirm from L2CAP.
**
** Returns          void
**
*******************************************************************************/
void rfc_mx_sm_state_wait_conn_cnf (tRFC_MCB *p_mcb, UINT16 event, void *p_data)
{
    RFCOMM_TRACE_EVENT1 ("rfc_mx_sm_state_wait_conn_cnf - evt:%d", event);
    switch (event)
    {
    case RFC_MX_EVENT_START_REQ:
        RFCOMM_TRACE_ERROR2 ("Mx error state %d event %d", p_mcb->state, event);
        return;

    /* There is some new timing so that Config Ind comes before security is completed
       so we are still waiting fo the confirmation. */
    case RFC_MX_EVENT_CONF_IND:
        rfc_mx_conf_ind (p_mcb, (tL2CAP_CFG_INFO *)p_data);
        return;

    case RFC_MX_EVENT_CONN_CNF:
        if (*((UINT16 *)p_data) != L2CAP_SUCCESS)
        {
            p_mcb->state = RFC_MX_STATE_IDLE;

            PORT_StartCnf (p_mcb, *((UINT16 *)p_data));
            return;
        }
        p_mcb->state = RFC_MX_STATE_CONFIGURE;
        rfc_mx_send_config_req (p_mcb);
        return;

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

    case RFC_EVENT_TIMEOUT:
        p_mcb->state = RFC_MX_STATE_IDLE;
        L2CA_DisconnectReq (p_mcb->lcid);

        /* we gave up outgoing connection request then try peer's request */
        if (p_mcb->pending_lcid)
        {
            UINT16 i;
            UINT8  idx;

            RFCOMM_TRACE_DEBUG2 ("RFCOMM MX retry as acceptor in collision case - evt:%d in state:%d", event, p_mcb->state);

            rfc_save_lcid_mcb (NULL, p_mcb->lcid);
            p_mcb->lcid = p_mcb->pending_lcid;
            rfc_save_lcid_mcb (p_mcb, p_mcb->lcid);

            p_mcb->is_initiator = FALSE;

            /* update direction bit */
            for (i = 0; i < RFCOMM_MAX_DLCI; i += 2)
            {
                if ((idx = p_mcb->port_inx[i]) != 0)
                {
                    p_mcb->port_inx[i] = 0;
                    p_mcb->port_inx[i+1] = idx;
                    rfc_cb.port.port[idx - 1].dlci += 1;
                    RFCOMM_TRACE_DEBUG2 ("RFCOMM MX - DLCI:%d -> %d", i, rfc_cb.port.port[idx - 1].dlci);
                }
            }

            rfc_mx_sm_execute (p_mcb, RFC_MX_EVENT_CONN_IND, &(p_mcb->pending_id));
        }
        else
        {
            PORT_CloseInd (p_mcb);
        }
        return;
    }
    RFCOMM_TRACE_EVENT2 ("RFCOMM MX ignored - evt:%d in state:%d", event, p_mcb->state);
}
/*******************************************************************************
**
** Function         sdp_disconnect
**
** Description      This function disconnects a connection.
**
** Returns          void
**
*******************************************************************************/
void sdp_disconnect (tCONN_CB*p_ccb, UINT16 reason)
{
#if (defined(SDP_BROWSE_PLUS) && SDP_BROWSE_PLUS == TRUE)

    /* If we are browsing for multiple UUIDs ... */
    if ((p_ccb->con_state == SDP_STATE_CONNECTED)
            && (p_ccb->con_flags & SDP_FLAGS_IS_ORIG)
            && ((reason == SDP_SUCCESS) || (reason == SDP_NO_RECS_MATCH)))
    {
        /* If the browse found something, do no more searching */
        if ((p_ccb->cur_uuid_idx == 0) && (p_ccb->p_db->p_first_rec))
            p_ccb->cur_uuid_idx = p_ccb->p_db->num_uuid_filters;

        while (++p_ccb->cur_uuid_idx < p_ccb->p_db->num_uuid_filters)
        {
            /* Check we have not already found the UUID (maybe through browse) */
            if ((p_ccb->p_db->uuid_filters[p_ccb->cur_uuid_idx].len == 2)
                    && (SDP_FindServiceInDb (p_ccb->p_db,
                                             p_ccb->p_db->uuid_filters[p_ccb->cur_uuid_idx].uu.uuid16,
                                             NULL)))
                continue;

            if ((p_ccb->p_db->uuid_filters[p_ccb->cur_uuid_idx].len > 2)
                    && (SDP_FindServiceUUIDInDb (p_ccb->p_db,
                                                 &p_ccb->p_db->uuid_filters[p_ccb->cur_uuid_idx], NULL)))
                continue;

            p_ccb->cur_handle = 0;

            SDP_TRACE_EVENT1 ("SDP - looking for for more,  CID: 0x%x",
                              p_ccb->connection_id);

            sdp_disc_connected (p_ccb);
            return;
        }
    }

    if ((reason == SDP_NO_RECS_MATCH) && (p_ccb->p_db->p_first_rec))
        reason = SDP_SUCCESS;

#endif

    SDP_TRACE_EVENT1 ("SDP - disconnect  CID: 0x%x", p_ccb->connection_id);

    /* Check if we have a connection ID */
    if (p_ccb->connection_id != 0)
    {
        L2CA_DisconnectReq (p_ccb->connection_id);
        p_ccb->disconnect_reason = reason;
    }

    /* If at setup state, we may not get callback ind from L2CAP */
    /* Call user callback immediately */
    if (p_ccb->con_state == SDP_STATE_CONN_SETUP)
    {
        /* Tell the user if he has a callback */
        if (p_ccb->p_cb)
            (*p_ccb->p_cb) (reason);
        else if (p_ccb->p_cb2)
            (*p_ccb->p_cb2) (reason, p_ccb->user_data);

        sdpu_release_ccb (p_ccb);
    }

}
示例#25
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);
}
示例#26
0
void l2captester_handler(ilm_struct *ilm_ptr)
{
    char *string;
    bt_test_cmd_struct *test_msg;
		if (ilm_ptr->msg_id == MSG_ID_BT_TEST_CMD_REQ)    	
    {
        test_msg = ((bt_test_cmd_struct *)ilm_ptr->local_para_ptr);    
        string = (char *)test_msg->string;    
        if(strncmp(string, "init",4)==0)
        {
            l2capTesterInit();
        }
        else if(strncmp(string, "senddata",8)==0)
        {
            L2capSendData();
        }        
        else if(strncmp(string, "conn",4)==0)
        {
            U8 bd_addr[6];
            L2capConnectRequest parms;
            
            memset(bd_addr, 0, 6);
            if(!l2capTester_get_bdaddr_from_string(bd_addr, string+4))
            {
                return;
            }    		
            memcpy((U8 *)parms.bd_addr, (U8 *)bd_addr, 6);
            L2CA_ConnectReq(&parms);
        }    
        else if(strncmp(string, "disconn",7)==0)
        {
            L2capDisconnectRequest parms;
            parms.cid = L2CAPTS(cid);
            L2CA_DisconnectReq(&parms);
        }     
        else if(strncmp(string, "info",4)==0)
        {
            L2capInfoRequest parms;
            U8 bd_addr[6];
            
            memset(bd_addr, 0, 6);
            if(!l2capTester_get_bdaddr_from_string(bd_addr, string+4))
            {
                return;
            }    		
            memcpy((U8 *)parms.bd_addr, (U8 *)bd_addr, 6);
            parms.info_type = 0x0002;
            L2CA_InfoReq(&parms);
        }     
        else if(strncmp(string, "echo",4)==0)
        {
            L2capEchoRequest parms;
            U8 bd_addr[6];
            
            memset(bd_addr, 0, 6);
            if(!l2capTester_get_bdaddr_from_string(bd_addr, string+4))
            {
                return;
            }    		
            memcpy((U8 *)parms.bd_addr, (U8 *)bd_addr, 6);
            L2CA_EchoReq(&parms);
        }     
        else if(strncmp(string, "encry",5)==0)
        {
            bt_bm_write_authentication_mode_req_struct ptr;

            ptr.mode = BTBM_AUTHENTICATION_ENABLE_LEVEL3_ENCRYPT_ON;
            BTBMGapSetAuthenticationMode(TRUE, &ptr); 
        }             
#if L2CAP_NUM_GROUPS > 0
        else if(strncmp(string, "groupreq",8)==0)
        {
            L2capGroupAddr parms;
            U8 bd_addr[6];
            
            bt_trace(TRACE_GROUP_1,GROUP_ADD_REQUEST);
            memset(bd_addr, 0, 6);
            if(!l2capTester_get_bdaddr_from_string(bd_addr, string+8))
            {
                return;
            }    		
            memcpy((U8 *)parms.bd_addr, (U8 *)bd_addr, 6);
            L2CA_AddGroup(&parms);
        }   
        else if(strncmp(string, "grouprem",8)==0)
        {
            L2capGroupAddr parms;
            U8 bd_addr[6];
            
            bt_trace(TRACE_GROUP_1,GROUP_REMOVE_REQUEST);
            memset(bd_addr, 0, 6);
            if(!l2capTester_get_bdaddr_from_string(bd_addr, string+8))
            {
                return;
            }    		
            memcpy((U8 *)parms.bd_addr, (U8 *)bd_addr, 6);
            L2CA_RemoveGroup(&parms);
        }   
        else if(strncmp(string, "sendgroupdata",13)==0)
        {
            bt_trace(TRACE_GROUP_1,SEND_GROUP_DATA);
            L2CA_GroupDataReq();
        }
        else if(strncmp(string, "sendunidata",11)==0)
        {
            bt_trace(TRACE_GROUP_1,SEND_GROUP_DATA);
            L2CA_UniCastDataReq();
        }
        else if(strncmp(string, "setencry", 8)==0)
        {
            Report(("set encryption on"));
            BTBMGapSetEncryptionOn();        
        }
#endif
    }
}