/******************************************************************************* ** ** Function avdt_l2c_config_ind_cback ** ** Description This is the L2CAP config indication callback function. ** ** ** Returns void ** *******************************************************************************/ void avdt_l2c_config_ind_cback(UINT16 lcid, tL2CAP_CFG_INFO *p_cfg) { tAVDT_TC_TBL *p_tbl; /* look up info for this channel */ if ((p_tbl = avdt_ad_tc_tbl_by_lcid(lcid)) != NULL) { /* store the mtu in tbl */ if (p_cfg->mtu_present) { p_tbl->peer_mtu = p_cfg->mtu; } else { p_tbl->peer_mtu = L2CAP_DEFAULT_MTU; } AVDT_TRACE_DEBUG("peer_mtu: %d, lcid: x%x\n", p_tbl->peer_mtu, lcid); /* send L2CAP configure response */ memset(p_cfg, 0, sizeof(tL2CAP_CFG_INFO)); p_cfg->result = L2CAP_CFG_OK; L2CA_ConfigRsp(lcid, p_cfg); /* if first config ind */ if ((p_tbl->cfg_flags & AVDT_L2C_CFG_IND_DONE) == 0) { /* update cfg_flags */ p_tbl->cfg_flags |= AVDT_L2C_CFG_IND_DONE; /* if configuration complete */ if (p_tbl->cfg_flags & AVDT_L2C_CFG_CFM_DONE) { avdt_ad_tc_open_ind(p_tbl); } } } }
/******************************************************************************* ** ** Function avct_l2c_config_ind_cback ** ** Description This is the L2CAP config indication callback function. ** ** ** Returns void ** *******************************************************************************/ void avct_l2c_config_ind_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_ind_cback: 0x%x, ch_state: %d", lcid, p_lcb->ch_state); /* store the mtu in tbl */ if (p_cfg->mtu_present) { p_lcb->peer_mtu = p_cfg->mtu; } else { p_lcb->peer_mtu = L2CAP_DEFAULT_MTU; } /* send L2CAP configure response */ memset(p_cfg, 0, sizeof(tL2CAP_CFG_INFO)); p_cfg->result = L2CAP_CFG_OK; L2CA_ConfigRsp(lcid, p_cfg); /* if first config ind */ if ((p_lcb->ch_flags & AVCT_L2C_CFG_IND_DONE) == 0) { /* update flags */ p_lcb->ch_flags |= AVCT_L2C_CFG_IND_DONE; /* if configuration complete */ if (p_lcb->ch_flags & AVCT_L2C_CFG_CFM_DONE) { p_lcb->ch_state = AVCT_CH_OPEN; avct_lcb_event(p_lcb, AVCT_LCB_LL_OPEN_EVT, NULL); } } AVCT_TRACE_DEBUG("ch_state cfi: %d ", p_lcb->ch_state); } }
/******************************************************************************* ** ** Function rfc_mx_conf_ind ** ** Description This function handles L2CA_ConfigInd message from the ** L2CAP. Send the L2CA_ConfigRsp message. ** *******************************************************************************/ static void rfc_mx_conf_ind (tRFC_MCB *p_mcb, tL2CAP_CFG_INFO *p_cfg) { /* Save peer L2CAP MTU if present */ /* RFCOMM adds 3-4 bytes in the beginning and 1 bytes FCS */ if (p_cfg->mtu_present) p_mcb->peer_l2cap_mtu = p_cfg->mtu - RFCOMM_MIN_OFFSET - 1; else p_mcb->peer_l2cap_mtu = L2CAP_DEFAULT_MTU - RFCOMM_MIN_OFFSET - 1; p_cfg->mtu_present = FALSE; p_cfg->flush_to_present = FALSE; p_cfg->qos_present = FALSE; p_cfg->result = L2CAP_CFG_OK; L2CA_ConfigRsp (p_mcb->lcid, p_cfg); p_mcb->peer_cfg_rcvd = TRUE; if ((p_mcb->state == RFC_MX_STATE_CONFIGURE) && p_mcb->local_cfg_sent) { 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); } } }
/******************************************************************************* ** ** Function hidh_l2cif_config_ind ** ** Description This function processes the L2CAP configuration indication ** event. ** ** Returns void ** *******************************************************************************/ static void hidh_l2cif_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg) { UINT8 dhandle; tHID_CONN *p_hcon = NULL; tHID_HOST_DEV_CTB *p_dev; /* Find CCB based on CID */ if( (dhandle = find_conn_by_cid(l2cap_cid)) < HID_HOST_MAX_DEVICES ) { p_dev = &hh_cb.devices[dhandle]; p_hcon = &hh_cb.devices[dhandle].conn; } if (p_hcon == NULL) { HIDH_TRACE_WARNING1 ("HID-Host Rcvd L2CAP cfg ind, unknown CID: 0x%x", l2cap_cid); return; } HIDH_TRACE_EVENT1 ("HID-Host Rcvd cfg ind, sent cfg cfm, CID: 0x%x", l2cap_cid); /* Remember the remote MTU size */ if ((!p_cfg->mtu_present) || (p_cfg->mtu > HID_HOST_MTU)) p_hcon->rem_mtu_size = HID_HOST_MTU; else p_hcon->rem_mtu_size = p_cfg->mtu; /* For now, always accept configuration from the other side */ p_cfg->flush_to_present = FALSE; p_cfg->mtu_present = FALSE; p_cfg->result = L2CAP_CFG_OK; L2CA_ConfigRsp (l2cap_cid, p_cfg); if (l2cap_cid == p_hcon->ctrl_cid) p_hcon->conn_flags |= HID_CONN_FLAGS_HIS_CTRL_CFG_DONE; else p_hcon->conn_flags |= HID_CONN_FLAGS_HIS_INTR_CFG_DONE; /* If all configuration is complete, change state and tell management we are up */ if (((p_hcon->conn_flags & HID_CONN_FLAGS_ALL_CONFIGURED) == HID_CONN_FLAGS_ALL_CONFIGURED) && (p_hcon->conn_state == HID_CONN_STATE_CONFIG)) { p_hcon->conn_state = HID_CONN_STATE_CONNECTED; hh_cb.devices[dhandle].state = HID_DEV_CONNECTED; hh_cb.callback( dhandle, hh_cb.devices[dhandle].addr, HID_HDEV_EVT_OPEN, 0, NULL ) ; } }
/******************************************************************************* ** ** Function gatt_l2cif_config_ind_cback ** ** Description This is the L2CAP config indication callback function. ** ** ** Returns void ** *******************************************************************************/ void gatt_l2cif_config_ind_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) { /* GATT uses the smaller of our MTU and peer's MTU */ if ( p_cfg->mtu_present && (p_cfg->mtu >= GATT_MIN_BR_MTU_SIZE && p_cfg->mtu < L2CAP_DEFAULT_MTU)) p_tcb->payload_size = p_cfg->mtu; else p_tcb->payload_size = L2CAP_DEFAULT_MTU; /* send L2CAP configure response */ memset(p_cfg, 0, sizeof(tL2CAP_CFG_INFO)); p_cfg->result = L2CAP_CFG_OK; L2CA_ConfigRsp(lcid, p_cfg); /* if first config ind */ if ((p_tcb->ch_flags & GATT_L2C_CFG_IND_DONE) == 0) { /* update flags */ p_tcb->ch_flags |= GATT_L2C_CFG_IND_DONE; /* if configuration complete */ if (p_tcb->ch_flags & GATT_L2C_CFG_CFM_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) && btm_sec_is_le_capable_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); } } } }
/******************************************************************************* ** ** Function mca_l2c_config_ind_cback ** ** Description This is the L2CAP config indication callback function. ** ** ** Returns void ** *******************************************************************************/ void mca_l2c_config_ind_cback(UINT16 lcid, tL2CAP_CFG_INFO *p_cfg) { tMCA_TC_TBL *p_tbl; UINT16 result = L2CAP_CFG_OK; /* look up info for this channel */ if ((p_tbl = mca_tc_tbl_by_lcid(lcid)) != NULL) { /* store the mtu in tbl */ if (p_cfg->mtu_present) { p_tbl->peer_mtu = p_cfg->mtu; if (p_tbl->peer_mtu < MCA_MIN_MTU) { result = L2CAP_CFG_UNACCEPTABLE_PARAMS; } } else { p_tbl->peer_mtu = L2CAP_DEFAULT_MTU; } MCA_TRACE_DEBUG3("peer_mtu: %d, lcid: x%x mtu_present:%d",p_tbl->peer_mtu, lcid, p_cfg->mtu_present); /* send L2CAP configure response */ memset(p_cfg, 0, sizeof(tL2CAP_CFG_INFO)); p_cfg->result = result; L2CA_ConfigRsp(lcid, p_cfg); /* if first config ind */ if ((p_tbl->cfg_flags & MCA_L2C_CFG_IND_DONE) == 0) { /* update cfg_flags */ p_tbl->cfg_flags |= MCA_L2C_CFG_IND_DONE; /* if configuration complete */ if (p_tbl->cfg_flags & MCA_L2C_CFG_CFM_DONE) { mca_tc_open_ind(p_tbl); } } } }
/******************************************************************************* ** ** Function sdp_config_ind ** ** Description This function processes the L2CAP configuration indication ** event. ** ** Returns void ** *******************************************************************************/ static void sdp_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg) { tCONN_CB *p_ccb; /* Find CCB based on CID */ if ((p_ccb = sdpu_find_ccb_by_cid (l2cap_cid)) == NULL) { SDP_TRACE_WARNING1 ("SDP - Rcvd L2CAP cfg ind, unknown CID: 0x%x", l2cap_cid); return; } /* Remember the remote MTU size */ if (!p_cfg->mtu_present) { /* use min(L2CAP_DEFAULT_MTU,SDP_MTU_SIZE) for GKI buffer size reasons */ p_ccb->rem_mtu_size = (L2CAP_DEFAULT_MTU > SDP_MTU_SIZE)?SDP_MTU_SIZE:L2CAP_DEFAULT_MTU; } else { if (p_cfg->mtu > SDP_MTU_SIZE) p_ccb->rem_mtu_size = SDP_MTU_SIZE; else p_ccb->rem_mtu_size = p_cfg->mtu; } /* For now, always accept configuration from the other side */ p_cfg->flush_to_present = FALSE; p_cfg->mtu_present = FALSE; p_cfg->result = L2CAP_CFG_OK; /* Check peer config request against our rfcomm configuration */ if (p_cfg->fcr_present) { /* Reject the window size if it is bigger than we want it to be */ if (p_cfg->fcr.mode != L2CAP_FCR_BASIC_MODE) { if (sdp_cb.l2cap_my_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE && p_cfg->fcr.tx_win_sz > sdp_cb.l2cap_my_cfg.fcr.tx_win_sz) { p_cfg->fcr.tx_win_sz = sdp_cb.l2cap_my_cfg.fcr.tx_win_sz; p_cfg->result = L2CAP_CFG_UNACCEPTABLE_PARAMS; SDP_TRACE_DEBUG0("sdp_config_ind(CONFIG) -> Please try again with SMALLER TX WINDOW"); } /* Reject if locally we want basic and they don't */ if (sdp_cb.l2cap_my_cfg.fcr.mode == L2CAP_FCR_BASIC_MODE) { /* Ask for a new setup */ p_cfg->fcr.mode = L2CAP_FCR_BASIC_MODE; p_cfg->result = L2CAP_CFG_UNACCEPTABLE_PARAMS; SDP_TRACE_DEBUG0("sdp_config_ind(CONFIG) -> Please try again with BASIC mode"); } /* Remain in configure state and give the peer our desired configuration */ if (p_cfg->result != L2CAP_CFG_OK) { SDP_TRACE_WARNING1 ("SDP - Rcvd cfg ind, Unacceptable Parameters sent cfg cfm, CID: 0x%x", l2cap_cid); L2CA_ConfigRsp (l2cap_cid, p_cfg); return; } } else /* We agree with peer's request */ p_cfg->fcr_present = FALSE; } L2CA_ConfigRsp (l2cap_cid, p_cfg); SDP_TRACE_EVENT1 ("SDP - Rcvd cfg ind, sent cfg cfm, CID: 0x%x", l2cap_cid); p_ccb->con_flags |= SDP_FLAGS_HIS_CFG_DONE; if (p_ccb->con_flags & SDP_FLAGS_MY_CFG_DONE) { p_ccb->con_state = SDP_STATE_CONNECTED; if (p_ccb->con_flags & SDP_FLAGS_IS_ORIG) sdp_disc_connected (p_ccb); else /* Start inactivity timer */ btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_SDP, SDP_INACT_TIMEOUT); } }
/******************************************************************************* ** ** Function hidh_l2cif_config_ind ** ** Description This function processes the L2CAP configuration indication ** event. ** ** Returns void ** *******************************************************************************/ static void hidh_l2cif_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg) { UINT8 dhandle; tHID_CONN *p_hcon = NULL; UINT32 reason; /* 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 cfg ind, unknown CID: 0x%x", l2cap_cid); return; } HIDH_TRACE_EVENT ("HID-Host Rcvd cfg ind, sent cfg cfm, CID: 0x%x", l2cap_cid); /* Remember the remote MTU size */ if ((!p_cfg->mtu_present) || (p_cfg->mtu > HID_HOST_MTU)) p_hcon->rem_mtu_size = HID_HOST_MTU; else p_hcon->rem_mtu_size = p_cfg->mtu; /* For now, always accept configuration from the other side */ p_cfg->flush_to_present = FALSE; p_cfg->mtu_present = FALSE; p_cfg->result = L2CAP_CFG_OK; L2CA_ConfigRsp (l2cap_cid, p_cfg); if (l2cap_cid == p_hcon->ctrl_cid) { p_hcon->conn_flags |= HID_CONN_FLAGS_HIS_CTRL_CFG_DONE; if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) && (p_hcon->conn_flags & HID_CONN_FLAGS_MY_CTRL_CFG_DONE)) { /* Connect interrupt channel */ p_hcon->disc_reason = HID_L2CAP_CONN_FAIL; /* Reset initial reason for CLOSE_EVT: Connection Attempt was made but failed */ if ((p_hcon->intr_cid = L2CA_ConnectReq (HID_PSM_INTERRUPT, hh_cb.devices[dhandle].addr)) == 0) { HIDH_TRACE_WARNING ("HID-Host INTR Originate failed"); reason = HID_L2CAP_REQ_FAIL ; p_hcon->conn_state = HID_CONN_STATE_UNUSED; hidh_conn_disconnect (dhandle); HIDH_TRACE_WARNING ("HID-Host: l2cap config failed, reason = %d", reason); hh_cb.callback( dhandle, hh_cb.devices[dhandle].addr, HID_HDEV_EVT_CLOSE, reason, NULL ) ; return; } else { /* Transition to the next appropriate state, waiting for connection confirm on interrupt channel. */ p_hcon->conn_state = HID_CONN_STATE_CONNECTING_INTR; } } } else p_hcon->conn_flags |= HID_CONN_FLAGS_HIS_INTR_CFG_DONE; /* If all configuration is complete, change state and tell management we are up */ if (((p_hcon->conn_flags & HID_CONN_FLAGS_ALL_CONFIGURED) == HID_CONN_FLAGS_ALL_CONFIGURED) && (p_hcon->conn_state == HID_CONN_STATE_CONFIG)) { p_hcon->conn_state = HID_CONN_STATE_CONNECTED; /* Reset disconnect reason to success, as connection successful */ p_hcon->disc_reason = HID_SUCCESS; hh_cb.devices[dhandle].state = HID_DEV_CONNECTED; hh_cb.callback( dhandle, hh_cb.devices[dhandle].addr, HID_HDEV_EVT_OPEN, 0, NULL ) ; } }
static BOOLEAN L2cap_ConfigRsp(UINT16 cid, tL2CAP_CFG_INFO *p_cfg) { BTIF_TRACE_DEBUG("L2cap_ConfigRsp:: Invoked"); return L2CA_ConfigRsp (cid, p_cfg); }