diff options
Diffstat (limited to 'stack/obx/obx_l2c.c')
-rw-r--r-- | stack/obx/obx_l2c.c | 1031 |
1 files changed, 0 insertions, 1031 deletions
diff --git a/stack/obx/obx_l2c.c b/stack/obx/obx_l2c.c deleted file mode 100644 index 51226d9..0000000 --- a/stack/obx/obx_l2c.c +++ /dev/null @@ -1,1031 +0,0 @@ -/***************************************************************************** -** -** Name: obx_l2c.c -** -** Description: This OBX module interfaces to L2CAP -** -** Copyright (c) 2008-2011, Broadcom Corp., All Rights Reserved. -** Broadcom Bluetooth Core. Proprietary and confidential. -** -*****************************************************************************/ - -#include <string.h> -#include "wcassert.h" -#include "data_types.h" -#include "bt_target.h" -#include "obx_api.h" -#include "obx_int.h" -#include "l2c_api.h" -#include "l2cdefs.h" -#include "port_api.h" -#include "btu.h" -#include "btm_int.h" - -/* Configuration flags. */ -#define OBX_L2C_CFG_IND_DONE 0x01 -#define OBX_L2C_CFG_CFM_DONE 0x02 -#define OBX_L2C_SECURITY_DONE 0x04 -#define OBX_L2C_CONN_RQS_DONE 0x07 - -/* "states" used for L2CAP channel */ -#define OBX_CH_IDLE 0 /* No connection */ -#define OBX_CH_CONN 1 /* Waiting for connection confirm */ -#define OBX_CH_CFG 2 /* Waiting for configuration complete */ -#define OBX_CH_OPEN 3 /* Channel opened */ - -/* callback function declarations */ -void obx_l2c_connect_ind_cback(BD_ADDR bd_addr, UINT16 lcid, UINT16 psm, UINT8 id); -void obx_l2c_connect_cfm_cback(UINT16 lcid, UINT16 result); -void obx_l2c_config_cfm_cback(UINT16 lcid, tL2CAP_CFG_INFO *p_cfg); -void obx_l2c_config_ind_cback(UINT16 lcid, tL2CAP_CFG_INFO *p_cfg); -void obx_l2c_disconnect_ind_cback(UINT16 lcid, BOOLEAN ack_needed); -void obx_l2c_disconnect_cfm_cback(UINT16 lcid, UINT16 result); -void obx_l2c_data_ind_cback(UINT16 lcid, BT_HDR *p_buf); -void obx_l2c_congestion_ind_cback(UINT16 lcid, BOOLEAN is_congested); -tOBX_SR_SESS_CB * obx_lcb_2_sr_sess_cb(tOBX_L2C_CB *p_lcb); - -#if (OBX_SERVER_INCLUDED == TRUE) -/* L2CAP callback function structure for server */ -const tL2CAP_APPL_INFO obx_l2c_sr_appl = { - obx_l2c_connect_ind_cback, /* tL2CA_CONNECT_IND_CB */ - NULL, /* tL2CA_CONNECT_CFM_CB */ - NULL, /* tL2CA_CONNECT_PND_CB */ - obx_l2c_config_ind_cback, /* tL2CA_CONFIG_IND_CB */ - obx_l2c_config_cfm_cback, /* tL2CA_CONFIG_CFM_CB */ - obx_l2c_disconnect_ind_cback, /* tL2CA_DISCONNECT_IND_CB */ - obx_l2c_disconnect_cfm_cback, /* tL2CA_DISCONNECT_CFM_CB */ - NULL, /* tL2CA_QOS_VIOLATION_IND_CB */ - obx_l2c_data_ind_cback, /* tL2CA_DATA_IND_CB */ - obx_l2c_congestion_ind_cback, /* tL2CA_CONGESTION_STATUS_CB */ - NULL /* tL2CA_TX_COMPLETE_CB */ -}; -#endif - -#if (OBX_CLIENT_INCLUDED == TRUE) -/* L2CAP callback function structure for client */ -const tL2CAP_APPL_INFO obx_l2c_cl_appl = { - NULL, /* tL2CA_CONNECT_IND_CB */ - obx_l2c_connect_cfm_cback, /* tL2CA_CONNECT_CFM_CB */ - NULL, /* tL2CA_CONNECT_PND_CB */ - obx_l2c_config_ind_cback, /* tL2CA_CONFIG_IND_CB */ - obx_l2c_config_cfm_cback, /* tL2CA_CONFIG_CFM_CB */ - obx_l2c_disconnect_ind_cback, /* tL2CA_DISCONNECT_IND_CB */ - obx_l2c_disconnect_cfm_cback, /* tL2CA_DISCONNECT_CFM_CB */ - NULL, /* tL2CA_QOS_VIOLATION_IND_CB */ - obx_l2c_data_ind_cback, /* tL2CA_DATA_IND_CB */ - obx_l2c_congestion_ind_cback, /* tL2CA_CONGESTION_STATUS_CB */ - NULL /* tL2CA_TX_COMPLETE_CB */ -}; -#endif - -/* OBX eL2CAP default options */ -const tL2CAP_FCR_OPTS obx_l2c_fcr_opts_def = { - L2CAP_FCR_ERTM_MODE, /* Mandatory for Obex over L2CAP */ - OBX_FCR_OPT_TX_WINDOW_SIZE_BR_EDR, /* Tx window size over Bluetooth */ - OBX_FCR_OPT_MAX_TX_B4_DISCNT, /* Maximum transmissions before disconnecting */ - OBX_FCR_OPT_RETX_TOUT, /* Retransmission timeout (2 secs) */ - OBX_FCR_OPT_MONITOR_TOUT, /* Monitor timeout (12 secs) */ - L2CAP_DEFAULT_ERM_MPS /* MPS segment size */ -}; - -/******************************************************************************* -** Function obx_l2c_snd_evt -** Description Sends an L2CAP event to OBX through the BTU task. -*******************************************************************************/ -void obx_l2c_snd_evt (tOBX_L2C_CB *p_l2cb, tOBX_L2C_EVT_PARAM param, tOBX_L2C_EVT l2c_evt) -{ - BT_HDR *p_msg; - tOBX_L2C_EVT_MSG *p_evt; - UINT16 event; - - if (!p_l2cb) - return; - - p_msg = (BT_HDR*)GKI_getbuf(BT_HDR_SIZE + sizeof(tOBX_PORT_EVT)); - WC_ASSERT(p_msg); - - if (p_l2cb->handle & OBX_CL_HANDLE_MASK) - event = BT_EVT_TO_OBX_CL_L2C_MSG; - else - event = BT_EVT_TO_OBX_SR_L2C_MSG; - - p_msg->event = event; - p_msg->len = sizeof(tOBX_L2C_EVT_MSG); - p_msg->offset = 0; - p_evt = (tOBX_L2C_EVT_MSG *)(p_msg + 1); - p_evt->l2c_evt = l2c_evt; - p_evt->p_l2cb = p_l2cb; - p_evt->param = param; - - GKI_send_msg(BTU_TASK, BTU_HCI_RCV_MBOX, p_msg); -} - -#if (OBX_SERVER_INCLUDED == TRUE) -/******************************************************************************* -** -** Function obx_sr_scb_by_psm -** -** Description Find the server session control block for L2CAP. -** -** -** Returns void -** -*******************************************************************************/ -tOBX_SR_SESS_CB * obx_sr_scb_by_psm (UINT16 psm) -{ - UINT32 xx, yy; - tOBX_SR_CB *p_cb; - tOBX_SR_SESS_CB *p_scb = NULL, *p_scbt; - UINT16 port_handle; - - for (xx=0; xx<obx_cb.num_server; xx++) - { - if (obx_cb.server[xx].psm == psm) - { - p_cb = &obx_cb.server[xx]; - /* find one that has not allocated a RFCOMM port */ - for (yy=0; yy<p_cb->num_sess; yy++) - { - p_scbt = &obx_cb.sr_sess[p_cb->sess[yy]-1]; - if (p_scbt->ll_cb.comm.id == 0) - { - p_scb = p_scbt; - p_scb->ll_cb.l2c.p_close_fn = obx_close_l2c; - p_scb->ll_cb.l2c.p_send_fn = (tOBX_SEND_FN *)obx_l2c_snd_msg; - break; - } - } - - if (p_scb == NULL) - { - /* check if an RFCOMM port can be freed */ - for (yy=0; yy<p_cb->num_sess; yy++) - { - p_scbt = &obx_cb.sr_sess[p_cb->sess[yy]-1]; - if (p_scbt->ll_cb.comm.p_send_fn == (tOBX_SEND_FN *)obx_rfc_snd_msg && p_scbt->state == OBX_SS_NOT_CONNECTED) - { - port_handle = p_scbt->ll_cb.port.port_handle; - p_scbt->ll_cb.port.port_handle = 0; - p_scb = p_scbt; - p_scb->ll_cb.l2c.p_close_fn = obx_close_l2c; - p_scb->ll_cb.l2c.p_send_fn = (tOBX_SEND_FN *)obx_l2c_snd_msg; - obx_close_port(port_handle); - RFCOMM_RemoveServer(port_handle); - obx_sr_free_scb(p_scbt); - break; - } - } - } - break; - } - } - - return p_scb; -} - -/******************************************************************************* -** -** Function obx_sr_proc_l2c_evt -** -** Description This is called to process BT_EVT_TO_OBX_SR_L2C_MSG -** Process server events from L2CAP. Get the associated server control -** block. If this is a request packet, stop timer. Find the -** associated API event and save it in server control block -** (api_evt). Fill the event parameter (param). -** Call obx_ssm_event() with the associated events.If the associated -** control block is not found (maybe the target header does not -** match) or busy, compose a service unavailable response and call -** obx_l2c_snd_msg(). -** Returns void -** -*******************************************************************************/ -void obx_sr_proc_l2c_evt (tOBX_L2C_EVT_MSG *p_msg) -{ - tOBX_SR_SESS_CB *p_scb = NULL; - tOBX_L2C_CB *p_lcb; - BT_HDR *p_pkt=NULL; - tOBX_RX_HDR *p_rxh; - UINT8 opcode; - tOBX_L2C_IND *p_ind; - tL2CAP_CFG_INFO cfg; - UINT16 result = L2CAP_CONN_NO_RESOURCES; -#if (BT_USE_TRACES == TRUE) - UINT16 len; -#endif - tL2CAP_ERTM_INFO ertm_info; - tBT_UUID bt_uuid = {2, {UUID_PROTOCOL_OBEX}}; - tOBX_EVT_PARAM param; - tOBX_SR_CB *p_cb; - - if (p_msg == NULL || p_msg->p_l2cb == NULL) - return; - - if (p_msg->l2c_evt == OBX_L2C_EVT_CONN_IND) - { - memset(&cfg, 0, sizeof(tL2CAP_CFG_INFO)); - cfg.mtu_present = TRUE; - - p_ind = &p_msg->param.conn_ind; - if ((p_scb = obx_sr_scb_by_psm(p_ind->psm)) != NULL) - { - memcpy(p_scb->param.conn.peer_addr, p_ind->bd_addr, BD_ADDR_LEN); - memcpy(p_scb->peer_addr, p_ind->bd_addr, BD_ADDR_LEN); - result = L2CAP_CONN_OK; - p_lcb = &p_scb->ll_cb.l2c; - cfg.mtu = p_lcb->rx_mtu; - - cfg.fcr_present = TRUE; - cfg.fcr = obx_l2c_fcr_opts_def; - } - /* else no control channel yet, reject */ - - /* Set the FCR options: */ - ertm_info.preferred_mode = obx_l2c_fcr_opts_def.mode; - ertm_info.allowed_modes = L2CAP_FCR_CHAN_OPT_ERTM; - ertm_info.user_rx_pool_id = OBX_USER_RX_POOL_ID; - ertm_info.user_tx_pool_id = OBX_USER_TX_POOL_ID; - ertm_info.fcr_rx_pool_id = OBX_FCR_RX_POOL_ID; - ertm_info.fcr_tx_pool_id = OBX_FCR_TX_POOL_ID; - - /* Send L2CAP connect rsp */ - L2CA_CONNECT_RSP(p_ind->bd_addr, p_ind->id, p_ind->lcid, result, 0, &ertm_info, &bt_uuid); - - /* if result ok, proceed with connection */ - if (result == L2CAP_CONN_OK) - { - /* store LCID */ - p_lcb->lcid = p_ind->lcid; - obx_cb.l2c_map[p_ind->lcid - L2CAP_BASE_APPL_CID] = p_lcb->handle; - OBX_TRACE_DEBUG2("l2c_map[%d]=0x%x",p_ind->lcid - L2CAP_BASE_APPL_CID, p_lcb->handle ); - - /* transition to configuration state */ - p_lcb->ch_state = OBX_CH_CFG; - p_lcb->ch_flags = OBX_L2C_SECURITY_DONE; - - /* Send L2CAP config req */ - L2CA_CONFIG_REQ(p_ind->lcid, &cfg); - } - return; - } - - p_lcb = p_msg->p_l2cb; - p_scb = obx_lcb_2_sr_sess_cb(p_lcb); - if (p_scb == NULL) - return; - - switch (p_msg->l2c_evt) - { - case OBX_L2C_EVT_RESUME: - p_cb = &obx_cb.server[p_scb->handle - 1]; - param.ssn = p_scb->ssn; - (p_cb->p_cback) (p_scb->ll_cb.comm.handle, OBX_GET_REQ_EVT, param, p_pkt); - break; - - case OBX_L2C_EVT_CONG: - p_lcb->cong = p_msg->param.is_cong; - obx_ssm_event (p_scb, OBX_FCS_SET_SEVT, NULL); - break; - - case OBX_L2C_EVT_CLOSE: - obx_ssm_event (p_scb, OBX_PORT_CLOSE_SEVT, NULL); - break; - - case OBX_L2C_EVT_DATA_IND: - p_pkt = p_msg->param.p_pkt; - OBX_TRACE_DEBUG2("obx_sr_proc_l2c_evt len:%d, offset:%d", p_pkt->len, p_pkt->offset ); -#if (BT_USE_TRACES == TRUE) - len = p_pkt->len; - if (len > 0x20) - len = 0x20; - obxu_dump_hex ((UINT8 *)(p_pkt + 1) + p_pkt->offset, "rsp evt", len); -#endif - p_rxh = (tOBX_RX_HDR *)(p_pkt + 1); - opcode = *((UINT8 *)(p_pkt + 1) + p_pkt->offset); - memset(p_rxh, 0, sizeof(tOBX_RX_HDR)); - if (obx_verify_request (opcode, p_rxh) == OBX_BAD_SM_EVT) - { - OBX_TRACE_ERROR1("bad opcode:0x%x disconnect now", opcode ); - GKI_freebuf(p_pkt); - /* coverity [overrun-call] */ - obx_ssm_event(p_scb, OBX_TX_EMPTY_SEVT, NULL); - return; - } - p_pkt->event = obx_sm_evt_to_api_evt[p_rxh->sm_evt]; - p_pkt->layer_specific = GKI_get_buf_size(p_pkt) - BT_HDR_SIZE - p_pkt->offset - p_pkt->len; - OBX_TRACE_DEBUG3("opcode:0x%x event:%d sm_evt:%d", opcode, p_pkt->event, p_rxh->sm_evt ); - if (p_pkt->event != OBX_BAD_SM_EVT) - { - if (GKI_queue_is_empty(&p_lcb->rx_q) && (p_scb->srm & OBX_SRM_WAIT_UL) == 0) - { - obx_sr_proc_pkt (p_scb, p_pkt); - } - else - { - GKI_enqueue (&p_lcb->rx_q, p_pkt); - if (p_lcb->rx_q.count > obx_cb.max_rx_qcount) - { - p_lcb->stopped = TRUE; - L2CA_FlowControl(p_lcb->lcid, FALSE); - } - OBX_TRACE_DEBUG4 ("obx_sr_proc_l2c_evt stopped:%d state:%d rx_q.count:%d, srm:0x%x", - p_lcb->stopped, p_scb->state, p_lcb->rx_q.count, p_scb->srm ); - } - } - else - { - OBX_TRACE_ERROR0("bad SM event" ); - } - break; - } -} - -/******************************************************************************* -** -** Function obx_l2c_sr_register -** -** Description register the PSM to L2CAP. -** -** -** Returns void -** -*******************************************************************************/ -tOBX_STATUS obx_l2c_sr_register (tOBX_SR_CB *p_cb) -{ - tOBX_STATUS status = OBX_NO_RESOURCES; - - if (L2CA_REGISTER (p_cb->psm, &obx_l2c_sr_appl, AMP_AUTOSWITCH_ALLOWED|AMP_USE_AMP_IF_POSSIBLE)) - { - status = OBX_SUCCESS; - } - return status; -} -#endif - -#if (OBX_SERVER_INCLUDED == TRUE) - -/******************************************************************************* -** -** Function obx_lcb_2_sr_sess_cb -** -** Description Find the client control block for the given l2cap session. -** -** -** Returns void -** -*******************************************************************************/ -tOBX_SR_SESS_CB * obx_lcb_2_sr_sess_cb(tOBX_L2C_CB *p_lcb) -{ - UINT32 xx, yy; - tOBX_SR_CB *p_cb; - tOBX_SR_SESS_CB *p_scb = NULL; - - for (xx=0; xx<obx_cb.num_server; xx++) - { - if (obx_cb.server[xx].num_sess) - { - p_cb = &obx_cb.server[xx]; - for (yy=0; yy<p_cb->num_sess; yy++) - { - if (&(obx_cb.sr_sess[p_cb->sess[yy]-1].ll_cb.l2c) == p_lcb) - { - p_scb = &(obx_cb.sr_sess[p_cb->sess[yy]-1]); - break; - } - } - - if (p_scb) - break; - } - } - return p_scb; -} -#endif - -#if (OBX_CLIENT_INCLUDED == TRUE) -/******************************************************************************* -** -** Function obx_lcb_2_clcb -** -** Description Find the client control block for the given l2cap session. -** -** -** Returns void -** -*******************************************************************************/ -tOBX_CL_CB * obx_lcb_2_clcb(tOBX_L2C_CB *p_lcb) -{ - UINT32 xx; - tOBX_CL_CB *p_cl_cb = NULL; - - for (xx=0; xx<obx_cb.num_client; xx++) - { - if (&obx_cb.client[xx].ll_cb.l2c == p_lcb) - { - p_cl_cb = &obx_cb.client[xx]; - break; - } - } - return p_cl_cb; -} -#endif - -/******************************************************************************* -** -** Function obx_lcid_2lcb -** -** Description Given a lcid, return the associated client or server -** control block. -** -** Returns -** -*******************************************************************************/ -tOBX_L2C_CB * obx_lcid_2lcb(UINT16 lcid) -{ - tOBX_L2C_CB *p_lcb = NULL; - tOBX_HANDLE obx_handle = 0; -#if (OBX_SERVER_INCLUDED == TRUE) - tOBX_SR_CB *p_cb; -#endif - tOBX_HANDLE obx_mskd_handle; - - /* this function is called by obx_rfc_cback() only. - * assume that port_handle is within range */ - obx_handle = obx_cb.l2c_map[lcid-L2CAP_BASE_APPL_CID]; - obx_mskd_handle = obx_handle&OBX_HANDLE_MASK; - OBX_TRACE_DEBUG3("obx_lcid_2lcb lcid:0x%x obx_handle:0x%x obx_mskd_handle:0x%x", - lcid, obx_handle, obx_mskd_handle); - - if (obx_handle > 0) - { - if (obx_mskd_handle & OBX_CL_HANDLE_MASK) - { -#if (OBX_CLIENT_INCLUDED == TRUE) - obx_mskd_handle &= ~OBX_CL_HANDLE_MASK; - p_lcb = &obx_cb.client[obx_mskd_handle - 1].ll_cb.l2c; -#endif /* OBX_CLIENT_INCLUDED */ - } - else if (obx_mskd_handle < OBX_NUM_SERVERS) - { -#if (OBX_SERVER_INCLUDED == TRUE) - p_cb = &obx_cb.server[obx_mskd_handle - 1]; - p_lcb = &obx_cb.sr_sess[p_cb->sess[OBX_DEC_SESS_IND(obx_handle)]-1].ll_cb.l2c; - OBX_TRACE_DEBUG3("p_lcb lcid:0x%x sess_ind:%d, sr_sess[%d]", - p_lcb->lcid, OBX_DEC_SESS_IND(obx_handle), p_cb->sess[OBX_DEC_SESS_IND(obx_handle)]-1); -#endif /* OBX_SERVER_INCLUDED */ - } - } - - return p_lcb; -} - -/******************************************************************************* -** -** Function obx_l2c_checks_ch_flags -** -** Description This function processes the L2CAP configuration indication -** event. -** -** Returns void -** -*******************************************************************************/ -static void obx_l2c_checks_ch_flags (tOBX_L2C_CB *p_lcb) -{ - tOBX_L2C_EVT_PARAM evt_param; - - OBX_TRACE_DEBUG1 ("obx_l2c_checks_ch_flags ch_flags:0x%x ", p_lcb->ch_flags); - /* if all the required ch_flags are set, report the OPEN event now */ - if ((p_lcb->ch_flags & OBX_L2C_CONN_RQS_DONE) == OBX_L2C_CONN_RQS_DONE) - { - p_lcb->ch_state = OBX_CH_OPEN; - obx_start_timer((tOBX_COMM_CB *)p_lcb); - evt_param.is_cong = FALSE; - obx_l2c_snd_evt (p_lcb, evt_param, OBX_L2C_EVT_CONG); - } -} - -/******************************************************************************* -** -** Function obx_l2c_connect_ind_cback -** -** Description This is the L2CAP connect indication callback function. -** -** -** Returns void -** -*******************************************************************************/ -#if (OBX_SERVER_INCLUDED == TRUE) -void obx_l2c_connect_ind_cback(BD_ADDR bd_addr, UINT16 lcid, UINT16 psm, UINT8 id) -{ - tOBX_L2C_EVT_PARAM evt_param; - - obx_cb.sr_l2cb.handle = 0; /* to mark as server event */ - memcpy( evt_param.conn_ind.bd_addr, bd_addr, BD_ADDR_LEN); - evt_param.conn_ind.lcid = lcid; - evt_param.conn_ind.psm = psm; - evt_param.conn_ind.id = id; - obx_l2c_snd_evt (&obx_cb.sr_l2cb, evt_param, OBX_L2C_EVT_CONN_IND); -} -#endif /* OBX_SERVER_INCLUDED */ - -#if (OBX_CLIENT_INCLUDED == TRUE) -/******************************************************************************* -** -** Function obx_cl_proc_l2c_evt -** -** Description This is called to process BT_EVT_TO_OBX_CL_L2C_MSG -** Process client events from L2CAP. Get the associated client control -** block. If this is a response packet, stop timer. Call -** obx_csm_event() with event OK_CFM, FAIL_CFM or CONT_CFM. -** Returns void -** -*******************************************************************************/ -void obx_cl_proc_l2c_evt (tOBX_L2C_EVT_MSG *p_msg) -{ - tOBX_CL_CB *p_cl_cb = NULL; - tOBX_L2C_CB *p_l2cb; - BT_HDR *p_pkt; - tOBX_RX_HDR *p_rxh; - UINT8 opcode; - - if (p_msg == NULL || p_msg->p_l2cb == NULL) - return; - - p_l2cb = p_msg->p_l2cb; - p_cl_cb = obx_lcb_2_clcb(p_l2cb); - if (p_cl_cb == NULL) - return; - - switch (p_msg->l2c_evt) - { - case OBX_L2C_EVT_CONG: - p_msg->p_l2cb->cong = p_msg->param.is_cong; - obx_csm_event (p_cl_cb, OBX_FCS_SET_CEVT, NULL); - break; - - case OBX_L2C_EVT_CLOSE: - obx_csm_event (p_cl_cb, OBX_PORT_CLOSE_CEVT, NULL); - break; - - case OBX_L2C_EVT_DATA_IND: - p_pkt = p_msg->param.p_pkt; - p_rxh = (tOBX_RX_HDR *)(p_pkt + 1); - opcode = *((UINT8 *)(p_pkt + 1) + p_pkt->offset); - memset(p_rxh, 0, sizeof(tOBX_RX_HDR)); - obx_verify_response (opcode, p_rxh); - - OBX_TRACE_DEBUG4 ("obx_cl_proc_l2c_evt event:0x%x/0x%x state:%d srm:0x%x", p_pkt->event, p_rxh->sm_evt, p_cl_cb->state, p_cl_cb->srm ); - if (p_rxh->sm_evt != OBX_BAD_SM_EVT) - { - if (GKI_queue_is_empty(&p_l2cb->rx_q) && (p_cl_cb->srm & OBX_SRM_WAIT_UL) == 0) - { - obx_cl_proc_pkt (p_cl_cb, p_pkt); - } - else - { - GKI_enqueue (&p_l2cb->rx_q, p_pkt); - if (p_l2cb->rx_q.count > obx_cb.max_rx_qcount) - { - p_l2cb->stopped = TRUE; - L2CA_FlowControl(p_l2cb->lcid, FALSE); - } - OBX_TRACE_DEBUG3 ("obx_cl_proc_l2c_evt rx_q.count:%d, stopped:%d state:%d", p_l2cb->rx_q.count, p_l2cb->stopped, p_cl_cb->state ); - } - } - else - { - OBX_TRACE_ERROR0("bad SM event" ); - } - break; - - } -} - -/******************************************************************************* -** -** Function obx_l2c_sec_check_complete -** -** Description The function called when Security Manager finishes -** verification of the service side connection -** -** Returns void -** -*******************************************************************************/ -static void obx_l2c_sec_check_complete (BD_ADDR bd_addr, void *p_ref_data, UINT8 res) -{ - tOBX_L2C_CB *p_lcb = (tOBX_L2C_CB *)p_ref_data; - - OBX_TRACE_DEBUG3 ("obx_l2c_sec_check_complete ch_state:%d, ch_flags:0x%x, status:%d", - p_lcb->ch_state, p_lcb->ch_flags, res); - if (p_lcb->ch_state == OBX_CH_IDLE) - return; - - if (res == BTM_SUCCESS) - { - p_lcb->ch_flags |= OBX_L2C_SECURITY_DONE; - obx_l2c_checks_ch_flags (p_lcb); - } - else - { - /* security failed - disconnect the channel */ - L2CA_DISCONNECT_REQ (p_lcb->lcid); - } -} - -/******************************************************************************* -** -** Function obx_l2c_connect_cfm_cback -** -** Description This is the L2CAP connect confirm callback function. -** -** -** Returns void -** -*******************************************************************************/ -void obx_l2c_connect_cfm_cback(UINT16 lcid, UINT16 result) -{ - tOBX_L2C_CB *p_lcb; - tL2CAP_CFG_INFO cfg; - tOBX_L2C_EVT_PARAM evt_param; - tOBX_CL_CB *p_cl_cb = NULL; - - /* look up lcb for this channel */ - if ((p_lcb = obx_lcid_2lcb(lcid)) != NULL) - { - OBX_TRACE_DEBUG1("obx_l2c_connect_cfm_cback ch_state:%d", p_lcb->ch_state); - /* if in correct state */ - if (p_lcb->ch_state == OBX_CH_CONN) - { - /* if result successful */ - if (result == L2CAP_CONN_OK) - { - /* set channel state */ - p_lcb->ch_state = OBX_CH_CFG; - - p_cl_cb = obx_lcb_2_clcb(p_lcb); - btm_sec_mx_access_request (p_cl_cb->peer_addr, p_cl_cb->psm, TRUE, - 0, 0, &obx_l2c_sec_check_complete, p_lcb); - - /* Send L2CAP config req */ - memset(&cfg, 0, sizeof(tL2CAP_CFG_INFO)); - - cfg.mtu_present = TRUE; - cfg.mtu = p_lcb->rx_mtu; - - cfg.fcr_present = TRUE; - cfg.fcr = obx_l2c_fcr_opts_def; - - L2CA_CONFIG_REQ(lcid, &cfg); - } - /* else failure */ - else - { - evt_param.any = 0; - obx_l2c_snd_evt (p_lcb, evt_param, OBX_L2C_EVT_CLOSE); - } - } - } -} -#endif /* OBX_CLIENT_INCLUDED */ - - -/******************************************************************************* -** -** Function obx_l2c_config_cfm_cback -** -** Description This is the L2CAP config confirm callback function. -** -** -** Returns void -** -*******************************************************************************/ -void obx_l2c_config_cfm_cback(UINT16 lcid, tL2CAP_CFG_INFO *p_cfg) -{ - tOBX_L2C_CB *p_lcb; - - /* look up lcb for this channel */ - if ((p_lcb = obx_lcid_2lcb(lcid)) != NULL) - { - /* if in correct state */ - if (p_lcb->ch_state == OBX_CH_CFG) - { - /* if result successful */ - if (p_cfg->result == L2CAP_CFG_OK) - { - /* update flags */ - p_lcb->ch_flags |= OBX_L2C_CFG_CFM_DONE; - - /* if configuration complete */ - obx_l2c_checks_ch_flags(p_lcb); - } - /* else failure */ - else - { - /* store result value - p_lcb->ch_result = p_cfg->result; */ - - /* Send L2CAP disconnect req */ - L2CA_DISCONNECT_REQ(lcid); - } - } - } -} - -/******************************************************************************* -** -** Function obx_l2c_config_ind_cback -** -** Description This is the L2CAP config indication callback function. -** -** -** Returns void -** -*******************************************************************************/ -void obx_l2c_config_ind_cback(UINT16 lcid, tL2CAP_CFG_INFO *p_cfg) -{ - tOBX_L2C_CB *p_lcb; - UINT16 max_mtu = OBX_MAX_MTU; - - /* Don't include QoS nor flush timeout in the response since we - currently always accept these values. Note: fcr_present is left - untouched since l2cap negotiates this internally - */ - p_cfg->flush_to_present = FALSE; - p_cfg->qos_present = FALSE; - - /* look up lcb for this channel */ - if ((p_lcb = obx_lcid_2lcb(lcid)) != NULL) - { - /* store the mtu in tbl */ - if (p_cfg->mtu_present) - { - p_lcb->tx_mtu = p_cfg->mtu; - } - else - { - p_lcb->tx_mtu = L2CAP_DEFAULT_MTU; - } - - if (p_lcb->tx_mtu > max_mtu) - { - p_lcb->tx_mtu = p_cfg->mtu = max_mtu; - - /* Must tell the peer what the adjusted value is */ - p_cfg->mtu_present = TRUE; - } - else /* Don't include in the response */ - p_cfg->mtu_present = FALSE; - OBX_TRACE_DEBUG2 ("obx_l2c_config_ind_cback tx_mtu:%d use:%d", p_lcb->tx_mtu, max_mtu); - - p_cfg->result = L2CAP_CFG_OK; - - /* send L2CAP configure response */ - L2CA_CONFIG_RSP(lcid, p_cfg); - - if (p_cfg->result != L2CAP_CFG_OK) - { - return; - } - - /* if first config ind */ - if ((p_lcb->ch_flags & OBX_L2C_CFG_IND_DONE) == 0) - { - /* update flags */ - p_lcb->ch_flags |= OBX_L2C_CFG_IND_DONE; - - /* if configuration complete */ - obx_l2c_checks_ch_flags(p_lcb); - } - } -} - -/******************************************************************************* -** -** Function obx_l2c_disconnect_ind_cback -** -** Description This is the L2CAP disconnect indication callback function. -** -** -** Returns void -** -*******************************************************************************/ -void obx_l2c_disconnect_ind_cback(UINT16 lcid, BOOLEAN ack_needed) -{ - tOBX_L2C_CB *p_lcb; - tOBX_L2C_EVT_PARAM evt_param; - - /* look up lcb for this channel */ - if ((p_lcb = obx_lcid_2lcb(lcid)) != NULL) - { - if (ack_needed) - { - /* send L2CAP disconnect response */ - L2CA_DISCONNECT_RSP(lcid); - } - - evt_param.any = 0; - obx_l2c_snd_evt (p_lcb, evt_param, OBX_L2C_EVT_CLOSE); - } -} - -/******************************************************************************* -** -** Function obx_l2c_disconnect_cfm_cback -** -** Description This is the L2CAP disconnect confirm callback function. -** -** -** Returns void -** -*******************************************************************************/ -void obx_l2c_disconnect_cfm_cback(UINT16 lcid, UINT16 result) -{ - tOBX_L2C_CB *p_lcb; - tOBX_L2C_EVT_PARAM evt_param; - - /* look up lcb for this channel */ - if ((p_lcb = obx_lcid_2lcb(lcid)) != NULL) - { - evt_param.any = 0; - obx_l2c_snd_evt (p_lcb, evt_param, OBX_L2C_EVT_CLOSE); - } -} - -/******************************************************************************* -** -** Function obx_l2c_data_ind_cback -** -** Description This is the L2CAP data indication callback function. -** -** -** Returns void -** -*******************************************************************************/ -void obx_l2c_data_ind_cback(UINT16 lcid, BT_HDR *p_buf) -{ - tOBX_L2C_CB *p_lcb; - tOBX_L2C_EVT_PARAM evt_param; -#if (BT_USE_TRACES == TRUE) - UINT16 len; -#endif - - /* look up lcb for this channel */ - if ((p_lcb = obx_lcid_2lcb(lcid)) != NULL) - { - evt_param.p_pkt = p_buf; - OBX_TRACE_DEBUG3("obx_l2c_data_ind_cback 0x%x, len:%d, offset:%d", p_buf, p_buf->len, p_buf->offset ); -#if (BT_USE_TRACES == TRUE) - len = p_buf->len; - if (len > 0x20) - len = 0x20; - obxu_dump_hex ((UINT8 *)(p_buf + 1) + p_buf->offset, "rsp cback", len); -#endif - obx_l2c_snd_evt (p_lcb, evt_param, OBX_L2C_EVT_DATA_IND); - } - else /* prevent buffer leak */ - GKI_freebuf(p_buf); -} - - -/******************************************************************************* -** -** Function obx_l2c_congestion_ind_cback -** -** Description This is the L2CAP congestion indication callback function. -** -** -** Returns void -** -*******************************************************************************/ -void obx_l2c_congestion_ind_cback(UINT16 lcid, BOOLEAN is_congested) -{ - tOBX_L2C_CB *p_lcb; - tOBX_L2C_EVT_PARAM evt_param; - - OBX_TRACE_DEBUG2("obx_l2c_congestion_ind_cback lcid:%d, is_congested:%d",lcid, is_congested ); - /* look up lcb for this channel */ - if ((p_lcb = obx_lcid_2lcb(lcid)) != NULL) - { - evt_param.is_cong = is_congested; - obx_l2c_snd_evt (p_lcb, evt_param, OBX_L2C_EVT_CONG); - } -} - -#if (OBX_CLIENT_INCLUDED == TRUE) -/******************************************************************************* -** Function obx_register_l2c -** Description Call L2CA_Register() to get virtual psm. -** Returns -*******************************************************************************/ -void obx_register_l2c(tOBX_CL_CB *p_cl_cb, UINT16 psm) -{ - p_cl_cb->psm = L2CA_REGISTER (psm, &obx_l2c_cl_appl, AMP_AUTOSWITCH_ALLOWED|AMP_USE_AMP_IF_POSSIBLE); -} - -/******************************************************************************* -** Function obx_open_l2c -** Description Call L2CA_Register() & L2CA_ConnectReq() to get lcid. -** Returns port handle -*******************************************************************************/ -tOBX_STATUS obx_open_l2c(tOBX_CL_CB *p_cl_cb, const BD_ADDR bd_addr) -{ - tOBX_L2C_CB *p_l2cb = &p_cl_cb->ll_cb.l2c; - tOBX_STATUS status = OBX_NO_RESOURCES; /* successful */ - UINT16 max_mtu = OBX_MAX_MTU; - tL2CAP_CFG_INFO cfg; - tL2CAP_ERTM_INFO ertm_info; - tBT_UUID bt_uuid = {2, {UUID_PROTOCOL_OBEX}}; - - OBX_TRACE_DEBUG2("obx_open_l2c rxmtu:%d, cbmtu:%d", p_l2cb->rx_mtu, max_mtu ); - - /* clear buffers from previous connection */ - obx_free_buf(&p_cl_cb->ll_cb); - - /* make sure the MTU is in registered range */ - if (p_l2cb->rx_mtu > max_mtu) - p_l2cb->rx_mtu = max_mtu; - if (p_l2cb->rx_mtu < OBX_MIN_MTU) - p_l2cb->rx_mtu = OBX_MIN_MTU; - - if (p_cl_cb->psm) - { - memcpy (p_cl_cb->peer_addr, bd_addr, BD_ADDR_LEN); - - /* Set the FCR options: */ - ertm_info.preferred_mode = obx_l2c_fcr_opts_def.mode; - ertm_info.allowed_modes = L2CAP_FCR_CHAN_OPT_ERTM; - ertm_info.user_rx_pool_id = OBX_USER_RX_POOL_ID; - ertm_info.user_tx_pool_id = OBX_USER_TX_POOL_ID; - ertm_info.fcr_rx_pool_id = OBX_FCR_RX_POOL_ID; - ertm_info.fcr_tx_pool_id = OBX_FCR_TX_POOL_ID; - - p_l2cb->lcid = L2CA_CONNECT_REQ (p_cl_cb->psm, (BD_ADDR_PTR)bd_addr, &ertm_info, &bt_uuid); - if (p_l2cb->lcid) - { - p_l2cb->ch_state = OBX_CH_CONN; - p_l2cb->ch_flags = 0; - p_l2cb->cong = TRUE; - memset(&cfg, 0, sizeof(tL2CAP_CFG_INFO)); - cfg.fcr_present = TRUE; - cfg.fcr = obx_l2c_fcr_opts_def; - status = OBX_SUCCESS; - } - } - - OBX_TRACE_DEBUG3("obx_open_l2c rxmtu:%d, lcid:%d, l2c.handle:0x%x", - p_l2cb->rx_mtu, p_l2cb->lcid, p_l2cb->handle ); - - if (status == OBX_SUCCESS) - { - obx_cb.l2c_map[p_l2cb->lcid - L2CAP_BASE_APPL_CID] = p_l2cb->handle; - p_l2cb->p_send_fn = (tOBX_SEND_FN *)obx_l2c_snd_msg; - p_l2cb->p_close_fn = obx_close_l2c; - } - else - { - status = OBX_NO_RESOURCES; - } - - return status; -} -#endif - -/******************************************************************************* -** -** Function obx_close_l2c -** Description Clear the port event mask and callback. Close the port. -** Returns void -*******************************************************************************/ -void obx_close_l2c(UINT16 lcid) -{ - L2CA_DISCONNECT_REQ (lcid); -} - -/******************************************************************************* -** Function obx_l2c_snd_msg -** Description Call PORT_WriteData() to send an OBEX message to peer. If -** all data is sent, free the GKI buffer that holds -** the OBEX message. If only portion of data is -** sent, adjust the BT_HDR for PART state. -** Returns TRUE if all data is sent -*******************************************************************************/ -BOOLEAN obx_l2c_snd_msg(tOBX_L2C_CB *p_l2cb) -{ - BOOLEAN sent = FALSE; - - if (!p_l2cb->cong) - { - OBX_TRACE_DEBUG2("obx_l2c_snd_msg len:%d, offset:0x%x", p_l2cb->p_txmsg->len, p_l2cb->p_txmsg->offset); - - obx_stop_timer(&p_l2cb->tle); - if (L2CA_DATA_WRITE (p_l2cb->lcid, p_l2cb->p_txmsg) == L2CAP_DW_CONGESTED) - { - OBX_TRACE_DEBUG0("obx_l2c_snd_msg congested"); - p_l2cb->cong = TRUE; - } - obx_start_timer ((tOBX_COMM_CB *)p_l2cb); - p_l2cb->p_txmsg = NULL; - sent = TRUE; - } - - return sent; -} |