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