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