コード例 #1
0
/*******************************************************************************
**
** Function         mca_l2c_dconn_ind_cback
**
** Description      This is the L2CAP connect indication callback function.
**
**
** Returns          void
**
*******************************************************************************/
void mca_l2c_dconn_ind_cback(BD_ADDR bd_addr, UINT16 lcid, UINT16 psm, UINT8 id)
{
    tMCA_HANDLE handle = mca_handle_by_dpsm(psm);
    tMCA_CCB    *p_ccb;
    tMCA_DCB       *p_dcb;
    tMCA_TC_TBL    *p_tbl = NULL;
    UINT16          result;
    tL2CAP_CFG_INFO cfg;
    tL2CAP_ERTM_INFO *p_ertm_info = NULL, ertm_info;
    const tMCA_CHNL_CFG   *p_chnl_cfg;

    MCA_TRACE_EVENT2 ("mca_l2c_dconn_ind_cback: lcid:x%x psm:x%x ", lcid, psm);

    if (((p_ccb = mca_ccb_by_bd(handle, bd_addr)) != NULL) && /* find the CCB */
        (p_ccb->status == MCA_CCB_STAT_PENDING) &&  /* this CCB is expecting a MDL */
        (p_ccb->p_tx_req && (p_dcb = mca_dcb_by_hdl(p_ccb->p_tx_req->dcb_idx)) != NULL))
    {
        /* found the associated dcb in listening mode */
        /* proceed with connection */
        p_dcb->lcid     = lcid;
        p_tbl           = mca_tc_tbl_dalloc(p_dcb);
        p_tbl->id       = id;
        p_tbl->cfg_flags= MCA_L2C_CFG_CONN_ACP;
        p_chnl_cfg = p_dcb->p_chnl_cfg;
        /* assume that control channel has verified the security requirement */
        /* Set the FCR options: control channel mandates ERTM */
        ertm_info.preferred_mode    = p_chnl_cfg->fcr_opt.mode;
        ertm_info.allowed_modes     = (1 << p_chnl_cfg->fcr_opt.mode);
        ertm_info.user_rx_pool_id   = p_chnl_cfg->user_rx_pool_id;
        ertm_info.user_tx_pool_id   = p_chnl_cfg->user_tx_pool_id;
        ertm_info.fcr_rx_pool_id    = p_chnl_cfg->fcr_rx_pool_id;
        ertm_info.fcr_tx_pool_id    = p_chnl_cfg->fcr_tx_pool_id;
        p_ertm_info = &ertm_info;
        result = L2CAP_CONN_OK;
    }
    else
    {
        /* else we're not listening for traffic channel; reject
         * (this error code is specified by MCAP spec) */
        result = L2CAP_CONN_NO_RESOURCES;
    }

    /* Send L2CAP connect rsp */
    L2CA_ErtmConnectRsp (bd_addr, id, lcid, result, result, p_ertm_info);

    /* if result ok, proceed with connection */
    if (result == L2CAP_CONN_OK)
    {
        /* transition to configuration state */
        p_tbl->state = MCA_TC_ST_CFG;

        /* Send L2CAP config req */
        mca_set_cfg_by_tbl (&cfg, p_tbl);
        L2CA_ConfigReq(lcid, &cfg);
    }
}
コード例 #2
0
/*******************************************************************************
**
** Function         mca_ccb_hdl_rsp
**
** Description      This function is called when a MCAP response is received from
**                  the peer.  It calls the application callback function with
**                  the results.
**
** Returns          void.
**
*******************************************************************************/
void mca_ccb_hdl_rsp(tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
{
    BT_HDR  *p_pkt = &p_data->hdr;
    UINT8   *p;
    tMCA_CTRL   evt_data;
    BOOLEAN     chk_mdl = FALSE;
    tMCA_DCB    *p_dcb;
    tMCA_RESULT result = MCA_BAD_HANDLE;
    tMCA_TC_TBL *p_tbl;

    if (p_ccb->p_tx_req)
    {
        /* verify that the received response matches the sent request */
        p = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
        evt_data.hdr.op_code = *p++;
        if ((evt_data.hdr.op_code == 0) ||
                ((p_ccb->p_tx_req->op_code + 1) == evt_data.hdr.op_code))
        {
            evt_data.rsp.rsp_code = *p++;
            mca_stop_timer(p_ccb);
            BE_STREAM_TO_UINT16 (evt_data.hdr.mdl_id, p);
            if (evt_data.hdr.op_code == MCA_OP_MDL_CREATE_RSP)
            {
                evt_data.create_cfm.cfg = *p++;
                chk_mdl = TRUE;
            }
            else if (evt_data.hdr.op_code == MCA_OP_MDL_RECONNECT_RSP)
                chk_mdl = TRUE;

            if (chk_mdl)
            {
                p_dcb = mca_dcb_by_hdl(p_ccb->p_tx_req->dcb_idx);
                if (p_dcb && evt_data.rsp.rsp_code == MCA_RSP_SUCCESS)
                {
                    if (evt_data.hdr.mdl_id != p_dcb->mdl_id)
                    {
                        MCA_TRACE_ERROR ("peer's mdl_id=%d != our mdl_id=%d", evt_data.hdr.mdl_id, p_dcb->mdl_id);
                        /* change the response code to be an error */
                        if (evt_data.rsp.rsp_code == MCA_RSP_SUCCESS)
                        {
                            evt_data.rsp.rsp_code = MCA_RSP_BAD_MDL;
                            /* send Abort */
                            p_ccb->status = MCA_CCB_STAT_PENDING;
                            MCA_Abort(mca_ccb_to_hdl(p_ccb));
                        }
                    }
                    else if (p_dcb->p_chnl_cfg)
                    {
                        /* the data channel configuration is known. Proceed with data channel initiation */
                        BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_MCAP_DATA, p_ccb->sec_mask,
                                             p_ccb->data_vpsm, BTM_SEC_PROTO_MCA, p_ccb->p_tx_req->dcb_idx);
                        p_dcb->lcid = mca_l2c_open_req(p_ccb->peer_addr, p_ccb->data_vpsm, p_dcb->p_chnl_cfg);
                        if (p_dcb->lcid)
                        {
                            p_tbl = mca_tc_tbl_dalloc(p_dcb);
                            if (p_tbl)
                            {
                                p_tbl->state = MCA_TC_ST_CONN;
                                p_ccb->status = MCA_CCB_STAT_PENDING;
                                result = MCA_SUCCESS;
                            }
                        }
                    }
                    else
                    {
                        /* mark this MCL as pending and wait for MCA_DataChnlCfg */
                        p_ccb->status = MCA_CCB_STAT_PENDING;
                        result = MCA_SUCCESS;
                    }
                }

                if (result != MCA_SUCCESS && p_dcb)
                {
                    mca_dcb_dealloc(p_dcb, NULL);
                }
            } /* end of chk_mdl */

            if (p_ccb->status != MCA_CCB_STAT_PENDING)
                mca_free_buf ((void **)&p_ccb->p_tx_req);
            mca_ccb_report_event(p_ccb, evt_data.hdr.op_code, &evt_data);
        }
        /* else a bad response is received */
    }
    else
    {
        /* not expecting any response. drop it */
        MCA_TRACE_WARNING ("dropping received rsp (not expecting a response)");
    }
    GKI_freebuf (p_data);
}