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