1 // Copyright 2023 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 15 #pragma once 16 #include <lib/fit/function.h> 17 #include <pw_assert/check.h> 18 19 #include <memory> 20 #include <unordered_map> 21 22 #include "pw_bluetooth_sapphire/internal/host/common/device_address.h" 23 #include "pw_bluetooth_sapphire/internal/host/common/device_class.h" 24 #include "pw_bluetooth_sapphire/internal/host/common/macros.h" 25 #include "pw_bluetooth_sapphire/internal/host/hci-spec/constants.h" 26 #include "pw_bluetooth_sapphire/internal/host/hci-spec/le_connection_parameters.h" 27 #include "pw_bluetooth_sapphire/internal/host/hci-spec/protocol.h" 28 #include "pw_bluetooth_sapphire/internal/host/hci/low_energy_advertiser.h" 29 #include "pw_bluetooth_sapphire/internal/host/l2cap/l2cap_defs.h" 30 #include "pw_bluetooth_sapphire/internal/host/testing/controller_test_double_base.h" 31 #include "pw_bluetooth_sapphire/internal/host/testing/fake_peer.h" 32 33 namespace bt::testing { 34 35 namespace android_emb = pw::bluetooth::vendor::android_hci; 36 37 class FakePeer; 38 39 // FakeController emulates a real Bluetooth controller. It can be configured to 40 // respond to HCI commands in a predictable manner. 41 class FakeController final : public ControllerTestDoubleBase, 42 public WeakSelf<FakeController> { 43 public: 44 // Global settings for the FakeController. These can be used to initialize a 45 // FakeController and/or to re-configure an existing one. 46 struct Settings final { 47 // The default constructor initializes all fields to 0, unless another 48 // default is specified below. 49 Settings() = default; 50 ~Settings() = default; 51 52 void ApplyDualModeDefaults(); 53 void ApplyLEOnlyDefaults(); 54 void ApplyLegacyLEConfig(); 55 void ApplyExtendedLEConfig(); 56 void ApplyAndroidVendorExtensionDefaults(); 57 58 void AddBREDRSupportedCommands(); 59 void AddLESupportedCommands(); 60 61 bool is_event_unmasked(hci_spec::LEEventMask event) const; 62 SupportedCommandsViewfinal63 auto SupportedCommandsView() { 64 return pw::bluetooth::emboss::MakeSupportedCommandsView( 65 supported_commands, sizeof(supported_commands)); 66 } 67 68 // The time elapsed from the receipt of a LE Create Connection command until 69 // the resulting LE Connection Complete event. 70 pw::chrono::SystemClock::duration le_connection_delay = 71 std::chrono::seconds(0); 72 73 // Our role in any LE connections we make. 74 pw::bluetooth::emboss::ConnectionRole le_connection_role = 75 pw::bluetooth::emboss::ConnectionRole::CENTRAL; 76 77 // HCI settings. 78 pw::bluetooth::emboss::CoreSpecificationVersion hci_version = 79 pw::bluetooth::emboss::CoreSpecificationVersion::V5_0; 80 uint8_t num_hci_command_packets = 250; 81 uint64_t event_mask = 0; 82 uint64_t le_event_mask = 0; 83 84 // BD_ADDR (BR/EDR) or Public Device Address (LE) 85 DeviceAddress bd_addr; 86 87 // Local supported features and commands. 88 uint64_t lmp_features_page0 = 0; 89 uint64_t lmp_features_page1 = 0; 90 uint64_t lmp_features_page2 = 0; 91 uint64_t le_features = 0; 92 uint64_t le_supported_states = 0; 93 uint8_t supported_commands[64] = {0}; 94 95 // Buffer Size. 96 uint16_t acl_data_packet_length = 1; 97 uint8_t total_num_acl_data_packets = 1; 98 uint16_t le_acl_data_packet_length = 0; 99 uint8_t le_total_num_acl_data_packets = 0; 100 uint8_t synchronous_data_packet_length = 1; 101 uint8_t total_num_synchronous_data_packets = 0; 102 uint16_t iso_data_packet_length = 0; 103 uint8_t total_num_iso_data_packets = 0; 104 105 // Vendor extensions 106 StaticPacket<android_emb::LEGetVendorCapabilitiesCommandCompleteEventWriter> 107 android_extension_settings; 108 }; 109 110 // Configuration of an L2CAP channel for A2DP offloading. 111 struct OffloadedA2dpChannel final { 112 android_emb::A2dpCodecType codec_type = android_emb::A2dpCodecType::SBC; 113 uint16_t max_latency = 0; 114 StaticPacket<android_emb::A2dpScmsTEnableWriter> scms_t_enable; 115 android_emb::A2dpSamplingFrequency sampling_frequency = 116 android_emb::A2dpSamplingFrequency::HZ_44100; 117 android_emb::A2dpBitsPerSample bits_per_sample = 118 android_emb::A2dpBitsPerSample::BITS_PER_SAMPLE_16; 119 android_emb::A2dpChannelMode channel_mode = 120 android_emb::A2dpChannelMode::MONO; 121 uint32_t encoded_audio_bitrate = 0; 122 hci_spec::ConnectionHandle connection_handle = 0; 123 l2cap::ChannelId l2cap_channel_id = 0; 124 uint16_t l2cap_mtu_size = 0; 125 }; 126 127 // Current device low energy scan state. 128 struct LEScanState final { 129 bool enabled = false; 130 pw::bluetooth::emboss::LEScanType scan_type = 131 pw::bluetooth::emboss::LEScanType::PASSIVE; 132 pw::bluetooth::emboss::LEOwnAddressType own_address_type = 133 pw::bluetooth::emboss::LEOwnAddressType::PUBLIC; 134 pw::bluetooth::emboss::LEScanFilterPolicy filter_policy = 135 pw::bluetooth::emboss::LEScanFilterPolicy::BASIC_UNFILTERED; 136 uint16_t scan_interval = 0; 137 uint16_t scan_window = 0; 138 bool filter_duplicates = false; 139 uint16_t duration = 0; 140 uint16_t period = 0; 141 }; 142 143 // Current device basic advertising state 144 struct LEAdvertisingState final { advertised_viewfinal145 BufferView advertised_view() const { return BufferView(data, data_length); } scan_rsp_viewfinal146 BufferView scan_rsp_view() const { 147 return BufferView(scan_rsp_data, scan_rsp_length); 148 } 149 150 bool IsDirectedAdvertising() const; 151 152 bool enabled = false; 153 hci::LowEnergyAdvertiser::AdvertisingEventProperties properties; 154 155 std::optional<DeviceAddress> random_address; 156 pw::bluetooth::emboss::LEOwnAddressType own_address_type = 157 pw::bluetooth::emboss::LEOwnAddressType::PUBLIC; 158 159 uint32_t interval_min = 0; 160 uint32_t interval_max = 0; 161 162 uint16_t data_length = 0; 163 uint8_t data[hci_spec::kMaxLEExtendedAdvertisingDataLength] = {0}; 164 uint16_t scan_rsp_length = 0; 165 uint8_t scan_rsp_data[hci_spec::kMaxLEExtendedAdvertisingDataLength] = {0}; 166 }; 167 168 // The parameters of the most recent low energy connection initiation request 169 struct LEConnectParams final { 170 enum class InitiatingPHYs { 171 kLE_1M = 0, 172 kLE_2M, 173 kLE_Coded, 174 }; 175 176 struct Parameters { 177 uint16_t scan_interval = 0; 178 uint16_t scan_window = 0; 179 uint16_t connection_interval_min = 0; 180 uint16_t connection_interval_max = 0; 181 uint16_t max_latency = 0; 182 uint16_t supervision_timeout = 0; 183 uint16_t min_ce_length = 0; 184 uint16_t max_ce_length = 0; 185 }; 186 187 bool use_filter_policy = false; 188 pw::bluetooth::emboss::LEOwnAddressType own_address_type; 189 DeviceAddress peer_address; 190 std::unordered_map<InitiatingPHYs, Parameters> phy_conn_params; 191 }; 192 193 // Constructor initializes the controller with the minimal default settings 194 // (equivalent to calling Settings::ApplyDefaults()). FakeController(pw::async::Dispatcher & pw_dispatcher)195 explicit FakeController(pw::async::Dispatcher& pw_dispatcher) 196 : ControllerTestDoubleBase(pw_dispatcher), WeakSelf(this) {} 197 ~FakeController() override = default; 198 199 // Resets the controller settings. set_settings(const Settings & settings)200 void set_settings(const Settings& settings) { settings_ = settings; } 201 202 // Always respond to the given command |opcode| with an Command Status event 203 // specifying |status|. 204 void SetDefaultCommandStatus(hci_spec::OpCode opcode, 205 pw::bluetooth::emboss::StatusCode status); 206 void ClearDefaultCommandStatus(hci_spec::OpCode opcode); 207 208 // Tells the FakeController to always respond to the given command opcode with 209 // a Command Complete event specifying the given HCI status code. 210 void SetDefaultResponseStatus(hci_spec::OpCode opcode, 211 pw::bluetooth::emboss::StatusCode status); 212 void ClearDefaultResponseStatus(hci_spec::OpCode opcode); 213 214 // Returns the current LE scan state. le_scan_state()215 const LEScanState& le_scan_state() const { return le_scan_state_; } 216 217 // Returns the current LE advertising state for legacy advertising legacy_advertising_state()218 const LEAdvertisingState& legacy_advertising_state() const { 219 return legacy_advertising_state_; 220 } 221 222 // Returns the current LE advertising state for extended advertising, for the 223 // given advertising handle extended_advertising_state(hci_spec::AdvertisingHandle handle)224 const LEAdvertisingState& extended_advertising_state( 225 hci_spec::AdvertisingHandle handle) { 226 return extended_advertising_states_[handle]; 227 } 228 229 // Returns the most recent LE connection request parameters. le_connect_params()230 const std::optional<LEConnectParams>& le_connect_params() const { 231 return le_connect_params_; 232 } 233 234 // Store the most recent LE Connection Parameters for inspection 235 void CaptureLEConnectParams( 236 const pw::bluetooth::emboss::LECreateConnectionCommandView& params); 237 238 // Store the most recent LE Connection Parameters for inspection 239 void CaptureLEConnectParams( 240 const pw::bluetooth::emboss::LEExtendedCreateConnectionCommandV1View& 241 params); 242 243 // Returns the current local name set in the controller local_name()244 const std::string& local_name() const { return local_name_; } 245 246 // Returns the current class of device. device_class()247 const DeviceClass& device_class() const { return device_class_; } 248 249 // Adds a fake remote peer. Returns false if a peer with the same address 250 // was previously added. 251 bool AddPeer(std::unique_ptr<FakePeer> peer); 252 253 // Removes a previously registered peer with the given device |address|. 254 // Does nothing if |address| is unrecognized. 255 void RemovePeer(const DeviceAddress& address); 256 257 // Returns a pointer to the FakePeer with the given |address|. Returns 258 // nullptr if the |address| is unknown. 259 FakePeer* FindPeer(const DeviceAddress& address); 260 261 // Counters for HCI commands received. le_create_connection_command_count()262 int le_create_connection_command_count() const { 263 return le_create_connection_command_count_; 264 } acl_create_connection_command_count()265 int acl_create_connection_command_count() const { 266 return acl_create_connection_command_count_; 267 } 268 269 // Setting this callback allows test code to introspect the 270 // LECreateConnectionCommand from bt-host, but does not affect 271 // FakeController's handling of the command (i.e. this method exists solely 272 // for introspection). To change how FakeController responds to an 273 // LECreateConnectionCommand, use the FakePeer::set_connect_status or 274 // FakePeer::set_connect_response methods. set_le_create_connection_command_callback(fit::function<void (pw::bluetooth::emboss::LECreateConnectionCommandView)> callback)275 void set_le_create_connection_command_callback( 276 fit::function<void(pw::bluetooth::emboss::LECreateConnectionCommandView)> 277 callback) { 278 le_create_connection_cb_ = std::move(callback); 279 } 280 281 // Sets a callback to be invoked when the the base controller parameters 282 // change due to a HCI command. These parameters are: 283 // 284 // - The local name. 285 // - The local class of device. set_controller_parameters_callback(fit::closure callback)286 void set_controller_parameters_callback(fit::closure callback) { 287 controller_parameters_cb_ = std::move(callback); 288 } 289 290 // Sets a callback to be invoked when the scan state changes. 291 using ScanStateCallback = fit::function<void(bool enabled)>; set_scan_state_callback(ScanStateCallback callback)292 void set_scan_state_callback(ScanStateCallback callback) { 293 scan_state_cb_ = std::move(callback); 294 } 295 296 // Sets a callback to be invoked when the LE Advertising state changes. set_advertising_state_callback(fit::closure callback)297 void set_advertising_state_callback(fit::closure callback) { 298 advertising_state_cb_ = std::move(callback); 299 } 300 301 // Sets a callback to be invoked on connection events. 302 using ConnectionStateCallback = 303 fit::function<void(const DeviceAddress&, 304 hci_spec::ConnectionHandle handle, 305 bool connected, 306 bool canceled)>; set_connection_state_callback(ConnectionStateCallback callback)307 void set_connection_state_callback(ConnectionStateCallback callback) { 308 conn_state_cb_ = std::move(callback); 309 } 310 311 // Sets a callback to be invoked when LE connection parameters are updated 312 // for a fake device. 313 using LEConnectionParametersCallback = fit::function<void( 314 const DeviceAddress&, const hci_spec::LEConnectionParameters&)>; set_le_connection_parameters_callback(LEConnectionParametersCallback callback)315 void set_le_connection_parameters_callback( 316 LEConnectionParametersCallback callback) { 317 le_conn_params_cb_ = std::move(callback); 318 } 319 320 // Sets a callback to be invoked just before LE Read Remote Feature commands 321 // are handled. set_le_read_remote_features_callback(fit::closure callback)322 void set_le_read_remote_features_callback(fit::closure callback) { 323 le_read_remote_features_cb_ = std::move(callback); 324 } 325 326 // Sends an HCI event, filling in the parameters in a provided event packet. 327 void SendEvent(hci_spec::EventCode event_code, hci::EventPacket* packet); 328 329 // Sends an ACL data packet with the given parameters. 330 void SendACLPacket(hci_spec::ConnectionHandle handle, 331 const ByteBuffer& payload); 332 333 // Sends a L2CAP basic frame. 334 void SendL2CAPBFrame(hci_spec::ConnectionHandle handle, 335 l2cap::ChannelId channel_id, 336 const ByteBuffer& payload); 337 338 // Sends a L2CAP control frame over a signaling channel. If |is_le| is true, 339 // then the LE signaling channel will be used. 340 void SendL2CAPCFrame(hci_spec::ConnectionHandle handle, 341 bool is_le, 342 l2cap::CommandCode code, 343 uint8_t id, 344 const ByteBuffer& payload); 345 346 void SendNumberOfCompletedPacketsEvent(hci_spec::ConnectionHandle handle, 347 uint16_t num); 348 349 // Sets up a LE link to the device with the given |addr|. FakeController 350 // will report a connection event in which it is in the given |role|. 351 void ConnectLowEnergy(const DeviceAddress& addr, 352 pw::bluetooth::emboss::ConnectionRole role = 353 pw::bluetooth::emboss::ConnectionRole::PERIPHERAL); 354 355 // Sends an HCI Connection Request event. 356 void SendConnectionRequest(const DeviceAddress& addr, 357 pw::bluetooth::emboss::LinkType link_type); 358 359 // Tells a fake device to initiate the L2CAP Connection Parameter Update 360 // procedure using the given |params|. Has no effect if a connected fake 361 // device with the given |addr| is not found. 362 void L2CAPConnectionParameterUpdate( 363 const DeviceAddress& addr, 364 const hci_spec::LEPreferredConnectionParameters& params); 365 366 // Sends an LE Meta Event Connection Update Complete Subevent. Used to 367 // simulate updates initiated by LE central or spontaneously by the 368 // controller. 369 void SendLEConnectionUpdateCompleteSubevent( 370 hci_spec::ConnectionHandle handle, 371 const hci_spec::LEConnectionParameters& params, 372 pw::bluetooth::emboss::StatusCode status = 373 pw::bluetooth::emboss::StatusCode::SUCCESS); 374 375 // Marks the FakePeer with address |address| as disconnected and sends a HCI 376 // Disconnection Complete event for all of its links. 377 void Disconnect( 378 const DeviceAddress& addr, 379 pw::bluetooth::emboss::StatusCode reason = 380 pw::bluetooth::emboss::StatusCode::REMOTE_USER_TERMINATED_CONNECTION); 381 382 // Send HCI Disconnection Complete event for |handle|. 383 void SendDisconnectionCompleteEvent( 384 hci_spec::ConnectionHandle handle, 385 pw::bluetooth::emboss::StatusCode reason = 386 pw::bluetooth::emboss::StatusCode::REMOTE_USER_TERMINATED_CONNECTION); 387 388 // Send HCI encryption change event for |handle| with the given parameters. 389 void SendEncryptionChangeEvent( 390 hci_spec::ConnectionHandle handle, 391 pw::bluetooth::emboss::StatusCode status, 392 pw::bluetooth::emboss::EncryptionStatus encryption_enabled); 393 394 // Callback to invoke when a packet is received over the data channel. Care 395 // should be taken to ensure that a callback with a reference to test case 396 // variables is not invoked when tearing down. 397 using DataCallback = fit::function<void(const ByteBuffer& packet)>; 398 void SetDataCallback(DataCallback callback, 399 pw::async::Dispatcher& pw_dispatcher); 400 void ClearDataCallback(); 401 402 // Callback to invoke when a packet is received over the SCO data channel. SetScoDataCallback(DataCallback callback)403 void SetScoDataCallback(DataCallback callback) { 404 sco_data_callback_ = std::move(callback); 405 } ClearScoDataCallback()406 void ClearScoDataCallback() { sco_data_callback_ = nullptr; } 407 408 // Callback to invoke when a packet is received over the ISO data channel. SetIsoDataCallback(DataCallback callback)409 void SetIsoDataCallback(DataCallback callback) { 410 iso_data_callback_ = std::move(callback); 411 } ClearIsoDataCallback()412 void ClearIsoDataCallback() { iso_data_callback_ = nullptr; } 413 414 // Automatically send HCI Number of Completed Packets event for each packet 415 // received. Enabled by default. set_auto_completed_packets_event_enabled(bool enabled)416 void set_auto_completed_packets_event_enabled(bool enabled) { 417 auto_completed_packets_event_enabled_ = enabled; 418 } 419 420 // Automatically send HCI Disconnection Complete event when HCI Disconnect 421 // command received. Enabled by default. set_auto_disconnection_complete_event_enabled(bool enabled)422 void set_auto_disconnection_complete_event_enabled(bool enabled) { 423 auto_disconnection_complete_event_enabled_ = enabled; 424 } 425 426 // Sets the response flag for a TX Power Level Read. 427 // Enabled by default (i.e it will respond to TXPowerLevelRead by default). set_tx_power_level_read_response_flag(bool respond)428 void set_tx_power_level_read_response_flag(bool respond) { 429 respond_to_tx_power_read_ = respond; 430 } 431 432 // Upon reception of a command packet with `opcode`, FakeController invokes 433 // `pause_listener` with a closure. The command will hang until this closure 434 // is invoked, enabling clients to control the timing of command completion. pause_responses_for_opcode(hci_spec::OpCode code,fit::function<void (fit::closure)> pause_listener)435 void pause_responses_for_opcode( 436 hci_spec::OpCode code, fit::function<void(fit::closure)> pause_listener) { 437 paused_opcode_listeners_[code] = std::move(pause_listener); 438 } 439 clear_pause_listener_for_opcode(hci_spec::OpCode code)440 void clear_pause_listener_for_opcode(hci_spec::OpCode code) { 441 paused_opcode_listeners_.erase(code); 442 } 443 set_maximum_advertising_data_length(uint16_t value)444 void set_maximum_advertising_data_length(uint16_t value) { 445 max_advertising_data_length_ = value; 446 } 447 448 // Called when a HCI_LE_Read_Advertising_Channel_Tx_Power command is 449 // received. 450 void OnLEReadAdvertisingChannelTxPower(); 451 452 // Inform the controller that the advertising handle is connected via the 453 // connection handle. This method then generates the necessary LE Meta 454 // Events (e.g. Advertising Set Terminated) to inform extended advertising 455 // listeners. 456 void SendLEAdvertisingSetTerminatedEvent( 457 hci_spec::ConnectionHandle conn_handle, 458 hci_spec::AdvertisingHandle adv_handle); 459 460 // Inform the controller that the advertising handle is connected via the 461 // connection handle. This method then generates the necessary Vendor Event 462 // (e.g. LE multi-advertising state change sub-event) to inform Android 463 // Multiple Advertising listeners. 464 void SendAndroidLEMultipleAdvertisingStateChangeSubevent( 465 hci_spec::ConnectionHandle conn_handle, 466 hci_spec::AdvertisingHandle adv_handle); 467 468 // The maximum number of advertising sets supported by the controller. Core 469 // Spec Volume 4, Part E, Section 7.8.58: the memory used to store 470 // advertising sets can also be used for other purposes. This value can 471 // change over time. num_supported_advertising_sets()472 uint8_t num_supported_advertising_sets() const { 473 return num_supported_advertising_sets_; 474 } set_num_supported_advertising_sets(uint8_t value)475 void set_num_supported_advertising_sets(uint8_t value) { 476 PW_CHECK(value >= extended_advertising_states_.size()); 477 PW_CHECK(value <= hci_spec::kAdvertisingHandleMax + 478 1); // support advertising handle of 0 479 num_supported_advertising_sets_ = value; 480 } 481 482 // Controller overrides: 483 void SendCommand(pw::span<const std::byte> command) override; 484 SendAclData(pw::span<const std::byte> data)485 void SendAclData(pw::span<const std::byte> data) override { 486 // Post the packet to simulate async HCI behavior. 487 (void)heap_dispatcher().Post( 488 [self = GetWeakPtr(), data = DynamicByteBuffer(BufferView(data))]( 489 pw::async::Context /*ctx*/, pw::Status status) { 490 if (self.is_alive() && status.ok()) { 491 self->OnACLDataPacketReceived(BufferView(data)); 492 } 493 }); 494 } 495 SendScoData(pw::span<const std::byte> data)496 void SendScoData(pw::span<const std::byte> data) override { 497 // Post the packet to simulate async HCI behavior. 498 (void)heap_dispatcher().Post( 499 [self = GetWeakPtr(), data = DynamicByteBuffer(BufferView(data))]( 500 pw::async::Context /*ctx*/, pw::Status status) { 501 if (self.is_alive() && status.ok()) { 502 self->OnScoDataPacketReceived(BufferView(data)); 503 } 504 }); 505 } 506 SendIsoData(pw::span<const std::byte> data)507 void SendIsoData(pw::span<const std::byte> data) override { 508 // Post the packet to simulate async HCI behavior. 509 (void)heap_dispatcher().Post( 510 [self = GetWeakPtr(), data = DynamicByteBuffer(BufferView(data))]( 511 pw::async::Context /*ctx*/, pw::Status status) { 512 if (self.is_alive() && status.ok()) { 513 self->OnIsoDataPacketReceived(BufferView(data)); 514 } 515 }); 516 } 517 518 // Sends a single LE advertising report for the given peer. This method will 519 // send a legacy or extended advertising report, depending on which one the 520 // peer is configured to send. 521 // 522 // Does nothing if a LE scan is not currently enabled or if the peer doesn't 523 // support advertising. 524 void SendAdvertisingReport(const FakePeer& peer); 525 526 // Sends a single LE advertising report including the scan response for the 527 // given peer. This method will send a legacy or extended advertising 528 // report, depending on which one the peer is configured to send. 529 // 530 // Does nothing if a LE scan is not currently enabled or if the peer doesn't 531 // support advertising. 532 void SendScanResponseReport(const FakePeer& peer); 533 534 // Gets a reference to the set of LE Host Features that were set le_features()535 hci_spec::LESupportedFeatures le_features() { 536 return hci_spec::LESupportedFeatures{settings_.le_features}; 537 } 538 539 private: IsValidAdvertisingHandle(hci_spec::AdvertisingHandle handle)540 static bool IsValidAdvertisingHandle(hci_spec::AdvertisingHandle handle) { 541 return handle <= hci_spec::kAdvertisingHandleMax; 542 } 543 544 // Helper function to capture_le_connect_params 545 void CaptureLEConnectParamsForPHY( 546 const pw::bluetooth::emboss::LEExtendedCreateConnectionCommandV1View& 547 params, 548 LEConnectParams::InitiatingPHYs phy); 549 550 // Finds and returns the FakePeer with the given parameters or nullptr if no 551 // such device exists. 552 FakePeer* FindByConnHandle(hci_spec::ConnectionHandle handle); 553 554 // Returns the next available L2CAP signaling channel command ID. 555 uint8_t NextL2CAPCommandId(); 556 557 // Sends a HCI_Command_Complete event with the given status in response to 558 // the command with |opcode|. 559 // 560 // NOTE: This method returns only a status field. Some HCI commands have 561 // multiple fields in their return message. In those cases, it's better (and 562 // clearer) to use the other RespondWithCommandComplete (ByteBuffer as 563 // second parameter) instead. 564 void RespondWithCommandComplete(pw::bluetooth::emboss::OpCode opcode, 565 pw::bluetooth::emboss::StatusCode status); 566 567 // Sends an HCI_Command_Complete event in response to the command with 568 // |opcode| and using the provided event packet, filling in the event header 569 // fields. 570 void RespondWithCommandComplete(pw::bluetooth::emboss::OpCode opcode, 571 hci::EventPacket* packet); 572 573 // Sends a HCI_Command_Status event in response to the command with |opcode| 574 // and using the given data as the parameter payload. 575 void RespondWithCommandStatus(pw::bluetooth::emboss::OpCode opcode, 576 pw::bluetooth::emboss::StatusCode status); 577 578 // If a default Command Status event status has been set for the given 579 // |opcode|, send a Command Status event and returns true. 580 bool MaybeRespondWithDefaultCommandStatus(hci_spec::OpCode opcode); 581 582 // If a default status has been configured for the given opcode, sends back 583 // an error Command Complete event and returns true. Returns false if no 584 // response was set. 585 bool MaybeRespondWithDefaultStatus(hci_spec::OpCode opcode); 586 587 // Sends Inquiry Response reports for known BR/EDR devices. 588 void SendInquiryResponses(); 589 590 // Sends LE advertising reports for all known peers with advertising data, 591 // if a scan is currently enabled. If duplicate filtering is disabled then 592 // the reports are continued to be sent until scan is disabled. 593 void SendAdvertisingReports(); 594 595 // Notifies |controller_parameters_cb_|. 596 void NotifyControllerParametersChanged(); 597 598 // Notifies |advertising_state_cb_| 599 void NotifyAdvertisingState(); 600 601 // Notifies |conn_state_cb_| with the given parameters. 602 void NotifyConnectionState(const DeviceAddress& addr, 603 hci_spec::ConnectionHandle handle, 604 bool connected, 605 bool canceled = false); 606 607 // Notifies |le_conn_params_cb_| 608 void NotifyLEConnectionParameters( 609 const DeviceAddress& addr, 610 const hci_spec::LEConnectionParameters& params); 611 612 template <typename T> 613 void SendEnhancedConnectionCompleteEvent( 614 pw::bluetooth::emboss::StatusCode status, 615 const T& params, 616 uint16_t interval, 617 uint16_t max_latency, 618 uint16_t supervision_timeout); 619 620 void SendConnectionCompleteEvent( 621 pw::bluetooth::emboss::StatusCode status, 622 const pw::bluetooth::emboss::LECreateConnectionCommandView& params, 623 uint16_t interval); 624 625 // Called when a HCI_Create_Connection command is received. 626 void OnCreateConnectionCommandReceived( 627 const pw::bluetooth::emboss::CreateConnectionCommandView& params); 628 629 // Called when a HCI_LE_Create_Connection command is received. 630 void OnLECreateConnectionCommandReceived( 631 const pw::bluetooth::emboss::LECreateConnectionCommandView& params); 632 633 // Called when a HCI_LE_Create_Connection command is received. 634 void OnLEExtendedCreateConnectionCommandReceived( 635 const pw::bluetooth::emboss::LEExtendedCreateConnectionCommandV1View& 636 params); 637 638 // Called when a HCI_LE_Connection_Update command is received. 639 void OnLEConnectionUpdateCommandReceived( 640 const pw::bluetooth::emboss::LEConnectionUpdateCommandView& params); 641 642 // Called when a HCI_Disconnect command is received. 643 void OnDisconnectCommandReceived( 644 const pw::bluetooth::emboss::DisconnectCommandView& params); 645 646 // Called when a HCI_LE_Write_Host_Support command is received. 647 void OnWriteLEHostSupportCommandReceived( 648 const pw::bluetooth::emboss::WriteLEHostSupportCommandView& params); 649 650 // Called when a HCI_Write_Secure_Connections_Host_Support command is 651 // received. 652 void OnWriteSecureConnectionsHostSupport( 653 const pw::bluetooth::emboss::WriteSecureConnectionsHostSupportCommandView& 654 params); 655 656 // Called when a HCI_Reset command is received. 657 void OnReset(); 658 659 // Called when a HCI_Inquiry command is received. 660 void OnInquiry(const pw::bluetooth::emboss::InquiryCommandView& params); 661 662 // Called when a HCI_LE_Set_Scan_Enable command is received. 663 void OnLESetScanEnable( 664 const pw::bluetooth::emboss::LESetScanEnableCommandView& params); 665 666 // Called when a HCI_LE_Set_Extended_Scan_Enable command is received. 667 void OnLESetExtendedScanEnable( 668 const pw::bluetooth::emboss::LESetExtendedScanEnableCommandView& params); 669 670 // Called when a HCI_LE_Set_Scan_Parameters command is received. 671 672 void OnLESetScanParameters( 673 const pw::bluetooth::emboss::LESetScanParametersCommandView& params); 674 675 // Called when a HCI_LE_Extended_Set_Scan_Parameters command is received. 676 void OnLESetExtendedScanParameters( 677 const pw::bluetooth::emboss::LESetExtendedScanParametersCommandView& 678 params); 679 680 // Called when a HCI_Read_Local_Extended_Features command is received. 681 void OnReadLocalExtendedFeatures( 682 const pw::bluetooth::emboss::ReadLocalExtendedFeaturesCommandView& 683 params); 684 685 // Called when a HCI_SetEventMask command is received. 686 void OnSetEventMask( 687 const pw::bluetooth::emboss::SetEventMaskCommandView& params); 688 689 // Called when a HCI_LE_Set_Event_Mask command is received. 690 void OnLESetEventMask( 691 const pw::bluetooth::emboss::LESetEventMaskCommandView& params); 692 693 // Called when a HCI_LE_Read_Buffer_Size [v1] command is received. 694 void OnLEReadBufferSizeV1(); 695 696 // Called when a HCI_LE_Read_Buffer_Size [v2] command is received. 697 void OnLEReadBufferSizeV2(); 698 699 // Called when a HCI_LE_Read_Supported_States command is received. 700 void OnLEReadSupportedStates(); 701 702 // Called when a HCI_LE_Read_Local_Supported_Features command is received. 703 void OnLEReadLocalSupportedFeatures(); 704 705 // Called when a HCI_LE_Create_Connection_Cancel command is received. 706 void OnLECreateConnectionCancel(); 707 708 // Called when a HCI_Write_Extended_Inquiry_Response command is received. 709 void OnWriteExtendedInquiryResponse( 710 const pw::bluetooth::emboss::WriteExtendedInquiryResponseCommandView& 711 params); 712 713 // Called when a HCI_Write_Simple_PairingMode command is received. 714 void OnWriteSimplePairingMode( 715 const pw::bluetooth::emboss::WriteSimplePairingModeCommandView& params); 716 717 // Called when a HCI_Read_Simple_Pairing_Mode command is received. 718 void OnReadSimplePairingMode(); 719 720 // Called when a HCI_Write_Page_Scan_Type command is received. 721 void OnWritePageScanType( 722 const pw::bluetooth::emboss::WritePageScanTypeCommandView& params); 723 724 // Called when a HCI_Read_Page_Scan_Type command is received. 725 void OnReadPageScanType(); 726 727 // Called when a HCI_Write_Inquiry_Mode command is received. 728 void OnWriteInquiryMode( 729 const pw::bluetooth::emboss::WriteInquiryModeCommandView& params); 730 731 // Called when a HCI_Read_Inquiry_Mode command is received. 732 void OnReadInquiryMode(); 733 734 // Called when a HCI_Write_Class_OfDevice command is received. 735 void OnWriteClassOfDevice( 736 const pw::bluetooth::emboss::WriteClassOfDeviceCommandView& params); 737 738 // Called when a HCI_Write_Page_Scan_Activity command is received. 739 void OnWritePageScanActivity( 740 const pw::bluetooth::emboss::WritePageScanActivityCommandView& params); 741 742 // Called when a HCI_Read_Page_Scan_Activity command is received. 743 void OnReadPageScanActivity(); 744 745 // Called when a HCI_Write_Scan_Enable command is received. 746 void OnWriteScanEnable( 747 const pw::bluetooth::emboss::WriteScanEnableCommandView& params); 748 749 // Called when a HCI_Read_Scan_Enable command is received. 750 void OnReadScanEnable(); 751 752 // Called when a HCI_Read_Local_Name command is received. 753 void OnReadLocalName(); 754 755 // Called when a HCI_Write_Local_Name command is received. 756 void OnWriteLocalName( 757 const pw::bluetooth::emboss::WriteLocalNameCommandView& params); 758 759 // Called when a HCI_Create_Connection_Cancel command is received. 760 void OnCreateConnectionCancel(); 761 762 // Called when a HCI_Read_Buffer_Size command is received. 763 void OnReadBufferSize(); 764 765 // Called when a HCI_Read_BRADDR command is received. 766 void OnReadBRADDR(); 767 768 // Called when a HCI_LE_Set_Advertising_Enable command is received. 769 void OnLESetAdvertisingEnable( 770 const pw::bluetooth::emboss::LESetAdvertisingEnableCommandView& params); 771 772 // Called when a HCI_LE_Set_Scan_Response_Data command is received. 773 void OnLESetScanResponseData( 774 const pw::bluetooth::emboss::LESetScanResponseDataCommandView& params); 775 776 // Called when a HCI_LE_Set_Advertising_Data command is received. 777 void OnLESetAdvertisingData( 778 const pw::bluetooth::emboss::LESetAdvertisingDataCommandView& params); 779 780 // Called when a HCI_LE_Set_Advertising_Parameters command is received. 781 void OnLESetAdvertisingParameters( 782 const pw::bluetooth::emboss::LESetAdvertisingParametersCommandView& 783 params); 784 785 // Called when a HCI_LE_Set_Random_Address command is received. 786 void OnLESetRandomAddress( 787 const pw::bluetooth::emboss::LESetRandomAddressCommandView& params); 788 789 // Called when a HCI_LE_Set_Advertising_Set_Random_Address command is 790 // received. 791 void OnLESetAdvertisingSetRandomAddress( 792 const pw::bluetooth::emboss::LESetAdvertisingSetRandomAddressCommandView& 793 params); 794 795 // Called when a HCI_LE_Set_Extended_Advertising_Data command is received. 796 void OnLESetExtendedAdvertisingParameters( 797 const pw::bluetooth::emboss:: 798 LESetExtendedAdvertisingParametersV1CommandView& params); 799 800 // Called when a HCI_LE_Set_Extended_Advertising_Data command is received. 801 void OnLESetExtendedAdvertisingData( 802 const pw::bluetooth::emboss::LESetExtendedAdvertisingDataCommandView& 803 params); 804 805 // Called when a HCI_LE_Set_Extended_Scan_Response_Data command is received. 806 void OnLESetExtendedScanResponseData( 807 const pw::bluetooth::emboss::LESetExtendedScanResponseDataCommandView& 808 params); 809 810 // Called when a HCI_LE_Set_Extended_Advertising_Enable command is received. 811 void OnLESetExtendedAdvertisingEnable( 812 const pw::bluetooth::emboss::LESetExtendedAdvertisingEnableCommandView& 813 params); 814 815 // Called when a HCI_LE_Set_Host_Feature command is received. 816 void OnLESetHostFeature( 817 const pw::bluetooth::emboss::LESetHostFeatureCommandView& params); 818 819 // Called when a HCI_LE_Read_Maximum_Advertising_Data_Length command is 820 // received. 821 void OnLEReadMaximumAdvertisingDataLength(); 822 823 // Called when a HCI_LE_Read_Number_of_Supported_Advertising_Sets command is 824 // received. 825 void OnLEReadNumberOfSupportedAdvertisingSets(); 826 827 // Called when a HCI_LE_Remove_Advertising_Set command is received. 828 void OnLERemoveAdvertisingSet( 829 const pw::bluetooth::emboss::LERemoveAdvertisingSetCommandView& params); 830 831 // Called when a HCI_LE_Clear_Advertising_Sets command is received. 832 void OnLEClearAdvertisingSets(); 833 834 // Called when a HCI_Read_Local_Supported_Features command is received. 835 void OnReadLocalSupportedFeatures(); 836 837 // Called when a HCI_Read_Local_Supported_Commands command is received. 838 void OnReadLocalSupportedCommands(); 839 840 // Called when a HCI_Read_Local_Version_Info command is received. 841 void OnReadLocalVersionInfo(); 842 843 // Interrogation command handlers: 844 845 // Called when a HCI_Read_Remote_Name_Request command is received. 846 void OnReadRemoteNameRequestCommandReceived( 847 const pw::bluetooth::emboss::RemoteNameRequestCommandView& params); 848 849 // Called when a HCI_Read_Remote_Supported_Features command is received. 850 void OnReadRemoteSupportedFeaturesCommandReceived( 851 const pw::bluetooth::emboss::ReadRemoteSupportedFeaturesCommandView& 852 params); 853 854 // Called when a HCI_Read_Remote_Version_Information command is received. 855 void OnReadRemoteVersionInfoCommandReceived( 856 const pw::bluetooth::emboss::ReadRemoteVersionInfoCommandView& params); 857 858 // Called when a HCI_Read_Remote_Extended_Features command is received. 859 void OnReadRemoteExtendedFeaturesCommandReceived( 860 const pw::bluetooth::emboss::ReadRemoteExtendedFeaturesCommandView& 861 params); 862 863 // Pairing command handlers: 864 865 // Called when a HCI_Authentication_Requested command is received. 866 void OnAuthenticationRequestedCommandReceived( 867 const pw::bluetooth::emboss::AuthenticationRequestedCommandView& params); 868 869 // Called when a HCI_Link_Key_Request_Reply command is received. 870 void OnLinkKeyRequestReplyCommandReceived( 871 const pw::bluetooth::emboss::LinkKeyRequestReplyCommandView& params); 872 873 // Called when a HCI_Link_Key_Request_Negative_Reply command is received. 874 void OnLinkKeyRequestNegativeReplyCommandReceived( 875 const pw::bluetooth::emboss::LinkKeyRequestNegativeReplyCommandView& 876 params); 877 878 // Called when a HCI_IO_Capability_Request_Reply command is received. 879 void OnIOCapabilityRequestReplyCommand( 880 const pw::bluetooth::emboss::IoCapabilityRequestReplyCommandView& params); 881 882 // Called when a HCI_User_Confirmation_Request_Reply command is received. 883 void OnUserConfirmationRequestReplyCommand( 884 const pw::bluetooth::emboss::UserConfirmationRequestReplyCommandView& 885 params); 886 887 // Called when a HCI_User_Confirmation_Request_Negative_Reply command is 888 // received. 889 void OnUserConfirmationRequestNegativeReplyCommand( 890 const pw::bluetooth::emboss:: 891 UserConfirmationRequestNegativeReplyCommandView& params); 892 893 // Called when a HCI_Set_Connection_Encryption command is received. 894 void OnSetConnectionEncryptionCommand( 895 const pw::bluetooth::emboss::SetConnectionEncryptionCommandView& params); 896 897 // Called when a HCI_Read_Encryption_Key_Size command is received. 898 void OnReadEncryptionKeySizeCommand( 899 const pw::bluetooth::emboss::ReadEncryptionKeySizeCommandView& params); 900 901 // Called when a HCI_Enhanced_Accept_Synchronous_Connection_Request command 902 // is received. 903 void OnEnhancedAcceptSynchronousConnectionRequestCommand( 904 const pw::bluetooth::emboss:: 905 EnhancedAcceptSynchronousConnectionRequestCommandView& params); 906 907 // Called when a HCI_Enhanced_Setup_Synchronous_Connection command is 908 // received. 909 void OnEnhancedSetupSynchronousConnectionCommand( 910 const pw::bluetooth::emboss:: 911 EnhancedSetupSynchronousConnectionCommandView& params); 912 913 // Called when a HCI_LE_Read_Remote_Features_Command is received. 914 void OnLEReadRemoteFeaturesCommand( 915 const pw::bluetooth::emboss::LEReadRemoteFeaturesCommandView& params); 916 917 // Called when a HCI_LE_Enable_Encryption command is received, responds with 918 // a successful encryption change event. 919 void OnLEStartEncryptionCommand( 920 const pw::bluetooth::emboss::LEEnableEncryptionCommandView& params); 921 922 void OnWriteSynchronousFlowControlEnableCommand( 923 const pw::bluetooth::emboss::WriteSynchronousFlowControlEnableCommandView& 924 params); 925 926 void OnReadLocalSupportedControllerDelay( 927 const pw::bluetooth::emboss::ReadLocalSupportedControllerDelayCommandView& 928 params); 929 930 void OnAndroidLEGetVendorCapabilities(); 931 932 void OnAndroidA2dpOffloadCommand( 933 const PacketView<hci_spec::CommandHeader>& command_packet); 934 935 void OnAndroidStartA2dpOffload( 936 const android_emb::StartA2dpOffloadCommandView& params); 937 938 void OnAndroidStopA2dpOffload(); 939 940 void OnAndroidLEMultiAdvt( 941 const PacketView<hci_spec::CommandHeader>& command_packet); 942 943 void OnAndroidLEMultiAdvtSetAdvtParam( 944 const android_emb::LEMultiAdvtSetAdvtParamCommandView& params); 945 946 void OnAndroidLEMultiAdvtSetAdvtData( 947 const android_emb::LEMultiAdvtSetAdvtDataCommandView& params); 948 949 void OnAndroidLEMultiAdvtSetScanResp( 950 const android_emb::LEMultiAdvtSetScanRespDataCommandView& params); 951 952 void OnAndroidLEMultiAdvtSetRandomAddr( 953 const android_emb::LEMultiAdvtSetRandomAddrCommandView& params); 954 955 void OnAndroidLEMultiAdvtEnable( 956 const android_emb::LEMultiAdvtEnableCommandView& params); 957 958 // Called when a command with an OGF of hci_spec::kVendorOGF is received. 959 void OnVendorCommand( 960 const PacketView<hci_spec::CommandHeader>& command_packet); 961 962 // Respond to a command packet. This may be done immediately upon reception 963 // or via a client- triggered callback if pause_responses_for_opcode has 964 // been called for that command's opcode. 965 void HandleReceivedCommandPacket( 966 const PacketView<hci_spec::CommandHeader>& command_packet); 967 void HandleReceivedCommandPacket(const hci::CommandPacket& command_packet); 968 969 void OnCommandPacketReceived( 970 const PacketView<hci_spec::CommandHeader>& command_packet); 971 void OnACLDataPacketReceived(const ByteBuffer& acl_data_packet); 972 void OnScoDataPacketReceived(const ByteBuffer& sco_data_packet); 973 void OnIsoDataPacketReceived(const ByteBuffer& iso_data_packet); 974 975 const uint8_t BIT_1 = 1; isBREDRPageScanEnabled()976 bool isBREDRPageScanEnabled() const { 977 return (bredr_scan_state_ >> BIT_1) & BIT_1; 978 } 979 980 enum class AdvertisingProcedure : uint8_t { 981 kUnknown, 982 kLegacy, 983 kExtended, 984 }; 985 advertising_procedure()986 const AdvertisingProcedure& advertising_procedure() const { 987 return advertising_procedure_; 988 } 989 990 bool EnableLegacyAdvertising(); 991 bool EnableExtendedAdvertising(); 992 993 Settings settings_; 994 995 // Value is non-null when A2DP offload is started, and null when it is 996 // stopped. 997 std::optional<OffloadedA2dpChannel> offloaded_a2dp_channel_state_; 998 999 LEScanState le_scan_state_; 1000 LEAdvertisingState legacy_advertising_state_; 1001 std::unordered_map<hci_spec::AdvertisingHandle, LEAdvertisingState> 1002 extended_advertising_states_; 1003 1004 // Used for BR/EDR Scans 1005 uint8_t bredr_scan_state_ = 0x00; 1006 pw::bluetooth::emboss::PageScanType page_scan_type_ = 1007 pw::bluetooth::emboss::PageScanType::STANDARD_SCAN; 1008 uint16_t page_scan_interval_ = 0x0800; 1009 uint16_t page_scan_window_ = 0x0012; 1010 1011 // The GAP local name, as written/read by HCI_(Read/Write)_Local_Name. While 1012 // the aforementioned HCI commands carry the name in a 248 byte buffer, 1013 // |local_name_| contains the intended value. 1014 std::string local_name_; 1015 1016 // The local device class configured by HCI_Write_Class_of_Device. 1017 DeviceClass device_class_; 1018 1019 // Variables used for 1020 // HCI_LE_Create_Connection/HCI_LE_Create_Connection_Cancel. 1021 uint16_t next_conn_handle_ = 0u; 1022 SmartTask le_connect_rsp_task_{pw_dispatcher()}; 1023 std::optional<LEConnectParams> le_connect_params_; 1024 bool le_connect_pending_ = false; 1025 1026 // Variables used for 1027 // HCI_BREDR_Create_Connection/HCI_BREDR_Create_Connection_Cancel. 1028 bool bredr_connect_pending_ = false; 1029 DeviceAddress pending_bredr_connect_addr_; 1030 SmartTask bredr_connect_rsp_task_{pw_dispatcher()}; 1031 1032 // ID used for L2CAP LE signaling channel commands. 1033 uint8_t next_le_sig_id_ = 1u; 1034 1035 // Used to indicate whether to respond back to TX Power Level read or not. 1036 bool respond_to_tx_power_read_ = true; 1037 1038 // The Inquiry Mode that the controller is in. Determines what types of 1039 // events are faked when a hci_spec::kInquiry is started. 1040 pw::bluetooth::emboss::InquiryMode inquiry_mode_; 1041 1042 // The maximum number of advertising sets supported by the controller 1043 uint8_t num_supported_advertising_sets_ = 1; 1044 1045 // The number of results left in Inquiry Mode operation. 1046 // If negative, no limit has been set. 1047 int16_t inquiry_num_responses_left_; 1048 1049 // Used to setup default Command Status event responses. 1050 std::unordered_map<hci_spec::OpCode, pw::bluetooth::emboss::StatusCode> 1051 default_command_status_map_; 1052 1053 // Used to setup default Command Complete event status responses (for 1054 // simulating errors) 1055 std::unordered_map<hci_spec::OpCode, pw::bluetooth::emboss::StatusCode> 1056 default_status_map_; 1057 1058 // The set of fake peers that are visible. 1059 std::unordered_map<DeviceAddress, std::unique_ptr<FakePeer>> peers_; 1060 1061 // Callbacks and counters that are intended for unit tests. 1062 int le_create_connection_command_count_ = 0; 1063 int acl_create_connection_command_count_ = 0; 1064 1065 fit::function<void(pw::bluetooth::emboss::LECreateConnectionCommandView)> 1066 le_create_connection_cb_; 1067 fit::closure controller_parameters_cb_; 1068 ScanStateCallback scan_state_cb_; 1069 fit::closure advertising_state_cb_; 1070 ConnectionStateCallback conn_state_cb_; 1071 LEConnectionParametersCallback le_conn_params_cb_; 1072 fit::closure le_read_remote_features_cb_; 1073 1074 // Associates opcodes with client-supplied pause listeners. Commands with 1075 // these opcodes will hang with no response until the client invokes the 1076 // passed-out closure. 1077 std::unordered_map<hci_spec::OpCode, fit::function<void(fit::closure)>> 1078 paused_opcode_listeners_; 1079 1080 // Called when ACL data packets received. 1081 DataCallback acl_data_callback_ = nullptr; 1082 std::optional<pw::async::HeapDispatcher> data_dispatcher_; 1083 1084 // Called when SCO data packets received. 1085 DataCallback sco_data_callback_ = nullptr; 1086 1087 // Called when ISO data packets received. 1088 DataCallback iso_data_callback_ = nullptr; 1089 1090 bool auto_completed_packets_event_enabled_ = true; 1091 bool auto_disconnection_complete_event_enabled_ = true; 1092 1093 AdvertisingProcedure advertising_procedure_ = AdvertisingProcedure::kUnknown; 1094 uint16_t max_advertising_data_length_ = hci_spec::kMaxLEAdvertisingDataLength; 1095 1096 BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(FakeController); 1097 }; 1098 1099 } // namespace bt::testing 1100