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