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/********************************************************************************/ 32static void gap_connect_ind (BD_ADDR bd_addr, UINT16 l2cap_cid, UINT16 psm, UINT8 l2cap_id); 33static void gap_connect_cfm (UINT16 l2cap_cid, UINT16 result); 34static void gap_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg); 35static void gap_config_cfm (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg); 36static void gap_disconnect_ind (UINT16 l2cap_cid, BOOLEAN ack_needed); 37static void gap_data_ind (UINT16 l2cap_cid, BT_HDR *p_msg); 38static void gap_congestion_ind (UINT16 lcid, BOOLEAN is_congested); 39 40static tGAP_CCB *gap_find_ccb_by_cid (UINT16 cid); 41static tGAP_CCB *gap_find_ccb_by_handle (UINT16 handle); 42static tGAP_CCB *gap_allocate_ccb (void); 43static 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*******************************************************************************/ 54void 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*******************************************************************************/ 121UINT16 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*******************************************************************************/ 252UINT16 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*******************************************************************************/ 291UINT16 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*******************************************************************************/ 356int 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*******************************************************************************/ 397UINT16 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*******************************************************************************/ 436UINT16 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*******************************************************************************/ 504UINT16 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*******************************************************************************/ 584UINT16 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*******************************************************************************/ 622UINT16 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*******************************************************************************/ 650UINT8 *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*******************************************************************************/ 682UINT16 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*******************************************************************************/ 704UINT16 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*******************************************************************************/ 726static 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*******************************************************************************/ 779static 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*******************************************************************************/ 801static 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*******************************************************************************/ 833static 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*******************************************************************************/ 877static 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*******************************************************************************/ 927static 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*******************************************************************************/ 965static 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*******************************************************************************/ 992static 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*******************************************************************************/ 1030static 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*******************************************************************************/ 1077static 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*******************************************************************************/ 1104static 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*******************************************************************************/ 1131static 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*******************************************************************************/ 1164static 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*******************************************************************************/ 1204void 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*******************************************************************************/ 1232void 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