1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <bluetooth/log.h> 20 21 #include <memory> 22 23 #include "common/bind.h" 24 #include "hci/acl_manager/acl_scheduler.h" 25 #include "hci/acl_manager/assembler.h" 26 #include "hci/acl_manager/connection_callbacks.h" 27 #include "hci/acl_manager/connection_management_callbacks.h" 28 #include "hci/acl_manager/round_robin_scheduler.h" 29 #include "hci/class_of_device.h" 30 #include "hci/controller.h" 31 #include "hci/event_checkers.h" 32 #include "hci/hci_layer.h" 33 #include "hci/remote_name_request.h" 34 #include "metrics/bluetooth_event.h" 35 #include "os/metrics.h" 36 37 namespace bluetooth { 38 namespace hci { 39 namespace acl_manager { 40 41 struct acl_connection { acl_connectionacl_connection42 acl_connection(AddressWithType address_with_type, AclConnection::QueueDownEnd* queue_down_end, 43 os::Handler* handler) 44 : address_with_type_(address_with_type), 45 assembler_(new acl_manager::assembler(address_with_type, queue_down_end, handler)) {} ~acl_connectionacl_connection46 ~acl_connection() { delete assembler_; } 47 AddressWithType address_with_type_; 48 struct acl_manager::assembler* assembler_; 49 ConnectionManagementCallbacks* connection_management_callbacks_ = nullptr; 50 }; 51 52 struct classic_impl { classic_implclassic_impl53 classic_impl(HciLayer* hci_layer, Controller* controller, os::Handler* handler, 54 RoundRobinScheduler* round_robin_scheduler, bool crash_on_unknown_handle, 55 AclScheduler* acl_scheduler, RemoteNameRequestModule* remote_name_request_module) 56 : hci_layer_(hci_layer), 57 controller_(controller), 58 round_robin_scheduler_(round_robin_scheduler), 59 acl_scheduler_(acl_scheduler), 60 remote_name_request_module_(remote_name_request_module) { 61 hci_layer_ = hci_layer; 62 controller_ = controller; 63 handler_ = handler; 64 connections.crash_on_unknown_handle_ = crash_on_unknown_handle; 65 should_accept_connection_ = common::Bind([](Address, ClassOfDevice) { return true; }); 66 acl_connection_interface_ = hci_layer_->GetAclConnectionInterface( 67 handler_->BindOn(this, &classic_impl::on_classic_event), 68 handler_->BindOn(this, &classic_impl::on_classic_disconnect), 69 handler_->BindOn(this, &classic_impl::on_incoming_connection), 70 handler_->BindOn(this, &classic_impl::on_read_remote_version_information)); 71 } 72 ~classic_implclassic_impl73 ~classic_impl() { 74 hci_layer_->PutAclConnectionInterface(); 75 connections.reset(); 76 } 77 on_classic_eventclassic_impl78 void on_classic_event(EventView event_packet) { 79 EventCode event_code = event_packet.GetEventCode(); 80 switch (event_code) { 81 case EventCode::CONNECTION_COMPLETE: 82 on_connection_complete(event_packet); 83 break; 84 case EventCode::CONNECTION_PACKET_TYPE_CHANGED: 85 on_connection_packet_type_changed(event_packet); 86 break; 87 case EventCode::AUTHENTICATION_COMPLETE: 88 on_authentication_complete(event_packet); 89 break; 90 case EventCode::READ_CLOCK_OFFSET_COMPLETE: 91 on_read_clock_offset_complete(event_packet); 92 break; 93 case EventCode::MODE_CHANGE: 94 on_mode_change(event_packet); 95 break; 96 case EventCode::SNIFF_SUBRATING: 97 on_sniff_subrating(event_packet); 98 break; 99 case EventCode::QOS_SETUP_COMPLETE: 100 on_qos_setup_complete(event_packet); 101 break; 102 case EventCode::ROLE_CHANGE: 103 on_role_change(event_packet); 104 break; 105 case EventCode::FLOW_SPECIFICATION_COMPLETE: 106 on_flow_specification_complete(event_packet); 107 break; 108 case EventCode::FLUSH_OCCURRED: 109 on_flush_occurred(event_packet); 110 break; 111 case EventCode::ENHANCED_FLUSH_COMPLETE: 112 on_enhanced_flush_complete(event_packet); 113 break; 114 case EventCode::READ_REMOTE_SUPPORTED_FEATURES_COMPLETE: 115 on_read_remote_supported_features_complete(event_packet); 116 break; 117 case EventCode::READ_REMOTE_EXTENDED_FEATURES_COMPLETE: 118 on_read_remote_extended_features_complete(event_packet); 119 break; 120 case EventCode::LINK_SUPERVISION_TIMEOUT_CHANGED: 121 on_link_supervision_timeout_changed(event_packet); 122 break; 123 case EventCode::CENTRAL_LINK_KEY_COMPLETE: 124 on_central_link_key_complete(event_packet); 125 break; 126 default: 127 log::fatal("Unhandled event code {}", EventCodeText(event_code)); 128 } 129 } 130 131 private: 132 static constexpr uint16_t kIllegalConnectionHandle = 0xffff; 133 struct { 134 private: 135 std::map<uint16_t, acl_connection> acl_connections_; 136 mutable std::mutex acl_connections_guard_; find_callbacksclassic_impl::__anon3a71c9430108137 ConnectionManagementCallbacks* find_callbacks(uint16_t handle) { 138 auto connection = acl_connections_.find(handle); 139 if (connection == acl_connections_.end()) { 140 return nullptr; 141 } 142 return connection->second.connection_management_callbacks_; 143 } find_callbacksclassic_impl::__anon3a71c9430108144 ConnectionManagementCallbacks* find_callbacks(const Address& address) { 145 for (auto& connection_pair : acl_connections_) { 146 if (connection_pair.second.address_with_type_.GetAddress() == address) { 147 return connection_pair.second.connection_management_callbacks_; 148 } 149 } 150 return nullptr; 151 } removeclassic_impl::__anon3a71c9430108152 void remove(uint16_t handle) { 153 auto connection = acl_connections_.find(handle); 154 if (connection != acl_connections_.end()) { 155 connection->second.connection_management_callbacks_ = nullptr; 156 acl_connections_.erase(handle); 157 } 158 } 159 160 public: 161 bool crash_on_unknown_handle_ = false; sizeclassic_impl::__anon3a71c9430108162 size_t size() const { 163 std::unique_lock<std::mutex> lock(acl_connections_guard_); 164 return acl_connections_.size(); 165 } is_emptyclassic_impl::__anon3a71c9430108166 bool is_empty() const { 167 std::unique_lock<std::mutex> lock(acl_connections_guard_); 168 return acl_connections_.empty(); 169 } resetclassic_impl::__anon3a71c9430108170 void reset() { 171 std::unique_lock<std::mutex> lock(acl_connections_guard_); 172 acl_connections_.clear(); 173 } invalidateclassic_impl::__anon3a71c9430108174 void invalidate(uint16_t handle) { 175 std::unique_lock<std::mutex> lock(acl_connections_guard_); 176 remove(handle); 177 } 178 void execute(uint16_t handle, 179 std::function<void(ConnectionManagementCallbacks* callbacks)> execute, 180 bool remove_afterwards = false) { 181 std::unique_lock<std::mutex> lock(acl_connections_guard_); 182 auto callbacks = find_callbacks(handle); 183 if (callbacks != nullptr) { 184 execute(callbacks); 185 } else { 186 log::assert_that(!crash_on_unknown_handle_, "Received command for unknown handle:0x{:x}", 187 handle); 188 } 189 if (remove_afterwards) { 190 remove(handle); 191 } 192 } executeclassic_impl::__anon3a71c9430108193 void execute(const Address& address, 194 std::function<void(ConnectionManagementCallbacks* callbacks)> execute) { 195 std::unique_lock<std::mutex> lock(acl_connections_guard_); 196 auto callbacks = find_callbacks(address); 197 if (callbacks != nullptr) { 198 execute(callbacks); 199 } 200 } send_packet_upwardclassic_impl::__anon3a71c9430108201 bool send_packet_upward(uint16_t handle, 202 std::function<void(struct acl_manager::assembler* assembler)> cb) { 203 std::unique_lock<std::mutex> lock(acl_connections_guard_); 204 auto connection = acl_connections_.find(handle); 205 if (connection != acl_connections_.end()) { 206 cb(connection->second.assembler_); 207 } 208 return connection != acl_connections_.end(); 209 } addclassic_impl::__anon3a71c9430108210 void add(uint16_t handle, const AddressWithType& remote_address, 211 AclConnection::QueueDownEnd* queue_end, os::Handler* handler, 212 ConnectionManagementCallbacks* connection_management_callbacks) { 213 std::unique_lock<std::mutex> lock(acl_connections_guard_); 214 auto emplace_pair = 215 acl_connections_.emplace(std::piecewise_construct, std::forward_as_tuple(handle), 216 std::forward_as_tuple(remote_address, queue_end, handler)); 217 log::assert_that(emplace_pair.second, 218 "assert failed: emplace_pair.second"); // Make sure the connection is unique 219 emplace_pair.first->second.connection_management_callbacks_ = connection_management_callbacks; 220 } HACK_get_handleclassic_impl::__anon3a71c9430108221 uint16_t HACK_get_handle(const Address& address) const { 222 std::unique_lock<std::mutex> lock(acl_connections_guard_); 223 for (auto it = acl_connections_.begin(); it != acl_connections_.end(); it++) { 224 if (it->second.address_with_type_.GetAddress() == address) { 225 return it->first; 226 } 227 } 228 return kIllegalConnectionHandle; 229 } get_addressclassic_impl::__anon3a71c9430108230 Address get_address(uint16_t handle) const { 231 std::unique_lock<std::mutex> lock(acl_connections_guard_); 232 auto connection = acl_connections_.find(handle); 233 if (connection == acl_connections_.end()) { 234 return Address::kEmpty; 235 } 236 return connection->second.address_with_type_.GetAddress(); 237 } is_classic_link_already_connectedclassic_impl::__anon3a71c9430108238 bool is_classic_link_already_connected(const Address& address) const { 239 std::unique_lock<std::mutex> lock(acl_connections_guard_); 240 for (const auto& connection : acl_connections_) { 241 if (connection.second.address_with_type_.GetAddress() == address) { 242 return true; 243 } 244 } 245 return false; 246 } 247 } connections; 248 249 public: send_packet_upwardclassic_impl250 bool send_packet_upward(uint16_t handle, 251 std::function<void(struct acl_manager::assembler* assembler)> cb) { 252 return connections.send_packet_upward(handle, cb); 253 } 254 on_incoming_connectionclassic_impl255 void on_incoming_connection(Address address, ClassOfDevice cod) { 256 if (client_callbacks_ == nullptr) { 257 log::error("No callbacks to call"); 258 auto reason = RejectConnectionReason::LIMITED_RESOURCES; 259 this->reject_connection(RejectConnectionRequestBuilder::Create(address, reason)); 260 return; 261 } 262 263 client_handler_->CallOn(client_callbacks_, &ConnectionCallbacks::OnConnectRequest, address, 264 cod); 265 266 bluetooth::metrics::LogIncomingAclStartEvent(address); 267 268 acl_scheduler_->RegisterPendingIncomingConnection(address); 269 270 if (is_classic_link_already_connected(address)) { 271 auto reason = RejectConnectionReason::UNACCEPTABLE_BD_ADDR; 272 this->reject_connection(RejectConnectionRequestBuilder::Create(address, reason)); 273 } else if (should_accept_connection_.Run(address, cod)) { 274 this->accept_connection(address); 275 } else { 276 auto reason = RejectConnectionReason::LIMITED_RESOURCES; // TODO: determine reason 277 this->reject_connection(RejectConnectionRequestBuilder::Create(address, reason)); 278 } 279 } 280 is_classic_link_already_connectedclassic_impl281 bool is_classic_link_already_connected(Address address) { 282 return connections.is_classic_link_already_connected(address); 283 } 284 get_connection_countclassic_impl285 size_t get_connection_count() { return connections.size(); } 286 create_connectionclassic_impl287 void create_connection(Address address) { 288 // TODO: Configure default connection parameters? 289 uint16_t packet_type = 0x4408 /* DM 1,3,5 */ | 0x8810 /*DH 1,3,5 */; 290 PageScanRepetitionMode page_scan_repetition_mode = PageScanRepetitionMode::R1; 291 uint16_t clock_offset = 0; 292 ClockOffsetValid clock_offset_valid = ClockOffsetValid::INVALID; 293 CreateConnectionRoleSwitch allow_role_switch = CreateConnectionRoleSwitch::ALLOW_ROLE_SWITCH; 294 log::assert_that(client_callbacks_ != nullptr, "assert failed: client_callbacks_ != nullptr"); 295 std::unique_ptr<CreateConnectionBuilder> packet = 296 CreateConnectionBuilder::Create(address, packet_type, page_scan_repetition_mode, 297 clock_offset, clock_offset_valid, allow_role_switch); 298 299 acl_scheduler_->EnqueueOutgoingAclConnection( 300 address, handler_->BindOnceOn(this, &classic_impl::actually_create_connection, address, 301 std::move(packet))); 302 } 303 actually_create_connectionclassic_impl304 void actually_create_connection(Address address, 305 std::unique_ptr<CreateConnectionBuilder> packet) { 306 if (is_classic_link_already_connected(address)) { 307 log::warn("already connected: {}", address); 308 acl_scheduler_->ReportOutgoingAclConnectionFailure(); 309 return; 310 } 311 acl_connection_interface_->EnqueueCommand( 312 std::move(packet), 313 handler_->BindOnceOn(this, &classic_impl::on_create_connection_status, address)); 314 } 315 on_create_connection_statusclassic_impl316 void on_create_connection_status(Address address, CommandStatusView status) { 317 log::assert_that(status.IsValid(), "assert failed: status.IsValid()"); 318 log::assert_that(status.GetCommandOpCode() == OpCode::CREATE_CONNECTION, 319 "assert failed: status.GetCommandOpCode() == OpCode::CREATE_CONNECTION"); 320 if (status.GetStatus() != hci::ErrorCode::SUCCESS /* = pending */) { 321 // something went wrong, but unblock queue and report to caller 322 log::error("Failed to create connection, reporting failure and continuing"); 323 log::assert_that(client_callbacks_ != nullptr, "assert failed: client_callbacks_ != nullptr"); 324 client_handler_->Post(common::BindOnce(&ConnectionCallbacks::OnConnectFail, 325 common::Unretained(client_callbacks_), address, 326 status.GetStatus(), true /* locally initiated */)); 327 acl_scheduler_->ReportOutgoingAclConnectionFailure(); 328 } else { 329 // everything is good, resume when a connection_complete event arrives 330 return; 331 } 332 } 333 334 enum class Initiator { 335 LOCALLY_INITIATED, 336 REMOTE_INITIATED, 337 }; 338 create_and_announce_connectionclassic_impl339 void create_and_announce_connection(ConnectionCompleteView connection_complete, Role current_role, 340 Initiator initiator) { 341 auto status = connection_complete.GetStatus(); 342 auto address = connection_complete.GetBdAddr(); 343 if (client_callbacks_ == nullptr) { 344 log::warn("No client callbacks registered for connection"); 345 return; 346 } 347 if (status != ErrorCode::SUCCESS) { 348 client_handler_->Post(common::BindOnce(&ConnectionCallbacks::OnConnectFail, 349 common::Unretained(client_callbacks_), address, status, 350 initiator == Initiator::LOCALLY_INITIATED)); 351 return; 352 } 353 uint16_t handle = connection_complete.GetConnectionHandle(); 354 auto queue = std::make_shared<AclConnection::Queue>(10); 355 auto queue_down_end = queue->GetDownEnd(); 356 round_robin_scheduler_->Register(RoundRobinScheduler::ConnectionType::CLASSIC, handle, queue); 357 std::unique_ptr<ClassicAclConnection> connection( 358 new ClassicAclConnection(std::move(queue), acl_connection_interface_, handle, address)); 359 connection->locally_initiated_ = initiator == Initiator::LOCALLY_INITIATED; 360 connections.add(handle, AddressWithType{address, AddressType::PUBLIC_DEVICE_ADDRESS}, 361 queue_down_end, handler_, 362 connection->GetEventCallbacks( 363 [this](uint16_t handle) { this->connections.invalidate(handle); })); 364 connections.execute(address, [=, this](ConnectionManagementCallbacks* callbacks) { 365 if (delayed_role_change_ == nullptr) { 366 callbacks->OnRoleChange(hci::ErrorCode::SUCCESS, current_role); 367 } else if (delayed_role_change_->GetBdAddr() == address) { 368 log::info("Sending delayed role change for {}", delayed_role_change_->GetBdAddr()); 369 callbacks->OnRoleChange(delayed_role_change_->GetStatus(), 370 delayed_role_change_->GetNewRole()); 371 delayed_role_change_.reset(); 372 } 373 }); 374 client_handler_->Post(common::BindOnce(&ConnectionCallbacks::OnConnectSuccess, 375 common::Unretained(client_callbacks_), 376 std::move(connection))); 377 } 378 on_connection_completeclassic_impl379 void on_connection_complete(EventView packet) { 380 ConnectionCompleteView connection_complete = ConnectionCompleteView::Create(packet); 381 log::assert_that(connection_complete.IsValid(), "assert failed: connection_complete.IsValid()"); 382 auto status = connection_complete.GetStatus(); 383 auto address = connection_complete.GetBdAddr(); 384 385 acl_scheduler_->ReportAclConnectionCompletion( 386 address, 387 handler_->BindOnceOn(this, &classic_impl::create_and_announce_connection, 388 connection_complete, Role::CENTRAL, Initiator::LOCALLY_INITIATED), 389 handler_->BindOnceOn(this, &classic_impl::create_and_announce_connection, 390 connection_complete, Role::PERIPHERAL, 391 Initiator::REMOTE_INITIATED), 392 handler_->BindOnce( 393 [=](RemoteNameRequestModule* remote_name_request_module, Address address, 394 ErrorCode status, std::string valid_incoming_addresses) { 395 log::warn("No matching connection to {} ({})", address, 396 ErrorCodeText(status)); 397 log::assert_that(status != ErrorCode::SUCCESS, 398 "No prior connection request for {} expecting:{}", address, 399 valid_incoming_addresses.c_str()); 400 remote_name_request_module->ReportRemoteNameRequestCancellation(address); 401 }, 402 common::Unretained(remote_name_request_module_), address, status)); 403 } 404 cancel_connectclassic_impl405 void cancel_connect(Address address) { 406 acl_scheduler_->CancelAclConnection( 407 address, handler_->BindOnceOn(this, &classic_impl::actually_cancel_connect, address), 408 client_handler_->BindOnceOn(client_callbacks_, &ConnectionCallbacks::OnConnectFail, 409 address, ErrorCode::UNKNOWN_CONNECTION, 410 true /* locally initiated */)); 411 } 412 actually_cancel_connectclassic_impl413 void actually_cancel_connect(Address address) { 414 std::unique_ptr<CreateConnectionCancelBuilder> packet = 415 CreateConnectionCancelBuilder::Create(address); 416 acl_connection_interface_->EnqueueCommand( 417 std::move(packet), 418 handler_->BindOnce(check_complete<CreateConnectionCancelCompleteView>)); 419 } 420 421 static constexpr bool kRemoveConnectionAfterwards = true; on_classic_disconnectclassic_impl422 void on_classic_disconnect(uint16_t handle, ErrorCode reason) { 423 bool event_also_routes_to_other_receivers = connections.crash_on_unknown_handle_; 424 bluetooth::os::LogMetricBluetoothDisconnectionReasonReported( 425 static_cast<uint32_t>(reason), connections.get_address(handle), handle); 426 connections.crash_on_unknown_handle_ = false; 427 connections.execute( 428 handle, 429 [=, this](ConnectionManagementCallbacks* callbacks) { 430 round_robin_scheduler_->Unregister(handle); 431 callbacks->OnDisconnection(reason); 432 }, 433 kRemoveConnectionAfterwards); 434 connections.crash_on_unknown_handle_ = event_also_routes_to_other_receivers; 435 } 436 on_connection_packet_type_changedclassic_impl437 void on_connection_packet_type_changed(EventView packet) { 438 ConnectionPacketTypeChangedView packet_type_changed = 439 ConnectionPacketTypeChangedView::Create(packet); 440 if (!packet_type_changed.IsValid()) { 441 log::error("Received on_connection_packet_type_changed with invalid packet"); 442 return; 443 } else if (packet_type_changed.GetStatus() != ErrorCode::SUCCESS) { 444 auto status = packet_type_changed.GetStatus(); 445 std::string error_code = ErrorCodeText(status); 446 log::error("Received on_connection_packet_type_changed with error code {}", error_code); 447 return; 448 } 449 uint16_t handle = packet_type_changed.GetConnectionHandle(); 450 connections.execute(handle, [=](ConnectionManagementCallbacks* /* callbacks */) { 451 // We don't handle this event; we didn't do this in legacy stack either. 452 }); 453 } 454 on_central_link_key_completeclassic_impl455 void on_central_link_key_complete(EventView packet) { 456 CentralLinkKeyCompleteView complete_view = CentralLinkKeyCompleteView::Create(packet); 457 if (!complete_view.IsValid()) { 458 log::error("Received on_central_link_key_complete with invalid packet"); 459 return; 460 } else if (complete_view.GetStatus() != ErrorCode::SUCCESS) { 461 auto status = complete_view.GetStatus(); 462 std::string error_code = ErrorCodeText(status); 463 log::error("Received on_central_link_key_complete with error code {}", error_code); 464 return; 465 } 466 uint16_t handle = complete_view.GetConnectionHandle(); 467 connections.execute(handle, [=](ConnectionManagementCallbacks* callbacks) { 468 KeyFlag key_flag = complete_view.GetKeyFlag(); 469 callbacks->OnCentralLinkKeyComplete(key_flag); 470 }); 471 } 472 on_authentication_completeclassic_impl473 void on_authentication_complete(EventView packet) { 474 AuthenticationCompleteView authentication_complete = AuthenticationCompleteView::Create(packet); 475 if (!authentication_complete.IsValid()) { 476 log::error("Received on_authentication_complete with invalid packet"); 477 return; 478 } 479 uint16_t handle = authentication_complete.GetConnectionHandle(); 480 connections.execute(handle, [=](ConnectionManagementCallbacks* callbacks) { 481 callbacks->OnAuthenticationComplete(authentication_complete.GetStatus()); 482 }); 483 } 484 on_change_connection_link_key_completeclassic_impl485 void on_change_connection_link_key_complete(EventView packet) { 486 ChangeConnectionLinkKeyCompleteView complete_view = 487 ChangeConnectionLinkKeyCompleteView::Create(packet); 488 if (!complete_view.IsValid()) { 489 log::error("Received on_change_connection_link_key_complete with invalid packet"); 490 return; 491 } else if (complete_view.GetStatus() != ErrorCode::SUCCESS) { 492 auto status = complete_view.GetStatus(); 493 std::string error_code = ErrorCodeText(status); 494 log::error("Received on_change_connection_link_key_complete with error code {}", error_code); 495 return; 496 } 497 uint16_t handle = complete_view.GetConnectionHandle(); 498 connections.execute(handle, [=](ConnectionManagementCallbacks* callbacks) { 499 callbacks->OnChangeConnectionLinkKeyComplete(); 500 }); 501 } 502 on_read_clock_offset_completeclassic_impl503 void on_read_clock_offset_complete(EventView packet) { 504 ReadClockOffsetCompleteView complete_view = ReadClockOffsetCompleteView::Create(packet); 505 if (!complete_view.IsValid()) { 506 log::error("Received on_read_clock_offset_complete with invalid packet"); 507 return; 508 } else if (complete_view.GetStatus() != ErrorCode::SUCCESS) { 509 auto status = complete_view.GetStatus(); 510 std::string error_code = ErrorCodeText(status); 511 log::error("Received on_read_clock_offset_complete with error code {}", error_code); 512 return; 513 } 514 uint16_t handle = complete_view.GetConnectionHandle(); 515 connections.execute(handle, [=](ConnectionManagementCallbacks* callbacks) { 516 uint16_t clock_offset = complete_view.GetClockOffset(); 517 callbacks->OnReadClockOffsetComplete(clock_offset); 518 }); 519 } 520 on_mode_changeclassic_impl521 void on_mode_change(EventView packet) { 522 ModeChangeView mode_change_view = ModeChangeView::Create(packet); 523 if (!mode_change_view.IsValid()) { 524 log::error("Received on_mode_change with invalid packet"); 525 return; 526 } 527 uint16_t handle = mode_change_view.GetConnectionHandle(); 528 connections.execute(handle, [=](ConnectionManagementCallbacks* callbacks) { 529 callbacks->OnModeChange(mode_change_view.GetStatus(), mode_change_view.GetCurrentMode(), 530 mode_change_view.GetInterval()); 531 }); 532 } 533 on_sniff_subratingclassic_impl534 void on_sniff_subrating(EventView packet) { 535 SniffSubratingEventView sniff_subrating_view = SniffSubratingEventView::Create(packet); 536 if (!sniff_subrating_view.IsValid()) { 537 log::error("Received on_sniff_subrating with invalid packet"); 538 return; 539 } 540 uint16_t handle = sniff_subrating_view.GetConnectionHandle(); 541 connections.execute(handle, [=](ConnectionManagementCallbacks* callbacks) { 542 callbacks->OnSniffSubrating(sniff_subrating_view.GetStatus(), 543 sniff_subrating_view.GetMaximumTransmitLatency(), 544 sniff_subrating_view.GetMaximumReceiveLatency(), 545 sniff_subrating_view.GetMinimumRemoteTimeout(), 546 sniff_subrating_view.GetMinimumLocalTimeout()); 547 }); 548 } 549 on_qos_setup_completeclassic_impl550 void on_qos_setup_complete(EventView packet) { 551 QosSetupCompleteView complete_view = QosSetupCompleteView::Create(packet); 552 if (!complete_view.IsValid()) { 553 log::error("Received on_qos_setup_complete with invalid packet"); 554 return; 555 } else if (complete_view.GetStatus() != ErrorCode::SUCCESS) { 556 auto status = complete_view.GetStatus(); 557 std::string error_code = ErrorCodeText(status); 558 log::error("Received on_qos_setup_complete with error code {}", error_code); 559 return; 560 } 561 uint16_t handle = complete_view.GetConnectionHandle(); 562 connections.execute(handle, [=](ConnectionManagementCallbacks* callbacks) { 563 ServiceType service_type = complete_view.GetServiceType(); 564 uint32_t token_rate = complete_view.GetTokenRate(); 565 uint32_t peak_bandwidth = complete_view.GetPeakBandwidth(); 566 uint32_t latency = complete_view.GetLatency(); 567 uint32_t delay_variation = complete_view.GetDelayVariation(); 568 callbacks->OnQosSetupComplete(service_type, token_rate, peak_bandwidth, latency, 569 delay_variation); 570 }); 571 } 572 on_flow_specification_completeclassic_impl573 void on_flow_specification_complete(EventView packet) { 574 FlowSpecificationCompleteView complete_view = FlowSpecificationCompleteView::Create(packet); 575 if (!complete_view.IsValid()) { 576 log::error("Received on_flow_specification_complete with invalid packet"); 577 return; 578 } else if (complete_view.GetStatus() != ErrorCode::SUCCESS) { 579 auto status = complete_view.GetStatus(); 580 std::string error_code = ErrorCodeText(status); 581 log::error("Received on_flow_specification_complete with error code {}", error_code); 582 return; 583 } 584 uint16_t handle = complete_view.GetConnectionHandle(); 585 connections.execute(handle, [=](ConnectionManagementCallbacks* callbacks) { 586 FlowDirection flow_direction = complete_view.GetFlowDirection(); 587 ServiceType service_type = complete_view.GetServiceType(); 588 uint32_t token_rate = complete_view.GetTokenRate(); 589 uint32_t token_bucket_size = complete_view.GetTokenBucketSize(); 590 uint32_t peak_bandwidth = complete_view.GetPeakBandwidth(); 591 uint32_t access_latency = complete_view.GetAccessLatency(); 592 callbacks->OnFlowSpecificationComplete(flow_direction, service_type, token_rate, 593 token_bucket_size, peak_bandwidth, access_latency); 594 }); 595 } 596 on_flush_occurredclassic_impl597 void on_flush_occurred(EventView packet) { 598 FlushOccurredView flush_occurred_view = FlushOccurredView::Create(packet); 599 if (!flush_occurred_view.IsValid()) { 600 log::error("Received on_flush_occurred with invalid packet"); 601 return; 602 } 603 uint16_t handle = flush_occurred_view.GetConnectionHandle(); 604 connections.execute(handle, [=](ConnectionManagementCallbacks* callbacks) { 605 callbacks->OnFlushOccurred(); 606 }); 607 } 608 on_enhanced_flush_completeclassic_impl609 void on_enhanced_flush_complete(EventView packet) { 610 auto flush_complete = EnhancedFlushCompleteView::Create(packet); 611 if (!flush_complete.IsValid()) { 612 log::error("Received an invalid packet"); 613 return; 614 } 615 uint16_t handle = flush_complete.GetConnectionHandle(); 616 connections.execute( 617 handle, [](ConnectionManagementCallbacks* callbacks) { callbacks->OnFlushOccurred(); }); 618 } 619 on_read_remote_version_informationclassic_impl620 void on_read_remote_version_information(hci::ErrorCode hci_status, uint16_t handle, 621 uint8_t version, uint16_t manufacturer_name, 622 uint16_t sub_version) { 623 connections.execute(handle, [=](ConnectionManagementCallbacks* callbacks) { 624 callbacks->OnReadRemoteVersionInformationComplete(hci_status, version, manufacturer_name, 625 sub_version); 626 }); 627 } 628 on_read_remote_supported_features_completeclassic_impl629 void on_read_remote_supported_features_complete(EventView packet) { 630 auto view = ReadRemoteSupportedFeaturesCompleteView::Create(packet); 631 log::assert_that(view.IsValid(), "Read remote supported features packet invalid"); 632 uint16_t handle = view.GetConnectionHandle(); 633 auto status = view.GetStatus(); 634 if (status != ErrorCode::SUCCESS) { 635 log::error("handle:{} status:{}", handle, ErrorCodeText(status)); 636 return; 637 } 638 bluetooth::os::LogMetricBluetoothRemoteSupportedFeatures(connections.get_address(handle), 0, 639 view.GetLmpFeatures(), handle); 640 connections.execute(handle, [=](ConnectionManagementCallbacks* callbacks) { 641 callbacks->OnReadRemoteSupportedFeaturesComplete(view.GetLmpFeatures()); 642 }); 643 } 644 on_read_remote_extended_features_completeclassic_impl645 void on_read_remote_extended_features_complete(EventView packet) { 646 auto view = ReadRemoteExtendedFeaturesCompleteView::Create(packet); 647 log::assert_that(view.IsValid(), "Read remote extended features packet invalid"); 648 uint16_t handle = view.GetConnectionHandle(); 649 auto status = view.GetStatus(); 650 if (status != ErrorCode::SUCCESS) { 651 log::error("handle:{} status:{}", handle, ErrorCodeText(status)); 652 return; 653 } 654 bluetooth::os::LogMetricBluetoothRemoteSupportedFeatures(connections.get_address(handle), 655 view.GetPageNumber(), 656 view.GetExtendedLmpFeatures(), handle); 657 connections.execute(handle, [=](ConnectionManagementCallbacks* callbacks) { 658 callbacks->OnReadRemoteExtendedFeaturesComplete( 659 view.GetPageNumber(), view.GetMaximumPageNumber(), view.GetExtendedLmpFeatures()); 660 }); 661 } 662 on_role_changeclassic_impl663 void on_role_change(EventView packet) { 664 RoleChangeView role_change_view = RoleChangeView::Create(packet); 665 if (!role_change_view.IsValid()) { 666 log::error("Received on_role_change with invalid packet"); 667 return; 668 } 669 auto hci_status = role_change_view.GetStatus(); 670 Address bd_addr = role_change_view.GetBdAddr(); 671 Role new_role = role_change_view.GetNewRole(); 672 bool sent = false; 673 connections.execute(bd_addr, [=, &sent](ConnectionManagementCallbacks* callbacks) { 674 if (callbacks != nullptr) { 675 callbacks->OnRoleChange(hci_status, new_role); 676 sent = true; 677 } 678 }); 679 if (!sent) { 680 if (delayed_role_change_ != nullptr) { 681 log::warn("Second delayed role change (@{} dropped)", delayed_role_change_->GetBdAddr()); 682 } 683 log::info("Role change for {} with no matching connection (new role: {})", 684 role_change_view.GetBdAddr(), RoleText(role_change_view.GetNewRole())); 685 delayed_role_change_ = std::make_unique<RoleChangeView>(role_change_view); 686 } 687 } 688 on_link_supervision_timeout_changedclassic_impl689 void on_link_supervision_timeout_changed(EventView packet) { 690 auto view = LinkSupervisionTimeoutChangedView::Create(packet); 691 log::assert_that(view.IsValid(), "Link supervision timeout changed packet invalid"); 692 log::info("UNIMPLEMENTED called"); 693 } 694 on_accept_connection_statusclassic_impl695 void on_accept_connection_status(Address address, CommandStatusView status) { 696 auto accept_status = AcceptConnectionRequestStatusView::Create(status); 697 log::assert_that(accept_status.IsValid(), "assert failed: accept_status.IsValid()"); 698 if (status.GetStatus() != ErrorCode::SUCCESS) { 699 cancel_connect(address); 700 } 701 } 702 central_link_keyclassic_impl703 void central_link_key(KeyFlag key_flag) { 704 std::unique_ptr<CentralLinkKeyBuilder> packet = CentralLinkKeyBuilder::Create(key_flag); 705 acl_connection_interface_->EnqueueCommand( 706 std::move(packet), handler_->BindOnce(check_status<CentralLinkKeyStatusView>)); 707 } 708 switch_roleclassic_impl709 void switch_role(Address address, Role role) { 710 std::unique_ptr<SwitchRoleBuilder> packet = SwitchRoleBuilder::Create(address, role); 711 acl_connection_interface_->EnqueueCommand( 712 std::move(packet), handler_->BindOnce(check_status<SwitchRoleStatusView>)); 713 } 714 write_default_link_policy_settingsclassic_impl715 void write_default_link_policy_settings(uint16_t default_link_policy_settings) { 716 std::unique_ptr<WriteDefaultLinkPolicySettingsBuilder> packet = 717 WriteDefaultLinkPolicySettingsBuilder::Create(default_link_policy_settings); 718 acl_connection_interface_->EnqueueCommand( 719 std::move(packet), 720 handler_->BindOnce(check_complete<WriteDefaultLinkPolicySettingsCompleteView>)); 721 } 722 accept_connectionclassic_impl723 void accept_connection(Address address) { 724 auto role = AcceptConnectionRequestRole::BECOME_CENTRAL; // We prefer to be central 725 acl_connection_interface_->EnqueueCommand( 726 AcceptConnectionRequestBuilder::Create(address, role), 727 handler_->BindOnceOn(this, &classic_impl::on_accept_connection_status, address)); 728 } 729 reject_connectionclassic_impl730 void reject_connection(std::unique_ptr<RejectConnectionRequestBuilder> builder) { 731 acl_connection_interface_->EnqueueCommand( 732 std::move(builder), 733 handler_->BindOnce(check_status<RejectConnectionRequestStatusView>)); 734 } 735 HACK_get_handleclassic_impl736 uint16_t HACK_get_handle(Address address) { return connections.HACK_get_handle(address); } 737 handle_register_callbacksclassic_impl738 void handle_register_callbacks(ConnectionCallbacks* callbacks, os::Handler* handler) { 739 log::assert_that(client_callbacks_ == nullptr, "assert failed: client_callbacks_ == nullptr"); 740 log::assert_that(client_handler_ == nullptr, "assert failed: client_handler_ == nullptr"); 741 client_callbacks_ = callbacks; 742 client_handler_ = handler; 743 } 744 handle_unregister_callbacksclassic_impl745 void handle_unregister_callbacks(ConnectionCallbacks* callbacks, std::promise<void> promise) { 746 log::assert_that(client_callbacks_ == callbacks, 747 "Registered callback entity is different then unregister request"); 748 client_callbacks_ = nullptr; 749 client_handler_ = nullptr; 750 promise.set_value(); 751 } 752 753 HciLayer* hci_layer_ = nullptr; 754 Controller* controller_ = nullptr; 755 RoundRobinScheduler* round_robin_scheduler_ = nullptr; 756 AclScheduler* acl_scheduler_ = nullptr; 757 RemoteNameRequestModule* remote_name_request_module_ = nullptr; 758 AclConnectionInterface* acl_connection_interface_ = nullptr; 759 os::Handler* handler_ = nullptr; 760 ConnectionCallbacks* client_callbacks_ = nullptr; 761 os::Handler* client_handler_ = nullptr; 762 763 common::Callback<bool(Address, ClassOfDevice)> should_accept_connection_; 764 std::unique_ptr<RoleChangeView> delayed_role_change_ = nullptr; 765 }; 766 767 } // namespace acl_manager 768 } // namespace hci 769 } // namespace bluetooth 770