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 file contains state machine and action routines for multiplexer 22 * channel of the RFCOMM unit 23 * 24 ******************************************************************************/ 25 #include <string.h> 26 #include "bt_common.h" 27 #include "bt_types.h" 28 #include "rfcdefs.h" 29 #include "l2cdefs.h" 30 #include "port_api.h" 31 #include "port_int.h" 32 #include "l2c_api.h" 33 #include "rfc_int.h" 34 #include "bt_utils.h" 35 36 #define L2CAP_SUCCESS 0 37 #define L2CAP_ERROR 1 38 39 40 /********************************************************************************/ 41 /* L O C A L F U N C T I O N P R O T O T Y P E S */ 42 /********************************************************************************/ 43 static void rfc_mx_sm_state_idle (tRFC_MCB *p_mcb, UINT16 event, void *p_data); 44 static void rfc_mx_sm_state_wait_conn_cnf (tRFC_MCB *p_mcb, UINT16 event, void *p_data); 45 static void rfc_mx_sm_state_configure (tRFC_MCB *p_mcb, UINT16 event, void *p_data); 46 static void rfc_mx_sm_sabme_wait_ua (tRFC_MCB *p_mcb, UINT16 event, void *p_data); 47 static void rfc_mx_sm_state_wait_sabme (tRFC_MCB *p_mcb, UINT16 event, void *p_data); 48 static void rfc_mx_sm_state_connected (tRFC_MCB *p_mcb, UINT16 event, void *p_data); 49 static void rfc_mx_sm_state_disc_wait_ua (tRFC_MCB *p_mcb, UINT16 event, void *p_data); 50 51 static void rfc_mx_send_config_req (tRFC_MCB *p_mcb); 52 static void rfc_mx_conf_ind (tRFC_MCB *p_mcb, tL2CAP_CFG_INFO *p_cfg); 53 static void rfc_mx_conf_cnf (tRFC_MCB *p_mcb, tL2CAP_CFG_INFO *p_cfg); 54 55 56 57 /******************************************************************************* 58 ** 59 ** Function rfc_mx_sm_execute 60 ** 61 ** Description This function sends multiplexor events through the state 62 ** machine. 63 ** 64 ** Returns void 65 ** 66 *******************************************************************************/ 67 void rfc_mx_sm_execute (tRFC_MCB *p_mcb, UINT16 event, void *p_data) 68 { 69 switch (p_mcb->state) 70 { 71 case RFC_MX_STATE_IDLE: 72 rfc_mx_sm_state_idle (p_mcb, event, p_data); 73 break; 74 75 case RFC_MX_STATE_WAIT_CONN_CNF: 76 rfc_mx_sm_state_wait_conn_cnf (p_mcb, event, p_data); 77 break; 78 79 case RFC_MX_STATE_CONFIGURE: 80 rfc_mx_sm_state_configure (p_mcb, event, p_data); 81 break; 82 83 case RFC_MX_STATE_SABME_WAIT_UA: 84 rfc_mx_sm_sabme_wait_ua (p_mcb, event, p_data); 85 break; 86 87 case RFC_MX_STATE_WAIT_SABME: 88 rfc_mx_sm_state_wait_sabme (p_mcb, event, p_data); 89 break; 90 91 case RFC_MX_STATE_CONNECTED: 92 rfc_mx_sm_state_connected (p_mcb, event, p_data); 93 break; 94 95 case RFC_MX_STATE_DISC_WAIT_UA: 96 rfc_mx_sm_state_disc_wait_ua (p_mcb, event, p_data); 97 break; 98 99 } 100 } 101 102 103 /******************************************************************************* 104 ** 105 ** Function rfc_mx_sm_state_idle 106 ** 107 ** Description This function handles events when the multiplexer is in 108 ** IDLE state. This state exists when connection is being 109 ** initially established. 110 ** 111 ** Returns void 112 ** 113 *******************************************************************************/ 114 void rfc_mx_sm_state_idle (tRFC_MCB *p_mcb, UINT16 event, void *p_data) 115 { 116 RFCOMM_TRACE_EVENT ("rfc_mx_sm_state_idle - evt:%d", event); 117 switch (event) 118 { 119 case RFC_MX_EVENT_START_REQ: 120 121 /* Initialize L2CAP MTU */ 122 p_mcb->peer_l2cap_mtu = L2CAP_DEFAULT_MTU - RFCOMM_MIN_OFFSET - 1; 123 124 UINT16 lcid = L2CA_ConnectReq(BT_PSM_RFCOMM, p_mcb->bd_addr); 125 if (lcid == 0) { 126 rfc_save_lcid_mcb(NULL, p_mcb->lcid); 127 p_mcb->lcid = 0; 128 PORT_StartCnf(p_mcb, RFCOMM_ERROR); 129 return; 130 } 131 p_mcb->lcid = lcid; 132 /* Save entry for quicker access to mcb based on the LCID */ 133 rfc_save_lcid_mcb (p_mcb, p_mcb->lcid); 134 135 p_mcb->state = RFC_MX_STATE_WAIT_CONN_CNF; 136 return; 137 138 case RFC_MX_EVENT_START_RSP: 139 case RFC_MX_EVENT_CONN_CNF: 140 case RFC_MX_EVENT_CONF_IND: 141 case RFC_MX_EVENT_CONF_CNF: 142 RFCOMM_TRACE_ERROR ("Mx error state %d event %d", p_mcb->state, event); 143 return; 144 145 case RFC_MX_EVENT_CONN_IND: 146 147 rfc_timer_start (p_mcb, RFCOMM_CONN_TIMEOUT); 148 L2CA_ConnectRsp (p_mcb->bd_addr, *((UINT8 *)p_data), p_mcb->lcid, L2CAP_CONN_OK, 0); 149 150 rfc_mx_send_config_req (p_mcb); 151 152 p_mcb->state = RFC_MX_STATE_CONFIGURE; 153 return; 154 155 case RFC_EVENT_SABME: 156 break; 157 158 case RFC_EVENT_UA: 159 case RFC_EVENT_DM: 160 return; 161 162 case RFC_EVENT_DISC: 163 rfc_send_dm (p_mcb, RFCOMM_MX_DLCI, TRUE); 164 return; 165 166 case RFC_EVENT_UIH: 167 rfc_send_dm (p_mcb, RFCOMM_MX_DLCI, FALSE); 168 return; 169 } 170 RFCOMM_TRACE_EVENT ("RFCOMM MX ignored - evt:%d in state:%d", event, p_mcb->state); 171 } 172 173 174 /******************************************************************************* 175 ** 176 ** Function rfc_mx_sm_state_wait_conn_cnf 177 ** 178 ** Description This function handles events when the multiplexer is 179 ** waiting for Connection Confirm from L2CAP. 180 ** 181 ** Returns void 182 ** 183 *******************************************************************************/ 184 void rfc_mx_sm_state_wait_conn_cnf (tRFC_MCB *p_mcb, UINT16 event, void *p_data) 185 { 186 RFCOMM_TRACE_EVENT ("rfc_mx_sm_state_wait_conn_cnf - evt:%d", event); 187 switch (event) 188 { 189 case RFC_MX_EVENT_START_REQ: 190 RFCOMM_TRACE_ERROR ("Mx error state %d event %d", p_mcb->state, event); 191 return; 192 193 /* There is some new timing so that Config Ind comes before security is completed 194 so we are still waiting fo the confirmation. */ 195 case RFC_MX_EVENT_CONF_IND: 196 rfc_mx_conf_ind (p_mcb, (tL2CAP_CFG_INFO *)p_data); 197 return; 198 199 case RFC_MX_EVENT_CONN_CNF: 200 if (*((UINT16 *)p_data) != L2CAP_SUCCESS) 201 { 202 p_mcb->state = RFC_MX_STATE_IDLE; 203 204 PORT_StartCnf (p_mcb, *((UINT16 *)p_data)); 205 return; 206 } 207 p_mcb->state = RFC_MX_STATE_CONFIGURE; 208 rfc_mx_send_config_req (p_mcb); 209 return; 210 211 case RFC_MX_EVENT_DISC_IND: 212 p_mcb->state = RFC_MX_STATE_IDLE; 213 PORT_CloseInd (p_mcb); 214 return; 215 216 case RFC_EVENT_TIMEOUT: 217 p_mcb->state = RFC_MX_STATE_IDLE; 218 L2CA_DisconnectReq (p_mcb->lcid); 219 220 /* we gave up outgoing connection request then try peer's request */ 221 if (p_mcb->pending_lcid) 222 { 223 UINT16 i; 224 UINT8 idx; 225 226 RFCOMM_TRACE_DEBUG ("RFCOMM MX retry as acceptor in collision case - evt:%d in state:%d", event, p_mcb->state); 227 228 rfc_save_lcid_mcb (NULL, p_mcb->lcid); 229 p_mcb->lcid = p_mcb->pending_lcid; 230 rfc_save_lcid_mcb (p_mcb, p_mcb->lcid); 231 232 p_mcb->is_initiator = FALSE; 233 234 /* update direction bit */ 235 for (i = 0; i < RFCOMM_MAX_DLCI; i += 2) 236 { 237 if ((idx = p_mcb->port_inx[i]) != 0) 238 { 239 p_mcb->port_inx[i] = 0; 240 p_mcb->port_inx[i+1] = idx; 241 rfc_cb.port.port[idx - 1].dlci += 1; 242 RFCOMM_TRACE_DEBUG ("RFCOMM MX - DLCI:%d -> %d", i, rfc_cb.port.port[idx - 1].dlci); 243 } 244 } 245 246 rfc_mx_sm_execute (p_mcb, RFC_MX_EVENT_CONN_IND, &(p_mcb->pending_id)); 247 } 248 else 249 { 250 PORT_CloseInd (p_mcb); 251 } 252 return; 253 } 254 RFCOMM_TRACE_EVENT ("RFCOMM MX ignored - evt:%d in state:%d", event, p_mcb->state); 255 } 256 257 258 /******************************************************************************* 259 ** 260 ** Function rfc_mx_sm_state_configure 261 ** 262 ** Description This function handles events when the multiplexer in the 263 ** configuration state. 264 ** 265 ** Returns void 266 ** 267 *******************************************************************************/ 268 void rfc_mx_sm_state_configure (tRFC_MCB *p_mcb, UINT16 event, void *p_data) 269 { 270 RFCOMM_TRACE_EVENT ("rfc_mx_sm_state_configure - evt:%d", event); 271 switch (event) 272 { 273 case RFC_MX_EVENT_START_REQ: 274 case RFC_MX_EVENT_CONN_CNF: 275 276 RFCOMM_TRACE_ERROR ("Mx error state %d event %d", p_mcb->state, event); 277 return; 278 279 case RFC_MX_EVENT_CONF_IND: 280 rfc_mx_conf_ind (p_mcb, (tL2CAP_CFG_INFO *)p_data); 281 return; 282 283 case RFC_MX_EVENT_CONF_CNF: 284 rfc_mx_conf_cnf (p_mcb, (tL2CAP_CFG_INFO *)p_data); 285 return; 286 287 case RFC_MX_EVENT_DISC_IND: 288 p_mcb->state = RFC_MX_STATE_IDLE; 289 PORT_CloseInd (p_mcb); 290 return; 291 292 case RFC_EVENT_TIMEOUT: 293 p_mcb->state = RFC_MX_STATE_IDLE; 294 L2CA_DisconnectReq (p_mcb->lcid); 295 296 PORT_StartCnf (p_mcb, RFCOMM_ERROR); 297 return; 298 } 299 RFCOMM_TRACE_EVENT ("RFCOMM MX ignored - evt:%d in state:%d", event, p_mcb->state); 300 } 301 302 303 /******************************************************************************* 304 ** 305 ** Function rfc_mx_sm_sabme_wait_ua 306 ** 307 ** Description This function handles events when the multiplexer sent 308 ** SABME and is waiting for UA reply. 309 ** 310 ** Returns void 311 ** 312 *******************************************************************************/ 313 void rfc_mx_sm_sabme_wait_ua (tRFC_MCB *p_mcb, UINT16 event, void *p_data) 314 { 315 UNUSED(p_data); 316 317 RFCOMM_TRACE_EVENT ("rfc_mx_sm_sabme_wait_ua - evt:%d", event); 318 switch (event) 319 { 320 case RFC_MX_EVENT_START_REQ: 321 case RFC_MX_EVENT_CONN_CNF: 322 RFCOMM_TRACE_ERROR ("Mx error state %d event %d", p_mcb->state, event); 323 return; 324 325 /* workaround: we don't support reconfig */ 326 /* commented out until we support reconfig 327 case RFC_MX_EVENT_CONF_IND: 328 rfc_mx_conf_ind (p_mcb, (tL2CAP_CFG_INFO *)p_data); 329 return; 330 331 case RFC_MX_EVENT_CONF_CNF: 332 rfc_mx_conf_cnf (p_mcb, (tL2CAP_CFG_INFO *)p_data); 333 return; 334 */ 335 336 case RFC_MX_EVENT_DISC_IND: 337 p_mcb->state = RFC_MX_STATE_IDLE; 338 PORT_CloseInd (p_mcb); 339 return; 340 341 case RFC_EVENT_UA: 342 rfc_timer_stop (p_mcb); 343 344 p_mcb->state = RFC_MX_STATE_CONNECTED; 345 p_mcb->peer_ready = TRUE; 346 347 PORT_StartCnf (p_mcb, RFCOMM_SUCCESS); 348 return; 349 350 case RFC_EVENT_DM: 351 rfc_timer_stop (p_mcb); 352 /* Case falls through */ 353 354 case RFC_MX_EVENT_CONF_IND: /* workaround: we don't support reconfig */ 355 case RFC_MX_EVENT_CONF_CNF: /* workaround: we don't support reconfig */ 356 case RFC_EVENT_TIMEOUT: 357 p_mcb->state = RFC_MX_STATE_IDLE; 358 L2CA_DisconnectReq (p_mcb->lcid); 359 360 PORT_StartCnf (p_mcb, RFCOMM_ERROR); 361 return; 362 } 363 RFCOMM_TRACE_EVENT ("RFCOMM MX ignored - evt:%d in state:%d", event, p_mcb->state); 364 } 365 366 /******************************************************************************* 367 ** 368 ** Function rfc_mx_sm_state_wait_sabme 369 ** 370 ** Description This function handles events when the multiplexer is 371 ** waiting for SABME on the acceptor side after configuration 372 ** 373 ** Returns void 374 ** 375 *******************************************************************************/ 376 void rfc_mx_sm_state_wait_sabme (tRFC_MCB *p_mcb, UINT16 event, void *p_data) 377 { 378 RFCOMM_TRACE_EVENT ("rfc_mx_sm_state_wait_sabme - evt:%d", event); 379 switch (event) 380 { 381 case RFC_MX_EVENT_DISC_IND: 382 p_mcb->state = RFC_MX_STATE_IDLE; 383 PORT_CloseInd (p_mcb); 384 return; 385 386 case RFC_EVENT_SABME: 387 /* if we gave up outgoing connection request */ 388 if (p_mcb->pending_lcid) 389 { 390 p_mcb->pending_lcid = 0; 391 392 rfc_send_ua (p_mcb, RFCOMM_MX_DLCI); 393 394 rfc_timer_stop (p_mcb); 395 p_mcb->state = RFC_MX_STATE_CONNECTED; 396 p_mcb->peer_ready = TRUE; 397 398 /* MX channel collision has been resolved, continue to open ports */ 399 PORT_StartCnf (p_mcb, RFCOMM_SUCCESS); 400 } 401 else 402 { 403 rfc_timer_stop (p_mcb); 404 PORT_StartInd (p_mcb); 405 } 406 return; 407 408 case RFC_MX_EVENT_START_RSP: 409 if (*((UINT16 *)p_data) != RFCOMM_SUCCESS) 410 rfc_send_dm (p_mcb, RFCOMM_MX_DLCI, TRUE); 411 else 412 { 413 rfc_send_ua (p_mcb, RFCOMM_MX_DLCI); 414 415 p_mcb->state = RFC_MX_STATE_CONNECTED; 416 p_mcb->peer_ready = TRUE; 417 PORT_StartCnf (p_mcb, RFCOMM_SUCCESS); 418 } 419 return; 420 421 case RFC_MX_EVENT_CONF_IND: /* workaround: we don't support reconfig */ 422 case RFC_MX_EVENT_CONF_CNF: /* workaround: we don't support reconfig */ 423 case RFC_EVENT_TIMEOUT: 424 p_mcb->state = RFC_MX_STATE_IDLE; 425 L2CA_DisconnectReq (p_mcb->lcid); 426 427 PORT_CloseInd (p_mcb); 428 return; 429 } 430 RFCOMM_TRACE_EVENT ("RFCOMM MX ignored - evt:%d in state:%d", event, p_mcb->state); 431 } 432 433 434 /******************************************************************************* 435 ** 436 ** Function rfc_mx_sm_state_connected 437 ** 438 ** Description This function handles events when the multiplexer is 439 ** in the CONNECTED state 440 ** 441 ** Returns void 442 ** 443 *******************************************************************************/ 444 void rfc_mx_sm_state_connected (tRFC_MCB *p_mcb, UINT16 event, void *p_data) 445 { 446 UNUSED(p_data); 447 448 RFCOMM_TRACE_EVENT ("rfc_mx_sm_state_connected - evt:%d", event); 449 450 switch (event) 451 { 452 case RFC_EVENT_TIMEOUT: 453 case RFC_MX_EVENT_CLOSE_REQ: 454 rfc_timer_start (p_mcb, RFC_DISC_TIMEOUT); 455 p_mcb->state = RFC_MX_STATE_DISC_WAIT_UA; 456 rfc_send_disc (p_mcb, RFCOMM_MX_DLCI); 457 return; 458 459 case RFC_MX_EVENT_DISC_IND: 460 p_mcb->state = RFC_MX_STATE_IDLE; 461 PORT_CloseInd (p_mcb); 462 return; 463 464 case RFC_EVENT_DISC: 465 /* Reply with UA. If initiator bring down L2CAP connection */ 466 /* If server wait for some time if client decide to reinitiate channel */ 467 rfc_send_ua (p_mcb, RFCOMM_MX_DLCI); 468 if (p_mcb->is_initiator) 469 { 470 L2CA_DisconnectReq (p_mcb->lcid); 471 } 472 /* notify all ports that connection is gone */ 473 PORT_CloseInd (p_mcb); 474 return; 475 } 476 RFCOMM_TRACE_EVENT ("RFCOMM MX ignored - evt:%d in state:%d", event, p_mcb->state); 477 } 478 479 480 /******************************************************************************* 481 ** 482 ** Function rfc_mx_sm_state_disc_wait_ua 483 ** 484 ** Description This function handles events when the multiplexer sent 485 ** DISC and is waiting for UA reply. 486 ** 487 ** Returns void 488 ** 489 *******************************************************************************/ 490 void rfc_mx_sm_state_disc_wait_ua (tRFC_MCB *p_mcb, UINT16 event, void *p_data) 491 { 492 BT_HDR *p_buf; 493 494 RFCOMM_TRACE_EVENT ("rfc_mx_sm_state_disc_wait_ua - evt:%d", event); 495 switch (event) 496 { 497 case RFC_EVENT_UA: 498 case RFC_EVENT_DM: 499 case RFC_EVENT_TIMEOUT: 500 L2CA_DisconnectReq (p_mcb->lcid); 501 502 if (p_mcb->restart_required) 503 { 504 /* Start Request was received while disconnecting. Execute it again */ 505 UINT16 lcid = L2CA_ConnectReq(BT_PSM_RFCOMM, p_mcb->bd_addr); 506 if (lcid == 0) { 507 rfc_save_lcid_mcb(NULL, p_mcb->lcid); 508 p_mcb->lcid = 0; 509 PORT_StartCnf(p_mcb, RFCOMM_ERROR); 510 return; 511 } 512 p_mcb->lcid = lcid; 513 /* Save entry for quicker access to mcb based on the LCID */ 514 rfc_save_lcid_mcb (p_mcb, p_mcb->lcid); 515 516 /* clean up before reuse it */ 517 while ((p_buf = (BT_HDR *)fixed_queue_try_dequeue(p_mcb->cmd_q)) != NULL) 518 osi_free(p_buf); 519 520 rfc_timer_start (p_mcb, RFC_MCB_INIT_INACT_TIMER); 521 522 p_mcb->is_initiator = TRUE; 523 p_mcb->restart_required = FALSE; 524 p_mcb->local_cfg_sent = FALSE; 525 p_mcb->peer_cfg_rcvd = FALSE; 526 527 p_mcb->state = RFC_MX_STATE_WAIT_CONN_CNF; 528 return; 529 } 530 rfc_release_multiplexer_channel (p_mcb); 531 return; 532 533 case RFC_EVENT_DISC: 534 rfc_send_ua (p_mcb, RFCOMM_MX_DLCI); 535 return; 536 537 case RFC_EVENT_UIH: 538 osi_free(p_data); 539 rfc_send_dm (p_mcb, RFCOMM_MX_DLCI, FALSE); 540 return; 541 542 case RFC_MX_EVENT_START_REQ: 543 p_mcb->restart_required = TRUE; 544 return; 545 546 case RFC_MX_EVENT_DISC_IND: 547 p_mcb->state = RFC_MX_STATE_IDLE; 548 PORT_CloseInd (p_mcb); 549 return; 550 551 case RFC_MX_EVENT_CLOSE_REQ: 552 return; 553 554 case RFC_MX_EVENT_QOS_VIOLATION_IND: 555 break; 556 } 557 RFCOMM_TRACE_EVENT ("RFCOMM MX ignored - evt:%d in state:%d", event, p_mcb->state); 558 } 559 560 561 /******************************************************************************* 562 ** 563 ** Function rfc_mx_send_config_req 564 ** 565 ** Description This function handles L2CA_ConnectInd message from the 566 ** L2CAP. Accept connection. 567 ** 568 *******************************************************************************/ 569 static void rfc_mx_send_config_req (tRFC_MCB *p_mcb) 570 { 571 tL2CAP_CFG_INFO cfg; 572 573 RFCOMM_TRACE_EVENT ("rfc_mx_send_config_req"); 574 575 memset (&cfg, 0, sizeof (tL2CAP_CFG_INFO)); 576 577 cfg.mtu_present = TRUE; 578 cfg.mtu = L2CAP_MTU_SIZE; 579 580 /* Defaults set by memset 581 cfg.flush_to_present = FALSE; 582 cfg.qos_present = FALSE; 583 cfg.fcr_present = FALSE; 584 cfg.fcr.mode = L2CAP_FCR_BASIC_MODE; 585 cfg.fcs_present = FALSE; 586 cfg.fcs = N/A when fcs_present is FALSE; 587 */ 588 L2CA_ConfigReq (p_mcb->lcid, &cfg); 589 } 590 591 592 /******************************************************************************* 593 ** 594 ** Function rfc_mx_conf_cnf 595 ** 596 ** Description This function handles L2CA_ConfigCnf message from the 597 ** L2CAP. If result is not success tell upper layer that 598 ** start has not been accepted. If initiator send SABME 599 ** on DLCI 0. T1 is still running. 600 ** 601 *******************************************************************************/ 602 static void rfc_mx_conf_cnf (tRFC_MCB *p_mcb, tL2CAP_CFG_INFO *p_cfg) 603 { 604 RFCOMM_TRACE_EVENT ("rfc_mx_conf_cnf p_cfg:%08x res:%d ", p_cfg, (p_cfg) ? p_cfg->result : 0); 605 606 if (p_cfg->result != L2CAP_CFG_OK) 607 { 608 if (p_mcb->is_initiator) 609 { 610 PORT_StartCnf (p_mcb, p_cfg->result); 611 L2CA_DisconnectReq (p_mcb->lcid); 612 } 613 rfc_release_multiplexer_channel (p_mcb); 614 return; 615 } 616 617 p_mcb->local_cfg_sent = TRUE; 618 if ((p_mcb->state == RFC_MX_STATE_CONFIGURE) && p_mcb->peer_cfg_rcvd) 619 { 620 if (p_mcb->is_initiator) 621 { 622 p_mcb->state = RFC_MX_STATE_SABME_WAIT_UA; 623 rfc_send_sabme (p_mcb, RFCOMM_MX_DLCI); 624 rfc_timer_start (p_mcb, RFC_T1_TIMEOUT); 625 } 626 else 627 { 628 p_mcb->state = RFC_MX_STATE_WAIT_SABME; 629 rfc_timer_start (p_mcb, RFCOMM_CONN_TIMEOUT); /* - increased from T2=20 to CONN=120 630 to allow the user more than 10 sec to type in the 631 pin which can be e.g. 16 digits */ 632 } 633 } 634 } 635 636 637 /******************************************************************************* 638 ** 639 ** Function rfc_mx_conf_ind 640 ** 641 ** Description This function handles L2CA_ConfigInd message from the 642 ** L2CAP. Send the L2CA_ConfigRsp message. 643 ** 644 *******************************************************************************/ 645 static void rfc_mx_conf_ind (tRFC_MCB *p_mcb, tL2CAP_CFG_INFO *p_cfg) 646 { 647 /* Save peer L2CAP MTU if present */ 648 /* RFCOMM adds 3-4 bytes in the beginning and 1 bytes FCS */ 649 if (p_cfg->mtu_present) 650 p_mcb->peer_l2cap_mtu = p_cfg->mtu - RFCOMM_MIN_OFFSET - 1; 651 else 652 p_mcb->peer_l2cap_mtu = L2CAP_DEFAULT_MTU - RFCOMM_MIN_OFFSET - 1; 653 654 p_cfg->mtu_present = FALSE; 655 p_cfg->flush_to_present = FALSE; 656 p_cfg->qos_present = FALSE; 657 658 p_cfg->result = L2CAP_CFG_OK; 659 660 L2CA_ConfigRsp (p_mcb->lcid, p_cfg); 661 662 p_mcb->peer_cfg_rcvd = TRUE; 663 if ((p_mcb->state == RFC_MX_STATE_CONFIGURE) && p_mcb->local_cfg_sent) 664 { 665 if (p_mcb->is_initiator) 666 { 667 p_mcb->state = RFC_MX_STATE_SABME_WAIT_UA; 668 rfc_send_sabme (p_mcb, RFCOMM_MX_DLCI); 669 rfc_timer_start (p_mcb, RFC_T1_TIMEOUT); 670 } 671 else 672 { 673 p_mcb->state = RFC_MX_STATE_WAIT_SABME; 674 rfc_timer_start (p_mcb, RFCOMM_CONN_TIMEOUT); /* - increased from T2=20 to CONN=120 675 to allow the user more than 10 sec to type in the 676 pin which can be e.g. 16 digits */ 677 } 678 } 679 } 680