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 state machine and action routines for a port of the
22 * RFCOMM unit
23 *
24 ******************************************************************************/
25 #include <string.h>
26 #include "common/bt_target.h"
27 #include "stack/rfcdefs.h"
28 #include "stack/btm_api.h"
29 #include "btm_int.h"
30 #include "stack/port_api.h"
31 #include "port_int.h"
32 #include "rfc_int.h"
33 #include "common/bt_defs.h"
34 #include "osi/allocator.h"
35 #include "osi/mutex.h"
36 #if (defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == 1)
37
38 /********************************************************************************/
39 /* L O C A L F U N C T I O N P R O T O T Y P E S */
40 /********************************************************************************/
41 static void rfc_port_sm_state_closed (tPORT *p_port, UINT16 event, void *p_data);
42 static void rfc_port_sm_sabme_wait_ua (tPORT *p_port, UINT16 event, void *p_data);
43 static void rfc_port_sm_opened (tPORT *p_port, UINT16 event, void *p_data);
44 static void rfc_port_sm_orig_wait_sec_check (tPORT *p_port, UINT16 event, void *p_data);
45 static void rfc_port_sm_term_wait_sec_check (tPORT *p_port, UINT16 event, void *p_data);
46 static void rfc_port_sm_disc_wait_ua (tPORT *p_port, UINT16 event, void *p_data);
47
48 static void rfc_port_uplink_data (tPORT *p_port, BT_HDR *p_buf);
49
50 static void rfc_set_port_state(tPORT_STATE *port_pars, MX_FRAME *p_frame);
51
52
53 /*******************************************************************************
54 **
55 ** Function rfc_port_sm_execute
56 **
57 ** Description This function sends port events through the state
58 ** machine.
59 **
60 ** Returns void
61 **
62 *******************************************************************************/
rfc_port_sm_execute(tPORT * p_port,UINT16 event,void * p_data)63 void rfc_port_sm_execute (tPORT *p_port, UINT16 event, void *p_data)
64 {
65 if (!p_port) {
66 RFCOMM_TRACE_WARNING ("NULL port event %d", event);
67 return;
68 }
69
70 switch (p_port->rfc.state) {
71 case RFC_STATE_CLOSED:
72 rfc_port_sm_state_closed (p_port, event, p_data);
73 break;
74
75 case RFC_STATE_SABME_WAIT_UA:
76 rfc_port_sm_sabme_wait_ua (p_port, event, p_data);
77 break;
78
79 case RFC_STATE_ORIG_WAIT_SEC_CHECK:
80 rfc_port_sm_orig_wait_sec_check (p_port, event, p_data);
81 break;
82
83 case RFC_STATE_TERM_WAIT_SEC_CHECK:
84 rfc_port_sm_term_wait_sec_check (p_port, event, p_data);
85 break;
86
87 case RFC_STATE_OPENED:
88 rfc_port_sm_opened (p_port, event, p_data);
89 break;
90
91 case RFC_STATE_DISC_WAIT_UA:
92 rfc_port_sm_disc_wait_ua (p_port, event, p_data);
93 break;
94 }
95 }
96
97
98 /*******************************************************************************
99 **
100 ** Function rfc_port_sm_state_closed
101 **
102 ** Description This function handles events when the port is in
103 ** CLOSED state. This state exists when port is
104 ** being initially established.
105 **
106 ** Returns void
107 **
108 *******************************************************************************/
rfc_port_sm_state_closed(tPORT * p_port,UINT16 event,void * p_data)109 void rfc_port_sm_state_closed (tPORT *p_port, UINT16 event, void *p_data)
110 {
111 switch (event) {
112 case RFC_EVENT_OPEN:
113 p_port->rfc.state = RFC_STATE_ORIG_WAIT_SEC_CHECK;
114 btm_sec_mx_access_request (p_port->rfc.p_mcb->bd_addr, BT_PSM_RFCOMM, 1,
115 BTM_SEC_PROTO_RFCOMM, (UINT32)(p_port->dlci / 2),
116 &rfc_sec_check_complete, p_port);
117 return;
118
119 case RFC_EVENT_CLOSE:
120 break;
121
122 case RFC_EVENT_CLEAR:
123 return;
124
125 case RFC_EVENT_DATA:
126 osi_free (p_data);
127 break;
128
129 case RFC_EVENT_SABME:
130 /* make sure the multiplexer disconnect timer is not running (reconnect case) */
131 rfc_timer_stop(p_port->rfc.p_mcb );
132
133 /* Open will be continued after security checks are passed */
134 p_port->rfc.state = RFC_STATE_TERM_WAIT_SEC_CHECK;
135 btm_sec_mx_access_request (p_port->rfc.p_mcb->bd_addr, BT_PSM_RFCOMM, 0,
136 BTM_SEC_PROTO_RFCOMM, (UINT32)(p_port->dlci / 2),
137 &rfc_sec_check_complete, p_port);
138 return;
139
140 case RFC_EVENT_UA:
141 return;
142
143 case RFC_EVENT_DM:
144 rfc_port_closed (p_port);
145 return;
146
147 case RFC_EVENT_UIH:
148 osi_free (p_data);
149 rfc_send_dm (p_port->rfc.p_mcb, p_port->dlci, 0);
150 return;
151
152 case RFC_EVENT_DISC:
153 rfc_send_dm (p_port->rfc.p_mcb, p_port->dlci, 0);
154 return;
155
156 case RFC_EVENT_TIMEOUT:
157 Port_TimeOutCloseMux( p_port->rfc.p_mcb ) ;
158 RFCOMM_TRACE_ERROR ("Port error state %d event %d", p_port->rfc.state, event);
159 return;
160 }
161
162 RFCOMM_TRACE_WARNING ("Port state closed Event ignored %d", event);
163 return;
164 }
165
166 /*******************************************************************************
167 **
168 ** Function rfc_port_sm_sabme_wait_ua
169 **
170 ** Description This function handles events when SABME on the DLC was
171 ** sent and SM is waiting for UA or DM.
172 **
173 ** Returns void
174 **
175 *******************************************************************************/
rfc_port_sm_sabme_wait_ua(tPORT * p_port,UINT16 event,void * p_data)176 void rfc_port_sm_sabme_wait_ua (tPORT *p_port, UINT16 event, void *p_data)
177 {
178 switch (event) {
179 case RFC_EVENT_OPEN:
180 case RFC_EVENT_ESTABLISH_RSP:
181 RFCOMM_TRACE_ERROR ("Port error state %d event %d", p_port->rfc.state, event);
182 return;
183
184 case RFC_EVENT_CLOSE:
185 rfc_port_timer_start (p_port, RFC_DISC_TIMEOUT);
186 rfc_send_disc (p_port->rfc.p_mcb, p_port->dlci);
187 p_port->rfc.expected_rsp = 0;
188 p_port->rfc.state = RFC_STATE_DISC_WAIT_UA;
189 return;
190
191 case RFC_EVENT_CLEAR:
192 rfc_port_closed (p_port);
193 return;
194
195 case RFC_EVENT_DATA:
196 osi_free (p_data);
197 break;
198
199 case RFC_EVENT_UA:
200 rfc_port_timer_stop (p_port);
201 p_port->rfc.state = RFC_STATE_OPENED;
202 PORT_DlcEstablishCnf (p_port->rfc.p_mcb, p_port->dlci, p_port->rfc.p_mcb->peer_l2cap_mtu, RFCOMM_SUCCESS);
203 return;
204
205 case RFC_EVENT_DM:
206 p_port->rfc.p_mcb->is_disc_initiator = 1;
207 PORT_DlcEstablishCnf (p_port->rfc.p_mcb, p_port->dlci, p_port->rfc.p_mcb->peer_l2cap_mtu, RFCOMM_ERROR);
208 rfc_port_closed (p_port);
209 return;
210
211 case RFC_EVENT_DISC:
212 rfc_send_ua (p_port->rfc.p_mcb, p_port->dlci);
213 PORT_DlcEstablishCnf (p_port->rfc.p_mcb, p_port->dlci, p_port->rfc.p_mcb->peer_l2cap_mtu, RFCOMM_ERROR);
214 rfc_port_closed (p_port);
215 return;
216
217 case RFC_EVENT_SABME:
218 /* Continue to wait for the UA the SABME this side sent */
219 rfc_send_ua (p_port->rfc.p_mcb, p_port->dlci);
220 return;
221
222 case RFC_EVENT_UIH:
223 osi_free (p_data);
224 return;
225
226 case RFC_EVENT_TIMEOUT:
227 p_port->rfc.state = RFC_STATE_CLOSED;
228 PORT_DlcEstablishCnf (p_port->rfc.p_mcb, p_port->dlci, p_port->rfc.p_mcb->peer_l2cap_mtu, RFCOMM_ERROR);
229 return;
230 }
231 RFCOMM_TRACE_WARNING ("Port state sabme_wait_ua Event ignored %d", event);
232 }
233
234
235 /*******************************************************************************
236 **
237 ** Function rfc_port_sm_term_wait_sec_check
238 **
239 ** Description This function handles events for the port in the
240 ** WAIT_SEC_CHECK state. SABME has been received from the
241 ** peer and Security Manager verifes BD_ADDR, before we can
242 ** send ESTABLISH_IND to the Port entity
243 **
244 ** Returns void
245 **
246 *******************************************************************************/
rfc_port_sm_term_wait_sec_check(tPORT * p_port,UINT16 event,void * p_data)247 void rfc_port_sm_term_wait_sec_check (tPORT *p_port, UINT16 event, void *p_data)
248 {
249 switch (event) {
250 case RFC_EVENT_SEC_COMPLETE:
251 if (*((UINT8 *)p_data) != BTM_SUCCESS) {
252 /* Authentication/authorization failed. If link is still */
253 /* up send DM and check if we need to start inactive timer */
254 if (p_port->rfc.p_mcb) {
255 rfc_send_dm (p_port->rfc.p_mcb, p_port->dlci, 1);
256 p_port->rfc.p_mcb->is_disc_initiator = 1;
257 port_rfc_closed (p_port, PORT_SEC_FAILED);
258 }
259 } else {
260 PORT_DlcEstablishInd (p_port->rfc.p_mcb, p_port->dlci, p_port->rfc.p_mcb->peer_l2cap_mtu);
261 }
262 return;
263
264 case RFC_EVENT_OPEN:
265 case RFC_EVENT_CLOSE:
266 RFCOMM_TRACE_ERROR ("Port error state %d event %d", p_port->rfc.state, event);
267 return;
268
269 case RFC_EVENT_CLEAR:
270 btm_sec_abort_access_req (p_port->rfc.p_mcb->bd_addr);
271 rfc_port_closed (p_port);
272 return;
273
274 case RFC_EVENT_DATA:
275 RFCOMM_TRACE_ERROR ("Port error state Term Wait Sec event Data");
276 osi_free (p_data);
277 return;
278
279 case RFC_EVENT_SABME:
280 /* Ignore SABME retransmission if client dares to do so */
281 return;
282
283 case RFC_EVENT_DISC:
284 btm_sec_abort_access_req (p_port->rfc.p_mcb->bd_addr);
285 p_port->rfc.state = RFC_STATE_CLOSED;
286 rfc_send_ua (p_port->rfc.p_mcb, p_port->dlci);
287
288 PORT_DlcReleaseInd (p_port->rfc.p_mcb, p_port->dlci);
289 return;
290
291 case RFC_EVENT_UIH:
292 osi_free (p_data);
293 return;
294
295 case RFC_EVENT_ESTABLISH_RSP:
296 if (*((UINT8 *)p_data) != RFCOMM_SUCCESS) {
297 if (p_port->rfc.p_mcb) {
298 rfc_send_dm (p_port->rfc.p_mcb, p_port->dlci, 1);
299 }
300 } else {
301 rfc_send_ua (p_port->rfc.p_mcb, p_port->dlci);
302 p_port->rfc.state = RFC_STATE_OPENED;
303 }
304 return;
305 }
306 RFCOMM_TRACE_WARNING ("Port state term_wait_sec_check Event ignored %d", event);
307 }
308
309
310 /*******************************************************************************
311 **
312 ** Function rfc_port_sm_orig_wait_sec_check
313 **
314 ** Description This function handles events for the port in the
315 ** ORIG_WAIT_SEC_CHECK state. RFCOMM is waiting for Security
316 ** manager to finish before sending SABME to the peer
317 **
318 ** Returns void
319 **
320 *******************************************************************************/
rfc_port_sm_orig_wait_sec_check(tPORT * p_port,UINT16 event,void * p_data)321 void rfc_port_sm_orig_wait_sec_check (tPORT *p_port, UINT16 event, void *p_data)
322 {
323 switch (event) {
324 case RFC_EVENT_SEC_COMPLETE:
325 if (*((UINT8 *)p_data) != BTM_SUCCESS) {
326 p_port->rfc.p_mcb->is_disc_initiator = 1;
327 PORT_DlcEstablishCnf (p_port->rfc.p_mcb, p_port->dlci, 0, RFCOMM_SECURITY_ERR);
328 rfc_port_closed (p_port);
329 return;
330 }
331 rfc_send_sabme (p_port->rfc.p_mcb, p_port->dlci);
332 rfc_port_timer_start (p_port, RFC_PORT_T1_TIMEOUT);
333 p_port->rfc.state = RFC_STATE_SABME_WAIT_UA;
334 return;
335
336 case RFC_EVENT_OPEN:
337 case RFC_EVENT_SABME: /* Peer should not use the same dlci */
338 RFCOMM_TRACE_ERROR ("Port error state %d event %d", p_port->rfc.state, event);
339 return;
340
341 case RFC_EVENT_CLOSE:
342 btm_sec_abort_access_req (p_port->rfc.p_mcb->bd_addr);
343 rfc_port_closed (p_port);
344 return;
345
346 case RFC_EVENT_DATA:
347 RFCOMM_TRACE_ERROR ("Port error state Orig Wait Sec event Data");
348 osi_free (p_data);
349 return;
350
351 case RFC_EVENT_UIH:
352 osi_free (p_data);
353 return;
354 }
355 RFCOMM_TRACE_WARNING ("Port state orig_wait_sec_check Event ignored %d", event);
356 }
357
358
359 /*******************************************************************************
360 **
361 ** Function rfc_port_sm_opened
362 **
363 ** Description This function handles events for the port in the OPENED
364 ** state
365 **
366 ** Returns void
367 **
368 *******************************************************************************/
rfc_port_sm_opened(tPORT * p_port,UINT16 event,void * p_data)369 void rfc_port_sm_opened (tPORT *p_port, UINT16 event, void *p_data)
370 {
371 switch (event) {
372 case RFC_EVENT_OPEN:
373 RFCOMM_TRACE_ERROR ("Port error state %d event %d", p_port->rfc.state, event);
374 return;
375
376 case RFC_EVENT_CLOSE:
377 rfc_port_timer_start (p_port, RFC_DISC_TIMEOUT);
378 rfc_send_disc (p_port->rfc.p_mcb, p_port->dlci);
379 p_port->rfc.expected_rsp = 0;
380 p_port->rfc.state = RFC_STATE_DISC_WAIT_UA;
381 return;
382
383 case RFC_EVENT_CLEAR:
384 rfc_port_closed (p_port);
385 return;
386
387 case RFC_EVENT_DATA:
388 /* Send credits in the frame. Pass them in the layer specific member of the hdr. */
389 /* There might be an initial case when we reduced rx_max and credit_rx is still */
390 /* bigger. Make sure that we do not send 255 */
391 if ((p_port->rfc.p_mcb->flow == PORT_FC_CREDIT)
392 && (((BT_HDR *)p_data)->len < p_port->peer_mtu)
393 && (!p_port->rx.user_fc)
394 && (p_port->credit_rx_max > p_port->credit_rx)) {
395 ((BT_HDR *)p_data)->layer_specific = (UINT8) (p_port->credit_rx_max - p_port->credit_rx);
396 p_port->credit_rx = p_port->credit_rx_max;
397 } else {
398 ((BT_HDR *)p_data)->layer_specific = 0;
399 }
400 rfc_send_buf_uih (p_port->rfc.p_mcb, p_port->dlci, (BT_HDR *)p_data);
401 rfc_dec_credit (p_port);
402 return;
403
404 case RFC_EVENT_UA:
405 return;
406
407 case RFC_EVENT_SABME:
408 rfc_send_ua (p_port->rfc.p_mcb, p_port->dlci);
409 return;
410
411 case RFC_EVENT_DM:
412 PORT_DlcReleaseInd (p_port->rfc.p_mcb, p_port->dlci);
413 rfc_port_closed (p_port);
414 return;
415
416 case RFC_EVENT_DISC:
417 p_port->rfc.state = RFC_STATE_CLOSED;
418 rfc_send_ua (p_port->rfc.p_mcb, p_port->dlci);
419 if (! fixed_queue_is_empty(p_port->rx.queue)) {
420 /* give a chance to upper stack to close port properly */
421 RFCOMM_TRACE_DEBUG("port queue is not empty");
422 rfc_port_timer_start (p_port, RFC_DISC_TIMEOUT);
423 } else {
424 PORT_DlcReleaseInd (p_port->rfc.p_mcb, p_port->dlci);
425 }
426 return;
427
428 case RFC_EVENT_UIH:
429 rfc_port_uplink_data (p_port, (BT_HDR *)p_data);
430 return;
431
432 case RFC_EVENT_TIMEOUT:
433 Port_TimeOutCloseMux( p_port->rfc.p_mcb ) ;
434 RFCOMM_TRACE_ERROR ("Port error state %d event %d", p_port->rfc.state, event);
435 return;
436 }
437 RFCOMM_TRACE_WARNING ("Port state opened Event ignored %d", event);
438 }
439
440
441 /*******************************************************************************
442 **
443 ** Function rfc_port_sm_disc_wait_ua
444 **
445 ** Description This function handles events when DISC on the DLC was
446 ** sent and SM is waiting for UA or DM.
447 **
448 ** Returns void
449 **
450 *******************************************************************************/
rfc_port_sm_disc_wait_ua(tPORT * p_port,UINT16 event,void * p_data)451 void rfc_port_sm_disc_wait_ua (tPORT *p_port, UINT16 event, void *p_data)
452 {
453 switch (event) {
454 case RFC_EVENT_OPEN:
455 case RFC_EVENT_ESTABLISH_RSP:
456 RFCOMM_TRACE_ERROR ("Port error state %d event %d", p_port->rfc.state, event);
457 return;
458
459 case RFC_EVENT_CLEAR:
460 rfc_port_closed (p_port);
461 return;
462
463 case RFC_EVENT_DATA:
464 osi_free (p_data);
465 return;
466
467 case RFC_EVENT_UA:
468 p_port->rfc.p_mcb->is_disc_initiator = 1;
469 /* Case falls through */
470
471 case RFC_EVENT_DM:
472 rfc_port_closed (p_port);
473 return;
474
475 case RFC_EVENT_SABME:
476 rfc_send_dm (p_port->rfc.p_mcb, p_port->dlci, 1);
477 return;
478
479 case RFC_EVENT_DISC:
480 rfc_send_dm (p_port->rfc.p_mcb, p_port->dlci, 1);
481 return;
482
483 case RFC_EVENT_UIH:
484 osi_free (p_data);
485 rfc_send_dm (p_port->rfc.p_mcb, p_port->dlci, 0);
486 return;
487
488 case RFC_EVENT_TIMEOUT:
489 rfc_port_closed (p_port);
490 return;
491 }
492
493 RFCOMM_TRACE_WARNING ("Port state disc_wait_ua Event ignored %d", event);
494 }
495
496
497 /*******************************************************************************
498 **
499 ** Function rfc_port_uplink_data
500 **
501 ** Description This function handles uplink information data frame.
502 **
503 *******************************************************************************/
rfc_port_uplink_data(tPORT * p_port,BT_HDR * p_buf)504 void rfc_port_uplink_data (tPORT *p_port, BT_HDR *p_buf)
505 {
506 PORT_DataInd (p_port->rfc.p_mcb, p_port->dlci, p_buf);
507 }
508
509
510 /*******************************************************************************
511 **
512 ** Function rfc_process_pn
513 **
514 ** Description This function handles DLC parameter negotiation frame.
515 ** Record MTU and pass indication to the upper layer.
516 **
517 *******************************************************************************/
rfc_process_pn(tRFC_MCB * p_mcb,BOOLEAN is_command,MX_FRAME * p_frame)518 void rfc_process_pn (tRFC_MCB *p_mcb, BOOLEAN is_command, MX_FRAME *p_frame)
519 {
520 tPORT *p_port;
521 UINT8 dlci = p_frame->dlci;
522
523 if (is_command) {
524 /* Ignore if Multiplexer is being shut down */
525 if (p_mcb->state != RFC_MX_STATE_DISC_WAIT_UA) {
526 PORT_ParNegInd (p_mcb, dlci, p_frame->u.pn.mtu,
527 p_frame->u.pn.conv_layer, p_frame->u.pn.k);
528 } else {
529 rfc_send_dm(p_mcb, dlci, 0);
530 RFCOMM_TRACE_WARNING("***** MX PN while disconnecting *****");
531 }
532
533 return;
534 }
535 /* If we are not awaiting response just ignore it */
536 p_port = port_find_mcb_dlci_port (p_mcb, dlci);
537 if ((p_port == NULL) || !(p_port->rfc.expected_rsp & RFC_RSP_PN)) {
538 return;
539 }
540
541 p_port->rfc.expected_rsp &= ~RFC_RSP_PN;
542
543 rfc_port_timer_stop (p_port);
544
545 PORT_ParNegCnf (p_mcb, dlci, p_frame->u.pn.mtu,
546 p_frame->u.pn.conv_layer, p_frame->u.pn.k);
547 }
548
549
550 /*******************************************************************************
551 **
552 ** Function rfc_process_rpn
553 **
554 ** Description This function handles Remote DLC parameter negotiation
555 ** command/response. Pass command to the user.
556 **
557 *******************************************************************************/
rfc_process_rpn(tRFC_MCB * p_mcb,BOOLEAN is_command,BOOLEAN is_request,MX_FRAME * p_frame)558 void rfc_process_rpn (tRFC_MCB *p_mcb, BOOLEAN is_command,
559 BOOLEAN is_request, MX_FRAME *p_frame)
560 {
561 tPORT_STATE port_pars;
562 tPORT *p_port;
563
564 if ((p_port = port_find_mcb_dlci_port (p_mcb, p_frame->dlci)) == NULL) {
565 /* This is the first command on the port */
566 if (is_command) {
567
568 memset(&port_pars, 0, sizeof(tPORT_STATE));
569 rfc_set_port_state(&port_pars, p_frame);
570
571 PORT_PortNegInd(p_mcb, p_frame->dlci, &port_pars, p_frame->u.rpn.param_mask);
572 }
573 return;
574 }
575
576 if (is_command && is_request) {
577 /* This is the special situation when peer just request local pars */
578 port_pars = p_port->peer_port_pars;
579 rfc_send_rpn (p_mcb, p_frame->dlci, 0, &p_port->peer_port_pars, 0);
580 return;
581 }
582
583 port_pars = p_port->peer_port_pars;
584
585 rfc_set_port_state(&port_pars, p_frame);
586
587 if (is_command) {
588 PORT_PortNegInd (p_mcb, p_frame->dlci, &port_pars, p_frame->u.rpn.param_mask);
589 return;
590 }
591
592 /* If we are not awaiting response just ignore it */
593 p_port = port_find_mcb_dlci_port (p_mcb, p_frame->dlci);
594 if ((p_port == NULL) || !(p_port->rfc.expected_rsp & (RFC_RSP_RPN | RFC_RSP_RPN_REPLY))) {
595 return;
596 }
597
598 /* If we sent a request for port parameters to the peer he is replying with */
599 /* mask 0. */
600 rfc_port_timer_stop (p_port);
601
602 if (p_port->rfc.expected_rsp & RFC_RSP_RPN_REPLY) {
603 p_port->rfc.expected_rsp &= ~RFC_RSP_RPN_REPLY;
604
605 p_port->peer_port_pars = port_pars;
606
607 if ((port_pars.fc_type == (RFCOMM_FC_RTR_ON_INPUT | RFCOMM_FC_RTR_ON_OUTPUT))
608 || (port_pars.fc_type == (RFCOMM_FC_RTC_ON_INPUT | RFCOMM_FC_RTC_ON_OUTPUT))) {
609 /* This is satisfactory port parameters. Set mask as it was Ok */
610 p_frame->u.rpn.param_mask = RFCOMM_RPN_PM_MASK;
611 } else {
612 /* Current peer parameters are not good, try to fix them */
613 p_port->peer_port_pars.fc_type = (RFCOMM_FC_RTR_ON_INPUT | RFCOMM_FC_RTR_ON_OUTPUT);
614
615 p_port->rfc.expected_rsp |= RFC_RSP_RPN;
616 rfc_send_rpn (p_mcb, p_frame->dlci, 1, &p_port->peer_port_pars,
617 RFCOMM_RPN_PM_RTR_ON_INPUT | RFCOMM_RPN_PM_RTR_ON_OUTPUT);
618 rfc_port_timer_start (p_port, RFC_T2_TIMEOUT) ;
619 return;
620 }
621 } else {
622 p_port->rfc.expected_rsp &= ~RFC_RSP_RPN;
623 }
624
625 /* Check if all suggested parameters were accepted */
626 if (((p_frame->u.rpn.param_mask & (RFCOMM_RPN_PM_RTR_ON_INPUT | RFCOMM_RPN_PM_RTR_ON_OUTPUT)) ==
627 (RFCOMM_RPN_PM_RTR_ON_INPUT | RFCOMM_RPN_PM_RTR_ON_OUTPUT))
628 || ((p_frame->u.rpn.param_mask & (RFCOMM_RPN_PM_RTC_ON_INPUT | RFCOMM_RPN_PM_RTC_ON_OUTPUT)) ==
629 (RFCOMM_RPN_PM_RTC_ON_INPUT | RFCOMM_RPN_PM_RTC_ON_OUTPUT))) {
630 PORT_PortNegCnf (p_mcb, p_port->dlci, &port_pars, RFCOMM_SUCCESS);
631 return;
632 }
633
634 /* If we were proposing RTR flow control try RTC flow control */
635 /* If we were proposing RTC flow control try no flow control */
636 /* otherwise drop the connection */
637 if (p_port->peer_port_pars.fc_type == (RFCOMM_FC_RTR_ON_INPUT | RFCOMM_FC_RTR_ON_OUTPUT)) {
638 /* Current peer parameters are not good, try to fix them */
639 p_port->peer_port_pars.fc_type = (RFCOMM_FC_RTC_ON_INPUT | RFCOMM_FC_RTC_ON_OUTPUT);
640
641 p_port->rfc.expected_rsp |= RFC_RSP_RPN;
642
643 rfc_send_rpn (p_mcb, p_frame->dlci, 1, &p_port->peer_port_pars,
644 RFCOMM_RPN_PM_RTC_ON_INPUT | RFCOMM_RPN_PM_RTC_ON_OUTPUT);
645 rfc_port_timer_start (p_port, RFC_T2_TIMEOUT) ;
646 return;
647 }
648
649 /* Other side does not support flow control */
650 if (p_port->peer_port_pars.fc_type == (RFCOMM_FC_RTC_ON_INPUT | RFCOMM_FC_RTC_ON_OUTPUT)) {
651 p_port->peer_port_pars.fc_type = RFCOMM_FC_OFF;
652 PORT_PortNegCnf (p_mcb, p_port->dlci, &port_pars, RFCOMM_SUCCESS);
653 }
654 }
655
656
657 /*******************************************************************************
658 **
659 ** Function rfc_process_msc
660 **
661 ** Description This function handles Modem Status Command.
662 ** Pass command to the user.
663 **
664 *******************************************************************************/
rfc_process_msc(tRFC_MCB * p_mcb,BOOLEAN is_command,MX_FRAME * p_frame)665 void rfc_process_msc (tRFC_MCB *p_mcb, BOOLEAN is_command, MX_FRAME *p_frame)
666 {
667 tPORT_CTRL pars;
668 tPORT *p_port;
669 UINT8 modem_signals = p_frame->u.msc.signals;
670 BOOLEAN new_peer_fc = 0;
671
672 p_port = port_find_mcb_dlci_port (p_mcb, p_frame->dlci);
673 if (p_port == NULL) {
674 return;
675 }
676
677 pars.modem_signal = 0;
678
679 if (modem_signals & RFCOMM_MSC_RTC) {
680 pars.modem_signal |= MODEM_SIGNAL_DTRDSR;
681 }
682
683 if (modem_signals & RFCOMM_MSC_RTR) {
684 pars.modem_signal |= MODEM_SIGNAL_RTSCTS;
685 }
686
687 if (modem_signals & RFCOMM_MSC_IC) {
688 pars.modem_signal |= MODEM_SIGNAL_RI;
689 }
690
691 if (modem_signals & RFCOMM_MSC_DV) {
692 pars.modem_signal |= MODEM_SIGNAL_DCD;
693 }
694
695 pars.fc = ((modem_signals & RFCOMM_MSC_FC) == RFCOMM_MSC_FC);
696
697 pars.break_signal = (p_frame->u.msc.break_present) ?
698 p_frame->u.msc.break_duration : 0;
699 pars.discard_buffers = 0;
700 pars.break_signal_seq = RFCOMM_CTRL_BREAK_IN_SEQ; /* this is default */
701
702 /* Check if this command is passed only to indicate flow control */
703 if (is_command) {
704 rfc_send_msc (p_mcb, p_frame->dlci, 0, &pars);
705
706 if (p_port->rfc.p_mcb->flow != PORT_FC_CREDIT) {
707 /* Spec 1.1 indicates that only FC bit is used for flow control */
708 p_port->peer_ctrl.fc = new_peer_fc = pars.fc;
709
710 if (new_peer_fc != p_port->tx.peer_fc) {
711 PORT_FlowInd (p_mcb, p_frame->dlci, (BOOLEAN)!new_peer_fc);
712 }
713 }
714
715 PORT_ControlInd (p_mcb, p_frame->dlci, &pars);
716
717 return;
718 }
719
720 /* If we are not awaiting response just ignore it */
721 if (!(p_port->rfc.expected_rsp & RFC_RSP_MSC)) {
722 return;
723 }
724
725 p_port->rfc.expected_rsp &= ~RFC_RSP_MSC;
726
727 rfc_port_timer_stop (p_port);
728
729 PORT_ControlCnf (p_port->rfc.p_mcb, p_port->dlci, &pars);
730 }
731
732
733 /*******************************************************************************
734 **
735 ** Function rfc_process_rls
736 **
737 ** Description This function handles Remote Line Status command.
738 ** Pass command to the user.
739 **
740 *******************************************************************************/
rfc_process_rls(tRFC_MCB * p_mcb,BOOLEAN is_command,MX_FRAME * p_frame)741 void rfc_process_rls (tRFC_MCB *p_mcb, BOOLEAN is_command, MX_FRAME *p_frame)
742 {
743 tPORT *p_port;
744
745 if (is_command) {
746 PORT_LineStatusInd (p_mcb, p_frame->dlci, p_frame->u.rls.line_status);
747 rfc_send_rls (p_mcb, p_frame->dlci, 0, p_frame->u.rls.line_status);
748 } else {
749 p_port = port_find_mcb_dlci_port (p_mcb, p_frame->dlci);
750
751 /* If we are not awaiting response just ignore it */
752 if (!p_port || !(p_port->rfc.expected_rsp & RFC_RSP_RLS)) {
753 return;
754 }
755
756 p_port->rfc.expected_rsp &= ~RFC_RSP_RLS;
757
758 rfc_port_timer_stop (p_port);
759 }
760 }
761
762
763 /*******************************************************************************
764 **
765 ** Function rfc_process_nsc
766 **
767 ** Description This function handles None Supported Command frame.
768 **
769 *******************************************************************************/
rfc_process_nsc(tRFC_MCB * p_mcb,MX_FRAME * p_frame)770 void rfc_process_nsc (tRFC_MCB *p_mcb, MX_FRAME *p_frame)
771 {
772 UNUSED(p_mcb);
773 UNUSED(p_frame);
774 }
775
776
777 /*******************************************************************************
778 **
779 ** Function rfc_process_test
780 **
781 ** Description This function handles Test frame. If this is a command
782 ** reply to it. Otherwise pass response to the user.
783 **
784 *******************************************************************************/
rfc_process_test_rsp(tRFC_MCB * p_mcb,BT_HDR * p_buf)785 void rfc_process_test_rsp (tRFC_MCB *p_mcb, BT_HDR *p_buf)
786 {
787 UNUSED(p_mcb);
788
789 osi_free (p_buf);
790 }
791
792
793 /*******************************************************************************
794 **
795 ** Function rfc_process_fcon
796 **
797 ** Description This function handles FCON frame. The peer entity is able
798 ** to receive new information
799 **
800 *******************************************************************************/
rfc_process_fcon(tRFC_MCB * p_mcb,BOOLEAN is_command)801 void rfc_process_fcon (tRFC_MCB *p_mcb, BOOLEAN is_command)
802 {
803 if (is_command) {
804 rfc_cb.rfc.peer_rx_disabled = 0;
805
806 rfc_send_fcon (p_mcb, 0);
807
808 if (!p_mcb->l2cap_congested) {
809 PORT_FlowInd (p_mcb, 0, 1);
810 }
811 }
812 }
813
814 /*******************************************************************************
815 **
816 ** Function rfc_process_fcoff
817 **
818 ** Description This function handles FCOFF frame. The peer entity is unable
819 ** to receive new information
820 **
821 *******************************************************************************/
rfc_process_fcoff(tRFC_MCB * p_mcb,BOOLEAN is_command)822 void rfc_process_fcoff (tRFC_MCB *p_mcb, BOOLEAN is_command)
823 {
824 if (is_command) {
825 rfc_cb.rfc.peer_rx_disabled = 1;
826
827 if (!p_mcb->l2cap_congested) {
828 PORT_FlowInd (p_mcb, 0, 0);
829 }
830
831 rfc_send_fcoff (p_mcb, 0);
832 }
833 }
834
835
836 /*******************************************************************************
837 **
838 ** Function rfc_process_l2cap_congestion
839 **
840 ** Description This function handles L2CAP congestion messages
841 **
842 *******************************************************************************/
rfc_process_l2cap_congestion(tRFC_MCB * p_mcb,BOOLEAN is_congested)843 void rfc_process_l2cap_congestion (tRFC_MCB *p_mcb, BOOLEAN is_congested)
844 {
845 p_mcb->l2cap_congested = is_congested;
846
847 if (!is_congested) {
848 rfc_check_send_cmd(p_mcb, NULL);
849 }
850
851 if (!rfc_cb.rfc.peer_rx_disabled) {
852 if (!is_congested) {
853 PORT_FlowInd (p_mcb, 0, 1);
854 } else {
855 PORT_FlowInd (p_mcb, 0, 0);
856 }
857 }
858 }
859
860 /*******************************************************************************
861 **
862 ** Function rfc_set_port_pars
863 **
864 ** Description This function sets the tPORT_STATE structure given a p_frame.
865 **
866 *******************************************************************************/
867
rfc_set_port_state(tPORT_STATE * port_pars,MX_FRAME * p_frame)868 void rfc_set_port_state(tPORT_STATE *port_pars, MX_FRAME *p_frame)
869 {
870 if (p_frame->u.rpn.param_mask & RFCOMM_RPN_PM_BIT_RATE) {
871 port_pars->baud_rate = p_frame->u.rpn.baud_rate;
872 }
873 if (p_frame->u.rpn.param_mask & RFCOMM_RPN_PM_DATA_BITS) {
874 port_pars->byte_size = p_frame->u.rpn.byte_size;
875 }
876 if (p_frame->u.rpn.param_mask & RFCOMM_RPN_PM_STOP_BITS) {
877 port_pars->stop_bits = p_frame->u.rpn.stop_bits;
878 }
879 if (p_frame->u.rpn.param_mask & RFCOMM_RPN_PM_PARITY) {
880 port_pars->parity = p_frame->u.rpn.parity;
881 }
882 if (p_frame->u.rpn.param_mask & RFCOMM_RPN_PM_PARITY_TYPE) {
883 port_pars->parity_type = p_frame->u.rpn.parity_type;
884 }
885 if (p_frame->u.rpn.param_mask & (RFCOMM_RPN_PM_XONXOFF_ON_INPUT |
886 RFCOMM_RPN_PM_XONXOFF_ON_OUTPUT |
887 RFCOMM_RPN_PM_RTR_ON_INPUT |
888 RFCOMM_RPN_PM_RTR_ON_OUTPUT |
889 RFCOMM_RPN_PM_RTC_ON_INPUT |
890 RFCOMM_RPN_PM_RTC_ON_OUTPUT)) {
891 port_pars->fc_type = p_frame->u.rpn.fc_type;
892 }
893 if (p_frame->u.rpn.param_mask & RFCOMM_RPN_PM_XON_CHAR) {
894 port_pars->xon_char = p_frame->u.rpn.xon_char;
895 }
896 if (p_frame->u.rpn.param_mask & RFCOMM_RPN_PM_XOFF_CHAR) {
897 port_pars->xoff_char = p_frame->u.rpn.xoff_char;
898 }
899 }
900
901 #endif ///(defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == 1)
902