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 * 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 ******************************************************************************/ 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 nullptr; 95 } 96 97 /******************************************************************************* 98 * 99 * Function port_set_defaults 100 * 101 * Description Set defualt port parameters 102 * 103 * 104 ******************************************************************************/ 105 void port_set_defaults(tPORT* p_port) { 106 p_port->ev_mask = 0; 107 p_port->p_callback = nullptr; 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 ******************************************************************************/ 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 ******************************************************************************/ 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)) != 211 nullptr) { 212 osi_free(p_buf); 213 } 214 p_port->rx.queue_size = 0; 215 216 while ((p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_port->tx.queue)) != 217 nullptr) { 218 osi_free(p_buf); 219 } 220 p_port->tx.queue_size = 0; 221 mutex_global_unlock(); 222 223 alarm_cancel(p_port->rfc.port_timer); 224 225 p_port->state = PORT_STATE_CLOSED; 226 227 if (p_port->rfc.state == RFC_STATE_CLOSED) { 228 if (p_port->rfc.p_mcb) { 229 p_port->rfc.p_mcb->port_inx[p_port->dlci] = 0; 230 231 /* If there are no more ports opened on this MCB release it */ 232 rfc_check_mcb_active(p_port->rfc.p_mcb); 233 } 234 235 rfc_port_timer_stop(p_port); 236 237 mutex_global_lock(); 238 fixed_queue_free(p_port->tx.queue, nullptr); 239 p_port->tx.queue = nullptr; 240 fixed_queue_free(p_port->rx.queue, nullptr); 241 p_port->rx.queue = nullptr; 242 mutex_global_unlock(); 243 244 if (p_port->keep_port_handle) { 245 RFCOMM_TRACE_DEBUG("%s Re-initialize handle: %d", __func__, p_port->inx); 246 247 /* save event mask and callback */ 248 uint32_t mask = p_port->ev_mask; 249 tPORT_CALLBACK* p_port_cb = p_port->p_callback; 250 tPORT_STATE user_port_pars = p_port->user_port_pars; 251 252 port_set_defaults(p_port); 253 254 /* restore */ 255 p_port->ev_mask = mask; 256 p_port->p_callback = p_port_cb; 257 p_port->user_port_pars = user_port_pars; 258 p_port->mtu = p_port->keep_mtu; 259 260 p_port->state = PORT_STATE_OPENING; 261 p_port->rfc.p_mcb = nullptr; 262 if (p_port->is_server) p_port->dlci &= 0xfe; 263 264 p_port->local_ctrl.modem_signal = p_port->default_signal_state; 265 p_port->bd_addr = RawAddress::kAny; 266 } else { 267 RFCOMM_TRACE_DEBUG("%s Clean-up handle: %d", __func__, p_port->inx); 268 alarm_free(p_port->rfc.port_timer); 269 memset(p_port, 0, sizeof(tPORT)); 270 } 271 } 272 } 273 274 /******************************************************************************* 275 * 276 * Function port_find_mcb 277 * 278 * Description This function checks if connection exists to device with 279 * the address. 280 * 281 ******************************************************************************/ 282 tRFC_MCB* port_find_mcb(const RawAddress& bd_addr) { 283 for (tRFC_MCB& mcb : rfc_cb.port.rfc_mcb) { 284 if ((mcb.state != RFC_MX_STATE_IDLE) && (mcb.bd_addr == bd_addr)) { 285 /* Multiplexer channel found do not change anything */ 286 VLOG(1) << __func__ << ": found bd_addr=" << bd_addr 287 << ", rfc_mcb=" << &mcb << ", lcid=" << loghex(mcb.lcid); 288 return &mcb; 289 } 290 } 291 VLOG(1) << __func__ << ": not found, bd_addr:" << bd_addr; 292 return nullptr; 293 } 294 295 /******************************************************************************* 296 * 297 * Function port_find_mcb_dlci_port 298 * 299 * Description Find port on the multiplexer channel based on DLCI. If 300 * this port with DLCI not found try to use even DLCI. This 301 * is for the case when client is establishing connection on 302 * none-initiator MCB. 303 * 304 * Returns Pointer to the PORT or NULL if not found 305 * 306 ******************************************************************************/ 307 tPORT* port_find_mcb_dlci_port(tRFC_MCB* p_mcb, uint8_t dlci) { 308 if (!p_mcb) { 309 LOG(ERROR) << __func__ << ": p_mcb is null, dlci=" << std::to_string(dlci); 310 return nullptr; 311 } 312 313 if (dlci > RFCOMM_MAX_DLCI) { 314 LOG(WARNING) << __func__ << ": DLCI " << std::to_string(dlci) 315 << " is too large, bd_addr=" << p_mcb->bd_addr 316 << ", p_mcb=" << p_mcb; 317 return nullptr; 318 } 319 320 uint8_t inx = p_mcb->port_inx[dlci]; 321 if (inx == 0) { 322 LOG(INFO) << __func__ << ": Cannot find allocated RFCOMM app port for DLCI " 323 << std::to_string(dlci) << " on " << p_mcb->bd_addr 324 << ", p_mcb=" << p_mcb; 325 return nullptr; 326 } 327 return &rfc_cb.port.port[inx - 1]; 328 } 329 330 /******************************************************************************* 331 * 332 * Function port_find_dlci_port 333 * 334 * Description Find port with DLCI not assigned to multiplexer channel 335 * 336 * Returns Pointer to the PORT or NULL if not found 337 * 338 ******************************************************************************/ 339 tPORT* port_find_dlci_port(uint8_t dlci) { 340 for (tPORT& port : rfc_cb.port.port) { 341 if (port.in_use && (port.rfc.p_mcb == nullptr)) { 342 if (port.dlci == dlci) { 343 return &port; 344 } else if ((dlci & 0x01) && (port.dlci == (dlci - 1))) { 345 port.dlci++; 346 return &port; 347 } 348 } 349 } 350 return nullptr; 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 ******************************************************************************/ 362 tPORT* port_find_port(uint8_t dlci, const RawAddress& bd_addr) { 363 for (tPORT& port : rfc_cb.port.port) { 364 if (port.in_use && (port.dlci == dlci) && (port.bd_addr == bd_addr)) { 365 return &port; 366 } 367 } 368 return nullptr; 369 } 370 371 /******************************************************************************* 372 * 373 * Function port_flow_control_user 374 * 375 * Description Check the current user flow control and if necessary return 376 * events to be send to the user based on the user's specified 377 * flow control type. 378 * 379 * Returns event mask to be returned to the application 380 * 381 ******************************************************************************/ 382 uint32_t port_flow_control_user(tPORT* p_port) { 383 uint32_t event = 0; 384 385 /* Flow control to the user can be caused by flow controlling by the peer */ 386 /* (FlowInd, or flow control by the peer RFCOMM (Fcon) or internally if */ 387 /* tx_queue is full */ 388 bool fc = p_port->tx.peer_fc || !p_port->rfc.p_mcb || 389 !p_port->rfc.p_mcb->peer_ready || 390 (p_port->tx.queue_size > PORT_TX_HIGH_WM) || 391 (fixed_queue_length(p_port->tx.queue) > PORT_TX_BUF_HIGH_WM); 392 393 if (p_port->tx.user_fc == fc) return (0); 394 395 p_port->tx.user_fc = fc; 396 397 if (fc) 398 event = PORT_EV_FC; 399 else 400 event = PORT_EV_FC | PORT_EV_FCS; 401 402 return (event); 403 } 404 405 /******************************************************************************* 406 * 407 * Function port_get_signal_changes 408 * 409 * Description Check modem signals that has been changed 410 * 411 * Returns event mask to be returned to the application 412 * 413 ******************************************************************************/ 414 uint32_t port_get_signal_changes(tPORT* p_port, uint8_t old_signals, 415 uint8_t signal) { 416 uint8_t changed_signals = (signal ^ old_signals); 417 uint32_t events = 0; 418 419 if (changed_signals & PORT_DTRDSR_ON) { 420 events |= PORT_EV_DSR; 421 422 if (signal & PORT_DTRDSR_ON) events |= PORT_EV_DSRS; 423 } 424 425 if (changed_signals & PORT_CTSRTS_ON) { 426 events |= PORT_EV_CTS; 427 428 if (signal & PORT_CTSRTS_ON) events |= PORT_EV_CTSS; 429 } 430 431 if (changed_signals & PORT_RING_ON) events |= PORT_EV_RING; 432 433 if (changed_signals & PORT_DCD_ON) { 434 events |= PORT_EV_RLSD; 435 436 if (signal & PORT_DCD_ON) events |= PORT_EV_RLSDS; 437 } 438 439 return (p_port->ev_mask & events); 440 } 441 442 /******************************************************************************* 443 * 444 * Function port_flow_control_peer 445 * 446 * Description Send flow control messages to the peer for both enabling 447 * and disabling flow control, for both credit-based and 448 * TS 07.10 flow control mechanisms. 449 * 450 * Returns nothing 451 * 452 ******************************************************************************/ 453 void port_flow_control_peer(tPORT* p_port, bool enable, uint16_t count) { 454 if (!p_port->rfc.p_mcb) return; 455 456 /* If using credit based flow control */ 457 if (p_port->rfc.p_mcb->flow == PORT_FC_CREDIT) { 458 /* if want to enable flow from peer */ 459 if (enable) { 460 /* update rx credits */ 461 if (count > p_port->credit_rx) { 462 p_port->credit_rx = 0; 463 } else { 464 p_port->credit_rx -= count; 465 } 466 467 /* If credit count is less than low credit watermark, and user */ 468 /* did not force flow control, send a credit update */ 469 /* There might be a special case when we just adjusted rx_max */ 470 if ((p_port->credit_rx <= p_port->credit_rx_low) && !p_port->rx.user_fc && 471 (p_port->credit_rx_max > p_port->credit_rx)) { 472 rfc_send_credit(p_port->rfc.p_mcb, p_port->dlci, 473 (uint8_t)(p_port->credit_rx_max - p_port->credit_rx)); 474 475 p_port->credit_rx = p_port->credit_rx_max; 476 477 p_port->rx.peer_fc = false; 478 } 479 } 480 /* else want to disable flow from peer */ 481 else { 482 /* if client registered data callback, just do what they want */ 483 if (p_port->p_data_callback || p_port->p_data_co_callback) { 484 p_port->rx.peer_fc = true; 485 } 486 /* if queue count reached credit rx max, set peer fc */ 487 else if (fixed_queue_length(p_port->rx.queue) >= p_port->credit_rx_max) { 488 p_port->rx.peer_fc = true; 489 } 490 } 491 } 492 /* else using TS 07.10 flow control */ 493 else { 494 /* if want to enable flow from peer */ 495 if (enable) { 496 /* If rfcomm suspended traffic from the peer based on the rx_queue_size */ 497 /* check if it can be resumed now */ 498 if (p_port->rx.peer_fc && (p_port->rx.queue_size < PORT_RX_LOW_WM) && 499 (fixed_queue_length(p_port->rx.queue) < PORT_RX_BUF_LOW_WM)) { 500 p_port->rx.peer_fc = false; 501 502 /* If user did not force flow control allow traffic now */ 503 if (!p_port->rx.user_fc) 504 RFCOMM_FlowReq(p_port->rfc.p_mcb, p_port->dlci, true); 505 } 506 } 507 /* else want to disable flow from peer */ 508 else { 509 /* if client registered data callback, just do what they want */ 510 if (p_port->p_data_callback || p_port->p_data_co_callback) { 511 p_port->rx.peer_fc = true; 512 RFCOMM_FlowReq(p_port->rfc.p_mcb, p_port->dlci, false); 513 } 514 /* Check the size of the rx queue. If it exceeds certain */ 515 /* level and flow control has not been sent to the peer do it now */ 516 else if (((p_port->rx.queue_size > PORT_RX_HIGH_WM) || 517 (fixed_queue_length(p_port->rx.queue) > PORT_RX_BUF_HIGH_WM)) && 518 !p_port->rx.peer_fc) { 519 RFCOMM_TRACE_EVENT("PORT_DataInd Data reached HW. Sending FC set."); 520 521 p_port->rx.peer_fc = true; 522 RFCOMM_FlowReq(p_port->rfc.p_mcb, p_port->dlci, false); 523 } 524 } 525 } 526 } 527