xref: /aosp_15_r20/external/pigweed/pw_bluetooth_sapphire/host/testing/fake_controller.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
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 #include "pw_bluetooth_sapphire/internal/host/testing/fake_controller.h"
16 
17 #include <pw_bytes/endian.h>
18 
19 #include <cstddef>
20 #include <cstdint>
21 
22 #include "pw_bluetooth/hci_android.emb.h"
23 #include "pw_bluetooth/hci_data.emb.h"
24 #include "pw_bluetooth/hci_events.emb.h"
25 #include "pw_bluetooth_sapphire/internal/host/common/log.h"
26 #include "pw_bluetooth_sapphire/internal/host/common/packet_view.h"
27 #include "pw_bluetooth_sapphire/internal/host/hci-spec/constants.h"
28 #include "pw_bluetooth_sapphire/internal/host/hci-spec/defaults.h"
29 #include "pw_bluetooth_sapphire/internal/host/hci-spec/protocol.h"
30 #include "pw_bluetooth_sapphire/internal/host/hci-spec/util.h"
31 #include "pw_bluetooth_sapphire/internal/host/hci-spec/vendor_protocol.h"
32 
33 namespace bt::testing {
34 namespace {
35 
36 template <typename NUM_TYPE, typename ENUM_TYPE>
SetBit(NUM_TYPE * num_type,ENUM_TYPE bit)37 void SetBit(NUM_TYPE* num_type, ENUM_TYPE bit) {
38   *num_type |= static_cast<NUM_TYPE>(bit);
39 }
40 
41 template <typename NUM_TYPE, typename ENUM_TYPE>
UnsetBit(NUM_TYPE * num_type,ENUM_TYPE bit)42 void UnsetBit(NUM_TYPE* num_type, ENUM_TYPE bit) {
43   *num_type &= ~static_cast<NUM_TYPE>(bit);
44 }
45 
46 template <typename NUM_TYPE, typename ENUM_TYPE>
CheckBit(NUM_TYPE num_type,ENUM_TYPE bit)47 bool CheckBit(NUM_TYPE num_type, ENUM_TYPE bit) {
48   return (num_type & static_cast<NUM_TYPE>(bit));
49 }
50 
51 }  // namespace
52 
53 namespace android_hci = hci_spec::vendor::android;
54 namespace android_emb = pw::bluetooth::vendor::android_hci;
55 namespace pwemb = pw::bluetooth::emboss;
56 
ApplyDualModeDefaults()57 void FakeController::Settings::ApplyDualModeDefaults() {
58   le_connection_delay = std::chrono::seconds(0);
59   hci_version = pwemb::CoreSpecificationVersion::V5_0;
60   num_hci_command_packets = 250;
61   event_mask = 0;
62   le_event_mask = 0;
63   bd_addr = DeviceAddress();
64   lmp_features_page0 = 0;
65   SetBit(&lmp_features_page0, hci_spec::LMPFeature::kLESupportedHost);
66   SetBit(&lmp_features_page0, hci_spec::LMPFeature::kSimultaneousLEAndBREDR);
67   SetBit(&lmp_features_page0, hci_spec::LMPFeature::kExtendedFeatures);
68   SetBit(&lmp_features_page0, hci_spec::LMPFeature::kRSSIwithInquiryResults);
69   SetBit(&lmp_features_page0, hci_spec::LMPFeature::kExtendedInquiryResponse);
70   SetBit(&lmp_features_page0,
71          hci_spec::LMPFeature::kSecureSimplePairingControllerSupport);
72   lmp_features_page1 = 0;
73   SetBit(&lmp_features_page1,
74          hci_spec::LMPFeature::kSecureSimplePairingHostSupport);
75   lmp_features_page2 = 0;
76   le_features = 0;
77   le_supported_states = 0;
78   std::memset(supported_commands, 0, sizeof(supported_commands));
79   AddBREDRSupportedCommands();
80   AddLESupportedCommands();
81   acl_data_packet_length = 512;
82   total_num_acl_data_packets = 1;
83   le_acl_data_packet_length = 512;
84   le_total_num_acl_data_packets = 1;
85   // Must be 0x01-0xFF, even if not supported
86   synchronous_data_packet_length = 1;
87   total_num_synchronous_data_packets = 0;
88   iso_data_packet_length = 512;
89   total_num_iso_data_packets = 1;
90   android_extension_settings.SetToZeros();
91 }
92 
ApplyLEOnlyDefaults()93 void FakeController::Settings::ApplyLEOnlyDefaults() {
94   ApplyDualModeDefaults();
95 
96   UnsetBit(&lmp_features_page0, hci_spec::LMPFeature::kSimultaneousLEAndBREDR);
97   SetBit(&lmp_features_page0, hci_spec::LMPFeature::kBREDRNotSupported);
98   std::memset(supported_commands, 0, sizeof(supported_commands));
99 
100   AddLESupportedCommands();
101 }
102 
AddBREDRSupportedCommands()103 void FakeController::Settings::AddBREDRSupportedCommands() {
104   auto view = SupportedCommandsView();
105   view.create_connection().Write(true);
106   view.create_connection_cancel().Write(true);
107   view.disconnect().Write(true);
108   view.write_local_name().Write(true);
109   view.read_local_name().Write(true);
110   view.read_scan_enable().Write(true);
111   view.write_scan_enable().Write(true);
112   view.read_page_scan_activity().Write(true);
113   view.write_page_scan_activity().Write(true);
114   view.write_class_of_device().Write(true);
115   view.write_synchronous_flow_control_enable().Write(true);
116   view.read_inquiry_mode().Write(true);
117   view.write_inquiry_mode().Write(true);
118   view.read_page_scan_type().Write(true);
119   view.write_page_scan_type().Write(true);
120   view.read_buffer_size().Write(true);
121   view.read_simple_pairing_mode().Write(true);
122   view.write_simple_pairing_mode().Write(true);
123   view.write_extended_inquiry_response().Write(true);
124   view.write_secure_connections_host_support().Write(true);
125 }
126 
AddLESupportedCommands()127 void FakeController::Settings::AddLESupportedCommands() {
128   auto view = SupportedCommandsView();
129   view.disconnect().Write(true);
130   view.set_event_mask().Write(true);
131   view.reset().Write(true);
132   view.read_local_version_information().Write(true);
133   view.read_local_supported_features().Write(true);
134   view.read_local_extended_features().Write(true);
135   view.write_le_host_support().Write(true);
136   view.le_set_event_mask().Write(true);
137   view.le_read_buffer_size_v1().Write(true);
138   view.le_read_local_supported_features().Write(true);
139   view.le_set_random_address().Write(true);
140   view.le_set_advertising_parameters().Write(true);
141   view.le_set_advertising_data().Write(true);
142   view.le_set_scan_response_data().Write(true);
143   view.le_set_advertising_enable().Write(true);
144   view.le_create_connection().Write(true);
145   view.le_create_connection_cancel().Write(true);
146   view.le_connection_update().Write(true);
147   view.le_read_remote_features().Write(true);
148   view.le_start_encryption().Write(true);
149   view.le_read_buffer_size_v2().Write(true);
150   view.read_local_supported_controller_delay().Write(true);
151 }
152 
ApplyLegacyLEConfig()153 void FakeController::Settings::ApplyLegacyLEConfig() {
154   ApplyLEOnlyDefaults();
155 
156   hci_version = pwemb::CoreSpecificationVersion::V4_2;
157 
158   auto view = pwemb::MakeSupportedCommandsView(supported_commands,
159                                                sizeof(supported_commands));
160   view.le_set_scan_parameters().Write(true);
161   view.le_set_scan_enable().Write(true);
162 }
163 
ApplyExtendedLEConfig()164 void FakeController::Settings::ApplyExtendedLEConfig() {
165   ApplyLEOnlyDefaults();
166 
167   SetBit(&le_features, hci_spec::LESupportedFeature::kLEExtendedAdvertising);
168 
169   auto view = SupportedCommandsView();
170   view.le_set_advertising_set_random_address().Write(true);
171   view.le_set_extended_advertising_parameters().Write(true);
172   view.le_set_extended_advertising_data().Write(true);
173   view.le_set_extended_scan_response_data().Write(true);
174   view.le_set_extended_advertising_enable().Write(true);
175   view.le_read_maximum_advertising_data_length().Write(true);
176   view.le_read_number_of_supported_advertising_sets().Write(true);
177   view.le_remove_advertising_set().Write(true);
178   view.le_clear_advertising_sets().Write(true);
179 }
180 
ApplyAndroidVendorExtensionDefaults()181 void FakeController::Settings::ApplyAndroidVendorExtensionDefaults() {
182   // Settings for the android vendor extensions component within the Fake
183   // Controller. These settings correspond to the vendor capabilities returned
184   // by the controller. See hci_vendor.emb LEGetVendorCapabilities for more
185   // information.
186   auto view = android_extension_settings.view();
187   view.status().Write(pwemb::StatusCode::SUCCESS);
188   view.max_advt_instances().Write(3);
189   view.version_supported().major_number().Write(0);
190   view.version_supported().minor_number().Write(55);
191 }
192 
is_event_unmasked(hci_spec::LEEventMask event) const193 bool FakeController::Settings::is_event_unmasked(
194     hci_spec::LEEventMask event) const {
195   return le_event_mask | static_cast<uint64_t>(event);
196 }
197 
SetDefaultCommandStatus(hci_spec::OpCode opcode,pwemb::StatusCode status)198 void FakeController::SetDefaultCommandStatus(hci_spec::OpCode opcode,
199                                              pwemb::StatusCode status) {
200   default_command_status_map_[opcode] = status;
201 }
202 
ClearDefaultCommandStatus(hci_spec::OpCode opcode)203 void FakeController::ClearDefaultCommandStatus(hci_spec::OpCode opcode) {
204   default_command_status_map_.erase(opcode);
205 }
206 
SetDefaultResponseStatus(hci_spec::OpCode opcode,pwemb::StatusCode status)207 void FakeController::SetDefaultResponseStatus(hci_spec::OpCode opcode,
208                                               pwemb::StatusCode status) {
209   PW_DCHECK(status != pwemb::StatusCode::SUCCESS);
210   default_status_map_[opcode] = status;
211 }
212 
ClearDefaultResponseStatus(hci_spec::OpCode opcode)213 void FakeController::ClearDefaultResponseStatus(hci_spec::OpCode opcode) {
214   default_status_map_.erase(opcode);
215 }
216 
AddPeer(std::unique_ptr<FakePeer> peer)217 bool FakeController::AddPeer(std::unique_ptr<FakePeer> peer) {
218   PW_DCHECK(peer);
219 
220   if (peers_.count(peer->address()) != 0u) {
221     return false;
222   }
223 
224   peer->set_controller(this);
225 
226   // If a scan is enabled then send an advertising report for the peer that just
227   // got registered if it supports advertising.
228   if (peer->send_advertising_report()) {
229     SendAdvertisingReport(*peer);
230     SendScanResponseReport(*peer);
231   }
232 
233   peers_[peer->address()] = std::move(peer);
234   return true;
235 }
236 
RemovePeer(const DeviceAddress & address)237 void FakeController::RemovePeer(const DeviceAddress& address) {
238   peers_.erase(address);
239 }
240 
FindPeer(const DeviceAddress & address)241 FakePeer* FakeController::FindPeer(const DeviceAddress& address) {
242   auto iter = peers_.find(address);
243   return (iter == peers_.end()) ? nullptr : iter->second.get();
244 }
245 
SendCommand(pw::span<const std::byte> command)246 void FakeController::SendCommand(pw::span<const std::byte> command) {
247   PW_CHECK(command.size() >= sizeof(hci_spec::CommandHeader));
248 
249   // Post the packet to simulate async HCI behavior.
250   (void)heap_dispatcher().Post(
251       [self = GetWeakPtr(), command = DynamicByteBuffer(BufferView(command))](
252           pw::async::Context /*ctx*/, pw::Status status) {
253         if (!self.is_alive() || !status.ok()) {
254           return;
255         }
256         const size_t payload_size =
257             command.size() - sizeof(hci_spec::CommandHeader);
258         PacketView<hci_spec::CommandHeader> packet_view(&command, payload_size);
259         self->OnCommandPacketReceived(packet_view);
260       });
261 }
262 
FindByConnHandle(hci_spec::ConnectionHandle handle)263 FakePeer* FakeController::FindByConnHandle(hci_spec::ConnectionHandle handle) {
264   for (auto& [addr, peer] : peers_) {
265     if (peer->HasLink(handle)) {
266       return peer.get();
267     }
268   }
269   return nullptr;
270 }
271 
NextL2CAPCommandId()272 uint8_t FakeController::NextL2CAPCommandId() {
273   // TODO(armansito): Guard against overflow?
274   return next_le_sig_id_++;
275 }
276 
RespondWithCommandComplete(hci_spec::OpCode opcode,pwemb::StatusCode status)277 void FakeController::RespondWithCommandComplete(hci_spec::OpCode opcode,
278                                                 pwemb::StatusCode status) {
279   auto packet = hci::EventPacket::New<pwemb::SimpleCommandCompleteEventWriter>(
280       hci_spec::kCommandCompleteEventCode);
281   auto view = packet.view_t();
282   view.status().Write(status);
283   RespondWithCommandComplete(opcode, &packet);
284 }
285 
RespondWithCommandComplete(hci_spec::OpCode opcode,hci::EventPacket * packet)286 void FakeController::RespondWithCommandComplete(hci_spec::OpCode opcode,
287                                                 hci::EventPacket* packet) {
288   RespondWithCommandComplete(static_cast<pwemb::OpCode>(opcode), packet);
289 }
290 
RespondWithCommandComplete(pwemb::OpCode opcode,hci::EventPacket * packet)291 void FakeController::RespondWithCommandComplete(pwemb::OpCode opcode,
292                                                 hci::EventPacket* packet) {
293   auto header = packet->template view<pwemb::CommandCompleteEventWriter>();
294 
295   header.num_hci_command_packets().Write(settings_.num_hci_command_packets);
296   header.command_opcode_enum().Write(opcode);
297 
298   SendEvent(hci_spec::kCommandCompleteEventCode, packet);
299 }
300 
RespondWithCommandStatus(hci_spec::OpCode opcode,pwemb::StatusCode status)301 void FakeController::RespondWithCommandStatus(hci_spec::OpCode opcode,
302                                               pwemb::StatusCode status) {
303   auto packet = hci::EventPacket::New<pwemb::CommandStatusEventWriter>(
304       hci_spec::kCommandStatusEventCode);
305   auto view = packet.view_t();
306   view.status().Write(status);
307   view.num_hci_command_packets().Write(settings_.num_hci_command_packets);
308   view.command_opcode_enum().Write(static_cast<pwemb::OpCode>(opcode));
309 
310   SendEvent(hci_spec::kCommandStatusEventCode, &packet);
311 }
312 
SendEvent(hci_spec::EventCode event_code,const ByteBuffer & payload)313 void FakeController::SendEvent(hci_spec::EventCode event_code,
314                                const ByteBuffer& payload) {
315   DynamicByteBuffer buffer(sizeof(hci_spec::EventHeader) + payload.size());
316   MutablePacketView<hci_spec::EventHeader> event(&buffer, payload.size());
317 
318   event.mutable_header()->event_code = event_code;
319   event.mutable_header()->parameter_total_size =
320       static_cast<uint8_t>(payload.size());
321   event.mutable_payload_data().Write(payload);
322 
323   SendCommandChannelPacket(buffer);
324 }
325 
SendEvent(hci_spec::EventCode event_code,hci::EventPacket * packet)326 void FakeController::SendEvent(hci_spec::EventCode event_code,
327                                hci::EventPacket* packet) {
328   auto header = packet->template view<pwemb::EventHeaderWriter>();
329   uint8_t parameter_total_size = static_cast<uint8_t>(
330       packet->size() - pwemb::EventHeader::IntrinsicSizeInBytes());
331 
332   header.event_code_uint().Write(event_code);
333   header.parameter_total_size().Write(parameter_total_size);
334 
335   SendCommandChannelPacket(packet->data());
336 }
337 
SendLEMetaEvent(hci_spec::EventCode subevent_code,const ByteBuffer & payload)338 void FakeController::SendLEMetaEvent(hci_spec::EventCode subevent_code,
339                                      const ByteBuffer& payload) {
340   DynamicByteBuffer buffer(pwemb::LEMetaEvent::IntrinsicSizeInBytes() +
341                            payload.size());
342   buffer[0] = subevent_code;
343   buffer.Write(payload, 1);
344   SendEvent(hci_spec::kLEMetaEventCode, buffer);
345 }
346 
SendACLPacket(hci_spec::ConnectionHandle handle,const ByteBuffer & payload)347 void FakeController::SendACLPacket(hci_spec::ConnectionHandle handle,
348                                    const ByteBuffer& payload) {
349   PW_DCHECK(payload.size() <= hci_spec::kMaxACLPayloadSize);
350 
351   DynamicByteBuffer buffer(sizeof(hci_spec::ACLDataHeader) + payload.size());
352   MutablePacketView<hci_spec::ACLDataHeader> acl(&buffer, payload.size());
353 
354   acl.mutable_header()->handle_and_flags =
355       pw::bytes::ConvertOrderTo(cpp20::endian::little, handle);
356   acl.mutable_header()->data_total_length = pw::bytes::ConvertOrderTo(
357       cpp20::endian::little, static_cast<uint16_t>(payload.size()));
358   acl.mutable_payload_data().Write(payload);
359 
360   SendACLDataChannelPacket(buffer);
361 }
362 
SendL2CAPBFrame(hci_spec::ConnectionHandle handle,l2cap::ChannelId channel_id,const ByteBuffer & payload)363 void FakeController::SendL2CAPBFrame(hci_spec::ConnectionHandle handle,
364                                      l2cap::ChannelId channel_id,
365                                      const ByteBuffer& payload) {
366   PW_DCHECK(payload.size() <=
367             hci_spec::kMaxACLPayloadSize - sizeof(l2cap::BasicHeader));
368 
369   DynamicByteBuffer buffer(sizeof(l2cap::BasicHeader) + payload.size());
370   MutablePacketView<l2cap::BasicHeader> bframe(&buffer, payload.size());
371 
372   bframe.mutable_header()->length = pw::bytes::ConvertOrderTo(
373       cpp20::endian::little, static_cast<uint16_t>(payload.size()));
374   bframe.mutable_header()->channel_id =
375       pw::bytes::ConvertOrderTo(cpp20::endian::little, channel_id);
376   bframe.mutable_payload_data().Write(payload);
377 
378   SendACLPacket(handle, buffer);
379 }
380 
SendL2CAPCFrame(hci_spec::ConnectionHandle handle,bool is_le,l2cap::CommandCode code,uint8_t id,const ByteBuffer & payload)381 void FakeController::SendL2CAPCFrame(hci_spec::ConnectionHandle handle,
382                                      bool is_le,
383                                      l2cap::CommandCode code,
384                                      uint8_t id,
385                                      const ByteBuffer& payload) {
386   DynamicByteBuffer buffer(sizeof(l2cap::CommandHeader) + payload.size());
387   MutablePacketView<l2cap::CommandHeader> cframe(&buffer, payload.size());
388 
389   cframe.mutable_header()->code = code;
390   cframe.mutable_header()->id = id;
391   cframe.mutable_header()->length = static_cast<uint16_t>(payload.size());
392   cframe.mutable_payload_data().Write(payload);
393 
394   SendL2CAPBFrame(
395       handle,
396       is_le ? l2cap::kLESignalingChannelId : l2cap::kSignalingChannelId,
397       buffer);
398 }
399 
SendNumberOfCompletedPacketsEvent(hci_spec::ConnectionHandle handle,uint16_t num)400 void FakeController::SendNumberOfCompletedPacketsEvent(
401     hci_spec::ConnectionHandle handle, uint16_t num) {
402   constexpr size_t buffer_size =
403       pwemb::NumberOfCompletedPacketsEvent::MinSizeInBytes() +
404       pwemb::NumberOfCompletedPacketsEventData::IntrinsicSizeInBytes();
405   auto event =
406       hci::EventPacket::New<pwemb::NumberOfCompletedPacketsEventWriter>(
407           hci_spec::kNumberOfCompletedPacketsEventCode, buffer_size);
408   auto view = event.view_t();
409 
410   view.num_handles().Write(1);
411   view.nocp_data()[0].connection_handle().Write(handle);
412   view.nocp_data()[0].num_completed_packets().Write(num);
413 
414   SendEvent(hci_spec::kNumberOfCompletedPacketsEventCode, &event);
415 }
416 
ConnectLowEnergy(const DeviceAddress & addr,pwemb::ConnectionRole role)417 void FakeController::ConnectLowEnergy(const DeviceAddress& addr,
418                                       pwemb::ConnectionRole role) {
419   (void)heap_dispatcher().Post(
420       [addr, role, this](pw::async::Context /*ctx*/, pw::Status status) {
421         if (!status.ok()) {
422           return;
423         }
424         FakePeer* peer = FindPeer(addr);
425         if (!peer) {
426           bt_log(WARN,
427                  "fake-hci",
428                  "no peer found with address: %s",
429                  addr.ToString().c_str());
430           return;
431         }
432 
433         // TODO(armansito): Don't worry about managing multiple links per peer
434         // until this supports Bluetooth classic.
435         if (peer->connected()) {
436           bt_log(WARN, "fake-hci", "peer already connected");
437           return;
438         }
439 
440         hci_spec::ConnectionHandle handle = ++next_conn_handle_;
441         peer->AddLink(handle);
442 
443         NotifyConnectionState(addr, handle, /*connected=*/true);
444 
445         uint16_t interval_min = hci_spec::defaults::kLEConnectionIntervalMin;
446         uint16_t interval_max = hci_spec::defaults::kLEConnectionIntervalMax;
447         uint16_t interval = interval_min + ((interval_max - interval_min) / 2);
448 
449         hci_spec::LEConnectionParameters conn_params(
450             interval, 0, hci_spec::defaults::kLESupervisionTimeout);
451         peer->set_le_params(conn_params);
452 
453         auto packet = hci::EventPacket::New<
454             pwemb::LEEnhancedConnectionCompleteSubeventV1Writer>(
455             hci_spec::kLEMetaEventCode);
456         auto view = packet.view_t();
457         view.le_meta_event().subevent_code().Write(
458             hci_spec::kLEEnhancedConnectionCompleteSubeventCode);
459         view.status().Write(pwemb::StatusCode::SUCCESS);
460         view.peer_address().CopyFrom(addr.value().view());
461         view.peer_address_type().Write(
462             DeviceAddress::DeviceAddrToLeAddr(addr.type()));
463         view.peripheral_latency().Write(conn_params.latency());
464         view.connection_interval().Write(conn_params.interval());
465         view.supervision_timeout().Write(conn_params.supervision_timeout());
466         view.role().Write(role);
467         view.connection_handle().Write(handle);
468         SendCommandChannelPacket(packet.data());
469       });
470 }
471 
SendConnectionRequest(const DeviceAddress & addr,pwemb::LinkType link_type)472 void FakeController::SendConnectionRequest(const DeviceAddress& addr,
473                                            pwemb::LinkType link_type) {
474   FakePeer* peer = FindPeer(addr);
475   PW_CHECK(peer);
476   peer->set_last_connection_request_link_type(link_type);
477 
478   bt_log(DEBUG,
479          "fake-hci",
480          "sending connection request (addr: %s, link: %s)",
481          bt_str(addr),
482          hci_spec::LinkTypeToString(link_type));
483   auto packet = hci::EventPacket::New<pwemb::ConnectionRequestEventWriter>(
484       hci_spec::kConnectionRequestEventCode);
485   packet.view_t().bd_addr().CopyFrom(addr.value().view());
486   packet.view_t().link_type().Write(link_type);
487   SendCommandChannelPacket(packet.data());
488 }
489 
L2CAPConnectionParameterUpdate(const DeviceAddress & addr,const hci_spec::LEPreferredConnectionParameters & params)490 void FakeController::L2CAPConnectionParameterUpdate(
491     const DeviceAddress& addr,
492     const hci_spec::LEPreferredConnectionParameters& params) {
493   (void)heap_dispatcher().Post([addr, params, this](pw::async::Context /*ctx*/,
494                                                     pw::Status status) {
495     if (!status.ok()) {
496       return;
497     }
498     FakePeer* peer = FindPeer(addr);
499     if (!peer) {
500       bt_log(WARN,
501              "fake-hci",
502              "no peer found with address: %s",
503              addr.ToString().c_str());
504       return;
505     }
506 
507     if (!peer->connected()) {
508       bt_log(WARN, "fake-hci", "peer not connected");
509       return;
510     }
511 
512     PW_DCHECK(!peer->logical_links().empty());
513 
514     l2cap::ConnectionParameterUpdateRequestPayload payload;
515     payload.interval_min =
516         pw::bytes::ConvertOrderTo(cpp20::endian::little, params.min_interval());
517     payload.interval_max =
518         pw::bytes::ConvertOrderTo(cpp20::endian::little, params.max_interval());
519     payload.peripheral_latency =
520         pw::bytes::ConvertOrderTo(cpp20::endian::little, params.max_latency());
521     payload.timeout_multiplier = pw::bytes::ConvertOrderTo(
522         cpp20::endian::little, params.supervision_timeout());
523 
524     // TODO(armansito): Instead of picking the first handle we should pick
525     // the handle that matches the current LE-U link.
526     SendL2CAPCFrame(*peer->logical_links().begin(),
527                     /*is_le=*/true,
528                     l2cap::kConnectionParameterUpdateRequest,
529                     NextL2CAPCommandId(),
530                     BufferView(&payload, sizeof(payload)));
531   });
532 }
533 
SendLEConnectionUpdateCompleteSubevent(hci_spec::ConnectionHandle handle,const hci_spec::LEConnectionParameters & params,pwemb::StatusCode status)534 void FakeController::SendLEConnectionUpdateCompleteSubevent(
535     hci_spec::ConnectionHandle handle,
536     const hci_spec::LEConnectionParameters& params,
537     pwemb::StatusCode status) {
538   auto packet =
539       hci::EventPacket::New<pwemb::LEConnectionUpdateCompleteSubeventWriter>(
540           hci_spec::kLEMetaEventCode);
541   auto view = packet.view_t();
542   view.le_meta_event().subevent_code().Write(
543       hci_spec::kLEConnectionUpdateCompleteSubeventCode);
544   view.status().Write(status);
545   view.connection_handle().Write(handle);
546   view.connection_interval().UncheckedWrite(params.interval());
547   view.peripheral_latency().Write(params.latency());
548   view.supervision_timeout().UncheckedWrite(params.supervision_timeout());
549   SendCommandChannelPacket(packet.data());
550 }
551 
Disconnect(const DeviceAddress & addr,pwemb::StatusCode reason)552 void FakeController::Disconnect(const DeviceAddress& addr,
553                                 pwemb::StatusCode reason) {
554   (void)heap_dispatcher().Post(
555       [this, addr, reason](pw::async::Context /*ctx*/, pw::Status status) {
556         if (!status.ok()) {
557           return;
558         }
559         FakePeer* peer = FindPeer(addr);
560         if (!peer || !peer->connected()) {
561           bt_log(WARN,
562                  "fake-hci",
563                  "no connected peer found with address: %s",
564                  addr.ToString().c_str());
565           return;
566         }
567 
568         auto links = peer->Disconnect();
569         PW_DCHECK(!peer->connected());
570         PW_DCHECK(!links.empty());
571 
572         for (auto link : links) {
573           NotifyConnectionState(addr, link, /*connected=*/false);
574           SendDisconnectionCompleteEvent(link, reason);
575         }
576       });
577 }
578 
SendDisconnectionCompleteEvent(hci_spec::ConnectionHandle handle,pwemb::StatusCode reason)579 void FakeController::SendDisconnectionCompleteEvent(
580     hci_spec::ConnectionHandle handle, pwemb::StatusCode reason) {
581   auto event = hci::EventPacket::New<pwemb::DisconnectionCompleteEventWriter>(
582       hci_spec::kDisconnectionCompleteEventCode);
583   event.view_t().status().Write(pwemb::StatusCode::SUCCESS);
584   event.view_t().connection_handle().Write(handle);
585   event.view_t().reason().Write(reason);
586   SendCommandChannelPacket(event.data());
587 }
588 
SendEncryptionChangeEvent(hci_spec::ConnectionHandle handle,pwemb::StatusCode status,pwemb::EncryptionStatus encryption_enabled)589 void FakeController::SendEncryptionChangeEvent(
590     hci_spec::ConnectionHandle handle,
591     pwemb::StatusCode status,
592     pwemb::EncryptionStatus encryption_enabled) {
593   auto response = hci::EventPacket::New<pwemb::EncryptionChangeEventV1Writer>(
594       hci_spec::kEncryptionChangeEventCode);
595   response.view_t().status().Write(status);
596   response.view_t().connection_handle().Write(handle);
597   response.view_t().encryption_enabled().Write(encryption_enabled);
598   SendCommandChannelPacket(response.data());
599 }
600 
MaybeRespondWithDefaultCommandStatus(hci_spec::OpCode opcode)601 bool FakeController::MaybeRespondWithDefaultCommandStatus(
602     hci_spec::OpCode opcode) {
603   auto iter = default_command_status_map_.find(opcode);
604   if (iter == default_command_status_map_.end()) {
605     return false;
606   }
607 
608   RespondWithCommandStatus(opcode, iter->second);
609   return true;
610 }
611 
MaybeRespondWithDefaultStatus(hci_spec::OpCode opcode)612 bool FakeController::MaybeRespondWithDefaultStatus(hci_spec::OpCode opcode) {
613   auto iter = default_status_map_.find(opcode);
614   if (iter == default_status_map_.end())
615     return false;
616 
617   bt_log(INFO,
618          "fake-hci",
619          "responding with error (command: %#.4x, status: %#.2hhx)",
620          opcode,
621          static_cast<unsigned char>(iter->second));
622   RespondWithCommandComplete(opcode, iter->second);
623   return true;
624 }
625 
SendInquiryResponses()626 void FakeController::SendInquiryResponses() {
627   // TODO(jamuraa): combine some of these into a single response event
628   for (const auto& [addr, peer] : peers_) {
629     if (!peer->supports_bredr()) {
630       continue;
631     }
632 
633     SendCommandChannelPacket(peer->CreateInquiryResponseEvent(inquiry_mode_));
634     inquiry_num_responses_left_--;
635     if (inquiry_num_responses_left_ == 0) {
636       break;
637     }
638   }
639 }
640 
SendAdvertisingReports()641 void FakeController::SendAdvertisingReports() {
642   if (!le_scan_state_.enabled || peers_.empty()) {
643     return;
644   }
645 
646   for (const auto& iter : peers_) {
647     if (iter.second->send_advertising_report()) {
648       SendAdvertisingReport(*iter.second);
649       SendScanResponseReport(*iter.second);
650     }
651   }
652 
653   // We'll send new reports for the same peers if duplicate filtering is
654   // disabled.
655   if (!le_scan_state_.filter_duplicates) {
656     (void)heap_dispatcher().Post(
657         [this](pw::async::Context /*ctx*/, pw::Status status) {
658           if (status.ok()) {
659             SendAdvertisingReports();
660           }
661         });
662   }
663 }
664 
SendAdvertisingReport(const FakePeer & peer)665 void FakeController::SendAdvertisingReport(const FakePeer& peer) {
666   if (!le_scan_state_.enabled || !peer.supports_le() ||
667       !peer.advertising_enabled()) {
668     return;
669   }
670 
671   DynamicByteBuffer buffer;
672   if (advertising_procedure() == AdvertisingProcedure::kExtended) {
673     buffer = peer.BuildExtendedAdvertisingReportEvent();
674   } else {
675     buffer = peer.BuildLegacyAdvertisingReportEvent();
676   }
677 
678   SendCommandChannelPacket(buffer);
679 }
680 
SendScanResponseReport(const FakePeer & peer)681 void FakeController::SendScanResponseReport(const FakePeer& peer) {
682   if (!le_scan_state_.enabled || !peer.supports_le() ||
683       !peer.advertising_enabled()) {
684     return;
685   }
686 
687   // We want to send scan response packets only during an active scan and if the
688   // peer is scannable.
689   bool is_active_scan = (le_scan_state_.scan_type == pwemb::LEScanType::ACTIVE);
690   bool need_scan_rsp = (is_active_scan && peer.scannable());
691 
692   if (!need_scan_rsp) {
693     return;
694   }
695 
696   DynamicByteBuffer buffer;
697   if (advertising_procedure() == AdvertisingProcedure::kExtended) {
698     buffer = peer.BuildExtendedScanResponseEvent();
699   } else {
700     buffer = peer.BuildLegacyScanResponseReportEvent();
701   }
702 
703   SendCommandChannelPacket(buffer);
704 }
705 
NotifyControllerParametersChanged()706 void FakeController::NotifyControllerParametersChanged() {
707   if (controller_parameters_cb_) {
708     controller_parameters_cb_();
709   }
710 }
711 
NotifyAdvertisingState()712 void FakeController::NotifyAdvertisingState() {
713   if (advertising_state_cb_) {
714     advertising_state_cb_();
715   }
716 }
717 
NotifyConnectionState(const DeviceAddress & addr,hci_spec::ConnectionHandle handle,bool connected,bool canceled)718 void FakeController::NotifyConnectionState(const DeviceAddress& addr,
719                                            hci_spec::ConnectionHandle handle,
720                                            bool connected,
721                                            bool canceled) {
722   if (conn_state_cb_) {
723     conn_state_cb_(addr, handle, connected, canceled);
724   }
725 }
726 
NotifyLEConnectionParameters(const DeviceAddress & addr,const hci_spec::LEConnectionParameters & params)727 void FakeController::NotifyLEConnectionParameters(
728     const DeviceAddress& addr, const hci_spec::LEConnectionParameters& params) {
729   if (le_conn_params_cb_) {
730     le_conn_params_cb_(addr, params);
731   }
732 }
733 
CaptureLEConnectParams(const pwemb::LECreateConnectionCommandView & params)734 void FakeController::CaptureLEConnectParams(
735     const pwemb::LECreateConnectionCommandView& params) {
736   le_connect_params_ = LEConnectParams();
737 
738   switch (params.initiator_filter_policy().Read()) {
739     case pwemb::GenericEnableParam::ENABLE:
740       le_connect_params_->use_filter_policy = true;
741       break;
742     case pwemb::GenericEnableParam::DISABLE:
743       le_connect_params_->use_filter_policy = false;
744       break;
745   }
746 
747   le_connect_params_->own_address_type = params.own_address_type().Read();
748   le_connect_params_->peer_address = DeviceAddress(
749       DeviceAddress::LeAddrToDeviceAddr(params.peer_address_type().Read()),
750       DeviceAddressBytes(params.peer_address()));
751 
752   LEConnectParams::Parameters& connect_params =
753       le_connect_params_
754           ->phy_conn_params[LEConnectParams::InitiatingPHYs::kLE_1M];
755   connect_params.scan_interval = params.le_scan_interval().Read();
756   connect_params.scan_window = params.le_scan_window().Read();
757   connect_params.connection_interval_min =
758       params.connection_interval_min().Read();
759   connect_params.connection_interval_max =
760       params.connection_interval_max().Read();
761   connect_params.max_latency = params.max_latency().Read();
762   connect_params.supervision_timeout = params.supervision_timeout().Read();
763   connect_params.min_ce_length = params.min_connection_event_length().Read();
764   connect_params.max_ce_length = params.max_connection_event_length().Read();
765 }
766 
CaptureLEConnectParamsForPHY(const pwemb::LEExtendedCreateConnectionCommandV1View & params,LEConnectParams::InitiatingPHYs phy)767 void FakeController::CaptureLEConnectParamsForPHY(
768     const pwemb::LEExtendedCreateConnectionCommandV1View& params,
769     LEConnectParams::InitiatingPHYs phy) {
770   int index = static_cast<int>(phy);
771 
772   LEConnectParams::Parameters& connect_params =
773       le_connect_params_->phy_conn_params[phy];
774   connect_params.scan_interval = params.data()[index].scan_interval().Read();
775   connect_params.scan_window = params.data()[index].scan_window().Read();
776   connect_params.connection_interval_min =
777       params.data()[index].connection_interval_min().Read();
778   connect_params.connection_interval_min =
779       params.data()[index].connection_interval_max().Read();
780   connect_params.max_latency = params.data()[index].max_latency().Read();
781   connect_params.supervision_timeout =
782       params.data()[index].supervision_timeout().Read();
783   connect_params.min_ce_length =
784       params.data()[index].min_connection_event_length().Read();
785   connect_params.max_ce_length =
786       params.data()[index].max_connection_event_length().Read();
787 }
788 
CaptureLEConnectParams(const pwemb::LEExtendedCreateConnectionCommandV1View & params)789 void FakeController::CaptureLEConnectParams(
790     const pwemb::LEExtendedCreateConnectionCommandV1View& params) {
791   le_connect_params_ = LEConnectParams();
792 
793   switch (params.initiator_filter_policy().Read()) {
794     case pwemb::GenericEnableParam::ENABLE:
795       le_connect_params_->use_filter_policy = true;
796       break;
797     case pwemb::GenericEnableParam::DISABLE:
798       le_connect_params_->use_filter_policy = false;
799       break;
800   }
801 
802   le_connect_params_->own_address_type = params.own_address_type().Read();
803   le_connect_params_->peer_address = DeviceAddress(
804       DeviceAddress::LeAddrToDeviceAddr(params.peer_address_type().Read()),
805       DeviceAddressBytes(params.peer_address()));
806 
807   CaptureLEConnectParamsForPHY(params, LEConnectParams::InitiatingPHYs::kLE_1M);
808   CaptureLEConnectParamsForPHY(params, LEConnectParams::InitiatingPHYs::kLE_2M);
809   CaptureLEConnectParamsForPHY(params,
810                                LEConnectParams::InitiatingPHYs::kLE_Coded);
811 }
812 
OnCreateConnectionCommandReceived(const pwemb::CreateConnectionCommandView & params)813 void FakeController::OnCreateConnectionCommandReceived(
814     const pwemb::CreateConnectionCommandView& params) {
815   acl_create_connection_command_count_++;
816 
817   // Cannot issue this command while a request is already pending.
818   if (bredr_connect_pending_) {
819     RespondWithCommandStatus(hci_spec::kCreateConnection,
820                              pwemb::StatusCode::COMMAND_DISALLOWED);
821     return;
822   }
823 
824   const DeviceAddress peer_address(DeviceAddress::Type::kBREDR,
825                                    DeviceAddressBytes(params.bd_addr()));
826   pwemb::StatusCode status = pwemb::StatusCode::SUCCESS;
827 
828   // Find the peer that matches the requested address.
829   FakePeer* peer = FindPeer(peer_address);
830   if (peer) {
831     if (peer->connected()) {
832       status = pwemb::StatusCode::CONNECTION_ALREADY_EXISTS;
833     } else {
834       status = peer->connect_status();
835     }
836   }
837 
838   // First send the Command Status response.
839   RespondWithCommandStatus(hci_spec::kCreateConnection, status);
840 
841   // If we just sent back an error status then the operation is complete.
842   if (status != pwemb::StatusCode::SUCCESS)
843     return;
844 
845   bredr_connect_pending_ = true;
846   pending_bredr_connect_addr_ = peer_address;
847 
848   // The procedure was initiated successfully but the peer cannot be connected
849   // because it either doesn't exist or isn't connectable.
850   if (!peer || !peer->connectable()) {
851     bt_log(INFO,
852            "fake-hci",
853            "requested peer %s cannot be connected; request will time out",
854            peer_address.ToString().c_str());
855 
856     bredr_connect_rsp_task_.Cancel();
857     bredr_connect_rsp_task_.set_function(
858         [this, peer_address](pw::async::Context /*ctx*/, pw::Status status) {
859           if (!status.ok()) {
860             return;
861           }
862           bredr_connect_pending_ = false;
863 
864           auto response =
865               hci::EventPacket::New<pwemb::ConnectionCompleteEventWriter>(
866                   hci_spec::kConnectionCompleteEventCode);
867           response.view_t().status().Write(pwemb::StatusCode::PAGE_TIMEOUT);
868           response.view_t().bd_addr().CopyFrom(peer_address.value().view());
869           SendCommandChannelPacket(response.data());
870         });
871 
872     // Default page timeout of 5.12s
873     // See Core Spec v5.0 Vol 2, Part E, Section 6.6
874     constexpr pw::chrono::SystemClock::duration default_page_timeout =
875         std::chrono::microseconds(static_cast<int64_t>(625) * 0x2000);
876     bredr_connect_rsp_task_.PostAfter(default_page_timeout);
877     return;
878   }
879 
880   if (next_conn_handle_ == 0x0FFF) {
881     // Ran out of handles
882     status = pwemb::StatusCode::CONNECTION_LIMIT_EXCEEDED;
883   } else {
884     status = peer->connect_response();
885   }
886 
887   auto response = hci::EventPacket::New<pwemb::ConnectionCompleteEventWriter>(
888       hci_spec::kConnectionCompleteEventCode);
889   response.view_t().status().Write(status);
890   response.view_t().bd_addr().CopyFrom(params.bd_addr());
891   response.view_t().link_type().Write(pwemb::LinkType::ACL);
892   response.view_t().encryption_enabled().Write(
893       pwemb::GenericEnableParam::DISABLE);
894 
895   if (status == pwemb::StatusCode::SUCCESS) {
896     hci_spec::ConnectionHandle handle = ++next_conn_handle_;
897     response.view_t().connection_handle().Write(handle);
898   }
899 
900   // Don't send a connection event if we were asked to force the request to
901   // remain pending. This is used by test cases that operate during the pending
902   // state.
903   if (peer->force_pending_connect()) {
904     return;
905   }
906 
907   bredr_connect_rsp_task_.Cancel();
908   bredr_connect_rsp_task_.set_function(
909       [response, peer, this](pw::async::Context /*ctx*/,
910                              pw::Status status) mutable {
911         if (!status.ok()) {
912           return;
913         }
914         bredr_connect_pending_ = false;
915 
916         if (response.view_t().status().Read() == pwemb::StatusCode::SUCCESS) {
917           bool notify = !peer->connected();
918           hci_spec::ConnectionHandle handle =
919               response.view_t().connection_handle().Read();
920           peer->AddLink(handle);
921           if (notify && peer->connected()) {
922             NotifyConnectionState(peer->address(), handle, /*connected=*/true);
923           }
924         }
925 
926         SendCommandChannelPacket(response.data());
927       });
928   bredr_connect_rsp_task_.Post();
929 }
930 
OnLECreateConnectionCommandReceived(const pwemb::LECreateConnectionCommandView & params)931 void FakeController::OnLECreateConnectionCommandReceived(
932     const pwemb::LECreateConnectionCommandView& params) {
933   le_create_connection_command_count_++;
934 
935   if (advertising_procedure() == AdvertisingProcedure::kExtended) {
936     RespondWithCommandStatus(hci_spec::kLECreateConnection,
937                              pwemb::StatusCode::COMMAND_DISALLOWED);
938     return;
939   }
940 
941   if (le_create_connection_cb_) {
942     le_create_connection_cb_(params);
943   }
944 
945   // Cannot issue this command while a request is already pending.
946   if (le_connect_pending_) {
947     RespondWithCommandStatus(hci_spec::kLECreateConnection,
948                              pwemb::StatusCode::COMMAND_DISALLOWED);
949     return;
950   }
951 
952   // The link is considered lost after connection_interval_max * 2. Connection
953   // events (when data pdus are transmitted) must occur at least once within
954   // that time frame.
955   if (params.max_connection_event_length().Read() >
956       2 * params.connection_interval_max().Read()) {
957     RespondWithCommandStatus(hci_spec::kLECreateConnection,
958                              pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
959     return;
960   }
961 
962   std::optional<DeviceAddress::Type> addr_type =
963       DeviceAddress::LeAddrToDeviceAddr(params.peer_address_type().Read());
964   PW_DCHECK(addr_type && *addr_type != DeviceAddress::Type::kBREDR);
965 
966   const DeviceAddress peer_address(*addr_type,
967                                    DeviceAddressBytes(params.peer_address()));
968   pw::bluetooth::emboss::StatusCode status =
969       pw::bluetooth::emboss::StatusCode::SUCCESS;
970 
971   // Find the peer that matches the requested address.
972   FakePeer* peer = FindPeer(peer_address);
973   if (peer) {
974     if (peer->connected()) {
975       status = pwemb::StatusCode::CONNECTION_ALREADY_EXISTS;
976     } else {
977       status = peer->connect_status();
978     }
979   }
980 
981   // First send the Command Status response.
982   RespondWithCommandStatus(hci_spec::kLECreateConnection, status);
983 
984   // If we just sent back an error status then the operation is complete.
985   if (status != pwemb::StatusCode::SUCCESS) {
986     return;
987   }
988 
989   le_connect_pending_ = true;
990   CaptureLEConnectParams(params);
991 
992   // The procedure was initiated successfully but the peer cannot be connected
993   // because it either doesn't exist or isn't connectable.
994   if (!peer || !peer->connectable()) {
995     bt_log(INFO,
996            "fake-hci",
997            "requested fake peer cannot be connected; request will time out");
998     return;
999   }
1000 
1001   // Don't send a connection event if we were asked to force the request to
1002   // remain pending. This is used by test cases that operate during the pending
1003   // state.
1004   if (peer->force_pending_connect()) {
1005     return;
1006   }
1007 
1008   if (next_conn_handle_ == 0x0FFF) {
1009     // Ran out of handles
1010     status = pwemb::StatusCode::CONNECTION_LIMIT_EXCEEDED;
1011   } else {
1012     status = peer->connect_response();
1013   }
1014 
1015   uint16_t interval_min = params.connection_interval_min().Read();
1016   uint16_t interval_max = params.connection_interval_max().Read();
1017   uint16_t interval = interval_min + ((interval_max - interval_min) / 2);
1018 
1019   hci_spec::LEConnectionParameters conn_params(
1020       interval,
1021       params.max_latency().Read(),
1022       params.supervision_timeout().Read());
1023   peer->set_le_params(conn_params);
1024 
1025   bool use_enhanced_connection_complete = settings_.is_event_unmasked(
1026       hci_spec::LEEventMask::kLEEnhancedConnectionComplete);
1027   if (use_enhanced_connection_complete) {
1028     SendEnhancedConnectionCompleteEvent(status,
1029                                         params,
1030                                         interval,
1031                                         params.max_latency().Read(),
1032                                         params.supervision_timeout().Read());
1033   } else {
1034     SendConnectionCompleteEvent(status, params, interval);
1035   }
1036 }
1037 
OnLEExtendedCreateConnectionCommandReceived(const pwemb::LEExtendedCreateConnectionCommandV1View & params)1038 void FakeController::OnLEExtendedCreateConnectionCommandReceived(
1039     const pwemb::LEExtendedCreateConnectionCommandV1View& params) {
1040   if (!EnableExtendedAdvertising()) {
1041     bt_log(INFO,
1042            "fake-hci",
1043            "extended create connection command rejected, legacy advertising is "
1044            "in use");
1045     RespondWithCommandStatus(hci_spec::kLEExtendedCreateConnection,
1046                              pwemb::StatusCode::COMMAND_DISALLOWED);
1047     return;
1048   }
1049 
1050   if (const auto& phys = params.initiating_phys();
1051       !phys.le_1m().Read() && !phys.le_2m().Read() && phys.le_coded().Read()) {
1052     RespondWithCommandStatus(hci_spec::kLEExtendedCreateConnection,
1053                              pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
1054   }
1055 
1056   // Cannot issue this command while a request is already pending.
1057   if (le_connect_pending_) {
1058     RespondWithCommandStatus(hci_spec::kLEExtendedCreateConnection,
1059                              pwemb::StatusCode::COMMAND_DISALLOWED);
1060     return;
1061   }
1062 
1063   // The link is considered lost after connection_interval_max * 2. Connection
1064   // events (when data pdus are transmitted) must occur at least once within
1065   // that time frame.
1066   if (params.data()[0].max_connection_event_length().Read() >
1067       2 * params.data()[0].connection_interval_max().Read()) {
1068     RespondWithCommandStatus(hci_spec::kLEExtendedCreateConnection,
1069                              pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
1070     return;
1071   }
1072 
1073   DeviceAddress::Type addr_type =
1074       DeviceAddress::LeAddrToDeviceAddr(params.peer_address_type().Read());
1075   const DeviceAddress peer_address(addr_type,
1076                                    DeviceAddressBytes(params.peer_address()));
1077 
1078   pwemb::StatusCode status = pwemb::StatusCode::SUCCESS;
1079 
1080   // Find the peer that matches the requested address.
1081   FakePeer* peer = FindPeer(peer_address);
1082   if (peer) {
1083     if (peer->connected()) {
1084       status = pwemb::StatusCode::CONNECTION_ALREADY_EXISTS;
1085     } else {
1086       status = peer->connect_status();
1087     }
1088   }
1089 
1090   // First send the Command Status response.
1091   RespondWithCommandStatus(hci_spec::kLEExtendedCreateConnection, status);
1092 
1093   // If we just sent back an error status then the operation is complete.
1094   if (status != pwemb::StatusCode::SUCCESS) {
1095     return;
1096   }
1097 
1098   le_connect_pending_ = true;
1099   CaptureLEConnectParams(params);
1100 
1101   // The procedure was initiated successfully but the peer cannot be connected
1102   // because it either doesn't exist or isn't connectable.
1103   if (!peer || !peer->connectable()) {
1104     bt_log(INFO,
1105            "fake-hci",
1106            "requested fake peer cannot be connected; request will time out");
1107     return;
1108   }
1109 
1110   // Don't send a connection event if we were asked to force the request to
1111   // remain pending. This is used by test cases that operate during the pending
1112   // state.
1113   if (peer->force_pending_connect()) {
1114     return;
1115   }
1116 
1117   if (next_conn_handle_ == 0x0FFF) {
1118     // Ran out of handles
1119     status = pwemb::StatusCode::CONNECTION_LIMIT_EXCEEDED;
1120   } else {
1121     status = peer->connect_response();
1122   }
1123 
1124   uint16_t interval_min = params.data()[0].connection_interval_min().Read();
1125   uint16_t interval_max = params.data()[0].connection_interval_max().Read();
1126   uint16_t interval = interval_min + ((interval_max - interval_min) / 2);
1127 
1128   hci_spec::LEConnectionParameters conn_params(
1129       interval,
1130       params.data()[0].max_latency().Read(),
1131       params.data()[0].supervision_timeout().Read());
1132   peer->set_le_params(conn_params);
1133 
1134   SendEnhancedConnectionCompleteEvent(
1135       status,
1136       params,
1137       interval,
1138       params.data()[0].max_latency().Read(),
1139       params.data()[0].supervision_timeout().Read());
1140 }
1141 
1142 template <typename T>
SendEnhancedConnectionCompleteEvent(pwemb::StatusCode status,const T & params,uint16_t interval,uint16_t max_latency,uint16_t supervision_timeout)1143 void FakeController::SendEnhancedConnectionCompleteEvent(
1144     pwemb::StatusCode status,
1145     const T& params,
1146     uint16_t interval,
1147     uint16_t max_latency,
1148     uint16_t supervision_timeout) {
1149   DeviceAddress::Type addr_type =
1150       DeviceAddress::LeAddrToDeviceAddr(params.peer_address_type().Read());
1151   const DeviceAddress peer_address(addr_type,
1152                                    DeviceAddressBytes(params.peer_address()));
1153 
1154   auto packet = hci::EventPacket::New<
1155       pwemb::LEEnhancedConnectionCompleteSubeventV1Writer>(
1156       hci_spec::kLEMetaEventCode);
1157   auto view = packet.view_t();
1158   view.le_meta_event().subevent_code().Write(
1159       hci_spec::kLEEnhancedConnectionCompleteSubeventCode);
1160   view.status().Write(status);
1161   view.peer_address().CopyFrom(params.peer_address());
1162   view.peer_address_type().Write(DeviceAddress::DeviceAddrToLeAddr(addr_type));
1163   view.peripheral_latency().Write(max_latency);
1164   view.connection_interval().Write(interval);
1165   view.supervision_timeout().Write(supervision_timeout);
1166   view.role().Write(settings_.le_connection_role);
1167   view.connection_handle().Write(++next_conn_handle_);
1168 
1169   le_connect_rsp_task_.Cancel();
1170   le_connect_rsp_task_.set_function(
1171       [packet, address = peer_address, this](pw::async::Context /*ctx*/,
1172                                              pw::Status status) {
1173         auto peer = FindPeer(address);
1174         if (!peer || !status.ok()) {
1175           // The peer has been removed or dispatcher shut down; Ignore this
1176           // response
1177           return;
1178         }
1179 
1180         le_connect_pending_ = false;
1181 
1182         auto view =
1183             packet.view<pwemb::LEEnhancedConnectionCompleteSubeventV1View>();
1184         if (view.status().Read() == pwemb::StatusCode::SUCCESS) {
1185           bool not_previously_connected = !peer->connected();
1186           hci_spec::ConnectionHandle handle = view.connection_handle().Read();
1187           peer->AddLink(handle);
1188           if (not_previously_connected && peer->connected()) {
1189             NotifyConnectionState(peer->address(), handle, /*connected=*/true);
1190           }
1191         }
1192 
1193         SendCommandChannelPacket(packet.data());
1194       });
1195 
1196   le_connect_rsp_task_.PostAfter(settings_.le_connection_delay);
1197 }
1198 
SendConnectionCompleteEvent(pwemb::StatusCode status,const pwemb::LECreateConnectionCommandView & params,uint16_t interval)1199 void FakeController::SendConnectionCompleteEvent(
1200     pwemb::StatusCode status,
1201     const pwemb::LECreateConnectionCommandView& params,
1202     uint16_t interval) {
1203   DeviceAddress::Type addr_type =
1204       DeviceAddress::LeAddrToDeviceAddr(params.peer_address_type().Read());
1205   const DeviceAddress peer_address(addr_type,
1206                                    DeviceAddressBytes(params.peer_address()));
1207 
1208   auto packet =
1209       hci::EventPacket::New<pwemb::LEConnectionCompleteSubeventWriter>(
1210           hci_spec::kLEMetaEventCode);
1211   auto view = packet.view_t();
1212   view.le_meta_event().subevent_code().Write(
1213       hci_spec::kLEConnectionCompleteSubeventCode);
1214   view.status().Write(status);
1215   view.peer_address().CopyFrom(params.peer_address());
1216   view.peer_address_type().Write(
1217       DeviceAddress::DeviceAddrToLePeerAddr(addr_type));
1218 
1219   view.peripheral_latency().CopyFrom(params.max_latency());
1220   view.connection_interval().Write(interval);
1221   view.supervision_timeout().CopyFrom(params.supervision_timeout());
1222   view.role().Write(settings_.le_connection_role);
1223   view.connection_handle().Write(++next_conn_handle_);
1224 
1225   le_connect_rsp_task_.Cancel();
1226   le_connect_rsp_task_.set_function(
1227       [packet, address = peer_address, this](pw::async::Context /*ctx*/,
1228                                              pw::Status status) {
1229         auto peer = FindPeer(address);
1230         if (!peer || !status.ok()) {
1231           // The peer has been removed or dispatcher shut down; Ignore this
1232           // response
1233           return;
1234         }
1235 
1236         le_connect_pending_ = false;
1237 
1238         auto view = packet.view<pwemb::LEConnectionCompleteSubeventView>();
1239         if (view.status().Read() == pwemb::StatusCode::SUCCESS) {
1240           bool not_previously_connected = !peer->connected();
1241           hci_spec::ConnectionHandle handle = view.connection_handle().Read();
1242           peer->AddLink(handle);
1243           if (not_previously_connected && peer->connected()) {
1244             NotifyConnectionState(peer->address(), handle, /*connected=*/true);
1245           }
1246         }
1247 
1248         SendCommandChannelPacket(packet.data());
1249       });
1250   le_connect_rsp_task_.PostAfter(settings_.le_connection_delay);
1251 }
1252 
OnLEConnectionUpdateCommandReceived(const pwemb::LEConnectionUpdateCommandView & params)1253 void FakeController::OnLEConnectionUpdateCommandReceived(
1254     const pwemb::LEConnectionUpdateCommandView& params) {
1255   hci_spec::ConnectionHandle handle = params.connection_handle().Read();
1256   FakePeer* peer = FindByConnHandle(handle);
1257   if (!peer) {
1258     RespondWithCommandStatus(hci_spec::kLEConnectionUpdate,
1259                              pwemb::StatusCode::UNKNOWN_CONNECTION_ID);
1260     return;
1261   }
1262 
1263   PW_DCHECK(peer->connected());
1264 
1265   uint16_t min_interval = params.connection_interval_min().UncheckedRead();
1266   uint16_t max_interval = params.connection_interval_max().UncheckedRead();
1267   uint16_t max_latency = params.max_latency().UncheckedRead();
1268   uint16_t supv_timeout = params.supervision_timeout().UncheckedRead();
1269 
1270   if (min_interval > max_interval) {
1271     RespondWithCommandStatus(hci_spec::kLEConnectionUpdate,
1272                              pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
1273     return;
1274   }
1275 
1276   RespondWithCommandStatus(hci_spec::kLEConnectionUpdate,
1277                            pwemb::StatusCode::SUCCESS);
1278 
1279   hci_spec::LEConnectionParameters conn_params(
1280       min_interval + ((max_interval - min_interval) / 2),
1281       max_latency,
1282       supv_timeout);
1283   peer->set_le_params(conn_params);
1284 
1285   auto packet =
1286       hci::EventPacket::New<pwemb::LEConnectionUpdateCompleteSubeventWriter>(
1287           hci_spec::kLEMetaEventCode);
1288   auto view = packet.view_t();
1289   view.le_meta_event().subevent_code().Write(
1290       hci_spec::kLEConnectionUpdateCompleteSubeventCode);
1291   view.connection_handle().CopyFrom(params.connection_handle());
1292   if (peer->supports_ll_conn_update_procedure()) {
1293     view.status().Write(pwemb::StatusCode::SUCCESS);
1294     view.connection_interval().UncheckedWrite(conn_params.interval());
1295     view.peripheral_latency().CopyFrom(params.max_latency());
1296     view.supervision_timeout().UncheckedCopyFrom(params.supervision_timeout());
1297   } else {
1298     view.status().Write(pwemb::StatusCode::UNSUPPORTED_REMOTE_FEATURE);
1299   }
1300   SendCommandChannelPacket(packet.data());
1301 
1302   NotifyLEConnectionParameters(peer->address(), conn_params);
1303 }
1304 
OnDisconnectCommandReceived(const pwemb::DisconnectCommandView & params)1305 void FakeController::OnDisconnectCommandReceived(
1306     const pwemb::DisconnectCommandView& params) {
1307   hci_spec::ConnectionHandle handle = params.connection_handle().Read();
1308 
1309   // Find the peer that matches the disconnected handle.
1310   FakePeer* peer = FindByConnHandle(handle);
1311   if (!peer) {
1312     RespondWithCommandStatus(hci_spec::kDisconnect,
1313                              pwemb::StatusCode::UNKNOWN_CONNECTION_ID);
1314     return;
1315   }
1316 
1317   PW_DCHECK(peer->connected());
1318 
1319   RespondWithCommandStatus(hci_spec::kDisconnect, pwemb::StatusCode::SUCCESS);
1320 
1321   bool notify = peer->connected();
1322   peer->RemoveLink(handle);
1323   if (notify && !peer->connected()) {
1324     NotifyConnectionState(peer->address(), handle, /*connected=*/false);
1325   }
1326 
1327   if (auto_disconnection_complete_event_enabled_) {
1328     SendDisconnectionCompleteEvent(handle);
1329   }
1330 }
1331 
OnWriteLEHostSupportCommandReceived(const pwemb::WriteLEHostSupportCommandView & params)1332 void FakeController::OnWriteLEHostSupportCommandReceived(
1333     const pwemb::WriteLEHostSupportCommandView& params) {
1334   if (params.le_supported_host().Read() == pwemb::GenericEnableParam::ENABLE) {
1335     SetBit(&settings_.lmp_features_page1,
1336            hci_spec::LMPFeature::kLESupportedHost);
1337   } else {
1338     UnsetBit(&settings_.lmp_features_page1,
1339              hci_spec::LMPFeature::kLESupportedHost);
1340   }
1341 
1342   RespondWithCommandComplete(hci_spec::kWriteLEHostSupport,
1343                              pwemb::StatusCode::SUCCESS);
1344 }
1345 
OnWriteSecureConnectionsHostSupport(const pwemb::WriteSecureConnectionsHostSupportCommandView & params)1346 void FakeController::OnWriteSecureConnectionsHostSupport(
1347     const pwemb::WriteSecureConnectionsHostSupportCommandView& params) {
1348   // Core Spec Volume 4, Part E, Section 7.3.92: If the Host issues this command
1349   // while the Controller is paging, has page scanning enabled, or has an ACL
1350   // connection, the Controller shall return the error code Command Disallowed
1351   // (0x0C).
1352   bool has_acl_connection = false;
1353   for (auto& [_, peer] : peers_) {
1354     if (peer->connected()) {
1355       has_acl_connection = true;
1356       break;
1357     }
1358   }
1359   if (bredr_connect_pending_ || isBREDRPageScanEnabled() ||
1360       has_acl_connection) {
1361     RespondWithCommandComplete(hci_spec::kWriteSecureConnectionsHostSupport,
1362                                pwemb::StatusCode::COMMAND_DISALLOWED);
1363     return;
1364   }
1365 
1366   if (params.secure_connections_host_support().Read() ==
1367       pwemb::GenericEnableParam::ENABLE) {
1368     SetBit(&settings_.lmp_features_page1,
1369            hci_spec::LMPFeature::kSecureConnectionsHostSupport);
1370   } else {
1371     UnsetBit(&settings_.lmp_features_page1,
1372              hci_spec::LMPFeature::kSecureConnectionsHostSupport);
1373   }
1374 
1375   RespondWithCommandComplete(hci_spec::kWriteSecureConnectionsHostSupport,
1376                              pwemb::StatusCode::SUCCESS);
1377 }
1378 
OnReset()1379 void FakeController::OnReset() {
1380   // TODO(fxbug.dev/42159137): actually do some resetting of stuff here
1381   RespondWithCommandComplete(hci_spec::kReset, pwemb::StatusCode::SUCCESS);
1382 }
1383 
OnInquiry(const pwemb::InquiryCommandView & params)1384 void FakeController::OnInquiry(const pwemb::InquiryCommandView& params) {
1385   // Confirm that LAP array is equal to either kGIAC or kLIAC.
1386   if (params.lap().Read() != pwemb::InquiryAccessCode::GIAC &&
1387       params.lap().Read() != pwemb::InquiryAccessCode::LIAC) {
1388     RespondWithCommandStatus(hci_spec::kInquiry,
1389                              pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
1390     return;
1391   }
1392 
1393   if (params.inquiry_length().Read() == 0x00 ||
1394       params.inquiry_length().Read() > hci_spec::kInquiryLengthMax) {
1395     RespondWithCommandStatus(hci_spec::kInquiry,
1396                              pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
1397     return;
1398   }
1399 
1400   inquiry_num_responses_left_ = params.num_responses().Read();
1401   if (params.num_responses().Read() == 0) {
1402     inquiry_num_responses_left_ = -1;
1403   }
1404 
1405   RespondWithCommandStatus(hci_spec::kInquiry, pwemb::StatusCode::SUCCESS);
1406 
1407   bt_log(INFO, "fake-hci", "sending inquiry responses..");
1408   SendInquiryResponses();
1409 
1410   (void)heap_dispatcher().PostAfter(
1411       [this](pw::async::Context /*ctx*/, pw::Status status) {
1412         if (!status.ok()) {
1413           return;
1414         }
1415         auto output = hci::EventPacket::New<pwemb::InquiryCompleteEventWriter>(
1416             hci_spec::kInquiryCompleteEventCode);
1417         output.view_t().status().Write(pwemb::StatusCode::SUCCESS);
1418         SendCommandChannelPacket(output.data());
1419       },
1420       std::chrono::milliseconds(params.inquiry_length().Read()) * 1280);
1421 }
1422 
OnLESetScanEnable(const pwemb::LESetScanEnableCommandView & params)1423 void FakeController::OnLESetScanEnable(
1424     const pwemb::LESetScanEnableCommandView& params) {
1425   if (!EnableLegacyAdvertising()) {
1426     bt_log(
1427         INFO,
1428         "fake-hci",
1429         "legacy advertising command rejected, extended advertising is in use");
1430     RespondWithCommandStatus(hci_spec::kLESetScanEnable,
1431                              pwemb::StatusCode::COMMAND_DISALLOWED);
1432     return;
1433   }
1434 
1435   le_scan_state_.enabled = false;
1436   if (params.le_scan_enable().Read() == pwemb::GenericEnableParam::ENABLE) {
1437     le_scan_state_.enabled = true;
1438   }
1439 
1440   le_scan_state_.filter_duplicates = false;
1441   if (params.filter_duplicates().Read() == pwemb::GenericEnableParam::ENABLE) {
1442     le_scan_state_.filter_duplicates = true;
1443   }
1444 
1445   // Post the scan state update before scheduling the HCI Command Complete
1446   // event. This guarantees that single-threaded unit tests receive the scan
1447   // state update BEFORE the HCI command sequence terminates.
1448   if (scan_state_cb_) {
1449     scan_state_cb_(le_scan_state_.enabled);
1450   }
1451 
1452   RespondWithCommandComplete(hci_spec::kLESetScanEnable,
1453                              pwemb::StatusCode::SUCCESS);
1454 
1455   if (le_scan_state_.enabled) {
1456     SendAdvertisingReports();
1457   }
1458 }
1459 
OnLESetExtendedScanEnable(const pwemb::LESetExtendedScanEnableCommandView & params)1460 void FakeController::OnLESetExtendedScanEnable(
1461     const pwemb::LESetExtendedScanEnableCommandView& params) {
1462   if (!EnableExtendedAdvertising()) {
1463     bt_log(
1464         INFO,
1465         "fake-hci",
1466         "extended advertising command rejected, legacy advertising is in use");
1467     RespondWithCommandStatus(hci_spec::kLESetExtendedScanEnable,
1468                              pwemb::StatusCode::COMMAND_DISALLOWED);
1469     return;
1470   }
1471 
1472   le_scan_state_.enabled = false;
1473   if (params.scanning_enabled().Read() == pwemb::GenericEnableParam::ENABLE) {
1474     le_scan_state_.enabled = true;
1475   }
1476 
1477   le_scan_state_.filter_duplicates = true;
1478   if (params.filter_duplicates().Read() ==
1479       pwemb::LEExtendedDuplicateFilteringOption::DISABLED) {
1480     le_scan_state_.filter_duplicates = false;
1481   }
1482 
1483   le_scan_state_.duration = params.duration().Read();
1484   le_scan_state_.period = params.period().Read();
1485 
1486   // Post the scan state update before scheduling the HCI Command Complete
1487   // event. This guarantees that single-threaded unit tests receive the scan
1488   // state update BEFORE the HCI command sequence terminates.
1489   if (scan_state_cb_) {
1490     scan_state_cb_(le_scan_state_.enabled);
1491   }
1492 
1493   RespondWithCommandComplete(hci_spec::kLESetExtendedScanEnable,
1494                              pwemb::StatusCode::SUCCESS);
1495 
1496   if (le_scan_state_.enabled) {
1497     SendAdvertisingReports();
1498   }
1499 }
1500 
OnLESetScanParameters(const pwemb::LESetScanParametersCommandView & params)1501 void FakeController::OnLESetScanParameters(
1502     const pwemb::LESetScanParametersCommandView& params) {
1503   if (!EnableLegacyAdvertising()) {
1504     bt_log(
1505         INFO,
1506         "fake-hci",
1507         "legacy advertising command rejected, extended advertising is in use");
1508     RespondWithCommandStatus(hci_spec::kLESetScanParameters,
1509                              pwemb::StatusCode::COMMAND_DISALLOWED);
1510     return;
1511   }
1512 
1513   if (le_scan_state_.enabled) {
1514     RespondWithCommandComplete(hci_spec::kLESetScanParameters,
1515                                pwemb::StatusCode::COMMAND_DISALLOWED);
1516     return;
1517   }
1518 
1519   le_scan_state_.own_address_type = params.own_address_type().Read();
1520   le_scan_state_.filter_policy = params.scanning_filter_policy().Read();
1521   le_scan_state_.scan_type = params.le_scan_type().Read();
1522   le_scan_state_.scan_interval = params.le_scan_interval().Read();
1523   le_scan_state_.scan_window = params.le_scan_window().Read();
1524 
1525   RespondWithCommandComplete(hci_spec::kLESetScanParameters,
1526                              pwemb::StatusCode::SUCCESS);
1527 }
1528 
OnLESetExtendedScanParameters(const pwemb::LESetExtendedScanParametersCommandView & params)1529 void FakeController::OnLESetExtendedScanParameters(
1530     const pwemb::LESetExtendedScanParametersCommandView& params) {
1531   if (!EnableExtendedAdvertising()) {
1532     bt_log(
1533         INFO,
1534         "fake-hci",
1535         "extended advertising command rejected, legacy advertising is in use");
1536     RespondWithCommandStatus(hci_spec::kLESetScanParameters,
1537                              pwemb::StatusCode::COMMAND_DISALLOWED);
1538     return;
1539   }
1540 
1541   if (le_scan_state_.enabled) {
1542     RespondWithCommandComplete(hci_spec::kLESetScanParameters,
1543                                pwemb::StatusCode::COMMAND_DISALLOWED);
1544     return;
1545   }
1546 
1547   if (params.num_entries().Read() == 0) {
1548     RespondWithCommandComplete(
1549         hci_spec::kLESetScanParameters,
1550         pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
1551     return;
1552   }
1553 
1554   le_scan_state_.own_address_type = params.own_address_type().Read();
1555   le_scan_state_.filter_policy = params.scanning_filter_policy().Read();
1556 
1557   // ExtendedLowEnergyScanner sets the same parameters for both the LE 1M and LE
1558   // Coded PHYs. We just take the parameters from the LE 1M PHY for now since we
1559   // don't support using different parameters for different PHYs.
1560   if (!params.scanning_phys().le_1m().Read()) {
1561     RespondWithCommandComplete(
1562         hci_spec::kLESetScanParameters,
1563         pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
1564     return;
1565   }
1566 
1567   le_scan_state_.scan_type = params.data()[0].scan_type().Read();
1568   le_scan_state_.scan_interval = params.data()[0].scan_interval().Read();
1569   le_scan_state_.scan_window = params.data()[0].scan_window().Read();
1570   RespondWithCommandComplete(hci_spec::kLESetExtendedScanParameters,
1571                              pwemb::StatusCode::SUCCESS);
1572 }
1573 
OnLESetHostFeature(const pwemb::LESetHostFeatureCommandView & params)1574 void FakeController::OnLESetHostFeature(
1575     const pwemb::LESetHostFeatureCommandView& params) {
1576   // We only support setting the CIS Host Support Bit
1577   if (params.bit_number().Read() !=
1578       static_cast<uint8_t>(hci_spec::LESupportedFeatureBitPos::
1579                                kConnectedIsochronousStreamHostSupport)) {
1580     RespondWithCommandComplete(
1581         hci_spec::kLESetHostFeature,
1582         pwemb::StatusCode::UNSUPPORTED_FEATURE_OR_PARAMETER);
1583     return;
1584   }
1585   if (params.bit_value().Read() ==
1586       pw::bluetooth::emboss::GenericEnableParam::ENABLE) {
1587     SetBit(
1588         &settings_.le_features,
1589         hci_spec::LESupportedFeature::kConnectedIsochronousStreamHostSupport);
1590   } else {
1591     UnsetBit(
1592         &settings_.le_features,
1593         hci_spec::LESupportedFeature::kConnectedIsochronousStreamHostSupport);
1594   }
1595 
1596   RespondWithCommandComplete(hci_spec::kLESetHostFeature,
1597                              pwemb::StatusCode::SUCCESS);
1598 }
1599 
OnReadLocalExtendedFeatures(const pwemb::ReadLocalExtendedFeaturesCommandView & params)1600 void FakeController::OnReadLocalExtendedFeatures(
1601     const pwemb::ReadLocalExtendedFeaturesCommandView& params) {
1602   auto packet = hci::EventPacket::New<
1603       pwemb::ReadLocalExtendedFeaturesCommandCompleteEventWriter>(
1604       hci_spec::kCommandCompleteEventCode);
1605   auto view = packet.view_t();
1606   view.status().Write(pwemb::StatusCode::SUCCESS);
1607   view.page_number().Write(params.page_number().Read());
1608   view.max_page_number().Write(2);
1609   view.extended_lmp_features().Write(0);
1610   switch (params.page_number().Read()) {
1611     case 0:
1612       view.extended_lmp_features().Write(settings_.lmp_features_page0);
1613       break;
1614     case 1:
1615       view.extended_lmp_features().Write(settings_.lmp_features_page1);
1616       break;
1617     case 2:
1618       view.extended_lmp_features().Write(settings_.lmp_features_page2);
1619       break;
1620     default:
1621       view.status().Write(pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
1622   }
1623 
1624   RespondWithCommandComplete(hci_spec::kReadLocalExtendedFeatures, &packet);
1625 }
1626 
OnSetEventMask(const pwemb::SetEventMaskCommandView & params)1627 void FakeController::OnSetEventMask(
1628     const pwemb::SetEventMaskCommandView& params) {
1629   settings_.event_mask = params.event_mask().Read();
1630   RespondWithCommandComplete(hci_spec::kSetEventMask,
1631                              pwemb::StatusCode::SUCCESS);
1632 }
1633 
OnLESetEventMask(const pwemb::LESetEventMaskCommandView & params)1634 void FakeController::OnLESetEventMask(
1635     const pwemb::LESetEventMaskCommandView& params) {
1636   settings_.le_event_mask = params.le_event_mask().BackingStorage().ReadUInt();
1637   RespondWithCommandComplete(hci_spec::kLESetEventMask,
1638                              pwemb::StatusCode::SUCCESS);
1639 }
1640 
OnLEReadBufferSizeV1()1641 void FakeController::OnLEReadBufferSizeV1() {
1642   auto packet = hci::EventPacket::New<
1643       pwemb::LEReadBufferSizeV1CommandCompleteEventWriter>(
1644       hci_spec::kCommandCompleteEventCode);
1645   auto view = packet.view_t();
1646   view.status().Write(pwemb::StatusCode::SUCCESS);
1647   view.le_acl_data_packet_length().Write(settings_.le_acl_data_packet_length);
1648   view.total_num_le_acl_data_packets().Write(
1649       settings_.le_total_num_acl_data_packets);
1650   RespondWithCommandComplete(pwemb::OpCode::LE_READ_BUFFER_SIZE_V1, &packet);
1651 }
1652 
OnLEReadBufferSizeV2()1653 void FakeController::OnLEReadBufferSizeV2() {
1654   auto packet = hci::EventPacket::New<
1655       pwemb::LEReadBufferSizeV2CommandCompleteEventWriter>(
1656       hci_spec::kCommandCompleteEventCode);
1657   auto view = packet.view_t();
1658 
1659   view.status().Write(pwemb::StatusCode::SUCCESS);
1660   view.le_acl_data_packet_length().Write(settings_.le_acl_data_packet_length);
1661   view.total_num_le_acl_data_packets().Write(
1662       settings_.le_total_num_acl_data_packets);
1663   view.iso_data_packet_length().Write(settings_.iso_data_packet_length);
1664   view.total_num_iso_data_packets().Write(settings_.total_num_iso_data_packets);
1665 
1666   RespondWithCommandComplete(pwemb::OpCode::LE_READ_BUFFER_SIZE_V2, &packet);
1667 }
1668 
OnLEReadSupportedStates()1669 void FakeController::OnLEReadSupportedStates() {
1670   auto packet = hci::EventPacket::New<
1671       pwemb::LEReadSupportedStatesCommandCompleteEventWriter>(
1672       hci_spec::kCommandCompleteEventCode);
1673   auto view = packet.view_t();
1674   view.status().Write(pwemb::StatusCode::SUCCESS);
1675   view.le_states().BackingStorage().WriteLittleEndianUInt<64>(
1676       settings_.le_supported_states);
1677   RespondWithCommandComplete(pwemb::OpCode::LE_READ_SUPPORTED_STATES, &packet);
1678 }
1679 
OnLEReadLocalSupportedFeatures()1680 void FakeController::OnLEReadLocalSupportedFeatures() {
1681   auto packet = hci::EventPacket::New<
1682       pwemb::LEReadLocalSupportedFeaturesCommandCompleteEventWriter>(
1683       hci_spec::kCommandCompleteEventCode);
1684   auto view = packet.view_t();
1685   view.status().Write(pwemb::StatusCode::SUCCESS);
1686   view.le_features().BackingStorage().WriteUInt(settings_.le_features);
1687   RespondWithCommandComplete(pwemb::OpCode::LE_READ_LOCAL_SUPPORTED_FEATURES,
1688                              &packet);
1689 }
1690 
OnLECreateConnectionCancel()1691 void FakeController::OnLECreateConnectionCancel() {
1692   if (!le_connect_pending_) {
1693     RespondWithCommandComplete(hci_spec::kLECreateConnectionCancel,
1694                                pwemb::StatusCode::COMMAND_DISALLOWED);
1695     return;
1696   }
1697 
1698   le_connect_pending_ = false;
1699   le_connect_rsp_task_.Cancel();
1700   PW_DCHECK(le_connect_params_);
1701 
1702   NotifyConnectionState(le_connect_params_->peer_address,
1703                         0,
1704                         /*connected=*/false,
1705                         /*canceled=*/true);
1706 
1707   bool use_enhanced_connection_complete = settings_.is_event_unmasked(
1708       hci_spec::LEEventMask::kLEEnhancedConnectionComplete);
1709   if (use_enhanced_connection_complete) {
1710     auto packet = hci::EventPacket::New<
1711         pwemb::LEEnhancedConnectionCompleteSubeventV1Writer>(
1712         hci_spec::kLEMetaEventCode);
1713     auto params = packet.view_t();
1714     params.le_meta_event().subevent_code().Write(
1715         hci_spec::kLEEnhancedConnectionCompleteSubeventCode);
1716     params.status().Write(pwemb::StatusCode::UNKNOWN_CONNECTION_ID);
1717     params.peer_address().CopyFrom(
1718         le_connect_params_->peer_address.value().view());
1719     params.peer_address_type().Write(DeviceAddress::DeviceAddrToLeAddr(
1720         le_connect_params_->peer_address.type()));
1721 
1722     RespondWithCommandComplete(hci_spec::kLECreateConnectionCancel,
1723                                pwemb::StatusCode::SUCCESS);
1724     SendCommandChannelPacket(packet.data());
1725   } else {
1726     auto packet =
1727         hci::EventPacket::New<pwemb::LEConnectionCompleteSubeventWriter>(
1728             hci_spec::kLEMetaEventCode);
1729     auto params = packet.view_t();
1730     params.le_meta_event().subevent_code().Write(
1731         hci_spec::kLEConnectionCompleteSubeventCode);
1732     params.status().Write(pwemb::StatusCode::UNKNOWN_CONNECTION_ID);
1733     params.peer_address().CopyFrom(
1734         le_connect_params_->peer_address.value().view());
1735     params.peer_address_type().Write(DeviceAddress::DeviceAddrToLePeerAddr(
1736         le_connect_params_->peer_address.type()));
1737 
1738     RespondWithCommandComplete(hci_spec::kLECreateConnectionCancel,
1739                                pwemb::StatusCode::SUCCESS);
1740     SendCommandChannelPacket(packet.data());
1741   }
1742 }
1743 
OnWriteExtendedInquiryResponse(const pwemb::WriteExtendedInquiryResponseCommandView & params)1744 void FakeController::OnWriteExtendedInquiryResponse(
1745     const pwemb::WriteExtendedInquiryResponseCommandView& params) {
1746   // As of now, we don't support FEC encoding enabled.
1747   if (params.fec_required().Read() != 0x00) {
1748     RespondWithCommandStatus(hci_spec::kWriteExtendedInquiryResponse,
1749                              pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
1750   }
1751 
1752   RespondWithCommandComplete(hci_spec::kWriteExtendedInquiryResponse,
1753                              pwemb::StatusCode::SUCCESS);
1754 }
1755 
OnWriteSimplePairingMode(const pwemb::WriteSimplePairingModeCommandView & params)1756 void FakeController::OnWriteSimplePairingMode(
1757     const pwemb::WriteSimplePairingModeCommandView& params) {
1758   // "A host shall not set the Simple Pairing Mode to 'disabled'"
1759   // Spec 5.0 Vol 2 Part E Sec 7.3.59
1760   if (params.simple_pairing_mode().Read() !=
1761       pwemb::GenericEnableParam::ENABLE) {
1762     RespondWithCommandComplete(
1763         hci_spec::kWriteSimplePairingMode,
1764         pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
1765     return;
1766   }
1767 
1768   SetBit(&settings_.lmp_features_page1,
1769          hci_spec::LMPFeature::kSecureSimplePairingHostSupport);
1770   RespondWithCommandComplete(hci_spec::kWriteSimplePairingMode,
1771                              pwemb::StatusCode::SUCCESS);
1772 }
1773 
OnReadSimplePairingMode()1774 void FakeController::OnReadSimplePairingMode() {
1775   auto event_packet = hci::EventPacket::New<
1776       pwemb::ReadSimplePairingModeCommandCompleteEventWriter>(
1777       hci_spec::kCommandCompleteEventCode);
1778   auto view = event_packet.view_t();
1779   view.status().Write(pwemb::StatusCode::SUCCESS);
1780   if (CheckBit(settings_.lmp_features_page1,
1781                hci_spec::LMPFeature::kSecureSimplePairingHostSupport)) {
1782     view.simple_pairing_mode().Write(pwemb::GenericEnableParam::ENABLE);
1783   } else {
1784     view.simple_pairing_mode().Write(pwemb::GenericEnableParam::DISABLE);
1785   }
1786 
1787   RespondWithCommandComplete(pwemb::OpCode::READ_SIMPLE_PAIRING_MODE,
1788                              &event_packet);
1789 }
1790 
OnWritePageScanType(const pwemb::WritePageScanTypeCommandView & params)1791 void FakeController::OnWritePageScanType(
1792     const pwemb::WritePageScanTypeCommandView& params) {
1793   page_scan_type_ = params.page_scan_type().Read();
1794   RespondWithCommandComplete(hci_spec::kWritePageScanType,
1795                              pwemb::StatusCode::SUCCESS);
1796 }
1797 
OnReadPageScanType()1798 void FakeController::OnReadPageScanType() {
1799   auto event_packet =
1800       hci::EventPacket::New<pwemb::ReadPageScanTypeCommandCompleteEventWriter>(
1801           hci_spec::kCommandCompleteEventCode);
1802   auto view = event_packet.view_t();
1803   view.status().Write(pwemb::StatusCode::SUCCESS);
1804   view.page_scan_type().Write(page_scan_type_);
1805   RespondWithCommandComplete(pwemb::OpCode::READ_PAGE_SCAN_TYPE, &event_packet);
1806 }
1807 
OnWriteInquiryMode(const pwemb::WriteInquiryModeCommandView & params)1808 void FakeController::OnWriteInquiryMode(
1809     const pwemb::WriteInquiryModeCommandView& params) {
1810   inquiry_mode_ = params.inquiry_mode().Read();
1811   RespondWithCommandComplete(hci_spec::kWriteInquiryMode,
1812                              pwemb::StatusCode::SUCCESS);
1813 }
1814 
OnReadInquiryMode()1815 void FakeController::OnReadInquiryMode() {
1816   auto event_packet =
1817       hci::EventPacket::New<pwemb::ReadInquiryModeCommandCompleteEventWriter>(
1818           hci_spec::kCommandCompleteEventCode);
1819   auto view = event_packet.view_t();
1820   view.status().Write(pwemb::StatusCode::SUCCESS);
1821   view.inquiry_mode().Write(inquiry_mode_);
1822   RespondWithCommandComplete(pwemb::OpCode::READ_INQUIRY_MODE, &event_packet);
1823 }
1824 
OnWriteClassOfDevice(const pwemb::WriteClassOfDeviceCommandView & params)1825 void FakeController::OnWriteClassOfDevice(
1826     const pwemb::WriteClassOfDeviceCommandView& params) {
1827   device_class_ =
1828       DeviceClass(params.class_of_device().BackingStorage().ReadUInt());
1829   NotifyControllerParametersChanged();
1830   RespondWithCommandComplete(hci_spec::kWriteClassOfDevice,
1831                              pwemb::StatusCode::SUCCESS);
1832 }
1833 
OnWritePageScanActivity(const pwemb::WritePageScanActivityCommandView & params)1834 void FakeController::OnWritePageScanActivity(
1835     const pwemb::WritePageScanActivityCommandView& params) {
1836   page_scan_interval_ = params.page_scan_interval().Read();
1837   page_scan_window_ = params.page_scan_window().Read();
1838   RespondWithCommandComplete(hci_spec::kWritePageScanActivity,
1839                              pwemb::StatusCode::SUCCESS);
1840 }
1841 
OnReadPageScanActivity()1842 void FakeController::OnReadPageScanActivity() {
1843   auto event_packet = hci::EventPacket::New<
1844       pwemb::ReadPageScanActivityCommandCompleteEventWriter>(
1845       hci_spec::kCommandCompleteEventCode);
1846   auto view = event_packet.view_t();
1847   view.status().Write(pwemb::StatusCode::SUCCESS);
1848   view.page_scan_interval().Write(page_scan_interval_);
1849   view.page_scan_window().Write(page_scan_window_);
1850   RespondWithCommandComplete(pwemb::OpCode::READ_PAGE_SCAN_ACTIVITY,
1851                              &event_packet);
1852 }
1853 
OnWriteScanEnable(const pwemb::WriteScanEnableCommandView & params)1854 void FakeController::OnWriteScanEnable(
1855     const pwemb::WriteScanEnableCommandView& params) {
1856   bredr_scan_state_ = params.scan_enable().BackingStorage().ReadUInt();
1857   RespondWithCommandComplete(hci_spec::kWriteScanEnable,
1858                              pwemb::StatusCode::SUCCESS);
1859 }
1860 
OnReadScanEnable()1861 void FakeController::OnReadScanEnable() {
1862   auto event_packet =
1863       hci::EventPacket::New<pwemb::ReadScanEnableCommandCompleteEventWriter>(
1864           hci_spec::kCommandCompleteEventCode);
1865   auto view = event_packet.view_t();
1866   view.status().Write(pwemb::StatusCode::SUCCESS);
1867   view.scan_enable().BackingStorage().WriteUInt(bredr_scan_state_);
1868   RespondWithCommandComplete(pwemb::OpCode::READ_SCAN_ENABLE, &event_packet);
1869 }
1870 
OnReadLocalName()1871 void FakeController::OnReadLocalName() {
1872   auto event_packet =
1873       hci::EventPacket::New<pwemb::ReadLocalNameCommandCompleteEventWriter>(
1874           hci_spec::kCommandCompleteEventCode);
1875   auto view = event_packet.view_t();
1876   view.status().Write(pwemb::StatusCode::SUCCESS);
1877   unsigned char* name_from_event = view.local_name().BackingStorage().data();
1878   char* name_as_cstr = reinterpret_cast<char*>(name_from_event);
1879   std::strncpy(name_as_cstr, local_name_.c_str(), hci_spec::kMaxNameLength);
1880   RespondWithCommandComplete(pwemb::OpCode::READ_LOCAL_NAME, &event_packet);
1881 }
1882 
OnWriteLocalName(const pwemb::WriteLocalNameCommandView & params)1883 void FakeController::OnWriteLocalName(
1884     const pwemb::WriteLocalNameCommandView& params) {
1885   std::size_t name_len = 0;
1886 
1887   auto local_name = params.local_name().BackingStorage().data();
1888 
1889   for (; name_len < hci_spec::kMaxNameLength; ++name_len) {
1890     if (local_name[name_len] == '\0') {
1891       break;
1892     }
1893   }
1894   local_name_ = std::string(local_name, local_name + name_len);
1895   NotifyControllerParametersChanged();
1896   RespondWithCommandComplete(hci_spec::kWriteLocalName,
1897                              pwemb::StatusCode::SUCCESS);
1898 }
1899 
OnCreateConnectionCancel()1900 void FakeController::OnCreateConnectionCancel() {
1901   auto packet = hci::EventPacket::New<
1902       pwemb::CreateConnectionCancelCommandCompleteEventWriter>(
1903       hci_spec::kCommandCompleteEventCode);
1904   auto view = packet.view_t();
1905   view.status().Write(pwemb::StatusCode::SUCCESS);
1906   view.bd_addr().CopyFrom(pending_bredr_connect_addr_.value().view());
1907 
1908   if (!bredr_connect_pending_) {
1909     // No request is currently pending.
1910     view.status().Write(pwemb::StatusCode::UNKNOWN_CONNECTION_ID);
1911     RespondWithCommandComplete(hci_spec::kCreateConnectionCancel, &packet);
1912     return;
1913   }
1914 
1915   bredr_connect_pending_ = false;
1916   bredr_connect_rsp_task_.Cancel();
1917 
1918   NotifyConnectionState(
1919       pending_bredr_connect_addr_, 0, /*connected=*/false, /*canceled=*/true);
1920 
1921   RespondWithCommandComplete(hci_spec::kCreateConnectionCancel, &packet);
1922 
1923   auto response = hci::EventPacket::New<pwemb::ConnectionCompleteEventWriter>(
1924       hci_spec::kConnectionCompleteEventCode);
1925   response.view_t().status().Write(pwemb::StatusCode::UNKNOWN_CONNECTION_ID);
1926   response.view_t().bd_addr().CopyFrom(
1927       pending_bredr_connect_addr_.value().view());
1928   SendCommandChannelPacket(response.data());
1929 }
1930 
OnReadBufferSize()1931 void FakeController::OnReadBufferSize() {
1932   auto packet =
1933       hci::EventPacket::New<pwemb::ReadBufferSizeCommandCompleteEventWriter>(
1934           hci_spec::kCommandCompleteEventCode);
1935   auto view = packet.view_t();
1936   view.acl_data_packet_length().Write(settings_.acl_data_packet_length);
1937   view.total_num_acl_data_packets().Write(settings_.total_num_acl_data_packets);
1938   view.synchronous_data_packet_length().Write(
1939       settings_.synchronous_data_packet_length);
1940   view.total_num_synchronous_data_packets().Write(
1941       settings_.total_num_synchronous_data_packets);
1942   RespondWithCommandComplete(pwemb::OpCode::READ_BUFFER_SIZE, &packet);
1943 }
1944 
OnReadBRADDR()1945 void FakeController::OnReadBRADDR() {
1946   auto packet =
1947       hci::EventPacket::New<pwemb::ReadBdAddrCommandCompleteEventWriter>(
1948           hci_spec::kCommandCompleteEventCode);
1949   auto view = packet.view_t();
1950   view.status().Write(pwemb::StatusCode::SUCCESS);
1951   view.bd_addr().CopyFrom(settings_.bd_addr.value().view());
1952   RespondWithCommandComplete(pwemb::OpCode::READ_BD_ADDR, &packet);
1953 }
1954 
OnLESetAdvertisingEnable(const pwemb::LESetAdvertisingEnableCommandView & params)1955 void FakeController::OnLESetAdvertisingEnable(
1956     const pwemb::LESetAdvertisingEnableCommandView& params) {
1957   if (!EnableLegacyAdvertising()) {
1958     bt_log(
1959         INFO,
1960         "fake-hci",
1961         "legacy advertising command rejected, extended advertising is in use");
1962     RespondWithCommandStatus(hci_spec::kLESetAdvertisingEnable,
1963                              pwemb::StatusCode::COMMAND_DISALLOWED);
1964     return;
1965   }
1966 
1967   if (legacy_advertising_state_.own_address_type ==
1968           pw::bluetooth::emboss::LEOwnAddressType::RANDOM &&
1969       !legacy_advertising_state_.random_address.has_value()) {
1970     bt_log(INFO,
1971            "fake-hci",
1972            "cannot enable, random address type requires a random address set");
1973     RespondWithCommandComplete(
1974         hci_spec::kLESetAdvertisingEnable,
1975         pw::bluetooth::emboss::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
1976     return;
1977   }
1978 
1979   legacy_advertising_state_.enabled =
1980       params.advertising_enable().Read() == pwemb::GenericEnableParam::ENABLE;
1981   RespondWithCommandComplete(hci_spec::kLESetAdvertisingEnable,
1982                              pwemb::StatusCode::SUCCESS);
1983   NotifyAdvertisingState();
1984 }
1985 
OnLESetScanResponseData(const pwemb::LESetScanResponseDataCommandView & params)1986 void FakeController::OnLESetScanResponseData(
1987     const pwemb::LESetScanResponseDataCommandView& params) {
1988   if (!EnableLegacyAdvertising()) {
1989     bt_log(
1990         INFO,
1991         "fake-hci",
1992         "legacy advertising command rejected, extended advertising is in use");
1993     RespondWithCommandStatus(hci_spec::kLESetScanResponseData,
1994                              pwemb::StatusCode::COMMAND_DISALLOWED);
1995     return;
1996   }
1997 
1998   legacy_advertising_state_.scan_rsp_length =
1999       params.scan_response_data_length().Read();
2000 
2001   if (params.scan_response_data_length().Read() == 0) {
2002     std::memset(legacy_advertising_state_.scan_rsp_data,
2003                 0,
2004                 sizeof(legacy_advertising_state_.scan_rsp_data));
2005   } else {
2006     std::memcpy(legacy_advertising_state_.scan_rsp_data,
2007                 params.scan_response_data().BackingStorage().data(),
2008                 params.scan_response_data_length().Read());
2009   }
2010 
2011   RespondWithCommandComplete(hci_spec::kLESetScanResponseData,
2012                              pwemb::StatusCode::SUCCESS);
2013   NotifyAdvertisingState();
2014 }
2015 
OnLESetAdvertisingData(const pwemb::LESetAdvertisingDataCommandView & params)2016 void FakeController::OnLESetAdvertisingData(
2017     const pwemb::LESetAdvertisingDataCommandView& params) {
2018   if (!EnableLegacyAdvertising()) {
2019     bt_log(
2020         INFO,
2021         "fake-hci",
2022         "legacy advertising command rejected, extended advertising is in use");
2023     RespondWithCommandStatus(hci_spec::kLESetAdvertisingData,
2024                              pwemb::StatusCode::COMMAND_DISALLOWED);
2025     return;
2026   }
2027 
2028   legacy_advertising_state_.data_length =
2029       params.advertising_data_length().Read();
2030 
2031   if (params.advertising_data_length().Read() == 0) {
2032     std::memset(legacy_advertising_state_.data,
2033                 0,
2034                 sizeof(legacy_advertising_state_.data));
2035   } else {
2036     std::memcpy(legacy_advertising_state_.data,
2037                 params.advertising_data().BackingStorage().data(),
2038                 params.advertising_data_length().Read());
2039   }
2040 
2041   RespondWithCommandComplete(hci_spec::kLESetAdvertisingData,
2042                              pwemb::StatusCode::SUCCESS);
2043   NotifyAdvertisingState();
2044 }
2045 
OnLESetAdvertisingParameters(const pwemb::LESetAdvertisingParametersCommandView & params)2046 void FakeController::OnLESetAdvertisingParameters(
2047     const pwemb::LESetAdvertisingParametersCommandView& params) {
2048   if (!EnableLegacyAdvertising()) {
2049     bt_log(
2050         INFO,
2051         "fake-hci",
2052         "legacy advertising command rejected, extended advertising is in use");
2053     RespondWithCommandStatus(hci_spec::kLESetAdvertisingParameters,
2054                              pwemb::StatusCode::COMMAND_DISALLOWED);
2055     return;
2056   }
2057 
2058   if (legacy_advertising_state_.enabled) {
2059     bt_log(INFO,
2060            "fake-hci",
2061            "cannot set advertising parameters while advertising enabled");
2062     RespondWithCommandComplete(hci_spec::kLESetAdvertisingParameters,
2063                                pwemb::StatusCode::COMMAND_DISALLOWED);
2064     return;
2065   }
2066 
2067   uint16_t interval_min = params.advertising_interval_min().UncheckedRead();
2068   uint16_t interval_max = params.advertising_interval_max().UncheckedRead();
2069 
2070   // Core Spec Volume 4, Part E, Section 7.8.5: For high duty cycle directed
2071   // advertising, the Advertising_Interval_Min and Advertising_Interval_Max
2072   // parameters are not used and shall be ignored.
2073   if (params.adv_type().Read() !=
2074       pwemb::LEAdvertisingType::CONNECTABLE_HIGH_DUTY_CYCLE_DIRECTED) {
2075     if (interval_min >= interval_max) {
2076       bt_log(INFO,
2077              "fake-hci",
2078              "advertising interval min (%d) not strictly less than max (%d)",
2079              interval_min,
2080              interval_max);
2081       RespondWithCommandComplete(
2082           hci_spec::kLESetAdvertisingParameters,
2083           pwemb::StatusCode::UNSUPPORTED_FEATURE_OR_PARAMETER);
2084       return;
2085     }
2086 
2087     if (interval_min < hci_spec::kLEAdvertisingIntervalMin) {
2088       bt_log(INFO,
2089              "fake-hci",
2090              "advertising interval min (%d) less than spec min (%d)",
2091              interval_min,
2092              hci_spec::kLEAdvertisingIntervalMin);
2093       RespondWithCommandComplete(
2094           hci_spec::kLESetAdvertisingParameters,
2095           pwemb::StatusCode::UNSUPPORTED_FEATURE_OR_PARAMETER);
2096       return;
2097     }
2098 
2099     if (interval_max > hci_spec::kLEAdvertisingIntervalMax) {
2100       bt_log(INFO,
2101              "fake-hci",
2102              "advertising interval max (%d) greater than spec max (%d)",
2103              interval_max,
2104              hci_spec::kLEAdvertisingIntervalMax);
2105       RespondWithCommandComplete(
2106           hci_spec::kLESetAdvertisingParameters,
2107           pwemb::StatusCode::UNSUPPORTED_FEATURE_OR_PARAMETER);
2108       return;
2109     }
2110   }
2111 
2112   legacy_advertising_state_.own_address_type = params.own_address_type().Read();
2113   legacy_advertising_state_.interval_min = interval_min;
2114   legacy_advertising_state_.interval_max = interval_max;
2115 
2116   pwemb::LEAdvertisingType adv_type = params.adv_type().Read();
2117   switch (adv_type) {
2118     case pwemb::LEAdvertisingType::CONNECTABLE_AND_SCANNABLE_UNDIRECTED:
2119       legacy_advertising_state_.properties.scannable = true;
2120       legacy_advertising_state_.properties.connectable = true;
2121       break;
2122     case pwemb::LEAdvertisingType::CONNECTABLE_LOW_DUTY_CYCLE_DIRECTED:
2123       legacy_advertising_state_.properties.directed = true;
2124       legacy_advertising_state_.properties.connectable = true;
2125       break;
2126     case pwemb::LEAdvertisingType::CONNECTABLE_HIGH_DUTY_CYCLE_DIRECTED:
2127       legacy_advertising_state_.properties
2128           .high_duty_cycle_directed_connectable = true;
2129       legacy_advertising_state_.properties.directed = true;
2130       legacy_advertising_state_.properties.connectable = true;
2131       break;
2132     case pwemb::LEAdvertisingType::SCANNABLE_UNDIRECTED:
2133       legacy_advertising_state_.properties.scannable = true;
2134       break;
2135     case pwemb::LEAdvertisingType::NOT_CONNECTABLE_UNDIRECTED:
2136       break;
2137   }
2138 
2139   bt_log(INFO,
2140          "fake-hci",
2141          "start advertising using address type: %hhd",
2142          static_cast<char>(legacy_advertising_state_.own_address_type));
2143 
2144   RespondWithCommandComplete(hci_spec::kLESetAdvertisingParameters,
2145                              pwemb::StatusCode::SUCCESS);
2146   NotifyAdvertisingState();
2147 }
2148 
OnLESetRandomAddress(const pwemb::LESetRandomAddressCommandView & params)2149 void FakeController::OnLESetRandomAddress(
2150     const pwemb::LESetRandomAddressCommandView& params) {
2151   if (!EnableLegacyAdvertising()) {
2152     bt_log(
2153         INFO,
2154         "fake-hci",
2155         "legacy advertising command rejected, extended advertising is in use");
2156     RespondWithCommandStatus(hci_spec::kLESetRandomAddress,
2157                              pwemb::StatusCode::COMMAND_DISALLOWED);
2158     return;
2159   }
2160 
2161   if (legacy_advertising_state().enabled || le_scan_state().enabled) {
2162     bt_log(INFO,
2163            "fake-hci",
2164            "cannot set LE random address while scanning or advertising");
2165     RespondWithCommandComplete(hci_spec::kLESetRandomAddress,
2166                                pwemb::StatusCode::COMMAND_DISALLOWED);
2167     return;
2168   }
2169 
2170   legacy_advertising_state_.random_address =
2171       DeviceAddress(DeviceAddress::Type::kLERandom,
2172                     DeviceAddressBytes(params.random_address()));
2173   RespondWithCommandComplete(hci_spec::kLESetRandomAddress,
2174                              pwemb::StatusCode::SUCCESS);
2175 }
2176 
OnReadLocalSupportedFeatures()2177 void FakeController::OnReadLocalSupportedFeatures() {
2178   auto packet = hci::EventPacket::New<
2179       pwemb::ReadLocalSupportedFeaturesCommandCompleteEventWriter>(
2180       hci_spec::kCommandCompleteEventCode);
2181   auto view = packet.view_t();
2182   view.status().Write(pwemb::StatusCode::SUCCESS);
2183   view.lmp_features().Write(settings_.lmp_features_page0);
2184   RespondWithCommandComplete(hci_spec::kReadLocalSupportedFeatures, &packet);
2185 }
2186 
OnReadLocalSupportedCommands()2187 void FakeController::OnReadLocalSupportedCommands() {
2188   auto packet = hci::EventPacket::New<
2189       pwemb::ReadLocalSupportedCommandsCommandCompleteEventWriter>(
2190       hci_spec::kCommandCompleteEventCode);
2191   auto view = packet.view_t();
2192   view.status().Write(pwemb::StatusCode::SUCCESS);
2193   std::memcpy(view.supported_commands().BackingStorage().begin(),
2194               settings_.supported_commands,
2195               sizeof(settings_.supported_commands));
2196   RespondWithCommandComplete(hci_spec::kReadLocalSupportedCommands, &packet);
2197 }
2198 
OnReadLocalVersionInfo()2199 void FakeController::OnReadLocalVersionInfo() {
2200   auto packet = hci::EventPacket::New<
2201       pwemb::ReadLocalVersionInfoCommandCompleteEventWriter>(
2202       hci_spec::kCommandCompleteEventCode);
2203   packet.view_t().hci_version().Write(settings_.hci_version);
2204   RespondWithCommandComplete(pwemb::OpCode::READ_LOCAL_VERSION_INFO, &packet);
2205 }
2206 
OnReadRemoteNameRequestCommandReceived(const pwemb::RemoteNameRequestCommandView & params)2207 void FakeController::OnReadRemoteNameRequestCommandReceived(
2208     const pwemb::RemoteNameRequestCommandView& params) {
2209   const DeviceAddress peer_address(DeviceAddress::Type::kBREDR,
2210                                    DeviceAddressBytes(params.bd_addr()));
2211 
2212   // Find the peer that matches the requested address.
2213   FakePeer* peer = FindPeer(peer_address);
2214   if (!peer) {
2215     RespondWithCommandStatus(hci_spec::kRemoteNameRequest,
2216                              pwemb::StatusCode::UNKNOWN_CONNECTION_ID);
2217     return;
2218   }
2219 
2220   RespondWithCommandStatus(hci_spec::kRemoteNameRequest,
2221                            pwemb::StatusCode::SUCCESS);
2222 
2223   struct RemoteNameRequestCompleteEventParams {
2224     pwemb::StatusCode status;
2225     DeviceAddressBytes bd_addr;
2226     uint8_t remote_name[hci_spec::kMaxNameLength];
2227   } __attribute__((packed));
2228   RemoteNameRequestCompleteEventParams response = {};
2229   response.bd_addr = DeviceAddressBytes(params.bd_addr());
2230   std::strncpy((char*)response.remote_name,
2231                peer->name().c_str(),
2232                hci_spec::kMaxNameLength);
2233   response.status = pwemb::StatusCode::SUCCESS;
2234   SendEvent(hci_spec::kRemoteNameRequestCompleteEventCode,
2235             BufferView(&response, sizeof(response)));
2236 }
2237 
OnReadRemoteSupportedFeaturesCommandReceived(const pwemb::ReadRemoteSupportedFeaturesCommandView & params)2238 void FakeController::OnReadRemoteSupportedFeaturesCommandReceived(
2239     const pwemb::ReadRemoteSupportedFeaturesCommandView& params) {
2240   RespondWithCommandStatus(hci_spec::kReadRemoteSupportedFeatures,
2241                            pwemb::StatusCode::SUCCESS);
2242 
2243   auto response = hci::EventPacket::New<
2244       pwemb::ReadRemoteSupportedFeaturesCompleteEventWriter>(
2245       hci_spec::kReadRemoteSupportedFeaturesCompleteEventCode);
2246   auto view = response.view_t();
2247   view.status().Write(pwemb::StatusCode::SUCCESS);
2248   view.connection_handle().Write(params.connection_handle().Read());
2249   view.lmp_features().BackingStorage().WriteUInt(settings_.lmp_features_page0);
2250   SendCommandChannelPacket(response.data());
2251 }
2252 
OnReadRemoteVersionInfoCommandReceived(const pwemb::ReadRemoteVersionInfoCommandView & params)2253 void FakeController::OnReadRemoteVersionInfoCommandReceived(
2254     const pwemb::ReadRemoteVersionInfoCommandView& params) {
2255   RespondWithCommandStatus(hci_spec::kReadRemoteVersionInfo,
2256                            pwemb::StatusCode::SUCCESS);
2257   auto response =
2258       hci::EventPacket::New<pwemb::ReadRemoteVersionInfoCompleteEventWriter>(
2259           hci_spec::kReadRemoteVersionInfoCompleteEventCode);
2260   auto view = response.view_t();
2261   view.status().Write(pwemb::StatusCode::SUCCESS);
2262   view.connection_handle().CopyFrom(params.connection_handle());
2263   view.version().Write(pwemb::CoreSpecificationVersion::V4_2);
2264   view.company_identifier().Write(0xFFFF);  // anything
2265   view.subversion().Write(0xADDE);          // anything
2266   SendCommandChannelPacket(response.data());
2267 }
2268 
OnReadRemoteExtendedFeaturesCommandReceived(const pwemb::ReadRemoteExtendedFeaturesCommandView & params)2269 void FakeController::OnReadRemoteExtendedFeaturesCommandReceived(
2270     const pwemb::ReadRemoteExtendedFeaturesCommandView& params) {
2271   auto response = hci::EventPacket::New<
2272       pwemb::ReadRemoteExtendedFeaturesCompleteEventWriter>(
2273       hci_spec::kReadRemoteExtendedFeaturesCompleteEventCode);
2274   auto view = response.view_t();
2275 
2276   switch (params.page_number().Read()) {
2277     case 1: {
2278       view.lmp_features().BackingStorage().WriteUInt(
2279           settings_.lmp_features_page1);
2280       break;
2281     }
2282     case 2: {
2283       view.lmp_features().BackingStorage().WriteUInt(
2284           settings_.lmp_features_page2);
2285       break;
2286     }
2287     default: {
2288       RespondWithCommandStatus(
2289           hci_spec::kReadRemoteExtendedFeatures,
2290           pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
2291       return;
2292     }
2293   }
2294 
2295   RespondWithCommandStatus(hci_spec::kReadRemoteExtendedFeatures,
2296                            pwemb::StatusCode::SUCCESS);
2297   view.page_number().CopyFrom(params.page_number());
2298   view.max_page_number().Write(3);
2299   view.connection_handle().CopyFrom(params.connection_handle());
2300   view.status().Write(pwemb::StatusCode::SUCCESS);
2301   SendCommandChannelPacket(response.data());
2302 }
2303 
OnAuthenticationRequestedCommandReceived(const pwemb::AuthenticationRequestedCommandView & params)2304 void FakeController::OnAuthenticationRequestedCommandReceived(
2305     const pwemb::AuthenticationRequestedCommandView& params) {
2306   hci_spec::ConnectionHandle handle = params.connection_handle().Read();
2307   FakePeer* peer = FindByConnHandle(handle);
2308   if (!peer) {
2309     RespondWithCommandStatus(hci_spec::kAuthenticationRequested,
2310                              pwemb::StatusCode::UNKNOWN_CONNECTION_ID);
2311     return;
2312   }
2313 
2314   RespondWithCommandStatus(hci_spec::kAuthenticationRequested,
2315                            pwemb::StatusCode::SUCCESS);
2316 
2317   auto event = hci::EventPacket::New<pwemb::LinkKeyRequestEventWriter>(
2318       hci_spec::kLinkKeyRequestEventCode);
2319   event.view_t().bd_addr().CopyFrom(peer->address_.value().view());
2320   SendCommandChannelPacket(event.data());
2321 }
2322 
OnLinkKeyRequestReplyCommandReceived(const pwemb::LinkKeyRequestReplyCommandView & params)2323 void FakeController::OnLinkKeyRequestReplyCommandReceived(
2324     const pwemb::LinkKeyRequestReplyCommandView& params) {
2325   DeviceAddress peer_address(DeviceAddress::Type::kBREDR,
2326                              DeviceAddressBytes(params.bd_addr()));
2327   FakePeer* peer = FindPeer(peer_address);
2328   if (!peer) {
2329     RespondWithCommandStatus(hci_spec::kLinkKeyRequestReply,
2330                              pwemb::StatusCode::UNKNOWN_CONNECTION_ID);
2331     return;
2332   }
2333 
2334   RespondWithCommandStatus(hci_spec::kLinkKeyRequestReply,
2335                            pwemb::StatusCode::SUCCESS);
2336   RespondWithCommandComplete(hci_spec::kLinkKeyRequestReply,
2337                              pwemb::StatusCode::SUCCESS);
2338 
2339   PW_CHECK(!peer->logical_links().empty());
2340   for (auto& conn_handle : peer->logical_links()) {
2341     auto event =
2342         hci::EventPacket::New<pwemb::AuthenticationCompleteEventWriter>(
2343             hci_spec::kAuthenticationCompleteEventCode);
2344     event.view_t().status().Write(pwemb::StatusCode::SUCCESS);
2345     event.view_t().connection_handle().Write(conn_handle);
2346     SendCommandChannelPacket(event.data());
2347   }
2348 }
2349 
OnLinkKeyRequestNegativeReplyCommandReceived(const pwemb::LinkKeyRequestNegativeReplyCommandView & params)2350 void FakeController::OnLinkKeyRequestNegativeReplyCommandReceived(
2351     const pwemb::LinkKeyRequestNegativeReplyCommandView& params) {
2352   FakePeer* peer = FindPeer(DeviceAddress(
2353       DeviceAddress::Type::kBREDR, DeviceAddressBytes(params.bd_addr())));
2354   if (!peer) {
2355     RespondWithCommandStatus(hci_spec::kLinkKeyRequestNegativeReply,
2356                              pwemb::StatusCode::UNKNOWN_CONNECTION_ID);
2357     return;
2358   }
2359   RespondWithCommandStatus(hci_spec::kLinkKeyRequestNegativeReply,
2360                            pwemb::StatusCode::SUCCESS);
2361 
2362   auto event = hci::EventPacket::New<pwemb::IoCapabilityRequestEventWriter>(
2363       hci_spec::kIOCapabilityRequestEventCode);
2364   event.view_t().bd_addr().CopyFrom(params.bd_addr());
2365   SendCommandChannelPacket(event.data());
2366 }
2367 
OnIOCapabilityRequestReplyCommand(const pwemb::IoCapabilityRequestReplyCommandView & params)2368 void FakeController::OnIOCapabilityRequestReplyCommand(
2369     const pwemb::IoCapabilityRequestReplyCommandView& params) {
2370   RespondWithCommandStatus(hci_spec::kIOCapabilityRequestReply,
2371                            pwemb::StatusCode::SUCCESS);
2372 
2373   auto io_response =
2374       hci::EventPacket::New<pwemb::IoCapabilityResponseEventWriter>(
2375           hci_spec::kIOCapabilityResponseEventCode);
2376   io_response.view_t().bd_addr().CopyFrom(params.bd_addr());
2377   io_response.view_t().io_capability().Write(
2378       pwemb::IoCapability::NO_INPUT_NO_OUTPUT);
2379   io_response.view_t().oob_data_present().Write(
2380       pwemb::GenericPresenceParam::NOT_PRESENT);
2381   io_response.view_t().authentication_requirements().Write(
2382       pwemb::AuthenticationRequirements::GENERAL_BONDING);
2383   SendCommandChannelPacket(io_response.data());
2384 
2385   // Event type based on |params.io_capability| and |io_response.io_capability|.
2386   auto event = hci::EventPacket::New<pwemb::UserConfirmationRequestEventWriter>(
2387       hci_spec::kUserConfirmationRequestEventCode);
2388   event.view_t().bd_addr().CopyFrom(params.bd_addr());
2389   event.view_t().numeric_value().Write(0);
2390   SendCommandChannelPacket(event.data());
2391 }
2392 
OnUserConfirmationRequestReplyCommand(const pwemb::UserConfirmationRequestReplyCommandView & params)2393 void FakeController::OnUserConfirmationRequestReplyCommand(
2394     const pwemb::UserConfirmationRequestReplyCommandView& params) {
2395   FakePeer* peer = FindPeer(DeviceAddress(
2396       DeviceAddress::Type::kBREDR, DeviceAddressBytes(params.bd_addr())));
2397   if (!peer) {
2398     RespondWithCommandStatus(hci_spec::kUserConfirmationRequestReply,
2399                              pwemb::StatusCode::UNKNOWN_CONNECTION_ID);
2400     return;
2401   }
2402 
2403   RespondWithCommandStatus(hci_spec::kUserConfirmationRequestReply,
2404                            pwemb::StatusCode::SUCCESS);
2405 
2406   auto pairing_event =
2407       hci::EventPacket::New<pwemb::SimplePairingCompleteEventWriter>(
2408           hci_spec::kSimplePairingCompleteEventCode);
2409   pairing_event.view_t().bd_addr().CopyFrom(params.bd_addr());
2410   pairing_event.view_t().status().Write(pwemb::StatusCode::SUCCESS);
2411   SendCommandChannelPacket(pairing_event.data());
2412 
2413   auto link_key_event =
2414       hci::EventPacket::New<pwemb::LinkKeyNotificationEventWriter>(
2415           hci_spec::kLinkKeyNotificationEventCode);
2416   auto link_key_view = link_key_event.view_t();
2417   link_key_view.bd_addr().CopyFrom(params.bd_addr());
2418   uint8_t key[] = {0xc0,
2419                    0xde,
2420                    0xfa,
2421                    0x57,
2422                    0x4b,
2423                    0xad,
2424                    0xf0,
2425                    0x0d,
2426                    0xa7,
2427                    0x60,
2428                    0x06,
2429                    0x1e,
2430                    0xca,
2431                    0x1e,
2432                    0xca,
2433                    0xfe};
2434   link_key_view.link_key().value().BackingStorage().CopyFrom(
2435       ::emboss::support::ReadOnlyContiguousBuffer(key, sizeof(key)),
2436       sizeof(key));
2437   link_key_view.key_type().Write(
2438       pwemb::KeyType::UNAUTHENTICATED_COMBINATION_FROM_P192);
2439   SendCommandChannelPacket(link_key_event.data());
2440 
2441   PW_CHECK(!peer->logical_links().empty());
2442   for (auto& conn_handle : peer->logical_links()) {
2443     auto event =
2444         hci::EventPacket::New<pwemb::AuthenticationCompleteEventWriter>(
2445             hci_spec::kAuthenticationCompleteEventCode);
2446     event.view_t().status().Write(pwemb::StatusCode::SUCCESS);
2447     event.view_t().connection_handle().Write(conn_handle);
2448     SendCommandChannelPacket(event.data());
2449   }
2450 }
2451 
OnUserConfirmationRequestNegativeReplyCommand(const pwemb::UserConfirmationRequestNegativeReplyCommandView & params)2452 void FakeController::OnUserConfirmationRequestNegativeReplyCommand(
2453     const pwemb::UserConfirmationRequestNegativeReplyCommandView& params) {
2454   FakePeer* peer = FindPeer(DeviceAddress(
2455       DeviceAddress::Type::kBREDR, DeviceAddressBytes(params.bd_addr())));
2456   if (!peer) {
2457     RespondWithCommandStatus(hci_spec::kUserConfirmationRequestNegativeReply,
2458                              pwemb::StatusCode::UNKNOWN_CONNECTION_ID);
2459     return;
2460   }
2461 
2462   RespondWithCommandStatus(hci_spec::kUserConfirmationRequestNegativeReply,
2463                            pwemb::StatusCode::SUCCESS);
2464   RespondWithCommandComplete(hci_spec::kUserConfirmationRequestNegativeReply,
2465                              pwemb::StatusCode::SUCCESS);
2466 
2467   auto pairing_event =
2468       hci::EventPacket::New<pwemb::SimplePairingCompleteEventWriter>(
2469           hci_spec::kSimplePairingCompleteEventCode);
2470   pairing_event.view_t().bd_addr().CopyFrom(params.bd_addr());
2471   pairing_event.view_t().status().Write(
2472       pwemb::StatusCode::AUTHENTICATION_FAILURE);
2473   SendCommandChannelPacket(pairing_event.data());
2474 }
2475 
OnSetConnectionEncryptionCommand(const pwemb::SetConnectionEncryptionCommandView & params)2476 void FakeController::OnSetConnectionEncryptionCommand(
2477     const pwemb::SetConnectionEncryptionCommandView& params) {
2478   RespondWithCommandStatus(hci_spec::kSetConnectionEncryption,
2479                            pwemb::StatusCode::SUCCESS);
2480   SendEncryptionChangeEvent(
2481       params.connection_handle().Read(),
2482       pwemb::StatusCode::SUCCESS,
2483       pwemb::EncryptionStatus::ON_WITH_E0_FOR_BREDR_OR_AES_FOR_LE);
2484 }
2485 
OnReadEncryptionKeySizeCommand(const pwemb::ReadEncryptionKeySizeCommandView & params)2486 void FakeController::OnReadEncryptionKeySizeCommand(
2487     const pwemb::ReadEncryptionKeySizeCommandView& params) {
2488   auto response = hci::EventPacket::New<
2489       pwemb::ReadEncryptionKeySizeCommandCompleteEventWriter>(
2490       hci_spec::kCommandCompleteEventCode);
2491   auto view = response.view_t();
2492   view.status().Write(pwemb::StatusCode::SUCCESS);
2493   view.connection_handle().Write(params.connection_handle().Read());
2494   view.key_size().Write(16);
2495   RespondWithCommandComplete(pwemb::OpCode::READ_ENCRYPTION_KEY_SIZE,
2496                              &response);
2497 }
2498 
OnEnhancedAcceptSynchronousConnectionRequestCommand(const pwemb::EnhancedAcceptSynchronousConnectionRequestCommandView & params)2499 void FakeController::OnEnhancedAcceptSynchronousConnectionRequestCommand(
2500     const pwemb::EnhancedAcceptSynchronousConnectionRequestCommandView&
2501         params) {
2502   DeviceAddress peer_address(DeviceAddress::Type::kBREDR,
2503                              DeviceAddressBytes(params.bd_addr()));
2504   FakePeer* peer = FindPeer(peer_address);
2505   if (!peer || !peer->last_connection_request_link_type().has_value()) {
2506     RespondWithCommandStatus(
2507         hci_spec::kEnhancedAcceptSynchronousConnectionRequest,
2508         pwemb::StatusCode::UNKNOWN_CONNECTION_ID);
2509     return;
2510   }
2511 
2512   RespondWithCommandStatus(
2513       hci_spec::kEnhancedAcceptSynchronousConnectionRequest,
2514       pwemb::StatusCode::SUCCESS);
2515 
2516   hci_spec::ConnectionHandle sco_handle = ++next_conn_handle_;
2517   peer->AddLink(sco_handle);
2518 
2519   auto packet =
2520       hci::EventPacket::New<pwemb::SynchronousConnectionCompleteEventWriter>(
2521           hci_spec::kSynchronousConnectionCompleteEventCode);
2522   auto view = packet.view_t();
2523   view.status().Write(pwemb::StatusCode::SUCCESS);
2524   view.connection_handle().Write(sco_handle);
2525   view.bd_addr().CopyFrom(peer->address().value().view());
2526   view.link_type().Write(peer->last_connection_request_link_type().value());
2527   view.transmission_interval().Write(1);
2528   view.retransmission_window().Write(2);
2529   view.rx_packet_length().Write(3);
2530   view.tx_packet_length().Write(4);
2531   view.air_mode().Write(params.connection_parameters()
2532                             .transmit_coding_format()
2533                             .coding_format()
2534                             .Read());
2535   SendCommandChannelPacket(packet.data());
2536 }
2537 
OnEnhancedSetupSynchronousConnectionCommand(const pwemb::EnhancedSetupSynchronousConnectionCommandView & params)2538 void FakeController::OnEnhancedSetupSynchronousConnectionCommand(
2539     const pwemb::EnhancedSetupSynchronousConnectionCommandView& params) {
2540   const hci_spec::ConnectionHandle acl_handle =
2541       params.connection_handle().Read();
2542   FakePeer* peer = FindByConnHandle(acl_handle);
2543   if (!peer) {
2544     RespondWithCommandStatus(hci_spec::kEnhancedSetupSynchronousConnection,
2545                              pwemb::StatusCode::UNKNOWN_CONNECTION_ID);
2546     return;
2547   }
2548 
2549   RespondWithCommandStatus(hci_spec::kEnhancedSetupSynchronousConnection,
2550                            pwemb::StatusCode::SUCCESS);
2551 
2552   hci_spec::ConnectionHandle sco_handle = ++next_conn_handle_;
2553   peer->AddLink(sco_handle);
2554 
2555   auto packet =
2556       hci::EventPacket::New<pwemb::SynchronousConnectionCompleteEventWriter>(
2557           hci_spec::kSynchronousConnectionCompleteEventCode);
2558   auto view = packet.view_t();
2559   view.status().Write(pwemb::StatusCode::SUCCESS);
2560   view.connection_handle().Write(sco_handle);
2561   view.bd_addr().CopyFrom(peer->address().value().view());
2562   view.link_type().Write(pwemb::LinkType::ESCO);
2563   view.transmission_interval().Write(1);
2564   view.retransmission_window().Write(2);
2565   view.rx_packet_length().Write(3);
2566   view.tx_packet_length().Write(4);
2567   view.air_mode().Write(params.connection_parameters()
2568                             .transmit_coding_format()
2569                             .coding_format()
2570                             .Read());
2571   SendCommandChannelPacket(packet.data());
2572 }
2573 
OnLEReadRemoteFeaturesCommand(const pwemb::LEReadRemoteFeaturesCommandView & params)2574 void FakeController::OnLEReadRemoteFeaturesCommand(
2575     const pwemb::LEReadRemoteFeaturesCommandView& params) {
2576   if (le_read_remote_features_cb_) {
2577     le_read_remote_features_cb_();
2578   }
2579 
2580   const hci_spec::ConnectionHandle handle = params.connection_handle().Read();
2581   FakePeer* peer = FindByConnHandle(handle);
2582   if (!peer) {
2583     RespondWithCommandStatus(hci_spec::kLEReadRemoteFeatures,
2584                              pwemb::StatusCode::UNKNOWN_CONNECTION_ID);
2585     return;
2586   }
2587 
2588   RespondWithCommandStatus(hci_spec::kLEReadRemoteFeatures,
2589                            pwemb::StatusCode::SUCCESS);
2590 
2591   auto response =
2592       hci::EventPacket::New<pwemb::LEReadRemoteFeaturesCompleteSubeventWriter>(
2593           hci_spec::kLEMetaEventCode);
2594   auto view = response.view_t();
2595   view.le_meta_event().subevent_code().Write(
2596       hci_spec::kLEReadRemoteFeaturesCompleteSubeventCode);
2597   view.connection_handle().Write(handle);
2598   view.status().Write(pwemb::StatusCode::SUCCESS);
2599   view.le_features().BackingStorage().WriteUInt(
2600       peer->le_features().le_features);
2601   SendCommandChannelPacket(response.data());
2602 }
2603 
OnLEStartEncryptionCommand(const pwemb::LEEnableEncryptionCommandView & params)2604 void FakeController::OnLEStartEncryptionCommand(
2605     const pwemb::LEEnableEncryptionCommandView& params) {
2606   RespondWithCommandStatus(hci_spec::kLEStartEncryption,
2607                            pwemb::StatusCode::SUCCESS);
2608   SendEncryptionChangeEvent(
2609       params.connection_handle().Read(),
2610       pwemb::StatusCode::SUCCESS,
2611       pwemb::EncryptionStatus::ON_WITH_E0_FOR_BREDR_OR_AES_FOR_LE);
2612 }
2613 
OnWriteSynchronousFlowControlEnableCommand(const pwemb::WriteSynchronousFlowControlEnableCommandView & params)2614 void FakeController::OnWriteSynchronousFlowControlEnableCommand(
2615     const pwemb::WriteSynchronousFlowControlEnableCommandView& params) {
2616   if (!settings_.SupportedCommandsView()
2617            .write_synchronous_flow_control_enable()
2618            .Read()) {
2619     RespondWithCommandComplete(hci_spec::kWriteSynchronousFlowControlEnable,
2620                                pwemb::StatusCode::UNKNOWN_COMMAND);
2621     return;
2622   }
2623   RespondWithCommandComplete(hci_spec::kWriteSynchronousFlowControlEnable,
2624                              pwemb::StatusCode::SUCCESS);
2625 }
2626 
OnLESetAdvertisingSetRandomAddress(const pwemb::LESetAdvertisingSetRandomAddressCommandView & params)2627 void FakeController::OnLESetAdvertisingSetRandomAddress(
2628     const pwemb::LESetAdvertisingSetRandomAddressCommandView& params) {
2629   hci_spec::AdvertisingHandle handle = params.advertising_handle().Read();
2630 
2631   if (!IsValidAdvertisingHandle(handle)) {
2632     bt_log(ERROR, "fake-hci", "advertising handle outside range: %d", handle);
2633     RespondWithCommandComplete(
2634         hci_spec::kLESetAdvertisingSetRandomAddress,
2635         pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
2636     return;
2637   }
2638 
2639   if (extended_advertising_states_.count(handle) == 0) {
2640     bt_log(INFO,
2641            "fake-hci",
2642            "unknown advertising handle (%d), "
2643            "use HCI_LE_Set_Extended_Advertising_Parameters to create one first",
2644            handle);
2645     RespondWithCommandComplete(hci_spec::kLESetAdvertisingSetRandomAddress,
2646                                pwemb::StatusCode::COMMAND_DISALLOWED);
2647     return;
2648   }
2649 
2650   LEAdvertisingState& state = extended_advertising_states_[handle];
2651   if (state.properties.connectable && state.enabled) {
2652     bt_log(
2653         INFO,
2654         "fake-hci",
2655         "cannot set LE random address while connectable advertising enabled");
2656     RespondWithCommandComplete(hci_spec::kLESetAdvertisingSetRandomAddress,
2657                                pwemb::StatusCode::COMMAND_DISALLOWED);
2658     return;
2659   }
2660 
2661   state.random_address =
2662       DeviceAddress(DeviceAddress::Type::kLERandom,
2663                     DeviceAddressBytes(params.random_address()));
2664   RespondWithCommandComplete(hci_spec::kLESetAdvertisingSetRandomAddress,
2665                              pwemb::StatusCode::SUCCESS);
2666 }
2667 
OnLESetExtendedAdvertisingParameters(const pwemb::LESetExtendedAdvertisingParametersV1CommandView & params)2668 void FakeController::OnLESetExtendedAdvertisingParameters(
2669     const pwemb::LESetExtendedAdvertisingParametersV1CommandView& params) {
2670   if (!EnableExtendedAdvertising()) {
2671     bt_log(
2672         INFO,
2673         "fake-hci",
2674         "extended advertising command rejected, legacy advertising is in use");
2675     RespondWithCommandStatus(hci_spec::kLESetExtendedAdvertisingParameters,
2676                              pwemb::StatusCode::COMMAND_DISALLOWED);
2677     return;
2678   }
2679 
2680   hci_spec::AdvertisingHandle handle = params.advertising_handle().Read();
2681 
2682   if (!IsValidAdvertisingHandle(handle)) {
2683     bt_log(ERROR, "fake-hci", "advertising handle outside range: %d", handle);
2684     RespondWithCommandComplete(
2685         hci_spec::kLESetExtendedAdvertisingParameters,
2686         pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
2687     return;
2688   }
2689 
2690   // we cannot set parameters while an advertising set is currently enabled
2691   if (extended_advertising_states_.count(handle) != 0) {
2692     if (extended_advertising_states_[handle].enabled) {
2693       bt_log(INFO,
2694              "fake-hci",
2695              "cannot set parameters while advertising set is enabled");
2696       RespondWithCommandComplete(hci_spec::kLESetExtendedAdvertisingParameters,
2697                                  pwemb::StatusCode::COMMAND_DISALLOWED);
2698       return;
2699     }
2700   }
2701 
2702   // ensure we can allocate memory for this advertising set if not already
2703   // present
2704   if (extended_advertising_states_.count(handle) == 0 &&
2705       extended_advertising_states_.size() >= num_supported_advertising_sets()) {
2706     bt_log(INFO,
2707            "fake-hci",
2708            "no available memory for new advertising set, handle: %d",
2709            handle);
2710     RespondWithCommandComplete(hci_spec::kLESetExtendedAdvertisingParameters,
2711                                pwemb::StatusCode::MEMORY_CAPACITY_EXCEEDED);
2712     return;
2713   }
2714 
2715   // ensure we have a valid bit combination in the advertising event properties
2716   bool connectable = params.advertising_event_properties().connectable().Read();
2717   bool scannable = params.advertising_event_properties().scannable().Read();
2718   bool directed = params.advertising_event_properties().directed().Read();
2719   bool high_duty_cycle_directed_connectable =
2720       params.advertising_event_properties()
2721           .high_duty_cycle_directed_connectable()
2722           .Read();
2723   bool use_legacy_pdus =
2724       params.advertising_event_properties().use_legacy_pdus().Read();
2725   bool anonymous_advertising =
2726       params.advertising_event_properties().anonymous_advertising().Read();
2727   bool include_tx_power =
2728       params.advertising_event_properties().include_tx_power().Read();
2729 
2730   std::optional<pwemb::LEAdvertisingType> adv_type;
2731   if (use_legacy_pdus) {
2732     // ADV_IND
2733     if (!high_duty_cycle_directed_connectable && !directed && scannable &&
2734         connectable) {
2735       adv_type = pwemb::LEAdvertisingType::CONNECTABLE_AND_SCANNABLE_UNDIRECTED;
2736     }
2737 
2738     // ADV_DIRECT_IND
2739     if (!high_duty_cycle_directed_connectable && directed && !scannable &&
2740         connectable) {
2741       adv_type = pwemb::LEAdvertisingType::CONNECTABLE_LOW_DUTY_CYCLE_DIRECTED;
2742     }
2743 
2744     // ADV_DIRECT_IND
2745     if (high_duty_cycle_directed_connectable && directed && !scannable &&
2746         connectable) {
2747       adv_type = pwemb::LEAdvertisingType::CONNECTABLE_HIGH_DUTY_CYCLE_DIRECTED;
2748     }
2749 
2750     // ADV_SCAN_IND
2751     if (!high_duty_cycle_directed_connectable && !directed && scannable &&
2752         !connectable) {
2753       adv_type = pwemb::LEAdvertisingType::SCANNABLE_UNDIRECTED;
2754     }
2755 
2756     // ADV_NONCONN_IND
2757     if (!high_duty_cycle_directed_connectable && !directed && !scannable &&
2758         !connectable) {
2759       adv_type = pwemb::LEAdvertisingType::NOT_CONNECTABLE_UNDIRECTED;
2760     }
2761 
2762     if (!adv_type) {
2763       bt_log(INFO,
2764              "fake-hci",
2765              "invalid bit combination: %d",
2766              params.advertising_event_properties().BackingStorage().ReadUInt());
2767       RespondWithCommandComplete(
2768           hci_spec::kLESetExtendedAdvertisingParameters,
2769           pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
2770       return;
2771     }
2772 
2773     // Core spec Volume 4, Part E, Section 7.8.53: if legacy advertising PDUs
2774     // are being used, the Primary_Advertising_PHY shall indicate the LE 1M PHY.
2775     if (params.primary_advertising_phy().Read() !=
2776         pwemb::LEPrimaryAdvertisingPHY::LE_1M) {
2777       bt_log(INFO,
2778              "fake-hci",
2779              "only legacy pdus are supported, requires advertising on 1M PHY");
2780       RespondWithCommandComplete(
2781           hci_spec::kLESetExtendedAdvertisingParameters,
2782           pwemb::StatusCode::UNSUPPORTED_FEATURE_OR_PARAMETER);
2783       return;
2784     }
2785   } else {
2786     // Core spec Volume 4, Part E, Section 7.8.53: If extended advertising PDU
2787     // types are being used (bit 4 = 0) then: The advertisement shall not be
2788     // both connectable and scannable.
2789     if (connectable && scannable) {
2790       bt_log(
2791           INFO,
2792           "fake-hci",
2793           "extended advertising pdus can't be both connectable and scannable");
2794       RespondWithCommandComplete(
2795           hci_spec::kLESetExtendedAdvertisingParameters,
2796           pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
2797       return;
2798     }
2799 
2800     // Core spec Volume 4, Part E, Section 7.8.53: If extended advertising PDU
2801     // types are being used (bit 4 = 0) then: High duty cycle directed
2802     // connectable advertising (≤ 3.75 ms advertising interval) shall not be
2803     // used (bit 3 = 0).
2804     if (high_duty_cycle_directed_connectable) {
2805       bt_log(INFO,
2806              "fake-hci",
2807              "extended advertising pdus can't use the high duty cycle directed "
2808              "connectable type");
2809       RespondWithCommandComplete(
2810           hci_spec::kLESetExtendedAdvertisingParameters,
2811           pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
2812       return;
2813     }
2814   }
2815 
2816   // In case there is an error below, we want to reject all parameters instead
2817   // of storing a dead state and taking up an advertising handle. Avoid creating
2818   // the LEAdvertisingState directly in the map and add it in only once we have
2819   // made sure all is good.
2820   LEAdvertisingState state;
2821   state.properties.connectable = connectable;
2822   state.properties.scannable = scannable;
2823   state.properties.directed = directed;
2824   state.properties.high_duty_cycle_directed_connectable =
2825       high_duty_cycle_directed_connectable;
2826   state.properties.use_legacy_pdus = use_legacy_pdus;
2827   state.properties.anonymous_advertising = anonymous_advertising;
2828   state.properties.include_tx_power = include_tx_power;
2829 
2830   state.own_address_type = params.own_address_type().Read();
2831   state.interval_min = params.primary_advertising_interval_min().Read();
2832   state.interval_max = params.primary_advertising_interval_max().Read();
2833 
2834   if (state.interval_min >= state.interval_max) {
2835     bt_log(INFO,
2836            "fake-hci",
2837            "advertising interval min (%d) not strictly less than max (%d)",
2838            state.interval_min,
2839            state.interval_max);
2840     RespondWithCommandComplete(
2841         hci_spec::kLESetExtendedAdvertisingParameters,
2842         pwemb::StatusCode::UNSUPPORTED_FEATURE_OR_PARAMETER);
2843     return;
2844   }
2845 
2846   if (state.interval_min < hci_spec::kLEExtendedAdvertisingIntervalMin) {
2847     bt_log(INFO,
2848            "fake-hci",
2849            "advertising interval min (%d) less than spec min (%dstate.)",
2850            state.interval_min,
2851            hci_spec::kLEAdvertisingIntervalMin);
2852     RespondWithCommandComplete(
2853         hci_spec::kLESetExtendedAdvertisingParameters,
2854         pwemb::StatusCode::UNSUPPORTED_FEATURE_OR_PARAMETER);
2855     return;
2856   }
2857 
2858   if (state.interval_max > hci_spec::kLEExtendedAdvertisingIntervalMax) {
2859     bt_log(INFO,
2860            "fake-hci",
2861            "advertising interval max (%d) greater than spec max (%d)",
2862            state.interval_max,
2863            hci_spec::kLEAdvertisingIntervalMax);
2864     RespondWithCommandComplete(
2865         hci_spec::kLESetExtendedAdvertisingParameters,
2866         pwemb::StatusCode::UNSUPPORTED_FEATURE_OR_PARAMETER);
2867     return;
2868   }
2869 
2870   uint8_t advertising_channels =
2871       params.primary_advertising_channel_map().BackingStorage().ReadUInt();
2872   if (!advertising_channels) {
2873     bt_log(INFO,
2874            "fake-hci",
2875            "at least one bit must be set in primary advertising channel map");
2876     RespondWithCommandComplete(
2877         hci_spec::kLESetExtendedAdvertisingParameters,
2878         pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
2879     return;
2880   }
2881 
2882   int8_t advertising_tx_power = params.advertising_tx_power().Read();
2883   if (advertising_tx_power !=
2884           hci_spec::kLEExtendedAdvertisingTxPowerNoPreference &&
2885       (advertising_tx_power < hci_spec::kLEAdvertisingTxPowerMin ||
2886        advertising_tx_power > hci_spec::kLEAdvertisingTxPowerMax)) {
2887     bt_log(INFO,
2888            "fake-hci",
2889            "advertising tx power out of range: %d",
2890            advertising_tx_power);
2891     RespondWithCommandComplete(
2892         hci_spec::kLESetExtendedAdvertisingParameters,
2893         pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
2894     return;
2895   }
2896 
2897   // write full state back only at the end (we don't have a reference because we
2898   // only want to write if there are no errors)
2899   extended_advertising_states_[handle] = state;
2900 
2901   auto packet = hci::EventPacket::New<
2902       pwemb::LESetExtendedAdvertisingParametersCommandCompleteEventWriter>(
2903       hci_spec::kCommandCompleteEventCode);
2904   auto view = packet.view_t();
2905   view.status().Write(pwemb::StatusCode::SUCCESS);
2906   view.selected_tx_power().Write(hci_spec::kLEAdvertisingTxPowerMax);
2907   RespondWithCommandComplete(
2908       pwemb::OpCode::LE_SET_EXTENDED_ADVERTISING_PARAMETERS_V1, &packet);
2909   NotifyAdvertisingState();
2910 }
2911 
OnLESetExtendedAdvertisingData(const pwemb::LESetExtendedAdvertisingDataCommandView & params)2912 void FakeController::OnLESetExtendedAdvertisingData(
2913     const pwemb::LESetExtendedAdvertisingDataCommandView& params) {
2914   if (!EnableExtendedAdvertising()) {
2915     bt_log(
2916         INFO,
2917         "fake-hci",
2918         "extended advertising command rejected, legacy advertising is in use");
2919     RespondWithCommandStatus(hci_spec::kLESetExtendedAdvertisingData,
2920                              pwemb::StatusCode::COMMAND_DISALLOWED);
2921     return;
2922   }
2923 
2924   hci_spec::AdvertisingHandle handle = params.advertising_handle().Read();
2925 
2926   if (!IsValidAdvertisingHandle(handle)) {
2927     bt_log(ERROR, "fake-hci", "advertising handle outside range: %d", handle);
2928     RespondWithCommandComplete(
2929         hci_spec::kLESetExtendedAdvertisingData,
2930         pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
2931     return;
2932   }
2933 
2934   if (extended_advertising_states_.count(handle) == 0) {
2935     bt_log(INFO,
2936            "fake-hci",
2937            "advertising handle (%d) maps to an unknown advertising set",
2938            handle);
2939     RespondWithCommandComplete(
2940         hci_spec::kLESetExtendedAdvertisingData,
2941         pwemb::StatusCode::UNKNOWN_ADVERTISING_IDENTIFIER);
2942     return;
2943   }
2944 
2945   LEAdvertisingState& state = extended_advertising_states_[handle];
2946 
2947   // removing advertising data entirely doesn't require us to check for error
2948   // conditions
2949   size_t advertising_data_length = params.advertising_data_length().Read();
2950   if (advertising_data_length == 0) {
2951     state.data_length = 0;
2952     std::memset(state.data, 0, sizeof(state.data));
2953     RespondWithCommandComplete(hci_spec::kLESetExtendedAdvertisingData,
2954                                pwemb::StatusCode::SUCCESS);
2955     NotifyAdvertisingState();
2956     return;
2957   }
2958 
2959   // directed advertising doesn't support advertising data
2960   if (state.IsDirectedAdvertising()) {
2961     bt_log(INFO,
2962            "fake-hci",
2963            "cannot provide advertising data when using directed advertising");
2964     RespondWithCommandComplete(
2965         hci_spec::kLESetExtendedAdvertisingData,
2966         pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
2967     return;
2968   }
2969 
2970   if (params.operation().Read() ==
2971       pwemb::LESetExtendedAdvDataOp::UNCHANGED_DATA) {
2972     RespondWithCommandComplete(hci_spec::kLESetExtendedAdvertisingData,
2973                                pwemb::StatusCode::SUCCESS);
2974     return;
2975   }
2976 
2977   // For backwards compatibility with older devices, we support both legacy and
2978   // extended advertising pdus. Each pdu type has its own size limits.
2979   if (state.properties.use_legacy_pdus &&
2980       advertising_data_length > hci_spec::kMaxLEAdvertisingDataLength) {
2981     bt_log(INFO,
2982            "fake-hci",
2983            "data length (%zu bytes) larger than legacy PDU size limit",
2984            advertising_data_length);
2985     RespondWithCommandComplete(
2986         hci_spec::kLESetExtendedAdvertisingData,
2987         pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
2988     return;
2989   }
2990 
2991   if (!state.properties.use_legacy_pdus &&
2992       advertising_data_length > pwemb::LESetExtendedAdvertisingDataCommand::
2993                                     advertising_data_length_max()) {
2994     bt_log(INFO,
2995            "fake-hci",
2996            "data length (%zu bytes) larger than individual extended PDU size "
2997            "limit",
2998            advertising_data_length);
2999     RespondWithCommandComplete(
3000         hci_spec::kLESetExtendedAdvertisingData,
3001         pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
3002     return;
3003   }
3004 
3005   if (!state.properties.use_legacy_pdus &&
3006       state.data_length + advertising_data_length >
3007           max_advertising_data_length_) {
3008     bt_log(INFO,
3009            "fake-hci",
3010            "data length (%zu bytes) larger than total extended PDU size limit",
3011            advertising_data_length);
3012     RespondWithCommandComplete(
3013         hci_spec::kLESetExtendedAdvertisingData,
3014         pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
3015     return;
3016   }
3017 
3018   if (state.properties.use_legacy_pdus ||
3019       params.operation().Read() == pwemb::LESetExtendedAdvDataOp::COMPLETE ||
3020       params.operation().Read() ==
3021           pwemb::LESetExtendedAdvDataOp::FIRST_FRAGMENT) {
3022     std::memcpy(state.data,
3023                 params.advertising_data().BackingStorage().data(),
3024                 advertising_data_length);
3025     state.data_length = static_cast<uint16_t>(advertising_data_length);
3026   } else {
3027     std::memcpy(state.data + state.data_length,
3028                 params.advertising_data().BackingStorage().data(),
3029                 advertising_data_length);
3030     state.data_length += advertising_data_length;
3031   }
3032 
3033   RespondWithCommandComplete(hci_spec::kLESetExtendedAdvertisingData,
3034                              pwemb::StatusCode::SUCCESS);
3035   NotifyAdvertisingState();
3036 }
3037 
OnLESetExtendedScanResponseData(const pwemb::LESetExtendedScanResponseDataCommandView & params)3038 void FakeController::OnLESetExtendedScanResponseData(
3039     const pwemb::LESetExtendedScanResponseDataCommandView& params) {
3040   if (!EnableExtendedAdvertising()) {
3041     bt_log(
3042         INFO,
3043         "fake-hci",
3044         "extended advertising command rejected, legacy advertising is in use");
3045     RespondWithCommandStatus(hci_spec::kLESetExtendedScanResponseData,
3046                              pwemb::StatusCode::COMMAND_DISALLOWED);
3047     return;
3048   }
3049 
3050   hci_spec::AdvertisingHandle handle = params.advertising_handle().Read();
3051 
3052   if (!IsValidAdvertisingHandle(handle)) {
3053     bt_log(ERROR, "fake-hci", "advertising handle outside range: %d", handle);
3054     RespondWithCommandComplete(
3055         hci_spec::kLESetExtendedScanResponseData,
3056         pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
3057     return;
3058   }
3059 
3060   if (extended_advertising_states_.count(handle) == 0) {
3061     bt_log(INFO,
3062            "fake-hci",
3063            "advertising handle (%d) maps to an unknown advertising set",
3064            handle);
3065     RespondWithCommandComplete(
3066         hci_spec::kLESetExtendedScanResponseData,
3067         pwemb::StatusCode::UNKNOWN_ADVERTISING_IDENTIFIER);
3068     return;
3069   }
3070 
3071   LEAdvertisingState& state = extended_advertising_states_[handle];
3072 
3073   // removing scan response data entirely doesn't require us to check for error
3074   // conditions
3075   size_t scan_response_data_length = params.scan_response_data_length().Read();
3076   if (scan_response_data_length == 0) {
3077     state.scan_rsp_length = 0;
3078     std::memset(state.scan_rsp_data, 0, sizeof(state.scan_rsp_data));
3079     RespondWithCommandComplete(hci_spec::kLESetExtendedScanResponseData,
3080                                pwemb::StatusCode::SUCCESS);
3081     NotifyAdvertisingState();
3082     return;
3083   }
3084 
3085   // adding or changing scan response data, check for error conditions
3086   if (!state.properties.scannable) {
3087     bt_log(
3088         INFO,
3089         "fake-hci",
3090         "cannot provide scan response data for unscannable advertising types");
3091     RespondWithCommandComplete(
3092         hci_spec::kLESetExtendedScanResponseData,
3093         pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
3094     return;
3095   }
3096 
3097   if (params.operation().Read() ==
3098       pwemb::LESetExtendedAdvDataOp::UNCHANGED_DATA) {
3099     RespondWithCommandComplete(hci_spec::kLESetExtendedScanResponseData,
3100                                pwemb::StatusCode::SUCCESS);
3101     return;
3102   }
3103 
3104   // For backwards compatibility with older devices, we support both legacy and
3105   // extended advertising pdus. Each pdu type has its own size limits.
3106   if (state.properties.use_legacy_pdus &&
3107       scan_response_data_length > hci_spec::kMaxLEAdvertisingDataLength) {
3108     bt_log(INFO,
3109            "fake-hci",
3110            "data length (%zu bytes) larger than legacy PDU size limit",
3111            scan_response_data_length);
3112     RespondWithCommandComplete(
3113         hci_spec::kLESetExtendedScanResponseData,
3114         pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
3115     return;
3116   }
3117 
3118   if (!state.properties.use_legacy_pdus &&
3119       scan_response_data_length > pwemb::LESetExtendedAdvertisingDataCommand::
3120                                       advertising_data_length_max()) {
3121     bt_log(INFO,
3122            "fake-hci",
3123            "data length (%zu bytes) larger than individual extended PDU size "
3124            "limit",
3125            scan_response_data_length);
3126     RespondWithCommandComplete(
3127         hci_spec::kLESetExtendedScanResponseData,
3128         pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
3129     return;
3130   }
3131 
3132   if (!state.properties.use_legacy_pdus &&
3133       state.scan_rsp_length + scan_response_data_length >
3134           max_advertising_data_length_) {
3135     bt_log(INFO,
3136            "fake-hci",
3137            "data length (%zu bytes) larger than total extended PDU size limit",
3138            scan_response_data_length);
3139     RespondWithCommandComplete(
3140         hci_spec::kLESetExtendedScanResponseData,
3141         pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
3142     return;
3143   }
3144 
3145   if (state.properties.use_legacy_pdus ||
3146       params.operation().Read() == pwemb::LESetExtendedAdvDataOp::COMPLETE ||
3147       params.operation().Read() ==
3148           pwemb::LESetExtendedAdvDataOp::FIRST_FRAGMENT) {
3149     std::memcpy(state.scan_rsp_data,
3150                 params.scan_response_data().BackingStorage().data(),
3151                 scan_response_data_length);
3152     state.scan_rsp_length = static_cast<uint16_t>(scan_response_data_length);
3153   } else {
3154     std::memcpy(state.scan_rsp_data + state.scan_rsp_length,
3155                 params.scan_response_data().BackingStorage().data(),
3156                 scan_response_data_length);
3157     state.scan_rsp_length += scan_response_data_length;
3158   }
3159 
3160   RespondWithCommandComplete(hci_spec::kLESetExtendedScanResponseData,
3161                              pwemb::StatusCode::SUCCESS);
3162   NotifyAdvertisingState();
3163 }
3164 
OnLESetExtendedAdvertisingEnable(const pwemb::LESetExtendedAdvertisingEnableCommandView & params)3165 void FakeController::OnLESetExtendedAdvertisingEnable(
3166     const pwemb::LESetExtendedAdvertisingEnableCommandView& params) {
3167   if (!EnableExtendedAdvertising()) {
3168     bt_log(
3169         INFO,
3170         "fake-hci",
3171         "extended advertising command rejected, legacy advertising is in use");
3172     RespondWithCommandStatus(hci_spec::kLESetExtendedAdvertisingEnable,
3173                              pwemb::StatusCode::COMMAND_DISALLOWED);
3174     return;
3175   }
3176 
3177   uint8_t num_sets = params.num_sets().Read();
3178 
3179   // do some preliminary checks before making any state changes
3180   if (num_sets != 0) {
3181     std::unordered_set<hci_spec::AdvertisingHandle> handles;
3182 
3183     for (uint8_t i = 0; i < num_sets; i++) {
3184       hci_spec::AdvertisingHandle handle =
3185           params.data()[i].advertising_handle().Read();
3186 
3187       if (!IsValidAdvertisingHandle(handle)) {
3188         bt_log(
3189             ERROR, "fake-hci", "advertising handle outside range: %d", handle);
3190         RespondWithCommandComplete(
3191             hci_spec::kLESetExtendedAdvertisingEnable,
3192             pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
3193         return;
3194       }
3195 
3196       // cannot have two array entries for the same advertising handle
3197       if (handles.count(handle) != 0) {
3198         bt_log(INFO,
3199                "fake-hci",
3200                "cannot refer to handle more than once (handle: %d)",
3201                handle);
3202         RespondWithCommandComplete(
3203             hci_spec::kLESetExtendedAdvertisingEnable,
3204             pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
3205         return;
3206       }
3207       handles.insert(handle);
3208 
3209       // cannot have instructions for an advertising handle we don't know about
3210       if (extended_advertising_states_.count(handle) == 0) {
3211         bt_log(INFO,
3212                "fake-hci",
3213                "cannot enable/disable an unknown handle (handle: %d)",
3214                handle);
3215         RespondWithCommandComplete(
3216             hci_spec::kLESetExtendedAdvertisingEnable,
3217             pwemb::StatusCode::UNKNOWN_ADVERTISING_IDENTIFIER);
3218         return;
3219       }
3220     }
3221   }
3222 
3223   if (params.enable().Read() == pwemb::GenericEnableParam::DISABLE) {
3224     if (num_sets == 0) {
3225       // if params.enable == kDisable and params.num_sets == 0, spec asks we
3226       // disable all
3227       for (auto& element : extended_advertising_states_) {
3228         element.second.enabled = false;
3229       }
3230     } else {
3231       for (int i = 0; i < num_sets; i++) {
3232         hci_spec::AdvertisingHandle handle =
3233             params.data()[i].advertising_handle().Read();
3234         extended_advertising_states_[handle].enabled = false;
3235       }
3236     }
3237 
3238     RespondWithCommandComplete(hci_spec::kLESetExtendedAdvertisingEnable,
3239                                pwemb::StatusCode::SUCCESS);
3240     NotifyAdvertisingState();
3241     return;
3242   }
3243 
3244   // rest of the function deals with enabling advertising for a given set of
3245   // advertising sets
3246   PW_CHECK(params.enable().Read() == pwemb::GenericEnableParam::ENABLE);
3247 
3248   if (num_sets == 0) {
3249     bt_log(
3250         INFO, "fake-hci", "cannot enable with an empty advertising set list");
3251     RespondWithCommandComplete(
3252         hci_spec::kLESetExtendedAdvertisingEnable,
3253         pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
3254     return;
3255   }
3256 
3257   for (uint8_t i = 0; i < num_sets; i++) {
3258     // FakeController currently doesn't support testing with duration and max
3259     // events. When those are used in the host, these checks will fail and
3260     // remind us to add the necessary code to FakeController.
3261     PW_CHECK(params.data()[i].duration().Read() == 0);
3262     PW_CHECK(params.data()[i].max_extended_advertising_events().Read() == 0);
3263 
3264     hci_spec::AdvertisingHandle handle =
3265         params.data()[i].advertising_handle().Read();
3266     LEAdvertisingState& state = extended_advertising_states_[handle];
3267 
3268     if (state.IsDirectedAdvertising() && state.data_length == 0) {
3269       bt_log(
3270           INFO,
3271           "fake-hci",
3272           "cannot enable type requiring advertising data without setting it");
3273       RespondWithCommandComplete(hci_spec::kLESetExtendedAdvertisingEnable,
3274                                  pwemb::StatusCode::COMMAND_DISALLOWED);
3275       return;
3276     }
3277 
3278     if (state.properties.scannable && state.scan_rsp_length == 0) {
3279       bt_log(INFO,
3280              "fake-hci",
3281              "cannot enable, requires scan response data but hasn't been set");
3282       RespondWithCommandComplete(hci_spec::kLESetExtendedAdvertisingEnable,
3283                                  pwemb::StatusCode::COMMAND_DISALLOWED);
3284       return;
3285     }
3286 
3287     // TODO(fxbug.dev/42161900): if own address type is random, check that a
3288     // random address is set.
3289 
3290     state.enabled = true;
3291   }
3292 
3293   RespondWithCommandComplete(hci_spec::kLESetExtendedAdvertisingEnable,
3294                              pwemb::StatusCode::SUCCESS);
3295   NotifyAdvertisingState();
3296 }
3297 
OnLEReadMaximumAdvertisingDataLength()3298 void FakeController::OnLEReadMaximumAdvertisingDataLength() {
3299   if (!settings_.SupportedCommandsView()
3300            .le_read_maximum_advertising_data_length()
3301            .Read()) {
3302     RespondWithCommandComplete(hci_spec::kLEReadMaximumAdvertisingDataLength,
3303                                pwemb::StatusCode::UNKNOWN_COMMAND);
3304   }
3305 
3306   auto response = hci::EventPacket::New<
3307       pwemb::LEReadMaximumAdvertisingDataLengthCommandCompleteEventWriter>(
3308       hci_spec::kCommandCompleteEventCode);
3309   auto view = response.view_t();
3310   view.status().Write(pwemb::StatusCode::SUCCESS);
3311   view.max_advertising_data_length().Write(max_advertising_data_length_);
3312   RespondWithCommandComplete(
3313       pwemb::OpCode::LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH, &response);
3314 }
3315 
OnLEReadNumberOfSupportedAdvertisingSets()3316 void FakeController::OnLEReadNumberOfSupportedAdvertisingSets() {
3317   auto event = hci::EventPacket::New<
3318       pwemb::LEReadNumberOfSupportedAdvertisingSetsCommandCompleteEventWriter>(
3319       hci_spec::kCommandCompleteEventCode);
3320   auto view = event.view_t();
3321   view.status().Write(pwemb::StatusCode::SUCCESS);
3322   view.num_supported_advertising_sets().Write(num_supported_advertising_sets_);
3323   RespondWithCommandComplete(hci_spec::kLEReadNumSupportedAdvertisingSets,
3324                              &event);
3325 }
3326 
OnLERemoveAdvertisingSet(const pwemb::LERemoveAdvertisingSetCommandView & params)3327 void FakeController::OnLERemoveAdvertisingSet(
3328     const pwemb::LERemoveAdvertisingSetCommandView& params) {
3329   hci_spec::AdvertisingHandle handle = params.advertising_handle().Read();
3330 
3331   if (!IsValidAdvertisingHandle(handle)) {
3332     bt_log(ERROR, "fake-hci", "advertising handle outside range: %d", handle);
3333     RespondWithCommandComplete(
3334         hci_spec::kLERemoveAdvertisingSet,
3335         pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
3336     return;
3337   }
3338 
3339   if (extended_advertising_states_.count(handle) == 0) {
3340     bt_log(INFO,
3341            "fake-hci",
3342            "advertising handle (%d) maps to an unknown advertising set",
3343            handle);
3344     RespondWithCommandComplete(
3345         hci_spec::kLERemoveAdvertisingSet,
3346         pwemb::StatusCode::UNKNOWN_ADVERTISING_IDENTIFIER);
3347     return;
3348   }
3349 
3350   if (extended_advertising_states_[handle].enabled) {
3351     bt_log(INFO,
3352            "fake-hci",
3353            "cannot remove enabled advertising set (handle: %d)",
3354            handle);
3355     RespondWithCommandComplete(hci_spec::kLERemoveAdvertisingSet,
3356                                pwemb::StatusCode::COMMAND_DISALLOWED);
3357     return;
3358   }
3359 
3360   extended_advertising_states_.erase(handle);
3361   RespondWithCommandComplete(hci_spec::kLERemoveAdvertisingSet,
3362                              pwemb::StatusCode::SUCCESS);
3363   NotifyAdvertisingState();
3364 }
3365 
OnLEClearAdvertisingSets()3366 void FakeController::OnLEClearAdvertisingSets() {
3367   for (const auto& element : extended_advertising_states_) {
3368     if (element.second.enabled) {
3369       bt_log(INFO,
3370              "fake-hci",
3371              "cannot remove currently enabled advertising set (handle: %d)",
3372              element.second.enabled);
3373       RespondWithCommandComplete(hci_spec::kLEClearAdvertisingSets,
3374                                  pwemb::StatusCode::COMMAND_DISALLOWED);
3375       return;
3376     }
3377   }
3378 
3379   extended_advertising_states_.clear();
3380   RespondWithCommandComplete(hci_spec::kLEClearAdvertisingSets,
3381                              pwemb::StatusCode::SUCCESS);
3382   NotifyAdvertisingState();
3383 }
3384 
OnLEReadAdvertisingChannelTxPower()3385 void FakeController::OnLEReadAdvertisingChannelTxPower() {
3386   if (!respond_to_tx_power_read_) {
3387     return;
3388   }
3389 
3390   // Send back arbitrary tx power.
3391   auto packet = hci::EventPacket::New<
3392       pwemb::LEReadAdvertisingChannelTxPowerCommandCompleteEventWriter>(
3393       hci_spec::kCommandCompleteEventCode);
3394   auto view = packet.view_t();
3395   view.status().Write(pwemb::StatusCode::SUCCESS);
3396   view.tx_power_level().Write(9);
3397   RespondWithCommandComplete(
3398       pwemb::OpCode::LE_READ_ADVERTISING_CHANNEL_TX_POWER, &packet);
3399 }
3400 
SendLEAdvertisingSetTerminatedEvent(hci_spec::ConnectionHandle conn_handle,hci_spec::AdvertisingHandle adv_handle)3401 void FakeController::SendLEAdvertisingSetTerminatedEvent(
3402     hci_spec::ConnectionHandle conn_handle,
3403     hci_spec::AdvertisingHandle adv_handle) {
3404   auto packet =
3405       hci::EventPacket::New<pwemb::LEAdvertisingSetTerminatedSubeventWriter>(
3406           hci_spec::kLEMetaEventCode);
3407   auto view = packet.view_t();
3408   view.le_meta_event().subevent_code().Write(
3409       hci_spec::kLEAdvertisingSetTerminatedSubeventCode);
3410   view.status().Write(pwemb::StatusCode::SUCCESS);
3411   view.connection_handle().Write(conn_handle);
3412   view.advertising_handle().Write(adv_handle);
3413   SendCommandChannelPacket(packet.data());
3414 }
3415 
SendAndroidLEMultipleAdvertisingStateChangeSubevent(hci_spec::ConnectionHandle conn_handle,hci_spec::AdvertisingHandle adv_handle)3416 void FakeController::SendAndroidLEMultipleAdvertisingStateChangeSubevent(
3417     hci_spec::ConnectionHandle conn_handle,
3418     hci_spec::AdvertisingHandle adv_handle) {
3419   auto packet =
3420       hci::EventPacket::New<android_emb::LEMultiAdvtStateChangeSubeventWriter>(
3421           hci_spec::kVendorDebugEventCode);
3422   auto view = packet.view_t();
3423   view.vendor_event().subevent_code().Write(
3424       android_hci::kLEMultiAdvtStateChangeSubeventCode);
3425   view.advertising_handle().Write(adv_handle);
3426   view.status().Write(pwemb::StatusCode::SUCCESS);
3427   view.connection_handle().Write(conn_handle);
3428   SendCommandChannelPacket(packet.data());
3429 }
3430 
OnReadLocalSupportedControllerDelay(const pwemb::ReadLocalSupportedControllerDelayCommandView & params)3431 void FakeController::OnReadLocalSupportedControllerDelay(
3432     const pwemb::ReadLocalSupportedControllerDelayCommandView& params) {
3433   auto packet = hci::EventPacket::New<
3434       pwemb::ReadLocalSupportedControllerDelayCommandCompleteEventWriter>(
3435       hci_spec::kCommandCompleteEventCode);
3436   auto response_view = packet.view_t();
3437   if (settings_.SupportedCommandsView()
3438           .read_local_supported_controller_delay()
3439           .Read()) {
3440     response_view.status().Write(pwemb::StatusCode::SUCCESS);
3441     response_view.min_controller_delay().Write(0);  // no delay
3442     response_view.max_controller_delay().Write(
3443         pwemb::ReadLocalSupportedControllerDelayCommandCompleteEvent::
3444             max_delay_usecs());  // maximum allowable delay
3445   } else {
3446     response_view.status().Write(pwemb::StatusCode::UNKNOWN_COMMAND);
3447   }
3448 
3449   RespondWithCommandComplete(
3450       pwemb::OpCode::READ_LOCAL_SUPPORTED_CONTROLLER_DELAY, &packet);
3451 }
3452 
OnCommandPacketReceived(const PacketView<hci_spec::CommandHeader> & command_packet)3453 void FakeController::OnCommandPacketReceived(
3454     const PacketView<hci_spec::CommandHeader>& command_packet) {
3455   hci_spec::OpCode opcode = pw::bytes::ConvertOrderFrom(
3456       cpp20::endian::little, command_packet.header().opcode);
3457 
3458   bt_log(
3459       TRACE, "fake-hci", "received command packet with opcode: %#.4x", opcode);
3460   // We handle commands immediately unless a client has explicitly set a
3461   // listener for `opcode`.
3462   if (paused_opcode_listeners_.find(opcode) == paused_opcode_listeners_.end()) {
3463     HandleReceivedCommandPacket(command_packet);
3464     return;
3465   }
3466 
3467   bt_log(DEBUG, "fake-hci", "pausing response for opcode: %#.4x", opcode);
3468   paused_opcode_listeners_[opcode](
3469       [this, packet_data = DynamicByteBuffer(command_packet.data())]() {
3470         PacketView<hci_spec::CommandHeader> command_packet(
3471             &packet_data, packet_data.size() - sizeof(hci_spec::CommandHeader));
3472         HandleReceivedCommandPacket(command_packet);
3473       });
3474 }
3475 
OnAndroidLEGetVendorCapabilities()3476 void FakeController::OnAndroidLEGetVendorCapabilities() {
3477   // We use the
3478   // android_emb::LEGetVendorCapabilitiesCommandCompleteEventWriter as
3479   // storage. This is the full HCI packet, including the header. Ensure we don't
3480   // accidentally send the header twice by using the overloaded
3481   // RespondWithCommandComplete that takes in an EventPacket. The one that
3482   // takes a BufferView allocates space for the header, assuming that it's been
3483   // sent only the payload.
3484   auto packet = hci::EventPacket::New<
3485       android_emb::LEGetVendorCapabilitiesCommandCompleteEventWriter>(
3486       hci_spec::kCommandCompleteEventCode);
3487   MutableBufferView buffer = packet.mutable_data();
3488   settings_.android_extension_settings.data().Copy(&buffer);
3489   RespondWithCommandComplete(android_hci::kLEGetVendorCapabilities, &packet);
3490 }
3491 
OnAndroidStartA2dpOffload(const android_emb::StartA2dpOffloadCommandView & params)3492 void FakeController::OnAndroidStartA2dpOffload(
3493     const android_emb::StartA2dpOffloadCommandView& params) {
3494   auto packet =
3495       hci::EventPacket::New<android_emb::A2dpOffloadCommandCompleteEventWriter>(
3496           hci_spec::kCommandCompleteEventCode);
3497   auto view = packet.view_t();
3498   view.sub_opcode().Write(android_emb::A2dpOffloadSubOpcode::START_LEGACY);
3499 
3500   // return in case A2DP offload already started
3501   if (offloaded_a2dp_channel_state_) {
3502     view.status().Write(pwemb::StatusCode::CONNECTION_ALREADY_EXISTS);
3503     RespondWithCommandComplete(android_hci::kA2dpOffloadCommand, &packet);
3504     return;
3505   }
3506 
3507   // SCMS-T is not currently supported
3508   if (params.scms_t_enable().enabled().Read() ==
3509       pwemb::GenericEnableParam::ENABLE) {
3510     view.status().Write(pwemb::StatusCode::UNSUPPORTED_FEATURE_OR_PARAMETER);
3511     RespondWithCommandComplete(android_hci::kA2dpOffloadCommand, &packet);
3512     return;
3513   }
3514 
3515   // return in case any parameter has an invalid value
3516   view.status().Write(pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
3517 
3518   android_emb::A2dpCodecType const codec_type = params.codec_type().Read();
3519   switch (codec_type) {
3520     case android_emb::A2dpCodecType::SBC:
3521     case android_emb::A2dpCodecType::AAC:
3522     case android_emb::A2dpCodecType::APTX:
3523     case android_emb::A2dpCodecType::APTX_HD:
3524     case android_emb::A2dpCodecType::LDAC:
3525       break;
3526       RespondWithCommandComplete(android_hci::kA2dpOffloadCommand, &packet);
3527       return;
3528   }
3529 
3530   android_emb::A2dpSamplingFrequency const sampling_frequency =
3531       params.sampling_frequency().Read();
3532   switch (sampling_frequency) {
3533     case android_emb::A2dpSamplingFrequency::HZ_44100:
3534     case android_emb::A2dpSamplingFrequency::HZ_48000:
3535     case android_emb::A2dpSamplingFrequency::HZ_88200:
3536     case android_emb::A2dpSamplingFrequency::HZ_96000:
3537       break;
3538     default:
3539       RespondWithCommandComplete(android_hci::kA2dpOffloadCommand, &packet);
3540       return;
3541   }
3542 
3543   android_emb::A2dpBitsPerSample const bits_per_sample =
3544       static_cast<android_emb::A2dpBitsPerSample>(
3545           params.bits_per_sample().Read());
3546   switch (bits_per_sample) {
3547     case android_emb::A2dpBitsPerSample::BITS_PER_SAMPLE_16:
3548     case android_emb::A2dpBitsPerSample::BITS_PER_SAMPLE_24:
3549     case android_emb::A2dpBitsPerSample::BITS_PER_SAMPLE_32:
3550       break;
3551     default:
3552       RespondWithCommandComplete(android_hci::kA2dpOffloadCommand, &packet);
3553       return;
3554   }
3555 
3556   android_emb::A2dpChannelMode const channel_mode =
3557       static_cast<android_emb::A2dpChannelMode>(params.channel_mode().Read());
3558   switch (channel_mode) {
3559     case android_emb::A2dpChannelMode::MONO:
3560     case android_emb::A2dpChannelMode::STEREO:
3561       break;
3562     default:
3563       RespondWithCommandComplete(android_hci::kA2dpOffloadCommand, &packet);
3564       return;
3565   }
3566 
3567   uint32_t const encoded_audio_bitrate = pw::bytes::ConvertOrderFrom(
3568       cpp20::endian::little, params.encoded_audio_bitrate().Read());
3569   // Bits 0x01000000 to 0xFFFFFFFF are reserved
3570   if (encoded_audio_bitrate >= 0x01000000) {
3571     RespondWithCommandComplete(android_hci::kA2dpOffloadCommand, &packet);
3572     return;
3573   }
3574 
3575   OffloadedA2dpChannel state;
3576   state.codec_type = codec_type;
3577   state.max_latency = pw::bytes::ConvertOrderFrom(cpp20::endian::little,
3578                                                   params.max_latency().Read());
3579   state.scms_t_enable.view().CopyFrom(params.scms_t_enable());
3580   state.sampling_frequency = sampling_frequency;
3581   state.bits_per_sample = bits_per_sample;
3582   state.channel_mode = channel_mode;
3583   state.encoded_audio_bitrate = encoded_audio_bitrate;
3584   state.connection_handle = pw::bytes::ConvertOrderFrom(
3585       cpp20::endian::little, params.connection_handle().Read());
3586   state.l2cap_channel_id = pw::bytes::ConvertOrderFrom(
3587       cpp20::endian::little, params.l2cap_channel_id().Read());
3588   state.l2cap_mtu_size = pw::bytes::ConvertOrderFrom(
3589       cpp20::endian::little, params.l2cap_mtu_size().Read());
3590   offloaded_a2dp_channel_state_ = state;
3591 
3592   view.status().Write(pwemb::StatusCode::SUCCESS);
3593   RespondWithCommandComplete(android_hci::kA2dpOffloadCommand, &packet);
3594 }
3595 
OnAndroidStopA2dpOffload()3596 void FakeController::OnAndroidStopA2dpOffload() {
3597   auto packet =
3598       hci::EventPacket::New<android_emb::A2dpOffloadCommandCompleteEventWriter>(
3599           hci_spec::kCommandCompleteEventCode);
3600   auto view = packet.view_t();
3601   view.sub_opcode().Write(android_emb::A2dpOffloadSubOpcode::STOP_LEGACY);
3602 
3603   if (!offloaded_a2dp_channel_state_) {
3604     view.status().Write(pwemb::StatusCode::REPEATED_ATTEMPTS);
3605     RespondWithCommandComplete(android_hci::kA2dpOffloadCommand, &packet);
3606     return;
3607   }
3608 
3609   offloaded_a2dp_channel_state_ = std::nullopt;
3610 
3611   view.status().Write(pwemb::StatusCode::SUCCESS);
3612   RespondWithCommandComplete(android_hci::kA2dpOffloadCommand, &packet);
3613 }
3614 
OnAndroidA2dpOffloadCommand(const PacketView<hci_spec::CommandHeader> & command_packet)3615 void FakeController::OnAndroidA2dpOffloadCommand(
3616     const PacketView<hci_spec::CommandHeader>& command_packet) {
3617   const auto& payload = command_packet.payload_data();
3618 
3619   uint8_t subopcode = payload.To<uint8_t>();
3620   switch (subopcode) {
3621     case android_hci::kStartA2dpOffloadCommandSubopcode: {
3622       auto view = android_emb::MakeStartA2dpOffloadCommandView(
3623           command_packet.data().data(), command_packet.data().size());
3624       OnAndroidStartA2dpOffload(view);
3625       break;
3626     }
3627     case android_hci::kStopA2dpOffloadCommandSubopcode:
3628       OnAndroidStopA2dpOffload();
3629       break;
3630     default:
3631       bt_log(WARN,
3632              "fake-hci",
3633              "unhandled android A2DP offload command, subopcode: %#.4x",
3634              subopcode);
3635       RespondWithCommandComplete(subopcode, pwemb::StatusCode::UNKNOWN_COMMAND);
3636       break;
3637   }
3638 }
3639 
OnAndroidLEMultiAdvtSetAdvtParam(const android_emb::LEMultiAdvtSetAdvtParamCommandView & params)3640 void FakeController::OnAndroidLEMultiAdvtSetAdvtParam(
3641     const android_emb::LEMultiAdvtSetAdvtParamCommandView& params) {
3642   auto packet =
3643       hci::EventPacket::New<android_emb::LEMultiAdvtCommandCompleteEventWriter>(
3644           hci_spec::kCommandCompleteEventCode);
3645   auto view = packet.view_t();
3646   view.sub_opcode().Write(
3647       android_emb::LEMultiAdvtSubOpcode::SET_ADVERTISING_PARAMETERS);
3648 
3649   hci_spec::AdvertisingHandle handle = params.adv_handle().Read();
3650   if (!IsValidAdvertisingHandle(handle)) {
3651     bt_log(ERROR, "fake-hci", "advertising handle outside range: %d", handle);
3652 
3653     view.status().Write(pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
3654     RespondWithCommandComplete(android_hci::kLEMultiAdvt, &packet);
3655     return;
3656   }
3657 
3658   // ensure we can allocate memory for this advertising set if not already
3659   // present
3660   if (extended_advertising_states_.count(handle) == 0 &&
3661       extended_advertising_states_.size() >= num_supported_advertising_sets()) {
3662     bt_log(INFO,
3663            "fake-hci",
3664            "no available memory for new advertising set, handle: %d",
3665            handle);
3666 
3667     view.status().Write(pwemb::StatusCode::MEMORY_CAPACITY_EXCEEDED);
3668     RespondWithCommandComplete(android_hci::kLEMultiAdvt, &packet);
3669     return;
3670   }
3671 
3672   // In case there is an error below, we want to reject all parameters instead
3673   // of storing a dead state and taking up an advertising handle. Avoid creating
3674   // the LEAdvertisingState directly in the map and add it in only once we have
3675   // made sure all is good.
3676   LEAdvertisingState state;
3677   state.own_address_type = params.own_addr_type().Read();
3678 
3679   pwemb::LEAdvertisingType adv_type = params.adv_type().Read();
3680   switch (adv_type) {
3681     case pwemb::LEAdvertisingType::CONNECTABLE_AND_SCANNABLE_UNDIRECTED:
3682       state.properties.connectable = true;
3683       state.properties.scannable = true;
3684       break;
3685     case pwemb::LEAdvertisingType::CONNECTABLE_LOW_DUTY_CYCLE_DIRECTED:
3686       state.properties.directed = true;
3687       state.properties.connectable = true;
3688       break;
3689     case pwemb::LEAdvertisingType::CONNECTABLE_HIGH_DUTY_CYCLE_DIRECTED:
3690       state.properties.high_duty_cycle_directed_connectable = true;
3691       state.properties.directed = true;
3692       state.properties.connectable = true;
3693       break;
3694     case pwemb::LEAdvertisingType::SCANNABLE_UNDIRECTED:
3695       state.properties.scannable = true;
3696       break;
3697     case pwemb::LEAdvertisingType::NOT_CONNECTABLE_UNDIRECTED:
3698       break;
3699   }
3700 
3701   state.interval_min = params.adv_interval_min().Read();
3702   state.interval_max = params.adv_interval_max().Read();
3703 
3704   if (state.interval_min >= state.interval_max) {
3705     bt_log(INFO,
3706            "fake-hci",
3707            "advertising interval min (%d) not strictly less than max (%d)",
3708            state.interval_min,
3709            state.interval_max);
3710 
3711     view.status().Write(pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
3712     RespondWithCommandComplete(android_hci::kLEMultiAdvt, &packet);
3713     return;
3714   }
3715 
3716   if (state.interval_min < hci_spec::kLEAdvertisingIntervalMin) {
3717     bt_log(INFO,
3718            "fake-hci",
3719            "advertising interval min (%d) less than spec min (%d)",
3720            state.interval_min,
3721            hci_spec::kLEAdvertisingIntervalMin);
3722     view.status().Write(pwemb::StatusCode::UNSUPPORTED_FEATURE_OR_PARAMETER);
3723     RespondWithCommandComplete(android_hci::kLEMultiAdvt, &packet);
3724     return;
3725   }
3726 
3727   if (state.interval_max > hci_spec::kLEAdvertisingIntervalMax) {
3728     bt_log(INFO,
3729            "fake-hci",
3730            "advertising interval max (%d) greater than spec max (%d)",
3731            state.interval_max,
3732            hci_spec::kLEAdvertisingIntervalMax);
3733     view.status().Write(pwemb::StatusCode::UNSUPPORTED_FEATURE_OR_PARAMETER);
3734     RespondWithCommandComplete(android_hci::kLEMultiAdvt, &packet);
3735     return;
3736   }
3737 
3738   // write full state back only at the end (we don't have a reference because we
3739   // only want to write if there are no errors)
3740   extended_advertising_states_[handle] = state;
3741 
3742   view.status().Write(pwemb::StatusCode::SUCCESS);
3743   RespondWithCommandComplete(android_hci::kLEMultiAdvt, &packet);
3744   NotifyAdvertisingState();
3745 }
3746 
OnAndroidLEMultiAdvtSetAdvtData(const android_emb::LEMultiAdvtSetAdvtDataCommandView & params)3747 void FakeController::OnAndroidLEMultiAdvtSetAdvtData(
3748     const android_emb::LEMultiAdvtSetAdvtDataCommandView& params) {
3749   auto packet =
3750       hci::EventPacket::New<android_emb::LEMultiAdvtCommandCompleteEventWriter>(
3751           hci_spec::kCommandCompleteEventCode);
3752   auto view = packet.view_t();
3753   view.sub_opcode().Write(
3754       android_emb::LEMultiAdvtSubOpcode::SET_ADVERTISING_DATA);
3755 
3756   hci_spec::AdvertisingHandle handle = params.adv_handle().Read();
3757   if (!IsValidAdvertisingHandle(handle)) {
3758     bt_log(ERROR, "fake-hci", "advertising handle outside range: %d", handle);
3759 
3760     view.status().Write(pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
3761     RespondWithCommandComplete(android_hci::kLEMultiAdvt, &packet);
3762     return;
3763   }
3764 
3765   if (extended_advertising_states_.count(handle) == 0) {
3766     bt_log(INFO,
3767            "fake-hci",
3768            "advertising handle (%d) maps to an unknown advertising set",
3769            handle);
3770 
3771     view.status().Write(pwemb::StatusCode::UNKNOWN_ADVERTISING_IDENTIFIER);
3772     RespondWithCommandComplete(android_hci::kLEMultiAdvt, &packet);
3773     return;
3774   }
3775 
3776   LEAdvertisingState& state = extended_advertising_states_[handle];
3777 
3778   // removing advertising data entirely doesn't require us to check for error
3779   // conditions
3780   if (params.adv_data_length().Read() == 0) {
3781     state.data_length = 0;
3782     std::memset(state.data, 0, sizeof(state.data));
3783     view.status().Write(pwemb::StatusCode::SUCCESS);
3784     RespondWithCommandComplete(android_hci::kLEMultiAdvt, &packet);
3785     NotifyAdvertisingState();
3786     return;
3787   }
3788 
3789   // directed advertising doesn't support advertising data
3790   if (state.IsDirectedAdvertising()) {
3791     bt_log(INFO,
3792            "fake-hci",
3793            "cannot provide advertising data when using directed advertising");
3794 
3795     view.status().Write(pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
3796     RespondWithCommandComplete(android_hci::kLEMultiAdvt, &packet);
3797     return;
3798   }
3799 
3800   if (params.adv_data_length().Read() > hci_spec::kMaxLEAdvertisingDataLength) {
3801     bt_log(INFO,
3802            "fake-hci",
3803            "data length (%d bytes) larger than legacy PDU size limit",
3804            params.adv_data_length().Read());
3805 
3806     view.status().Write(pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
3807     RespondWithCommandComplete(android_hci::kLEMultiAdvt, &packet);
3808     return;
3809   }
3810 
3811   state.data_length = params.adv_data_length().Read();
3812   std::memcpy(state.data,
3813               params.adv_data().BackingStorage().data(),
3814               params.adv_data_length().Read());
3815 
3816   view.status().Write(pwemb::StatusCode::SUCCESS);
3817   RespondWithCommandComplete(android_hci::kLEMultiAdvt, &packet);
3818   NotifyAdvertisingState();
3819 }
3820 
OnAndroidLEMultiAdvtSetScanResp(const android_emb::LEMultiAdvtSetScanRespDataCommandView & params)3821 void FakeController::OnAndroidLEMultiAdvtSetScanResp(
3822     const android_emb::LEMultiAdvtSetScanRespDataCommandView& params) {
3823   auto packet =
3824       hci::EventPacket::New<android_emb::LEMultiAdvtCommandCompleteEventWriter>(
3825           hci_spec::kCommandCompleteEventCode);
3826   auto view = packet.view_t();
3827   view.sub_opcode().Write(
3828       android_emb::LEMultiAdvtSubOpcode::SET_SCAN_RESPONSE_DATA);
3829 
3830   hci_spec::AdvertisingHandle handle = params.adv_handle().Read();
3831   if (!IsValidAdvertisingHandle(handle)) {
3832     bt_log(ERROR, "fake-hci", "advertising handle outside range: %d", handle);
3833 
3834     view.status().Write(pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
3835     RespondWithCommandComplete(android_hci::kLEMultiAdvt, &packet);
3836     return;
3837   }
3838 
3839   if (extended_advertising_states_.count(handle) == 0) {
3840     bt_log(INFO,
3841            "fake-hci",
3842            "advertising handle (%d) maps to an unknown advertising set",
3843            handle);
3844 
3845     view.status().Write(pwemb::StatusCode::UNKNOWN_ADVERTISING_IDENTIFIER);
3846     RespondWithCommandComplete(android_hci::kLEMultiAdvt, &packet);
3847     return;
3848   }
3849 
3850   LEAdvertisingState& state = extended_advertising_states_[handle];
3851 
3852   // removing scan response data entirely doesn't require us to check for error
3853   // conditions
3854   if (params.scan_resp_length().Read() == 0) {
3855     state.scan_rsp_length = 0;
3856     std::memset(state.scan_rsp_data, 0, sizeof(state.scan_rsp_data));
3857 
3858     view.status().Write(pwemb::StatusCode::SUCCESS);
3859     RespondWithCommandComplete(android_hci::kLEMultiAdvt, &packet);
3860     NotifyAdvertisingState();
3861     return;
3862   }
3863 
3864   // adding or changing scan response data, check for error conditions
3865   if (!state.properties.scannable) {
3866     bt_log(
3867         INFO,
3868         "fake-hci",
3869         "cannot provide scan response data for unscannable advertising types");
3870 
3871     view.status().Write(pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
3872     RespondWithCommandComplete(android_hci::kLEMultiAdvt, &packet);
3873     return;
3874   }
3875 
3876   if (params.scan_resp_length().Read() >
3877       hci_spec::kMaxLEAdvertisingDataLength) {
3878     bt_log(INFO,
3879            "fake-hci",
3880            "data length (%d bytes) larger than legacy PDU size limit",
3881            params.scan_resp_length().Read());
3882 
3883     view.status().Write(pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
3884     RespondWithCommandComplete(android_hci::kLEMultiAdvt, &packet);
3885     return;
3886   }
3887 
3888   state.scan_rsp_length = params.scan_resp_length().Read();
3889   std::memcpy(state.scan_rsp_data,
3890               params.adv_data().BackingStorage().data(),
3891               params.scan_resp_length().Read());
3892 
3893   view.status().Write(pwemb::StatusCode::SUCCESS);
3894   RespondWithCommandComplete(android_hci::kLEMultiAdvt, &packet);
3895   NotifyAdvertisingState();
3896 }
3897 
OnAndroidLEMultiAdvtSetRandomAddr(const android_emb::LEMultiAdvtSetRandomAddrCommandView & params)3898 void FakeController::OnAndroidLEMultiAdvtSetRandomAddr(
3899     const android_emb::LEMultiAdvtSetRandomAddrCommandView& params) {
3900   auto packet =
3901       hci::EventPacket::New<android_emb::LEMultiAdvtCommandCompleteEventWriter>(
3902           hci_spec::kCommandCompleteEventCode);
3903   auto view = packet.view_t();
3904   view.sub_opcode().Write(
3905       android_emb::LEMultiAdvtSubOpcode::SET_RANDOM_ADDRESS);
3906 
3907   hci_spec::AdvertisingHandle handle = params.adv_handle().Read();
3908   if (!IsValidAdvertisingHandle(handle)) {
3909     bt_log(ERROR, "fake-hci", "advertising handle outside range: %d", handle);
3910 
3911     view.status().Write(pwemb::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
3912     RespondWithCommandComplete(android_hci::kLEMultiAdvt, &packet);
3913     return;
3914   }
3915 
3916   if (extended_advertising_states_.count(handle) == 0) {
3917     bt_log(INFO,
3918            "fake-hci",
3919            "advertising handle (%d) maps to an unknown advertising set",
3920            handle);
3921 
3922     view.status().Write(pwemb::StatusCode::UNKNOWN_ADVERTISING_IDENTIFIER);
3923     RespondWithCommandComplete(android_hci::kLEMultiAdvt, &packet);
3924     return;
3925   }
3926 
3927   LEAdvertisingState& state = extended_advertising_states_[handle];
3928   if (state.properties.connectable && state.enabled) {
3929     bt_log(
3930         INFO,
3931         "fake-hci",
3932         "cannot set LE random address while connectable advertising enabled");
3933 
3934     view.status().Write(pwemb::StatusCode::COMMAND_DISALLOWED);
3935     RespondWithCommandComplete(android_hci::kLEMultiAdvt, &packet);
3936     return;
3937   }
3938 
3939   state.random_address =
3940       DeviceAddress(DeviceAddress::Type::kLERandom,
3941                     DeviceAddressBytes(params.peer_address()));
3942 
3943   view.status().Write(pwemb::StatusCode::SUCCESS);
3944   RespondWithCommandComplete(android_hci::kLEMultiAdvt, &packet);
3945 }
3946 
OnAndroidLEMultiAdvtEnable(const android_emb::LEMultiAdvtEnableCommandView & params)3947 void FakeController::OnAndroidLEMultiAdvtEnable(
3948     const android_emb::LEMultiAdvtEnableCommandView& params) {
3949   auto packet =
3950       hci::EventPacket::New<android_emb::LEMultiAdvtCommandCompleteEventWriter>(
3951           hci_spec::kCommandCompleteEventCode);
3952   auto view = packet.view_t();
3953   view.sub_opcode().Write(android_emb::LEMultiAdvtSubOpcode::ENABLE);
3954 
3955   hci_spec::AdvertisingHandle handle = params.advertising_handle().Read();
3956 
3957   if (!IsValidAdvertisingHandle(handle)) {
3958     bt_log(ERROR, "fake-hci", "advertising handle outside range: %d", handle);
3959 
3960     view.status().Write(pwemb::StatusCode::UNKNOWN_ADVERTISING_IDENTIFIER);
3961     RespondWithCommandComplete(android_hci::kLEMultiAdvt, &packet);
3962     return;
3963   }
3964 
3965   bool enabled = false;
3966   if (params.enable().Read() == pwemb::GenericEnableParam::ENABLE) {
3967     enabled = true;
3968   }
3969 
3970   extended_advertising_states_[handle].enabled = enabled;
3971 
3972   view.status().Write(pwemb::StatusCode::SUCCESS);
3973   RespondWithCommandComplete(android_hci::kLEMultiAdvt, &packet);
3974   NotifyAdvertisingState();
3975 }
3976 
OnAndroidLEMultiAdvt(const PacketView<hci_spec::CommandHeader> & command_packet)3977 void FakeController::OnAndroidLEMultiAdvt(
3978     const PacketView<hci_spec::CommandHeader>& command_packet) {
3979   const auto& payload = command_packet.payload_data();
3980 
3981   uint8_t subopcode = payload.To<uint8_t>();
3982   switch (subopcode) {
3983     case android_hci::kLEMultiAdvtSetAdvtParamSubopcode: {
3984       auto params = android_emb::MakeLEMultiAdvtSetAdvtParamCommandView(
3985           command_packet.data().data(), command_packet.data().size());
3986       OnAndroidLEMultiAdvtSetAdvtParam(params);
3987       break;
3988     }
3989     case android_hci::kLEMultiAdvtSetAdvtDataSubopcode: {
3990       auto params = android_emb::MakeLEMultiAdvtSetAdvtDataCommandView(
3991           command_packet.data().data(), command_packet.data().size());
3992       OnAndroidLEMultiAdvtSetAdvtData(params);
3993       break;
3994     }
3995     case android_hci::kLEMultiAdvtSetScanRespSubopcode: {
3996       auto params = android_emb::MakeLEMultiAdvtSetScanRespDataCommandView(
3997           command_packet.data().data(), command_packet.data().size());
3998       OnAndroidLEMultiAdvtSetScanResp(params);
3999       break;
4000     }
4001     case android_hci::kLEMultiAdvtSetRandomAddrSubopcode: {
4002       auto params = android_emb::MakeLEMultiAdvtSetRandomAddrCommandView(
4003           command_packet.data().data(), command_packet.data().size());
4004       OnAndroidLEMultiAdvtSetRandomAddr(params);
4005       break;
4006     }
4007     case android_hci::kLEMultiAdvtEnableSubopcode: {
4008       auto view = android_emb::MakeLEMultiAdvtEnableCommandView(
4009           command_packet.data().data(), command_packet.data().size());
4010       OnAndroidLEMultiAdvtEnable(view);
4011       break;
4012     }
4013     default: {
4014       bt_log(WARN,
4015              "fake-hci",
4016              "unhandled android multiple advertising command, subopcode: %#.4x",
4017              subopcode);
4018       RespondWithCommandComplete(subopcode, pwemb::StatusCode::UNKNOWN_COMMAND);
4019       break;
4020     }
4021   }
4022 }
4023 
OnVendorCommand(const PacketView<hci_spec::CommandHeader> & command_packet)4024 void FakeController::OnVendorCommand(
4025     const PacketView<hci_spec::CommandHeader>& command_packet) {
4026   auto opcode = pw::bytes::ConvertOrderFrom(cpp20::endian::little,
4027                                             command_packet.header().opcode);
4028 
4029   switch (opcode) {
4030     case android_hci::kLEGetVendorCapabilities:
4031       OnAndroidLEGetVendorCapabilities();
4032       break;
4033     case android_hci::kA2dpOffloadCommand:
4034       OnAndroidA2dpOffloadCommand(command_packet);
4035       break;
4036     case android_hci::kLEMultiAdvt:
4037       OnAndroidLEMultiAdvt(command_packet);
4038       break;
4039     default:
4040       bt_log(WARN,
4041              "fake-hci",
4042              "received unhandled vendor command with opcode: %#.4x",
4043              opcode);
4044       RespondWithCommandComplete(opcode, pwemb::StatusCode::UNKNOWN_COMMAND);
4045       break;
4046   }
4047 }
4048 
OnACLDataPacketReceived(const ByteBuffer & acl_data_packet)4049 void FakeController::OnACLDataPacketReceived(
4050     const ByteBuffer& acl_data_packet) {
4051   if (acl_data_callback_) {
4052     PW_DCHECK(data_dispatcher_);
4053     DynamicByteBuffer packet_copy(acl_data_packet);
4054     (void)data_dispatcher_->Post(
4055         [packet_copy = std::move(packet_copy), cb = acl_data_callback_.share()](
4056             pw::async::Context /*ctx*/, pw::Status status) mutable {
4057           if (status.ok()) {
4058             cb(packet_copy);
4059           }
4060         });
4061   }
4062 
4063   if (acl_data_packet.size() < sizeof(hci_spec::ACLDataHeader)) {
4064     bt_log(WARN, "fake-hci", "malformed ACL packet!");
4065     return;
4066   }
4067 
4068   const auto& header = acl_data_packet.To<hci_spec::ACLDataHeader>();
4069   hci_spec::ConnectionHandle handle =
4070       pw::bytes::ConvertOrderFrom(cpp20::endian::little,
4071                                   header.handle_and_flags) &
4072       0x0FFFF;
4073   FakePeer* peer = FindByConnHandle(handle);
4074   if (!peer) {
4075     bt_log(WARN, "fake-hci", "ACL data received for unknown handle!");
4076     return;
4077   }
4078 
4079   if (auto_completed_packets_event_enabled_) {
4080     SendNumberOfCompletedPacketsEvent(handle, 1);
4081   }
4082   peer->OnRxL2CAP(handle,
4083                   acl_data_packet.view(sizeof(hci_spec::ACLDataHeader)));
4084 }
4085 
OnScoDataPacketReceived(const ByteBuffer & sco_data_packet)4086 void FakeController::OnScoDataPacketReceived(
4087     const ByteBuffer& sco_data_packet) {
4088   if (sco_data_callback_) {
4089     sco_data_callback_(sco_data_packet);
4090   }
4091 
4092   if (sco_data_packet.size() < sizeof(hci_spec::SynchronousDataHeader)) {
4093     bt_log(WARN, "fake-hci", "malformed SCO packet!");
4094     return;
4095   }
4096 
4097   const auto& header = sco_data_packet.To<hci_spec::SynchronousDataHeader>();
4098   hci_spec::ConnectionHandle handle =
4099       pw::bytes::ConvertOrderFrom(cpp20::endian::little,
4100                                   header.handle_and_flags) &
4101       0x0FFFF;
4102   FakePeer* peer = FindByConnHandle(handle);
4103   if (!peer) {
4104     bt_log(WARN, "fake-hci", "SCO data received for unknown handle!");
4105     return;
4106   }
4107 
4108   if (auto_completed_packets_event_enabled_) {
4109     SendNumberOfCompletedPacketsEvent(handle, 1);
4110   }
4111 }
4112 
OnIsoDataPacketReceived(const ByteBuffer & iso_data_packet)4113 void FakeController::OnIsoDataPacketReceived(
4114     const ByteBuffer& iso_data_packet) {
4115   if (iso_data_callback_) {
4116     iso_data_callback_(iso_data_packet);
4117   }
4118 
4119   if (iso_data_packet.size() < pwemb::IsoDataFrameHeader::MinSizeInBytes()) {
4120     bt_log(WARN, "fake-hci", "malformed ISO packet!");
4121     return;
4122   }
4123 
4124   auto iso_header_view = pwemb::MakeIsoDataFrameHeaderView(
4125       iso_data_packet.data(), iso_data_packet.size());
4126   hci_spec::ConnectionHandle handle =
4127       iso_header_view.connection_handle().Read();
4128 
4129   if (auto_completed_packets_event_enabled_) {
4130     SendNumberOfCompletedPacketsEvent(handle, 1);
4131   }
4132 }
4133 
SetDataCallback(DataCallback callback,pw::async::Dispatcher & pw_dispatcher)4134 void FakeController::SetDataCallback(DataCallback callback,
4135                                      pw::async::Dispatcher& pw_dispatcher) {
4136   PW_DCHECK(callback);
4137   PW_DCHECK(!acl_data_callback_);
4138   PW_DCHECK(!data_dispatcher_);
4139 
4140   acl_data_callback_ = std::move(callback);
4141   data_dispatcher_.emplace(pw_dispatcher);
4142 }
4143 
ClearDataCallback()4144 void FakeController::ClearDataCallback() {
4145   // Leave dispatcher set (if already set) to preserve its write-once-ness (this
4146   // catches bugs with setting multiple data callbacks in class hierarchies).
4147   acl_data_callback_ = nullptr;
4148 }
4149 
IsDirectedAdvertising() const4150 bool FakeController::LEAdvertisingState::IsDirectedAdvertising() const {
4151   return properties.directed || properties.high_duty_cycle_directed_connectable;
4152 }
4153 
EnableLegacyAdvertising()4154 bool FakeController::EnableLegacyAdvertising() {
4155   if (advertising_procedure() == AdvertisingProcedure::kExtended) {
4156     return false;
4157   }
4158 
4159   advertising_procedure_ = AdvertisingProcedure::kLegacy;
4160   return true;
4161 }
4162 
EnableExtendedAdvertising()4163 bool FakeController::EnableExtendedAdvertising() {
4164   if (advertising_procedure() == AdvertisingProcedure::kLegacy) {
4165     return false;
4166   }
4167 
4168   advertising_procedure_ = AdvertisingProcedure::kExtended;
4169   return true;
4170 }
4171 
HandleReceivedCommandPacket(const PacketView<hci_spec::CommandHeader> & command_packet)4172 void FakeController::HandleReceivedCommandPacket(
4173     const PacketView<hci_spec::CommandHeader>& command_packet) {
4174   hci_spec::OpCode opcode = pw::bytes::ConvertOrderFrom(
4175       cpp20::endian::little, command_packet.header().opcode);
4176 
4177   if (MaybeRespondWithDefaultCommandStatus(opcode)) {
4178     return;
4179   }
4180 
4181   if (MaybeRespondWithDefaultStatus(opcode)) {
4182     return;
4183   }
4184 
4185   auto ogf = hci_spec::GetOGF(opcode);
4186   if (ogf == hci_spec::kVendorOGF) {
4187     OnVendorCommand(command_packet);
4188     return;
4189   }
4190 
4191   // TODO(fxbug.dev/42175513): Validate size of payload to be the correct length
4192   // below.
4193   switch (opcode) {
4194     case hci_spec::kReadLocalVersionInfo: {
4195       OnReadLocalVersionInfo();
4196       break;
4197     }
4198     case hci_spec::kReadLocalSupportedCommands: {
4199       OnReadLocalSupportedCommands();
4200       break;
4201     }
4202     case hci_spec::kReadLocalSupportedFeatures: {
4203       OnReadLocalSupportedFeatures();
4204       break;
4205     }
4206     case hci_spec::kReadBDADDR: {
4207       OnReadBRADDR();
4208       break;
4209     }
4210     case hci_spec::kReadBufferSize: {
4211       OnReadBufferSize();
4212       break;
4213     }
4214     case hci_spec::kCreateConnectionCancel: {
4215       OnCreateConnectionCancel();
4216       break;
4217     }
4218     case hci_spec::kReadLocalName: {
4219       OnReadLocalName();
4220       break;
4221     }
4222     case hci_spec::kReadScanEnable: {
4223       OnReadScanEnable();
4224       break;
4225     }
4226     case hci_spec::kReadPageScanActivity: {
4227       OnReadPageScanActivity();
4228       break;
4229     }
4230     case hci_spec::kReadInquiryMode: {
4231       OnReadInquiryMode();
4232       break;
4233     }
4234     case hci_spec::kReadPageScanType: {
4235       OnReadPageScanType();
4236       break;
4237     }
4238     case hci_spec::kReadSimplePairingMode: {
4239       OnReadSimplePairingMode();
4240       break;
4241     }
4242     case hci_spec::kLECreateConnectionCancel: {
4243       OnLECreateConnectionCancel();
4244       break;
4245     }
4246     case hci_spec::kLEReadLocalSupportedFeatures: {
4247       OnLEReadLocalSupportedFeatures();
4248       break;
4249     }
4250     case hci_spec::kLEReadSupportedStates: {
4251       OnLEReadSupportedStates();
4252       break;
4253     }
4254     case hci_spec::kLEReadBufferSizeV1: {
4255       OnLEReadBufferSizeV1();
4256       break;
4257     }
4258     case hci_spec::kLEReadBufferSizeV2: {
4259       OnLEReadBufferSizeV2();
4260       break;
4261     }
4262     case hci_spec::kReset: {
4263       OnReset();
4264       break;
4265     }
4266     case hci_spec::kLinkKeyRequestReply: {
4267       const auto& params =
4268           command_packet.payload<pwemb::LinkKeyRequestReplyCommandView>();
4269       OnLinkKeyRequestReplyCommandReceived(params);
4270       break;
4271     }
4272     case hci_spec::kLEReadAdvertisingChannelTxPower: {
4273       OnLEReadAdvertisingChannelTxPower();
4274       break;
4275     }
4276     case hci_spec::kAuthenticationRequested:
4277     case hci_spec::kCreateConnection:
4278     case hci_spec::kDisconnect:
4279     case hci_spec::kEnhancedAcceptSynchronousConnectionRequest:
4280     case hci_spec::kEnhancedSetupSynchronousConnection:
4281     case hci_spec::kIOCapabilityRequestReply:
4282     case hci_spec::kInquiry:
4283     case hci_spec::kLEClearAdvertisingSets:
4284     case hci_spec::kLEConnectionUpdate:
4285     case hci_spec::kLECreateConnection:
4286     case hci_spec::kLEExtendedCreateConnection:
4287     case hci_spec::kLEReadMaximumAdvertisingDataLength:
4288     case hci_spec::kLEReadNumSupportedAdvertisingSets:
4289     case hci_spec::kLEReadRemoteFeatures:
4290     case hci_spec::kLERemoveAdvertisingSet:
4291     case hci_spec::kLESetAdvertisingData:
4292     case hci_spec::kLESetAdvertisingEnable:
4293     case hci_spec::kLESetAdvertisingParameters:
4294     case hci_spec::kLESetAdvertisingSetRandomAddress:
4295     case hci_spec::kLESetEventMask:
4296     case hci_spec::kLESetExtendedAdvertisingData:
4297     case hci_spec::kLESetExtendedAdvertisingEnable:
4298     case hci_spec::kLESetExtendedAdvertisingParameters:
4299     case hci_spec::kLESetExtendedScanEnable:
4300     case hci_spec::kLESetExtendedScanParameters:
4301     case hci_spec::kLESetExtendedScanResponseData:
4302     case hci_spec::kLESetHostFeature:
4303     case hci_spec::kLESetRandomAddress:
4304     case hci_spec::kLESetScanEnable:
4305     case hci_spec::kLESetScanParameters:
4306     case hci_spec::kLESetScanResponseData:
4307     case hci_spec::kLEStartEncryption:
4308     case hci_spec::kLinkKeyRequestNegativeReply:
4309     case hci_spec::kReadEncryptionKeySize:
4310     case hci_spec::kReadLocalExtendedFeatures:
4311     case hci_spec::kReadLocalSupportedControllerDelay:
4312     case hci_spec::kReadRemoteExtendedFeatures:
4313     case hci_spec::kReadRemoteSupportedFeatures:
4314     case hci_spec::kReadRemoteVersionInfo:
4315     case hci_spec::kRemoteNameRequest:
4316     case hci_spec::kSetConnectionEncryption:
4317     case hci_spec::kSetEventMask:
4318     case hci_spec::kUserConfirmationRequestNegativeReply:
4319     case hci_spec::kUserConfirmationRequestReply:
4320     case hci_spec::kWriteClassOfDevice:
4321     case hci_spec::kWriteExtendedInquiryResponse:
4322     case hci_spec::kWriteInquiryMode:
4323     case hci_spec::kWriteLEHostSupport:
4324     case hci_spec::kWriteLocalName:
4325     case hci_spec::kWritePageScanActivity:
4326     case hci_spec::kWritePageScanType:
4327     case hci_spec::kWriteScanEnable:
4328     case hci_spec::kWriteSecureConnectionsHostSupport:
4329     case hci_spec::kWriteSimplePairingMode:
4330     case hci_spec::kWriteSynchronousFlowControlEnable: {
4331       // This case is for packet types that have been migrated to the new Emboss
4332       // architecture. Their old version can be still be assembled from the
4333       // HciEmulator channel, so here we repackage and forward them as Emboss
4334       // packets.
4335       auto emboss_packet =
4336           bt::hci::CommandPacket::New<pwemb::CommandHeaderView>(
4337               opcode, command_packet.size());
4338       bt::MutableBufferView dest = emboss_packet.mutable_data();
4339       command_packet.data().view().Copy(&dest);
4340       HandleReceivedCommandPacket(emboss_packet);
4341       break;
4342     }
4343     default: {
4344       bt_log(WARN,
4345              "fake-hci",
4346              "received unhandled command with opcode: %#.4x",
4347              opcode);
4348       RespondWithCommandComplete(opcode, pwemb::StatusCode::UNKNOWN_COMMAND);
4349       break;
4350     }
4351   }
4352 }
4353 
HandleReceivedCommandPacket(const hci::CommandPacket & command_packet)4354 void FakeController::HandleReceivedCommandPacket(
4355     const hci::CommandPacket& command_packet) {
4356   hci_spec::OpCode opcode = command_packet.opcode();
4357 
4358   if (MaybeRespondWithDefaultCommandStatus(opcode)) {
4359     return;
4360   }
4361 
4362   if (MaybeRespondWithDefaultStatus(opcode)) {
4363     return;
4364   }
4365 
4366   auto ogf = command_packet.ogf();
4367   if (ogf == hci_spec::kVendorOGF) {
4368     bt_log(WARN,
4369            "fake-hci",
4370            "vendor commands not yet migrated to Emboss; received Emboss vendor "
4371            "command with "
4372            "opcode: %#.4x",
4373            opcode);
4374     RespondWithCommandComplete(opcode, pwemb::StatusCode::UNKNOWN_COMMAND);
4375     return;
4376   }
4377 
4378   switch (opcode) {
4379     case hci_spec::kInquiry: {
4380       auto params = command_packet.view<pwemb::InquiryCommandView>();
4381       OnInquiry(params);
4382       break;
4383     }
4384     case hci_spec::kEnhancedAcceptSynchronousConnectionRequest: {
4385       auto params = command_packet.view<
4386           pwemb::EnhancedAcceptSynchronousConnectionRequestCommandView>();
4387       OnEnhancedAcceptSynchronousConnectionRequestCommand(params);
4388       break;
4389     }
4390     case hci_spec::kEnhancedSetupSynchronousConnection: {
4391       auto params =
4392           command_packet
4393               .view<pwemb::EnhancedSetupSynchronousConnectionCommandView>();
4394       OnEnhancedSetupSynchronousConnectionCommand(params);
4395       break;
4396     }
4397     case hci_spec::kCreateConnection: {
4398       const auto params =
4399           command_packet.view<pwemb::CreateConnectionCommandView>();
4400       OnCreateConnectionCommandReceived(params);
4401       break;
4402     }
4403     case hci_spec::kDisconnect: {
4404       const auto params = command_packet.view<pwemb::DisconnectCommandView>();
4405       OnDisconnectCommandReceived(params);
4406       break;
4407     }
4408     case hci_spec::kLESetAdvertisingEnable: {
4409       const auto params =
4410           command_packet.view<pwemb::LESetAdvertisingEnableCommandView>();
4411       OnLESetAdvertisingEnable(params);
4412       break;
4413     }
4414     case hci_spec::kLESetExtendedAdvertisingEnable: {
4415       const auto params =
4416           command_packet
4417               .view<pwemb::LESetExtendedAdvertisingEnableCommandView>();
4418       OnLESetExtendedAdvertisingEnable(params);
4419       break;
4420     }
4421     case hci_spec::kLERemoveAdvertisingSet: {
4422       const auto params =
4423           command_packet.view<pwemb::LERemoveAdvertisingSetCommandView>();
4424       OnLERemoveAdvertisingSet(params);
4425       break;
4426     }
4427     case hci_spec::kLinkKeyRequestNegativeReply: {
4428       const auto params =
4429           command_packet.view<pwemb::LinkKeyRequestNegativeReplyCommandView>();
4430       OnLinkKeyRequestNegativeReplyCommandReceived(params);
4431       break;
4432     }
4433     case hci_spec::kAuthenticationRequested: {
4434       const auto params =
4435           command_packet.view<pwemb::AuthenticationRequestedCommandView>();
4436       OnAuthenticationRequestedCommandReceived(params);
4437       break;
4438     }
4439     case hci_spec::kSetConnectionEncryption: {
4440       const auto params =
4441           command_packet.view<pwemb::SetConnectionEncryptionCommandView>();
4442       OnSetConnectionEncryptionCommand(params);
4443       break;
4444     }
4445     case hci_spec::kRemoteNameRequest: {
4446       const auto params =
4447           command_packet.view<pwemb::RemoteNameRequestCommandView>();
4448       OnReadRemoteNameRequestCommandReceived(params);
4449       break;
4450     }
4451     case hci_spec::kReadRemoteSupportedFeatures: {
4452       const auto params =
4453           command_packet.view<pwemb::ReadRemoteSupportedFeaturesCommandView>();
4454       OnReadRemoteSupportedFeaturesCommandReceived(params);
4455       break;
4456     }
4457     case hci_spec::kReadRemoteExtendedFeatures: {
4458       const auto params =
4459           command_packet.view<pwemb::ReadRemoteExtendedFeaturesCommandView>();
4460       OnReadRemoteExtendedFeaturesCommandReceived(params);
4461       break;
4462     }
4463     case hci_spec::kReadRemoteVersionInfo: {
4464       const auto params =
4465           command_packet.view<pwemb::ReadRemoteVersionInfoCommandView>();
4466       OnReadRemoteVersionInfoCommandReceived(params);
4467       break;
4468     }
4469     case hci_spec::kIOCapabilityRequestReply: {
4470       const auto params =
4471           command_packet.view<pwemb::IoCapabilityRequestReplyCommandView>();
4472       OnIOCapabilityRequestReplyCommand(params);
4473       break;
4474     }
4475     case hci_spec::kSetEventMask: {
4476       const auto params = command_packet.view<pwemb::SetEventMaskCommandView>();
4477       OnSetEventMask(params);
4478       break;
4479     }
4480     case hci_spec::kWriteLocalName: {
4481       const auto params =
4482           command_packet.view<pwemb::WriteLocalNameCommandView>();
4483       OnWriteLocalName(params);
4484       break;
4485     }
4486     case hci_spec::kWriteScanEnable: {
4487       const auto& params =
4488           command_packet.view<pwemb::WriteScanEnableCommandView>();
4489       OnWriteScanEnable(params);
4490       break;
4491     }
4492     case hci_spec::kWritePageScanActivity: {
4493       const auto& params =
4494           command_packet.view<pwemb::WritePageScanActivityCommandView>();
4495       OnWritePageScanActivity(params);
4496       break;
4497     }
4498     case hci_spec::kUserConfirmationRequestReply: {
4499       const auto& params =
4500           command_packet.view<pwemb::UserConfirmationRequestReplyCommandView>();
4501       OnUserConfirmationRequestReplyCommand(params);
4502       break;
4503     }
4504     case hci_spec::kUserConfirmationRequestNegativeReply: {
4505       const auto& params =
4506           command_packet
4507               .view<pwemb::UserConfirmationRequestNegativeReplyCommandView>();
4508       OnUserConfirmationRequestNegativeReplyCommand(params);
4509       break;
4510     }
4511     case hci_spec::kWriteSynchronousFlowControlEnable: {
4512       const auto& params =
4513           command_packet
4514               .view<pwemb::WriteSynchronousFlowControlEnableCommandView>();
4515       OnWriteSynchronousFlowControlEnableCommand(params);
4516       break;
4517     }
4518     case hci_spec::kWriteExtendedInquiryResponse: {
4519       const auto& params =
4520           command_packet.view<pwemb::WriteExtendedInquiryResponseCommandView>();
4521       OnWriteExtendedInquiryResponse(params);
4522       break;
4523     }
4524     case hci_spec::kWriteSimplePairingMode: {
4525       const auto& params =
4526           command_packet.view<pwemb::WriteSimplePairingModeCommandView>();
4527       OnWriteSimplePairingMode(params);
4528       break;
4529     }
4530     case hci_spec::kWriteClassOfDevice: {
4531       const auto& params =
4532           command_packet.view<pwemb::WriteClassOfDeviceCommandView>();
4533       OnWriteClassOfDevice(params);
4534       break;
4535     }
4536     case hci_spec::kWriteInquiryMode: {
4537       const auto& params =
4538           command_packet.view<pwemb::WriteInquiryModeCommandView>();
4539       OnWriteInquiryMode(params);
4540       break;
4541     };
4542     case hci_spec::kWritePageScanType: {
4543       const auto& params =
4544           command_packet.view<pwemb::WritePageScanTypeCommandView>();
4545       OnWritePageScanType(params);
4546       break;
4547     }
4548     case hci_spec::kWriteLEHostSupport: {
4549       const auto& params =
4550           command_packet.view<pwemb::WriteLEHostSupportCommandView>();
4551       OnWriteLEHostSupportCommandReceived(params);
4552       break;
4553     }
4554     case hci_spec::kWriteSecureConnectionsHostSupport: {
4555       const auto& params =
4556           command_packet
4557               .view<pwemb::WriteSecureConnectionsHostSupportCommandView>();
4558       OnWriteSecureConnectionsHostSupport(params);
4559       break;
4560     }
4561     case hci_spec::kReadEncryptionKeySize: {
4562       const auto& params =
4563           command_packet.view<pwemb::ReadEncryptionKeySizeCommandView>();
4564       OnReadEncryptionKeySizeCommand(params);
4565       break;
4566     }
4567     case hci_spec::kLEReadRemoteFeatures: {
4568       const auto& params =
4569           command_packet.view<pwemb::LEReadRemoteFeaturesCommandView>();
4570       OnLEReadRemoteFeaturesCommand(params);
4571       break;
4572     }
4573     case hci_spec::kLESetEventMask: {
4574       const auto& params =
4575           command_packet.view<pwemb::LESetEventMaskCommandView>();
4576       OnLESetEventMask(params);
4577       break;
4578     }
4579     case hci_spec::kLESetRandomAddress: {
4580       const auto& params =
4581           command_packet.view<pwemb::LESetRandomAddressCommandView>();
4582       OnLESetRandomAddress(params);
4583       break;
4584     }
4585     case hci_spec::kLESetAdvertisingData: {
4586       const auto& params =
4587           command_packet.view<pwemb::LESetAdvertisingDataCommandView>();
4588       OnLESetAdvertisingData(params);
4589       break;
4590     }
4591     case hci_spec::kLESetScanResponseData: {
4592       const auto& params =
4593           command_packet.view<pwemb::LESetScanResponseDataCommandView>();
4594       OnLESetScanResponseData(params);
4595       break;
4596     }
4597     case hci_spec::kLESetScanParameters: {
4598       const auto& params =
4599           command_packet.view<pwemb::LESetScanParametersCommandView>();
4600       OnLESetScanParameters(params);
4601       break;
4602     }
4603     case hci_spec::kLESetExtendedScanParameters: {
4604       const auto& params =
4605           command_packet.view<pwemb::LESetExtendedScanParametersCommandView>();
4606       OnLESetExtendedScanParameters(params);
4607       break;
4608     }
4609     case hci_spec::kLESetScanEnable: {
4610       const auto& params =
4611           command_packet.view<pwemb::LESetScanEnableCommandView>();
4612       OnLESetScanEnable(params);
4613       break;
4614     }
4615     case hci_spec::kLESetExtendedScanEnable: {
4616       const auto& params =
4617           command_packet.view<pwemb::LESetExtendedScanEnableCommandView>();
4618       OnLESetExtendedScanEnable(params);
4619       break;
4620     }
4621     case hci_spec::kLECreateConnection: {
4622       const auto& params =
4623           command_packet.view<pwemb::LECreateConnectionCommandView>();
4624       OnLECreateConnectionCommandReceived(params);
4625       break;
4626     }
4627     case hci_spec::kLEExtendedCreateConnection: {
4628       const auto& params =
4629           command_packet.view<pwemb::LEExtendedCreateConnectionCommandV1View>();
4630       OnLEExtendedCreateConnectionCommandReceived(params);
4631       break;
4632     }
4633     case hci_spec::kLEConnectionUpdate: {
4634       const auto& params =
4635           command_packet.view<pwemb::LEConnectionUpdateCommandView>();
4636       OnLEConnectionUpdateCommandReceived(params);
4637       break;
4638     }
4639     case hci_spec::kLEStartEncryption: {
4640       const auto& params =
4641           command_packet.view<pwemb::LEEnableEncryptionCommandView>();
4642       OnLEStartEncryptionCommand(params);
4643       break;
4644     }
4645     case hci_spec::kReadLocalExtendedFeatures: {
4646       const auto& params =
4647           command_packet.view<pwemb::ReadLocalExtendedFeaturesCommandView>();
4648       OnReadLocalExtendedFeatures(params);
4649       break;
4650     }
4651     case hci_spec::kLESetAdvertisingParameters: {
4652       const auto& params =
4653           command_packet.view<pwemb::LESetAdvertisingParametersCommandView>();
4654       OnLESetAdvertisingParameters(params);
4655       break;
4656     }
4657     case hci_spec::kLESetExtendedAdvertisingData: {
4658       const auto& params =
4659           command_packet.view<pwemb::LESetExtendedAdvertisingDataCommandView>();
4660       OnLESetExtendedAdvertisingData(params);
4661       break;
4662     }
4663     case hci_spec::kLESetExtendedScanResponseData: {
4664       const auto& params =
4665           command_packet
4666               .view<pwemb::LESetExtendedScanResponseDataCommandView>();
4667       OnLESetExtendedScanResponseData(params);
4668       break;
4669     }
4670     case hci_spec::kLESetHostFeature: {
4671       const auto& params =
4672           command_packet.view<pwemb::LESetHostFeatureCommandView>();
4673       OnLESetHostFeature(params);
4674       break;
4675     }
4676     case hci_spec::kLEReadMaximumAdvertisingDataLength: {
4677       OnLEReadMaximumAdvertisingDataLength();
4678       break;
4679     }
4680     case hci_spec::kLEReadNumSupportedAdvertisingSets: {
4681       OnLEReadNumberOfSupportedAdvertisingSets();
4682       break;
4683     }
4684     case hci_spec::kLEClearAdvertisingSets: {
4685       OnLEClearAdvertisingSets();
4686       break;
4687     }
4688     case hci_spec::kLESetAdvertisingSetRandomAddress: {
4689       const auto& params =
4690           command_packet
4691               .view<pwemb::LESetAdvertisingSetRandomAddressCommandView>();
4692       OnLESetAdvertisingSetRandomAddress(params);
4693       break;
4694     }
4695     case hci_spec::kLESetExtendedAdvertisingParameters: {
4696       const auto& params =
4697           command_packet
4698               .view<pwemb::LESetExtendedAdvertisingParametersV1CommandView>();
4699       OnLESetExtendedAdvertisingParameters(params);
4700       break;
4701     }
4702     case hci_spec::kReadLocalSupportedControllerDelay: {
4703       const auto& params =
4704           command_packet
4705               .view<pwemb::ReadLocalSupportedControllerDelayCommandView>();
4706       OnReadLocalSupportedControllerDelay(params);
4707       break;
4708     }
4709     default: {
4710       bt_log(WARN, "fake-hci", "opcode: %#.4x", opcode);
4711       break;
4712     }
4713   }
4714 }
4715 }  // namespace bt::testing
4716