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