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