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