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