1 /****************************************************************************** 2 * 3 * Copyright (C) 2009-2013 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 #include "bt_target.h" 21 #include "bt_utils.h" 22 #include "btu.h" 23 #include "gap_int.h" 24 #include "l2cdefs.h" 25 #include "l2c_int.h" 26 #include <string.h> 27 #if GAP_CONN_INCLUDED == TRUE 28 #include "btm_int.h" 29 30 /********************************************************************************/ 31 /* L O C A L F U N C T I O N P R O T O T Y P E S */ 32 /********************************************************************************/ 33 static void gap_connect_ind (BD_ADDR bd_addr, UINT16 l2cap_cid, UINT16 psm, UINT8 l2cap_id); 34 static void gap_connect_cfm (UINT16 l2cap_cid, UINT16 result); 35 static void gap_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg); 36 static void gap_config_cfm (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg); 37 static void gap_disconnect_ind (UINT16 l2cap_cid, BOOLEAN ack_needed); 38 static void gap_data_ind (UINT16 l2cap_cid, BT_HDR *p_msg); 39 static void gap_congestion_ind (UINT16 lcid, BOOLEAN is_congested); 40 41 static tGAP_CCB *gap_find_ccb_by_cid (UINT16 cid); 42 static tGAP_CCB *gap_find_ccb_by_handle (UINT16 handle); 43 static tGAP_CCB *gap_allocate_ccb (void); 44 static void gap_release_ccb (tGAP_CCB *p_ccb); 45 46 /******************************************************************************* 47 ** 48 ** Function gap_conn_init 49 ** 50 ** Description This function is called to initialize GAP connection management 51 ** 52 ** Returns void 53 ** 54 *******************************************************************************/ 55 void gap_conn_init (void) 56 { 57 #if AMP_INCLUDED == TRUE 58 gap_cb.conn.reg_info.pAMP_ConnectInd_Cb = gap_connect_ind; 59 gap_cb.conn.reg_info.pAMP_ConnectCfm_Cb = gap_connect_cfm; 60 gap_cb.conn.reg_info.pAMP_ConnectPnd_Cb = NULL; 61 gap_cb.conn.reg_info.pAMP_ConfigInd_Cb = gap_config_ind; 62 gap_cb.conn.reg_info.pAMP_ConfigCfm_Cb = gap_config_cfm; 63 gap_cb.conn.reg_info.pAMP_DisconnectInd_Cb = gap_disconnect_ind; 64 gap_cb.conn.reg_info.pAMP_DisconnectCfm_Cb = NULL; 65 gap_cb.conn.reg_info.pAMP_QoSViolationInd_Cb = NULL; 66 gap_cb.conn.reg_info.pAMP_DataInd_Cb = gap_data_ind; 67 gap_cb.conn.reg_info.pAMP_CongestionStatus_Cb = gap_congestion_ind; 68 gap_cb.conn.reg_info.pAMP_TxComplete_Cb = NULL; 69 gap_cb.conn.reg_info.pAMP_MoveInd_Cb = NULL; 70 gap_cb.conn.reg_info.pAMP_MoveRsp_Cb = NULL; 71 gap_cb.conn.reg_info.pAMP_MoveCfm_Cb = NULL; //gap_move_cfm 72 gap_cb.conn.reg_info.pAMP_MoveCfmRsp_Cb = NULL; //gap_move_cfm_rsp 73 74 #else 75 gap_cb.conn.reg_info.pL2CA_ConnectInd_Cb = gap_connect_ind; 76 gap_cb.conn.reg_info.pL2CA_ConnectCfm_Cb = gap_connect_cfm; 77 gap_cb.conn.reg_info.pL2CA_ConnectPnd_Cb = NULL; 78 gap_cb.conn.reg_info.pL2CA_ConfigInd_Cb = gap_config_ind; 79 gap_cb.conn.reg_info.pL2CA_ConfigCfm_Cb = gap_config_cfm; 80 gap_cb.conn.reg_info.pL2CA_DisconnectInd_Cb = gap_disconnect_ind; 81 gap_cb.conn.reg_info.pL2CA_DisconnectCfm_Cb = NULL; 82 gap_cb.conn.reg_info.pL2CA_QoSViolationInd_Cb = NULL; 83 gap_cb.conn.reg_info.pL2CA_DataInd_Cb = gap_data_ind; 84 gap_cb.conn.reg_info.pL2CA_CongestionStatus_Cb = gap_congestion_ind; 85 gap_cb.conn.reg_info.pL2CA_TxComplete_Cb = NULL; 86 #endif 87 } 88 89 90 /******************************************************************************* 91 ** 92 ** Function GAP_ConnOpen 93 ** 94 ** Description This function is called to open an L2CAP connection. 95 ** 96 ** Parameters: is_server - If TRUE, the connection is not created 97 ** but put into a "listen" mode waiting for 98 ** the remote side to connect. 99 ** 100 ** service_id - Unique service ID from 101 ** BTM_SEC_SERVICE_FIRST_EMPTY (6) 102 ** to BTM_SEC_MAX_SERVICE_RECORDS (32) 103 ** 104 ** p_rem_bda - Pointer to remote BD Address. 105 ** If a server, and we don't care about the 106 ** remote BD Address, then NULL should be passed. 107 ** 108 ** psm - the PSM used for the connection 109 ** 110 ** p_config - Optional pointer to configuration structure. 111 ** If NULL, the default GAP configuration will 112 ** be used. 113 ** 114 ** security - security flags 115 ** chan_mode_mask - (GAP_FCR_CHAN_OPT_BASIC, GAP_FCR_CHAN_OPT_ERTM, GAP_FCR_CHAN_OPT_STREAM) 116 ** 117 ** p_cb - Pointer to callback function for events. 118 ** 119 ** Returns handle of the connection if successful, else GAP_INVALID_HANDLE 120 ** 121 *******************************************************************************/ 122 UINT16 GAP_ConnOpen (char *p_serv_name, UINT8 service_id, BOOLEAN is_server, 123 BD_ADDR p_rem_bda, UINT16 psm, tL2CAP_CFG_INFO *p_cfg, 124 UINT16 security, UINT8 chan_mode_mask, tGAP_CONN_CALLBACK *p_cb) 125 { 126 tGAP_CCB *p_ccb; 127 UINT16 cid; 128 tBT_UUID bt_uuid = {2, {GAP_PROTOCOL_ID}}; 129 130 GAP_TRACE_EVENT ("GAP_CONN - Open Request"); 131 132 /* Allocate a new CCB. Return if none available. */ 133 if ((p_ccb = gap_allocate_ccb()) == NULL) 134 return (GAP_INVALID_HANDLE); 135 136 /* If caller specified a BD address, save it */ 137 if (p_rem_bda) 138 { 139 /* the bd addr is not BT_BD_ANY, then a bd address was specified */ 140 if (memcmp (p_rem_bda, BT_BD_ANY, BD_ADDR_LEN)) 141 p_ccb->rem_addr_specified = TRUE; 142 143 memcpy (&p_ccb->rem_dev_address[0], p_rem_bda, BD_ADDR_LEN); 144 } 145 else if (!is_server) 146 { 147 /* remore addr is not specified and is not a server -> bad */ 148 return (GAP_INVALID_HANDLE); 149 } 150 151 /* A client MUST have specified a bd addr to connect with */ 152 if (!p_ccb->rem_addr_specified && !is_server) 153 { 154 gap_release_ccb (p_ccb); 155 GAP_TRACE_ERROR ("GAP ERROR: Client must specify a remote BD ADDR to connect to!"); 156 return (GAP_INVALID_HANDLE); 157 } 158 159 /* Check if configuration was specified */ 160 if (p_cfg) 161 p_ccb->cfg = *p_cfg; 162 163 p_ccb->p_callback = p_cb; 164 165 /* If originator, use a dynamic PSM */ 166 #if AMP_INCLUDED == TRUE 167 if (!is_server) 168 gap_cb.conn.reg_info.pAMP_ConnectInd_Cb = NULL; 169 else 170 gap_cb.conn.reg_info.pAMP_ConnectInd_Cb = gap_connect_ind; 171 #else 172 if (!is_server) 173 gap_cb.conn.reg_info.pL2CA_ConnectInd_Cb = NULL; 174 else 175 gap_cb.conn.reg_info.pL2CA_ConnectInd_Cb = gap_connect_ind; 176 #endif 177 178 /* Register the PSM with L2CAP */ 179 if ((p_ccb->psm = L2CA_REGISTER (psm, &gap_cb.conn.reg_info, AMP_AUTOSWITCH_ALLOWED|AMP_USE_AMP_IF_POSSIBLE)) == 0) 180 { 181 GAP_TRACE_ERROR ("GAP_ConnOpen: Failure registering PSM 0x%04x", psm); 182 gap_release_ccb (p_ccb); 183 return (GAP_INVALID_HANDLE); 184 } 185 186 /* Register with Security Manager for the specific security level */ 187 p_ccb->service_id = service_id; 188 if (!BTM_SetSecurityLevel ((UINT8)!is_server, p_serv_name, p_ccb->service_id, security, p_ccb->psm, 0, 0)) 189 { 190 GAP_TRACE_ERROR ("GAP_CONN - Security Error"); 191 gap_release_ccb (p_ccb); 192 return (GAP_INVALID_HANDLE); 193 } 194 195 /* Fill in eL2CAP parameter data */ 196 if( p_ccb->cfg.fcr_present ) 197 { 198 p_ccb->ertm_info.preferred_mode = p_ccb->cfg.fcr.mode; 199 p_ccb->ertm_info.user_rx_pool_id = GAP_DATA_POOL_ID; 200 p_ccb->ertm_info.user_tx_pool_id = GAP_DATA_POOL_ID; 201 p_ccb->ertm_info.fcr_rx_pool_id = L2CAP_DEFAULT_ERM_POOL_ID; 202 p_ccb->ertm_info.fcr_tx_pool_id = L2CAP_DEFAULT_ERM_POOL_ID; 203 } 204 205 /* optional FCR channel modes */ 206 p_ccb->ertm_info.allowed_modes = (chan_mode_mask) ? chan_mode_mask : (UINT8)L2CAP_FCR_CHAN_OPT_BASIC; 207 208 if (is_server) 209 { 210 p_ccb->con_flags |= GAP_CCB_FLAGS_SEC_DONE; /* assume btm/l2cap would handle it */ 211 p_ccb->con_state = GAP_CCB_STATE_LISTENING; 212 return (p_ccb->gap_handle); 213 } 214 else 215 { 216 /* We are the originator of this connection */ 217 p_ccb->con_flags = GAP_CCB_FLAGS_IS_ORIG; 218 219 /* Transition to the next appropriate state, waiting for connection confirm. */ 220 p_ccb->con_state = GAP_CCB_STATE_CONN_SETUP; 221 222 /* mark security done flag, when security is not required */ 223 if ((security & (BTM_SEC_OUT_AUTHORIZE | BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT) ) == 0) 224 p_ccb->con_flags |= GAP_CCB_FLAGS_SEC_DONE; 225 226 /* Check if L2CAP started the connection process */ 227 if (p_rem_bda && ((cid = L2CA_CONNECT_REQ (p_ccb->psm, p_rem_bda, &p_ccb->ertm_info, &bt_uuid)) != 0)) 228 { 229 p_ccb->connection_id = cid; 230 return (p_ccb->gap_handle); 231 } 232 else 233 { 234 gap_release_ccb (p_ccb); 235 return (GAP_INVALID_HANDLE); 236 } 237 } 238 } 239 240 241 /******************************************************************************* 242 ** 243 ** Function GAP_ConnClose 244 ** 245 ** Description This function is called to close a connection. 246 ** 247 ** Parameters: handle - Handle of the connection returned by GAP_ConnOpen 248 ** 249 ** Returns BT_PASS - closed OK 250 ** GAP_ERR_BAD_HANDLE - invalid handle 251 ** 252 *******************************************************************************/ 253 UINT16 GAP_ConnClose (UINT16 gap_handle) 254 { 255 tGAP_CCB *p_ccb = gap_find_ccb_by_handle (gap_handle); 256 257 GAP_TRACE_EVENT ("GAP_CONN - close handle: 0x%x", gap_handle); 258 259 if (p_ccb) 260 { 261 /* Check if we have a connection ID */ 262 if (p_ccb->con_state != GAP_CCB_STATE_LISTENING) 263 L2CA_DISCONNECT_REQ (p_ccb->connection_id); 264 265 gap_release_ccb (p_ccb); 266 267 return (BT_PASS); 268 } 269 270 return (GAP_ERR_BAD_HANDLE); 271 } 272 273 274 275 /******************************************************************************* 276 ** 277 ** Function GAP_ConnReadData 278 ** 279 ** Description Normally not GKI aware application will call this function 280 ** after receiving GAP_EVT_RXDATA event. 281 ** 282 ** Parameters: handle - Handle of the connection returned in the Open 283 ** p_data - Data area 284 ** max_len - Byte count requested 285 ** p_len - Byte count received 286 ** 287 ** Returns BT_PASS - data read 288 ** GAP_ERR_BAD_HANDLE - invalid handle 289 ** GAP_NO_DATA_AVAIL - no data available 290 ** 291 *******************************************************************************/ 292 UINT16 GAP_ConnReadData (UINT16 gap_handle, UINT8 *p_data, UINT16 max_len, UINT16 *p_len) 293 { 294 tGAP_CCB *p_ccb = gap_find_ccb_by_handle (gap_handle); 295 BT_HDR *p_buf; 296 UINT16 copy_len; 297 298 if (!p_ccb) 299 return (GAP_ERR_BAD_HANDLE); 300 301 *p_len = 0; 302 303 p_buf = (BT_HDR *)GKI_getfirst (&p_ccb->rx_queue); 304 if (!p_buf) 305 return (GAP_NO_DATA_AVAIL); 306 307 GKI_disable(); 308 309 while (max_len && p_buf) 310 { 311 copy_len = (p_buf->len > max_len)?max_len:p_buf->len; 312 max_len -= copy_len; 313 *p_len += copy_len; 314 if (p_data) 315 { 316 memcpy (p_data, (UINT8 *)(p_buf + 1) + p_buf->offset, copy_len); 317 p_data += copy_len; 318 } 319 320 if (p_buf->len > copy_len) 321 { 322 p_buf->offset += copy_len; 323 p_buf->len -= copy_len; 324 break; 325 } 326 else 327 { 328 if (max_len) 329 { 330 p_buf = (BT_HDR *)GKI_getnext (p_buf); 331 } 332 GKI_freebuf (GKI_dequeue (&p_ccb->rx_queue)); 333 } 334 } 335 336 p_ccb->rx_queue_size -= *p_len; 337 338 GKI_enable(); 339 340 GAP_TRACE_EVENT ("GAP_ConnReadData - rx_queue_size left=%d, *p_len=%d", 341 p_ccb->rx_queue_size, *p_len); 342 343 return (BT_PASS); 344 } 345 346 /******************************************************************************* 347 ** 348 ** Function GAP_GetRxQueueCnt 349 ** 350 ** Description This function return number of bytes on the rx queue. 351 ** 352 ** Parameters: handle - Handle returned in the GAP_ConnOpen 353 ** p_rx_queue_count - Pointer to return queue count in. 354 ** 355 ** 356 *******************************************************************************/ 357 int GAP_GetRxQueueCnt (UINT16 handle, UINT32 *p_rx_queue_count) 358 { 359 tGAP_CCB *p_ccb; 360 int rc = BT_PASS; 361 362 /* Check that handle is valid */ 363 if (handle < GAP_MAX_CONNECTIONS) 364 { 365 p_ccb = &gap_cb.conn.ccb_pool[handle]; 366 367 if (p_ccb->con_state == GAP_CCB_STATE_CONNECTED) 368 { 369 *p_rx_queue_count = p_ccb->rx_queue_size; 370 } 371 else 372 rc = GAP_INVALID_HANDLE; 373 } 374 else 375 rc = GAP_INVALID_HANDLE; 376 377 GAP_TRACE_EVENT ("GAP_GetRxQueueCnt - rc = 0x%04x, rx_queue_count=%d", 378 rc , *p_rx_queue_count); 379 380 return (rc); 381 } 382 383 /******************************************************************************* 384 ** 385 ** Function GAP_ConnBTRead 386 ** 387 ** Description Bluetooth aware applications will call this function after receiving 388 ** GAP_EVT_RXDATA event. 389 ** 390 ** Parameters: handle - Handle of the connection returned in the Open 391 ** pp_buf - pointer to address of buffer with data, 392 ** 393 ** Returns BT_PASS - data read 394 ** GAP_ERR_BAD_HANDLE - invalid handle 395 ** GAP_NO_DATA_AVAIL - no data available 396 ** 397 *******************************************************************************/ 398 UINT16 GAP_ConnBTRead (UINT16 gap_handle, BT_HDR **pp_buf) 399 { 400 tGAP_CCB *p_ccb = gap_find_ccb_by_handle (gap_handle); 401 BT_HDR *p_buf; 402 403 if (!p_ccb) 404 return (GAP_ERR_BAD_HANDLE); 405 406 p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->rx_queue); 407 408 if (p_buf) 409 { 410 *pp_buf = p_buf; 411 412 p_ccb->rx_queue_size -= p_buf->len; 413 return (BT_PASS); 414 } 415 else 416 { 417 *pp_buf = NULL; 418 return (GAP_NO_DATA_AVAIL); 419 } 420 } 421 422 423 /******************************************************************************* 424 ** 425 ** Function GAP_ConnBTWrite 426 ** 427 ** Description Bluetooth Aware applications can call this function to write data. 428 ** 429 ** Parameters: handle - Handle of the connection returned in the Open 430 ** p_buf - pointer to address of buffer with data, 431 ** 432 ** Returns BT_PASS - data read 433 ** GAP_ERR_BAD_HANDLE - invalid handle 434 ** GAP_ERR_BAD_STATE - connection not established 435 ** GAP_INVALID_BUF_OFFSET - buffer offset is invalid 436 *******************************************************************************/ 437 UINT16 GAP_ConnBTWrite (UINT16 gap_handle, BT_HDR *p_buf) 438 { 439 tGAP_CCB *p_ccb = gap_find_ccb_by_handle (gap_handle); 440 441 if (!p_ccb) 442 { 443 GKI_freebuf (p_buf); 444 return (GAP_ERR_BAD_HANDLE); 445 } 446 447 if (p_ccb->con_state != GAP_CCB_STATE_CONNECTED) 448 { 449 GKI_freebuf (p_buf); 450 return (GAP_ERR_BAD_STATE); 451 } 452 453 if (p_buf->offset < L2CAP_MIN_OFFSET) 454 { 455 GKI_freebuf (p_buf); 456 return (GAP_ERR_BUF_OFFSET); 457 } 458 459 GKI_enqueue (&p_ccb->tx_queue, p_buf); 460 461 if (p_ccb->is_congested) 462 { 463 return (BT_PASS); 464 } 465 466 /* Send the buffer through L2CAP */ 467 #if (GAP_CONN_POST_EVT_INCLUDED == TRUE) 468 gap_send_event (gap_handle); 469 #else 470 while ((p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->tx_queue)) != NULL) 471 { 472 UINT8 status = L2CA_DATA_WRITE (p_ccb->connection_id, p_buf); 473 474 if (status == L2CAP_DW_CONGESTED) 475 { 476 p_ccb->is_congested = TRUE; 477 break; 478 } 479 else if (status != L2CAP_DW_SUCCESS) 480 return (GAP_ERR_BAD_STATE); 481 } 482 #endif 483 return (BT_PASS); 484 } 485 486 487 /******************************************************************************* 488 ** 489 ** Function GAP_ConnWriteData 490 ** 491 ** Description Normally not GKI aware application will call this function 492 ** to send data to the connection. 493 ** 494 ** Parameters: handle - Handle of the connection returned in the Open 495 ** p_data - Data area 496 ** max_len - Byte count requested 497 ** p_len - Byte count received 498 ** 499 ** Returns BT_PASS - data read 500 ** GAP_ERR_BAD_HANDLE - invalid handle 501 ** GAP_ERR_BAD_STATE - connection not established 502 ** GAP_CONGESTION - system is congested 503 ** 504 *******************************************************************************/ 505 UINT16 GAP_ConnWriteData (UINT16 gap_handle, UINT8 *p_data, UINT16 max_len, UINT16 *p_len) 506 { 507 tGAP_CCB *p_ccb = gap_find_ccb_by_handle (gap_handle); 508 BT_HDR *p_buf; 509 510 *p_len = 0; 511 512 if (!p_ccb) 513 return (GAP_ERR_BAD_HANDLE); 514 515 if (p_ccb->con_state != GAP_CCB_STATE_CONNECTED) 516 return (GAP_ERR_BAD_STATE); 517 518 while (max_len) 519 { 520 if (p_ccb->cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) 521 { 522 if ((p_buf = (BT_HDR *)GKI_getpoolbuf (p_ccb->ertm_info.user_tx_pool_id)) == NULL) 523 return (GAP_ERR_CONGESTED); 524 } 525 else 526 { 527 if ((p_buf = (BT_HDR *)GKI_getpoolbuf (GAP_DATA_POOL_ID)) == NULL) 528 return (GAP_ERR_CONGESTED); 529 } 530 531 p_buf->offset = L2CAP_MIN_OFFSET; 532 p_buf->len = (p_ccb->rem_mtu_size < max_len) ? p_ccb->rem_mtu_size : max_len; 533 p_buf->event = BT_EVT_TO_BTU_SP_DATA; 534 535 memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset, p_data, p_buf->len); 536 537 *p_len += p_buf->len; 538 max_len -= p_buf->len; 539 p_data += p_buf->len; 540 541 GAP_TRACE_EVENT ("GAP_WriteData %d bytes", p_buf->len); 542 543 GKI_enqueue (&p_ccb->tx_queue, p_buf); 544 } 545 546 if (p_ccb->is_congested) 547 { 548 return (BT_PASS); 549 } 550 551 /* Send the buffer through L2CAP */ 552 #if (GAP_CONN_POST_EVT_INCLUDED == TRUE) 553 gap_send_event (gap_handle); 554 #else 555 while ((p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->tx_queue)) != NULL) 556 { 557 UINT8 status = L2CA_DATA_WRITE (p_ccb->connection_id, p_buf); 558 559 if (status == L2CAP_DW_CONGESTED) 560 { 561 p_ccb->is_congested = TRUE; 562 break; 563 } 564 else if (status != L2CAP_DW_SUCCESS) 565 return (GAP_ERR_BAD_STATE); 566 } 567 #endif 568 return (BT_PASS); 569 } 570 571 572 /******************************************************************************* 573 ** 574 ** Function GAP_ConnReconfig 575 ** 576 ** Description Applications can call this function to reconfigure the connection. 577 ** 578 ** Parameters: handle - Handle of the connection 579 ** p_cfg - Pointer to new configuration 580 ** 581 ** Returns BT_PASS - config process started 582 ** GAP_ERR_BAD_HANDLE - invalid handle 583 ** 584 *******************************************************************************/ 585 UINT16 GAP_ConnReconfig (UINT16 gap_handle, tL2CAP_CFG_INFO *p_cfg) 586 { 587 tGAP_CCB *p_ccb = gap_find_ccb_by_handle (gap_handle); 588 589 if (!p_ccb) 590 return (GAP_ERR_BAD_HANDLE); 591 592 p_ccb->cfg = *p_cfg; 593 594 if (p_ccb->con_state == GAP_CCB_STATE_CONNECTED) 595 L2CA_CONFIG_REQ (p_ccb->connection_id, p_cfg); 596 597 return (BT_PASS); 598 } 599 600 601 602 /******************************************************************************* 603 ** 604 ** Function GAP_ConnSetIdleTimeout 605 ** 606 ** Description Higher layers call this function to set the idle timeout for 607 ** a connection, or for all future connections. The "idle timeout" 608 ** is the amount of time that a connection can remain up with 609 ** no L2CAP channels on it. A timeout of zero means that the 610 ** connection will be torn down immediately when the last channel 611 ** is removed. A timeout of 0xFFFF means no timeout. Values are 612 ** in seconds. 613 ** 614 ** Parameters: handle - Handle of the connection 615 ** timeout - in secs 616 ** 0 = immediate disconnect when last channel is removed 617 ** 0xFFFF = no idle timeout 618 ** 619 ** Returns BT_PASS - config process started 620 ** GAP_ERR_BAD_HANDLE - invalid handle 621 ** 622 *******************************************************************************/ 623 UINT16 GAP_ConnSetIdleTimeout (UINT16 gap_handle, UINT16 timeout) 624 { 625 tGAP_CCB *p_ccb; 626 627 if ((p_ccb = gap_find_ccb_by_handle (gap_handle)) == NULL) 628 return (GAP_ERR_BAD_HANDLE); 629 630 if (L2CA_SetIdleTimeout (p_ccb->connection_id, timeout, FALSE)) 631 return (BT_PASS); 632 else 633 return (GAP_ERR_BAD_HANDLE); 634 } 635 636 637 638 /******************************************************************************* 639 ** 640 ** Function GAP_ConnGetRemoteAddr 641 ** 642 ** Description This function is called to get the remote BD address 643 ** of a connection. 644 ** 645 ** Parameters: handle - Handle of the connection returned by GAP_ConnOpen 646 ** 647 ** Returns BT_PASS - closed OK 648 ** GAP_ERR_BAD_HANDLE - invalid handle 649 ** 650 *******************************************************************************/ 651 UINT8 *GAP_ConnGetRemoteAddr (UINT16 gap_handle) 652 { 653 tGAP_CCB *p_ccb = gap_find_ccb_by_handle (gap_handle); 654 655 GAP_TRACE_EVENT ("GAP_ConnGetRemoteAddr gap_handle = %d", gap_handle); 656 657 if ((p_ccb) && (p_ccb->con_state > GAP_CCB_STATE_LISTENING)) 658 { 659 GAP_TRACE_EVENT("GAP_ConnGetRemoteAddr bda :0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", \ 660 p_ccb->rem_dev_address[0],p_ccb->rem_dev_address[1],p_ccb->rem_dev_address[2], 661 p_ccb->rem_dev_address[3],p_ccb->rem_dev_address[4],p_ccb->rem_dev_address[5]); 662 return (p_ccb->rem_dev_address); 663 } 664 else 665 { 666 GAP_TRACE_EVENT ("GAP_ConnGetRemoteAddr return Error "); 667 return (NULL); 668 } 669 } 670 671 672 /******************************************************************************* 673 ** 674 ** Function GAP_ConnGetRemMtuSize 675 ** 676 ** Description Returns the remote device's MTU size 677 ** 678 ** Parameters: handle - Handle of the connection 679 ** 680 ** Returns UINT16 - maximum size buffer that can be transmitted to the peer 681 ** 682 *******************************************************************************/ 683 UINT16 GAP_ConnGetRemMtuSize (UINT16 gap_handle) 684 { 685 tGAP_CCB *p_ccb; 686 687 if ((p_ccb = gap_find_ccb_by_handle (gap_handle)) == NULL) 688 return (0); 689 690 return (p_ccb->rem_mtu_size); 691 } 692 693 /******************************************************************************* 694 ** 695 ** Function GAP_ConnGetL2CAPCid 696 ** 697 ** Description Returns the L2CAP channel id 698 ** 699 ** Parameters: handle - Handle of the connection 700 ** 701 ** Returns UINT16 - The L2CAP channel id 702 ** 0, if error 703 ** 704 *******************************************************************************/ 705 UINT16 GAP_ConnGetL2CAPCid (UINT16 gap_handle) 706 { 707 tGAP_CCB *p_ccb; 708 709 if ((p_ccb = gap_find_ccb_by_handle (gap_handle)) == NULL) 710 return (0); 711 712 return (p_ccb->connection_id); 713 } 714 715 716 /******************************************************************************* 717 ** 718 ** Function gap_connect_ind 719 ** 720 ** Description This function handles an inbound connection indication 721 ** from L2CAP. This is the case where we are acting as a 722 ** server. 723 ** 724 ** Returns void 725 ** 726 *******************************************************************************/ 727 static void gap_connect_ind (BD_ADDR bd_addr, UINT16 l2cap_cid, UINT16 psm, UINT8 l2cap_id) 728 { 729 UINT16 xx; 730 tGAP_CCB *p_ccb; 731 tBT_UUID bt_uuid = {2, {GAP_PROTOCOL_ID}}; 732 733 /* See if we have a CCB listening for the connection */ 734 for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++) 735 { 736 if ((p_ccb->con_state == GAP_CCB_STATE_LISTENING) 737 && (p_ccb->psm == psm) 738 && ((p_ccb->rem_addr_specified == FALSE) 739 || (!memcmp (bd_addr, p_ccb->rem_dev_address, BD_ADDR_LEN)))) 740 break; 741 } 742 743 if (xx == GAP_MAX_CONNECTIONS) 744 { 745 GAP_TRACE_WARNING("*******"); 746 GAP_TRACE_WARNING("WARNING: GAP Conn Indication for Unexpected Bd Addr...Disconnecting"); 747 GAP_TRACE_WARNING("*******"); 748 749 /* Disconnect because it is an unexpected connection */ 750 L2CA_DISCONNECT_REQ (l2cap_cid); 751 return; 752 } 753 754 /* Transition to the next appropriate state, waiting for config setup. */ 755 p_ccb->con_state = GAP_CCB_STATE_CFG_SETUP; 756 757 /* Save the BD Address and Channel ID. */ 758 memcpy (&p_ccb->rem_dev_address[0], bd_addr, BD_ADDR_LEN); 759 p_ccb->connection_id = l2cap_cid; 760 761 /* Send response to the L2CAP layer. */ 762 L2CA_CONNECT_RSP (bd_addr, l2cap_id, l2cap_cid, L2CAP_CONN_OK, L2CAP_CONN_OK, &p_ccb->ertm_info, &bt_uuid); 763 764 GAP_TRACE_EVENT("GAP_CONN - Rcvd L2CAP conn ind, CID: 0x%x", p_ccb->connection_id); 765 766 /* Send a Configuration Request. */ 767 L2CA_CONFIG_REQ (l2cap_cid, &p_ccb->cfg); 768 } 769 770 /******************************************************************************* 771 ** 772 ** Function gap_checks_con_flags 773 ** 774 ** Description This function processes the L2CAP configuration indication 775 ** event. 776 ** 777 ** Returns void 778 ** 779 *******************************************************************************/ 780 static void gap_checks_con_flags (tGAP_CCB *p_ccb) 781 { 782 GAP_TRACE_EVENT ("gap_checks_con_flags conn_flags:0x%x, ", p_ccb->con_flags); 783 /* if all the required con_flags are set, report the OPEN event now */ 784 if ((p_ccb->con_flags & GAP_CCB_FLAGS_CONN_DONE) == GAP_CCB_FLAGS_CONN_DONE) 785 { 786 p_ccb->con_state = GAP_CCB_STATE_CONNECTED; 787 788 p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_OPENED); 789 } 790 } 791 792 /******************************************************************************* 793 ** 794 ** Function gap_sec_check_complete 795 ** 796 ** Description The function called when Security Manager finishes 797 ** verification of the service side connection 798 ** 799 ** Returns void 800 ** 801 *******************************************************************************/ 802 static void gap_sec_check_complete (BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, UINT8 res) 803 { 804 tGAP_CCB *p_ccb = (tGAP_CCB *)p_ref_data; 805 UNUSED(bd_addr); 806 UNUSED (transport); 807 808 GAP_TRACE_EVENT ("gap_sec_check_complete conn_state:%d, conn_flags:0x%x, status:%d", 809 p_ccb->con_state, p_ccb->con_flags, res); 810 if (p_ccb->con_state == GAP_CCB_STATE_IDLE) 811 return; 812 813 if (res == BTM_SUCCESS) 814 { 815 p_ccb->con_flags |= GAP_CCB_FLAGS_SEC_DONE; 816 gap_checks_con_flags (p_ccb); 817 } 818 else 819 { 820 /* security failed - disconnect the channel */ 821 L2CA_DISCONNECT_REQ (p_ccb->connection_id); 822 } 823 } 824 825 /******************************************************************************* 826 ** 827 ** Function gap_connect_cfm 828 ** 829 ** Description This function handles the connect confirm events 830 ** from L2CAP. This is the case when we are acting as a 831 ** client and have sent a connect request. 832 ** 833 ** Returns void 834 ** 835 *******************************************************************************/ 836 static void gap_connect_cfm (UINT16 l2cap_cid, UINT16 result) 837 { 838 tGAP_CCB *p_ccb; 839 840 /* Find CCB based on CID */ 841 if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL) 842 return; 843 844 /* initiate security process, if needed */ 845 if ( (p_ccb->con_flags & GAP_CCB_FLAGS_SEC_DONE) == 0) 846 { 847 btm_sec_mx_access_request (p_ccb->rem_dev_address, p_ccb->psm, TRUE, 848 0, 0, &gap_sec_check_complete, p_ccb); 849 } 850 851 /* If the connection response contains success status, then */ 852 /* Transition to the next state and startup the timer. */ 853 if ((result == L2CAP_CONN_OK) && (p_ccb->con_state == GAP_CCB_STATE_CONN_SETUP)) 854 { 855 p_ccb->con_state = GAP_CCB_STATE_CFG_SETUP; 856 857 /* Send a Configuration Request. */ 858 L2CA_CONFIG_REQ (l2cap_cid, &p_ccb->cfg); 859 } 860 else 861 { 862 /* Tell the user if he has a callback */ 863 if (p_ccb->p_callback) 864 (*p_ccb->p_callback) (p_ccb->gap_handle, GAP_EVT_CONN_CLOSED); 865 866 gap_release_ccb (p_ccb); 867 } 868 } 869 870 /******************************************************************************* 871 ** 872 ** Function gap_config_ind 873 ** 874 ** Description This function processes the L2CAP configuration indication 875 ** event. 876 ** 877 ** Returns void 878 ** 879 *******************************************************************************/ 880 static void gap_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg) 881 { 882 tGAP_CCB *p_ccb; 883 UINT16 local_mtu_size; 884 885 /* Find CCB based on CID */ 886 if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL) 887 return; 888 889 /* Remember the remote MTU size */ 890 891 if (p_ccb->cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) 892 { 893 local_mtu_size = GKI_get_pool_bufsize (p_ccb->ertm_info.user_tx_pool_id) 894 - sizeof(BT_HDR) - L2CAP_MIN_OFFSET; 895 } 896 else 897 local_mtu_size = L2CAP_MTU_SIZE; 898 899 if ((!p_cfg->mtu_present)||(p_cfg->mtu > local_mtu_size)) 900 { 901 p_ccb->rem_mtu_size = local_mtu_size; 902 } 903 else 904 p_ccb->rem_mtu_size = p_cfg->mtu; 905 906 /* For now, always accept configuration from the other side */ 907 p_cfg->flush_to_present = FALSE; 908 p_cfg->mtu_present = FALSE; 909 p_cfg->result = L2CAP_CFG_OK; 910 p_cfg->fcs_present = FALSE; 911 912 L2CA_CONFIG_RSP (l2cap_cid, p_cfg); 913 914 p_ccb->con_flags |= GAP_CCB_FLAGS_HIS_CFG_DONE; 915 916 gap_checks_con_flags (p_ccb); 917 } 918 919 920 /******************************************************************************* 921 ** 922 ** Function gap_config_cfm 923 ** 924 ** Description This function processes the L2CAP configuration confirmation 925 ** event. 926 ** 927 ** Returns void 928 ** 929 *******************************************************************************/ 930 static void gap_config_cfm (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg) 931 { 932 tGAP_CCB *p_ccb; 933 934 /* Find CCB based on CID */ 935 if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL) 936 return; 937 938 if (p_cfg->result == L2CAP_CFG_OK) 939 { 940 p_ccb->con_flags |= GAP_CCB_FLAGS_MY_CFG_DONE; 941 942 943 if (p_ccb->cfg.fcr_present) 944 p_ccb->cfg.fcr.mode = p_cfg->fcr.mode; 945 else 946 p_ccb->cfg.fcr.mode = L2CAP_FCR_BASIC_MODE; 947 948 gap_checks_con_flags (p_ccb); 949 } 950 else 951 { 952 p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_CLOSED); 953 gap_release_ccb (p_ccb); 954 } 955 } 956 957 958 /******************************************************************************* 959 ** 960 ** Function gap_disconnect_ind 961 ** 962 ** Description This function handles a disconnect event from L2CAP. If 963 ** requested to, we ack the disconnect before dropping the CCB 964 ** 965 ** Returns void 966 ** 967 *******************************************************************************/ 968 static void gap_disconnect_ind (UINT16 l2cap_cid, BOOLEAN ack_needed) 969 { 970 tGAP_CCB *p_ccb; 971 972 GAP_TRACE_EVENT ("GAP_CONN - Rcvd L2CAP disc, CID: 0x%x", l2cap_cid); 973 974 /* Find CCB based on CID */ 975 if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL) 976 return; 977 978 if (ack_needed) 979 L2CA_DISCONNECT_RSP (l2cap_cid); 980 981 p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_CLOSED); 982 gap_release_ccb (p_ccb); 983 } 984 985 986 /******************************************************************************* 987 ** 988 ** Function gap_data_ind 989 ** 990 ** Description This function is called when data is received from L2CAP. 991 ** 992 ** Returns void 993 ** 994 *******************************************************************************/ 995 static void gap_data_ind (UINT16 l2cap_cid, BT_HDR *p_msg) 996 { 997 tGAP_CCB *p_ccb; 998 999 /* Find CCB based on CID */ 1000 if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL) 1001 { 1002 GKI_freebuf (p_msg); 1003 return; 1004 } 1005 1006 if (p_ccb->con_state == GAP_CCB_STATE_CONNECTED) 1007 { 1008 GKI_enqueue (&p_ccb->rx_queue, p_msg); 1009 1010 p_ccb->rx_queue_size += p_msg->len; 1011 /* 1012 GAP_TRACE_EVENT ("gap_data_ind - rx_queue_size=%d, msg len=%d", 1013 p_ccb->rx_queue_size, p_msg->len); 1014 */ 1015 1016 p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_DATA_AVAIL); 1017 } 1018 else 1019 { 1020 GKI_freebuf (p_msg); 1021 } 1022 } 1023 1024 1025 /******************************************************************************* 1026 ** 1027 ** Function gap_congestion_ind 1028 ** 1029 ** Description This is a callback function called by L2CAP when 1030 ** data L2CAP congestion status changes 1031 ** 1032 *******************************************************************************/ 1033 static void gap_congestion_ind (UINT16 lcid, BOOLEAN is_congested) 1034 { 1035 tGAP_CCB *p_ccb; 1036 UINT16 event; 1037 BT_HDR *p_buf; 1038 UINT8 status; 1039 1040 GAP_TRACE_EVENT ("GAP_CONN - Rcvd L2CAP Is Congested (%d), CID: 0x%x", 1041 is_congested, lcid); 1042 1043 /* Find CCB based on CID */ 1044 if ((p_ccb = gap_find_ccb_by_cid (lcid)) == NULL) 1045 return; 1046 1047 p_ccb->is_congested = is_congested; 1048 1049 event = (is_congested) ? GAP_EVT_CONN_CONGESTED : GAP_EVT_CONN_UNCONGESTED; 1050 p_ccb->p_callback (p_ccb->gap_handle, event); 1051 1052 if (!is_congested) 1053 { 1054 while ((p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->tx_queue)) != NULL) 1055 { 1056 status = L2CA_DATA_WRITE (p_ccb->connection_id, p_buf); 1057 1058 if (status == L2CAP_DW_CONGESTED) 1059 { 1060 p_ccb->is_congested = TRUE; 1061 break; 1062 } 1063 else if (status != L2CAP_DW_SUCCESS) 1064 break; 1065 } 1066 } 1067 } 1068 1069 1070 /******************************************************************************* 1071 ** 1072 ** Function gap_find_ccb_by_cid 1073 ** 1074 ** Description This function searches the CCB table for an entry with the 1075 ** passed CID. 1076 ** 1077 ** Returns the CCB address, or NULL if not found. 1078 ** 1079 *******************************************************************************/ 1080 static tGAP_CCB *gap_find_ccb_by_cid (UINT16 cid) 1081 { 1082 UINT16 xx; 1083 tGAP_CCB *p_ccb; 1084 1085 /* Look through each connection control block */ 1086 for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++) 1087 { 1088 if ((p_ccb->con_state != GAP_CCB_STATE_IDLE) && (p_ccb->connection_id == cid)) 1089 return (p_ccb); 1090 } 1091 1092 /* If here, not found */ 1093 return (NULL); 1094 } 1095 1096 1097 /******************************************************************************* 1098 ** 1099 ** Function gap_find_ccb_by_handle 1100 ** 1101 ** Description This function searches the CCB table for an entry with the 1102 ** passed handle. 1103 ** 1104 ** Returns the CCB address, or NULL if not found. 1105 ** 1106 *******************************************************************************/ 1107 static tGAP_CCB *gap_find_ccb_by_handle (UINT16 handle) 1108 { 1109 tGAP_CCB *p_ccb; 1110 1111 /* Check that handle is valid */ 1112 if (handle < GAP_MAX_CONNECTIONS) 1113 { 1114 p_ccb = &gap_cb.conn.ccb_pool[handle]; 1115 1116 if (p_ccb->con_state != GAP_CCB_STATE_IDLE) 1117 return (p_ccb); 1118 } 1119 1120 /* If here, handle points to invalid connection */ 1121 return (NULL); 1122 } 1123 1124 1125 /******************************************************************************* 1126 ** 1127 ** Function gap_allocate_ccb 1128 ** 1129 ** Description This function allocates a new CCB. 1130 ** 1131 ** Returns CCB address, or NULL if none available. 1132 ** 1133 *******************************************************************************/ 1134 static tGAP_CCB *gap_allocate_ccb (void) 1135 { 1136 UINT16 xx; 1137 tGAP_CCB *p_ccb; 1138 1139 /* Look through each connection control block for a free one */ 1140 for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++) 1141 { 1142 if (p_ccb->con_state == GAP_CCB_STATE_IDLE) 1143 { 1144 memset (p_ccb, 0, sizeof (tGAP_CCB)); 1145 1146 p_ccb->gap_handle = xx; 1147 p_ccb->rem_mtu_size = L2CAP_MTU_SIZE; 1148 1149 return (p_ccb); 1150 } 1151 } 1152 1153 /* If here, no free CCB found */ 1154 return (NULL); 1155 } 1156 1157 1158 /******************************************************************************* 1159 ** 1160 ** Function gap_release_ccb 1161 ** 1162 ** Description This function releases a CCB. 1163 ** 1164 ** Returns void 1165 ** 1166 *******************************************************************************/ 1167 static void gap_release_ccb (tGAP_CCB *p_ccb) 1168 { 1169 UINT16 xx; 1170 UINT16 psm = p_ccb->psm; 1171 UINT8 service_id = p_ccb->service_id; 1172 1173 /* Drop any buffers we may be holding */ 1174 p_ccb->rx_queue_size = 0; 1175 1176 while (p_ccb->rx_queue.p_first) 1177 GKI_freebuf (GKI_dequeue (&p_ccb->rx_queue)); 1178 1179 while (p_ccb->tx_queue.p_first) 1180 GKI_freebuf (GKI_dequeue (&p_ccb->tx_queue)); 1181 1182 p_ccb->con_state = GAP_CCB_STATE_IDLE; 1183 1184 /* If no-one else is using the PSM, deregister from L2CAP */ 1185 for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++) 1186 { 1187 if ((p_ccb->con_state != GAP_CCB_STATE_IDLE) && (p_ccb->psm == psm)) 1188 return; 1189 } 1190 1191 /* Free the security record for this PSM */ 1192 BTM_SecClrService(service_id); 1193 L2CA_DEREGISTER (psm); 1194 } 1195 1196 #if (GAP_CONN_POST_EVT_INCLUDED == TRUE) 1197 1198 /******************************************************************************* 1199 ** 1200 ** Function gap_send_event 1201 ** 1202 ** Description Send BT_EVT_TO_GAP_MSG event to BTU task 1203 ** 1204 ** Returns None 1205 ** 1206 *******************************************************************************/ 1207 void gap_send_event (UINT16 gap_handle) 1208 { 1209 BT_HDR *p_msg; 1210 1211 if ((p_msg = (BT_HDR*)GKI_getbuf(BT_HDR_SIZE)) != NULL) 1212 { 1213 p_msg->event = BT_EVT_TO_GAP_MSG; 1214 p_msg->len = 0; 1215 p_msg->offset = 0; 1216 p_msg->layer_specific = gap_handle; 1217 1218 GKI_send_msg(BTU_TASK, BTU_HCI_RCV_MBOX, p_msg); 1219 } 1220 else 1221 { 1222 GAP_TRACE_ERROR("Unable to allocate message buffer for event."); 1223 } 1224 } 1225 1226 /******************************************************************************* 1227 ** 1228 ** Function gap_proc_btu_event 1229 ** 1230 ** Description Event handler for BT_EVT_TO_GAP_MSG event from BTU task 1231 ** 1232 ** Returns None 1233 ** 1234 *******************************************************************************/ 1235 void gap_proc_btu_event(BT_HDR *p_msg) 1236 { 1237 tGAP_CCB *p_ccb = gap_find_ccb_by_handle (p_msg->layer_specific); 1238 UINT8 status; 1239 BT_HDR *p_buf; 1240 1241 if (!p_ccb) 1242 { 1243 return; 1244 } 1245 1246 if (p_ccb->con_state != GAP_CCB_STATE_CONNECTED) 1247 { 1248 return; 1249 } 1250 1251 if (p_ccb->is_congested) 1252 { 1253 return; 1254 } 1255 1256 /* Send the buffer through L2CAP */ 1257 1258 while ((p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->tx_queue)) != NULL) 1259 { 1260 status = L2CA_DATA_WRITE (p_ccb->connection_id, p_buf); 1261 1262 if (status == L2CAP_DW_CONGESTED) 1263 { 1264 p_ccb->is_congested = TRUE; 1265 break; 1266 } 1267 else if (status != L2CAP_DW_SUCCESS) 1268 break; 1269 } 1270 1271 } 1272 #endif /* (GAP_CONN_POST_EVT_INCLUDED == TRUE) */ 1273 #endif /* GAP_CONN_INCLUDED */ 1274