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