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 "common/bind.h" 20 #include "crypto_toolbox/crypto_toolbox.h" 21 #include "hci/acl_manager/assembler.h" 22 #include "hci/acl_manager/round_robin_scheduler.h" 23 #include "hci/le_address_manager.h" 24 #include "os/alarm.h" 25 #include "os/rand.h" 26 27 using bluetooth::crypto_toolbox::Octet16; 28 29 namespace bluetooth { 30 namespace hci { 31 namespace acl_manager { 32 33 using common::BindOnce; 34 35 constexpr uint16_t kScanIntervalFast = 0x0060; 36 constexpr uint16_t kScanWindowFast = 0x0030; 37 constexpr uint16_t kScanIntervalSlow = 0x0800; 38 constexpr uint16_t kScanWindowSlow = 0x0030; 39 constexpr std::chrono::milliseconds kCreateConnectionTimeoutMs = std::chrono::milliseconds(30 * 1000); 40 41 struct le_acl_connection { le_acl_connectionle_acl_connection42 le_acl_connection(AddressWithType remote_address, AclConnection::QueueDownEnd* queue_down_end, os::Handler* handler) 43 : assembler_(remote_address, queue_down_end, handler), remote_address_(remote_address) {} 44 ~le_acl_connection() = default; 45 struct acl_manager::assembler assembler_; 46 AddressWithType remote_address_; 47 LeConnectionManagementCallbacks* le_connection_management_callbacks_ = nullptr; 48 }; 49 50 struct le_impl : public bluetooth::hci::LeAddressManagerCallback { le_implle_impl51 le_impl( 52 HciLayer* hci_layer, 53 Controller* controller, 54 os::Handler* handler, 55 RoundRobinScheduler* round_robin_scheduler, 56 bool crash_on_unknown_handle) 57 : hci_layer_(hci_layer), 58 controller_(controller), 59 round_robin_scheduler_(round_robin_scheduler), 60 crash_on_unknown_handle_(crash_on_unknown_handle) { 61 hci_layer_ = hci_layer; 62 controller_ = controller; 63 handler_ = handler; 64 le_acl_connection_interface_ = hci_layer_->GetLeAclConnectionInterface( 65 handler_->BindOn(this, &le_impl::on_le_event), 66 handler_->BindOn(this, &le_impl::on_le_disconnect), 67 handler_->BindOn(this, &le_impl::on_le_read_remote_version_information)); 68 le_address_manager_ = new LeAddressManager( 69 common::Bind(&le_impl::enqueue_command, common::Unretained(this)), 70 handler_, 71 controller->GetMacAddress(), 72 controller->GetLeConnectListSize(), 73 controller->GetLeResolvingListSize()); 74 } 75 ~le_implle_impl76 ~le_impl() { 77 for (auto subevent_code : LeConnectionManagementEvents) { 78 hci_layer_->UnregisterLeEventHandler(subevent_code); 79 } 80 if (address_manager_registered) { 81 le_address_manager_->Unregister(this); 82 } 83 delete le_address_manager_; 84 le_acl_connections_.clear(); 85 } 86 on_le_eventle_impl87 void on_le_event(LeMetaEventView event_packet) { 88 SubeventCode code = event_packet.GetSubeventCode(); 89 switch (code) { 90 case SubeventCode::CONNECTION_COMPLETE: 91 on_le_connection_complete(event_packet); 92 break; 93 case SubeventCode::ENHANCED_CONNECTION_COMPLETE: 94 on_le_enhanced_connection_complete(event_packet); 95 break; 96 case SubeventCode::CONNECTION_UPDATE_COMPLETE: 97 on_le_connection_update_complete(event_packet); 98 break; 99 case SubeventCode::PHY_UPDATE_COMPLETE: 100 on_le_phy_update_complete(event_packet); 101 break; 102 case SubeventCode::DATA_LENGTH_CHANGE: 103 on_data_length_change(event_packet); 104 break; 105 case SubeventCode::REMOTE_CONNECTION_PARAMETER_REQUEST: 106 on_remote_connection_parameter_request(event_packet); 107 break; 108 default: 109 LOG_ALWAYS_FATAL("Unhandled event code %s", SubeventCodeText(code).c_str()); 110 } 111 } 112 get_callbacksle_impl113 LeConnectionManagementCallbacks* get_callbacks(uint16_t handle) { 114 auto connection = le_acl_connections_.find(handle); 115 if (connection == le_acl_connections_.end()) { 116 return nullptr; 117 } 118 return connection->second.le_connection_management_callbacks_; 119 } 120 on_le_disconnectle_impl121 void on_le_disconnect(uint16_t handle, ErrorCode reason) { 122 auto callbacks = get_callbacks(handle); 123 if (callbacks == nullptr) { 124 return; 125 } 126 round_robin_scheduler_->Unregister(handle); 127 callbacks->OnDisconnection(reason); 128 le_acl_connections_.erase(handle); 129 } 130 on_common_le_connection_completele_impl131 void on_common_le_connection_complete(AddressWithType address_with_type) { 132 auto connecting_addr_with_type = connecting_le_.find(address_with_type); 133 if (connecting_addr_with_type == connecting_le_.end()) { 134 LOG_WARN("No prior connection request for %s", address_with_type.ToString().c_str()); 135 } else { 136 connecting_le_.erase(connecting_addr_with_type); 137 } 138 if (create_connection_timeout_alarms_.find(address_with_type) != create_connection_timeout_alarms_.end()) { 139 create_connection_timeout_alarms_.at(address_with_type).Cancel(); 140 create_connection_timeout_alarms_.erase(address_with_type); 141 } 142 } 143 on_le_connection_completele_impl144 void on_le_connection_complete(LeMetaEventView packet) { 145 LeConnectionCompleteView connection_complete = LeConnectionCompleteView::Create(packet); 146 ASSERT(connection_complete.IsValid()); 147 auto status = connection_complete.GetStatus(); 148 auto address = connection_complete.GetPeerAddress(); 149 auto peer_address_type = connection_complete.GetPeerAddressType(); 150 // TODO: find out which address and type was used to initiate the connection 151 AddressWithType remote_address(address, peer_address_type); 152 AddressWithType local_address = le_address_manager_->GetCurrentAddress(); 153 on_common_le_connection_complete(remote_address); 154 if (status == ErrorCode::UNKNOWN_CONNECTION && pause_connection) { 155 // connection canceled by LeAddressManager.OnPause(), will auto reconnect by LeAddressManager.OnResume() 156 return; 157 } else { 158 canceled_connections_.erase(remote_address); 159 ready_to_unregister = true; 160 remove_device_from_connect_list(remote_address); 161 } 162 163 if (le_client_handler_ == nullptr) { 164 LOG_ERROR("No callbacks to call"); 165 return; 166 } 167 168 if (status != ErrorCode::SUCCESS) { 169 le_client_handler_->Post(common::BindOnce(&LeConnectionCallbacks::OnLeConnectFail, 170 common::Unretained(le_client_callbacks_), remote_address, status)); 171 return; 172 } 173 174 uint16_t conn_interval = connection_complete.GetConnInterval(); 175 uint16_t conn_latency = connection_complete.GetConnLatency(); 176 uint16_t supervision_timeout = connection_complete.GetSupervisionTimeout(); 177 if (!check_connection_parameters(conn_interval, conn_interval, conn_latency, supervision_timeout)) { 178 LOG_ERROR("Receive connection complete with invalid connection parameters"); 179 return; 180 } 181 182 auto role = connection_complete.GetRole(); 183 uint16_t handle = connection_complete.GetConnectionHandle(); 184 auto queue = std::make_shared<AclConnection::Queue>(10); 185 auto emplace_pair = le_acl_connections_.emplace( 186 std::piecewise_construct, 187 std::forward_as_tuple(handle), 188 std::forward_as_tuple(remote_address, queue->GetDownEnd(), handler_)); 189 ASSERT(emplace_pair.second); // Make sure the connection is unique 190 auto& connection_proxy = emplace_pair.first->second; 191 round_robin_scheduler_->Register(RoundRobinScheduler::ConnectionType::LE, handle, queue); 192 std::unique_ptr<LeAclConnection> connection(new LeAclConnection( 193 std::move(queue), le_acl_connection_interface_, handle, local_address, remote_address, role)); 194 connection_proxy.le_connection_management_callbacks_ = connection->GetEventCallbacks(); 195 le_client_handler_->Post(common::BindOnce(&LeConnectionCallbacks::OnLeConnectSuccess, 196 common::Unretained(le_client_callbacks_), remote_address, 197 std::move(connection))); 198 } 199 on_le_enhanced_connection_completele_impl200 void on_le_enhanced_connection_complete(LeMetaEventView packet) { 201 LeEnhancedConnectionCompleteView connection_complete = LeEnhancedConnectionCompleteView::Create(packet); 202 ASSERT(connection_complete.IsValid()); 203 auto status = connection_complete.GetStatus(); 204 auto address = connection_complete.GetPeerAddress(); 205 auto peer_address_type = connection_complete.GetPeerAddressType(); 206 auto peer_resolvable_address = connection_complete.GetPeerResolvablePrivateAddress(); 207 AddressWithType remote_address(address, peer_address_type); 208 if (!peer_resolvable_address.IsEmpty()) { 209 remote_address = AddressWithType(peer_resolvable_address, AddressType::RANDOM_DEVICE_ADDRESS); 210 } 211 on_common_le_connection_complete(remote_address); 212 if (status == ErrorCode::UNKNOWN_CONNECTION && pause_connection) { 213 // connection canceled by LeAddressManager.OnPause(), will auto reconnect by LeAddressManager.OnResume() 214 return; 215 } else { 216 canceled_connections_.erase(remote_address); 217 ready_to_unregister = true; 218 remove_device_from_connect_list(remote_address); 219 } 220 221 if (le_client_handler_ == nullptr) { 222 LOG_ERROR("No callbacks to call"); 223 return; 224 } 225 226 if (status != ErrorCode::SUCCESS) { 227 le_client_handler_->Post(common::BindOnce(&LeConnectionCallbacks::OnLeConnectFail, 228 common::Unretained(le_client_callbacks_), remote_address, status)); 229 return; 230 } 231 232 auto role = connection_complete.GetRole(); 233 AddressWithType local_address; 234 if (role == hci::Role::CENTRAL) { 235 local_address = le_address_manager_->GetCurrentAddress(); 236 } else { 237 // when accepting connection, we must obtain the address from the advertiser. 238 // When we receive "set terminated event", we associate connection handle with advertiser address 239 local_address = AddressWithType{}; 240 } 241 242 uint16_t conn_interval = connection_complete.GetConnInterval(); 243 uint16_t conn_latency = connection_complete.GetConnLatency(); 244 uint16_t supervision_timeout = connection_complete.GetSupervisionTimeout(); 245 if (!check_connection_parameters(conn_interval, conn_interval, conn_latency, supervision_timeout)) { 246 LOG_ERROR("Receive enhenced connection complete with invalid connection parameters"); 247 return; 248 } 249 uint16_t handle = connection_complete.GetConnectionHandle(); 250 auto queue = std::make_shared<AclConnection::Queue>(10); 251 auto emplace_pair = le_acl_connections_.emplace( 252 std::piecewise_construct, 253 std::forward_as_tuple(handle), 254 std::forward_as_tuple(remote_address, queue->GetDownEnd(), handler_)); 255 ASSERT(emplace_pair.second); // Make sure it's not a duplicate 256 auto& connection_proxy = emplace_pair.first->second; 257 round_robin_scheduler_->Register(RoundRobinScheduler::ConnectionType::LE, handle, queue); 258 std::unique_ptr<LeAclConnection> connection(new LeAclConnection( 259 std::move(queue), le_acl_connection_interface_, handle, local_address, remote_address, role)); 260 connection_proxy.le_connection_management_callbacks_ = connection->GetEventCallbacks(); 261 le_client_handler_->Post(common::BindOnce(&LeConnectionCallbacks::OnLeConnectSuccess, 262 common::Unretained(le_client_callbacks_), remote_address, 263 std::move(connection))); 264 } 265 on_le_connection_update_completele_impl266 void on_le_connection_update_complete(LeMetaEventView view) { 267 auto complete_view = LeConnectionUpdateCompleteView::Create(view); 268 if (!complete_view.IsValid()) { 269 LOG_ERROR("Received on_le_connection_update_complete with invalid packet"); 270 return; 271 } 272 auto handle = complete_view.GetConnectionHandle(); 273 auto callbacks = get_callbacks(handle); 274 if (callbacks == nullptr) { 275 LOG_WARN("Can't find connection 0x%hx", handle); 276 ASSERT(!crash_on_unknown_handle_); 277 return; 278 } 279 callbacks->OnConnectionUpdate( 280 complete_view.GetStatus(), 281 complete_view.GetConnInterval(), 282 complete_view.GetConnLatency(), 283 complete_view.GetSupervisionTimeout()); 284 } 285 on_le_phy_update_completele_impl286 void on_le_phy_update_complete(LeMetaEventView view) { 287 auto complete_view = LePhyUpdateCompleteView::Create(view); 288 if (!complete_view.IsValid()) { 289 LOG_ERROR("Received on_le_phy_update_complete with invalid packet"); 290 return; 291 } 292 auto handle = complete_view.GetConnectionHandle(); 293 auto callbacks = get_callbacks(handle); 294 if (callbacks == nullptr) { 295 LOG_WARN("Can't find connection 0x%hx", handle); 296 ASSERT(!crash_on_unknown_handle_); 297 return; 298 } 299 callbacks->OnPhyUpdate(complete_view.GetStatus(), complete_view.GetTxPhy(), complete_view.GetRxPhy()); 300 } 301 on_le_read_remote_version_informationle_impl302 void on_le_read_remote_version_information( 303 hci::ErrorCode hci_status, uint16_t handle, uint8_t version, uint16_t manufacturer_name, uint16_t sub_version) { 304 auto callbacks = get_callbacks(handle); 305 if (callbacks == nullptr) { 306 LOG_INFO("No le connection registered for 0x%hx", handle); 307 return; 308 } 309 callbacks->OnReadRemoteVersionInformationComplete(hci_status, version, manufacturer_name, sub_version); 310 } 311 enqueue_commandle_impl312 void enqueue_command(std::unique_ptr<CommandBuilder> command_packet) { 313 hci_layer_->EnqueueCommand( 314 std::move(command_packet), 315 handler_->BindOnce(&LeAddressManager::OnCommandComplete, common::Unretained(le_address_manager_))); 316 } 317 on_data_length_changele_impl318 void on_data_length_change(LeMetaEventView view) { 319 auto data_length_view = LeDataLengthChangeView::Create(view); 320 if (!data_length_view.IsValid()) { 321 LOG_ERROR("Invalid packet"); 322 return; 323 } 324 auto handle = data_length_view.GetConnectionHandle(); 325 auto callbacks = get_callbacks(handle); 326 if (callbacks == nullptr) { 327 LOG_WARN("Can't find connection 0x%hx", handle); 328 ASSERT(!crash_on_unknown_handle_); 329 return; 330 } 331 callbacks->OnDataLengthChange( 332 data_length_view.GetMaxTxOctets(), 333 data_length_view.GetMaxTxTime(), 334 data_length_view.GetMaxRxOctets(), 335 data_length_view.GetMaxRxTime()); 336 } 337 on_remote_connection_parameter_requestle_impl338 void on_remote_connection_parameter_request(LeMetaEventView view) { 339 auto request_view = LeRemoteConnectionParameterRequestView::Create(view); 340 if (!request_view.IsValid()) { 341 LOG_ERROR("Invalid packet"); 342 return; 343 } 344 345 auto handle = request_view.GetConnectionHandle(); 346 auto callbacks = get_callbacks(handle); 347 if (callbacks == nullptr) { 348 LOG_WARN("Can't find connection 0x%hx", handle); 349 ASSERT(!crash_on_unknown_handle_); 350 return; 351 } 352 // TODO: this is blindly accepting any parameters, just so we don't hang connection 353 // have proper parameter negotiation 354 le_acl_connection_interface_->EnqueueCommand( 355 LeRemoteConnectionParameterRequestReplyBuilder::Create( 356 handle, 357 request_view.GetIntervalMin(), 358 request_view.GetIntervalMax(), 359 request_view.GetLatency(), 360 request_view.GetTimeout(), 361 0, 362 0), 363 handler_->BindOnce([](CommandCompleteView status) {})); 364 } 365 add_device_to_connect_listle_impl366 void add_device_to_connect_list(AddressWithType address_with_type) { 367 AddressType address_type = address_with_type.GetAddressType(); 368 if (!address_manager_registered) { 369 le_address_manager_->Register(this); 370 address_manager_registered = true; 371 } 372 pause_connection = true; 373 switch (address_type) { 374 case AddressType::PUBLIC_DEVICE_ADDRESS: 375 case AddressType::PUBLIC_IDENTITY_ADDRESS: { 376 le_address_manager_->AddDeviceToConnectList(ConnectListAddressType::PUBLIC, address_with_type.GetAddress()); 377 } break; 378 case AddressType::RANDOM_DEVICE_ADDRESS: 379 case AddressType::RANDOM_IDENTITY_ADDRESS: { 380 le_address_manager_->AddDeviceToConnectList(ConnectListAddressType::RANDOM, address_with_type.GetAddress()); 381 } 382 } 383 } 384 add_device_to_resolving_listle_impl385 void add_device_to_resolving_list( 386 AddressWithType address_with_type, 387 const std::array<uint8_t, 16>& peer_irk, 388 const std::array<uint8_t, 16>& local_irk) { 389 AddressType address_type = address_with_type.GetAddressType(); 390 if (!address_manager_registered) { 391 le_address_manager_->Register(this); 392 address_manager_registered = true; 393 } 394 pause_connection = true; 395 switch (address_type) { 396 case AddressType::PUBLIC_DEVICE_ADDRESS: 397 case AddressType::PUBLIC_IDENTITY_ADDRESS: { 398 le_address_manager_->AddDeviceToResolvingList( 399 PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, address_with_type.GetAddress(), peer_irk, local_irk); 400 } break; 401 case AddressType::RANDOM_DEVICE_ADDRESS: 402 case AddressType::RANDOM_IDENTITY_ADDRESS: { 403 le_address_manager_->AddDeviceToResolvingList( 404 PeerAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS, address_with_type.GetAddress(), peer_irk, local_irk); 405 } 406 } 407 } 408 create_le_connectionle_impl409 void create_le_connection(AddressWithType address_with_type, bool add_to_connect_list, bool is_direct) { 410 // TODO: Configure default LE connection parameters? 411 if (add_to_connect_list) { 412 add_device_to_connect_list(address_with_type); 413 if (is_direct) { 414 direct_connections_.insert(address_with_type); 415 if (create_connection_timeout_alarms_.find(address_with_type) == create_connection_timeout_alarms_.end()) { 416 create_connection_timeout_alarms_.emplace( 417 std::piecewise_construct, 418 std::forward_as_tuple(address_with_type.GetAddress(), address_with_type.GetAddressType()), 419 std::forward_as_tuple(handler_)); 420 create_connection_timeout_alarms_.at(address_with_type) 421 .Schedule( 422 common::BindOnce(&le_impl::on_create_connection_timeout, common::Unretained(this), address_with_type), 423 kCreateConnectionTimeoutMs); 424 } 425 } 426 } 427 428 if (!address_manager_registered) { 429 auto policy = le_address_manager_->Register(this); 430 address_manager_registered = true; 431 432 // Pause connection, wait for set random address complete 433 if (policy == LeAddressManager::AddressPolicy::USE_RESOLVABLE_ADDRESS || 434 policy == LeAddressManager::AddressPolicy::USE_NON_RESOLVABLE_ADDRESS) { 435 pause_connection = true; 436 } 437 } 438 439 if (pause_connection) { 440 canceled_connections_.insert(address_with_type); 441 return; 442 } 443 if (le_client_callbacks_ == nullptr) { 444 LOG_ERROR("No callbacks to call"); 445 return; 446 } 447 448 uint16_t le_scan_interval = kScanIntervalSlow; 449 uint16_t le_scan_window = kScanWindowSlow; 450 // If there is any direct connection in the connection list, use the fast parameter 451 if (!direct_connections_.empty()) { 452 le_scan_interval = kScanIntervalFast; 453 le_scan_window = kScanWindowFast; 454 } 455 InitiatorFilterPolicy initiator_filter_policy = InitiatorFilterPolicy::USE_CONNECT_LIST; 456 OwnAddressType own_address_type = 457 static_cast<OwnAddressType>(le_address_manager_->GetCurrentAddress().GetAddressType()); 458 uint16_t conn_interval_min = 0x0018; 459 uint16_t conn_interval_max = 0x0028; 460 uint16_t conn_latency = 0x0000; 461 uint16_t supervision_timeout = 0x001f4; 462 ASSERT(check_connection_parameters(conn_interval_min, conn_interval_max, conn_latency, supervision_timeout)); 463 464 connecting_le_.insert(address_with_type); 465 466 if (initiator_filter_policy == InitiatorFilterPolicy::USE_CONNECT_LIST) { 467 address_with_type = AddressWithType(); 468 } 469 470 if (controller_->IsSupported(OpCode::LE_EXTENDED_CREATE_CONNECTION)) { 471 LeCreateConnPhyScanParameters tmp; 472 tmp.scan_interval_ = le_scan_interval; 473 tmp.scan_window_ = le_scan_window; 474 tmp.conn_interval_min_ = conn_interval_min; 475 tmp.conn_interval_max_ = conn_interval_max; 476 tmp.conn_latency_ = conn_latency; 477 tmp.supervision_timeout_ = supervision_timeout; 478 tmp.min_ce_length_ = 0x00; 479 tmp.max_ce_length_ = 0x00; 480 481 le_acl_connection_interface_->EnqueueCommand( 482 LeExtendedCreateConnectionBuilder::Create(initiator_filter_policy, own_address_type, 483 address_with_type.GetAddressType(), address_with_type.GetAddress(), 484 0x01 /* 1M PHY ONLY */, {tmp}), 485 handler_->BindOnce([](CommandStatusView status) { 486 ASSERT(status.IsValid()); 487 ASSERT(status.GetCommandOpCode() == OpCode::LE_EXTENDED_CREATE_CONNECTION); 488 })); 489 } else { 490 le_acl_connection_interface_->EnqueueCommand( 491 LeCreateConnectionBuilder::Create(le_scan_interval, le_scan_window, initiator_filter_policy, 492 address_with_type.GetAddressType(), address_with_type.GetAddress(), 493 own_address_type, conn_interval_min, conn_interval_max, conn_latency, 494 supervision_timeout, kMinimumCeLength, kMaximumCeLength), 495 handler_->BindOnce([](CommandStatusView status) { 496 ASSERT(status.IsValid()); 497 ASSERT(status.GetCommandOpCode() == OpCode::LE_CREATE_CONNECTION); 498 })); 499 } 500 } 501 on_create_connection_timeoutle_impl502 void on_create_connection_timeout(AddressWithType address_with_type) { 503 LOG_INFO("on_create_connection_timeout, address: %s", address_with_type.ToString().c_str()); 504 if (create_connection_timeout_alarms_.find(address_with_type) != create_connection_timeout_alarms_.end()) { 505 create_connection_timeout_alarms_.at(address_with_type).Cancel(); 506 create_connection_timeout_alarms_.erase(address_with_type); 507 cancel_connect(address_with_type); 508 } 509 } 510 cancel_connectle_impl511 void cancel_connect(AddressWithType address_with_type) { 512 // the connection will be canceled by LeAddressManager.OnPause() 513 remove_device_from_connect_list(address_with_type); 514 } 515 set_le_suggested_default_data_parametersle_impl516 void set_le_suggested_default_data_parameters(uint16_t length, uint16_t time) { 517 auto packet = LeWriteSuggestedDefaultDataLengthBuilder::Create(length, time); 518 le_acl_connection_interface_->EnqueueCommand( 519 std::move(packet), handler_->BindOnce([](CommandCompleteView complete) {})); 520 } 521 remove_device_from_connect_listle_impl522 void remove_device_from_connect_list(AddressWithType address_with_type) { 523 AddressType address_type = address_with_type.GetAddressType(); 524 direct_connections_.erase(address_with_type); 525 if (!address_manager_registered) { 526 le_address_manager_->Register(this); 527 address_manager_registered = true; 528 } 529 pause_connection = true; 530 switch (address_type) { 531 case AddressType::PUBLIC_DEVICE_ADDRESS: 532 case AddressType::PUBLIC_IDENTITY_ADDRESS: { 533 le_address_manager_->RemoveDeviceFromConnectList( 534 ConnectListAddressType::PUBLIC, address_with_type.GetAddress()); 535 } break; 536 case AddressType::RANDOM_DEVICE_ADDRESS: 537 case AddressType::RANDOM_IDENTITY_ADDRESS: { 538 le_address_manager_->RemoveDeviceFromConnectList( 539 ConnectListAddressType::RANDOM, address_with_type.GetAddress()); 540 } 541 } 542 } 543 remove_device_from_resolving_listle_impl544 void remove_device_from_resolving_list(AddressWithType address_with_type) { 545 AddressType address_type = address_with_type.GetAddressType(); 546 if (!address_manager_registered) { 547 le_address_manager_->Register(this); 548 address_manager_registered = true; 549 } 550 pause_connection = true; 551 switch (address_type) { 552 case AddressType::PUBLIC_DEVICE_ADDRESS: 553 case AddressType::PUBLIC_IDENTITY_ADDRESS: { 554 le_address_manager_->RemoveDeviceFromResolvingList( 555 PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, address_with_type.GetAddress()); 556 } break; 557 case AddressType::RANDOM_DEVICE_ADDRESS: 558 case AddressType::RANDOM_IDENTITY_ADDRESS: { 559 le_address_manager_->RemoveDeviceFromResolvingList( 560 PeerAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS, address_with_type.GetAddress()); 561 } 562 } 563 } 564 set_privacy_policy_for_initiator_addressle_impl565 void set_privacy_policy_for_initiator_address( 566 LeAddressManager::AddressPolicy address_policy, 567 AddressWithType fixed_address, 568 crypto_toolbox::Octet16 rotation_irk, 569 std::chrono::milliseconds minimum_rotation_time, 570 std::chrono::milliseconds maximum_rotation_time) { 571 le_address_manager_->SetPrivacyPolicyForInitiatorAddress( 572 address_policy, fixed_address, rotation_irk, minimum_rotation_time, maximum_rotation_time); 573 } 574 575 // TODO(jpawlowski): remove once we have config file abstraction in cert tests set_privacy_policy_for_initiator_address_for_testle_impl576 void set_privacy_policy_for_initiator_address_for_test( 577 LeAddressManager::AddressPolicy address_policy, 578 AddressWithType fixed_address, 579 crypto_toolbox::Octet16 rotation_irk, 580 std::chrono::milliseconds minimum_rotation_time, 581 std::chrono::milliseconds maximum_rotation_time) { 582 le_address_manager_->SetPrivacyPolicyForInitiatorAddressForTest( 583 address_policy, fixed_address, rotation_irk, minimum_rotation_time, maximum_rotation_time); 584 } 585 handle_register_le_callbacksle_impl586 void handle_register_le_callbacks(LeConnectionCallbacks* callbacks, os::Handler* handler) { 587 ASSERT(le_client_callbacks_ == nullptr); 588 ASSERT(le_client_handler_ == nullptr); 589 le_client_callbacks_ = callbacks; 590 le_client_handler_ = handler; 591 } 592 handle_unregister_le_callbacksle_impl593 void handle_unregister_le_callbacks(LeConnectionCallbacks* callbacks, std::promise<void> promise) { 594 ASSERT_LOG(le_client_callbacks_ == callbacks, "Registered le callback entity is different then unregister request"); 595 le_client_callbacks_ = nullptr; 596 le_client_handler_ = nullptr; 597 promise.set_value(); 598 } 599 check_connection_parametersle_impl600 bool check_connection_parameters( 601 uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout) { 602 if (conn_interval_min < 0x0006 || conn_interval_min > 0x0C80 || conn_interval_max < 0x0006 || 603 conn_interval_max > 0x0C80 || conn_latency > 0x01F3 || supervision_timeout < 0x000A || 604 supervision_timeout > 0x0C80) { 605 LOG_ERROR("Invalid parameter"); 606 return false; 607 } 608 609 // The Maximum interval in milliseconds will be conn_interval_max * 1.25 ms 610 // The Timeout in milliseconds will be expected_supervision_timeout * 10 ms 611 // The Timeout in milliseconds shall be larger than (1 + Latency) * Interval_Max * 2, where Interval_Max is given in 612 // milliseconds. 613 uint32_t supervision_timeout_min = (uint32_t)(1 + conn_latency) * conn_interval_max * 2 + 1; 614 if (supervision_timeout * 8 < supervision_timeout_min || conn_interval_max < conn_interval_min) { 615 LOG_ERROR("Invalid parameter"); 616 return false; 617 } 618 619 return true; 620 } 621 OnPausele_impl622 void OnPause() override { 623 pause_connection = true; 624 if (connecting_le_.empty()) { 625 le_address_manager_->AckPause(this); 626 return; 627 } 628 canceled_connections_ = connecting_le_; 629 le_acl_connection_interface_->EnqueueCommand( 630 LeCreateConnectionCancelBuilder::Create(), 631 handler_->BindOnce(&le_impl::on_create_connection_cancel_complete, common::Unretained(this))); 632 le_address_manager_->AckPause(this); 633 } 634 on_create_connection_cancel_completele_impl635 void on_create_connection_cancel_complete(CommandCompleteView view) { 636 auto complete_view = LeCreateConnectionCancelCompleteView::Create(view); 637 ASSERT(complete_view.IsValid()); 638 if (complete_view.GetStatus() != ErrorCode::SUCCESS) { 639 auto status = complete_view.GetStatus(); 640 std::string error_code = ErrorCodeText(status); 641 LOG_WARN("Received on_create_connection_cancel_complete with error code %s", error_code.c_str()); 642 } 643 } 644 check_for_unregisterle_impl645 void check_for_unregister() { 646 if (le_acl_connections_.empty() && connecting_le_.empty() && canceled_connections_.empty() && 647 address_manager_registered && ready_to_unregister) { 648 le_address_manager_->Unregister(this); 649 address_manager_registered = false; 650 pause_connection = false; 651 ready_to_unregister = false; 652 } 653 } 654 OnResumele_impl655 void OnResume() override { 656 pause_connection = false; 657 if (!canceled_connections_.empty()) { 658 create_le_connection(*canceled_connections_.begin(), false, false); 659 } 660 canceled_connections_.clear(); 661 le_address_manager_->AckResume(this); 662 check_for_unregister(); 663 } 664 HACK_get_handlele_impl665 uint16_t HACK_get_handle(Address address) { 666 for (auto it = le_acl_connections_.begin(); it != le_acl_connections_.end(); it++) { 667 if (it->second.remote_address_.GetAddress() == address) { 668 return it->first; 669 } 670 } 671 return 0xFFFF; 672 } 673 UpdateLocalAddressle_impl674 void UpdateLocalAddress(uint16_t handle, hci::AddressWithType address_with_type) { 675 auto callbacks = get_callbacks(handle); 676 if (callbacks == nullptr) { 677 LOG_WARN("Can't find connection 0x%hx", handle); 678 ASSERT(!crash_on_unknown_handle_); 679 return; 680 } 681 callbacks->OnLocalAddressUpdate(address_with_type); 682 } 683 684 static constexpr uint16_t kMinimumCeLength = 0x0002; 685 static constexpr uint16_t kMaximumCeLength = 0x0C00; 686 HciLayer* hci_layer_ = nullptr; 687 Controller* controller_ = nullptr; 688 os::Handler* handler_ = nullptr; 689 RoundRobinScheduler* round_robin_scheduler_ = nullptr; 690 LeAddressManager* le_address_manager_ = nullptr; 691 LeAclConnectionInterface* le_acl_connection_interface_ = nullptr; 692 LeConnectionCallbacks* le_client_callbacks_ = nullptr; 693 os::Handler* le_client_handler_ = nullptr; 694 std::map<uint16_t, le_acl_connection> le_acl_connections_; 695 std::set<AddressWithType> connecting_le_; 696 std::set<AddressWithType> canceled_connections_; 697 std::set<AddressWithType> direct_connections_; 698 bool address_manager_registered = false; 699 bool ready_to_unregister = false; 700 bool pause_connection = false; 701 bool crash_on_unknown_handle_ = false; 702 std::map<AddressWithType, os::Alarm> create_connection_timeout_alarms_; 703 }; 704 705 } // namespace acl_manager 706 } // namespace hci 707 } // namespace bluetooth 708