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