1 /******************************************************************************
2 *
3 * Copyright (C) 1999-2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 /******************************************************************************
20 *
21 * Port Emulation entity utilities
22 *
23 ******************************************************************************/
24 #include <base/logging.h>
25 #include <string.h>
26
27 #include "osi/include/mutex.h"
28
29 #include "bt_common.h"
30 #include "bt_target.h"
31 #include "btm_int.h"
32 #include "btu.h"
33 #include "l2cdefs.h"
34 #include "port_api.h"
35 #include "port_int.h"
36 #include "rfc_int.h"
37 #include "rfcdefs.h"
38
39 static const tPORT_STATE default_port_pars = {
40 PORT_BAUD_RATE_9600,
41 PORT_8_BITS,
42 PORT_ONESTOPBIT,
43 PORT_PARITY_NO,
44 PORT_ODD_PARITY,
45 PORT_FC_OFF,
46 0, /* No rx_char */
47 PORT_XON_DC1,
48 PORT_XOFF_DC3,
49 };
50
51 /*******************************************************************************
52 *
53 * Function port_allocate_port
54 *
55 * Description Look through the Port Control Blocks for a free one. Note
56 * that one server can open several ports with the same SCN
57 * if it can support simulteneous requests from different
58 * clients.
59 *
60 * Returns Pointer to the PORT or NULL if not found
61 *
62 ******************************************************************************/
port_allocate_port(uint8_t dlci,const RawAddress & bd_addr)63 tPORT* port_allocate_port(uint8_t dlci, const RawAddress& bd_addr) {
64 tPORT* p_port = &rfc_cb.port.port[0];
65 uint8_t xx, yy;
66
67 for (xx = 0, yy = rfc_cb.rfc.last_port + 1; xx < MAX_RFC_PORTS; xx++, yy++) {
68 if (yy >= MAX_RFC_PORTS) yy = 0;
69
70 p_port = &rfc_cb.port.port[yy];
71 if (!p_port->in_use) {
72 memset(p_port, 0, sizeof(tPORT));
73
74 p_port->in_use = true;
75 p_port->inx = yy + 1;
76
77 /* During the open set default state for the port connection */
78 port_set_defaults(p_port);
79
80 p_port->rfc.port_timer = alarm_new("rfcomm_port.port_timer");
81 rfc_cb.rfc.last_port = yy;
82
83 p_port->dlci = dlci;
84 p_port->bd_addr = bd_addr;
85
86 RFCOMM_TRACE_DEBUG("rfc_cb.port.port[%d]:%p allocated, last_port:%d", yy,
87 p_port, rfc_cb.rfc.last_port);
88 VLOG(1) << __func__ << ": bd_addr:" << bd_addr;
89 return (p_port);
90 }
91 }
92
93 /* If here, no free PORT found */
94 return (NULL);
95 }
96
97 /*******************************************************************************
98 *
99 * Function port_set_defaults
100 *
101 * Description Set defualt port parameters
102 *
103 *
104 ******************************************************************************/
port_set_defaults(tPORT * p_port)105 void port_set_defaults(tPORT* p_port) {
106 p_port->ev_mask = 0;
107 p_port->p_callback = NULL;
108 p_port->port_ctrl = 0;
109 p_port->error = 0;
110 p_port->line_status = 0;
111 p_port->rx_flag_ev_pending = false;
112 p_port->peer_mtu = RFCOMM_DEFAULT_MTU;
113
114 p_port->user_port_pars = default_port_pars;
115 p_port->peer_port_pars = default_port_pars;
116
117 p_port->credit_tx = 0;
118 p_port->credit_rx = 0;
119
120 memset(&p_port->local_ctrl, 0, sizeof(p_port->local_ctrl));
121 memset(&p_port->peer_ctrl, 0, sizeof(p_port->peer_ctrl));
122 memset(&p_port->rx, 0, sizeof(p_port->rx));
123 memset(&p_port->tx, 0, sizeof(p_port->tx));
124
125 p_port->tx.queue = fixed_queue_new(SIZE_MAX);
126 p_port->rx.queue = fixed_queue_new(SIZE_MAX);
127 }
128
129 /*******************************************************************************
130 *
131 * Function port_select_mtu
132 *
133 * Description Select MTU which will best serve connection from our
134 * point of view.
135 * If our device is 1.2 or lower we calculate how many DH5s
136 * fit into 1 RFCOMM buffer.
137 *
138 *
139 ******************************************************************************/
port_select_mtu(tPORT * p_port)140 void port_select_mtu(tPORT* p_port) {
141 uint16_t packet_size;
142
143 /* Will select MTU only if application did not setup something */
144 if (p_port->mtu == 0) {
145 /* find packet size which connection supports */
146 packet_size = btm_get_max_packet_size(p_port->bd_addr);
147 if (packet_size == 0) {
148 /* something is very wrong */
149 RFCOMM_TRACE_WARNING("port_select_mtu bad packet size");
150 p_port->mtu = RFCOMM_DEFAULT_MTU;
151 } else {
152 /* We try to negotiate MTU that each packet can be split into whole
153 number of max packets. For example if link is 1.2 max packet size is 339
154 bytes.
155 At first calculate how many whole packets it is. MAX L2CAP is 1691 + 4
156 overhead.
157 1695, that will be 5 Dh5 packets. Now maximum RFCOMM packet is
158 5 * 339 = 1695. Minus 4 bytes L2CAP header 1691. Minus RFCOMM 6 bytes
159 header overhead 1685
160
161 For EDR 2.0 packet size is 1027. So we better send RFCOMM packet as 1
162 3DH5 packet
163 1 * 1027 = 1027. Minus 4 bytes L2CAP header 1023. Minus RFCOMM 6 bytes
164 header overhead 1017 */
165 if ((L2CAP_MTU_SIZE + L2CAP_PKT_OVERHEAD) >= packet_size) {
166 p_port->mtu = ((L2CAP_MTU_SIZE + L2CAP_PKT_OVERHEAD) / packet_size *
167 packet_size) -
168 RFCOMM_DATA_OVERHEAD - L2CAP_PKT_OVERHEAD;
169 RFCOMM_TRACE_DEBUG(
170 "port_select_mtu selected %d based on connection speed",
171 p_port->mtu);
172 } else {
173 p_port->mtu = L2CAP_MTU_SIZE - RFCOMM_DATA_OVERHEAD;
174 RFCOMM_TRACE_DEBUG(
175 "port_select_mtu selected %d based on l2cap PDU size", p_port->mtu);
176 }
177 }
178 } else {
179 RFCOMM_TRACE_DEBUG("port_select_mtu application selected %d", p_port->mtu);
180 }
181 p_port->credit_rx_max = (PORT_RX_HIGH_WM / p_port->mtu);
182 if (p_port->credit_rx_max > PORT_RX_BUF_HIGH_WM)
183 p_port->credit_rx_max = PORT_RX_BUF_HIGH_WM;
184 p_port->credit_rx_low = (PORT_RX_LOW_WM / p_port->mtu);
185 if (p_port->credit_rx_low > PORT_RX_BUF_LOW_WM)
186 p_port->credit_rx_low = PORT_RX_BUF_LOW_WM;
187 p_port->rx_buf_critical = (PORT_RX_CRITICAL_WM / p_port->mtu);
188 if (p_port->rx_buf_critical > PORT_RX_BUF_CRITICAL_WM)
189 p_port->rx_buf_critical = PORT_RX_BUF_CRITICAL_WM;
190 RFCOMM_TRACE_DEBUG(
191 "port_select_mtu credit_rx_max %d, credit_rx_low %d, rx_buf_critical %d",
192 p_port->credit_rx_max, p_port->credit_rx_low, p_port->rx_buf_critical);
193 }
194
195 /*******************************************************************************
196 *
197 * Function port_release_port
198 *
199 * Description Release port control block.
200 *
201 * Returns Pointer to the PORT or NULL if not found
202 *
203 ******************************************************************************/
port_release_port(tPORT * p_port)204 void port_release_port(tPORT* p_port) {
205 RFCOMM_TRACE_DEBUG("%s p_port: %p state: %d keep_handle: %d", __func__,
206 p_port, p_port->rfc.state, p_port->keep_port_handle);
207
208 mutex_global_lock();
209 BT_HDR* p_buf;
210 while ((p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_port->rx.queue)) != NULL)
211 osi_free(p_buf);
212 p_port->rx.queue_size = 0;
213
214 while ((p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_port->tx.queue)) != NULL)
215 osi_free(p_buf);
216 p_port->tx.queue_size = 0;
217 mutex_global_unlock();
218
219 alarm_cancel(p_port->rfc.port_timer);
220
221 p_port->state = PORT_STATE_CLOSED;
222
223 if (p_port->rfc.state == RFC_STATE_CLOSED) {
224 if (p_port->rfc.p_mcb) {
225 p_port->rfc.p_mcb->port_inx[p_port->dlci] = 0;
226
227 /* If there are no more ports opened on this MCB release it */
228 rfc_check_mcb_active(p_port->rfc.p_mcb);
229 }
230
231 rfc_port_timer_stop(p_port);
232
233 mutex_global_lock();
234 fixed_queue_free(p_port->tx.queue, NULL);
235 p_port->tx.queue = NULL;
236 fixed_queue_free(p_port->rx.queue, NULL);
237 p_port->rx.queue = NULL;
238 mutex_global_unlock();
239
240 if (p_port->keep_port_handle) {
241 RFCOMM_TRACE_DEBUG("%s Re-initialize handle: %d", __func__, p_port->inx);
242
243 /* save event mask and callback */
244 uint32_t mask = p_port->ev_mask;
245 tPORT_CALLBACK* p_port_cb = p_port->p_callback;
246 tPORT_STATE user_port_pars = p_port->user_port_pars;
247
248 port_set_defaults(p_port);
249
250 /* restore */
251 p_port->ev_mask = mask;
252 p_port->p_callback = p_port_cb;
253 p_port->user_port_pars = user_port_pars;
254 p_port->mtu = p_port->keep_mtu;
255
256 p_port->state = PORT_STATE_OPENING;
257 p_port->rfc.p_mcb = NULL;
258 if (p_port->is_server) p_port->dlci &= 0xfe;
259
260 p_port->local_ctrl.modem_signal = p_port->default_signal_state;
261 p_port->bd_addr = RawAddress::kAny;
262 } else {
263 RFCOMM_TRACE_DEBUG("%s Clean-up handle: %d", __func__, p_port->inx);
264 alarm_free(p_port->rfc.port_timer);
265 memset(p_port, 0, sizeof(tPORT));
266 }
267 }
268 }
269
270 /*******************************************************************************
271 *
272 * Function port_find_mcb
273 *
274 * Description This function checks if connection exists to device with
275 * the address.
276 *
277 ******************************************************************************/
port_find_mcb(const RawAddress & bd_addr)278 tRFC_MCB* port_find_mcb(const RawAddress& bd_addr) {
279 int i;
280
281 for (i = 0; i < MAX_BD_CONNECTIONS; i++) {
282 if ((rfc_cb.port.rfc_mcb[i].state != RFC_MX_STATE_IDLE) &&
283 rfc_cb.port.rfc_mcb[i].bd_addr == bd_addr) {
284 /* Multiplexer channel found do not change anything */
285 VLOG(1) << __func__ << ": found bd_addr:" << bd_addr;
286 RFCOMM_TRACE_DEBUG(
287 "port_find_mcb: rfc_cb.port.rfc_mcb:index:%d, %p, lcid:%d", i,
288 &rfc_cb.port.rfc_mcb[i], rfc_cb.port.rfc_mcb[i].lcid);
289 return (&rfc_cb.port.rfc_mcb[i]);
290 }
291 }
292 VLOG(1) << __func__ << ": not found, bd_addr:" << bd_addr;
293 return (NULL);
294 }
295
296 /*******************************************************************************
297 *
298 * Function port_find_mcb_dlci_port
299 *
300 * Description Find port on the multiplexer channel based on DLCI. If
301 * this port with DLCI not found try to use even DLCI. This
302 * is for the case when client is establishing connection on
303 * none-initiator MCB.
304 *
305 * Returns Pointer to the PORT or NULL if not found
306 *
307 ******************************************************************************/
port_find_mcb_dlci_port(tRFC_MCB * p_mcb,uint8_t dlci)308 tPORT* port_find_mcb_dlci_port(tRFC_MCB* p_mcb, uint8_t dlci) {
309 uint8_t inx;
310
311 if (!p_mcb) return (NULL);
312
313 if (dlci > RFCOMM_MAX_DLCI) return (NULL);
314
315 inx = p_mcb->port_inx[dlci];
316 if (inx == 0) {
317 RFCOMM_TRACE_DEBUG(
318 "port_find_mcb_dlci_port: p_mcb:%p, port_inx[dlci:%d] is 0", p_mcb,
319 dlci);
320 return (NULL);
321 } else
322 return (&rfc_cb.port.port[inx - 1]);
323 }
324
325 /*******************************************************************************
326 *
327 * Function port_find_dlci_port
328 *
329 * Description Find port with DLCI not assigned to multiplexer channel
330 *
331 * Returns Pointer to the PORT or NULL if not found
332 *
333 ******************************************************************************/
port_find_dlci_port(uint8_t dlci)334 tPORT* port_find_dlci_port(uint8_t dlci) {
335 uint16_t i;
336 tPORT* p_port;
337
338 for (i = 0; i < MAX_RFC_PORTS; i++) {
339 p_port = &rfc_cb.port.port[i];
340
341 if (p_port->in_use && (p_port->rfc.p_mcb == NULL)) {
342 if (p_port->dlci == dlci) {
343 return (p_port);
344 } else if ((dlci & 0x01) && (p_port->dlci == (dlci - 1))) {
345 p_port->dlci++;
346 return (p_port);
347 }
348 }
349 }
350 return (NULL);
351 }
352
353 /*******************************************************************************
354 *
355 * Function port_find_port
356 *
357 * Description Find port with DLCI, address
358 *
359 * Returns Pointer to the PORT or NULL if not found
360 *
361 ******************************************************************************/
port_find_port(uint8_t dlci,const RawAddress & bd_addr)362 tPORT* port_find_port(uint8_t dlci, const RawAddress& bd_addr) {
363 uint16_t i;
364 tPORT* p_port;
365
366 for (i = 0; i < MAX_RFC_PORTS; i++) {
367 p_port = &rfc_cb.port.port[i];
368 if (p_port->in_use && (p_port->dlci == dlci) &&
369 p_port->bd_addr == bd_addr) {
370 return (p_port);
371 }
372 }
373 return (NULL);
374 }
375
376 /*******************************************************************************
377 *
378 * Function port_flow_control_user
379 *
380 * Description Check the current user flow control and if necessary return
381 * events to be send to the user based on the user's specified
382 * flow control type.
383 *
384 * Returns event mask to be returned to the application
385 *
386 ******************************************************************************/
port_flow_control_user(tPORT * p_port)387 uint32_t port_flow_control_user(tPORT* p_port) {
388 uint32_t event = 0;
389
390 /* Flow control to the user can be caused by flow controlling by the peer */
391 /* (FlowInd, or flow control by the peer RFCOMM (Fcon) or internally if */
392 /* tx_queue is full */
393 bool fc = p_port->tx.peer_fc || !p_port->rfc.p_mcb ||
394 !p_port->rfc.p_mcb->peer_ready ||
395 (p_port->tx.queue_size > PORT_TX_HIGH_WM) ||
396 (fixed_queue_length(p_port->tx.queue) > PORT_TX_BUF_HIGH_WM);
397
398 if (p_port->tx.user_fc == fc) return (0);
399
400 p_port->tx.user_fc = fc;
401
402 if (fc)
403 event = PORT_EV_FC;
404 else
405 event = PORT_EV_FC | PORT_EV_FCS;
406
407 return (event);
408 }
409
410 /*******************************************************************************
411 *
412 * Function port_get_signal_changes
413 *
414 * Description Check modem signals that has been changed
415 *
416 * Returns event mask to be returned to the application
417 *
418 ******************************************************************************/
port_get_signal_changes(tPORT * p_port,uint8_t old_signals,uint8_t signal)419 uint32_t port_get_signal_changes(tPORT* p_port, uint8_t old_signals,
420 uint8_t signal) {
421 uint8_t changed_signals = (signal ^ old_signals);
422 uint32_t events = 0;
423
424 if (changed_signals & PORT_DTRDSR_ON) {
425 events |= PORT_EV_DSR;
426
427 if (signal & PORT_DTRDSR_ON) events |= PORT_EV_DSRS;
428 }
429
430 if (changed_signals & PORT_CTSRTS_ON) {
431 events |= PORT_EV_CTS;
432
433 if (signal & PORT_CTSRTS_ON) events |= PORT_EV_CTSS;
434 }
435
436 if (changed_signals & PORT_RING_ON) events |= PORT_EV_RING;
437
438 if (changed_signals & PORT_DCD_ON) {
439 events |= PORT_EV_RLSD;
440
441 if (signal & PORT_DCD_ON) events |= PORT_EV_RLSDS;
442 }
443
444 return (p_port->ev_mask & events);
445 }
446
447 /*******************************************************************************
448 *
449 * Function port_flow_control_peer
450 *
451 * Description Send flow control messages to the peer for both enabling
452 * and disabling flow control, for both credit-based and
453 * TS 07.10 flow control mechanisms.
454 *
455 * Returns nothing
456 *
457 ******************************************************************************/
port_flow_control_peer(tPORT * p_port,bool enable,uint16_t count)458 void port_flow_control_peer(tPORT* p_port, bool enable, uint16_t count) {
459 if (!p_port->rfc.p_mcb) return;
460
461 /* If using credit based flow control */
462 if (p_port->rfc.p_mcb->flow == PORT_FC_CREDIT) {
463 /* if want to enable flow from peer */
464 if (enable) {
465 /* update rx credits */
466 if (count > p_port->credit_rx) {
467 p_port->credit_rx = 0;
468 } else {
469 p_port->credit_rx -= count;
470 }
471
472 /* If credit count is less than low credit watermark, and user */
473 /* did not force flow control, send a credit update */
474 /* There might be a special case when we just adjusted rx_max */
475 if ((p_port->credit_rx <= p_port->credit_rx_low) && !p_port->rx.user_fc &&
476 (p_port->credit_rx_max > p_port->credit_rx)) {
477 rfc_send_credit(p_port->rfc.p_mcb, p_port->dlci,
478 (uint8_t)(p_port->credit_rx_max - p_port->credit_rx));
479
480 p_port->credit_rx = p_port->credit_rx_max;
481
482 p_port->rx.peer_fc = false;
483 }
484 }
485 /* else want to disable flow from peer */
486 else {
487 /* if client registered data callback, just do what they want */
488 if (p_port->p_data_callback || p_port->p_data_co_callback) {
489 p_port->rx.peer_fc = true;
490 }
491 /* if queue count reached credit rx max, set peer fc */
492 else if (fixed_queue_length(p_port->rx.queue) >= p_port->credit_rx_max) {
493 p_port->rx.peer_fc = true;
494 }
495 }
496 }
497 /* else using TS 07.10 flow control */
498 else {
499 /* if want to enable flow from peer */
500 if (enable) {
501 /* If rfcomm suspended traffic from the peer based on the rx_queue_size */
502 /* check if it can be resumed now */
503 if (p_port->rx.peer_fc && (p_port->rx.queue_size < PORT_RX_LOW_WM) &&
504 (fixed_queue_length(p_port->rx.queue) < PORT_RX_BUF_LOW_WM)) {
505 p_port->rx.peer_fc = false;
506
507 /* If user did not force flow control allow traffic now */
508 if (!p_port->rx.user_fc)
509 RFCOMM_FlowReq(p_port->rfc.p_mcb, p_port->dlci, true);
510 }
511 }
512 /* else want to disable flow from peer */
513 else {
514 /* if client registered data callback, just do what they want */
515 if (p_port->p_data_callback || p_port->p_data_co_callback) {
516 p_port->rx.peer_fc = true;
517 RFCOMM_FlowReq(p_port->rfc.p_mcb, p_port->dlci, false);
518 }
519 /* Check the size of the rx queue. If it exceeds certain */
520 /* level and flow control has not been sent to the peer do it now */
521 else if (((p_port->rx.queue_size > PORT_RX_HIGH_WM) ||
522 (fixed_queue_length(p_port->rx.queue) > PORT_RX_BUF_HIGH_WM)) &&
523 !p_port->rx.peer_fc) {
524 RFCOMM_TRACE_EVENT("PORT_DataInd Data reached HW. Sending FC set.");
525
526 p_port->rx.peer_fc = true;
527 RFCOMM_FlowReq(p_port->rfc.p_mcb, p_port->dlci, false);
528 }
529 }
530 }
531 }
532