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