1 /* 2 * Copyright 2020 HIMSA II K/S - www.himsa.com. Represented by EHIMA - 3 * www.ehima.com 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 #pragma once 19 20 #include <bluetooth/log.h> 21 #include <com_android_bluetooth_flags.h> 22 23 #include <map> 24 #include <memory> 25 #include <utility> 26 #include <vector> 27 28 #include "hci/controller_interface.h" 29 #include "include/bind_helpers.h" 30 #include "internal_include/stack_config.h" 31 #include "main/shim/entry.h" 32 #include "osi/include/alarm.h" 33 #include "osi/include/allocator.h" 34 #include "stack/btm/btm_sec.h" 35 #include "stack/eatt/eatt.h" 36 #include "stack/gatt/gatt_int.h" 37 #include "stack/include/bt_hdr.h" 38 #include "stack/include/bt_psm_types.h" 39 #include "stack/include/btm_sec_api.h" 40 #include "stack/include/l2cap_interface.h" 41 #include "stack/include/l2cdefs.h" 42 #include "stack/include/main_thread.h" 43 44 namespace bluetooth { 45 namespace eatt { 46 47 #define BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK 0x01 48 49 class eatt_device { 50 public: 51 RawAddress bda_; 52 uint16_t rx_mtu_; 53 uint16_t rx_mps_; 54 55 tGATT_TCB* eatt_tcb_; 56 57 std::map<uint16_t, std::shared_ptr<EattChannel>> eatt_channels; 58 bool collision; eatt_device(const RawAddress & bd_addr,uint16_t mtu,uint16_t mps)59 eatt_device(const RawAddress& bd_addr, uint16_t mtu, uint16_t mps) 60 : rx_mtu_(mtu), rx_mps_(mps), eatt_tcb_(nullptr), collision(false) { 61 bda_ = bd_addr; 62 } 63 }; 64 65 struct eatt_impl { 66 std::vector<eatt_device> devices_; 67 uint16_t psm_; 68 uint16_t default_mtu_; 69 uint16_t max_mps_; 70 tL2CAP_APPL_INFO reg_info_; 71 72 base::WeakPtrFactory<eatt_impl> weak_factory_{this}; 73 eatt_impleatt_impl74 eatt_impl() { 75 default_mtu_ = EATT_DEFAULT_MTU; 76 max_mps_ = EATT_MIN_MTU_MPS; 77 psm_ = BT_PSM_EATT; 78 } 79 80 ~eatt_impl() = default; 81 find_device_by_cideatt_impl82 eatt_device* find_device_by_cid(uint16_t lcid) { 83 /* This works only because Android CIDs are unique across the ACL 84 * connections */ 85 auto iter = find_if(devices_.begin(), devices_.end(), [&lcid](const eatt_device& ed) { 86 auto it = ed.eatt_channels.find(lcid); 87 return it != ed.eatt_channels.end(); 88 }); 89 90 return (iter == devices_.end()) ? nullptr : &(*iter); 91 } 92 find_channel_by_cideatt_impl93 EattChannel* find_channel_by_cid(uint16_t lcid) { 94 eatt_device* eatt_dev = find_device_by_cid(lcid); 95 if (!eatt_dev) { 96 return nullptr; 97 } 98 99 auto it = eatt_dev->eatt_channels.find(lcid); 100 return (it == eatt_dev->eatt_channels.end()) ? nullptr : it->second.get(); 101 } 102 is_channel_connection_pendingeatt_impl103 bool is_channel_connection_pending(eatt_device* eatt_dev) { 104 for (const std::pair<uint16_t, std::shared_ptr<EattChannel>>& el : eatt_dev->eatt_channels) { 105 if (el.second->state_ == EattChannelState::EATT_CHANNEL_PENDING) { 106 return true; 107 } 108 } 109 return false; 110 } 111 find_channel_by_cideatt_impl112 EattChannel* find_channel_by_cid(const RawAddress& bdaddr, uint16_t lcid) { 113 eatt_device* eatt_dev = find_device_by_address(bdaddr); 114 if (!eatt_dev) { 115 return nullptr; 116 } 117 118 auto it = eatt_dev->eatt_channels.find(lcid); 119 return (it == eatt_dev->eatt_channels.end()) ? nullptr : it->second.get(); 120 } 121 remove_channel_by_cideatt_impl122 void remove_channel_by_cid(eatt_device* eatt_dev, uint16_t lcid) { 123 auto channel = eatt_dev->eatt_channels[lcid]; 124 if (!channel->cl_cmd_q_.empty()) { 125 log::warn("Channel {:c}, for device {} is not empty on disconnection.", lcid, channel->bda_); 126 channel->cl_cmd_q_.clear(); 127 } 128 129 eatt_dev->eatt_channels.erase(lcid); 130 131 if (eatt_dev->eatt_channels.size() == 0) { 132 eatt_dev->eatt_tcb_ = NULL; 133 } 134 } 135 remove_channel_by_cideatt_impl136 void remove_channel_by_cid(uint16_t lcid) { 137 eatt_device* eatt_dev = find_device_by_cid(lcid); 138 if (!eatt_dev) { 139 return; 140 } 141 142 remove_channel_by_cid(eatt_dev, lcid); 143 } 144 eatt_l2cap_connect_ind_commoneatt_impl145 bool eatt_l2cap_connect_ind_common(const RawAddress& bda, std::vector<uint16_t>& lcids, 146 uint16_t /* psm */, uint16_t peer_mtu, uint8_t identifier) { 147 /* The assumption is that L2CAP layer already check parameters etc. 148 * Get our capabilities and accept all the channels. 149 */ 150 eatt_device* eatt_dev = this->find_device_by_address(bda); 151 if (!eatt_dev) { 152 /* If there is no device it means, Android did not read yet Server 153 * supported features, but according to Core 5.3, Vol 3, Part G, 6.2.1, 154 * for LE case it is not necessary to read it before establish connection. 155 * Therefore assume, device supports EATT since we got request to create 156 * EATT channels. Just create device here. */ 157 log::info("Adding device: {} on incoming EATT creation request", bda); 158 eatt_dev = add_eatt_device(bda); 159 } 160 161 uint16_t max_mps = shim::GetController()->GetLeBufferSize().le_data_packet_length_; 162 163 tL2CAP_LE_CFG_INFO local_coc_cfg = { 164 .result = tL2CAP_CFG_RESULT::L2CAP_CFG_OK, 165 .mtu = eatt_dev->rx_mtu_, 166 .mps = eatt_dev->rx_mps_ < max_mps ? eatt_dev->rx_mps_ : max_mps, 167 .credits = L2CA_LeCreditDefault(), 168 }; 169 170 if (!stack::l2cap::get_interface().L2CA_ConnectCreditBasedRsp( 171 bda, identifier, lcids, tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_CONN_OK, 172 &local_coc_cfg)) { 173 log::warn("Unable to respond L2CAP le_coc credit indication peer:{}", bda); 174 return false; 175 } 176 177 if (!eatt_dev->eatt_tcb_) { 178 eatt_dev->eatt_tcb_ = gatt_find_tcb_by_addr(eatt_dev->bda_, BT_TRANSPORT_LE); 179 log::assert_that(eatt_dev->eatt_tcb_ != nullptr, 180 "assert failed: eatt_dev->eatt_tcb_ != nullptr"); 181 } 182 183 for (uint16_t cid : lcids) { 184 EattChannel* channel = find_eatt_channel_by_cid(bda, cid); 185 log::assert_that(channel == nullptr, "assert failed: channel == nullptr"); 186 187 auto chan = std::make_shared<EattChannel>(eatt_dev->bda_, cid, peer_mtu, eatt_dev->rx_mtu_); 188 eatt_dev->eatt_channels.insert({cid, chan}); 189 190 chan->EattChannelSetState(EattChannelState::EATT_CHANNEL_OPENED); 191 eatt_dev->eatt_tcb_->eatt++; 192 193 log::info("Channel connected CID 0x{:x}", cid); 194 } 195 196 return true; 197 } 198 199 /* This is for the L2CAP ECoC Testing. */ 200 void upper_tester_send_data_if_needed(const RawAddress& bda, uint16_t cid = 0) { 201 eatt_device* eatt_dev = find_device_by_address(bda); 202 auto num_of_sdu = stack_config_get_interface()->get_pts_l2cap_ecoc_send_num_of_sdu(); 203 log::info("device {}, num: {}", eatt_dev->bda_, num_of_sdu); 204 205 if (num_of_sdu <= 0) { 206 return; 207 } 208 209 uint16_t mtu = 0; 210 if (cid != 0) { 211 auto chan = find_channel_by_cid(cid); 212 mtu = chan->tx_mtu_; 213 } else { 214 for (const std::pair<uint16_t, std::shared_ptr<EattChannel>>& el : eatt_dev->eatt_channels) { 215 if (el.second->state_ == EattChannelState::EATT_CHANNEL_OPENED) { 216 cid = el.first; 217 mtu = el.second->tx_mtu_; 218 break; 219 } 220 } 221 } 222 223 if (cid == 0 || mtu == 0) { 224 log::error("There is no OPEN cid or MTU is 0"); 225 return; 226 } 227 228 for (int i = 0; i < num_of_sdu; i++) { 229 BT_HDR* p_buf = (BT_HDR*)osi_malloc(mtu + sizeof(BT_HDR)); 230 p_buf->offset = L2CAP_MIN_OFFSET; 231 p_buf->len = mtu; 232 233 auto status = stack::l2cap::get_interface().L2CA_DataWrite(cid, p_buf); 234 log::info("Data num: {} sent with status {}", i, static_cast<int>(status)); 235 } 236 } 237 238 /* This is for the L2CAP ECoC Testing. */ upper_tester_delay_connect_cbeatt_impl239 void upper_tester_delay_connect_cb(const RawAddress& bda) { 240 log::info("device {}", bda); 241 eatt_device* eatt_dev = find_device_by_address(bda); 242 if (eatt_dev == nullptr) { 243 log::error("device is not available"); 244 return; 245 } 246 247 connect_eatt_wrap(eatt_dev); 248 } 249 upper_tester_delay_connecteatt_impl250 void upper_tester_delay_connect(const RawAddress& bda, int timeout_ms) { 251 bt_status_t status = 252 do_in_main_thread_delayed(base::BindOnce(&eatt_impl::upper_tester_delay_connect_cb, 253 weak_factory_.GetWeakPtr(), bda), 254 std::chrono::milliseconds(timeout_ms)); 255 256 log::info("Scheduled peripheral connect eatt for device with status: {}", (int)status); 257 } 258 upper_tester_l2cap_connect_indeatt_impl259 void upper_tester_l2cap_connect_ind(const RawAddress& bda, std::vector<uint16_t>& lcids, 260 uint16_t psm, uint16_t peer_mtu, uint8_t identifier) { 261 /* This is just for L2CAP PTS test cases*/ 262 auto min_key_size = stack_config_get_interface()->get_pts_l2cap_ecoc_min_key_size(); 263 if (min_key_size > 0 && (min_key_size >= 7 && min_key_size <= 16)) { 264 auto key_size = btm_ble_read_sec_key_size(bda); 265 if (key_size < min_key_size) { 266 std::vector<uint16_t> empty; 267 log::error("Insufficient key size ({}<{}) for device {}", key_size, min_key_size, bda); 268 if (!stack::l2cap::get_interface().L2CA_ConnectCreditBasedRsp( 269 bda, identifier, empty, 270 tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_INSUFFICIENT_ENCRYP_KEY_SIZE, nullptr)) { 271 log::warn("Unable to respond L2CAP le_coc credit indication peer:{}", bda); 272 } 273 return; 274 } 275 } 276 277 if (!eatt_l2cap_connect_ind_common(bda, lcids, psm, peer_mtu, identifier)) { 278 log::debug("Reject L2CAP Connection request."); 279 return; 280 } 281 282 /* Android let Central to create EATT (PTS initiates EATT). Some PTS test 283 * cases wants Android to do it anyway (Android initiates EATT). 284 */ 285 if (stack_config_get_interface()->get_pts_eatt_peripheral_collision_support()) { 286 upper_tester_delay_connect(bda, 500); 287 return; 288 } 289 290 upper_tester_send_data_if_needed(bda); 291 292 if (stack_config_get_interface()->get_pts_l2cap_ecoc_reconfigure()) { 293 bt_status_t status = do_in_main_thread_delayed( 294 base::BindOnce(&eatt_impl::reconfigure_all, weak_factory_.GetWeakPtr(), bda, 300), 295 std::chrono::seconds(4)); 296 log::info("Scheduled ECOC reconfiguration with status: {}", (int)status); 297 } 298 } 299 eatt_l2cap_connect_indeatt_impl300 void eatt_l2cap_connect_ind(const RawAddress& bda, std::vector<uint16_t>& lcids, uint16_t psm, 301 uint16_t peer_mtu, uint8_t identifier) { 302 log::info("Device {}, num of cids: {}, psm 0x{:04x}, peer_mtu {}", bda, 303 static_cast<int>(lcids.size()), psm, peer_mtu); 304 305 if (!stack_config_get_interface()->get_pts_connect_eatt_before_encryption() && 306 !BTM_IsEncrypted(bda, BT_TRANSPORT_LE)) { 307 /* If Link is not encrypted, we shall not accept EATT channel creation. */ 308 std::vector<uint16_t> empty; 309 tL2CAP_LE_RESULT_CODE result = 310 tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_INSUFFICIENT_AUTHENTICATION; 311 if (BTM_IsLinkKeyKnown(bda, BT_TRANSPORT_LE)) { 312 result = tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_INSUFFICIENT_ENCRYP; 313 } 314 log::error("ACL to device {} is unencrypted.", bda); 315 if (!stack::l2cap::get_interface().L2CA_ConnectCreditBasedRsp(bda, identifier, empty, result, 316 nullptr)) { 317 log::warn("Unable to respond L2CAP le_coc credit indication peer:{}", bda); 318 } 319 return; 320 } 321 322 if (stack_config_get_interface()->get_pts_l2cap_ecoc_upper_tester()) { 323 log::info("Upper tester for the L2CAP ECoC enabled"); 324 return upper_tester_l2cap_connect_ind(bda, lcids, psm, peer_mtu, identifier); 325 } 326 327 eatt_l2cap_connect_ind_common(bda, lcids, psm, peer_mtu, identifier); 328 } 329 eatt_retry_after_collision_if_neededeatt_impl330 void eatt_retry_after_collision_if_needed(eatt_device* eatt_dev) { 331 if (!eatt_dev->collision) { 332 log::debug("No collision."); 333 return; 334 } 335 /* We are here, because remote device wanted to create channels when 336 * Android proceed its own EATT creation. How to handle it is described 337 * here: BT Core 5.3, Volume 3, Part G, 5.4 338 */ 339 log::info("EATT collision detected. If we are Central we will retry right away"); 340 341 eatt_dev->collision = false; 342 uint8_t role = stack::l2cap::get_interface().L2CA_GetBleConnRole(eatt_dev->bda_); 343 if (role == HCI_ROLE_CENTRAL) { 344 log::info("Retrying EATT setup due to previous collision for device {}", eatt_dev->bda_); 345 connect_eatt_wrap(eatt_dev); 346 } else if (stack_config_get_interface()->get_pts_eatt_peripheral_collision_support()) { 347 /* This is only for the PTS. Android does not setup EATT when is a 348 * peripheral. 349 */ 350 upper_tester_delay_connect(eatt_dev->bda_, 500); 351 } 352 } 353 354 /* This is for the L2CAP ECoC Testing. */ upper_tester_l2cap_connect_cfmeatt_impl355 void upper_tester_l2cap_connect_cfm(eatt_device* eatt_dev) { 356 log::info("Upper tester for L2CAP Ecoc {}", eatt_dev->bda_); 357 if (is_channel_connection_pending(eatt_dev)) { 358 log::info("Waiting for all channels to be connected"); 359 return; 360 } 361 362 if (stack_config_get_interface()->get_pts_l2cap_ecoc_connect_remaining() && 363 (static_cast<int>(eatt_dev->eatt_channels.size()) < L2CAP_CREDIT_BASED_MAX_CIDS)) { 364 log::info("Connecting remaining channels {}", 365 L2CAP_CREDIT_BASED_MAX_CIDS - static_cast<int>(eatt_dev->eatt_channels.size())); 366 upper_tester_delay_connect(eatt_dev->bda_, 1000); 367 return; 368 } 369 upper_tester_send_data_if_needed(eatt_dev->bda_); 370 } 371 eatt_l2cap_connect_cfmeatt_impl372 void eatt_l2cap_connect_cfm(const RawAddress& bda, uint16_t lcid, uint16_t peer_mtu, 373 tL2CAP_LE_RESULT_CODE result) { 374 log::info("bda: {} cid: {}peer mtu: {} result {}", bda, lcid, peer_mtu, result); 375 376 eatt_device* eatt_dev = find_device_by_address(bda); 377 if (!eatt_dev) { 378 log::error("unknown device"); 379 return; 380 } 381 382 EattChannel* channel = this->find_channel_by_cid(bda, lcid); 383 if (!channel) { 384 log::error("unknown cid: 0x{:x}", lcid); 385 return; 386 } 387 388 if (result != tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_CONN_OK) { 389 log::error("Could not connect CoC result: 0x{:x}", result); 390 remove_channel_by_cid(eatt_dev, lcid); 391 392 /* If there is no channels connected, check if there was collision */ 393 if (!is_channel_connection_pending(eatt_dev)) { 394 eatt_retry_after_collision_if_needed(eatt_dev); 395 } 396 return; 397 } 398 399 channel->EattChannelSetState(EattChannelState::EATT_CHANNEL_OPENED); 400 channel->EattChannelSetTxMTU(peer_mtu); 401 402 log::assert_that(eatt_dev->eatt_tcb_ != nullptr, 403 "assert failed: eatt_dev->eatt_tcb_ != nullptr"); 404 log::assert_that(eatt_dev->bda_ == channel->bda_, 405 "assert failed: eatt_dev->bda_ == channel->bda_"); 406 eatt_dev->eatt_tcb_->eatt++; 407 408 log::info("Channel connected CID 0x{:04x}", lcid); 409 410 if (stack_config_get_interface()->get_pts_l2cap_ecoc_upper_tester()) { 411 upper_tester_l2cap_connect_cfm(eatt_dev); 412 } 413 } 414 eatt_l2cap_reconfig_completedeatt_impl415 void eatt_l2cap_reconfig_completed(const RawAddress& bda, uint16_t lcid, bool is_local_cfg, 416 tL2CAP_LE_CFG_INFO* p_cfg) { 417 log::info("lcid: 0x{:x} local cfg?: {}", lcid, is_local_cfg); 418 419 EattChannel* channel = find_channel_by_cid(bda, lcid); 420 if (!channel) { 421 return; 422 } 423 424 // regardless of success result, we have finished reconfiguration 425 channel->EattChannelSetState(EattChannelState::EATT_CHANNEL_OPENED); 426 427 if (p_cfg->result != tL2CAP_CFG_RESULT::L2CAP_CFG_OK) { 428 log::info("reconfig failed lcid: 0x{:x} result:{}", lcid, 429 l2cap_cfg_result_text(p_cfg->result)); 430 return; 431 } 432 433 /* On this layer we don't care about mps as this is handled in L2CAP layer 434 */ 435 if (is_local_cfg) { 436 channel->rx_mtu_ = p_cfg->mtu; 437 } else { 438 channel->EattChannelSetTxMTU(p_cfg->mtu); 439 } 440 441 if (stack_config_get_interface()->get_pts_l2cap_ecoc_reconfigure()) { 442 /* Upper tester for L2CAP - schedule sending data */ 443 do_in_main_thread_delayed(base::BindOnce(&eatt_impl::upper_tester_send_data_if_needed, 444 weak_factory_.GetWeakPtr(), bda, lcid), 445 std::chrono::seconds(1)); 446 } 447 } 448 eatt_l2cap_collision_indeatt_impl449 void eatt_l2cap_collision_ind(const RawAddress& bda) { 450 eatt_device* eatt_dev = find_device_by_address(bda); 451 if (!eatt_dev) { 452 log::error("Device {} not available anymore:", bda); 453 return; 454 } 455 /* Remote wanted to setup channels as well. Let's retry remote's request 456 * when we are done with ours.*/ 457 eatt_dev->collision = true; 458 } 459 eatt_l2cap_error_cbeatt_impl460 void eatt_l2cap_error_cb(uint16_t lcid, uint16_t reason) { 461 EattChannel* channel = find_channel_by_cid(lcid); 462 if (!channel) { 463 log::error("Unknown cid: 0x{:x}, reason: 0x{:x}", lcid, reason); 464 return; 465 } 466 467 eatt_device* eatt_dev = find_device_by_address(channel->bda_); 468 switch (channel->state_) { 469 case EattChannelState::EATT_CHANNEL_PENDING: 470 log::warn("Channel for cid: 0x{:x} is not extablished, reason: 0x{:x}", lcid, reason); 471 remove_channel_by_cid(eatt_dev, lcid); 472 break; 473 case EattChannelState::EATT_CHANNEL_RECONFIGURING: 474 /* Just go back to open state */ 475 log::error("Reconfig failed fo cid: 0x{:x}, reason: 0x{:x}", lcid, reason); 476 channel->EattChannelSetState(EattChannelState::EATT_CHANNEL_OPENED); 477 break; 478 default: 479 log::error("cid: 0x{:x}, reason: 0x{:x}, invalid state: {}", lcid, reason, 480 static_cast<uint8_t>(channel->state_)); 481 break; 482 } 483 484 if (!is_channel_connection_pending(eatt_dev)) { 485 eatt_retry_after_collision_if_needed(eatt_dev); 486 } 487 } 488 eatt_l2cap_disconnect_indeatt_impl489 void eatt_l2cap_disconnect_ind(uint16_t lcid, bool /* please_confirm */) { 490 log::info("cid: 0x{:x}", lcid); 491 eatt_device* eatt_dev = find_device_by_cid(lcid); 492 if (!eatt_dev) { 493 log::error("unknown cid: 0x{:x}", lcid); 494 return; 495 } 496 497 eatt_dev->eatt_tcb_->eatt--; 498 remove_channel_by_cid(eatt_dev, lcid); 499 } 500 eatt_l2cap_data_indeatt_impl501 void eatt_l2cap_data_ind(uint16_t lcid, BT_HDR* data_p) { 502 log::info("cid: 0x{:x}", lcid); 503 eatt_device* eatt_dev = find_device_by_cid(lcid); 504 if (!eatt_dev) { 505 log::error("unknown cid: 0x{:x}", lcid); 506 return; 507 } 508 509 EattChannel* channel = find_channel_by_cid(eatt_dev->bda_, lcid); 510 if (!channel) { 511 log::error("Received data on closed channel 0x{:x}", lcid); 512 return; 513 } 514 515 gatt_data_process(*eatt_dev->eatt_tcb_, channel->cid_, data_p); 516 osi_free(data_p); 517 } 518 is_eatt_supported_by_peereatt_impl519 bool is_eatt_supported_by_peer(const RawAddress& bd_addr) { 520 return gatt_profile_get_eatt_support(bd_addr); 521 } 522 find_device_by_addresseatt_impl523 eatt_device* find_device_by_address(const RawAddress& bd_addr) { 524 auto iter = find_if(devices_.begin(), devices_.end(), 525 [&bd_addr](const eatt_device& ed) { return ed.bda_ == bd_addr; }); 526 527 return iter == devices_.end() ? nullptr : &(*iter); 528 } 529 add_eatt_deviceeatt_impl530 eatt_device* add_eatt_device(const RawAddress& bd_addr) { 531 devices_.push_back(eatt_device(bd_addr, default_mtu_, max_mps_)); 532 eatt_device* eatt_dev = &devices_.back(); 533 return eatt_dev; 534 } 535 connect_eatt_wrapeatt_impl536 void connect_eatt_wrap(eatt_device* eatt_dev) { 537 if (stack_config_get_interface()->get_pts_eatt_peripheral_collision_support()) { 538 /* For PTS case, lets assume we support only 5 channels */ 539 log::info("Number of existing channels {}", (int)eatt_dev->eatt_channels.size()); 540 connect_eatt(eatt_dev, L2CAP_CREDIT_BASED_MAX_CIDS - (int)eatt_dev->eatt_channels.size()); 541 return; 542 } 543 544 connect_eatt(eatt_dev); 545 } 546 547 void connect_eatt(eatt_device* eatt_dev, uint8_t num_of_channels = L2CAP_CREDIT_BASED_MAX_CIDS) { 548 /* Let us use maximum possible mps */ 549 if (eatt_dev->rx_mps_ == EATT_MIN_MTU_MPS) { 550 eatt_dev->rx_mps_ = shim::GetController()->GetLeBufferSize().le_data_packet_length_; 551 } 552 553 tL2CAP_LE_CFG_INFO local_coc_cfg = { 554 .result = tL2CAP_CFG_RESULT::L2CAP_CFG_OK, 555 .mtu = eatt_dev->rx_mtu_, 556 .mps = eatt_dev->rx_mps_, 557 .credits = L2CA_LeCreditDefault(), 558 .number_of_channels = num_of_channels, 559 }; 560 561 log::info("Connecting device {}, cnt count {}", eatt_dev->bda_, num_of_channels); 562 563 /* Warning! CIDs in Android are unique across the ACL connections */ 564 std::vector<uint16_t> connecting_cids = 565 stack::l2cap::get_interface().L2CA_ConnectCreditBasedReq(psm_, eatt_dev->bda_, 566 &local_coc_cfg); 567 568 if (connecting_cids.size() == 0) { 569 log::error("Unable to get cid"); 570 return; 571 } 572 573 log::info("Successfully sent CoC request, number of channel: {}", connecting_cids.size()); 574 575 for (uint16_t cid : connecting_cids) { 576 log::info("\t cid: 0x{:x}", cid); 577 578 auto chan = std::make_shared<EattChannel>(eatt_dev->bda_, cid, 0, eatt_dev->rx_mtu_); 579 eatt_dev->eatt_channels.insert({cid, chan}); 580 } 581 582 if (eatt_dev->eatt_tcb_) { 583 log::info("has tcb ? {}", eatt_dev->eatt_tcb_ == nullptr); 584 return; 585 } 586 587 eatt_dev->eatt_tcb_ = gatt_find_tcb_by_addr(eatt_dev->bda_, BT_TRANSPORT_LE); 588 log::assert_that(eatt_dev->eatt_tcb_ != nullptr, 589 "assert failed: eatt_dev->eatt_tcb_ != nullptr"); 590 } 591 find_eatt_channel_by_cideatt_impl592 EattChannel* find_eatt_channel_by_cid(const RawAddress& bd_addr, uint16_t cid) { 593 eatt_device* eatt_dev = find_device_by_address(bd_addr); 594 if (!eatt_dev) { 595 return nullptr; 596 } 597 598 auto iter = find_if(eatt_dev->eatt_channels.begin(), eatt_dev->eatt_channels.end(), 599 [&cid](const std::pair<uint16_t, std::shared_ptr<EattChannel>>& el) { 600 return el.first == cid; 601 }); 602 603 return iter == eatt_dev->eatt_channels.end() ? nullptr : iter->second.get(); 604 } 605 find_eatt_channel_by_transideatt_impl606 EattChannel* find_eatt_channel_by_transid(const RawAddress& bd_addr, uint32_t trans_id) { 607 eatt_device* eatt_dev = find_device_by_address(bd_addr); 608 if (!eatt_dev) { 609 return nullptr; 610 } 611 612 auto iter = find_if(eatt_dev->eatt_channels.begin(), eatt_dev->eatt_channels.end(), 613 [&trans_id](const std::pair<uint16_t, std::shared_ptr<EattChannel>>& el) { 614 return el.second->server_outstanding_cmd_.trans_id == trans_id; 615 }); 616 617 return iter == eatt_dev->eatt_channels.end() ? nullptr : iter->second.get(); 618 } 619 is_indication_pendingeatt_impl620 bool is_indication_pending(const RawAddress& bd_addr, uint16_t indication_handle) { 621 eatt_device* eatt_dev = find_device_by_address(bd_addr); 622 if (!eatt_dev) { 623 return false; 624 } 625 626 auto iter = find_if( 627 eatt_dev->eatt_channels.begin(), eatt_dev->eatt_channels.end(), 628 [&indication_handle](const std::pair<uint16_t, std::shared_ptr<EattChannel>>& el) { 629 return el.second->indicate_handle_ == indication_handle; 630 }); 631 632 return iter != eatt_dev->eatt_channels.end(); 633 } 634 get_channel_available_for_indicationeatt_impl635 EattChannel* get_channel_available_for_indication(const RawAddress& bd_addr) { 636 eatt_device* eatt_dev = find_device_by_address(bd_addr); 637 auto iter = find_if(eatt_dev->eatt_channels.begin(), eatt_dev->eatt_channels.end(), 638 [](const std::pair<uint16_t, std::shared_ptr<EattChannel>>& el) { 639 return el.second->state_ == EattChannelState::EATT_CHANNEL_OPENED && 640 !GATT_HANDLE_IS_VALID(el.second->indicate_handle_); 641 }); 642 643 return (iter == eatt_dev->eatt_channels.end()) ? nullptr : iter->second.get(); 644 } 645 get_channel_available_for_client_requesteatt_impl646 EattChannel* get_channel_available_for_client_request(const RawAddress& bd_addr) { 647 eatt_device* eatt_dev = find_device_by_address(bd_addr); 648 if (!eatt_dev) { 649 return nullptr; 650 } 651 652 auto iter = find_if(eatt_dev->eatt_channels.begin(), eatt_dev->eatt_channels.end(), 653 [](const std::pair<uint16_t, std::shared_ptr<EattChannel>>& el) { 654 return el.second->state_ == EattChannelState::EATT_CHANNEL_OPENED && 655 el.second->cl_cmd_q_.empty(); 656 }); 657 658 return (iter == eatt_dev->eatt_channels.end()) ? nullptr : iter->second.get(); 659 } 660 free_gatt_resourceseatt_impl661 void free_gatt_resources(const RawAddress& bd_addr) { 662 eatt_device* eatt_dev = find_device_by_address(bd_addr); 663 if (!eatt_dev) { 664 return; 665 } 666 667 auto iter = eatt_dev->eatt_channels.begin(); 668 while (iter != eatt_dev->eatt_channels.end()) { 669 EattChannel* channel = iter->second.get(); 670 671 fixed_queue_free(channel->server_outstanding_cmd_.multi_rsp_q, NULL); 672 channel->server_outstanding_cmd_.multi_rsp_q = NULL; 673 iter++; 674 } 675 } 676 is_outstanding_msg_in_send_queueeatt_impl677 bool is_outstanding_msg_in_send_queue(const RawAddress& bd_addr) { 678 eatt_device* eatt_dev = find_device_by_address(bd_addr); 679 if (!eatt_dev) { 680 return false; 681 } 682 683 auto iter = find_if(eatt_dev->eatt_channels.begin(), eatt_dev->eatt_channels.end(), 684 [](const std::pair<uint16_t, std::shared_ptr<EattChannel>>& el) { 685 if (el.second->cl_cmd_q_.empty()) { 686 return false; 687 } 688 689 tGATT_CMD_Q& cmd = el.second->cl_cmd_q_.front(); 690 return cmd.to_send; 691 }); 692 return iter != eatt_dev->eatt_channels.end(); 693 } 694 get_channel_with_queued_dataeatt_impl695 EattChannel* get_channel_with_queued_data(const RawAddress& bd_addr) { 696 eatt_device* eatt_dev = find_device_by_address(bd_addr); 697 if (!eatt_dev) { 698 return nullptr; 699 } 700 701 auto iter = find_if(eatt_dev->eatt_channels.begin(), eatt_dev->eatt_channels.end(), 702 [](const std::pair<uint16_t, std::shared_ptr<EattChannel>>& el) { 703 if (el.second->cl_cmd_q_.empty()) { 704 return false; 705 } 706 707 tGATT_CMD_Q& cmd = el.second->cl_cmd_q_.front(); 708 return cmd.to_send; 709 }); 710 return (iter == eatt_dev->eatt_channels.end()) ? nullptr : iter->second.get(); 711 } 712 eatt_ind_ack_timeouteatt_impl713 static void eatt_ind_ack_timeout(void* data) { 714 EattChannel* channel = (EattChannel*)data; 715 tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(channel->bda_, BT_TRANSPORT_LE); 716 717 log::warn("send ack now"); 718 attp_send_cl_confirmation_msg(*p_tcb, channel->cid_); 719 } 720 eatt_ind_confirmation_timeouteatt_impl721 static void eatt_ind_confirmation_timeout(void* data) { 722 EattChannel* channel = (EattChannel*)data; 723 tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(channel->bda_, BT_TRANSPORT_LE); 724 725 log::warn("disconnecting channel {:#x} for {}", channel->cid_, channel->bda_); 726 if (com::android::bluetooth::flags::gatt_disconnect_fix()) { 727 EattExtension::GetInstance()->Disconnect(channel->bda_, channel->cid_); 728 } else { 729 gatt_disconnect(p_tcb); 730 } 731 } 732 start_indication_confirm_timereatt_impl733 void start_indication_confirm_timer(const RawAddress& bd_addr, uint16_t cid) { 734 EattChannel* channel = find_eatt_channel_by_cid(bd_addr, cid); 735 if (!channel) { 736 log::error("Unknown cid: 0x{:x} or device {}", cid, bd_addr); 737 return; 738 } 739 740 alarm_set_on_mloop(channel->ind_confirmation_timer_, GATT_WAIT_FOR_RSP_TIMEOUT_MS, 741 eatt_ind_confirmation_timeout, channel); 742 } 743 stop_indication_confirm_timereatt_impl744 void stop_indication_confirm_timer(const RawAddress& bd_addr, uint16_t cid) { 745 EattChannel* channel = find_eatt_channel_by_cid(bd_addr, cid); 746 if (!channel) { 747 log::error("Unknown cid: 0x{:x} or device {}", cid, bd_addr); 748 return; 749 } 750 751 alarm_cancel(channel->ind_confirmation_timer_); 752 } 753 start_app_indication_timereatt_impl754 void start_app_indication_timer(const RawAddress& bd_addr, uint16_t cid) { 755 EattChannel* channel = find_eatt_channel_by_cid(bd_addr, cid); 756 if (!channel) { 757 log::error("Unknown cid: 0x{:x} or device {}", cid, bd_addr); 758 return; 759 } 760 761 alarm_set_on_mloop(channel->ind_ack_timer_, GATT_WAIT_FOR_RSP_TIMEOUT_MS, eatt_ind_ack_timeout, 762 channel); 763 } 764 stop_app_indication_timereatt_impl765 void stop_app_indication_timer(const RawAddress& bd_addr, uint16_t cid) { 766 EattChannel* channel = find_eatt_channel_by_cid(bd_addr, cid); 767 if (!channel) { 768 log::error("Unknown cid: 0x{:x} or device {}", cid, bd_addr); 769 return; 770 } 771 772 alarm_cancel(channel->ind_ack_timer_); 773 } 774 reconfigureeatt_impl775 void reconfigure(const RawAddress& bd_addr, uint16_t cid, uint16_t new_mtu) { 776 eatt_device* eatt_dev = find_device_by_address(bd_addr); 777 if (!eatt_dev) { 778 log::error("Unknown device {}", bd_addr); 779 return; 780 } 781 782 EattChannel* channel = find_eatt_channel_by_cid(bd_addr, cid); 783 if (!channel) { 784 log::error("Unknown cid: 0x{:x} or device {}", cid, bd_addr); 785 return; 786 } 787 788 if (new_mtu <= channel->rx_mtu_) { 789 log::error("Invalid mtu: 0x{:x}", new_mtu); 790 return; 791 } 792 793 std::vector<uint16_t> cids = {cid}; 794 795 tL2CAP_LE_CFG_INFO cfg = { 796 .result = tL2CAP_CFG_RESULT::L2CAP_CFG_OK, 797 .mtu = new_mtu, 798 .mps = eatt_dev->rx_mps_, 799 }; 800 801 if (!stack::l2cap::get_interface().L2CA_ReconfigCreditBasedConnsReq(eatt_dev->bda_, cids, 802 &cfg)) { 803 log::error("Could not start reconfig cid: 0x{:x} or device {}", cid, bd_addr); 804 return; 805 } 806 807 channel->EattChannelSetState(EattChannelState::EATT_CHANNEL_RECONFIGURING); 808 } 809 reconfigure_alleatt_impl810 void reconfigure_all(const RawAddress& bd_addr, uint16_t new_mtu) { 811 log::info("Device {}, new mtu {}", bd_addr, new_mtu); 812 eatt_device* eatt_dev = find_device_by_address(bd_addr); 813 if (!eatt_dev) { 814 log::error("Unknown device {}", bd_addr); 815 return; 816 } 817 818 uint8_t num_of_channels = eatt_dev->eatt_channels.size(); 819 if (num_of_channels == 0) { 820 log::error("No channels for device {}", bd_addr); 821 return; 822 } 823 824 std::vector<uint16_t> cids; 825 826 auto iter = eatt_dev->eatt_channels.begin(); 827 while (iter != eatt_dev->eatt_channels.end()) { 828 uint16_t cid = iter->first; 829 cids.push_back(cid); 830 iter++; 831 } 832 833 if (new_mtu <= EATT_MIN_MTU_MPS) { 834 log::error("Invalid mtu: 0x{:x}", new_mtu); 835 return; 836 } 837 838 tL2CAP_LE_CFG_INFO cfg = { 839 .result = tL2CAP_CFG_RESULT::L2CAP_CFG_OK, .mtu = new_mtu, .mps = eatt_dev->rx_mps_}; 840 841 if (!stack::l2cap::get_interface().L2CA_ReconfigCreditBasedConnsReq(eatt_dev->bda_, cids, 842 &cfg)) { 843 log::error("Could not start reconfig for device {}", bd_addr); 844 return; 845 } 846 847 for (auto& channel : eatt_dev->eatt_channels) { 848 channel.second->EattChannelSetState(EattChannelState::EATT_CHANNEL_RECONFIGURING); 849 } 850 } 851 supported_features_cbeatt_impl852 void supported_features_cb(uint8_t role, const RawAddress& bd_addr, uint8_t features) { 853 bool is_eatt_supported = features & BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK; 854 855 log::info("{} is_eatt_supported = {}", bd_addr, int(is_eatt_supported)); 856 if (!is_eatt_supported) { 857 return; 858 } 859 860 eatt_device* eatt_dev = this->find_device_by_address(bd_addr); 861 if (!eatt_dev) { 862 log::info("Adding device: {} on supported features callback.", bd_addr); 863 eatt_dev = add_eatt_device(bd_addr); 864 } 865 866 if (role != HCI_ROLE_CENTRAL) { 867 /* TODO For now do nothing, we could run a timer here and start EATT if 868 * not started by central */ 869 log::info("EATT Should be connected by the central. Let's wait for it."); 870 return; 871 } 872 873 connect_eatt_wrap(eatt_dev); 874 } 875 disconnect_channeleatt_impl876 void disconnect_channel(uint16_t cid) { 877 if (!stack::l2cap::get_interface().L2CA_DisconnectReq(cid)) { 878 log::warn("Unable to request L2CAP disconnect cid:{}", cid); 879 } 880 } 881 disconnecteatt_impl882 void disconnect(const RawAddress& bd_addr, uint16_t cid) { 883 log::info("Device: {}, cid: 0x{:04x}", bd_addr, cid); 884 885 eatt_device* eatt_dev = find_device_by_address(bd_addr); 886 if (!eatt_dev) { 887 log::warn("no eatt device found"); 888 return; 889 } 890 891 if (!eatt_dev->eatt_tcb_) { 892 log::assert_that(eatt_dev->eatt_channels.size() == 0, 893 "assert failed: eatt_dev->eatt_channels.size() == 0"); 894 log::warn("no eatt channels found"); 895 return; 896 } 897 898 if (cid != EATT_ALL_CIDS) { 899 auto chan = find_channel_by_cid(cid); 900 if (!chan) { 901 log::warn("Cid {} not found for device {}", cid, bd_addr); 902 return; 903 } 904 log::info("Disconnecting cid {}", cid); 905 disconnect_channel(cid); 906 remove_channel_by_cid(cid); 907 return; 908 } 909 910 auto iter = eatt_dev->eatt_channels.begin(); 911 while (iter != eatt_dev->eatt_channels.end()) { 912 uint16_t cid = iter->first; 913 disconnect_channel(cid); 914 /* When initiating disconnection, stack will not notify us that it is 915 * done. We need to assume success 916 */ 917 iter = eatt_dev->eatt_channels.erase(iter); 918 } 919 eatt_dev->eatt_tcb_->eatt = 0; 920 eatt_dev->eatt_tcb_ = nullptr; 921 eatt_dev->collision = false; 922 } 923 upper_tester_connecteatt_impl924 void upper_tester_connect(const RawAddress& bd_addr, eatt_device* eatt_dev, uint8_t role) { 925 log::info("L2CAP Upper tester enabled, {} ({}), role: {}({})", bd_addr, 926 std::format_ptr(eatt_dev), 927 role == HCI_ROLE_CENTRAL ? "HCI_ROLE_CENTRAL" : "HCI_ROLE_PERIPHERAL", role); 928 929 auto num_of_chan = stack_config_get_interface()->get_pts_l2cap_ecoc_initial_chan_cnt(); 930 if (num_of_chan <= 0) { 931 num_of_chan = L2CAP_CREDIT_BASED_MAX_CIDS; 932 } 933 934 /* This is needed for L2CAP test cases */ 935 if (stack_config_get_interface()->get_pts_connect_eatt_unconditionally()) { 936 /* Normally eatt_dev exist only if EATT is supported by remote device. 937 * Here it is created unconditionally */ 938 if (eatt_dev == nullptr) { 939 eatt_dev = add_eatt_device(bd_addr); 940 } 941 /* For PTS just start connecting EATT right away */ 942 connect_eatt(eatt_dev, num_of_chan); 943 return; 944 } 945 946 if (eatt_dev != nullptr && role == HCI_ROLE_CENTRAL) { 947 connect_eatt(eatt_dev, num_of_chan); 948 return; 949 } 950 951 /* If we don't know yet, read GATT server supported features. */ 952 if (gatt_cl_read_sr_supp_feat_req(bd_addr, base::BindOnce(&eatt_impl::supported_features_cb, 953 weak_factory_.GetWeakPtr(), role)) == 954 false) { 955 log::info("Read server supported features failed for device {}", bd_addr); 956 } 957 } 958 connecteatt_impl959 void connect(const RawAddress& bd_addr) { 960 eatt_device* eatt_dev = find_device_by_address(bd_addr); 961 962 uint8_t role = stack::l2cap::get_interface().L2CA_GetBleConnRole(bd_addr); 963 if (role == HCI_ROLE_UNKNOWN) { 964 log::error("Could not get device role{}", bd_addr); 965 return; 966 } 967 968 if (stack_config_get_interface()->get_pts_l2cap_ecoc_upper_tester()) { 969 upper_tester_connect(bd_addr, eatt_dev, role); 970 return; 971 } 972 973 log::info("Device {}, role {}", bd_addr, role == HCI_ROLE_CENTRAL ? "central" : "peripheral"); 974 975 if (eatt_dev) { 976 /* We are reconnecting device we know that support EATT. 977 * Just connect CoC 978 */ 979 log::info("Known device, connect eCoC"); 980 981 if (role != HCI_ROLE_CENTRAL) { 982 log::info("EATT Should be connected by the central. Let's wait for it."); 983 return; 984 } 985 986 connect_eatt_wrap(eatt_dev); 987 return; 988 } 989 990 if (role != HCI_ROLE_CENTRAL) { 991 return; 992 } 993 994 if (gatt_profile_get_eatt_support(bd_addr)) { 995 log::debug("Eatt is supported for device {}", bd_addr); 996 supported_features_cb(role, bd_addr, BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK); 997 return; 998 } 999 1000 /* If we don't know yet, read GATT server supported features. */ 1001 if (gatt_cl_read_sr_supp_feat_req(bd_addr, base::BindOnce(&eatt_impl::supported_features_cb, 1002 weak_factory_.GetWeakPtr(), role)) == 1003 false) { 1004 log::info("Read server supported features failed for device {}", bd_addr); 1005 } 1006 } 1007 add_from_storageeatt_impl1008 void add_from_storage(const RawAddress& bd_addr) { 1009 eatt_device* eatt_dev = find_device_by_address(bd_addr); 1010 1011 log::info("restoring: {}", bd_addr); 1012 1013 if (!eatt_dev) { 1014 add_eatt_device(bd_addr); 1015 } 1016 } 1017 }; 1018 1019 } // namespace eatt 1020 } // namespace bluetooth 1021