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