/******************************************************************************* ** ** Function gatt_l2cif_disconnect_ind_cback ** ** Description This is the L2CAP disconnect indication callback function. ** ** ** Returns void ** *******************************************************************************/ void gatt_l2cif_disconnect_ind_cback(UINT16 lcid, BOOLEAN ack_needed) { tGATT_TCB *p_tcb; UINT16 reason; /* look up clcb for this channel */ if ((p_tcb = gatt_find_tcb_by_cid(lcid)) != NULL) { if (ack_needed) { /* send L2CAP disconnect response */ L2CA_DisconnectRsp(lcid); } if (gatt_is_bda_in_the_srv_chg_clt_list(p_tcb->peer_bda) == NULL) { if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda)) gatt_add_a_bonded_dev_for_srv_chg(p_tcb->peer_bda); } /* if ACL link is still up, no reason is logged, l2cap is disconnect from peer */ if ((reason = L2CA_GetDisconnectReason(p_tcb->peer_bda, p_tcb->transport)) == 0) reason = GATT_CONN_TERMINATE_PEER_USER; /* send disconnect callback */ gatt_cleanup_upon_disc(p_tcb->peer_bda, reason, GATT_TRANSPORT_BR_EDR); } }
/******************************************************************************* ** ** Function sdp_disconnect_ind ** ** Description This function handles a disconnect event from L2CAP. If ** requested to, we ack the disconnect before dropping the CCB ** ** Returns void ** *******************************************************************************/ static void sdp_disconnect_ind (UINT16 l2cap_cid, BOOLEAN ack_needed) { 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 disc, unknown CID: 0x%x", l2cap_cid); return; } if (ack_needed) L2CA_DisconnectRsp (l2cap_cid); SDP_TRACE_EVENT1 ("SDP - Rcvd L2CAP disc, CID: 0x%x", l2cap_cid); #if SDP_CLIENT_ENABLED == TRUE /* Tell the user if he has a callback */ if (p_ccb->p_cb) (*p_ccb->p_cb) ((UINT16) ((p_ccb->con_state == SDP_STATE_CONNECTED) ? SDP_SUCCESS : SDP_CONN_FAILED)); else if (p_ccb->p_cb2) (*p_ccb->p_cb2) ((UINT16) ((p_ccb->con_state == SDP_STATE_CONNECTED) ? SDP_SUCCESS : SDP_CONN_FAILED), p_ccb->user_data); #endif sdpu_release_ccb (p_ccb); }
/******************************************************************************* ** ** Function RFCOMM_DisconnectInd ** ** Description This is a callback function called by L2CAP when ** L2CA_DisconnectInd received. Dispatch event to the FSM. ** *******************************************************************************/ void RFCOMM_DisconnectInd (UINT16 lcid, BOOLEAN is_conf_needed) { tRFC_MCB *p_mcb = rfc_find_lcid_mcb (lcid); if (is_conf_needed) { L2CA_DisconnectRsp (lcid); } if (!p_mcb) { RFCOMM_TRACE_WARNING ("RFCOMM_DisconnectInd LCID:0x%x", lcid); return; } rfc_mx_sm_execute (p_mcb, RFC_MX_EVENT_DISC_IND, NULL); }
/******************************************************************************* ** ** Function avct_l2c_disconnect_ind_cback ** ** Description This is the L2CAP disconnect indication callback function. ** ** ** Returns void ** *******************************************************************************/ void avct_l2c_disconnect_ind_cback(UINT16 lcid, BOOLEAN ack_needed) { tAVCT_LCB *p_lcb; UINT16 result = AVCT_RESULT_FAIL; /* look up lcb for this channel */ if ((p_lcb = avct_lcb_by_lcid(lcid)) != NULL) { AVCT_TRACE_DEBUG("avct_l2c_disconnect_ind_cback: 0x%x, ch_state: %d", lcid, p_lcb->ch_state); if (ack_needed) { /* send L2CAP disconnect response */ L2CA_DisconnectRsp(lcid); } avct_lcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, (tAVCT_LCB_EVT *) &result); AVCT_TRACE_DEBUG("ch_state di: %d ", p_lcb->ch_state); } }
/******************************************************************************* ** ** Function avdt_l2c_disconnect_ind_cback ** ** Description This is the L2CAP disconnect indication callback function. ** ** ** Returns void ** *******************************************************************************/ void avdt_l2c_disconnect_ind_cback(UINT16 lcid, BOOLEAN ack_needed) { tAVDT_TC_TBL *p_tbl; UINT16 disc_rsn = AVDT_DISC_RSN_NORMAL; AVDT_TRACE_DEBUG("avdt_l2c_disconnect_ind_cback lcid: %d, ack_needed: %d\n", lcid, ack_needed); /* look up info for this channel */ if ((p_tbl = avdt_ad_tc_tbl_by_lcid(lcid)) != NULL) { if (ack_needed) { /* send L2CAP disconnect response */ L2CA_DisconnectRsp(lcid); } else { disc_rsn = AVDT_DISC_RSN_ABNORMAL; } avdt_ad_tc_close_ind(p_tbl, disc_rsn); } }
/******************************************************************************* ** ** Function mca_l2c_disconnect_ind_cback ** ** Description This is the L2CAP disconnect indication callback function. ** ** ** Returns void ** *******************************************************************************/ void mca_l2c_disconnect_ind_cback(UINT16 lcid, BOOLEAN ack_needed) { tMCA_TC_TBL *p_tbl; UINT16 reason = L2CAP_DISC_TIMEOUT; MCA_TRACE_DEBUG2("mca_l2c_disconnect_ind_cback lcid: %d, ack_needed: %d", lcid, ack_needed); /* look up info for this channel */ if ((p_tbl = mca_tc_tbl_by_lcid(lcid)) != NULL) { if (ack_needed) { /* send L2CAP disconnect response */ L2CA_DisconnectRsp(lcid); } p_tbl->cfg_flags = MCA_L2C_CFG_DISCN_ACP; if (ack_needed) reason = L2CAP_DISC_OK; mca_tc_close_ind(p_tbl, reason); } }
/******************************************************************************* ** ** Function hidh_l2cif_disconnect_ind ** ** Description This function handles a disconnect event from L2CAP. If ** requested to, we ack the disconnect before dropping the CCB ** ** Returns void ** *******************************************************************************/ static void hidh_l2cif_disconnect_ind (UINT16 l2cap_cid, BOOLEAN ack_needed) { UINT8 dhandle; tHID_CONN *p_hcon = NULL; UINT16 disc_res = HCI_SUCCESS; UINT16 hid_close_evt_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 disc, unknown CID: 0x%x", l2cap_cid); return; } if (ack_needed) L2CA_DisconnectRsp (l2cap_cid); HIDH_TRACE_EVENT ("HID-Host Rcvd L2CAP disc, CID: 0x%x", l2cap_cid); p_hcon->conn_state = HID_CONN_STATE_DISCONNECTING; if (l2cap_cid == p_hcon->ctrl_cid) p_hcon->ctrl_cid = 0; else p_hcon->intr_cid = 0; 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; if( !ack_needed ) disc_res = btm_get_acl_disc_reason_code(); HIDH_TRACE_EVENT ("HID-Host: acl disconnect reason %d", disc_res); #if (HID_HOST_MAX_CONN_RETRY > 0) if( (disc_res == HCI_ERR_CONNECTION_TOUT || disc_res == HCI_ERR_UNSPECIFIED) && (!(hh_cb.devices[dhandle].attr_mask & HID_RECONN_INIT)) && (hh_cb.devices[dhandle].attr_mask & HID_NORMALLY_CONNECTABLE)) { hh_cb.devices[dhandle].conn_tries = 0; hh_cb.devices[dhandle].conn.timer_entry.param = (UINT32) dhandle; HIDH_TRACE_EVENT ("HID-Host: starting timer for reconnection"); btu_start_timer (&(hh_cb.devices[dhandle].conn.timer_entry), BTU_TTYPE_HID_HOST_REPAGE_TO, HID_HOST_REPAGE_WIN); hh_cb.callback( dhandle, hh_cb.devices[dhandle].addr, HID_HDEV_EVT_CLOSE, disc_res, NULL); } else #endif { /* Set reason code for HID_HDEV_EVT_CLOSE */ hid_close_evt_reason = p_hcon->disc_reason; /* If we got baseband sent HCI_DISCONNECT_COMPLETE_EVT due to security failure, then set reason to HID_ERR_AUTH_FAILED */ if ((disc_res == HCI_ERR_AUTH_FAILURE) || (disc_res == HCI_ERR_KEY_MISSING) || (disc_res == HCI_ERR_HOST_REJECT_SECURITY) || (disc_res == HCI_ERR_PAIRING_NOT_ALLOWED) || (disc_res == HCI_ERR_UNIT_KEY_USED) || (disc_res == HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED) || (disc_res == HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE) || (disc_res == HCI_ERR_REPEATED_ATTEMPTS)) { hid_close_evt_reason = HID_ERR_AUTH_FAILED; } HIDH_TRACE_EVENT ("HID-Host: disconnect ind, reason = %d", hid_close_evt_reason); hh_cb.callback( dhandle, hh_cb.devices[dhandle].addr, HID_HDEV_EVT_CLOSE, hid_close_evt_reason, NULL ) ; } } }
static BOOLEAN L2cap_DisconnectRsp (UINT16 cid) { BTIF_TRACE_DEBUG("L2cap_DisconnectRsp:: Invoked"); return L2CA_DisconnectRsp (cid); }