1 /* 2 * Copyright 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 "common/init_flags.h" 25 #include "hci/acl_manager/acl_scheduler.h" 26 #include "hci/acl_manager/assembler.h" 27 #include "hci/acl_manager/connection_callbacks.h" 28 #include "hci/acl_manager/connection_management_callbacks.h" 29 #include "hci/acl_manager/round_robin_scheduler.h" 30 #include "hci/class_of_device.h" 31 #include "hci/controller.h" 32 #include "hci/event_checkers.h" 33 #include "hci/hci_layer.h" 34 #include "hci/remote_name_request.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, os::Handler* handler) 43 : address_with_type_(address_with_type), 44 assembler_(new acl_manager::assembler(address_with_type, queue_down_end, handler)) {} ~acl_connectionacl_connection45 ~acl_connection() { 46 delete assembler_; 47 } 48 AddressWithType address_with_type_; 49 struct acl_manager::assembler* assembler_; 50 ConnectionManagementCallbacks* connection_management_callbacks_ = nullptr; 51 }; 52 53 struct classic_impl { classic_implclassic_impl54 classic_impl( 55 HciLayer* hci_layer, 56 Controller* controller, 57 os::Handler* handler, 58 RoundRobinScheduler* round_robin_scheduler, 59 bool crash_on_unknown_handle, 60 AclScheduler* acl_scheduler, 61 RemoteNameRequestModule* remote_name_request_module) 62 : hci_layer_(hci_layer), 63 controller_(controller), 64 round_robin_scheduler_(round_robin_scheduler), 65 acl_scheduler_(acl_scheduler), 66 remote_name_request_module_(remote_name_request_module) { 67 hci_layer_ = hci_layer; 68 controller_ = controller; 69 handler_ = handler; 70 connections.crash_on_unknown_handle_ = crash_on_unknown_handle; 71 should_accept_connection_ = common::Bind([](Address, ClassOfDevice) { return true; }); 72 acl_connection_interface_ = hci_layer_->GetAclConnectionInterface( 73 handler_->BindOn(this, &classic_impl::on_classic_event), 74 handler_->BindOn(this, &classic_impl::on_classic_disconnect), 75 handler_->BindOn(this, &classic_impl::on_incoming_connection), 76 handler_->BindOn(this, &classic_impl::on_read_remote_version_information)); 77 } 78 ~classic_implclassic_impl79 ~classic_impl() { 80 hci_layer_->PutAclConnectionInterface(); 81 connections.reset(); 82 } 83 on_classic_eventclassic_impl84 void on_classic_event(EventView event_packet) { 85 EventCode event_code = event_packet.GetEventCode(); 86 switch (event_code) { 87 case EventCode::CONNECTION_COMPLETE: 88 on_connection_complete(event_packet); 89 break; 90 case EventCode::CONNECTION_PACKET_TYPE_CHANGED: 91 on_connection_packet_type_changed(event_packet); 92 break; 93 case EventCode::AUTHENTICATION_COMPLETE: 94 on_authentication_complete(event_packet); 95 break; 96 case EventCode::READ_CLOCK_OFFSET_COMPLETE: 97 on_read_clock_offset_complete(event_packet); 98 break; 99 case EventCode::MODE_CHANGE: 100 on_mode_change(event_packet); 101 break; 102 case EventCode::SNIFF_SUBRATING: 103 on_sniff_subrating(event_packet); 104 break; 105 case EventCode::QOS_SETUP_COMPLETE: 106 on_qos_setup_complete(event_packet); 107 break; 108 case EventCode::ROLE_CHANGE: 109 on_role_change(event_packet); 110 break; 111 case EventCode::FLOW_SPECIFICATION_COMPLETE: 112 on_flow_specification_complete(event_packet); 113 break; 114 case EventCode::FLUSH_OCCURRED: 115 on_flush_occurred(event_packet); 116 break; 117 case EventCode::ENHANCED_FLUSH_COMPLETE: 118 on_enhanced_flush_complete(event_packet); 119 break; 120 case EventCode::READ_REMOTE_SUPPORTED_FEATURES_COMPLETE: 121 on_read_remote_supported_features_complete(event_packet); 122 break; 123 case EventCode::READ_REMOTE_EXTENDED_FEATURES_COMPLETE: 124 on_read_remote_extended_features_complete(event_packet); 125 break; 126 case EventCode::LINK_SUPERVISION_TIMEOUT_CHANGED: 127 on_link_supervision_timeout_changed(event_packet); 128 break; 129 case EventCode::CENTRAL_LINK_KEY_COMPLETE: 130 on_central_link_key_complete(event_packet); 131 break; 132 default: 133 log::fatal("Unhandled event code {}", EventCodeText(event_code)); 134 } 135 } 136 137 private: 138 static constexpr uint16_t kIllegalConnectionHandle = 0xffff; 139 struct { 140 private: 141 std::map<uint16_t, acl_connection> acl_connections_; 142 mutable std::mutex acl_connections_guard_; find_callbacksclassic_impl::__anonc961774d0108143 ConnectionManagementCallbacks* find_callbacks(uint16_t handle) { 144 auto connection = acl_connections_.find(handle); 145 if (connection == acl_connections_.end()) return nullptr; 146 return connection->second.connection_management_callbacks_; 147 } find_callbacksclassic_impl::__anonc961774d0108148 ConnectionManagementCallbacks* find_callbacks(const Address& address) { 149 for (auto& connection_pair : acl_connections_) { 150 if (connection_pair.second.address_with_type_.GetAddress() == address) { 151 return connection_pair.second.connection_management_callbacks_; 152 } 153 } 154 return nullptr; 155 } removeclassic_impl::__anonc961774d0108156 void remove(uint16_t handle) { 157 auto connection = acl_connections_.find(handle); 158 if (connection != acl_connections_.end()) { 159 connection->second.connection_management_callbacks_ = nullptr; 160 acl_connections_.erase(handle); 161 } 162 } 163 164 public: 165 bool crash_on_unknown_handle_ = false; is_emptyclassic_impl::__anonc961774d0108166 bool is_empty() const { 167 std::unique_lock<std::mutex> lock(acl_connections_guard_); 168 return acl_connections_.empty(); 169 } resetclassic_impl::__anonc961774d0108170 void reset() { 171 std::unique_lock<std::mutex> lock(acl_connections_guard_); 172 acl_connections_.clear(); 173 } invalidateclassic_impl::__anonc961774d0108174 void invalidate(uint16_t handle) { 175 std::unique_lock<std::mutex> lock(acl_connections_guard_); 176 remove(handle); 177 } 178 void execute( 179 uint16_t handle, 180 std::function<void(ConnectionManagementCallbacks* callbacks)> execute, 181 bool remove_afterwards = false) { 182 std::unique_lock<std::mutex> lock(acl_connections_guard_); 183 auto callbacks = find_callbacks(handle); 184 if (callbacks != nullptr) 185 execute(callbacks); 186 else 187 log::assert_that( 188 !crash_on_unknown_handle_, "Received command for unknown handle:0x{:x}", handle); 189 if (remove_afterwards) remove(handle); 190 } executeclassic_impl::__anonc961774d0108191 void execute(const Address& address, std::function<void(ConnectionManagementCallbacks* callbacks)> execute) { 192 std::unique_lock<std::mutex> lock(acl_connections_guard_); 193 auto callbacks = find_callbacks(address); 194 if (callbacks != nullptr) execute(callbacks); 195 } send_packet_upwardclassic_impl::__anonc961774d0108196 bool send_packet_upward(uint16_t handle, std::function<void(struct acl_manager::assembler* assembler)> cb) { 197 std::unique_lock<std::mutex> lock(acl_connections_guard_); 198 auto connection = acl_connections_.find(handle); 199 if (connection != acl_connections_.end()) cb(connection->second.assembler_); 200 return connection != acl_connections_.end(); 201 } addclassic_impl::__anonc961774d0108202 void add( 203 uint16_t handle, 204 const AddressWithType& remote_address, 205 AclConnection::QueueDownEnd* queue_end, 206 os::Handler* handler, 207 ConnectionManagementCallbacks* connection_management_callbacks) { 208 std::unique_lock<std::mutex> lock(acl_connections_guard_); 209 auto emplace_pair = acl_connections_.emplace( 210 std::piecewise_construct, 211 std::forward_as_tuple(handle), 212 std::forward_as_tuple(remote_address, queue_end, handler)); 213 log::assert_that( 214 emplace_pair.second, 215 "assert failed: emplace_pair.second"); // Make sure the connection is unique 216 emplace_pair.first->second.connection_management_callbacks_ = connection_management_callbacks; 217 } HACK_get_handleclassic_impl::__anonc961774d0108218 uint16_t HACK_get_handle(const Address& address) const { 219 std::unique_lock<std::mutex> lock(acl_connections_guard_); 220 for (auto it = acl_connections_.begin(); it != acl_connections_.end(); it++) { 221 if (it->second.address_with_type_.GetAddress() == address) { 222 return it->first; 223 } 224 } 225 return kIllegalConnectionHandle; 226 } get_addressclassic_impl::__anonc961774d0108227 Address get_address(uint16_t handle) const { 228 std::unique_lock<std::mutex> lock(acl_connections_guard_); 229 auto connection = acl_connections_.find(handle); 230 if (connection == acl_connections_.end()) { 231 return Address::kEmpty; 232 } 233 return connection->second.address_with_type_.GetAddress(); 234 } is_classic_link_already_connectedclassic_impl::__anonc961774d0108235 bool is_classic_link_already_connected(const Address& address) const { 236 std::unique_lock<std::mutex> lock(acl_connections_guard_); 237 for (const auto& connection : acl_connections_) { 238 if (connection.second.address_with_type_.GetAddress() == address) { 239 return true; 240 } 241 } 242 return false; 243 } 244 } connections; 245 246 public: send_packet_upwardclassic_impl247 bool send_packet_upward(uint16_t handle, std::function<void(struct acl_manager::assembler* assembler)> cb) { 248 return connections.send_packet_upward(handle, cb); 249 } 250 on_incoming_connectionclassic_impl251 void on_incoming_connection(Address address, ClassOfDevice cod) { 252 if (client_callbacks_ == nullptr) { 253 log::error("No callbacks to call"); 254 auto reason = RejectConnectionReason::LIMITED_RESOURCES; 255 this->reject_connection(RejectConnectionRequestBuilder::Create(address, reason)); 256 return; 257 } 258 259 client_handler_->CallOn( 260 client_callbacks_, &ConnectionCallbacks::OnConnectRequest, address, cod); 261 262 acl_scheduler_->RegisterPendingIncomingConnection(address); 263 264 if (is_classic_link_already_connected(address)) { 265 auto reason = RejectConnectionReason::UNACCEPTABLE_BD_ADDR; 266 this->reject_connection(RejectConnectionRequestBuilder::Create(address, reason)); 267 } else if (should_accept_connection_.Run(address, cod)) { 268 this->accept_connection(address); 269 } else { 270 auto reason = RejectConnectionReason::LIMITED_RESOURCES; // TODO: determine reason 271 this->reject_connection(RejectConnectionRequestBuilder::Create(address, reason)); 272 } 273 } 274 is_classic_link_already_connectedclassic_impl275 bool is_classic_link_already_connected(Address address) { 276 return connections.is_classic_link_already_connected(address); 277 } 278 create_connectionclassic_impl279 void create_connection(Address address) { 280 // TODO: Configure default connection parameters? 281 uint16_t packet_type = 0x4408 /* DM 1,3,5 */ | 0x8810 /*DH 1,3,5 */; 282 PageScanRepetitionMode page_scan_repetition_mode = PageScanRepetitionMode::R1; 283 uint16_t clock_offset = 0; 284 ClockOffsetValid clock_offset_valid = ClockOffsetValid::INVALID; 285 CreateConnectionRoleSwitch allow_role_switch = CreateConnectionRoleSwitch::ALLOW_ROLE_SWITCH; 286 log::assert_that(client_callbacks_ != nullptr, "assert failed: client_callbacks_ != nullptr"); 287 std::unique_ptr<CreateConnectionBuilder> packet = CreateConnectionBuilder::Create( 288 address, packet_type, page_scan_repetition_mode, clock_offset, clock_offset_valid, allow_role_switch); 289 290 acl_scheduler_->EnqueueOutgoingAclConnection( 291 address, handler_->BindOnceOn(this, &classic_impl::actually_create_connection, address, std::move(packet))); 292 } 293 actually_create_connectionclassic_impl294 void actually_create_connection(Address address, std::unique_ptr<CreateConnectionBuilder> packet) { 295 if (is_classic_link_already_connected(address)) { 296 log::warn("already connected: {}", address); 297 acl_scheduler_->ReportOutgoingAclConnectionFailure(); 298 return; 299 } 300 acl_connection_interface_->EnqueueCommand( 301 std::move(packet), handler_->BindOnceOn(this, &classic_impl::on_create_connection_status, address)); 302 } 303 on_create_connection_statusclassic_impl304 void on_create_connection_status(Address address, CommandStatusView status) { 305 log::assert_that(status.IsValid(), "assert failed: status.IsValid()"); 306 log::assert_that( 307 status.GetCommandOpCode() == OpCode::CREATE_CONNECTION, 308 "assert failed: status.GetCommandOpCode() == OpCode::CREATE_CONNECTION"); 309 if (status.GetStatus() != hci::ErrorCode::SUCCESS /* = pending */) { 310 // something went wrong, but unblock queue and report to caller 311 log::error("Failed to create connection, reporting failure and continuing"); 312 log::assert_that(client_callbacks_ != nullptr, "assert failed: client_callbacks_ != nullptr"); 313 client_handler_->Post(common::BindOnce( 314 &ConnectionCallbacks::OnConnectFail, 315 common::Unretained(client_callbacks_), 316 address, 317 status.GetStatus(), 318 true /* locally initiated */)); 319 acl_scheduler_->ReportOutgoingAclConnectionFailure(); 320 } else { 321 // everything is good, resume when a connection_complete event arrives 322 return; 323 } 324 } 325 326 enum class Initiator { 327 LOCALLY_INITIATED, 328 REMOTE_INITIATED, 329 }; 330 create_and_announce_connectionclassic_impl331 void create_and_announce_connection( 332 ConnectionCompleteView connection_complete, Role current_role, Initiator initiator) { 333 auto status = connection_complete.GetStatus(); 334 auto address = connection_complete.GetBdAddr(); 335 if (client_callbacks_ == nullptr) { 336 log::warn("No client callbacks registered for connection"); 337 return; 338 } 339 if (status != ErrorCode::SUCCESS) { 340 client_handler_->Post(common::BindOnce( 341 &ConnectionCallbacks::OnConnectFail, 342 common::Unretained(client_callbacks_), 343 address, 344 status, 345 initiator == Initiator::LOCALLY_INITIATED)); 346 return; 347 } 348 uint16_t handle = connection_complete.GetConnectionHandle(); 349 auto queue = std::make_shared<AclConnection::Queue>(10); 350 auto queue_down_end = queue->GetDownEnd(); 351 round_robin_scheduler_->Register(RoundRobinScheduler::ConnectionType::CLASSIC, handle, queue); 352 std::unique_ptr<ClassicAclConnection> connection( 353 new ClassicAclConnection(std::move(queue), acl_connection_interface_, handle, address)); 354 connection->locally_initiated_ = initiator == Initiator::LOCALLY_INITIATED; 355 connections.add( 356 handle, 357 AddressWithType{address, AddressType::PUBLIC_DEVICE_ADDRESS}, 358 queue_down_end, 359 handler_, 360 connection->GetEventCallbacks([this](uint16_t handle) { this->connections.invalidate(handle); })); 361 connections.execute(address, [=, this](ConnectionManagementCallbacks* callbacks) { 362 if (delayed_role_change_ == nullptr) { 363 callbacks->OnRoleChange(hci::ErrorCode::SUCCESS, current_role); 364 } else if (delayed_role_change_->GetBdAddr() == address) { 365 log::info("Sending delayed role change for {}", delayed_role_change_->GetBdAddr()); 366 callbacks->OnRoleChange(delayed_role_change_->GetStatus(), delayed_role_change_->GetNewRole()); 367 delayed_role_change_.reset(); 368 } 369 }); 370 client_handler_->Post(common::BindOnce( 371 &ConnectionCallbacks::OnConnectSuccess, common::Unretained(client_callbacks_), std::move(connection))); 372 } 373 on_connection_completeclassic_impl374 void on_connection_complete(EventView packet) { 375 ConnectionCompleteView connection_complete = ConnectionCompleteView::Create(packet); 376 log::assert_that(connection_complete.IsValid(), "assert failed: connection_complete.IsValid()"); 377 auto status = connection_complete.GetStatus(); 378 auto address = connection_complete.GetBdAddr(); 379 380 acl_scheduler_->ReportAclConnectionCompletion( 381 address, 382 handler_->BindOnceOn( 383 this, 384 &classic_impl::create_and_announce_connection, 385 connection_complete, 386 Role::CENTRAL, 387 Initiator::LOCALLY_INITIATED), 388 handler_->BindOnceOn( 389 this, 390 &classic_impl::create_and_announce_connection, 391 connection_complete, 392 Role::PERIPHERAL, 393 Initiator::REMOTE_INITIATED), 394 handler_->BindOnce( 395 [=](RemoteNameRequestModule* remote_name_request_module, 396 Address address, 397 ErrorCode status, 398 std::string valid_incoming_addresses) { 399 log::warn("No matching connection to {} ({})", address, ErrorCodeText(status)); 400 log::assert_that( 401 status != ErrorCode::SUCCESS, 402 "No prior connection request for {} expecting:{}", 403 address, 404 valid_incoming_addresses.c_str()); 405 remote_name_request_module->ReportRemoteNameRequestCancellation(address); 406 }, 407 common::Unretained(remote_name_request_module_), 408 address, 409 status)); 410 } 411 cancel_connectclassic_impl412 void cancel_connect(Address address) { 413 acl_scheduler_->CancelAclConnection( 414 address, 415 handler_->BindOnceOn(this, &classic_impl::actually_cancel_connect, address), 416 client_handler_->BindOnceOn( 417 client_callbacks_, 418 &ConnectionCallbacks::OnConnectFail, 419 address, 420 ErrorCode::UNKNOWN_CONNECTION, 421 true /* locally initiated */)); 422 } 423 actually_cancel_connectclassic_impl424 void actually_cancel_connect(Address address) { 425 std::unique_ptr<CreateConnectionCancelBuilder> packet = CreateConnectionCancelBuilder::Create(address); 426 acl_connection_interface_->EnqueueCommand( 427 std::move(packet), handler_->BindOnce(check_complete<CreateConnectionCancelCompleteView>)); 428 } 429 430 static constexpr bool kRemoveConnectionAfterwards = true; on_classic_disconnectclassic_impl431 void on_classic_disconnect(uint16_t handle, ErrorCode reason) { 432 bool event_also_routes_to_other_receivers = connections.crash_on_unknown_handle_; 433 bluetooth::os::LogMetricBluetoothDisconnectionReasonReported( 434 static_cast<uint32_t>(reason), connections.get_address(handle), handle); 435 connections.crash_on_unknown_handle_ = false; 436 connections.execute( 437 handle, 438 [=, this](ConnectionManagementCallbacks* callbacks) { 439 round_robin_scheduler_->Unregister(handle); 440 callbacks->OnDisconnection(reason); 441 }, 442 kRemoveConnectionAfterwards); 443 connections.crash_on_unknown_handle_ = event_also_routes_to_other_receivers; 444 } 445 on_connection_packet_type_changedclassic_impl446 void on_connection_packet_type_changed(EventView packet) { 447 ConnectionPacketTypeChangedView packet_type_changed = ConnectionPacketTypeChangedView::Create(packet); 448 if (!packet_type_changed.IsValid()) { 449 log::error("Received on_connection_packet_type_changed with invalid packet"); 450 return; 451 } else if (packet_type_changed.GetStatus() != ErrorCode::SUCCESS) { 452 auto status = packet_type_changed.GetStatus(); 453 std::string error_code = ErrorCodeText(status); 454 log::error("Received on_connection_packet_type_changed with error code {}", error_code); 455 return; 456 } 457 uint16_t handle = packet_type_changed.GetConnectionHandle(); 458 connections.execute(handle, [=](ConnectionManagementCallbacks* /* callbacks */) { 459 // We don't handle this event; we didn't do this in legacy stack either. 460 }); 461 } 462 on_central_link_key_completeclassic_impl463 void on_central_link_key_complete(EventView packet) { 464 CentralLinkKeyCompleteView complete_view = CentralLinkKeyCompleteView::Create(packet); 465 if (!complete_view.IsValid()) { 466 log::error("Received on_central_link_key_complete with invalid packet"); 467 return; 468 } else if (complete_view.GetStatus() != ErrorCode::SUCCESS) { 469 auto status = complete_view.GetStatus(); 470 std::string error_code = ErrorCodeText(status); 471 log::error("Received on_central_link_key_complete with error code {}", error_code); 472 return; 473 } 474 uint16_t handle = complete_view.GetConnectionHandle(); 475 connections.execute(handle, [=](ConnectionManagementCallbacks* callbacks) { 476 KeyFlag key_flag = complete_view.GetKeyFlag(); 477 callbacks->OnCentralLinkKeyComplete(key_flag); 478 }); 479 } 480 on_authentication_completeclassic_impl481 void on_authentication_complete(EventView packet) { 482 AuthenticationCompleteView authentication_complete = AuthenticationCompleteView::Create(packet); 483 if (!authentication_complete.IsValid()) { 484 log::error("Received on_authentication_complete with invalid packet"); 485 return; 486 } 487 uint16_t handle = authentication_complete.GetConnectionHandle(); 488 connections.execute(handle, [=](ConnectionManagementCallbacks* callbacks) { 489 callbacks->OnAuthenticationComplete(authentication_complete.GetStatus()); 490 }); 491 } 492 on_change_connection_link_key_completeclassic_impl493 void on_change_connection_link_key_complete(EventView packet) { 494 ChangeConnectionLinkKeyCompleteView complete_view = ChangeConnectionLinkKeyCompleteView::Create(packet); 495 if (!complete_view.IsValid()) { 496 log::error("Received on_change_connection_link_key_complete with invalid packet"); 497 return; 498 } else if (complete_view.GetStatus() != ErrorCode::SUCCESS) { 499 auto status = complete_view.GetStatus(); 500 std::string error_code = ErrorCodeText(status); 501 log::error("Received on_change_connection_link_key_complete with error code {}", error_code); 502 return; 503 } 504 uint16_t handle = complete_view.GetConnectionHandle(); 505 connections.execute( 506 handle, [=](ConnectionManagementCallbacks* callbacks) { callbacks->OnChangeConnectionLinkKeyComplete(); }); 507 } 508 on_read_clock_offset_completeclassic_impl509 void on_read_clock_offset_complete(EventView packet) { 510 ReadClockOffsetCompleteView complete_view = ReadClockOffsetCompleteView::Create(packet); 511 if (!complete_view.IsValid()) { 512 log::error("Received on_read_clock_offset_complete with invalid packet"); 513 return; 514 } else if (complete_view.GetStatus() != ErrorCode::SUCCESS) { 515 auto status = complete_view.GetStatus(); 516 std::string error_code = ErrorCodeText(status); 517 log::error("Received on_read_clock_offset_complete with error code {}", error_code); 518 return; 519 } 520 uint16_t handle = complete_view.GetConnectionHandle(); 521 connections.execute(handle, [=](ConnectionManagementCallbacks* callbacks) { 522 uint16_t clock_offset = complete_view.GetClockOffset(); 523 callbacks->OnReadClockOffsetComplete(clock_offset); 524 }); 525 } 526 on_mode_changeclassic_impl527 void on_mode_change(EventView packet) { 528 ModeChangeView mode_change_view = ModeChangeView::Create(packet); 529 if (!mode_change_view.IsValid()) { 530 log::error("Received on_mode_change with invalid packet"); 531 return; 532 } 533 uint16_t handle = mode_change_view.GetConnectionHandle(); 534 connections.execute(handle, [=](ConnectionManagementCallbacks* callbacks) { 535 callbacks->OnModeChange( 536 mode_change_view.GetStatus(), mode_change_view.GetCurrentMode(), mode_change_view.GetInterval()); 537 }); 538 } 539 on_sniff_subratingclassic_impl540 void on_sniff_subrating(EventView packet) { 541 SniffSubratingEventView sniff_subrating_view = SniffSubratingEventView::Create(packet); 542 if (!sniff_subrating_view.IsValid()) { 543 log::error("Received on_sniff_subrating with invalid packet"); 544 return; 545 } 546 uint16_t handle = sniff_subrating_view.GetConnectionHandle(); 547 connections.execute(handle, [=](ConnectionManagementCallbacks* callbacks) { 548 callbacks->OnSniffSubrating( 549 sniff_subrating_view.GetStatus(), 550 sniff_subrating_view.GetMaximumTransmitLatency(), 551 sniff_subrating_view.GetMaximumReceiveLatency(), 552 sniff_subrating_view.GetMinimumRemoteTimeout(), 553 sniff_subrating_view.GetMinimumLocalTimeout()); 554 }); 555 } 556 on_qos_setup_completeclassic_impl557 void on_qos_setup_complete(EventView packet) { 558 QosSetupCompleteView complete_view = QosSetupCompleteView::Create(packet); 559 if (!complete_view.IsValid()) { 560 log::error("Received on_qos_setup_complete with invalid packet"); 561 return; 562 } else if (complete_view.GetStatus() != ErrorCode::SUCCESS) { 563 auto status = complete_view.GetStatus(); 564 std::string error_code = ErrorCodeText(status); 565 log::error("Received on_qos_setup_complete with error code {}", error_code); 566 return; 567 } 568 uint16_t handle = complete_view.GetConnectionHandle(); 569 connections.execute(handle, [=](ConnectionManagementCallbacks* callbacks) { 570 ServiceType service_type = complete_view.GetServiceType(); 571 uint32_t token_rate = complete_view.GetTokenRate(); 572 uint32_t peak_bandwidth = complete_view.GetPeakBandwidth(); 573 uint32_t latency = complete_view.GetLatency(); 574 uint32_t delay_variation = complete_view.GetDelayVariation(); 575 callbacks->OnQosSetupComplete(service_type, token_rate, peak_bandwidth, latency, delay_variation); 576 }); 577 } 578 on_flow_specification_completeclassic_impl579 void on_flow_specification_complete(EventView packet) { 580 FlowSpecificationCompleteView complete_view = FlowSpecificationCompleteView::Create(packet); 581 if (!complete_view.IsValid()) { 582 log::error("Received on_flow_specification_complete with invalid packet"); 583 return; 584 } else if (complete_view.GetStatus() != ErrorCode::SUCCESS) { 585 auto status = complete_view.GetStatus(); 586 std::string error_code = ErrorCodeText(status); 587 log::error("Received on_flow_specification_complete with error code {}", error_code); 588 return; 589 } 590 uint16_t handle = complete_view.GetConnectionHandle(); 591 connections.execute(handle, [=](ConnectionManagementCallbacks* callbacks) { 592 FlowDirection flow_direction = complete_view.GetFlowDirection(); 593 ServiceType service_type = complete_view.GetServiceType(); 594 uint32_t token_rate = complete_view.GetTokenRate(); 595 uint32_t token_bucket_size = complete_view.GetTokenBucketSize(); 596 uint32_t peak_bandwidth = complete_view.GetPeakBandwidth(); 597 uint32_t access_latency = complete_view.GetAccessLatency(); 598 callbacks->OnFlowSpecificationComplete( 599 flow_direction, service_type, token_rate, token_bucket_size, peak_bandwidth, access_latency); 600 }); 601 } 602 on_flush_occurredclassic_impl603 void on_flush_occurred(EventView packet) { 604 FlushOccurredView flush_occurred_view = FlushOccurredView::Create(packet); 605 if (!flush_occurred_view.IsValid()) { 606 log::error("Received on_flush_occurred with invalid packet"); 607 return; 608 } 609 uint16_t handle = flush_occurred_view.GetConnectionHandle(); 610 connections.execute(handle, [=](ConnectionManagementCallbacks* callbacks) { callbacks->OnFlushOccurred(); }); 611 } 612 on_enhanced_flush_completeclassic_impl613 void on_enhanced_flush_complete(EventView packet) { 614 auto flush_complete = EnhancedFlushCompleteView::Create(packet); 615 if (!flush_complete.IsValid()) { 616 log::error("Received an invalid packet"); 617 return; 618 } 619 uint16_t handle = flush_complete.GetConnectionHandle(); 620 connections.execute( 621 handle, [](ConnectionManagementCallbacks* callbacks) { callbacks->OnFlushOccurred(); }); 622 } 623 on_read_remote_version_informationclassic_impl624 void on_read_remote_version_information( 625 hci::ErrorCode hci_status, uint16_t handle, uint8_t version, uint16_t manufacturer_name, uint16_t sub_version) { 626 connections.execute(handle, [=](ConnectionManagementCallbacks* callbacks) { 627 callbacks->OnReadRemoteVersionInformationComplete(hci_status, version, manufacturer_name, sub_version); 628 }); 629 } 630 on_read_remote_supported_features_completeclassic_impl631 void on_read_remote_supported_features_complete(EventView packet) { 632 auto view = ReadRemoteSupportedFeaturesCompleteView::Create(packet); 633 log::assert_that(view.IsValid(), "Read remote supported features packet invalid"); 634 uint16_t handle = view.GetConnectionHandle(); 635 bluetooth::os::LogMetricBluetoothRemoteSupportedFeatures( 636 connections.get_address(handle), 0, view.GetLmpFeatures(), handle); 637 connections.execute(handle, [=](ConnectionManagementCallbacks* callbacks) { 638 callbacks->OnReadRemoteSupportedFeaturesComplete(view.GetLmpFeatures()); 639 }); 640 } 641 on_read_remote_extended_features_completeclassic_impl642 void on_read_remote_extended_features_complete(EventView packet) { 643 auto view = ReadRemoteExtendedFeaturesCompleteView::Create(packet); 644 log::assert_that(view.IsValid(), "Read remote extended features packet invalid"); 645 uint16_t handle = view.GetConnectionHandle(); 646 bluetooth::os::LogMetricBluetoothRemoteSupportedFeatures( 647 connections.get_address(handle), view.GetPageNumber(), view.GetExtendedLmpFeatures(), handle); 648 connections.execute(handle, [=](ConnectionManagementCallbacks* callbacks) { 649 callbacks->OnReadRemoteExtendedFeaturesComplete( 650 view.GetPageNumber(), view.GetMaximumPageNumber(), view.GetExtendedLmpFeatures()); 651 }); 652 } 653 on_role_changeclassic_impl654 void on_role_change(EventView packet) { 655 RoleChangeView role_change_view = RoleChangeView::Create(packet); 656 if (!role_change_view.IsValid()) { 657 log::error("Received on_role_change with invalid packet"); 658 return; 659 } 660 auto hci_status = role_change_view.GetStatus(); 661 Address bd_addr = role_change_view.GetBdAddr(); 662 Role new_role = role_change_view.GetNewRole(); 663 bool sent = false; 664 connections.execute(bd_addr, [=, &sent](ConnectionManagementCallbacks* callbacks) { 665 if (callbacks != nullptr) { 666 callbacks->OnRoleChange(hci_status, new_role); 667 sent = true; 668 } 669 }); 670 if (!sent) { 671 if (delayed_role_change_ != nullptr) { 672 log::warn("Second delayed role change (@{} dropped)", delayed_role_change_->GetBdAddr()); 673 } 674 log::info( 675 "Role change for {} with no matching connection (new role: {})", 676 role_change_view.GetBdAddr(), 677 RoleText(role_change_view.GetNewRole())); 678 delayed_role_change_ = std::make_unique<RoleChangeView>(role_change_view); 679 } 680 } 681 on_link_supervision_timeout_changedclassic_impl682 void on_link_supervision_timeout_changed(EventView packet) { 683 auto view = LinkSupervisionTimeoutChangedView::Create(packet); 684 log::assert_that(view.IsValid(), "Link supervision timeout changed packet invalid"); 685 log::info("UNIMPLEMENTED called"); 686 } 687 on_accept_connection_statusclassic_impl688 void on_accept_connection_status(Address address, CommandStatusView status) { 689 auto accept_status = AcceptConnectionRequestStatusView::Create(status); 690 log::assert_that(accept_status.IsValid(), "assert failed: accept_status.IsValid()"); 691 if (status.GetStatus() != ErrorCode::SUCCESS) { 692 cancel_connect(address); 693 } 694 } 695 central_link_keyclassic_impl696 void central_link_key(KeyFlag key_flag) { 697 std::unique_ptr<CentralLinkKeyBuilder> packet = CentralLinkKeyBuilder::Create(key_flag); 698 acl_connection_interface_->EnqueueCommand( 699 std::move(packet), handler_->BindOnce(check_status<CentralLinkKeyStatusView>)); 700 } 701 switch_roleclassic_impl702 void switch_role(Address address, Role role) { 703 std::unique_ptr<SwitchRoleBuilder> packet = SwitchRoleBuilder::Create(address, role); 704 acl_connection_interface_->EnqueueCommand( 705 std::move(packet), handler_->BindOnce(check_status<SwitchRoleStatusView>)); 706 } 707 write_default_link_policy_settingsclassic_impl708 void write_default_link_policy_settings(uint16_t default_link_policy_settings) { 709 std::unique_ptr<WriteDefaultLinkPolicySettingsBuilder> packet = 710 WriteDefaultLinkPolicySettingsBuilder::Create(default_link_policy_settings); 711 acl_connection_interface_->EnqueueCommand( 712 std::move(packet), 713 handler_->BindOnce(check_complete<WriteDefaultLinkPolicySettingsCompleteView>)); 714 } 715 accept_connectionclassic_impl716 void accept_connection(Address address) { 717 auto role = AcceptConnectionRequestRole::BECOME_CENTRAL; // We prefer to be central 718 acl_connection_interface_->EnqueueCommand( 719 AcceptConnectionRequestBuilder::Create(address, role), 720 handler_->BindOnceOn(this, &classic_impl::on_accept_connection_status, address)); 721 } 722 reject_connectionclassic_impl723 void reject_connection(std::unique_ptr<RejectConnectionRequestBuilder> builder) { 724 acl_connection_interface_->EnqueueCommand( 725 std::move(builder), handler_->BindOnce(check_status<RejectConnectionRequestStatusView>)); 726 } 727 HACK_get_handleclassic_impl728 uint16_t HACK_get_handle(Address address) { 729 return connections.HACK_get_handle(address); 730 } 731 handle_register_callbacksclassic_impl732 void handle_register_callbacks(ConnectionCallbacks* callbacks, os::Handler* handler) { 733 log::assert_that(client_callbacks_ == nullptr, "assert failed: client_callbacks_ == nullptr"); 734 log::assert_that(client_handler_ == nullptr, "assert failed: client_handler_ == nullptr"); 735 client_callbacks_ = callbacks; 736 client_handler_ = handler; 737 } 738 handle_unregister_callbacksclassic_impl739 void handle_unregister_callbacks(ConnectionCallbacks* callbacks, std::promise<void> promise) { 740 log::assert_that( 741 client_callbacks_ == callbacks, 742 "Registered callback entity is different then unregister request"); 743 client_callbacks_ = nullptr; 744 client_handler_ = nullptr; 745 promise.set_value(); 746 } 747 748 HciLayer* hci_layer_ = nullptr; 749 Controller* controller_ = nullptr; 750 RoundRobinScheduler* round_robin_scheduler_ = nullptr; 751 AclScheduler* acl_scheduler_ = nullptr; 752 RemoteNameRequestModule* remote_name_request_module_ = nullptr; 753 AclConnectionInterface* acl_connection_interface_ = nullptr; 754 os::Handler* handler_ = nullptr; 755 ConnectionCallbacks* client_callbacks_ = nullptr; 756 os::Handler* client_handler_ = nullptr; 757 758 common::Callback<bool(Address, ClassOfDevice)> should_accept_connection_; 759 std::unique_ptr<RoleChangeView> delayed_role_change_ = nullptr; 760 }; 761 762 } // namespace acl_manager 763 } // namespace hci 764 } // namespace bluetooth 765