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