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