/******************************************************************************* ** ** Function mca_sec_check_complete_term ** ** Description The function called when Security Manager finishes ** verification of the service side connection ** ** Returns void ** *******************************************************************************/ static void mca_sec_check_complete_term (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; tL2CAP_ERTM_INFO ertm_info; MCA_TRACE_DEBUG1("mca_sec_check_complete_term res: %d", res); if ( res == BTM_SUCCESS ) { MCA_TRACE_DEBUG2 ("lcid:x%x id:x%x", p_tbl->lcid, p_tbl->id); /* Set the FCR options: control channel mandates ERTM */ ertm_info.preferred_mode = mca_l2c_fcr_opts_def.mode; ertm_info.allowed_modes = L2CAP_FCR_CHAN_OPT_ERTM; ertm_info.user_rx_pool_id = MCA_USER_RX_POOL_ID; ertm_info.user_tx_pool_id = MCA_USER_TX_POOL_ID; ertm_info.fcr_rx_pool_id = MCA_FCR_RX_POOL_ID; ertm_info.fcr_tx_pool_id = MCA_FCR_TX_POOL_ID; /* Send response to the L2CAP layer. */ L2CA_ErtmConnectRsp (bd_addr, p_tbl->id, p_tbl->lcid, L2CAP_CONN_OK, L2CAP_CONN_OK, &ertm_info); /* 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(p_tbl->lcid, &cfg); } else { L2CA_ConnectRsp (bd_addr, p_tbl->id, p_tbl->lcid, L2CAP_CONN_SECURITY_BLOCK, L2CAP_CONN_OK); mca_tc_close_ind(p_tbl, L2CAP_CONN_SECURITY_BLOCK); } }
/******************************************************************************* ** ** 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); } }
static BOOLEAN L2cap_ErtmConnectRsp (BD_ADDR p_bd_addr, UINT8 id, UINT16 lcid, UINT16 result, UINT16 status, tL2CAP_ERTM_INFO *p_ertm_info) { if (!L2CA_ErtmConnectRsp (p_bd_addr, id, lcid, result, status, p_ertm_info)) { BTIF_TRACE_DEBUG("L2CA_ErtmConnectRsp:: error "); return BT_STATUS_FAIL; } return BT_STATUS_SUCCESS; }
/******************************************************************************* ** ** Function mca_l2c_cconn_ind_cback ** ** Description This is the L2CAP connect indication callback function. ** ** Returns void ** *******************************************************************************/ void mca_l2c_cconn_ind_cback(BD_ADDR bd_addr, UINT16 lcid, UINT16 psm, UINT8 id) { tMCA_HANDLE handle = mca_handle_by_cpsm(psm); tMCA_CCB *p_ccb; tMCA_TC_TBL *p_tbl = NULL; UINT16 result = L2CAP_CONN_NO_RESOURCES; tBTM_STATUS rc; tL2CAP_ERTM_INFO ertm_info, *p_ertm_info = NULL; tL2CAP_CFG_INFO cfg; MCA_TRACE_EVENT3 ("mca_l2c_cconn_ind_cback: lcid:x%x psm:x%x id:x%x", lcid, psm, id); /* do we already have a control channel for this peer? */ if ((p_ccb = mca_ccb_by_bd(handle, bd_addr)) == NULL) { /* no, allocate ccb */ if ((p_ccb = mca_ccb_alloc(handle, bd_addr)) != NULL) { /* allocate and set up entry */ p_ccb->lcid = lcid; p_tbl = mca_tc_tbl_calloc(p_ccb); p_tbl->id = id; p_tbl->cfg_flags= MCA_L2C_CFG_CONN_ACP; /* proceed with connection */ /* Check the security */ rc = btm_sec_mx_access_request (bd_addr, psm, FALSE, BTM_SEC_PROTO_MCA, 0, &mca_sec_check_complete_term, p_tbl); if (rc == BTM_CMD_STARTED) { /* Set the FCR options: control channel mandates ERTM */ ertm_info.preferred_mode = mca_l2c_fcr_opts_def.mode; ertm_info.allowed_modes = L2CAP_FCR_CHAN_OPT_ERTM; ertm_info.user_rx_pool_id = MCA_USER_RX_POOL_ID; ertm_info.user_tx_pool_id = MCA_USER_TX_POOL_ID; ertm_info.fcr_rx_pool_id = MCA_FCR_RX_POOL_ID; ertm_info.fcr_tx_pool_id = MCA_FCR_TX_POOL_ID; p_ertm_info = &ertm_info; result = L2CAP_CONN_PENDING; } else result = L2CAP_CONN_OK; } /* deal with simultaneous control channel connect case */ } /* else reject their connection */ if (!p_tbl || (p_tbl->state != MCA_TC_ST_CFG)) { /* Send L2CAP connect rsp */ L2CA_ErtmConnectRsp (bd_addr, id, lcid, result, L2CAP_CONN_OK, p_ertm_info); /* if result ok, proceed with connection and send L2CAP config req */ if (result == L2CAP_CONN_OK) { /* 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); } } }