• 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 #include "bt_utils.h"
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     UNUSED(mtu);
86 
87     if (p_mcb->state != RFC_MX_STATE_CONNECTED)
88     {
89         PORT_DlcEstablishCnf (p_mcb, dlci, 0, RFCOMM_ERROR);
90         return;
91     }
92 
93     rfc_port_sm_execute(p_port, RFC_EVENT_OPEN, NULL);
94 }
95 
96 
97 /*******************************************************************************
98 **
99 ** Function         RFCOMM_DlcEstablishRsp
100 **
101 ** Description      This function is called by the port emulation entity
102 **                  acks Establish Indication.
103 **
104 *******************************************************************************/
RFCOMM_DlcEstablishRsp(tRFC_MCB * p_mcb,UINT8 dlci,UINT16 mtu,UINT16 result)105 void RFCOMM_DlcEstablishRsp (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu, UINT16 result)
106 {
107     tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
108     UNUSED(mtu);
109 
110     if ((p_mcb->state != RFC_MX_STATE_CONNECTED) && (result == RFCOMM_SUCCESS))
111     {
112         PORT_DlcReleaseInd (p_mcb, dlci);
113         return;
114     }
115 
116     rfc_port_sm_execute(p_port, RFC_EVENT_ESTABLISH_RSP, &result);
117 }
118 
119 
120 /*******************************************************************************
121 **
122 ** Function         RFCOMM_ParNegReq
123 **
124 ** Description      This function is called by the user app to start
125 **                  DLC parameter negotiation.  Port emulation can send this
126 **                  request before actually establishing the DLC.  In this
127 **                  case the function will allocate RFCOMM connection control
128 **                  block.
129 **
130 *******************************************************************************/
RFCOMM_ParNegReq(tRFC_MCB * p_mcb,UINT8 dlci,UINT16 mtu)131 void RFCOMM_ParNegReq (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu)
132 {
133     tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
134     UINT8 flow;
135     UINT8 cl;
136     UINT8 k;
137 
138     if (p_mcb->state != RFC_MX_STATE_CONNECTED)
139     {
140         p_port->error = PORT_PAR_NEG_FAILED;
141         return;
142     }
143 
144     /* Negotiate the flow control mechanism.  If flow control mechanism for */
145     /* mux has not been set yet, use our default value.  If it has been set, */
146     /* use that value. */
147     flow = (p_mcb->flow == PORT_FC_UNDEFINED) ? PORT_FC_DEFAULT : p_mcb->flow;
148 
149     /* Set convergence layer and number of credits (k) */
150     if (flow == PORT_FC_CREDIT)
151     {
152         cl = RFCOMM_PN_CONV_LAYER_CBFC_I;
153         k = (p_port->credit_rx_max < RFCOMM_K_MAX) ? p_port->credit_rx_max : RFCOMM_K_MAX;
154         p_port->credit_rx = k;
155     }
156     else
157     {
158         cl = RFCOMM_PN_CONV_LAYER_TYPE_1;
159         k = 0;
160     }
161 
162     /* Send Parameter Negotiation Command UIH frame */
163     p_port->rfc.expected_rsp |= RFC_RSP_PN;
164 
165     rfc_send_pn (p_mcb, dlci, TRUE, mtu, cl, k);
166 
167     rfc_port_timer_start (p_port, RFC_T2_TIMEOUT) ;
168 }
169 
170 
171 /*******************************************************************************
172 **
173 ** Function         RFCOMM_ParNegRsp
174 **
175 ** Description      This function is called by the user app to acknowledge
176 **                  DLC parameter negotiation.
177 **
178 *******************************************************************************/
RFCOMM_ParNegRsp(tRFC_MCB * p_mcb,UINT8 dlci,UINT16 mtu,UINT8 cl,UINT8 k)179 void RFCOMM_ParNegRsp (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu, UINT8 cl, UINT8 k)
180 {
181     if (p_mcb->state != RFC_MX_STATE_CONNECTED)
182         return;
183 
184     /* Send Parameter Negotiation Response UIH frame */
185     rfc_send_pn (p_mcb, dlci, FALSE, mtu, cl, k);
186 }
187 
188 
189 /*******************************************************************************
190 **
191 ** Function         RFCOMM_PortNegReq
192 **
193 ** Description      This function is called by the user app to start
194 **                  Remote Port parameter negotiation.  Port emulation can
195 **                  send this request before actually establishing the DLC.
196 **                  In this case the function will allocate RFCOMM connection
197 **                  control block.
198 **
199 *******************************************************************************/
RFCOMM_PortNegReq(tRFC_MCB * p_mcb,UINT8 dlci,tPORT_STATE * p_pars)200 void RFCOMM_PortNegReq (tRFC_MCB *p_mcb, UINT8 dlci, tPORT_STATE *p_pars)
201 {
202     tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
203 
204     if (p_mcb->state != RFC_MX_STATE_CONNECTED)
205     {
206         PORT_PortNegCnf (p_mcb, dlci, NULL, RFCOMM_ERROR);
207         return;
208     }
209 
210     /* Send Parameter Negotiation Command UIH frame */
211     if (!p_pars)
212         p_port->rfc.expected_rsp |= RFC_RSP_RPN_REPLY;
213     else
214         p_port->rfc.expected_rsp |= RFC_RSP_RPN;
215 
216     rfc_send_rpn (p_mcb, dlci, TRUE, p_pars, RFCOMM_RPN_PM_MASK);
217     rfc_port_timer_start (p_port, RFC_T2_TIMEOUT) ;
218 
219 }
220 
221 
222 /*******************************************************************************
223 **
224 ** Function         RFCOMM_PortNegRsp
225 **
226 ** Description      This function is called by the user app to acknowledge
227 **                  Port parameters negotiation.
228 **
229 *******************************************************************************/
RFCOMM_PortNegRsp(tRFC_MCB * p_mcb,UINT8 dlci,tPORT_STATE * p_pars,UINT16 param_mask)230 void RFCOMM_PortNegRsp (tRFC_MCB *p_mcb, UINT8 dlci, tPORT_STATE *p_pars,
231                         UINT16 param_mask)
232 {
233     if (p_mcb->state != RFC_MX_STATE_CONNECTED)
234         return;
235 
236    rfc_send_rpn (p_mcb, dlci, FALSE, p_pars, param_mask);
237 }
238 
239 
240 /*******************************************************************************
241 **
242 ** Function         RFCOMM_ControlReq
243 **
244 ** Description      This function is called by the port entity to send control
245 **                  parameters to remote port emulation entity.
246 **
247 *******************************************************************************/
RFCOMM_ControlReq(tRFC_MCB * p_mcb,UINT8 dlci,tPORT_CTRL * p_pars)248 void RFCOMM_ControlReq (tRFC_MCB *p_mcb, UINT8 dlci, tPORT_CTRL *p_pars)
249 {
250     tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
251 
252     if ((p_port->state != PORT_STATE_OPENED)
253      || (p_port->rfc.state  != RFC_STATE_OPENED))
254         return;
255 
256     p_port->port_ctrl |= PORT_CTRL_REQ_SENT;
257 
258     p_port->rfc.expected_rsp |= RFC_RSP_MSC;
259 
260     rfc_send_msc (p_mcb, dlci, TRUE, p_pars);
261     rfc_port_timer_start (p_port, RFC_T2_TIMEOUT) ;
262 
263 }
264 
265 
266 /*******************************************************************************
267 **
268 ** Function         RFCOMM_FlowReq
269 **
270 ** Description      This function is called by the port entity when flow
271 **                  control state has changed.  Enable flag passed shows if
272 **                  port can accept more data.
273 **
274 *******************************************************************************/
RFCOMM_FlowReq(tRFC_MCB * p_mcb,UINT8 dlci,UINT8 enable)275 void RFCOMM_FlowReq (tRFC_MCB *p_mcb, UINT8 dlci, UINT8 enable)
276 {
277     tPORT      *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
278 
279     if ((p_port->state != PORT_STATE_OPENED)
280      || (p_port->rfc.state  != RFC_STATE_OPENED))
281         return;
282 
283     p_port->local_ctrl.fc = !enable;
284 
285     p_port->rfc.expected_rsp |= RFC_RSP_MSC;
286 
287     rfc_send_msc (p_mcb, dlci, TRUE, &p_port->local_ctrl);
288     rfc_port_timer_start (p_port, RFC_T2_TIMEOUT) ;
289 
290 }
291 
292 
293 /*******************************************************************************
294 **
295 ** Function         RFCOMM_LineStatusReq
296 **
297 ** Description      This function is called by the port entity when line
298 **                  status should be delivered to the peer.
299 **
300 *******************************************************************************/
RFCOMM_LineStatusReq(tRFC_MCB * p_mcb,UINT8 dlci,UINT8 status)301 void RFCOMM_LineStatusReq (tRFC_MCB *p_mcb, UINT8 dlci, UINT8 status)
302 {
303     tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
304 
305     if ((p_port->state != PORT_STATE_OPENED)
306      || (p_port->rfc.state  != RFC_STATE_OPENED))
307         return;
308 
309     p_port->rfc.expected_rsp |= RFC_RSP_RLS;
310 
311     rfc_send_rls (p_mcb, dlci, TRUE, status);
312     rfc_port_timer_start (p_port, RFC_T2_TIMEOUT);
313 }
314 
315 
316 /*******************************************************************************
317 **
318 ** Function         RFCOMM_DlcReleaseReq
319 **
320 ** Description      This function is called by the PORT unit to close DLC
321 **
322 *******************************************************************************/
RFCOMM_DlcReleaseReq(tRFC_MCB * p_mcb,UINT8 dlci)323 void RFCOMM_DlcReleaseReq (tRFC_MCB *p_mcb, UINT8 dlci)
324 {
325     rfc_port_sm_execute(port_find_mcb_dlci_port (p_mcb, dlci), RFC_EVENT_CLOSE, 0);
326 }
327 
328 
329 /*******************************************************************************
330 **
331 ** Function         RFCOMM_DataReq
332 **
333 ** Description      This function is called by the user app to send data buffer
334 **
335 *******************************************************************************/
RFCOMM_DataReq(tRFC_MCB * p_mcb,UINT8 dlci,BT_HDR * p_buf)336 void RFCOMM_DataReq (tRFC_MCB *p_mcb, UINT8 dlci, BT_HDR *p_buf)
337 {
338     rfc_port_sm_execute(port_find_mcb_dlci_port (p_mcb, dlci), RFC_EVENT_DATA, p_buf);
339 }
340 
341 
342