1 /****************************************************************************** 2 * 3 * Copyright (C) 2008-2012 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 /****************************************************************************** 20 * 21 * this file contains the main ATT functions 22 * 23 ******************************************************************************/ 24 25 #include "bt_target.h" 26 27 #if BLE_INCLUDED == TRUE 28 29 #include "gki.h" 30 #include "gatt_int.h" 31 #include "l2c_api.h" 32 #include "btm_int.h" 33 #include "btm_ble_int.h" 34 #include "bt_utils.h" 35 36 /* Configuration flags. */ 37 #define GATT_L2C_CFG_IND_DONE (1<<0) 38 #define GATT_L2C_CFG_CFM_DONE (1<<1) 39 40 /* minimum GATT MTU size over BR/EDR link 41 */ 42 #define GATT_MIN_BR_MTU_SIZE 48 43 44 /********************************************************************************/ 45 /* L O C A L F U N C T I O N P R O T O T Y P E S */ 46 /********************************************************************************/ 47 static void gatt_le_connect_cback (UINT16 chan, BD_ADDR bd_addr, BOOLEAN connected, 48 UINT16 reason, tBT_TRANSPORT transport); 49 static void gatt_le_data_ind (UINT16 chan, BD_ADDR bd_addr, BT_HDR *p_buf); 50 static void gatt_le_cong_cback(BD_ADDR remote_bda, BOOLEAN congest); 51 52 static void gatt_l2cif_connect_ind_cback (BD_ADDR bd_addr, UINT16 l2cap_cid, 53 UINT16 psm, UINT8 l2cap_id); 54 static void gatt_l2cif_connect_cfm_cback (UINT16 l2cap_cid, UINT16 result); 55 static void gatt_l2cif_config_ind_cback (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg); 56 static void gatt_l2cif_config_cfm_cback (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg); 57 static void gatt_l2cif_disconnect_ind_cback (UINT16 l2cap_cid, BOOLEAN ack_needed); 58 static void gatt_l2cif_disconnect_cfm_cback (UINT16 l2cap_cid, UINT16 result); 59 static void gatt_l2cif_data_ind_cback (UINT16 l2cap_cid, BT_HDR *p_msg); 60 static void gatt_send_conn_cback (tGATT_TCB *p_tcb); 61 static void gatt_l2cif_congest_cback (UINT16 cid, BOOLEAN congested); 62 63 static const tL2CAP_APPL_INFO dyn_info = 64 { 65 gatt_l2cif_connect_ind_cback, 66 gatt_l2cif_connect_cfm_cback, 67 NULL, 68 gatt_l2cif_config_ind_cback, 69 gatt_l2cif_config_cfm_cback, 70 gatt_l2cif_disconnect_ind_cback, 71 gatt_l2cif_disconnect_cfm_cback, 72 NULL, 73 gatt_l2cif_data_ind_cback, 74 gatt_l2cif_congest_cback, 75 NULL 76 } ; 77 78 #if GATT_DYNAMIC_MEMORY == FALSE 79 tGATT_CB gatt_cb; 80 #endif 81 82 /******************************************************************************* 83 ** 84 ** Function gatt_init 85 ** 86 ** Description This function is enable the GATT profile on the device. 87 ** It clears out the control blocks, and registers with L2CAP. 88 ** 89 ** Returns void 90 ** 91 *******************************************************************************/ 92 void gatt_init (void) 93 { 94 tL2CAP_FIXED_CHNL_REG fixed_reg; 95 96 GATT_TRACE_DEBUG("gatt_init()"); 97 98 memset (&gatt_cb, 0, sizeof(tGATT_CB)); 99 memset (&fixed_reg, 0, sizeof(tL2CAP_FIXED_CHNL_REG)); 100 101 #if defined(GATT_INITIAL_TRACE_LEVEL) 102 gatt_cb.trace_level = GATT_INITIAL_TRACE_LEVEL; 103 #else 104 gatt_cb.trace_level = BT_TRACE_LEVEL_NONE; /* No traces */ 105 #endif 106 gatt_cb.def_mtu_size = GATT_DEF_BLE_MTU_SIZE; 107 GKI_init_q (&gatt_cb.sign_op_queue); 108 GKI_init_q (&gatt_cb.srv_chg_clt_q); 109 GKI_init_q (&gatt_cb.pending_new_srv_start_q); 110 /* First, register fixed L2CAP channel for ATT over BLE */ 111 fixed_reg.fixed_chnl_opts.mode = L2CAP_FCR_BASIC_MODE; 112 fixed_reg.fixed_chnl_opts.max_transmit = 0xFF; 113 fixed_reg.fixed_chnl_opts.rtrans_tout = 2000; 114 fixed_reg.fixed_chnl_opts.mon_tout = 12000; 115 fixed_reg.fixed_chnl_opts.mps = 670; 116 fixed_reg.fixed_chnl_opts.tx_win_sz = 1; 117 118 fixed_reg.pL2CA_FixedConn_Cb = gatt_le_connect_cback; 119 fixed_reg.pL2CA_FixedData_Cb = gatt_le_data_ind; 120 fixed_reg.pL2CA_FixedCong_Cb = gatt_le_cong_cback; /* congestion callback */ 121 fixed_reg.default_idle_tout = 0xffff; /* 0xffff default idle timeout */ 122 123 L2CA_RegisterFixedChannel (L2CAP_ATT_CID, &fixed_reg); 124 125 /* Now, register with L2CAP for ATT PSM over BR/EDR */ 126 if (!L2CA_Register (BT_PSM_ATT, (tL2CAP_APPL_INFO *) &dyn_info)) 127 { 128 GATT_TRACE_ERROR ("ATT Dynamic Registration failed"); 129 } 130 131 BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_ATT, BTM_SEC_NONE, BT_PSM_ATT, 0, 0); 132 BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_ATT, BTM_SEC_NONE, BT_PSM_ATT, 0, 0); 133 134 gatt_cb.hdl_cfg.gatt_start_hdl = GATT_GATT_START_HANDLE; 135 gatt_cb.hdl_cfg.gap_start_hdl = GATT_GAP_START_HANDLE; 136 gatt_cb.hdl_cfg.app_start_hdl = GATT_APP_START_HANDLE; 137 gatt_profile_db_init(); 138 139 } 140 141 142 /******************************************************************************* 143 ** 144 ** Function gatt_free 145 ** 146 ** Description This function frees resources used by the GATT profile. 147 ** 148 ** Returns void 149 ** 150 *******************************************************************************/ 151 void gatt_free(void) 152 { 153 int i; 154 GATT_TRACE_DEBUG("gatt_free()"); 155 for (i = 0; i < GATT_MAX_SR_PROFILES; i++) 156 { 157 gatt_free_hdl_buffer(&gatt_cb.hdl_list[i]); 158 } 159 } 160 161 /******************************************************************************* 162 ** 163 ** Function gatt_connect 164 ** 165 ** Description This function is called to initiate a connection to a peer device. 166 ** 167 ** Parameter rem_bda: remote device address to connect to. 168 ** 169 ** Returns TRUE if connection is started, otherwise return FALSE. 170 ** 171 *******************************************************************************/ 172 BOOLEAN gatt_connect (BD_ADDR rem_bda, tGATT_TCB *p_tcb, tBT_TRANSPORT transport) 173 { 174 BOOLEAN gatt_ret = FALSE; 175 176 if (gatt_get_ch_state(p_tcb) != GATT_CH_OPEN) 177 gatt_set_ch_state(p_tcb, GATT_CH_CONN); 178 179 if (transport == BT_TRANSPORT_LE) 180 { 181 p_tcb->att_lcid = L2CAP_ATT_CID; 182 gatt_ret = L2CA_ConnectFixedChnl (L2CAP_ATT_CID, rem_bda); 183 } 184 else 185 { 186 if ((p_tcb->att_lcid = L2CA_ConnectReq(BT_PSM_ATT, rem_bda)) != 0) 187 gatt_ret = TRUE; 188 } 189 190 return gatt_ret; 191 } 192 193 /******************************************************************************* 194 ** 195 ** Function gatt_disconnect 196 ** 197 ** Description This function is called to disconnect to an ATT device. 198 ** 199 ** Parameter p_tcb: pointer to the TCB to disconnect. 200 ** 201 ** Returns TRUE: if connection found and to be disconnected; otherwise 202 ** return FALSE. 203 ** 204 *******************************************************************************/ 205 BOOLEAN gatt_disconnect (tGATT_TCB *p_tcb) 206 { 207 BOOLEAN ret = FALSE; 208 tGATT_CH_STATE ch_state; 209 GATT_TRACE_DEBUG ("gatt_disconnect "); 210 211 if (p_tcb != NULL) 212 { 213 ret = TRUE; 214 if ( (ch_state = gatt_get_ch_state(p_tcb)) != GATT_CH_CLOSING ) 215 { 216 if (p_tcb->att_lcid == L2CAP_ATT_CID) 217 { 218 if (ch_state == GATT_CH_OPEN) 219 { 220 /* only LCB exist between remote device and local */ 221 ret = L2CA_RemoveFixedChnl (L2CAP_ATT_CID, p_tcb->peer_bda); 222 } 223 else 224 { 225 gatt_set_ch_state(p_tcb, GATT_CH_CLOSING); 226 ret = L2CA_CancelBleConnectReq (p_tcb->peer_bda); 227 } 228 } 229 else 230 { 231 ret = L2CA_DisconnectReq(p_tcb->att_lcid); 232 } 233 } 234 else 235 { 236 GATT_TRACE_DEBUG ("gatt_disconnect already in closing state"); 237 } 238 } 239 240 return ret; 241 } 242 243 /******************************************************************************* 244 ** 245 ** Function gatt_update_app_hold_link_status 246 ** 247 ** Description Update the application use link status 248 ** 249 ** Returns void. 250 ** 251 *******************************************************************************/ 252 void gatt_update_app_hold_link_status (tGATT_IF gatt_if, tGATT_TCB *p_tcb, BOOLEAN is_add) 253 { 254 UINT8 i; 255 BOOLEAN found=FALSE; 256 257 if (p_tcb == NULL) 258 { 259 GATT_TRACE_ERROR("gatt_update_app_hold_link_status p_tcb=NULL"); 260 return; 261 } 262 263 264 for (i=0; i<GATT_MAX_APPS; i++) 265 { 266 if (p_tcb->app_hold_link[i] == gatt_if) 267 { 268 found = TRUE; 269 if (!is_add) 270 { 271 p_tcb->app_hold_link[i] = 0; 272 break; 273 } 274 } 275 } 276 277 if (!found && is_add) 278 { 279 for (i=0; i<GATT_MAX_APPS; i++) 280 { 281 if (p_tcb->app_hold_link[i] == 0) 282 { 283 p_tcb->app_hold_link[i] = gatt_if; 284 found = TRUE; 285 break; 286 } 287 } 288 } 289 290 GATT_TRACE_DEBUG("gatt_update_app_hold_link_status found=%d[1-found] idx=%d gatt_if=%d is_add=%d", found, i, gatt_if, is_add); 291 292 } 293 294 /******************************************************************************* 295 ** 296 ** Function gatt_update_app_use_link_flag 297 ** 298 ** Description Update the application use link flag and optional to check the acl link 299 ** if the link is up then set the idle time out accordingly 300 ** 301 ** Returns void. 302 ** 303 *******************************************************************************/ 304 void gatt_update_app_use_link_flag (tGATT_IF gatt_if, tGATT_TCB *p_tcb, BOOLEAN is_add, BOOLEAN check_acl_link) 305 { 306 GATT_TRACE_DEBUG("gatt_update_app_use_link_flag is_add=%d chk_link=%d", 307 is_add, check_acl_link); 308 309 gatt_update_app_hold_link_status(gatt_if, p_tcb, is_add); 310 311 if (check_acl_link && 312 p_tcb && 313 p_tcb->att_lcid == L2CAP_ATT_CID && /* only update link idle timer for fixed channel */ 314 (BTM_GetHCIConnHandle(p_tcb->peer_bda, p_tcb->transport) != GATT_INVALID_ACL_HANDLE)) 315 { 316 if (is_add) 317 { 318 GATT_TRACE_DEBUG("GATT disables link idle timer"); 319 /* acl link is connected disable the idle timeout */ 320 GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT, p_tcb->transport); 321 } 322 else 323 { 324 if (!gatt_num_apps_hold_link(p_tcb)) 325 { 326 /* acl link is connected but no application needs to use the link 327 so set the timeout value to GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP seconds */ 328 GATT_TRACE_DEBUG("GATT starts link idle timer =%d sec", GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP); 329 GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP, p_tcb->transport); 330 } 331 332 } 333 } 334 } 335 336 /******************************************************************************* 337 ** 338 ** Function gatt_act_connect 339 ** 340 ** Description GATT connection initiation. 341 ** 342 ** Returns void. 343 ** 344 *******************************************************************************/ 345 BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr, tBT_TRANSPORT transport) 346 { 347 BOOLEAN ret = FALSE; 348 tGATT_TCB *p_tcb; 349 UINT8 st; 350 351 if ((p_tcb = gatt_find_tcb_by_addr(bd_addr, transport)) != NULL) 352 { 353 ret = TRUE; 354 st = gatt_get_ch_state(p_tcb); 355 356 /* before link down, another app try to open a GATT connection */ 357 if(st == GATT_CH_OPEN && gatt_num_apps_hold_link(p_tcb) == 0 && 358 transport == BT_TRANSPORT_LE ) 359 { 360 if (!gatt_connect(bd_addr, p_tcb, transport)) 361 ret = FALSE; 362 } 363 else if(st == GATT_CH_CLOSING) 364 { 365 /* need to complete the closing first */ 366 ret = FALSE; 367 } 368 } 369 else 370 { 371 if ((p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr, transport)) != NULL) 372 { 373 if (!gatt_connect(bd_addr, p_tcb, transport)) 374 { 375 GATT_TRACE_ERROR("gatt_connect failed"); 376 memset(p_tcb, 0, sizeof(tGATT_TCB)); 377 } 378 else 379 ret = TRUE; 380 } 381 else 382 { 383 ret = 0; 384 GATT_TRACE_ERROR("Max TCB for gatt_if [%d] reached.", p_reg->gatt_if); 385 } 386 } 387 388 if (ret) 389 { 390 gatt_update_app_use_link_flag(p_reg->gatt_if, p_tcb, TRUE, FALSE); 391 } 392 393 return ret; 394 } 395 396 /******************************************************************************* 397 ** 398 ** Function gatt_le_connect_cback 399 ** 400 ** Description This callback function is called by L2CAP to indicate that 401 ** the ATT fixed channel for LE is 402 ** connected (conn = TRUE)/disconnected (conn = FALSE). 403 ** 404 *******************************************************************************/ 405 static void gatt_le_connect_cback (UINT16 chan, BD_ADDR bd_addr, BOOLEAN connected, 406 UINT16 reason, tBT_TRANSPORT transport) 407 { 408 409 tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr, transport); 410 BOOLEAN check_srv_chg = FALSE; 411 tGATTS_SRV_CHG *p_srv_chg_clt=NULL; 412 413 /* ignore all fixed channel connect/disconnect on BR/EDR link for GATT */ 414 if (transport == BT_TRANSPORT_BR_EDR) 415 return; 416 417 GATT_TRACE_DEBUG ("GATT ATT protocol channel with BDA: %08x%04x is %s", 418 (bd_addr[0]<<24)+(bd_addr[1]<<16)+(bd_addr[2]<<8)+bd_addr[3], 419 (bd_addr[4]<<8)+bd_addr[5], (connected) ? "connected" : "disconnected"); 420 421 if ((p_srv_chg_clt = gatt_is_bda_in_the_srv_chg_clt_list(bd_addr)) != NULL) 422 { 423 check_srv_chg = TRUE; 424 } 425 else 426 { 427 if (btm_sec_is_a_bonded_dev(bd_addr)) 428 gatt_add_a_bonded_dev_for_srv_chg(bd_addr); 429 } 430 431 if (connected) 432 { 433 /* do we have a channel initiating a connection? */ 434 if (p_tcb) 435 { 436 /* we are initiating connection */ 437 if ( gatt_get_ch_state(p_tcb) == GATT_CH_CONN) 438 { 439 /* send callback */ 440 gatt_set_ch_state(p_tcb, GATT_CH_OPEN); 441 p_tcb->payload_size = GATT_DEF_BLE_MTU_SIZE; 442 443 gatt_send_conn_cback(p_tcb); 444 } 445 if (check_srv_chg) 446 gatt_chk_srv_chg (p_srv_chg_clt); 447 } 448 /* this is incoming connection or background connection callback */ 449 450 else 451 { 452 if ((p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr, BT_TRANSPORT_LE)) != NULL) 453 { 454 p_tcb->att_lcid = L2CAP_ATT_CID; 455 456 gatt_set_ch_state(p_tcb, GATT_CH_OPEN); 457 458 p_tcb->payload_size = GATT_DEF_BLE_MTU_SIZE; 459 460 gatt_send_conn_cback (p_tcb); 461 if (check_srv_chg) 462 { 463 gatt_chk_srv_chg (p_srv_chg_clt); 464 } 465 } 466 else 467 { 468 GATT_TRACE_ERROR("CCB max out, no rsources"); 469 } 470 } 471 } 472 else 473 { 474 gatt_cleanup_upon_disc(bd_addr, reason, transport); 475 GATT_TRACE_DEBUG ("ATT disconnected"); 476 } 477 } 478 479 /******************************************************************************* 480 ** 481 ** Function gatt_channel_congestion 482 ** 483 ** Description This function is called to process the congestion callback 484 ** from lcb 485 ** 486 ** Returns void 487 ** 488 *******************************************************************************/ 489 static void gatt_channel_congestion(tGATT_TCB *p_tcb, BOOLEAN congested) 490 { 491 UINT8 i = 0; 492 tGATT_REG *p_reg=NULL; 493 UINT16 conn_id; 494 495 /* if uncongested, check to see if there is any more pending data */ 496 if (p_tcb != NULL && congested == FALSE) 497 { 498 gatt_cl_send_next_cmd_inq(p_tcb); 499 } 500 /* notifying all applications for the connection up event */ 501 for (i = 0, p_reg = gatt_cb.cl_rcb ; i < GATT_MAX_APPS; i++, p_reg++) 502 { 503 if (p_reg->in_use) 504 { 505 if (p_reg->app_cb.p_congestion_cb) 506 { 507 conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if); 508 (*p_reg->app_cb.p_congestion_cb)(conn_id, congested); 509 } 510 } 511 } 512 } 513 514 /******************************************************************************* 515 ** 516 ** Function gatt_le_cong_cback 517 ** 518 ** Description This function is called when GATT fixed channel is congested 519 ** or uncongested. 520 ** 521 ** Returns void 522 ** 523 *******************************************************************************/ 524 static void gatt_le_cong_cback(BD_ADDR remote_bda, BOOLEAN congested) 525 { 526 tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(remote_bda, BT_TRANSPORT_LE); 527 528 /* if uncongested, check to see if there is any more pending data */ 529 if (p_tcb != NULL) 530 { 531 gatt_channel_congestion(p_tcb, congested); 532 } 533 } 534 535 /******************************************************************************* 536 ** 537 ** Function gatt_le_data_ind 538 ** 539 ** Description This function is called when data is received from L2CAP. 540 ** if we are the originator of the connection, we are the ATT 541 ** client, and the received message is queued up for the client. 542 ** 543 ** If we are the destination of the connection, we are the ATT 544 ** server, so the message is passed to the server processing 545 ** function. 546 ** 547 ** Returns void 548 ** 549 *******************************************************************************/ 550 static void gatt_le_data_ind (UINT16 chan, BD_ADDR bd_addr, BT_HDR *p_buf) 551 { 552 tGATT_TCB *p_tcb; 553 554 /* Find CCB based on bd addr */ 555 if ((p_tcb = gatt_find_tcb_by_addr (bd_addr, BT_TRANSPORT_LE)) != NULL && 556 gatt_get_ch_state(p_tcb) >= GATT_CH_OPEN) 557 { 558 gatt_data_process(p_tcb, p_buf); 559 } 560 else 561 { 562 GKI_freebuf (p_buf); 563 564 if (p_tcb != NULL) 565 { 566 GATT_TRACE_WARNING ("ATT - Ignored L2CAP data while in state: %d", 567 gatt_get_ch_state(p_tcb)); 568 } 569 } 570 } 571 572 /******************************************************************************* 573 ** 574 ** Function gatt_l2cif_connect_ind 575 ** 576 ** Description This function handles an inbound connection indication 577 ** from L2CAP. This is the case where we are acting as a 578 ** server. 579 ** 580 ** Returns void 581 ** 582 *******************************************************************************/ 583 static void gatt_l2cif_connect_ind_cback (BD_ADDR bd_addr, UINT16 lcid, UINT16 psm, UINT8 id) 584 { 585 /* do we already have a control channel for this peer? */ 586 UINT8 result = L2CAP_CONN_OK; 587 tL2CAP_CFG_INFO cfg; 588 tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_BR_EDR); 589 UNUSED(psm); 590 591 GATT_TRACE_ERROR("Connection indication cid = %d", lcid); 592 /* new connection ? */ 593 if (p_tcb == NULL) 594 { 595 /* allocate tcb */ 596 if ((p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr, BT_TRANSPORT_BR_EDR)) == NULL) 597 { 598 /* no tcb available, reject L2CAP connection */ 599 result = L2CAP_CONN_NO_RESOURCES; 600 } 601 else 602 p_tcb->att_lcid = lcid; 603 604 } 605 else /* existing connection , reject it */ 606 { 607 result = L2CAP_CONN_NO_RESOURCES; 608 } 609 610 /* Send L2CAP connect rsp */ 611 L2CA_ConnectRsp(bd_addr, id, lcid, result, 0); 612 613 /* if result ok, proceed with connection */ 614 if (result == L2CAP_CONN_OK) 615 { 616 /* transition to configuration state */ 617 gatt_set_ch_state(p_tcb, GATT_CH_CFG); 618 619 /* Send L2CAP config req */ 620 memset(&cfg, 0, sizeof(tL2CAP_CFG_INFO)); 621 cfg.mtu_present = TRUE; 622 cfg.mtu = GATT_MAX_MTU_SIZE; 623 624 L2CA_ConfigReq(lcid, &cfg); 625 } 626 } 627 628 /******************************************************************************* 629 ** 630 ** Function gatt_l2c_connect_cfm_cback 631 ** 632 ** Description This is the L2CAP connect confirm callback function. 633 ** 634 ** 635 ** Returns void 636 ** 637 *******************************************************************************/ 638 static void gatt_l2cif_connect_cfm_cback(UINT16 lcid, UINT16 result) 639 { 640 tGATT_TCB *p_tcb; 641 tL2CAP_CFG_INFO cfg; 642 643 /* look up clcb for this channel */ 644 if ((p_tcb = gatt_find_tcb_by_cid(lcid)) != NULL) 645 { 646 GATT_TRACE_DEBUG("gatt_l2c_connect_cfm_cback result: %d ch_state: %d, lcid:0x%x", result, gatt_get_ch_state(p_tcb), p_tcb->att_lcid); 647 648 /* if in correct state */ 649 if (gatt_get_ch_state(p_tcb) == GATT_CH_CONN) 650 { 651 /* if result successful */ 652 if (result == L2CAP_CONN_OK) 653 { 654 /* set channel state */ 655 gatt_set_ch_state(p_tcb, GATT_CH_CFG); 656 657 /* Send L2CAP config req */ 658 memset(&cfg, 0, sizeof(tL2CAP_CFG_INFO)); 659 cfg.mtu_present = TRUE; 660 cfg.mtu = GATT_MAX_MTU_SIZE; 661 L2CA_ConfigReq(lcid, &cfg); 662 } 663 /* else initiating connection failure */ 664 else 665 { 666 gatt_cleanup_upon_disc(p_tcb->peer_bda, result, GATT_TRANSPORT_BR_EDR); 667 } 668 } 669 else /* wrong state, disconnect it */ 670 { 671 if (result == L2CAP_CONN_OK) 672 { 673 /* just in case the peer also accepts our connection - Send L2CAP disconnect req */ 674 L2CA_DisconnectReq(lcid); 675 } 676 } 677 } 678 } 679 680 /******************************************************************************* 681 ** 682 ** Function gatt_l2cif_config_cfm_cback 683 ** 684 ** Description This is the L2CAP config confirm callback function. 685 ** 686 ** 687 ** Returns void 688 ** 689 *******************************************************************************/ 690 void gatt_l2cif_config_cfm_cback(UINT16 lcid, tL2CAP_CFG_INFO *p_cfg) 691 { 692 tGATT_TCB *p_tcb; 693 tGATTS_SRV_CHG *p_srv_chg_clt=NULL; 694 695 /* look up clcb for this channel */ 696 if ((p_tcb = gatt_find_tcb_by_cid(lcid)) != NULL) 697 { 698 /* if in correct state */ 699 if ( gatt_get_ch_state(p_tcb) == GATT_CH_CFG) 700 { 701 /* if result successful */ 702 if (p_cfg->result == L2CAP_CFG_OK) 703 { 704 /* update flags */ 705 p_tcb->ch_flags |= GATT_L2C_CFG_CFM_DONE; 706 707 /* if configuration complete */ 708 if (p_tcb->ch_flags & GATT_L2C_CFG_IND_DONE) 709 { 710 gatt_set_ch_state(p_tcb, GATT_CH_OPEN); 711 712 if ((p_srv_chg_clt = gatt_is_bda_in_the_srv_chg_clt_list(p_tcb->peer_bda)) != NULL) 713 { 714 gatt_chk_srv_chg(p_srv_chg_clt); 715 } 716 else 717 { 718 if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda)) 719 gatt_add_a_bonded_dev_for_srv_chg(p_tcb->peer_bda); 720 } 721 722 /* send callback */ 723 gatt_send_conn_cback(p_tcb); 724 } 725 } 726 /* else failure */ 727 else 728 { 729 /* Send L2CAP disconnect req */ 730 L2CA_DisconnectReq(lcid); 731 } 732 } 733 } 734 } 735 736 /******************************************************************************* 737 ** 738 ** Function gatt_l2cif_config_ind_cback 739 ** 740 ** Description This is the L2CAP config indication callback function. 741 ** 742 ** 743 ** Returns void 744 ** 745 *******************************************************************************/ 746 void gatt_l2cif_config_ind_cback(UINT16 lcid, tL2CAP_CFG_INFO *p_cfg) 747 { 748 tGATT_TCB *p_tcb; 749 tGATTS_SRV_CHG *p_srv_chg_clt=NULL; 750 /* look up clcb for this channel */ 751 if ((p_tcb = gatt_find_tcb_by_cid(lcid)) != NULL) 752 { 753 /* GATT uses the smaller of our MTU and peer's MTU */ 754 if ( p_cfg->mtu_present && 755 (p_cfg->mtu >= GATT_MIN_BR_MTU_SIZE && p_cfg->mtu < L2CAP_DEFAULT_MTU)) 756 p_tcb->payload_size = p_cfg->mtu; 757 else 758 p_tcb->payload_size = L2CAP_DEFAULT_MTU; 759 760 /* send L2CAP configure response */ 761 memset(p_cfg, 0, sizeof(tL2CAP_CFG_INFO)); 762 p_cfg->result = L2CAP_CFG_OK; 763 L2CA_ConfigRsp(lcid, p_cfg); 764 765 /* if first config ind */ 766 if ((p_tcb->ch_flags & GATT_L2C_CFG_IND_DONE) == 0) 767 { 768 /* update flags */ 769 p_tcb->ch_flags |= GATT_L2C_CFG_IND_DONE; 770 771 /* if configuration complete */ 772 if (p_tcb->ch_flags & GATT_L2C_CFG_CFM_DONE) 773 { 774 gatt_set_ch_state(p_tcb, GATT_CH_OPEN); 775 if ((p_srv_chg_clt = gatt_is_bda_in_the_srv_chg_clt_list(p_tcb->peer_bda)) != NULL) 776 { 777 gatt_chk_srv_chg(p_srv_chg_clt); 778 } 779 else 780 { 781 if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda)) 782 gatt_add_a_bonded_dev_for_srv_chg(p_tcb->peer_bda); 783 } 784 785 /* send callback */ 786 gatt_send_conn_cback(p_tcb); 787 } 788 } 789 } 790 } 791 792 /******************************************************************************* 793 ** 794 ** Function gatt_l2cif_disconnect_ind_cback 795 ** 796 ** Description This is the L2CAP disconnect indication callback function. 797 ** 798 ** 799 ** Returns void 800 ** 801 *******************************************************************************/ 802 void gatt_l2cif_disconnect_ind_cback(UINT16 lcid, BOOLEAN ack_needed) 803 { 804 tGATT_TCB *p_tcb; 805 UINT16 reason; 806 807 /* look up clcb for this channel */ 808 if ((p_tcb = gatt_find_tcb_by_cid(lcid)) != NULL) 809 { 810 if (ack_needed) 811 { 812 /* send L2CAP disconnect response */ 813 L2CA_DisconnectRsp(lcid); 814 } 815 if (gatt_is_bda_in_the_srv_chg_clt_list(p_tcb->peer_bda) == NULL) 816 { 817 if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda)) 818 gatt_add_a_bonded_dev_for_srv_chg(p_tcb->peer_bda); 819 } 820 /* if ACL link is still up, no reason is logged, l2cap is disconnect from peer */ 821 if ((reason = L2CA_GetDisconnectReason(p_tcb->peer_bda, p_tcb->transport)) == 0) 822 reason = GATT_CONN_TERMINATE_PEER_USER; 823 824 /* send disconnect callback */ 825 gatt_cleanup_upon_disc(p_tcb->peer_bda, reason, GATT_TRANSPORT_BR_EDR); 826 } 827 } 828 829 /******************************************************************************* 830 ** 831 ** Function gatt_l2cif_disconnect_cfm_cback 832 ** 833 ** Description This is the L2CAP disconnect confirm callback function. 834 ** 835 ** 836 ** Returns void 837 ** 838 *******************************************************************************/ 839 static void gatt_l2cif_disconnect_cfm_cback(UINT16 lcid, UINT16 result) 840 { 841 tGATT_TCB *p_tcb; 842 UINT16 reason; 843 UNUSED(result); 844 845 /* look up clcb for this channel */ 846 if ((p_tcb = gatt_find_tcb_by_cid(lcid)) != NULL) 847 { 848 /* If the device is not in the service changed client list, add it... */ 849 if (gatt_is_bda_in_the_srv_chg_clt_list(p_tcb->peer_bda) == NULL) 850 { 851 if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda)) 852 gatt_add_a_bonded_dev_for_srv_chg(p_tcb->peer_bda); 853 } 854 855 /* send disconnect callback */ 856 /* if ACL link is still up, no reason is logged, l2cap is disconnect from peer */ 857 if ((reason = L2CA_GetDisconnectReason(p_tcb->peer_bda, p_tcb->transport)) == 0) 858 reason = GATT_CONN_TERMINATE_LOCAL_HOST; 859 860 gatt_cleanup_upon_disc(p_tcb->peer_bda, reason, GATT_TRANSPORT_BR_EDR); 861 } 862 } 863 864 /******************************************************************************* 865 ** 866 ** Function gatt_l2cif_data_ind_cback 867 ** 868 ** Description This is the L2CAP data indication callback function. 869 ** 870 ** 871 ** Returns void 872 ** 873 *******************************************************************************/ 874 static void gatt_l2cif_data_ind_cback(UINT16 lcid, BT_HDR *p_buf) 875 { 876 tGATT_TCB *p_tcb; 877 878 /* look up clcb for this channel */ 879 if ((p_tcb = gatt_find_tcb_by_cid(lcid)) != NULL && 880 gatt_get_ch_state(p_tcb) == GATT_CH_OPEN) 881 { 882 /* process the data */ 883 gatt_data_process(p_tcb, p_buf); 884 } 885 else /* prevent buffer leak */ 886 GKI_freebuf(p_buf); 887 } 888 889 /******************************************************************************* 890 ** 891 ** Function gatt_l2cif_congest_cback 892 ** 893 ** Description L2CAP congestion callback 894 ** 895 ** Returns void 896 ** 897 *******************************************************************************/ 898 static void gatt_l2cif_congest_cback (UINT16 lcid, BOOLEAN congested) 899 { 900 tGATT_TCB *p_tcb = gatt_find_tcb_by_cid(lcid); 901 902 if (p_tcb != NULL) 903 { 904 gatt_channel_congestion(p_tcb, congested); 905 } 906 } 907 908 /******************************************************************************* 909 ** 910 ** Function gatt_send_conn_cback 911 ** 912 ** Description Callback used to notify layer above about a connection. 913 ** 914 ** 915 ** Returns void 916 ** 917 *******************************************************************************/ 918 static void gatt_send_conn_cback(tGATT_TCB *p_tcb) 919 { 920 UINT8 i; 921 tGATT_REG *p_reg; 922 tGATT_BG_CONN_DEV *p_bg_dev=NULL; 923 UINT16 conn_id; 924 925 p_bg_dev = gatt_find_bg_dev(p_tcb->peer_bda); 926 927 /* notifying all applications for the connection up event */ 928 for (i = 0, p_reg = gatt_cb.cl_rcb ; i < GATT_MAX_APPS; i++, p_reg++) 929 { 930 if (p_reg->in_use) 931 { 932 if (p_bg_dev && gatt_is_bg_dev_for_app(p_bg_dev, p_reg->gatt_if)) 933 gatt_update_app_use_link_flag(p_reg->gatt_if, p_tcb, TRUE, TRUE); 934 935 if (p_reg->app_cb.p_conn_cb) 936 { 937 conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if); 938 (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, p_tcb->peer_bda, conn_id, 939 TRUE, 0, p_tcb->transport); 940 } 941 } 942 } 943 944 945 if (gatt_num_apps_hold_link(p_tcb) && p_tcb->att_lcid == L2CAP_ATT_CID ) 946 { 947 /* disable idle timeout if one or more clients are holding the link disable the idle timer */ 948 GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT, p_tcb->transport); 949 } 950 } 951 952 /******************************************************************************* 953 ** 954 ** Function gatt_le_data_ind 955 ** 956 ** Description This function is called when data is received from L2CAP. 957 ** if we are the originator of the connection, we are the ATT 958 ** client, and the received message is queued up for the client. 959 ** 960 ** If we are the destination of the connection, we are the ATT 961 ** server, so the message is passed to the server processing 962 ** function. 963 ** 964 ** Returns void 965 ** 966 *******************************************************************************/ 967 void gatt_data_process (tGATT_TCB *p_tcb, BT_HDR *p_buf) 968 { 969 UINT8 *p = (UINT8 *)(p_buf + 1) + p_buf->offset; 970 UINT8 op_code, pseudo_op_code; 971 UINT16 msg_len; 972 973 974 if (p_buf->len > 0) 975 { 976 msg_len = p_buf->len - 1; 977 STREAM_TO_UINT8(op_code, p); 978 979 /* remove the two MSBs associated with sign write and write cmd */ 980 pseudo_op_code = op_code & (~GATT_WRITE_CMD_MASK); 981 982 if (pseudo_op_code < GATT_OP_CODE_MAX) 983 { 984 if (op_code == GATT_SIGN_CMD_WRITE) 985 { 986 gatt_verify_signature(p_tcb, p_buf); 987 } 988 else 989 { 990 /* message from client */ 991 if ((op_code % 2) == 0) 992 gatt_server_handle_client_req (p_tcb, op_code, msg_len, p); 993 else 994 gatt_client_handle_server_rsp (p_tcb, op_code, msg_len, p); 995 } 996 } 997 else 998 { 999 GATT_TRACE_ERROR ("ATT - Rcvd L2CAP data, unknown cmd: 0x%x", op_code); 1000 } 1001 } 1002 else 1003 { 1004 GATT_TRACE_ERROR ("invalid data length, ignore"); 1005 } 1006 1007 GKI_freebuf (p_buf); 1008 } 1009 1010 /******************************************************************************* 1011 ** 1012 ** Function gatt_add_a_bonded_dev_for_srv_chg 1013 ** 1014 ** Description Add a bonded dev to the service changed client list 1015 ** 1016 ** Returns void 1017 ** 1018 *******************************************************************************/ 1019 void gatt_add_a_bonded_dev_for_srv_chg (BD_ADDR bda) 1020 { 1021 tGATTS_SRV_CHG_REQ req; 1022 tGATTS_SRV_CHG srv_chg_clt; 1023 1024 memcpy(srv_chg_clt.bda, bda, BD_ADDR_LEN); 1025 srv_chg_clt.srv_changed = FALSE; 1026 if (gatt_add_srv_chg_clt(&srv_chg_clt) != NULL) 1027 { 1028 memcpy(req.srv_chg.bda, bda, BD_ADDR_LEN); 1029 req.srv_chg.srv_changed = FALSE; 1030 if (gatt_cb.cb_info.p_srv_chg_callback) 1031 (*gatt_cb.cb_info.p_srv_chg_callback)(GATTS_SRV_CHG_CMD_ADD_CLIENT, &req, NULL); 1032 } 1033 } 1034 1035 /******************************************************************************* 1036 ** 1037 ** Function gatt_send_srv_chg_ind 1038 ** 1039 ** Description This function is called to send a service chnaged indication to 1040 ** the specified bd address 1041 ** 1042 ** Returns void 1043 ** 1044 *******************************************************************************/ 1045 void gatt_send_srv_chg_ind (BD_ADDR peer_bda) 1046 { 1047 UINT8 handle_range[GATT_SIZE_OF_SRV_CHG_HNDL_RANGE]; 1048 UINT8 *p = handle_range; 1049 UINT16 conn_id; 1050 1051 GATT_TRACE_DEBUG("gatt_send_srv_chg_ind"); 1052 1053 if (gatt_cb.handle_of_h_r) 1054 { 1055 if ((conn_id = gatt_profile_find_conn_id_by_bd_addr(peer_bda)) != GATT_INVALID_CONN_ID) 1056 { 1057 UINT16_TO_STREAM (p, 1); 1058 UINT16_TO_STREAM (p, 0xFFFF); 1059 GATTS_HandleValueIndication (conn_id, 1060 gatt_cb.handle_of_h_r, 1061 GATT_SIZE_OF_SRV_CHG_HNDL_RANGE, 1062 handle_range); 1063 } 1064 else 1065 { 1066 GATT_TRACE_ERROR("Unable to find conn_id for %08x%04x ", 1067 (peer_bda[0]<<24)+(peer_bda[1]<<16)+(peer_bda[2]<<8)+peer_bda[3], 1068 (peer_bda[4]<<8)+peer_bda[5] ); 1069 } 1070 } 1071 } 1072 1073 /******************************************************************************* 1074 ** 1075 ** Function gatt_chk_srv_chg 1076 ** 1077 ** Description Check sending service chnaged Indication is required or not 1078 ** if required then send the Indication 1079 ** 1080 ** Returns void 1081 ** 1082 *******************************************************************************/ 1083 void gatt_chk_srv_chg(tGATTS_SRV_CHG *p_srv_chg_clt) 1084 { 1085 GATT_TRACE_DEBUG("gatt_chk_srv_chg srv_changed=%d", p_srv_chg_clt->srv_changed ); 1086 1087 if (p_srv_chg_clt->srv_changed) 1088 { 1089 gatt_send_srv_chg_ind(p_srv_chg_clt->bda); 1090 } 1091 } 1092 1093 /******************************************************************************* 1094 ** 1095 ** Function gatt_init_srv_chg 1096 ** 1097 ** Description This function is used to initialize the service changed 1098 ** attribute value 1099 ** 1100 ** Returns void 1101 ** 1102 *******************************************************************************/ 1103 void gatt_init_srv_chg (void) 1104 { 1105 tGATTS_SRV_CHG_REQ req; 1106 tGATTS_SRV_CHG_RSP rsp; 1107 BOOLEAN status; 1108 UINT8 num_clients,i; 1109 tGATTS_SRV_CHG srv_chg_clt; 1110 1111 GATT_TRACE_DEBUG("gatt_init_srv_chg"); 1112 if (gatt_cb.cb_info.p_srv_chg_callback) 1113 { 1114 status = (*gatt_cb.cb_info.p_srv_chg_callback)(GATTS_SRV_CHG_CMD_READ_NUM_CLENTS, NULL, &rsp); 1115 1116 if (status && rsp.num_clients) 1117 { 1118 GATT_TRACE_DEBUG("gatt_init_srv_chg num_srv_chg_clt_clients=%d", rsp.num_clients); 1119 num_clients = rsp.num_clients; 1120 i = 1; /* use one based index */ 1121 while ((i <= num_clients) && status) 1122 { 1123 req.client_read_index = i; 1124 if ((status = (*gatt_cb.cb_info.p_srv_chg_callback)(GATTS_SRV_CHG_CMD_READ_CLENT, &req, &rsp)) == TRUE) 1125 { 1126 memcpy(&srv_chg_clt, &rsp.srv_chg ,sizeof(tGATTS_SRV_CHG)); 1127 if (gatt_add_srv_chg_clt(&srv_chg_clt) == NULL) 1128 { 1129 GATT_TRACE_ERROR("Unable to add a service change client"); 1130 status = FALSE; 1131 } 1132 } 1133 i++; 1134 } 1135 } 1136 } 1137 else 1138 { 1139 GATT_TRACE_DEBUG("gatt_init_srv_chg callback not registered yet"); 1140 } 1141 } 1142 1143 /******************************************************************************* 1144 ** 1145 ** Function gatt_proc_srv_chg 1146 ** 1147 ** Description This function is process the service changed request 1148 ** 1149 ** Returns void 1150 ** 1151 *******************************************************************************/ 1152 void gatt_proc_srv_chg (void) 1153 { 1154 UINT8 start_idx, found_idx; 1155 BD_ADDR bda; 1156 BOOLEAN srv_chg_ind_pending=FALSE; 1157 tGATT_TCB *p_tcb; 1158 tBT_TRANSPORT transport; 1159 1160 GATT_TRACE_DEBUG ("gatt_proc_srv_chg"); 1161 1162 if (gatt_cb.cb_info.p_srv_chg_callback && gatt_cb.handle_of_h_r) 1163 { 1164 gatt_set_srv_chg(); 1165 start_idx =0; 1166 while (gatt_find_the_connected_bda(start_idx, bda, &found_idx, &transport)) 1167 { 1168 p_tcb = &gatt_cb.tcb[found_idx];; 1169 srv_chg_ind_pending = gatt_is_srv_chg_ind_pending(p_tcb); 1170 1171 if (!srv_chg_ind_pending) 1172 { 1173 gatt_send_srv_chg_ind(bda); 1174 } 1175 else 1176 { 1177 GATT_TRACE_DEBUG ("discard srv chg - already has one in the queue"); 1178 } 1179 start_idx = ++found_idx; 1180 } 1181 } 1182 } 1183 1184 /******************************************************************************* 1185 ** 1186 ** Function gatt_set_ch_state 1187 ** 1188 ** Description This function set the ch_state in tcb 1189 ** 1190 ** Returns none 1191 ** 1192 *******************************************************************************/ 1193 void gatt_set_ch_state(tGATT_TCB *p_tcb, tGATT_CH_STATE ch_state) 1194 { 1195 if (p_tcb) 1196 { 1197 GATT_TRACE_DEBUG ("gatt_set_ch_state: old=%d new=%d", p_tcb->ch_state, ch_state); 1198 p_tcb->ch_state = ch_state; 1199 } 1200 } 1201 1202 /******************************************************************************* 1203 ** 1204 ** Function gatt_get_ch_state 1205 ** 1206 ** Description This function get the ch_state in tcb 1207 ** 1208 ** Returns none 1209 ** 1210 *******************************************************************************/ 1211 tGATT_CH_STATE gatt_get_ch_state(tGATT_TCB *p_tcb) 1212 { 1213 tGATT_CH_STATE ch_state = GATT_CH_CLOSE; 1214 if (p_tcb) 1215 { 1216 GATT_TRACE_DEBUG ("gatt_get_ch_state: ch_state=%d", p_tcb->ch_state); 1217 ch_state = p_tcb->ch_state; 1218 } 1219 return ch_state; 1220 } 1221 1222 #endif /* BLE_INCLUDED */ 1223