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