1 /******************************************************************************
3 * Copyright (C) 1999-2012 Broadcom Corporation
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 ******************************************************************************/
19 /*****************************************************************************
21 * This file contains functions callable by an application
22 * running on top of RFCOMM
24 *****************************************************************************/
27 #include "bt_target.h"
28 #include "bt_common.h"
36 #if RFC_DYNAMIC_MEMORY == FALSE
40 /*******************************************************************************
42 ** Function RFCOMM_StartReq
44 ** Description This function handles Start Request from the upper layer.
45 ** If RFCOMM multiplexer channel can not be allocated
46 ** send start not accepted confirmation. Otherwise dispatch
47 ** start event to the state machine.
49 *******************************************************************************/
50 void RFCOMM_StartReq (tRFC_MCB *p_mcb)
52 rfc_mx_sm_execute (p_mcb, RFC_MX_EVENT_START_REQ, NULL);
56 /*******************************************************************************
58 ** Function RFCOMM_StartRsp
60 ** Description This function handles Start Response from the upper layer.
61 ** Save upper layer handle and result of the Start Indication
62 ** in the control block and dispatch event to the FSM.
64 *******************************************************************************/
65 void RFCOMM_StartRsp (tRFC_MCB *p_mcb, UINT16 result)
67 rfc_mx_sm_execute (p_mcb, RFC_MX_EVENT_START_RSP, &result);
71 /*******************************************************************************
73 ** Function RFCOMM_DlcEstablishReq
75 ** Description This function is called by the user app to establish
76 ** connection with the specific dlci on a specific bd device.
77 ** It will allocate RFCOMM connection control block if not
78 ** allocated before and dispatch open event to the state
81 *******************************************************************************/
82 void RFCOMM_DlcEstablishReq (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu)
85 if (p_mcb->state != RFC_MX_STATE_CONNECTED)
87 PORT_DlcEstablishCnf (p_mcb, dlci, 0, RFCOMM_ERROR);
91 tPORT *p_port = port_find_mcb_dlci_port(p_mcb, dlci);
93 RFCOMM_TRACE_WARNING("%s Unable to find DLCI port dlci:%d", __func__,
98 rfc_port_sm_execute(p_port, RFC_EVENT_OPEN, NULL);
102 /*******************************************************************************
104 ** Function RFCOMM_DlcEstablishRsp
106 ** Description This function is called by the port emulation entity
107 ** acks Establish Indication.
109 *******************************************************************************/
110 void RFCOMM_DlcEstablishRsp (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu, UINT16 result)
113 if ((p_mcb->state != RFC_MX_STATE_CONNECTED) && (result == RFCOMM_SUCCESS))
115 PORT_DlcReleaseInd (p_mcb, dlci);
119 tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
120 if (p_port == NULL) {
121 RFCOMM_TRACE_WARNING("%s Unable to find DLCI port dlci:%d", __func__,
125 rfc_port_sm_execute(p_port, RFC_EVENT_ESTABLISH_RSP, &result);
129 /*******************************************************************************
131 ** Function RFCOMM_ParNegReq
133 ** Description This function is called by the user app to start
134 ** DLC parameter negotiation. Port emulation can send this
135 ** request before actually establishing the DLC. In this
136 ** case the function will allocate RFCOMM connection control
139 *******************************************************************************/
140 void RFCOMM_ParNegReq (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu)
146 tPORT *p_port = port_find_mcb_dlci_port(p_mcb, dlci);
147 if (p_port == NULL) {
148 RFCOMM_TRACE_WARNING("%s Unable to find DLCI port dlci:%d", __func__,
153 if (p_mcb->state != RFC_MX_STATE_CONNECTED)
155 p_port->error = PORT_PAR_NEG_FAILED;
159 /* Negotiate the flow control mechanism. If flow control mechanism for */
160 /* mux has not been set yet, use our default value. If it has been set, */
161 /* use that value. */
162 flow = (p_mcb->flow == PORT_FC_UNDEFINED) ? PORT_FC_DEFAULT : p_mcb->flow;
164 /* Set convergence layer and number of credits (k) */
165 if (flow == PORT_FC_CREDIT)
167 cl = RFCOMM_PN_CONV_LAYER_CBFC_I;
168 k = (p_port->credit_rx_max < RFCOMM_K_MAX) ? p_port->credit_rx_max : RFCOMM_K_MAX;
169 p_port->credit_rx = k;
173 cl = RFCOMM_PN_CONV_LAYER_TYPE_1;
177 /* Send Parameter Negotiation Command UIH frame */
178 p_port->rfc.expected_rsp |= RFC_RSP_PN;
180 rfc_send_pn (p_mcb, dlci, TRUE, mtu, cl, k);
182 rfc_port_timer_start (p_port, RFC_T2_TIMEOUT) ;
186 /*******************************************************************************
188 ** Function RFCOMM_ParNegRsp
190 ** Description This function is called by the user app to acknowledge
191 ** DLC parameter negotiation.
193 *******************************************************************************/
194 void RFCOMM_ParNegRsp (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu, UINT8 cl, UINT8 k)
196 if (p_mcb->state != RFC_MX_STATE_CONNECTED)
199 /* Send Parameter Negotiation Response UIH frame */
200 rfc_send_pn (p_mcb, dlci, FALSE, mtu, cl, k);
204 /*******************************************************************************
206 ** Function RFCOMM_PortNegReq
208 ** Description This function is called by the user app to start
209 ** Remote Port parameter negotiation. Port emulation can
210 ** send this request before actually establishing the DLC.
211 ** In this case the function will allocate RFCOMM connection
214 *******************************************************************************/
215 void RFCOMM_PortNegReq (tRFC_MCB *p_mcb, UINT8 dlci, tPORT_STATE *p_pars)
217 if (p_mcb->state != RFC_MX_STATE_CONNECTED)
219 PORT_PortNegCnf (p_mcb, dlci, NULL, RFCOMM_ERROR);
223 tPORT *p_port = port_find_mcb_dlci_port(p_mcb, dlci);
224 if (p_port == NULL) {
225 RFCOMM_TRACE_WARNING("%s Unable to find DLCI port dlci:%d", __func__,
230 /* Send Parameter Negotiation Command UIH frame */
232 p_port->rfc.expected_rsp |= RFC_RSP_RPN_REPLY;
234 p_port->rfc.expected_rsp |= RFC_RSP_RPN;
236 rfc_send_rpn (p_mcb, dlci, TRUE, p_pars, RFCOMM_RPN_PM_MASK);
237 rfc_port_timer_start (p_port, RFC_T2_TIMEOUT) ;
242 /*******************************************************************************
244 ** Function RFCOMM_PortNegRsp
246 ** Description This function is called by the user app to acknowledge
247 ** Port parameters negotiation.
249 *******************************************************************************/
250 void RFCOMM_PortNegRsp (tRFC_MCB *p_mcb, UINT8 dlci, tPORT_STATE *p_pars,
253 if (p_mcb->state != RFC_MX_STATE_CONNECTED)
256 rfc_send_rpn (p_mcb, dlci, FALSE, p_pars, param_mask);
260 /*******************************************************************************
262 ** Function RFCOMM_ControlReq
264 ** Description This function is called by the port entity to send control
265 ** parameters to remote port emulation entity.
267 *******************************************************************************/
268 void RFCOMM_ControlReq (tRFC_MCB *p_mcb, UINT8 dlci, tPORT_CTRL *p_pars)
270 tPORT *p_port = port_find_mcb_dlci_port(p_mcb, dlci);
271 if (p_port == NULL) {
272 RFCOMM_TRACE_WARNING("%s Unable to find DLCI port dlci:%d", __func__,
277 if ((p_port->state != PORT_STATE_OPENED)
278 || (p_port->rfc.state != RFC_STATE_OPENED))
281 p_port->port_ctrl |= PORT_CTRL_REQ_SENT;
283 p_port->rfc.expected_rsp |= RFC_RSP_MSC;
285 rfc_send_msc (p_mcb, dlci, TRUE, p_pars);
286 rfc_port_timer_start (p_port, RFC_T2_TIMEOUT) ;
291 /*******************************************************************************
293 ** Function RFCOMM_FlowReq
295 ** Description This function is called by the port entity when flow
296 ** control state has changed. Enable flag passed shows if
297 ** port can accept more data.
299 *******************************************************************************/
300 void RFCOMM_FlowReq (tRFC_MCB *p_mcb, UINT8 dlci, UINT8 enable)
302 tPORT *p_port = port_find_mcb_dlci_port(p_mcb, dlci);
303 if (p_port == NULL) {
304 RFCOMM_TRACE_WARNING("%s Unable to find DLCI port dlci:%d", __func__,
309 if ((p_port->state != PORT_STATE_OPENED)
310 || (p_port->rfc.state != RFC_STATE_OPENED))
313 p_port->local_ctrl.fc = !enable;
315 p_port->rfc.expected_rsp |= RFC_RSP_MSC;
317 rfc_send_msc (p_mcb, dlci, TRUE, &p_port->local_ctrl);
318 rfc_port_timer_start (p_port, RFC_T2_TIMEOUT) ;
323 /*******************************************************************************
325 ** Function RFCOMM_LineStatusReq
327 ** Description This function is called by the port entity when line
328 ** status should be delivered to the peer.
330 *******************************************************************************/
331 void RFCOMM_LineStatusReq (tRFC_MCB *p_mcb, UINT8 dlci, UINT8 status)
333 tPORT *p_port = port_find_mcb_dlci_port(p_mcb, dlci);
334 if (p_port == NULL) {
335 RFCOMM_TRACE_WARNING("%s Unable to find DLCI port dlci:%d", __func__,
340 if ((p_port->state != PORT_STATE_OPENED)
341 || (p_port->rfc.state != RFC_STATE_OPENED))
344 p_port->rfc.expected_rsp |= RFC_RSP_RLS;
346 rfc_send_rls (p_mcb, dlci, TRUE, status);
347 rfc_port_timer_start (p_port, RFC_T2_TIMEOUT);
351 /*******************************************************************************
353 ** Function RFCOMM_DlcReleaseReq
355 ** Description This function is called by the PORT unit to close DLC
357 *******************************************************************************/
358 void RFCOMM_DlcReleaseReq (tRFC_MCB *p_mcb, UINT8 dlci)
360 rfc_port_sm_execute(port_find_mcb_dlci_port (p_mcb, dlci), RFC_EVENT_CLOSE, 0);
364 /*******************************************************************************
366 ** Function RFCOMM_DataReq
368 ** Description This function is called by the user app to send data buffer
370 *******************************************************************************/
371 void RFCOMM_DataReq (tRFC_MCB *p_mcb, UINT8 dlci, BT_HDR *p_buf)
373 rfc_port_sm_execute(port_find_mcb_dlci_port (p_mcb, dlci), RFC_EVENT_DATA, p_buf);