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