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 module contains functions for port emulation entity and RFCOMM
22  *  communications
23  *
24  ******************************************************************************/
25 
26 #define LOG_TAG "rfcomm"
27 
28 #include <base/functional/callback.h>
29 #include <bluetooth/log.h>
30 #include <frameworks/proto_logging/stats/enums/bluetooth/enums.pb.h>
31 
32 #include <cstdint>
33 
34 #include "hal/snoop_logger.h"
35 #include "internal_include/bt_target.h"
36 #include "internal_include/bt_trace.h"
37 #include "main/shim/entry.h"
38 #include "os/logging/log_adapter.h"
39 #include "osi/include/allocator.h"
40 #include "osi/include/mutex.h"
41 #include "stack/include/bt_hdr.h"
42 #include "stack/include/bt_uuid16.h"
43 #include "stack/include/stack_metrics_logging.h"
44 #include "stack/l2cap/l2c_int.h"
45 #include "stack/rfcomm/port_int.h"
46 #include "stack/rfcomm/rfc_int.h"
47 
48 using namespace bluetooth;
49 
50 /*
51  * Local function definitions
52 */
53 uint32_t port_rfc_send_tx_data(tPORT* p_port);
54 void port_rfc_closed(tPORT* p_port, uint8_t res);
55 void port_get_credits(tPORT* p_port, uint8_t k);
56 
57 /*******************************************************************************
58  *
59  * Function         port_open_continue
60  *
61  * Description      This function is called after security manager completes
62  *                  required security checks.
63  *
64  * Returns          PORT_SUCCESS or PORT_[ERROR]
65  *
66  ******************************************************************************/
port_open_continue(tPORT * p_port)67 int port_open_continue(tPORT* p_port) {
68   log::verbose("port_open_continue, p_port:{}", fmt::ptr(p_port));
69 
70   /* Check if multiplexer channel has already been established */
71   tRFC_MCB* p_mcb = rfc_alloc_multiplexer_channel(p_port->bd_addr, true);
72   if (p_mcb == nullptr) {
73     log::warn("port_open_continue no mx channel");
74     port_release_port(p_port);
75     return (PORT_NO_RESOURCES);
76   }
77 
78   p_port->rfc.p_mcb = p_mcb;
79 
80   p_mcb->port_handles[p_port->dlci] = p_port->handle;
81 
82   /* Connection is up and we know local and remote features, select MTU */
83   port_select_mtu(p_port);
84 
85   switch (p_mcb->state) {
86     case RFC_MX_STATE_CONNECTED:
87       RFCOMM_ParameterNegotiationRequest(p_mcb, p_port->dlci, p_port->mtu);
88       log::verbose("Multiplexer already connected peer:{} state:{} cid:{}",
89                    p_port->bd_addr, p_mcb->state, p_mcb->lcid);
90       break;
91 
92     case RFC_MX_STATE_IDLE:
93     case RFC_MX_STATE_DISC_WAIT_UA:
94       // In RFC_MX_STATE_IDLE state, MX state machine will create connection
95       // In RFC_MX_STATE_DISC_WAIT_UA state, MX state machine will recreate
96       // connection after disconnecting is completed
97       RFCOMM_StartReq(p_mcb);
98       log::verbose("Starting multiplexer connect peer:{} state:{} cid:{}",
99                    p_port->bd_addr, p_mcb->state, p_mcb->lcid);
100       break;
101 
102     default:
103       // MX state machine ignores RFC_MX_EVENT_START_REQ in these states
104       // When it enters RFC_MX_STATE_CONNECTED, it will check any opening ports
105       log::verbose("Ignoring RFC_MX_EVENT_START_REQ peer:{} state:{} cid:{}",
106                    p_port->bd_addr, p_mcb->state, p_mcb->lcid);
107       break;
108   }
109   return (PORT_SUCCESS);
110 }
111 
112 /*******************************************************************************
113  *
114  * Function         port_start_control
115  *
116  * Description      This function is called in the BTU_TASK context to
117  *                  send control information
118  *
119  ******************************************************************************/
port_start_control(tPORT * p_port)120 void port_start_control(tPORT* p_port) {
121   tRFC_MCB* p_mcb = p_port->rfc.p_mcb;
122 
123   if (p_mcb == NULL) return;
124 
125   RFCOMM_ControlReq(p_mcb, p_port->dlci, &p_port->local_ctrl);
126 }
127 
128 /*******************************************************************************
129  *
130  * Function         port_start_par_neg
131  *
132  * Description      This function is called in the BTU_TASK context to
133  *                  send configuration information
134  *
135  ******************************************************************************/
port_start_par_neg(tPORT * p_port)136 void port_start_par_neg(tPORT* p_port) {
137   tRFC_MCB* p_mcb = p_port->rfc.p_mcb;
138 
139   if (p_mcb == NULL) return;
140 
141   RFCOMM_PortParameterNegotiationRequest(p_mcb, p_port->dlci,
142                                          &p_port->user_port_pars);
143 }
144 
145 /*******************************************************************************
146  *
147  * Function         port_start_close
148  *
149  * Description      This function is called in the BTU_TASK context to
150  *                  release DLC
151  *
152  ******************************************************************************/
port_start_close(tPORT * p_port)153 void port_start_close(tPORT* p_port) {
154   tRFC_MCB* p_mcb = p_port->rfc.p_mcb;
155   uint8_t old_signals;
156   uint32_t events = 0;
157 
158   /* At first indicate to the user that signals on the connection were dropped
159    */
160   p_port->line_status |= LINE_STATUS_FAILED;
161   old_signals = p_port->peer_ctrl.modem_signal;
162 
163   p_port->peer_ctrl.modem_signal &=
164       ~(PORT_DTRDSR_ON | PORT_CTSRTS_ON | PORT_DCD_ON);
165 
166   events |= port_get_signal_changes(p_port, old_signals,
167                                     p_port->peer_ctrl.modem_signal);
168 
169   if (p_port->ev_mask & PORT_EV_CONNECT_ERR) events |= PORT_EV_CONNECT_ERR;
170 
171   if (p_port->ev_mask & PORT_EV_ERR) events |= PORT_EV_ERR;
172 
173   if ((p_port->p_callback != NULL) && events)
174     p_port->p_callback(events, p_port->handle);
175 
176   /* Check if RFCOMM side has been closed while the message was queued */
177   if ((p_mcb == NULL) || (p_port->rfc.state == RFC_STATE_CLOSED)) {
178     /* Call management callback function before calling port_release_port() to
179      * clear tPort */
180     if (p_port->p_mgmt_callback) {
181       p_port->p_mgmt_callback(PORT_CLOSED, p_port->handle);
182       log_counter_metrics(
183           android::bluetooth::CodePathCounterKeyEnum::RFCOMM_PORT_START_CLOSE,
184           1);
185     }
186 
187     port_release_port(p_port);
188   } else {
189     RFCOMM_DlcReleaseReq(p_mcb, p_port->dlci);
190   }
191 }
192 
193 /*******************************************************************************
194  *
195  * Function         PORT_StartCnf
196  *
197  * Description      This function is called from the RFCOMM layer when
198  *                  establishing of the multiplexer channel is completed.
199  *                  Continue establishing of the connection for all ports that
200  *                  are in the OPENING state
201  *
202  ******************************************************************************/
PORT_StartCnf(tRFC_MCB * p_mcb,uint16_t result)203 void PORT_StartCnf(tRFC_MCB* p_mcb, uint16_t result) {
204   bool no_ports_up = true;
205 
206   log::verbose("result {}", result);
207 
208   tPORT* p_port = &rfc_cb.port.port[0];
209   for (int i = 0; i < MAX_RFC_PORTS; i++, p_port++) {
210     if (p_port->rfc.p_mcb == p_mcb) {
211       no_ports_up = false;
212 
213       if (result == RFCOMM_SUCCESS) {
214         log::verbose("dlci {}", p_port->dlci);
215         RFCOMM_ParameterNegotiationRequest(p_mcb, p_port->dlci, p_port->mtu);
216       } else {
217         log::warn("Unable start configuration dlci:{} result:{}", p_port->dlci,
218                   result);
219 
220         rfc_release_multiplexer_channel(p_mcb);
221 
222         /* Send event to the application */
223         if (p_port->p_callback && (p_port->ev_mask & PORT_EV_CONNECT_ERR)) {
224           (p_port->p_callback)(PORT_EV_CONNECT_ERR, p_port->handle);
225         }
226 
227         if (p_port->p_mgmt_callback) {
228           p_port->p_mgmt_callback(PORT_START_FAILED, p_port->handle);
229           log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::
230                                   RFCOMM_PORT_START_CNF_FAILED,
231                               1);
232         }
233         port_release_port(p_port);
234       }
235     }
236   }
237 
238   /* There can be a situation when after starting connection, user closes the */
239   /* port, we can catch it here to close multiplexor channel */
240   if (no_ports_up) {
241     rfc_check_mcb_active(p_mcb);
242   }
243 }
244 
245 /*******************************************************************************
246  *
247  * Function         PORT_StartInd
248  *
249  * Description      This function is called from the RFCOMM layer when
250  *                  some peer device wants to establish a multiplexer
251  *                  connection.  Check if there are any ports open with this
252  *                  or not assigned multiplexer.
253  *
254  ******************************************************************************/
PORT_StartInd(tRFC_MCB * p_mcb)255 void PORT_StartInd(tRFC_MCB* p_mcb) {
256   tPORT* p_port;
257   int i;
258 
259   log::verbose("PORT_StartInd");
260 
261   p_port = &rfc_cb.port.port[0];
262   for (i = 0; i < MAX_RFC_PORTS; i++, p_port++) {
263     if ((p_port->rfc.p_mcb == NULL) || (p_port->rfc.p_mcb == p_mcb)) {
264       log::verbose("PORT_StartInd, RFCOMM_StartRsp RFCOMM_SUCCESS: p_mcb:{}",
265                    fmt::ptr(p_mcb));
266       RFCOMM_StartRsp(p_mcb, RFCOMM_SUCCESS);
267       return;
268     }
269   }
270   RFCOMM_StartRsp(p_mcb, RFCOMM_ERROR);
271 }
272 
273 /*******************************************************************************
274  *
275  * Function         PORT_ParNegInd
276  *
277  * Description      This function is called from the RFCOMM layer to change
278  *                  DLCI parameters (currently only MTU is negotiated).
279  *                  If can not find the port do not accept the request.
280  *                  Otherwise save the MTU size supported by the peer.
281  *
282  ******************************************************************************/
PORT_ParNegInd(tRFC_MCB * p_mcb,uint8_t dlci,uint16_t mtu,uint8_t cl,uint8_t k)283 void PORT_ParNegInd(tRFC_MCB* p_mcb, uint8_t dlci, uint16_t mtu, uint8_t cl,
284                     uint8_t k) {
285   log::verbose("bd_addr={}, dlci={}, mtu={}", p_mcb->bd_addr, dlci, mtu);
286   tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci);
287   if (!p_port) {
288     /* This can be a first request for this port */
289     p_port = port_find_dlci_port(dlci);
290     if (!p_port) {
291       log::error(
292           "Disconnect RFCOMM, port not found, dlci={}, p_mcb={}, bd_addr={}",
293           dlci, fmt::ptr(p_mcb), p_mcb->bd_addr);
294       /* If the port cannot be opened, send a DM.  Per Errata 1205 */
295       rfc_send_dm(p_mcb, dlci, false);
296       /* check if this is the last port open, some headsets have
297       problem, they don't disconnect if we send DM */
298       rfc_check_mcb_active(p_mcb);
299       return;
300     }
301     log::verbose("port_handles[dlci:{}]:{}->{}", dlci,
302                  p_mcb->port_handles[dlci], p_port->handle);
303     p_mcb->port_handles[dlci] = p_port->handle;
304   }
305 
306   p_port->bd_addr = p_mcb->bd_addr;
307 
308   /* Connection is up and we know local and remote features, select MTU */
309   port_select_mtu(p_port);
310 
311   p_port->rfc.p_mcb = p_mcb;
312   p_port->mtu = (p_port->mtu < mtu) ? p_port->mtu : mtu;
313   p_port->peer_mtu = p_port->mtu;
314 
315   /* Negotiate the flow control mechanism.  If flow control mechanism for */
316   /* mux has not been set yet, set it now.  If either we or peer wants TS 07.10,
317    */
318   /* use that.  Otherwise both must want credit based, so use that. If flow is
319    */
320   /* already defined for this mux, we respond with that value. */
321   if (p_mcb->flow == PORT_FC_UNDEFINED) {
322     if (cl == RFCOMM_PN_CONV_LAYER_TYPE_1) {
323       p_mcb->flow = PORT_FC_TS710;
324     } else {
325       p_mcb->flow = PORT_FC_CREDIT;
326     }
327   }
328 
329   /* Regardless of our flow control mechanism, if the PN cl is zero, we must */
330   /* respond with zero.  "A responding implementation must set this field to 14
331    */
332   /* if (and only if) the PN request was 15."  This could happen if a PN is sent
333    */
334   /* after the DLCI is already established-- the PN in that case must have cl =
335    * 0. */
336   /* See RFCOMM spec 5.5.3 */
337   uint8_t our_cl;
338   uint8_t our_k;
339   if (cl == RFCOMM_PN_CONV_LAYER_TYPE_1) {
340     our_cl = RFCOMM_PN_CONV_LAYER_TYPE_1;
341     our_k = 0;
342   } else if (p_mcb->flow == PORT_FC_CREDIT) {
343     /* get credits */
344     port_get_credits(p_port, k);
345 
346     /* Set convergence layer and number of credits (k) */
347     our_cl = RFCOMM_PN_CONV_LAYER_CBFC_R;
348     our_k = (p_port->credit_rx_max < RFCOMM_K_MAX) ? p_port->credit_rx_max
349                                                    : RFCOMM_K_MAX;
350     p_port->credit_rx = our_k;
351   } else {
352     /* must not be using credit based flow control; use TS 7.10 */
353     our_cl = RFCOMM_PN_CONV_LAYER_TYPE_1;
354     our_k = 0;
355   }
356   RFCOMM_ParameterNegotiationResponse(p_mcb, dlci, p_port->mtu, our_cl, our_k);
357 }
358 
359 /*******************************************************************************
360  *
361  * Function         PORT_ParNegCnf
362  *
363  * Description      This function is called from the RFCOMM layer to change
364  *                  DLCI parameters (currently only MTU is negotiated).
365  *                  Save the MTU size supported by the peer.
366  *                  If the confirmation is received during the port opening
367  *                  procedure send EstablishRequest to continue.
368  *
369  ******************************************************************************/
PORT_ParNegCnf(tRFC_MCB * p_mcb,uint8_t dlci,uint16_t mtu,uint8_t cl,uint8_t k)370 void PORT_ParNegCnf(tRFC_MCB* p_mcb, uint8_t dlci, uint16_t mtu, uint8_t cl,
371                     uint8_t k) {
372   log::verbose("PORT_ParNegCnf dlci:{} mtu:{} cl: {} k: {}", dlci, mtu, cl, k);
373   tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci);
374   if (!p_port) {
375     log::warn("port is null for {}", p_mcb->bd_addr);
376     return;
377   }
378 
379   /* Flow control mechanism not set yet.  Negotiate flow control mechanism. */
380   if (p_mcb->flow == PORT_FC_UNDEFINED) {
381     if (cl == RFCOMM_PN_CONV_LAYER_CBFC_R) {
382       // Our stack is configured for credit-based and they responded with
383       // credit-based.
384       p_mcb->flow = PORT_FC_CREDIT;
385     } else {
386       // They responded with any other value.  Treat this as negotiation to
387       // TS07.10.
388       p_mcb->flow = PORT_FC_TS710;
389     }
390   }
391   /* If mux flow control mechanism set, we honor that setting regardless of */
392   /* the CL value in their response.  This allows us to gracefully accept any */
393   /* illegal PN negotiation scenarios. */
394 
395   p_port->mtu = (p_port->mtu < mtu) ? p_port->mtu : mtu;
396   p_port->peer_mtu = p_port->mtu;
397 
398   if (p_mcb->flow == PORT_FC_CREDIT) {
399     port_get_credits(p_port, k);
400   }
401 
402   if (p_port->state == PORT_CONNECTION_STATE_OPENING)
403     RFCOMM_DlcEstablishReq(p_mcb, p_port->dlci, p_port->mtu);
404 }
405 
406 /*******************************************************************************
407  *
408  * Function         PORT_DlcEstablishInd
409  *
410  * Description      This function is called from the RFCOMM layer when peer
411  *                  device wants to establish a new DLC.  If this is not the
412  *                  first message in the establishment procedure port_handle
413  *                  has a handle to the port control block otherwise the control
414  *                  block should be found based on the muliplexer channel and
415  *                  dlci.  The block should be allocated before meaning
416  *                  that application already made open.
417  *
418  ******************************************************************************/
PORT_DlcEstablishInd(tRFC_MCB * p_mcb,uint8_t dlci,uint16_t mtu)419 void PORT_DlcEstablishInd(tRFC_MCB* p_mcb, uint8_t dlci, uint16_t mtu) {
420   tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci);
421 
422   log::verbose("p_mcb:{}, dlci:{} mtu:{}i, p_port:{}, bd_addr:{}",
423                fmt::ptr(p_mcb), dlci, mtu, fmt::ptr(p_port), p_mcb->bd_addr);
424 
425   if (!p_port) {
426     /* This can be a first request for this port */
427     p_port = port_find_dlci_port(dlci);
428     if (!p_port) {
429       RFCOMM_DlcEstablishRsp(p_mcb, dlci, 0, RFCOMM_ERROR);
430       return;
431     }
432     p_mcb->port_handles[dlci] = p_port->handle;
433   }
434 
435   /* If L2CAP's mtu less then RFCOMM's take it */
436   if (mtu && (mtu < p_port->peer_mtu)) p_port->peer_mtu = mtu;
437 
438   /* If there was an inactivity timer running for MCB stop it */
439   rfc_timer_stop(p_mcb);
440 
441   RFCOMM_DlcEstablishRsp(p_mcb, dlci, p_port->mtu, RFCOMM_SUCCESS);
442 
443   /* This is the server side.  If application wants to know when connection */
444   /* is established, thats the place */
445   if (p_port->p_callback && (p_port->ev_mask & PORT_EV_CONNECTED))
446     (p_port->p_callback)(PORT_EV_CONNECTED, p_port->handle);
447 
448   if (p_port->p_mgmt_callback) {
449     p_port->p_mgmt_callback(PORT_SUCCESS, p_port->handle);
450     log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::
451                             RFCOMM_CONNECTION_SUCCESS_IND,
452                         1);
453   }
454 
455   p_port->state = PORT_CONNECTION_STATE_OPENED;
456 }
457 
458 /*******************************************************************************
459  *
460  * Function         PORT_DlcEstablishCnf
461  *
462  * Description      This function is called from the RFCOMM layer when peer
463  *                  acknowledges establish procedure (SABME/UA).  Send reply
464  *                  to the user and set state to OPENED if result was
465  *                  successful.
466  *
467  ******************************************************************************/
PORT_DlcEstablishCnf(tRFC_MCB * p_mcb,uint8_t dlci,uint16_t mtu,uint16_t result)468 void PORT_DlcEstablishCnf(tRFC_MCB* p_mcb, uint8_t dlci, uint16_t mtu,
469                           uint16_t result) {
470   tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci);
471 
472   log::verbose("PORT_DlcEstablishCnf dlci:{} mtu:{} result:{}", dlci, mtu,
473                result);
474 
475   if (!p_port) return;
476 
477   if (result != RFCOMM_SUCCESS) {
478     log::warn("Unable to establish configuration dlci:{} result:{}", dlci,
479               result);
480     port_rfc_closed(p_port, PORT_START_FAILED);
481     log_counter_metrics(
482         android::bluetooth::CodePathCounterKeyEnum::RFCOMM_PORT_START_FAILED,
483         1);
484     return;
485   }
486 
487   /* If L2CAP's mtu less then RFCOMM's take it */
488   if (mtu && (mtu < p_port->peer_mtu)) p_port->peer_mtu = mtu;
489 
490   /* If there was an inactivity timer running for MCB stop it */
491   rfc_timer_stop(p_mcb);
492 
493   if (p_port->p_callback && (p_port->ev_mask & PORT_EV_CONNECTED))
494     (p_port->p_callback)(PORT_EV_CONNECTED, p_port->handle);
495 
496   if (p_port->p_mgmt_callback) {
497     p_port->p_mgmt_callback(PORT_SUCCESS, p_port->handle);
498     log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::
499                             RFCOMM_CONNECTION_SUCCESS_CNF,
500                         1);
501   }
502   p_port->state = PORT_CONNECTION_STATE_OPENED;
503 
504   /* RPN is required only if we want to tell DTE how the port should be opened
505    */
506   if ((p_port->uuid == UUID_SERVCLASS_DIALUP_NETWORKING) ||
507       (p_port->uuid == UUID_SERVCLASS_FAX))
508     RFCOMM_PortParameterNegotiationRequest(p_port->rfc.p_mcb, p_port->dlci,
509                                            NULL);
510   else
511     RFCOMM_ControlReq(p_port->rfc.p_mcb, p_port->dlci, &p_port->local_ctrl);
512 }
513 
514 /*******************************************************************************
515  *
516  * Function         PORT_PortNegInd
517  *
518  * Description      This function is called from the RFCOMM layer when peer
519  *                  device wants to set parameters of the port.  As per the spec
520  *                  this message has to be sent before the first data packet
521  *                  and can be sent before establish.  The block should be
522  *                  allocated before meaning that application already made open.
523  *
524  ******************************************************************************/
PORT_PortNegInd(tRFC_MCB * p_mcb,uint8_t dlci,tPORT_STATE * p_pars,uint16_t param_mask)525 void PORT_PortNegInd(tRFC_MCB* p_mcb, uint8_t dlci, tPORT_STATE* p_pars,
526                      uint16_t param_mask) {
527   tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci);
528 
529   log::verbose("PORT_PortNegInd");
530 
531   if (!p_port) {
532     /* This can be a first request for this port */
533     p_port = port_find_dlci_port(dlci);
534     if (!p_port) {
535       RFCOMM_PortParameterNegotiationResponse(p_mcb, dlci, p_pars, 0);
536       return;
537     }
538     p_mcb->port_handles[dlci] = p_port->handle;
539   }
540 
541   /* Check if the flow control is acceptable on local side */
542   p_port->peer_port_pars = *p_pars;
543   RFCOMM_PortParameterNegotiationResponse(p_mcb, dlci, p_pars, param_mask);
544 }
545 
546 /*******************************************************************************
547  *
548  * Function         PORT_PortNegCnf
549  *
550  * Description      This function is called from the RFCOMM layer to change
551  *                  state for the port.  Propagate change to the user.
552  *
553  ******************************************************************************/
PORT_PortNegCnf(tRFC_MCB * p_mcb,uint8_t dlci,tPORT_STATE *,uint16_t result)554 void PORT_PortNegCnf(tRFC_MCB* p_mcb, uint8_t dlci, tPORT_STATE* /* p_pars */,
555                      uint16_t result) {
556   tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci);
557 
558   log::verbose("PORT_PortNegCnf");
559 
560   if (!p_port) {
561     log::warn("PORT_PortNegCnf no port");
562     return;
563   }
564   /* Port negotiation failed. Drop the connection */
565   if (result != RFCOMM_SUCCESS) {
566     log::warn("Unable to negotiate port state dlci:{} result:{}", dlci, result);
567     RFCOMM_DlcReleaseReq(p_mcb, p_port->dlci);
568 
569     port_rfc_closed(p_port, PORT_PORT_NEG_FAILED);
570     log_counter_metrics(
571         android::bluetooth::CodePathCounterKeyEnum::RFCOMM_PORT_NEG_FAILED, 1);
572     return;
573   }
574 
575   if (!(p_port->port_ctrl & PORT_CTRL_REQ_SENT)) {
576     RFCOMM_ControlReq(p_port->rfc.p_mcb, p_port->dlci, &p_port->local_ctrl);
577   } else {
578     log::warn("PORT_PortNegCnf Control Already sent");
579   }
580 }
581 
582 /*******************************************************************************
583  *
584  * Function         PORT_ControlInd
585  *
586  * Description      This function is called from the RFCOMM layer on the modem
587  *                  signal change.  Propagate change to the user.
588  *
589  ******************************************************************************/
PORT_ControlInd(tRFC_MCB * p_mcb,uint8_t dlci,tPORT_CTRL * p_pars)590 void PORT_ControlInd(tRFC_MCB* p_mcb, uint8_t dlci, tPORT_CTRL* p_pars) {
591   tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci);
592   uint32_t event;
593   uint8_t old_signals;
594 
595   log::verbose("PORT_ControlInd");
596 
597   if (!p_port) return;
598 
599   old_signals = p_port->peer_ctrl.modem_signal;
600 
601   event = port_get_signal_changes(p_port, old_signals, p_pars->modem_signal);
602 
603   p_port->peer_ctrl = *p_pars;
604 
605   if (!(p_port->port_ctrl & PORT_CTRL_REQ_SENT)) {
606     RFCOMM_ControlReq(p_port->rfc.p_mcb, p_port->dlci, &p_port->local_ctrl);
607   } else {
608     /* If this is the first time we received control RFCOMM is connected */
609     if (!(p_port->port_ctrl & PORT_CTRL_IND_RECEIVED)) {
610       event |= (PORT_EV_CONNECTED & p_port->ev_mask);
611     }
612 
613     if (p_port->port_ctrl & PORT_CTRL_REQ_CONFIRMED) {
614       event |= port_rfc_send_tx_data(p_port);
615     }
616   }
617 
618   p_port->port_ctrl |= (PORT_CTRL_IND_RECEIVED | PORT_CTRL_IND_RESPONDED);
619 
620   if (p_pars->break_signal) event |= (PORT_EV_BREAK & p_port->ev_mask);
621 
622   /* execute call back function only if the application is registered for events
623    */
624   if (event && p_port->p_callback) (p_port->p_callback)(event, p_port->handle);
625 
626   log::verbose("PORT_ControlInd DTR_DSR : {}, RTS_CTS : {}, RI : {}, DCD : {}",
627                (p_port->peer_ctrl.modem_signal & MODEM_SIGNAL_DTRDSR) ? 1 : 0,
628                (p_port->peer_ctrl.modem_signal & MODEM_SIGNAL_RTSCTS) ? 1 : 0,
629                (p_port->peer_ctrl.modem_signal & MODEM_SIGNAL_RI) ? 1 : 0,
630                (p_port->peer_ctrl.modem_signal & MODEM_SIGNAL_DCD) ? 1 : 0);
631 }
632 
633 /*******************************************************************************
634  *
635  * Function         PORT_ControlCnf
636  *
637  * Description      This function is called from the RFCOMM layer when
638  *                  peer acknowleges change of the modem signals.
639  *
640  ******************************************************************************/
PORT_ControlCnf(tRFC_MCB * p_mcb,uint8_t dlci,tPORT_CTRL *)641 void PORT_ControlCnf(tRFC_MCB* p_mcb, uint8_t dlci, tPORT_CTRL* /* p_pars */) {
642   tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci);
643   uint32_t event = 0;
644 
645   log::verbose("PORT_ControlCnf");
646 
647   if (!p_port) return;
648 
649   if (!(p_port->port_ctrl & PORT_CTRL_REQ_CONFIRMED)) {
650     p_port->port_ctrl |= PORT_CTRL_REQ_CONFIRMED;
651 
652     if (p_port->port_ctrl & PORT_CTRL_IND_RECEIVED)
653       event = (p_port->ev_mask & PORT_EV_CONNECTED);
654   }
655 
656   if (p_port->port_ctrl & PORT_CTRL_IND_RECEIVED) {
657     event |= port_rfc_send_tx_data(p_port);
658   }
659 
660   /* execute call back function only if the application is registered for events
661    */
662   if (event && p_port->p_callback) (p_port->p_callback)(event, p_port->handle);
663 }
664 
665 /*******************************************************************************
666  *
667  * Function         PORT_LineStatusInd
668  *
669  * Description      This function is called from the RFCOMM layer when
670  *                  peer indicates change in the line status
671  *
672  ******************************************************************************/
PORT_LineStatusInd(tRFC_MCB * p_mcb,uint8_t dlci,uint8_t line_status)673 void PORT_LineStatusInd(tRFC_MCB* p_mcb, uint8_t dlci, uint8_t line_status) {
674   tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci);
675   uint32_t event = 0;
676 
677   log::verbose("PORT_LineStatusInd");
678 
679   if (!p_port) return;
680 
681   p_port->line_status |= line_status;
682 
683   if (line_status & PORT_ERR_OVERRUN) event |= PORT_EV_OVERRUN;
684 
685   if (line_status & PORT_ERR_BREAK) event |= PORT_EV_BREAK;
686 
687   if (line_status & ~(PORT_ERR_OVERRUN | PORT_ERR_BREAK)) event |= PORT_EV_ERR;
688 
689   if ((p_port->p_callback != NULL) && (p_port->ev_mask & event))
690     p_port->p_callback((p_port->ev_mask & event), p_port->handle);
691 }
692 
693 /*******************************************************************************
694  *
695  * Function         PORT_DlcReleaseInd
696  *
697  * Description      This function is called from the RFCOMM layer when
698  *                  DLC connection is released.
699  *
700  ******************************************************************************/
PORT_DlcReleaseInd(tRFC_MCB * p_mcb,uint8_t dlci)701 void PORT_DlcReleaseInd(tRFC_MCB* p_mcb, uint8_t dlci) {
702   log::verbose("dlci:{}, bd_addr:{}", dlci, p_mcb->bd_addr);
703   tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci);
704   if (!p_port) return;
705   port_rfc_closed(p_port, PORT_CLOSED);
706   log_counter_metrics(
707       android::bluetooth::CodePathCounterKeyEnum::RFCOMM_PORT_CLOSED, 1);
708 }
709 
710 /*******************************************************************************
711  *
712  * Function         PORT_CloseInd
713  *
714  * Description      This function is called from the RFCOMM layer when
715  *                  multiplexer connection is released.
716  *
717  ******************************************************************************/
PORT_CloseInd(tRFC_MCB * p_mcb)718 void PORT_CloseInd(tRFC_MCB* p_mcb) {
719   tPORT* p_port;
720   int i;
721 
722   log::verbose("PORT_CloseInd");
723 
724   p_port = &rfc_cb.port.port[0];
725   for (i = 0; i < MAX_RFC_PORTS; i++, p_port++) {
726     if (p_port->rfc.p_mcb == p_mcb) {
727       port_rfc_closed(p_port, PORT_PEER_CONNECTION_FAILED);
728       log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::
729                               RFCOMM_PORT_PEER_CONNECTION_FAILED,
730                           1);
731     }
732   }
733   rfc_release_multiplexer_channel(p_mcb);
734 }
735 
736 /*******************************************************************************
737  *
738  * Function         PORT_TimeOutCloseMux
739  *
740  * Description      This function is called when RFCOMM timesout on a command
741  *                  as a result multiplexer connection is closed.
742  *
743  ******************************************************************************/
PORT_TimeOutCloseMux(tRFC_MCB * p_mcb)744 void PORT_TimeOutCloseMux(tRFC_MCB* p_mcb) {
745   tPORT* p_port;
746   int i;
747 
748   log::verbose("PORT_TimeOutCloseMux");
749 
750   p_port = &rfc_cb.port.port[0];
751   for (i = 0; i < MAX_RFC_PORTS; i++, p_port++) {
752     if (p_port->rfc.p_mcb == p_mcb) {
753       port_rfc_closed(p_port, PORT_PEER_TIMEOUT);
754       log_counter_metrics(
755           android::bluetooth::CodePathCounterKeyEnum::RFCOMM_PORT_PEER_TIMEOUT,
756           1);
757     }
758   }
759 }
760 
761 /*******************************************************************************
762  *
763  * Function         PORT_DataInd
764  *
765  * Description      This function is called from the RFCOMM layer when data
766  *                  buffer is received from the peer.
767  *
768  ******************************************************************************/
PORT_DataInd(tRFC_MCB * p_mcb,uint8_t dlci,BT_HDR * p_buf)769 void PORT_DataInd(tRFC_MCB* p_mcb, uint8_t dlci, BT_HDR* p_buf) {
770   tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci);
771   uint8_t rx_char1;
772   uint32_t events = 0;
773   uint8_t* p;
774   int i;
775 
776   log::verbose("PORT_DataInd with data length {}, p_mcb:{},p_port:{},dlci:{}",
777                p_buf->len, fmt::ptr(p_mcb), fmt::ptr(p_port), dlci);
778   if (!p_port) {
779     osi_free(p_buf);
780     return;
781   }
782   /* If client registered callout callback with flow control we can just deliver
783    * receive data */
784   if (p_port->p_data_co_callback) {
785     /* Another packet is delivered to user.  Send credits to peer if required */
786     if (p_port->p_data_co_callback(p_port->handle, (uint8_t*)p_buf, -1,
787                                    DATA_CO_CALLBACK_TYPE_INCOMING)) {
788       port_flow_control_peer(p_port, true, 1);
789     } else {
790       port_flow_control_peer(p_port, false, 0);
791     }
792     // osi_free(p_buf);
793     return;
794   }
795   /* If client registered callback we can just deliver receive data */
796   if (p_port->p_data_callback) {
797     /* Another packet is delivered to user.  Send credits to peer if required */
798     port_flow_control_peer(p_port, true, 1);
799     p_port->p_data_callback(p_port->handle,
800                             (uint8_t*)(p_buf + 1) + p_buf->offset, p_buf->len);
801     osi_free(p_buf);
802     return;
803   }
804   /* Check if rx queue exceeds the limit */
805   if ((p_port->rx.queue_size + p_buf->len > PORT_RX_CRITICAL_WM) ||
806       (fixed_queue_length(p_port->rx.queue) + 1 > p_port->rx_buf_critical)) {
807     log::verbose("PORT_DataInd. Buffer over run. Dropping the buffer");
808     osi_free(p_buf);
809     RFCOMM_LineStatusReq(p_mcb, dlci, LINE_STATUS_OVERRUN);
810     return;
811   }
812   /* If user registered to receive notification when a particular byte is */
813   /* received we mast check all received bytes */
814   if (((rx_char1 = p_port->user_port_pars.rx_char1) != 0) &&
815       (p_port->ev_mask & PORT_EV_RXFLAG)) {
816     for (i = 0, p = (uint8_t*)(p_buf + 1) + p_buf->offset; i < p_buf->len;
817          i++) {
818       if (*p++ == rx_char1) {
819         events |= PORT_EV_RXFLAG;
820         break;
821       }
822     }
823   }
824 
825   mutex_global_lock();
826 
827   fixed_queue_enqueue(p_port->rx.queue, p_buf);
828   p_port->rx.queue_size += p_buf->len;
829 
830   mutex_global_unlock();
831 
832   /* perform flow control procedures if necessary */
833   port_flow_control_peer(p_port, false, 0);
834 
835   /* If user indicated flow control can not deliver any notifications to them */
836   if (p_port->rx.user_fc) {
837     if (events & PORT_EV_RXFLAG) {
838       p_port->rx_flag_ev_pending = true;
839     }
840     return;
841   }
842 
843   events |= PORT_EV_RXCHAR;
844 
845   /* Mask out all events that are not of interest to user */
846   events &= p_port->ev_mask;
847 
848   if (p_port->p_callback && events) p_port->p_callback(events, p_port->handle);
849 }
850 
851 /*******************************************************************************
852  *
853  * Function         PORT_FlowInd
854  *
855  * Description      This function is called from the RFCOMM layer on the flow
856  *                  control signal change.  Propagate change to the user.
857  *
858  ******************************************************************************/
PORT_FlowInd(tRFC_MCB * p_mcb,uint8_t dlci,bool enable_data)859 void PORT_FlowInd(tRFC_MCB* p_mcb, uint8_t dlci, bool enable_data) {
860   tPORT* p_port = (tPORT*)NULL;
861   uint32_t events = 0;
862   int i;
863 
864   log::verbose("PORT_FlowInd fc:{}", enable_data);
865 
866   if (dlci == 0) {
867     p_mcb->peer_ready = enable_data;
868   } else {
869     p_port = port_find_mcb_dlci_port(p_mcb, dlci);
870     if (p_port == NULL) return;
871 
872     p_port->tx.peer_fc = !enable_data;
873   }
874 
875   for (i = 0; i < MAX_RFC_PORTS; i++) {
876     /* If DLCI is 0 event applies to all ports */
877     if (dlci == 0) {
878       p_port = &rfc_cb.port.port[i];
879       if (!p_port->in_use || (p_port->rfc.p_mcb != p_mcb) ||
880           (p_port->rfc.state != RFC_STATE_OPENED))
881         continue;
882     }
883     events = 0;
884 
885     /* Check if flow of data is still enabled */
886     events |= port_flow_control_user(p_port);
887 
888     /* Check if data can be sent and send it */
889     events |= port_rfc_send_tx_data(p_port);
890 
891     /* Mask out all events that are not of interest to user */
892     events &= p_port->ev_mask;
893 
894     /* Send event to the application */
895     if (p_port->p_callback && events)
896       (p_port->p_callback)(events, p_port->handle);
897 
898     /* If DLCI is not 0 event applies to one port only */
899     if (dlci != 0) break;
900   }
901 }
902 
903 /*******************************************************************************
904  *
905  * Function         port_rfc_send_tx_data
906  *
907  * Description      This function is when forward data can be sent to the peer
908  *
909  ******************************************************************************/
port_rfc_send_tx_data(tPORT * p_port)910 uint32_t port_rfc_send_tx_data(tPORT* p_port) {
911   uint32_t events = 0;
912   BT_HDR* p_buf;
913 
914   /* if there is data to be sent */
915   if (p_port->tx.queue_size > 0) {
916     /* while the rfcomm peer is not flow controlling us, and peer is ready */
917     while (!p_port->tx.peer_fc && p_port->rfc.p_mcb &&
918            p_port->rfc.p_mcb->peer_ready) {
919       /* get data from tx queue and send it */
920       mutex_global_lock();
921 
922       p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_port->tx.queue);
923       if (p_buf != NULL) {
924         p_port->tx.queue_size -= p_buf->len;
925 
926         mutex_global_unlock();
927 
928         log::verbose("Sending RFCOMM_DataReq tx.queue_size={}",
929                      p_port->tx.queue_size);
930 
931         RFCOMM_DataReq(p_port->rfc.p_mcb, p_port->dlci, p_buf);
932 
933         events |= PORT_EV_TXCHAR;
934 
935         if (p_port->tx.queue_size == 0) {
936           events |= PORT_EV_TXEMPTY;
937           break;
938         }
939       }
940       /* queue is empty-- all data sent */
941       else {
942         mutex_global_unlock();
943 
944         events |= PORT_EV_TXEMPTY;
945         break;
946       }
947     }
948     /* If we flow controlled user based on the queue size enable data again */
949     events |= port_flow_control_user(p_port);
950   }
951   return (events & p_port->ev_mask);
952 }
953 
954 /*******************************************************************************
955  *
956  * Function         port_rfc_closed
957  *
958  * Description      Called when RFCOMM port is closed
959  *
960  ******************************************************************************/
port_rfc_closed(tPORT * p_port,uint8_t res)961 void port_rfc_closed(tPORT* p_port, uint8_t res) {
962   uint8_t old_signals;
963   uint32_t events = 0;
964   tRFC_MCB* p_mcb = p_port->rfc.p_mcb;
965 
966   if ((p_port->state == PORT_CONNECTION_STATE_OPENING) && (p_port->is_server)) {
967     /* The server side was not informed that connection is up, ignore */
968     log::warn("port_rfc_closed in OPENING state ignored");
969 
970     rfc_port_timer_stop(p_port);
971     p_port->rfc.state = RFC_STATE_CLOSED;
972 
973     if (p_mcb) {
974       p_mcb->port_handles[p_port->dlci] = 0;
975 
976       /* If there are no more ports opened on this MCB release it */
977       rfc_check_mcb_active(p_mcb);
978       p_port->rfc.p_mcb = NULL;
979     }
980 
981     /* Need to restore DLCI to listening state
982      * if the server was on the initiating RFC
983      */
984     p_port->dlci &= 0xfe;
985 
986     return;
987   }
988 
989   if (p_port->state >= PORT_CONNECTION_STATE_OPENED && p_mcb) {
990     uint16_t lcid;
991     tL2C_CCB* ccb;
992 
993     lcid = p_mcb->lcid;
994     ccb = l2cu_find_ccb_by_cid(nullptr, lcid);
995 
996     if (ccb) {
997       bluetooth::shim::GetSnoopLogger()->SetRfcommPortClose(
998           ccb->p_lcb->Handle(), lcid, p_port->dlci, p_port->uuid);
999     }
1000   }
1001 
1002   if ((p_port->state != PORT_CONNECTION_STATE_CLOSING) &&
1003       (p_port->state != PORT_CONNECTION_STATE_CLOSED)) {
1004     p_port->line_status |= LINE_STATUS_FAILED;
1005 
1006     old_signals = p_port->peer_ctrl.modem_signal;
1007 
1008     p_port->peer_ctrl.modem_signal &=
1009         ~(PORT_DTRDSR_ON | PORT_CTSRTS_ON | PORT_DCD_ON);
1010 
1011     events |= port_get_signal_changes(p_port, old_signals,
1012                                       p_port->peer_ctrl.modem_signal);
1013 
1014     if (p_port->ev_mask & PORT_EV_CONNECT_ERR) events |= PORT_EV_CONNECT_ERR;
1015   }
1016 
1017   if ((p_port->p_callback != NULL) && events)
1018     p_port->p_callback(events, p_port->handle);
1019 
1020   if (p_port->p_mgmt_callback) {
1021     uint32_t res2 = res;
1022     if (res2 >= PORT_ERR_MAX) res2 = PORT_ERR_MAX;
1023     p_port->p_mgmt_callback(static_cast<tPORT_RESULT>(res2), p_port->handle);
1024   }
1025 
1026   p_port->rfc.state = RFC_STATE_CLOSED;
1027 
1028   log::info(
1029       "RFCOMM connection closed, index={}, state={}, reason={}[{}], "
1030       "UUID=0x{:x}, bd_addr={}, is_server={}",
1031       p_port->handle, p_port->state, PORT_GetResultString(res), res,
1032       p_port->uuid, p_port->bd_addr, p_port->is_server);
1033 
1034   port_release_port(p_port);
1035 }
1036 
1037 /*******************************************************************************
1038  *
1039  * Function         port_get_credits
1040  *
1041  * Description      Set initial values for credits.
1042  *                  Adjust max number of rx credits based on negotiated MTU.
1043  *                  Check max allowed num of bytes, max allowed num buffers,
1044  *                  should be less then 255
1045  *
1046  ******************************************************************************/
port_get_credits(tPORT * p_port,uint8_t k)1047 void port_get_credits(tPORT* p_port, uint8_t k) {
1048   p_port->credit_tx = k;
1049   if (p_port->credit_tx == 0) p_port->tx.peer_fc = true;
1050 }
1051