• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 1999-2012 Broadcom Corporation
4  *
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:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  *
17  ******************************************************************************/
18 
19 /*****************************************************************************
20  *
21  * This file contains functions callable by an application
22  * running on top of RFCOMM
23  *
24  *****************************************************************************/
25 
26 #include <string.h>
27 #include "bt_target.h"
28 #include "gki.h"
29 #include "rfcdefs.h"
30 #include "port_api.h"
31 #include "l2c_api.h"
32 #include "port_int.h"
33 #include "rfc_int.h"
34 
35 
36 #if RFC_DYNAMIC_MEMORY == FALSE
37 tRFC_CB rfc_cb;
38 #endif
39 
40 /*******************************************************************************
41 **
42 ** Function         RFCOMM_StartReq
43 **
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.
48 **
49 *******************************************************************************/
RFCOMM_StartReq(tRFC_MCB * p_mcb)50 void RFCOMM_StartReq (tRFC_MCB *p_mcb)
51 {
52     rfc_mx_sm_execute (p_mcb, RFC_MX_EVENT_START_REQ, NULL);
53 }
54 
55 
56 /*******************************************************************************
57 **
58 ** Function         RFCOMM_StartRsp
59 **
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.
63 **
64 *******************************************************************************/
RFCOMM_StartRsp(tRFC_MCB * p_mcb,UINT16 result)65 void RFCOMM_StartRsp (tRFC_MCB *p_mcb, UINT16 result)
66 {
67     rfc_mx_sm_execute (p_mcb, RFC_MX_EVENT_START_RSP, &result);
68 }
69 
70 
71 /*******************************************************************************
72 **
73 ** Function         RFCOMM_DlcEstablishReq
74 **
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
79 **                  machine.
80 **
81 *******************************************************************************/
RFCOMM_DlcEstablishReq(tRFC_MCB * p_mcb,UINT8 dlci,UINT16 mtu)82 void RFCOMM_DlcEstablishReq (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu)
83 {
84     tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
85 
86     if (p_mcb->state != RFC_MX_STATE_CONNECTED)
87     {
88         PORT_DlcEstablishCnf (p_mcb, dlci, 0, RFCOMM_ERROR);
89         return;
90     }
91 
92     rfc_port_sm_execute(p_port, RFC_EVENT_OPEN, NULL);
93 }
94 
95 
96 /*******************************************************************************
97 **
98 ** Function         RFCOMM_DlcEstablishRsp
99 **
100 ** Description      This function is called by the port emulation entity
101 **                  acks Establish Indication.
102 **
103 *******************************************************************************/
RFCOMM_DlcEstablishRsp(tRFC_MCB * p_mcb,UINT8 dlci,UINT16 mtu,UINT16 result)104 void RFCOMM_DlcEstablishRsp (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu, UINT16 result)
105 {
106     tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
107 
108     if ((p_mcb->state != RFC_MX_STATE_CONNECTED) && (result == RFCOMM_SUCCESS))
109     {
110         PORT_DlcReleaseInd (p_mcb, dlci);
111         return;
112     }
113 
114     rfc_port_sm_execute(p_port, RFC_EVENT_ESTABLISH_RSP, &result);
115 }
116 
117 
118 /*******************************************************************************
119 **
120 ** Function         RFCOMM_ParNegReq
121 **
122 ** Description      This function is called by the user app to start
123 **                  DLC parameter negotiation.  Port emulation can send this
124 **                  request before actually establishing the DLC.  In this
125 **                  case the function will allocate RFCOMM connection control
126 **                  block.
127 **
128 *******************************************************************************/
RFCOMM_ParNegReq(tRFC_MCB * p_mcb,UINT8 dlci,UINT16 mtu)129 void RFCOMM_ParNegReq (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu)
130 {
131     tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
132     UINT8 flow;
133     UINT8 cl;
134     UINT8 k;
135 
136     if (p_mcb->state != RFC_MX_STATE_CONNECTED)
137     {
138         p_port->error = PORT_PAR_NEG_FAILED;
139         return;
140     }
141 
142     /* Negotiate the flow control mechanism.  If flow control mechanism for */
143     /* mux has not been set yet, use our default value.  If it has been set, */
144     /* use that value. */
145     flow = (p_mcb->flow == PORT_FC_UNDEFINED) ? PORT_FC_DEFAULT : p_mcb->flow;
146 
147     /* Set convergence layer and number of credits (k) */
148     if (flow == PORT_FC_CREDIT)
149     {
150         cl = RFCOMM_PN_CONV_LAYER_CBFC_I;
151         k = (p_port->credit_rx_max < RFCOMM_K_MAX) ? p_port->credit_rx_max : RFCOMM_K_MAX;
152         p_port->credit_rx = k;
153     }
154     else
155     {
156         cl = RFCOMM_PN_CONV_LAYER_TYPE_1;
157         k = 0;
158     }
159 
160     /* Send Parameter Negotiation Command UIH frame */
161     p_port->rfc.expected_rsp |= RFC_RSP_PN;
162 
163     rfc_send_pn (p_mcb, dlci, TRUE, mtu, cl, k);
164 
165     rfc_port_timer_start (p_port, RFC_T2_TIMEOUT) ;
166 }
167 
168 
169 /*******************************************************************************
170 **
171 ** Function         RFCOMM_ParNegRsp
172 **
173 ** Description      This function is called by the user app to acknowledge
174 **                  DLC parameter negotiation.
175 **
176 *******************************************************************************/
RFCOMM_ParNegRsp(tRFC_MCB * p_mcb,UINT8 dlci,UINT16 mtu,UINT8 cl,UINT8 k)177 void RFCOMM_ParNegRsp (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu, UINT8 cl, UINT8 k)
178 {
179     if (p_mcb->state != RFC_MX_STATE_CONNECTED)
180         return;
181 
182     /* Send Parameter Negotiation Response UIH frame */
183     rfc_send_pn (p_mcb, dlci, FALSE, mtu, cl, k);
184 }
185 
186 
187 /*******************************************************************************
188 **
189 ** Function         RFCOMM_PortNegReq
190 **
191 ** Description      This function is called by the user app to start
192 **                  Remote Port parameter negotiation.  Port emulation can
193 **                  send this request before actually establishing the DLC.
194 **                  In this case the function will allocate RFCOMM connection
195 **                  control block.
196 **
197 *******************************************************************************/
RFCOMM_PortNegReq(tRFC_MCB * p_mcb,UINT8 dlci,tPORT_STATE * p_pars)198 void RFCOMM_PortNegReq (tRFC_MCB *p_mcb, UINT8 dlci, tPORT_STATE *p_pars)
199 {
200     tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
201 
202     if (p_mcb->state != RFC_MX_STATE_CONNECTED)
203     {
204         PORT_PortNegCnf (p_mcb, dlci, NULL, RFCOMM_ERROR);
205         return;
206     }
207 
208     /* Send Parameter Negotiation Command UIH frame */
209     if (!p_pars)
210         p_port->rfc.expected_rsp |= RFC_RSP_RPN_REPLY;
211     else
212         p_port->rfc.expected_rsp |= RFC_RSP_RPN;
213 
214     rfc_send_rpn (p_mcb, dlci, TRUE, p_pars, RFCOMM_RPN_PM_MASK);
215     rfc_port_timer_start (p_port, RFC_T2_TIMEOUT) ;
216 
217 }
218 
219 
220 /*******************************************************************************
221 **
222 ** Function         RFCOMM_PortNegRsp
223 **
224 ** Description      This function is called by the user app to acknowledge
225 **                  Port parameters negotiation.
226 **
227 *******************************************************************************/
RFCOMM_PortNegRsp(tRFC_MCB * p_mcb,UINT8 dlci,tPORT_STATE * p_pars,UINT16 param_mask)228 void RFCOMM_PortNegRsp (tRFC_MCB *p_mcb, UINT8 dlci, tPORT_STATE *p_pars,
229                         UINT16 param_mask)
230 {
231     if (p_mcb->state != RFC_MX_STATE_CONNECTED)
232         return;
233 
234    rfc_send_rpn (p_mcb, dlci, FALSE, p_pars, param_mask);
235 }
236 
237 
238 /*******************************************************************************
239 **
240 ** Function         RFCOMM_ControlReq
241 **
242 ** Description      This function is called by the port entity to send control
243 **                  parameters to remote port emulation entity.
244 **
245 *******************************************************************************/
RFCOMM_ControlReq(tRFC_MCB * p_mcb,UINT8 dlci,tPORT_CTRL * p_pars)246 void RFCOMM_ControlReq (tRFC_MCB *p_mcb, UINT8 dlci, tPORT_CTRL *p_pars)
247 {
248     tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
249 
250     if ((p_port->state != PORT_STATE_OPENED)
251      || (p_port->rfc.state  != RFC_STATE_OPENED))
252         return;
253 
254     p_port->port_ctrl |= PORT_CTRL_REQ_SENT;
255 
256     p_port->rfc.expected_rsp |= RFC_RSP_MSC;
257 
258     rfc_send_msc (p_mcb, dlci, TRUE, p_pars);
259     rfc_port_timer_start (p_port, RFC_T2_TIMEOUT) ;
260 
261 }
262 
263 
264 /*******************************************************************************
265 **
266 ** Function         RFCOMM_FlowReq
267 **
268 ** Description      This function is called by the port entity when flow
269 **                  control state has changed.  Enable flag passed shows if
270 **                  port can accept more data.
271 **
272 *******************************************************************************/
RFCOMM_FlowReq(tRFC_MCB * p_mcb,UINT8 dlci,UINT8 enable)273 void RFCOMM_FlowReq (tRFC_MCB *p_mcb, UINT8 dlci, UINT8 enable)
274 {
275     tPORT      *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
276 
277     if ((p_port->state != PORT_STATE_OPENED)
278      || (p_port->rfc.state  != RFC_STATE_OPENED))
279         return;
280 
281     p_port->local_ctrl.fc = !enable;
282 
283     p_port->rfc.expected_rsp |= RFC_RSP_MSC;
284 
285     rfc_send_msc (p_mcb, dlci, TRUE, &p_port->local_ctrl);
286     rfc_port_timer_start (p_port, RFC_T2_TIMEOUT) ;
287 
288 }
289 
290 
291 /*******************************************************************************
292 **
293 ** Function         RFCOMM_LineStatusReq
294 **
295 ** Description      This function is called by the port entity when line
296 **                  status should be delivered to the peer.
297 **
298 *******************************************************************************/
RFCOMM_LineStatusReq(tRFC_MCB * p_mcb,UINT8 dlci,UINT8 status)299 void RFCOMM_LineStatusReq (tRFC_MCB *p_mcb, UINT8 dlci, UINT8 status)
300 {
301     tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
302 
303     if ((p_port->state != PORT_STATE_OPENED)
304      || (p_port->rfc.state  != RFC_STATE_OPENED))
305         return;
306 
307     p_port->rfc.expected_rsp |= RFC_RSP_RLS;
308 
309     rfc_send_rls (p_mcb, dlci, TRUE, status);
310     rfc_port_timer_start (p_port, RFC_T2_TIMEOUT);
311 }
312 
313 
314 /*******************************************************************************
315 **
316 ** Function         RFCOMM_DlcReleaseReq
317 **
318 ** Description      This function is called by the PORT unit to close DLC
319 **
320 *******************************************************************************/
RFCOMM_DlcReleaseReq(tRFC_MCB * p_mcb,UINT8 dlci)321 void RFCOMM_DlcReleaseReq (tRFC_MCB *p_mcb, UINT8 dlci)
322 {
323     rfc_port_sm_execute(port_find_mcb_dlci_port (p_mcb, dlci), RFC_EVENT_CLOSE, 0);
324 }
325 
326 
327 /*******************************************************************************
328 **
329 ** Function         RFCOMM_DataReq
330 **
331 ** Description      This function is called by the user app to send data buffer
332 **
333 *******************************************************************************/
RFCOMM_DataReq(tRFC_MCB * p_mcb,UINT8 dlci,BT_HDR * p_buf)334 void RFCOMM_DataReq (tRFC_MCB *p_mcb, UINT8 dlci, BT_HDR *p_buf)
335 {
336     rfc_port_sm_execute(port_find_mcb_dlci_port (p_mcb, dlci), RFC_EVENT_DATA, p_buf);
337 }
338 
339 
340