1 /*
2  * Copyright 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "model/controller/dual_mode_controller.h"
18 
19 #include <packet_runtime.h>
20 
21 #include <algorithm>
22 #include <cstdint>
23 #include <functional>
24 #include <memory>
25 #include <string>
26 #include <unordered_map>
27 #include <utility>
28 #include <vector>
29 
30 #include "crypto/crypto.h"
31 #include "hci/address_with_type.h"
32 #include "log.h"
33 #include "model/controller/acl_connection_handler.h"
34 #include "model/controller/controller_properties.h"
35 #include "model/controller/sco_connection.h"
36 #include "model/controller/vendor_commands/csr.h"
37 #include "model/devices/device.h"
38 #include "packets/hci_packets.h"
39 #include "packets/link_layer_packets.h"
40 #include "phy.h"
41 
42 using bluetooth::hci::ErrorCode;
43 using bluetooth::hci::LoopbackMode;
44 using bluetooth::hci::OpCode;
45 
46 namespace rootcanal {
47 constexpr uint16_t kNumCommandPackets = 0x01;
48 constexpr uint16_t kLeMaximumDataLength = 64;
49 constexpr uint16_t kLeMaximumDataTime = 0x148;
50 constexpr uint8_t kTransmitPowerLevel = -20;
51 
52 constexpr bool kLeApcfTransportDiscoveryDataFilterSupported = false;
53 constexpr bool kLeApcfAdTypeFilterSupported = true;
54 
55 #define CHECK_PACKET_VIEW(view)                                              \
56   do {                                                                       \
57     if (!CheckPacketView(view, fmt::format("{}:{} - {}() invalid packet",    \
58                                            __FILE__, __LINE__, __func__))) { \
59       return;                                                                \
60     }                                                                        \
61   } while (0)
62 
SetProperties(ControllerProperties properties)63 void DualModeController::SetProperties(ControllerProperties properties) {
64   WARNING(id_, "updating the device properties!");
65   properties_ = std::move(properties);
66 }
67 
68 // Device methods.
GetTypeString() const69 std::string DualModeController::GetTypeString() const {
70   return "Simulated Bluetooth Controller";
71 }
72 
ReceiveLinkLayerPacket(model::packets::LinkLayerPacketView incoming,Phy::Type,int8_t rssi)73 void DualModeController::ReceiveLinkLayerPacket(
74     model::packets::LinkLayerPacketView incoming, Phy::Type /*type*/,
75     int8_t rssi) {
76   link_layer_controller_.IncomingPacket(incoming, rssi);
77 }
78 
Tick()79 void DualModeController::Tick() { link_layer_controller_.Tick(); }
80 
Close()81 void DualModeController::Close() {
82   link_layer_controller_.Close();
83   Device::Close();
84 }
85 
SendCommandCompleteUnknownOpCodeEvent(bluetooth::hci::OpCode op_code) const86 void DualModeController::SendCommandCompleteUnknownOpCodeEvent(
87     bluetooth::hci::OpCode op_code) const {
88   send_event_(bluetooth::hci::CommandCompleteBuilder::Create(
89       kNumCommandPackets, op_code,
90       std::vector<uint8_t>{
91           static_cast<uint8_t>(ErrorCode::UNKNOWN_HCI_COMMAND)}));
92 }
93 
DualModeController(ControllerProperties properties)94 DualModeController::DualModeController(ControllerProperties properties)
95     : properties_(std::move(properties)), random_generator_(id_) {
96   Address public_address{};
97   ASSERT(Address::FromString("3C:5A:B4:04:05:06", public_address));
98   SetAddress(public_address);
99 
100   // Default invalid packet handler will abort the controller
101   // when receiving an invalid packet.
102   invalid_packet_handler_ =
103       [](uint32_t, InvalidPacketReason, std::string message,
104          std::vector<uint8_t> const&) { FATAL("{}", message); };
105 
106   link_layer_controller_.RegisterRemoteChannel(
107       [this](std::shared_ptr<model::packets::LinkLayerPacketBuilder> packet,
108              Phy::Type phy_type, int8_t tx_power) {
109         this->SendLinkLayerPacket(packet, phy_type, tx_power);
110       });
111 }
112 
ForwardToLm(CommandView command)113 void DualModeController::ForwardToLm(CommandView command) {
114   DEBUG(id_, "<< [LM] {}", bluetooth::hci::OpCodeText(command.GetOpCode()));
115   link_layer_controller_.ForwardToLm(command);
116 }
117 
ForwardToLl(CommandView command)118 void DualModeController::ForwardToLl(CommandView command) {
119   DEBUG(id_, "<< [LL] {}", bluetooth::hci::OpCodeText(command.GetOpCode()));
120   link_layer_controller_.ForwardToLl(command);
121 }
122 
HandleAcl(std::shared_ptr<std::vector<uint8_t>> packet)123 void DualModeController::HandleAcl(
124     std::shared_ptr<std::vector<uint8_t>> packet) {
125   auto acl_packet = bluetooth::hci::AclView::Create(pdl::packet::slice(packet));
126   CHECK_PACKET_VIEW(acl_packet);
127 
128   if (loopback_mode_ == LoopbackMode::ENABLE_LOCAL) {
129     uint16_t handle = acl_packet.GetHandle();
130 
131     std::vector<uint8_t> payload(acl_packet.GetPayload());
132     send_acl_(bluetooth::hci::AclBuilder::Create(
133         handle, acl_packet.GetPacketBoundaryFlag(),
134         acl_packet.GetBroadcastFlag(), std::move(payload)));
135 
136     std::vector<bluetooth::hci::CompletedPackets> completed_packets;
137     bluetooth::hci::CompletedPackets cp;
138     cp.connection_handle_ = handle;
139     cp.host_num_of_completed_packets_ = 1;
140     completed_packets.push_back(cp);
141     send_event_(bluetooth::hci::NumberOfCompletedPacketsBuilder::Create(
142         completed_packets));
143     return;
144   }
145 
146   link_layer_controller_.SendAclToRemote(acl_packet);
147 }
148 
HandleSco(std::shared_ptr<std::vector<uint8_t>> packet)149 void DualModeController::HandleSco(
150     std::shared_ptr<std::vector<uint8_t>> packet) {
151   auto sco_packet = bluetooth::hci::ScoView::Create(pdl::packet::slice(packet));
152   CHECK_PACKET_VIEW(sco_packet);
153 
154   if (loopback_mode_ == LoopbackMode::ENABLE_LOCAL) {
155     uint16_t handle = sco_packet.GetHandle();
156 
157     send_sco_(bluetooth::hci::ScoBuilder::Create(
158         handle, sco_packet.GetPacketStatusFlag(), sco_packet.GetData()));
159 
160     std::vector<bluetooth::hci::CompletedPackets> completed_packets;
161     bluetooth::hci::CompletedPackets cp;
162     cp.connection_handle_ = handle;
163     cp.host_num_of_completed_packets_ = 1;
164     completed_packets.push_back(cp);
165     if (link_layer_controller_.GetScoFlowControlEnable()) {
166       send_event_(bluetooth::hci::NumberOfCompletedPacketsBuilder::Create(
167           completed_packets));
168     }
169     return;
170   }
171 
172   link_layer_controller_.SendScoToRemote(sco_packet);
173 }
174 
HandleIso(std::shared_ptr<std::vector<uint8_t>> packet)175 void DualModeController::HandleIso(
176     std::shared_ptr<std::vector<uint8_t>> packet) {
177   auto iso = bluetooth::hci::IsoView::Create(pdl::packet::slice(packet));
178   CHECK_PACKET_VIEW(iso);
179   link_layer_controller_.HandleIso(iso);
180 }
181 
HandleCommand(std::shared_ptr<std::vector<uint8_t>> packet)182 void DualModeController::HandleCommand(
183     std::shared_ptr<std::vector<uint8_t>> packet) {
184   auto command_packet =
185       bluetooth::hci::CommandView::Create(pdl::packet::slice(packet));
186   CHECK_PACKET_VIEW(command_packet);
187 
188   OpCode op_code = command_packet.GetOpCode();
189   const bool is_vendor_command = (static_cast<uint16_t>(op_code) >> 10) == 0x3f;
190   const bool is_known_command =
191       hci_command_op_code_to_index_.count(op_code) > 0;
192   const bool is_implemented_command = hci_command_handlers_.count(op_code) > 0;
193 
194   // HCI Read Local Supported Commands is supported by default.
195   // Vendor commands are supported when implemented.
196   bool is_supported_command =
197       (op_code == OpCode::READ_LOCAL_SUPPORTED_COMMANDS) ||
198       (is_vendor_command && is_implemented_command);
199 
200   // For other commands, query the Support Commands bit mask in
201   // the controller properties.
202   if (!is_supported_command && is_known_command) {
203     int index = static_cast<int>(hci_command_op_code_to_index_.at(op_code));
204     is_supported_command = (properties_.supported_commands[index / 10] &
205                             (1U << (index % 10))) != 0;
206   }
207 
208   // Loopback mode, the commands are sent back to the host.
209   if (loopback_mode_ == LoopbackMode::ENABLE_LOCAL &&
210       op_code != OpCode::RESET &&
211       op_code != OpCode::SET_CONTROLLER_TO_HOST_FLOW_CONTROL &&
212       op_code != OpCode::HOST_BUFFER_SIZE &&
213       op_code != OpCode::HOST_NUMBER_OF_COMPLETED_PACKETS &&
214       op_code != OpCode::READ_BUFFER_SIZE &&
215       op_code != OpCode::READ_LOOPBACK_MODE &&
216       op_code != OpCode::WRITE_LOOPBACK_MODE) {
217     send_event_(bluetooth::hci::LoopbackCommandBuilder::Create(
218         std::vector<uint8_t>(packet->begin(), packet->end())));
219   }
220   // Quirk to reset the host stack when a command is received before the Hci
221   // Reset command.
222   else if (properties_.quirks.hardware_error_before_reset &&
223            !controller_reset_ && op_code != OpCode::RESET) {
224     WARNING(id_,
225             "Received command {} before HCI Reset; sending the Hardware"
226             " Error event",
227             OpCodeText(op_code));
228     send_event_(bluetooth::hci::HardwareErrorBuilder::Create(0x42));
229   }
230   // Command is both supported and implemented.
231   // Invoke the registered handler.
232   else if (is_supported_command && is_implemented_command) {
233     hci_command_handlers_.at(op_code)(this, command_packet);
234   }
235   // Command is supported but not implemented:
236   // the command needs to be implemented to fix this.
237   else if (is_supported_command && properties_.strict) {
238     FATAL(id_,
239           "Unimplemented command {};\n"
240           "This message will be displayed if the command is set as supported\n"
241           "in the command mask but no implementation was provided.\n"
242           "This warning will be fixed by implementing the command in "
243           "DualModeController",
244           OpCodeText(op_code));
245   }
246   // The command is not supported.
247   // Respond with the status code Unknown Command.
248   else {
249     SendCommandCompleteUnknownOpCodeEvent(op_code);
250     uint16_t raw_op_code = static_cast<uint16_t>(op_code);
251     INFO(id_, "Unknown command, opcode: 0x{:04x}, OGF: 0x{:02x}, OCF: 0x{:03x}",
252          raw_op_code, (raw_op_code & 0xFC00) >> 10, raw_op_code & 0x03FF);
253   }
254 }
255 
RegisterInvalidPacketHandler(const std::function<void (uint32_t,InvalidPacketReason,std::string,std::vector<uint8_t> const &)> & handler)256 void DualModeController::RegisterInvalidPacketHandler(
257     const std::function<void(uint32_t, InvalidPacketReason, std::string,
258                              std::vector<uint8_t> const&)>& handler) {
259   INFO(id_, "updating the invalid packet handler");
260   invalid_packet_handler_ = handler;
261 }
262 
RegisterEventChannel(const std::function<void (std::shared_ptr<std::vector<uint8_t>>)> & send_event)263 void DualModeController::RegisterEventChannel(
264     const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>&
265         send_event) {
266   send_event_ =
267       [send_event](std::shared_ptr<bluetooth::hci::EventBuilder> event) {
268         auto bytes = std::make_shared<std::vector<uint8_t>>();
269         event->Serialize(*bytes);
270         send_event(bytes);
271       };
272   link_layer_controller_.RegisterEventChannel(send_event_);
273 }
274 
RegisterAclChannel(const std::function<void (std::shared_ptr<std::vector<uint8_t>>)> & send_acl)275 void DualModeController::RegisterAclChannel(
276     const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>&
277         send_acl) {
278   send_acl_ = [send_acl](std::shared_ptr<bluetooth::hci::AclBuilder> acl_data) {
279     auto bytes = std::make_shared<std::vector<uint8_t>>();
280     acl_data->Serialize(*bytes);
281     send_acl(bytes);
282   };
283   link_layer_controller_.RegisterAclChannel(send_acl_);
284 }
285 
RegisterScoChannel(const std::function<void (std::shared_ptr<std::vector<uint8_t>>)> & send_sco)286 void DualModeController::RegisterScoChannel(
287     const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>&
288         send_sco) {
289   send_sco_ = [send_sco](std::shared_ptr<bluetooth::hci::ScoBuilder> sco_data) {
290     auto bytes = std::make_shared<std::vector<uint8_t>>();
291     sco_data->Serialize(*bytes);
292     send_sco(bytes);
293   };
294   link_layer_controller_.RegisterScoChannel(send_sco_);
295 }
296 
RegisterIsoChannel(const std::function<void (std::shared_ptr<std::vector<uint8_t>>)> & send_iso)297 void DualModeController::RegisterIsoChannel(
298     const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>&
299         send_iso) {
300   send_iso_ = [send_iso](std::shared_ptr<bluetooth::hci::IsoBuilder> iso_data) {
301     auto bytes = std::make_shared<std::vector<uint8_t>>();
302     iso_data->Serialize(*bytes);
303     send_iso(bytes);
304   };
305   link_layer_controller_.RegisterIsoChannel(send_iso_);
306 }
307 
Reset(CommandView command)308 void DualModeController::Reset(CommandView command) {
309   auto command_view = bluetooth::hci::ResetView::Create(command);
310   CHECK_PACKET_VIEW(command_view);
311 
312   DEBUG(id_, "<< Reset");
313 
314   link_layer_controller_.Reset();
315   loopback_mode_ = LoopbackMode::NO_LOOPBACK;
316   controller_reset_ = true;
317 
318   send_event_(bluetooth::hci::ResetCompleteBuilder::Create(kNumCommandPackets,
319                                                            ErrorCode::SUCCESS));
320 }
321 
ReadBufferSize(CommandView command)322 void DualModeController::ReadBufferSize(CommandView command) {
323   auto command_view = bluetooth::hci::ReadBufferSizeView::Create(command);
324   CHECK_PACKET_VIEW(command_view);
325 
326   DEBUG(id_, "<< Read Buffer Size");
327 
328   send_event_(bluetooth::hci::ReadBufferSizeCompleteBuilder::Create(
329       kNumCommandPackets, ErrorCode::SUCCESS,
330       properties_.acl_data_packet_length, properties_.sco_data_packet_length,
331       properties_.total_num_acl_data_packets,
332       properties_.total_num_sco_data_packets));
333 }
334 
ReadFailedContactCounter(CommandView command)335 void DualModeController::ReadFailedContactCounter(CommandView command) {
336   auto command_view =
337       bluetooth::hci::ReadFailedContactCounterView::Create(command);
338   CHECK_PACKET_VIEW(command_view);
339 
340   uint16_t connection_handle = command_view.GetConnectionHandle();
341   uint16_t failed_contact_counter = 0;
342   ErrorCode status = link_layer_controller_.HasAclConnection(connection_handle)
343                          ? ErrorCode::SUCCESS
344                          : ErrorCode::UNKNOWN_CONNECTION;
345 
346   DEBUG(id_, "<< Read Failed Contact Counter");
347   DEBUG(id_, "   connection_handle=0x{:x}", connection_handle);
348 
349   send_event_(bluetooth::hci::ReadFailedContactCounterCompleteBuilder::Create(
350       kNumCommandPackets, status, connection_handle, failed_contact_counter));
351 }
352 
ResetFailedContactCounter(CommandView command)353 void DualModeController::ResetFailedContactCounter(CommandView command) {
354   auto command_view =
355       bluetooth::hci::ReadFailedContactCounterView::Create(command);
356   CHECK_PACKET_VIEW(command_view);
357   uint16_t connection_handle = command_view.GetConnectionHandle();
358 
359   DEBUG(id_, "<< Reset Failed Contact Counter");
360   DEBUG(id_, "   connection_handle=0x{:x}", connection_handle);
361 
362   ErrorCode status = link_layer_controller_.HasAclConnection(connection_handle)
363                          ? ErrorCode::SUCCESS
364                          : ErrorCode::UNKNOWN_CONNECTION;
365 
366   send_event_(bluetooth::hci::ResetFailedContactCounterCompleteBuilder::Create(
367       kNumCommandPackets, status, connection_handle));
368 }
369 
ReadRssi(CommandView command)370 void DualModeController::ReadRssi(CommandView command) {
371   auto command_view = bluetooth::hci::ReadRssiView::Create(command);
372   CHECK_PACKET_VIEW(command_view);
373 
374   uint16_t connection_handle = command_view.GetConnectionHandle();
375   int8_t rssi = 0;
376 
377   DEBUG(id_, "<< Read RSSI");
378   DEBUG(id_, "   connection_handle=0x{:x}", connection_handle);
379 
380   ErrorCode status = link_layer_controller_.ReadRssi(connection_handle, &rssi);
381   send_event_(bluetooth::hci::ReadRssiCompleteBuilder::Create(
382       kNumCommandPackets, status, connection_handle, rssi));
383 }
384 
ReadEncryptionKeySize(CommandView command)385 void DualModeController::ReadEncryptionKeySize(CommandView command) {
386   auto command_view =
387       bluetooth::hci::ReadEncryptionKeySizeView::Create(command);
388   CHECK_PACKET_VIEW(command_view);
389 
390   DEBUG(id_, "<< Read Encryption Key Size");
391   DEBUG(id_, "   connection_handle=0x{:x}", command_view.GetConnectionHandle());
392 
393   send_event_(bluetooth::hci::ReadEncryptionKeySizeCompleteBuilder::Create(
394       kNumCommandPackets, ErrorCode::SUCCESS,
395       command_view.GetConnectionHandle(),
396       link_layer_controller_.GetEncryptionKeySize()));
397 }
398 
HostBufferSize(CommandView command)399 void DualModeController::HostBufferSize(CommandView command) {
400   auto command_view = bluetooth::hci::HostBufferSizeView::Create(command);
401   CHECK_PACKET_VIEW(command_view);
402 
403   DEBUG(id_, "<< Host Buffer Size");
404 
405   send_event_(bluetooth::hci::HostBufferSizeCompleteBuilder::Create(
406       kNumCommandPackets, ErrorCode::SUCCESS));
407 }
408 
ReadLocalVersionInformation(CommandView command)409 void DualModeController::ReadLocalVersionInformation(CommandView command) {
410   auto command_view =
411       bluetooth::hci::ReadLocalVersionInformationView::Create(command);
412   CHECK_PACKET_VIEW(command_view);
413 
414   DEBUG(id_, "<< Read Local Version Information");
415 
416   bluetooth::hci::LocalVersionInformation local_version_information;
417   local_version_information.hci_version_ = properties_.hci_version;
418   local_version_information.lmp_version_ = properties_.lmp_version;
419   local_version_information.hci_revision_ = properties_.hci_subversion;
420   local_version_information.lmp_subversion_ = properties_.lmp_subversion;
421   local_version_information.manufacturer_name_ = properties_.company_identifier;
422 
423   send_event_(
424       bluetooth::hci::ReadLocalVersionInformationCompleteBuilder::Create(
425           kNumCommandPackets, ErrorCode::SUCCESS, local_version_information));
426 }
427 
ReadRemoteVersionInformation(CommandView command)428 void DualModeController::ReadRemoteVersionInformation(CommandView command) {
429   auto command_view =
430       bluetooth::hci::ReadRemoteVersionInformationView::Create(command);
431   CHECK_PACKET_VIEW(command_view);
432 
433   DEBUG(id_, "<< Read Remote Version Information");
434   DEBUG(id_, "   connection_handle=0x{:x}", command_view.GetConnectionHandle());
435 
436   auto status = link_layer_controller_.SendCommandToRemoteByHandle(
437       OpCode::READ_REMOTE_VERSION_INFORMATION, command.bytes(),
438       command_view.GetConnectionHandle());
439 
440   send_event_(bluetooth::hci::ReadRemoteVersionInformationStatusBuilder::Create(
441       status, kNumCommandPackets));
442 }
443 
ReadBdAddr(CommandView command)444 void DualModeController::ReadBdAddr(CommandView command) {
445   auto command_view = bluetooth::hci::ReadBdAddrView::Create(command);
446   CHECK_PACKET_VIEW(command_view);
447 
448   DEBUG(id_, "<< Read BD_ADDR");
449 
450   send_event_(bluetooth::hci::ReadBdAddrCompleteBuilder::Create(
451       kNumCommandPackets, ErrorCode::SUCCESS, GetAddress()));
452 }
453 
ReadLocalSupportedCommands(CommandView command)454 void DualModeController::ReadLocalSupportedCommands(CommandView command) {
455   auto command_view =
456       bluetooth::hci::ReadLocalSupportedCommandsView::Create(command);
457   CHECK_PACKET_VIEW(command_view);
458 
459   DEBUG(id_, "<< Read Local Supported Commands");
460 
461   send_event_(bluetooth::hci::ReadLocalSupportedCommandsCompleteBuilder::Create(
462       kNumCommandPackets, ErrorCode::SUCCESS, properties_.supported_commands));
463 }
464 
ReadLocalSupportedFeatures(CommandView command)465 void DualModeController::ReadLocalSupportedFeatures(CommandView command) {
466   auto command_view =
467       bluetooth::hci::ReadLocalSupportedFeaturesView::Create(command);
468   CHECK_PACKET_VIEW(command_view);
469 
470   DEBUG(id_, "<< Read Local Supported Features");
471 
472   send_event_(bluetooth::hci::ReadLocalSupportedFeaturesCompleteBuilder::Create(
473       kNumCommandPackets, ErrorCode::SUCCESS,
474       link_layer_controller_.GetLmpFeatures()));
475 }
476 
ReadLocalSupportedCodecsV1(CommandView command)477 void DualModeController::ReadLocalSupportedCodecsV1(CommandView command) {
478   auto command_view =
479       bluetooth::hci::ReadLocalSupportedCodecsV1View::Create(command);
480   CHECK_PACKET_VIEW(command_view);
481 
482   DEBUG(id_, "<< Read Local Supported Codecs V1");
483 
484   send_event_(bluetooth::hci::ReadLocalSupportedCodecsV1CompleteBuilder::Create(
485       kNumCommandPackets, ErrorCode::SUCCESS,
486       properties_.supported_standard_codecs,
487       properties_.supported_vendor_specific_codecs));
488 }
489 
ReadLocalExtendedFeatures(CommandView command)490 void DualModeController::ReadLocalExtendedFeatures(CommandView command) {
491   auto command_view =
492       bluetooth::hci::ReadLocalExtendedFeaturesView::Create(command);
493   CHECK_PACKET_VIEW(command_view);
494   uint8_t page_number = command_view.GetPageNumber();
495 
496   DEBUG(id_, "<< Read Local Extended Features");
497   DEBUG(id_, "   page_number={}", page_number);
498 
499   send_event_(bluetooth::hci::ReadLocalExtendedFeaturesCompleteBuilder::Create(
500       kNumCommandPackets, ErrorCode::SUCCESS, page_number,
501       link_layer_controller_.GetMaxLmpFeaturesPageNumber(),
502       link_layer_controller_.GetLmpFeatures(page_number)));
503 }
504 
ReadRemoteExtendedFeatures(CommandView command)505 void DualModeController::ReadRemoteExtendedFeatures(CommandView command) {
506   auto command_view =
507       bluetooth::hci::ReadRemoteExtendedFeaturesView::Create(command);
508   CHECK_PACKET_VIEW(command_view);
509 
510   DEBUG(id_, "<< Read Remote Extended Features");
511   DEBUG(id_, "   connection_handle=0x{:x}", command_view.GetConnectionHandle());
512   DEBUG(id_, "   page_number={}", command_view.GetPageNumber());
513 
514   auto status = link_layer_controller_.SendCommandToRemoteByHandle(
515       OpCode::READ_REMOTE_EXTENDED_FEATURES, command_view.bytes(),
516       command_view.GetConnectionHandle());
517 
518   send_event_(bluetooth::hci::ReadRemoteExtendedFeaturesStatusBuilder::Create(
519       status, kNumCommandPackets));
520 }
521 
SwitchRole(CommandView command)522 void DualModeController::SwitchRole(CommandView command) {
523   auto command_view = bluetooth::hci::SwitchRoleView::Create(command);
524   CHECK_PACKET_VIEW(command_view);
525 
526   DEBUG(id_, "<< Switch Role");
527   DEBUG(id_, "   bd_addr={}", command_view.GetBdAddr());
528   DEBUG(id_, "   role={}", bluetooth::hci::RoleText(command_view.GetRole()));
529 
530   auto status = link_layer_controller_.SwitchRole(command_view.GetBdAddr(),
531                                                   command_view.GetRole());
532 
533   send_event_(bluetooth::hci::SwitchRoleStatusBuilder::Create(
534       status, kNumCommandPackets));
535 }
536 
ReadRemoteSupportedFeatures(CommandView command)537 void DualModeController::ReadRemoteSupportedFeatures(CommandView command) {
538   auto command_view =
539       bluetooth::hci::ReadRemoteSupportedFeaturesView::Create(command);
540   CHECK_PACKET_VIEW(command_view);
541 
542   DEBUG(id_, "<< Read Remote Supported Features");
543   DEBUG(id_, "   connection_handle=0x{:x}", command_view.GetConnectionHandle());
544 
545   auto status = link_layer_controller_.SendCommandToRemoteByHandle(
546       OpCode::READ_REMOTE_SUPPORTED_FEATURES, command_view.bytes(),
547       command_view.GetConnectionHandle());
548 
549   send_event_(bluetooth::hci::ReadRemoteSupportedFeaturesStatusBuilder::Create(
550       status, kNumCommandPackets));
551 }
552 
ReadClockOffset(CommandView command)553 void DualModeController::ReadClockOffset(CommandView command) {
554   auto command_view = bluetooth::hci::ReadClockOffsetView::Create(command);
555   CHECK_PACKET_VIEW(command_view);
556 
557   DEBUG(id_, "<< Read Clock Offset");
558   DEBUG(id_, "   connection_handle=0x{:x}", command_view.GetConnectionHandle());
559 
560   uint16_t handle = command_view.GetConnectionHandle();
561 
562   auto status = link_layer_controller_.SendCommandToRemoteByHandle(
563       OpCode::READ_CLOCK_OFFSET, command_view.bytes(), handle);
564 
565   send_event_(bluetooth::hci::ReadClockOffsetStatusBuilder::Create(
566       status, kNumCommandPackets));
567 }
568 
569 // Deprecated command, removed in v4.2.
570 // Support is provided to satisfy PTS tester requirements.
AddScoConnection(CommandView command)571 void DualModeController::AddScoConnection(CommandView command) {
572   auto command_view = bluetooth::hci::AddScoConnectionView::Create(command);
573   CHECK_PACKET_VIEW(command_view);
574 
575   DEBUG(id_, "<< Add SCO Connection");
576   DEBUG(id_, "   connection_handle=0x{:x}", command_view.GetConnectionHandle());
577   DEBUG(id_, "   packet_type=0x{:x}", command_view.GetPacketType());
578 
579   auto status = link_layer_controller_.AddScoConnection(
580       command_view.GetConnectionHandle(), command_view.GetPacketType(),
581       ScoDatapath::NORMAL);
582 
583   send_event_(bluetooth::hci::AddScoConnectionStatusBuilder::Create(
584       status, kNumCommandPackets));
585 }
586 
SetupSynchronousConnection(CommandView command)587 void DualModeController::SetupSynchronousConnection(CommandView command) {
588   auto command_view =
589       bluetooth::hci::SetupSynchronousConnectionView::Create(command);
590   CHECK_PACKET_VIEW(command_view);
591 
592   DEBUG(id_, "<< Setup Synchronous Connection");
593   DEBUG(id_, "   connection_handle=0x{:x}", command_view.GetConnectionHandle());
594   DEBUG(id_, "   packet_type=0x{:x}", command_view.GetPacketType());
595 
596   auto status = link_layer_controller_.SetupSynchronousConnection(
597       command_view.GetConnectionHandle(), command_view.GetTransmitBandwidth(),
598       command_view.GetReceiveBandwidth(), command_view.GetMaxLatency(),
599       command_view.GetVoiceSetting(),
600       static_cast<uint8_t>(command_view.GetRetransmissionEffort()),
601       command_view.GetPacketType(), ScoDatapath::NORMAL);
602 
603   send_event_(bluetooth::hci::SetupSynchronousConnectionStatusBuilder::Create(
604       status, kNumCommandPackets));
605 }
606 
AcceptSynchronousConnection(CommandView command)607 void DualModeController::AcceptSynchronousConnection(CommandView command) {
608   auto command_view =
609       bluetooth::hci::AcceptSynchronousConnectionView::Create(command);
610   CHECK_PACKET_VIEW(command_view);
611 
612   DEBUG(id_, "<< Accept Synchronous Connection");
613   DEBUG(id_, "   bd_addr={}", command_view.GetBdAddr());
614   DEBUG(id_, "   packet_type=0x{:x}", command_view.GetPacketType());
615 
616   auto status = link_layer_controller_.AcceptSynchronousConnection(
617       command_view.GetBdAddr(), command_view.GetTransmitBandwidth(),
618       command_view.GetReceiveBandwidth(), command_view.GetMaxLatency(),
619       command_view.GetVoiceSetting(),
620       static_cast<uint8_t>(command_view.GetRetransmissionEffort()),
621       command_view.GetPacketType());
622 
623   send_event_(bluetooth::hci::AcceptSynchronousConnectionStatusBuilder::Create(
624       status, kNumCommandPackets));
625 }
626 
EnhancedSetupSynchronousConnection(CommandView command)627 void DualModeController::EnhancedSetupSynchronousConnection(
628     CommandView command) {
629   auto command_view =
630       bluetooth::hci::EnhancedSetupSynchronousConnectionView::Create(command);
631   auto status = ErrorCode::SUCCESS;
632   CHECK_PACKET_VIEW(command_view);
633 
634   DEBUG(id_, "<< Enhanced Setup Synchronous Connection");
635   DEBUG(id_, "   connection_handle=0x{:x}", command_view.GetConnectionHandle());
636   DEBUG(id_, "   packet_type=0x{:x}", command_view.GetPacketType());
637 
638   // The Host shall set the Transmit_Coding_Format and Receive_Coding_Formats
639   // to be equal.
640   auto transmit_coding_format = command_view.GetTransmitCodingFormat();
641   auto receive_coding_format = command_view.GetReceiveCodingFormat();
642   if (transmit_coding_format.coding_format_ !=
643           receive_coding_format.coding_format_ ||
644       transmit_coding_format.company_id_ != receive_coding_format.company_id_ ||
645       transmit_coding_format.vendor_specific_codec_id_ !=
646           receive_coding_format.vendor_specific_codec_id_) {
647     INFO(id_,
648          "EnhancedSetupSynchronousConnection: rejected Transmit_Coding_Format "
649          "({}) and Receive_Coding_Format ({}) as they are not equal",
650          transmit_coding_format.ToString(), receive_coding_format.ToString());
651     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
652   }
653 
654   // The Host shall either set the Input_Bandwidth and Output_Bandwidth
655   // to be equal, or shall set one of them to be zero and the other non-zero.
656   auto input_bandwidth = command_view.GetInputBandwidth();
657   auto output_bandwidth = command_view.GetOutputBandwidth();
658   if (input_bandwidth != output_bandwidth && input_bandwidth != 0 &&
659       output_bandwidth != 0) {
660     INFO(
661         id_,
662         "EnhancedSetupSynchronousConnection: rejected Input_Bandwidth ({})"
663         " and Output_Bandwidth ({}) as they are not equal and different from 0",
664         input_bandwidth, output_bandwidth);
665     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
666   }
667 
668   // The Host shall set the Input_Coding_Format and Output_Coding_Format
669   // to be equal.
670   auto input_coding_format = command_view.GetInputCodingFormat();
671   auto output_coding_format = command_view.GetOutputCodingFormat();
672   if (input_coding_format.coding_format_ !=
673           output_coding_format.coding_format_ ||
674       input_coding_format.company_id_ != output_coding_format.company_id_ ||
675       input_coding_format.vendor_specific_codec_id_ !=
676           output_coding_format.vendor_specific_codec_id_) {
677     INFO(id_,
678          "EnhancedSetupSynchronousConnection: rejected Input_Coding_Format ({})"
679          " and Output_Coding_Format ({}) as they are not equal",
680          input_coding_format.ToString(), output_coding_format.ToString());
681     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
682   }
683 
684   // Root-Canal does not implement audio data transport paths other than the
685   // default HCI transport - other transports will receive spoofed data
686   ScoDatapath datapath = ScoDatapath::NORMAL;
687   if (command_view.GetInputDataPath() != bluetooth::hci::ScoDataPath::HCI ||
688       command_view.GetOutputDataPath() != bluetooth::hci::ScoDataPath::HCI) {
689     WARNING(id_,
690             "EnhancedSetupSynchronousConnection: Input_Data_Path ({})"
691             " and/or Output_Data_Path ({}) are not over HCI, so data will be "
692             "spoofed",
693             static_cast<unsigned>(command_view.GetInputDataPath()),
694             static_cast<unsigned>(command_view.GetOutputDataPath()));
695     datapath = ScoDatapath::SPOOFED;
696   }
697 
698   // Either both the Transmit_Coding_Format and Input_Coding_Format shall be
699   // “transparent” or neither shall be. If both are “transparent”, the
700   // Transmit_Bandwidth and the Input_Bandwidth shall be the same and the
701   // Controller shall not modify the data sent to the remote device.
702   auto transmit_bandwidth = command_view.GetTransmitBandwidth();
703   auto receive_bandwidth = command_view.GetReceiveBandwidth();
704   if (transmit_coding_format.coding_format_ ==
705           bluetooth::hci::ScoCodingFormatValues::TRANSPARENT &&
706       input_coding_format.coding_format_ ==
707           bluetooth::hci::ScoCodingFormatValues::TRANSPARENT &&
708       transmit_bandwidth != input_bandwidth) {
709     INFO(id_,
710          "EnhancedSetupSynchronousConnection: rejected Transmit_Bandwidth ({})"
711          " and Input_Bandwidth ({}) as they are not equal",
712          transmit_bandwidth, input_bandwidth);
713     INFO(id_,
714          "EnhancedSetupSynchronousConnection: the Transmit_Bandwidth and "
715          "Input_Bandwidth shall be equal when both Transmit_Coding_Format "
716          "and Input_Coding_Format are 'transparent'");
717     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
718   }
719   if ((transmit_coding_format.coding_format_ ==
720        bluetooth::hci::ScoCodingFormatValues::TRANSPARENT) !=
721       (input_coding_format.coding_format_ ==
722        bluetooth::hci::ScoCodingFormatValues::TRANSPARENT)) {
723     INFO(id_,
724          "EnhancedSetupSynchronousConnection: rejected Transmit_Coding_Format "
725          "({}) and Input_Coding_Format ({}) as they are incompatible",
726          transmit_coding_format.ToString(), input_coding_format.ToString());
727     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
728   }
729 
730   // Either both the Receive_Coding_Format and Output_Coding_Format shall
731   // be “transparent” or neither shall be. If both are “transparent”, the
732   // Receive_Bandwidth and the Output_Bandwidth shall be the same and the
733   // Controller shall not modify the data sent to the Host.
734   if (receive_coding_format.coding_format_ ==
735           bluetooth::hci::ScoCodingFormatValues::TRANSPARENT &&
736       output_coding_format.coding_format_ ==
737           bluetooth::hci::ScoCodingFormatValues::TRANSPARENT &&
738       receive_bandwidth != output_bandwidth) {
739     INFO(id_,
740          "EnhancedSetupSynchronousConnection: rejected Receive_Bandwidth ({})"
741          " and Output_Bandwidth ({}) as they are not equal",
742          receive_bandwidth, output_bandwidth);
743     INFO(id_,
744          "EnhancedSetupSynchronousConnection: the Receive_Bandwidth and "
745          "Output_Bandwidth shall be equal when both Receive_Coding_Format "
746          "and Output_Coding_Format are 'transparent'");
747     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
748   }
749   if ((receive_coding_format.coding_format_ ==
750        bluetooth::hci::ScoCodingFormatValues::TRANSPARENT) !=
751       (output_coding_format.coding_format_ ==
752        bluetooth::hci::ScoCodingFormatValues::TRANSPARENT)) {
753     INFO(id_,
754          "EnhancedSetupSynchronousConnection: rejected Receive_Coding_Format "
755          "({}) and Output_Coding_Format ({}) as they are incompatible",
756          receive_coding_format.ToString(), output_coding_format.ToString());
757     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
758   }
759 
760   if (status == ErrorCode::SUCCESS) {
761     status = link_layer_controller_.SetupSynchronousConnection(
762         command_view.GetConnectionHandle(), transmit_bandwidth,
763         receive_bandwidth, command_view.GetMaxLatency(),
764         link_layer_controller_.GetVoiceSetting(),
765         static_cast<uint8_t>(command_view.GetRetransmissionEffort()),
766         command_view.GetPacketType(), datapath);
767   }
768 
769   send_event_(
770       bluetooth::hci::EnhancedSetupSynchronousConnectionStatusBuilder::Create(
771           status, kNumCommandPackets));
772 }
773 
EnhancedAcceptSynchronousConnection(CommandView command)774 void DualModeController::EnhancedAcceptSynchronousConnection(
775     CommandView command) {
776   auto command_view =
777       bluetooth::hci::EnhancedAcceptSynchronousConnectionView::Create(command);
778   auto status = ErrorCode::SUCCESS;
779   CHECK_PACKET_VIEW(command_view);
780 
781   DEBUG(id_, "<< Enhanced Accept Synchronous Connection");
782   DEBUG(id_, "   bd_addr={}", command_view.GetBdAddr());
783   DEBUG(id_, "   packet_type=0x{:x}", command_view.GetPacketType());
784 
785   // The Host shall set the Transmit_Coding_Format and Receive_Coding_Formats
786   // to be equal.
787   auto transmit_coding_format = command_view.GetTransmitCodingFormat();
788   auto receive_coding_format = command_view.GetReceiveCodingFormat();
789   if (transmit_coding_format.coding_format_ !=
790           receive_coding_format.coding_format_ ||
791       transmit_coding_format.company_id_ != receive_coding_format.company_id_ ||
792       transmit_coding_format.vendor_specific_codec_id_ !=
793           receive_coding_format.vendor_specific_codec_id_) {
794     INFO(id_,
795          "EnhancedAcceptSynchronousConnection: rejected Transmit_Coding_Format "
796          "({})"
797          " and Receive_Coding_Format ({}) as they are not equal",
798          transmit_coding_format.ToString(), receive_coding_format.ToString());
799     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
800   }
801 
802   // The Host shall either set the Input_Bandwidth and Output_Bandwidth
803   // to be equal, or shall set one of them to be zero and the other non-zero.
804   auto input_bandwidth = command_view.GetInputBandwidth();
805   auto output_bandwidth = command_view.GetOutputBandwidth();
806   if (input_bandwidth != output_bandwidth && input_bandwidth != 0 &&
807       output_bandwidth != 0) {
808     INFO(
809         id_,
810         "EnhancedAcceptSynchronousConnection: rejected Input_Bandwidth ({})"
811         " and Output_Bandwidth ({}) as they are not equal and different from 0",
812         input_bandwidth, output_bandwidth);
813     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
814   }
815 
816   // The Host shall set the Input_Coding_Format and Output_Coding_Format
817   // to be equal.
818   auto input_coding_format = command_view.GetInputCodingFormat();
819   auto output_coding_format = command_view.GetOutputCodingFormat();
820   if (input_coding_format.coding_format_ !=
821           output_coding_format.coding_format_ ||
822       input_coding_format.company_id_ != output_coding_format.company_id_ ||
823       input_coding_format.vendor_specific_codec_id_ !=
824           output_coding_format.vendor_specific_codec_id_) {
825     INFO(
826         id_,
827         "EnhancedAcceptSynchronousConnection: rejected Input_Coding_Format ({})"
828         " and Output_Coding_Format ({}) as they are not equal",
829         input_coding_format.ToString(), output_coding_format.ToString());
830     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
831   }
832 
833   // Root-Canal does not implement audio data transport paths other than the
834   // default HCI transport.
835   if (command_view.GetInputDataPath() != bluetooth::hci::ScoDataPath::HCI ||
836       command_view.GetOutputDataPath() != bluetooth::hci::ScoDataPath::HCI) {
837     INFO(id_,
838          "EnhancedSetupSynchronousConnection: Input_Data_Path ({})"
839          " and/or Output_Data_Path ({}) are not over HCI, so data will be "
840          "spoofed",
841          static_cast<unsigned>(command_view.GetInputDataPath()),
842          static_cast<unsigned>(command_view.GetOutputDataPath()));
843   }
844 
845   // Either both the Transmit_Coding_Format and Input_Coding_Format shall be
846   // “transparent” or neither shall be. If both are “transparent”, the
847   // Transmit_Bandwidth and the Input_Bandwidth shall be the same and the
848   // Controller shall not modify the data sent to the remote device.
849   auto transmit_bandwidth = command_view.GetTransmitBandwidth();
850   auto receive_bandwidth = command_view.GetReceiveBandwidth();
851   if (transmit_coding_format.coding_format_ ==
852           bluetooth::hci::ScoCodingFormatValues::TRANSPARENT &&
853       input_coding_format.coding_format_ ==
854           bluetooth::hci::ScoCodingFormatValues::TRANSPARENT &&
855       transmit_bandwidth != input_bandwidth) {
856     INFO(id_,
857          "EnhancedSetupSynchronousConnection: rejected Transmit_Bandwidth ({})"
858          " and Input_Bandwidth ({}) as they are not equal",
859          transmit_bandwidth, input_bandwidth);
860     INFO(id_,
861          "EnhancedSetupSynchronousConnection: the Transmit_Bandwidth and "
862          "Input_Bandwidth shall be equal when both Transmit_Coding_Format "
863          "and Input_Coding_Format are 'transparent'");
864     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
865   }
866   if ((transmit_coding_format.coding_format_ ==
867        bluetooth::hci::ScoCodingFormatValues::TRANSPARENT) !=
868       (input_coding_format.coding_format_ ==
869        bluetooth::hci::ScoCodingFormatValues::TRANSPARENT)) {
870     INFO(id_,
871          "EnhancedSetupSynchronousConnection: rejected Transmit_Coding_Format "
872          "({}) and Input_Coding_Format ({}) as they are incompatible",
873          transmit_coding_format.ToString(), input_coding_format.ToString());
874     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
875   }
876 
877   // Either both the Receive_Coding_Format and Output_Coding_Format shall
878   // be “transparent” or neither shall be. If both are “transparent”, the
879   // Receive_Bandwidth and the Output_Bandwidth shall be the same and the
880   // Controller shall not modify the data sent to the Host.
881   if (receive_coding_format.coding_format_ ==
882           bluetooth::hci::ScoCodingFormatValues::TRANSPARENT &&
883       output_coding_format.coding_format_ ==
884           bluetooth::hci::ScoCodingFormatValues::TRANSPARENT &&
885       receive_bandwidth != output_bandwidth) {
886     INFO(id_,
887          "EnhancedSetupSynchronousConnection: rejected Receive_Bandwidth ({})"
888          " and Output_Bandwidth ({}) as they are not equal",
889          receive_bandwidth, output_bandwidth);
890     INFO(id_,
891          "EnhancedSetupSynchronousConnection: the Receive_Bandwidth and "
892          "Output_Bandwidth shall be equal when both Receive_Coding_Format "
893          "and Output_Coding_Format are 'transparent'");
894     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
895   }
896   if ((receive_coding_format.coding_format_ ==
897        bluetooth::hci::ScoCodingFormatValues::TRANSPARENT) !=
898       (output_coding_format.coding_format_ ==
899        bluetooth::hci::ScoCodingFormatValues::TRANSPARENT)) {
900     INFO(id_,
901          "EnhancedSetupSynchronousConnection: rejected Receive_Coding_Format "
902          "({}) and Output_Coding_Format ({}) as they are incompatible",
903          receive_coding_format.ToString(), output_coding_format.ToString());
904     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
905   }
906 
907   if (status == ErrorCode::SUCCESS) {
908     status = link_layer_controller_.AcceptSynchronousConnection(
909         command_view.GetBdAddr(), transmit_bandwidth, receive_bandwidth,
910         command_view.GetMaxLatency(), link_layer_controller_.GetVoiceSetting(),
911         static_cast<uint8_t>(command_view.GetRetransmissionEffort()),
912         command_view.GetPacketType());
913   }
914 
915   send_event_(
916       bluetooth::hci::EnhancedAcceptSynchronousConnectionStatusBuilder::Create(
917           status, kNumCommandPackets));
918 }
919 
RejectSynchronousConnection(CommandView command)920 void DualModeController::RejectSynchronousConnection(CommandView command) {
921   auto command_view =
922       bluetooth::hci::RejectSynchronousConnectionView::Create(command);
923   CHECK_PACKET_VIEW(command_view);
924 
925   DEBUG(id_, "<< Reject Synchronous Connection");
926   DEBUG(id_, "   bd_addr={}", command_view.GetBdAddr());
927   DEBUG(id_, "   reason={}",
928         bluetooth::hci::RejectConnectionReasonText(command_view.GetReason()));
929 
930   auto status = link_layer_controller_.RejectSynchronousConnection(
931       command_view.GetBdAddr(), (uint16_t)command_view.GetReason());
932 
933   send_event_(bluetooth::hci::RejectSynchronousConnectionStatusBuilder::Create(
934       status, kNumCommandPackets));
935 }
936 
ReadInquiryResponseTransmitPowerLevel(CommandView command)937 void DualModeController::ReadInquiryResponseTransmitPowerLevel(
938     CommandView command) {
939   auto command_view =
940       bluetooth::hci::ReadInquiryResponseTransmitPowerLevelView::Create(
941           command);
942   CHECK_PACKET_VIEW(command_view);
943 
944   DEBUG(id_, "<< Read Inquiry Response Transmit Power Level");
945 
946   uint8_t tx_power = 20;  // maximum
947   send_event_(
948       bluetooth::hci::ReadInquiryResponseTransmitPowerLevelCompleteBuilder::
949           Create(kNumCommandPackets, ErrorCode::SUCCESS, tx_power));
950 }
951 
EnhancedFlush(CommandView command)952 void DualModeController::EnhancedFlush(CommandView command) {
953   auto command_view = bluetooth::hci::EnhancedFlushView::Create(command);
954   CHECK_PACKET_VIEW(command_view);
955 
956   DEBUG(id_, "<< Enhanced Flush");
957   DEBUG(id_, "   connection_handle=0x{:x}", command_view.GetConnectionHandle());
958 
959   auto handle = command_view.GetConnectionHandle();
960   send_event_(bluetooth::hci::EnhancedFlushStatusBuilder::Create(
961       ErrorCode::SUCCESS, kNumCommandPackets));
962 
963   // TODO: When adding a queue of ACL packets.
964   // Send the Enhanced Flush Complete event after discarding
965   // all L2CAP packets identified by the Packet Type.
966   if (link_layer_controller_.IsEventUnmasked(
967           bluetooth::hci::EventCode::ENHANCED_FLUSH_COMPLETE)) {
968     send_event_(bluetooth::hci::EnhancedFlushCompleteBuilder::Create(handle));
969   }
970 }
971 
SetEventMaskPage2(CommandView command)972 void DualModeController::SetEventMaskPage2(CommandView command) {
973   auto command_view = bluetooth::hci::SetEventMaskPage2View::Create(command);
974   CHECK_PACKET_VIEW(command_view);
975 
976   DEBUG(id_, "<< Set Event Mask Page 2");
977   DEBUG(id_, "   event_mask_page_2=0x{:x}", command_view.GetEventMaskPage2());
978 
979   link_layer_controller_.SetEventMaskPage2(command_view.GetEventMaskPage2());
980   send_event_(bluetooth::hci::SetEventMaskPage2CompleteBuilder::Create(
981       kNumCommandPackets, ErrorCode::SUCCESS));
982 }
983 
ReadLocalOobData(CommandView command)984 void DualModeController::ReadLocalOobData(CommandView command) {
985   auto command_view = bluetooth::hci::ReadLocalOobDataView::Create(command);
986 
987   DEBUG(id_, "<< Read Local Oob Data");
988 
989   link_layer_controller_.ReadLocalOobData();
990 }
991 
ReadLocalOobExtendedData(CommandView command)992 void DualModeController::ReadLocalOobExtendedData(CommandView command) {
993   auto command_view =
994       bluetooth::hci::ReadLocalOobExtendedDataView::Create(command);
995 
996   DEBUG(id_, "<< Read Local Oob Extended Data");
997 
998   link_layer_controller_.ReadLocalOobExtendedData();
999 }
1000 
WriteSimplePairingMode(CommandView command)1001 void DualModeController::WriteSimplePairingMode(CommandView command) {
1002   auto command_view =
1003       bluetooth::hci::WriteSimplePairingModeView::Create(command);
1004   CHECK_PACKET_VIEW(command_view);
1005 
1006   DEBUG(id_, "<< Write Simple Pairing Mode");
1007   DEBUG(id_, "   simple_pairing_mode={}",
1008         command_view.GetSimplePairingMode() == bluetooth::hci::Enable::ENABLED);
1009 
1010   auto enabled =
1011       command_view.GetSimplePairingMode() == bluetooth::hci::Enable::ENABLED;
1012   link_layer_controller_.SetSecureSimplePairingSupport(enabled);
1013   send_event_(bluetooth::hci::WriteSimplePairingModeCompleteBuilder::Create(
1014       kNumCommandPackets, ErrorCode::SUCCESS));
1015 }
1016 
ChangeConnectionPacketType(CommandView command)1017 void DualModeController::ChangeConnectionPacketType(CommandView command) {
1018   auto command_view =
1019       bluetooth::hci::ChangeConnectionPacketTypeView::Create(command);
1020   CHECK_PACKET_VIEW(command_view);
1021 
1022   DEBUG(id_, "<< Change Connection Packet Type");
1023   DEBUG(id_, "   connection_handle=0x{:x}", command_view.GetConnectionHandle());
1024   DEBUG(id_, "   packet_type=0x{:x}", command_view.GetPacketType());
1025 
1026   uint16_t handle = command_view.GetConnectionHandle();
1027   uint16_t packet_type = static_cast<uint16_t>(command_view.GetPacketType());
1028 
1029   auto status =
1030       link_layer_controller_.ChangeConnectionPacketType(handle, packet_type);
1031   send_event_(bluetooth::hci::ChangeConnectionPacketTypeStatusBuilder::Create(
1032       status, kNumCommandPackets));
1033 }
1034 
WriteLeHostSupport(CommandView command)1035 void DualModeController::WriteLeHostSupport(CommandView command) {
1036   auto command_view = bluetooth::hci::WriteLeHostSupportView::Create(command);
1037   CHECK_PACKET_VIEW(command_view);
1038 
1039   DEBUG(id_, "<< Write LE Host Support");
1040   DEBUG(id_, "   le_supported_host={}",
1041         command_view.GetLeSupportedHost() == bluetooth::hci::Enable::ENABLED);
1042 
1043   auto le_support =
1044       command_view.GetLeSupportedHost() == bluetooth::hci::Enable::ENABLED;
1045   link_layer_controller_.SetLeHostSupport(le_support);
1046   send_event_(bluetooth::hci::WriteLeHostSupportCompleteBuilder::Create(
1047       kNumCommandPackets, ErrorCode::SUCCESS));
1048 }
1049 
WriteSecureConnectionsHostSupport(CommandView command)1050 void DualModeController::WriteSecureConnectionsHostSupport(
1051     CommandView command) {
1052   auto command_view =
1053       bluetooth::hci::WriteSecureConnectionsHostSupportView::Create(command);
1054   CHECK_PACKET_VIEW(command_view);
1055 
1056   DEBUG(id_, "<< Write Secure Connections Host Support");
1057   DEBUG(id_, "   secure_connections_host_support={}",
1058         command_view.GetSecureConnectionsHostSupport() ==
1059             bluetooth::hci::Enable::ENABLED);
1060 
1061   link_layer_controller_.SetSecureConnectionsSupport(
1062       command_view.GetSecureConnectionsHostSupport() ==
1063       bluetooth::hci::Enable::ENABLED);
1064   send_event_(
1065       bluetooth::hci::WriteSecureConnectionsHostSupportCompleteBuilder::Create(
1066           kNumCommandPackets, ErrorCode::SUCCESS));
1067 }
1068 
SetEventMask(CommandView command)1069 void DualModeController::SetEventMask(CommandView command) {
1070   auto command_view = bluetooth::hci::SetEventMaskView::Create(command);
1071   CHECK_PACKET_VIEW(command_view);
1072 
1073   DEBUG(id_, "<< Set Event Mask");
1074   DEBUG(id_, "   event_mask=0x{:x}", command_view.GetEventMask());
1075 
1076   link_layer_controller_.SetEventMask(command_view.GetEventMask());
1077   send_event_(bluetooth::hci::SetEventMaskCompleteBuilder::Create(
1078       kNumCommandPackets, ErrorCode::SUCCESS));
1079 }
1080 
ReadInquiryMode(CommandView command)1081 void DualModeController::ReadInquiryMode(CommandView command) {
1082   auto command_view = bluetooth::hci::ReadInquiryModeView::Create(command);
1083   CHECK_PACKET_VIEW(command_view);
1084 
1085   DEBUG(id_, "<< Read Inquiry Mode");
1086 
1087   bluetooth::hci::InquiryMode inquiry_mode =
1088       bluetooth::hci::InquiryMode::STANDARD;
1089   send_event_(bluetooth::hci::ReadInquiryModeCompleteBuilder::Create(
1090       kNumCommandPackets, ErrorCode::SUCCESS, inquiry_mode));
1091 }
1092 
WriteInquiryMode(CommandView command)1093 void DualModeController::WriteInquiryMode(CommandView command) {
1094   auto command_view = bluetooth::hci::WriteInquiryModeView::Create(command);
1095   CHECK_PACKET_VIEW(command_view);
1096 
1097   DEBUG(id_, "<< Write Inquiry Mode");
1098   DEBUG(id_, "   inquiry_mode={}",
1099         bluetooth::hci::InquiryModeText(command_view.GetInquiryMode()));
1100 
1101   link_layer_controller_.SetInquiryMode(
1102       static_cast<uint8_t>(command_view.GetInquiryMode()));
1103   send_event_(bluetooth::hci::WriteInquiryModeCompleteBuilder::Create(
1104       kNumCommandPackets, ErrorCode::SUCCESS));
1105 }
1106 
ReadPageScanType(CommandView command)1107 void DualModeController::ReadPageScanType(CommandView command) {
1108   auto command_view = bluetooth::hci::ReadPageScanTypeView::Create(command);
1109   CHECK_PACKET_VIEW(command_view);
1110 
1111   DEBUG(id_, "<< Read Page Scan Type");
1112 
1113   bluetooth::hci::PageScanType page_scan_type =
1114       bluetooth::hci::PageScanType::STANDARD;
1115   send_event_(bluetooth::hci::ReadPageScanTypeCompleteBuilder::Create(
1116       kNumCommandPackets, ErrorCode::SUCCESS, page_scan_type));
1117 }
1118 
WritePageScanType(CommandView command)1119 void DualModeController::WritePageScanType(CommandView command) {
1120   auto command_view = bluetooth::hci::WritePageScanTypeView::Create(command);
1121   CHECK_PACKET_VIEW(command_view);
1122 
1123   DEBUG(id_, "<< Write Page Scan Type");
1124   DEBUG(id_, "   page_scan_type={}",
1125         bluetooth::hci::PageScanTypeText(command_view.GetPageScanType()));
1126 
1127   send_event_(bluetooth::hci::WritePageScanTypeCompleteBuilder::Create(
1128       kNumCommandPackets, ErrorCode::SUCCESS));
1129 }
1130 
ReadInquiryScanType(CommandView command)1131 void DualModeController::ReadInquiryScanType(CommandView command) {
1132   auto command_view = bluetooth::hci::ReadInquiryScanTypeView::Create(command);
1133   CHECK_PACKET_VIEW(command_view);
1134 
1135   DEBUG(id_, "<< Read Inquiry Scan Type");
1136 
1137   bluetooth::hci::InquiryScanType inquiry_scan_type =
1138       bluetooth::hci::InquiryScanType::STANDARD;
1139   send_event_(bluetooth::hci::ReadInquiryScanTypeCompleteBuilder::Create(
1140       kNumCommandPackets, ErrorCode::SUCCESS, inquiry_scan_type));
1141 }
1142 
WriteInquiryScanType(CommandView command)1143 void DualModeController::WriteInquiryScanType(CommandView command) {
1144   auto command_view = bluetooth::hci::WriteInquiryScanTypeView::Create(command);
1145   CHECK_PACKET_VIEW(command_view);
1146 
1147   DEBUG(id_, "<< Write Inquiry Scan Type");
1148   DEBUG(id_, "   inquiry_scan_type={}",
1149         bluetooth::hci::InquiryScanTypeText(command_view.GetInquiryScanType()));
1150 
1151   send_event_(bluetooth::hci::WriteInquiryScanTypeCompleteBuilder::Create(
1152       kNumCommandPackets, ErrorCode::SUCCESS));
1153 }
1154 
ChangeConnectionLinkKey(CommandView command)1155 void DualModeController::ChangeConnectionLinkKey(CommandView command) {
1156   auto command_view =
1157       bluetooth::hci::ChangeConnectionLinkKeyView::Create(command);
1158   CHECK_PACKET_VIEW(command_view);
1159 
1160   DEBUG(id_, "<< Change Connection Link Key");
1161   DEBUG(id_, "   connection_handle=0x{:x}", command_view.GetConnectionHandle());
1162 
1163   uint16_t handle = command_view.GetConnectionHandle();
1164   auto status = link_layer_controller_.ChangeConnectionLinkKey(handle);
1165 
1166   send_event_(bluetooth::hci::ChangeConnectionLinkKeyStatusBuilder::Create(
1167       status, kNumCommandPackets));
1168 }
1169 
CentralLinkKey(CommandView command)1170 void DualModeController::CentralLinkKey(CommandView command) {
1171   auto command_view = bluetooth::hci::CentralLinkKeyView::Create(command);
1172   CHECK_PACKET_VIEW(command_view);
1173 
1174   DEBUG(id_, "<< Central Link Key");
1175   DEBUG(id_, "   key_flag={}",
1176         bluetooth::hci::KeyFlagText(command_view.GetKeyFlag()));
1177 
1178   uint8_t key_flag = static_cast<uint8_t>(command_view.GetKeyFlag());
1179   auto status = link_layer_controller_.CentralLinkKey(key_flag);
1180 
1181   send_event_(bluetooth::hci::CentralLinkKeyStatusBuilder::Create(
1182       status, kNumCommandPackets));
1183 }
1184 
WriteAuthenticationEnable(CommandView command)1185 void DualModeController::WriteAuthenticationEnable(CommandView command) {
1186   auto command_view =
1187       bluetooth::hci::WriteAuthenticationEnableView::Create(command);
1188   CHECK_PACKET_VIEW(command_view);
1189 
1190   DEBUG(id_, "<< Write Authentication Enable");
1191   DEBUG(id_, "   authentication_enable={}",
1192         bluetooth::hci::AuthenticationEnableText(
1193             command_view.GetAuthenticationEnable()));
1194 
1195   link_layer_controller_.SetAuthenticationEnable(
1196       command_view.GetAuthenticationEnable());
1197   send_event_(bluetooth::hci::WriteAuthenticationEnableCompleteBuilder::Create(
1198       kNumCommandPackets, ErrorCode::SUCCESS));
1199 }
1200 
ReadAuthenticationEnable(CommandView command)1201 void DualModeController::ReadAuthenticationEnable(CommandView command) {
1202   auto command_view =
1203       bluetooth::hci::ReadAuthenticationEnableView::Create(command);
1204   CHECK_PACKET_VIEW(command_view);
1205 
1206   DEBUG(id_, "<< Read Authentication Enable");
1207 
1208   send_event_(bluetooth::hci::ReadAuthenticationEnableCompleteBuilder::Create(
1209       kNumCommandPackets, ErrorCode::SUCCESS,
1210       static_cast<bluetooth::hci::AuthenticationEnable>(
1211           link_layer_controller_.GetAuthenticationEnable())));
1212 }
1213 
ReadClassOfDevice(CommandView command)1214 void DualModeController::ReadClassOfDevice(CommandView command) {
1215   auto command_view = bluetooth::hci::ReadClassOfDeviceView::Create(command);
1216   CHECK_PACKET_VIEW(command_view);
1217 
1218   DEBUG(id_, "<< Read Class of Device");
1219 
1220   send_event_(bluetooth::hci::ReadClassOfDeviceCompleteBuilder::Create(
1221       kNumCommandPackets, ErrorCode::SUCCESS,
1222       link_layer_controller_.GetClassOfDevice()));
1223 }
1224 
WriteClassOfDevice(CommandView command)1225 void DualModeController::WriteClassOfDevice(CommandView command) {
1226   auto command_view = bluetooth::hci::WriteClassOfDeviceView::Create(command);
1227   CHECK_PACKET_VIEW(command_view);
1228 
1229   DEBUG(id_, "<< Write Class of Device");
1230   DEBUG(id_, "   class_of_device=0x{:x}", command_view.GetClassOfDevice());
1231 
1232   link_layer_controller_.SetClassOfDevice(command_view.GetClassOfDevice());
1233   send_event_(bluetooth::hci::WriteClassOfDeviceCompleteBuilder::Create(
1234       kNumCommandPackets, ErrorCode::SUCCESS));
1235 }
1236 
ReadPageTimeout(CommandView command)1237 void DualModeController::ReadPageTimeout(CommandView command) {
1238   auto command_view = bluetooth::hci::ReadPageTimeoutView::Create(command);
1239   CHECK_PACKET_VIEW(command_view);
1240 
1241   DEBUG(id_, "<< Read Page Timeout");
1242 
1243   uint16_t page_timeout = link_layer_controller_.GetPageTimeout();
1244   send_event_(bluetooth::hci::ReadPageTimeoutCompleteBuilder::Create(
1245       kNumCommandPackets, ErrorCode::SUCCESS, page_timeout));
1246 }
1247 
WritePageTimeout(CommandView command)1248 void DualModeController::WritePageTimeout(CommandView command) {
1249   auto command_view = bluetooth::hci::WritePageTimeoutView::Create(command);
1250   CHECK_PACKET_VIEW(command_view);
1251 
1252   DEBUG(id_, "<< Write Page Timeout");
1253   DEBUG(id_, "   page_timeout={}", command_view.GetPageTimeout());
1254 
1255   link_layer_controller_.SetPageTimeout(command_view.GetPageTimeout());
1256   send_event_(bluetooth::hci::WritePageTimeoutCompleteBuilder::Create(
1257       kNumCommandPackets, ErrorCode::SUCCESS));
1258 }
1259 
HoldMode(CommandView command)1260 void DualModeController::HoldMode(CommandView command) {
1261   auto command_view = bluetooth::hci::HoldModeView::Create(command);
1262   CHECK_PACKET_VIEW(command_view);
1263   uint16_t handle = command_view.GetConnectionHandle();
1264   uint16_t hold_mode_max_interval = command_view.GetHoldModeMaxInterval();
1265   uint16_t hold_mode_min_interval = command_view.GetHoldModeMinInterval();
1266 
1267   DEBUG(id_, "<< Hold Mode");
1268   DEBUG(id_, "   connection_handle=0x{:x}", command_view.GetConnectionHandle());
1269 
1270   auto status = link_layer_controller_.HoldMode(handle, hold_mode_max_interval,
1271                                                 hold_mode_min_interval);
1272 
1273   send_event_(bluetooth::hci::HoldModeStatusBuilder::Create(
1274       status, kNumCommandPackets));
1275 }
1276 
SniffMode(CommandView command)1277 void DualModeController::SniffMode(CommandView command) {
1278   auto command_view = bluetooth::hci::SniffModeView::Create(command);
1279   CHECK_PACKET_VIEW(command_view);
1280   uint16_t handle = command_view.GetConnectionHandle();
1281   uint16_t sniff_max_interval = command_view.GetSniffMaxInterval();
1282   uint16_t sniff_min_interval = command_view.GetSniffMinInterval();
1283   uint16_t sniff_attempt = command_view.GetSniffAttempt();
1284   uint16_t sniff_timeout = command_view.GetSniffTimeout();
1285 
1286   DEBUG(id_, "<< Sniff Mode");
1287   DEBUG(id_, "   connection_handle=0x{:x}", command_view.GetConnectionHandle());
1288 
1289   auto status = link_layer_controller_.SniffMode(handle, sniff_max_interval,
1290                                                  sniff_min_interval,
1291                                                  sniff_attempt, sniff_timeout);
1292 
1293   send_event_(bluetooth::hci::SniffModeStatusBuilder::Create(
1294       status, kNumCommandPackets));
1295 }
1296 
ExitSniffMode(CommandView command)1297 void DualModeController::ExitSniffMode(CommandView command) {
1298   auto command_view = bluetooth::hci::ExitSniffModeView::Create(command);
1299   CHECK_PACKET_VIEW(command_view);
1300 
1301   DEBUG(id_, "<< Exit Sniff Mode");
1302   DEBUG(id_, "   connection_handle=0x{:x}", command_view.GetConnectionHandle());
1303 
1304   auto status =
1305       link_layer_controller_.ExitSniffMode(command_view.GetConnectionHandle());
1306 
1307   send_event_(bluetooth::hci::ExitSniffModeStatusBuilder::Create(
1308       status, kNumCommandPackets));
1309 }
1310 
QosSetup(CommandView command)1311 void DualModeController::QosSetup(CommandView command) {
1312   auto command_view = bluetooth::hci::QosSetupView::Create(command);
1313   CHECK_PACKET_VIEW(command_view);
1314   uint16_t handle = command_view.GetConnectionHandle();
1315   uint8_t service_type = static_cast<uint8_t>(command_view.GetServiceType());
1316   uint32_t token_rate = command_view.GetTokenRate();
1317   uint32_t peak_bandwidth = command_view.GetPeakBandwidth();
1318   uint32_t latency = command_view.GetLatency();
1319   uint32_t delay_variation = command_view.GetDelayVariation();
1320 
1321   DEBUG(id_, "<< Qos Setup");
1322   DEBUG(id_, "   connection_handle=0x{:x}", command_view.GetConnectionHandle());
1323 
1324   auto status =
1325       link_layer_controller_.QosSetup(handle, service_type, token_rate,
1326                                       peak_bandwidth, latency, delay_variation);
1327 
1328   send_event_(bluetooth::hci::QosSetupStatusBuilder::Create(
1329       status, kNumCommandPackets));
1330 }
1331 
RoleDiscovery(CommandView command)1332 void DualModeController::RoleDiscovery(CommandView command) {
1333   auto command_view = bluetooth::hci::RoleDiscoveryView::Create(command);
1334   CHECK_PACKET_VIEW(command_view);
1335   uint16_t handle = command_view.GetConnectionHandle();
1336 
1337   DEBUG(id_, "<< Role Discovery");
1338   DEBUG(id_, "   connection_handle=0x{:x}", handle);
1339 
1340   auto role = bluetooth::hci::Role::CENTRAL;
1341   auto status = link_layer_controller_.RoleDiscovery(handle, &role);
1342 
1343   send_event_(bluetooth::hci::RoleDiscoveryCompleteBuilder::Create(
1344       kNumCommandPackets, status, handle, role));
1345 }
1346 
ReadDefaultLinkPolicySettings(CommandView command)1347 void DualModeController::ReadDefaultLinkPolicySettings(CommandView command) {
1348   auto command_view =
1349       bluetooth::hci::ReadDefaultLinkPolicySettingsView::Create(command);
1350   CHECK_PACKET_VIEW(command_view);
1351 
1352   DEBUG(id_, "<< Read Default Link Policy Settings");
1353 
1354   uint16_t settings = link_layer_controller_.ReadDefaultLinkPolicySettings();
1355   send_event_(
1356       bluetooth::hci::ReadDefaultLinkPolicySettingsCompleteBuilder::Create(
1357           kNumCommandPackets, ErrorCode::SUCCESS, settings));
1358 }
1359 
WriteDefaultLinkPolicySettings(CommandView command)1360 void DualModeController::WriteDefaultLinkPolicySettings(CommandView command) {
1361   auto command_view =
1362       bluetooth::hci::WriteDefaultLinkPolicySettingsView::Create(command);
1363   CHECK_PACKET_VIEW(command_view);
1364 
1365   DEBUG(id_, "<< Write Default Link Policy Settings");
1366   DEBUG(id_, "   default_link_policy_settings=0x{:x}",
1367         command_view.GetDefaultLinkPolicySettings());
1368 
1369   ErrorCode status = link_layer_controller_.WriteDefaultLinkPolicySettings(
1370       command_view.GetDefaultLinkPolicySettings());
1371   send_event_(
1372       bluetooth::hci::WriteDefaultLinkPolicySettingsCompleteBuilder::Create(
1373           kNumCommandPackets, status));
1374 }
1375 
SniffSubrating(CommandView command)1376 void DualModeController::SniffSubrating(CommandView command) {
1377   auto command_view = bluetooth::hci::SniffSubratingView::Create(command);
1378   CHECK_PACKET_VIEW(command_view);
1379   uint16_t connection_handle = command_view.GetConnectionHandle();
1380 
1381   DEBUG(id_, "<< Sniff Subrating");
1382   DEBUG(id_, "   connection_handle=0x{:x}", connection_handle);
1383 
1384   send_event_(bluetooth::hci::SniffSubratingCompleteBuilder::Create(
1385       kNumCommandPackets, ErrorCode::SUCCESS, connection_handle));
1386 }
1387 
FlowSpecification(CommandView command)1388 void DualModeController::FlowSpecification(CommandView command) {
1389   auto command_view = bluetooth::hci::FlowSpecificationView::Create(command);
1390   CHECK_PACKET_VIEW(command_view);
1391   uint16_t handle = command_view.GetConnectionHandle();
1392   uint8_t flow_direction =
1393       static_cast<uint8_t>(command_view.GetFlowDirection());
1394   uint8_t service_type = static_cast<uint8_t>(command_view.GetServiceType());
1395   uint32_t token_rate = command_view.GetTokenRate();
1396   uint32_t token_bucket_size = command_view.GetTokenBucketSize();
1397   uint32_t peak_bandwidth = command_view.GetPeakBandwidth();
1398   uint32_t access_latency = command_view.GetAccessLatency();
1399 
1400   DEBUG(id_, "<< Flow Specification");
1401   DEBUG(id_, "   connection_handle=0x{:x}", handle);
1402 
1403   auto status = link_layer_controller_.FlowSpecification(
1404       handle, flow_direction, service_type, token_rate, token_bucket_size,
1405       peak_bandwidth, access_latency);
1406 
1407   send_event_(bluetooth::hci::FlowSpecificationStatusBuilder::Create(
1408       status, kNumCommandPackets));
1409 }
1410 
ReadLinkPolicySettings(CommandView command)1411 void DualModeController::ReadLinkPolicySettings(CommandView command) {
1412   auto command_view =
1413       bluetooth::hci::ReadLinkPolicySettingsView::Create(command);
1414   CHECK_PACKET_VIEW(command_view);
1415   uint16_t handle = command_view.GetConnectionHandle();
1416 
1417   DEBUG(id_, "<< Read Link Policy Settings");
1418   DEBUG(id_, "   connection_handle=0x{:x}", handle);
1419 
1420   uint16_t settings = 0;
1421   auto status =
1422       link_layer_controller_.ReadLinkPolicySettings(handle, &settings);
1423 
1424   send_event_(bluetooth::hci::ReadLinkPolicySettingsCompleteBuilder::Create(
1425       kNumCommandPackets, status, handle, settings));
1426 }
1427 
WriteLinkPolicySettings(CommandView command)1428 void DualModeController::WriteLinkPolicySettings(CommandView command) {
1429   auto command_view =
1430       bluetooth::hci::WriteLinkPolicySettingsView::Create(command);
1431   CHECK_PACKET_VIEW(command_view);
1432   uint16_t handle = command_view.GetConnectionHandle();
1433   uint16_t settings = command_view.GetLinkPolicySettings();
1434 
1435   DEBUG(id_, "<< Write Link Policy Settings");
1436   DEBUG(id_, "   connection_handle=0x{:x}", handle);
1437   DEBUG(id_, "   link_policy_settings=0x{:x}", settings);
1438 
1439   auto status =
1440       link_layer_controller_.WriteLinkPolicySettings(handle, settings);
1441 
1442   send_event_(bluetooth::hci::WriteLinkPolicySettingsCompleteBuilder::Create(
1443       kNumCommandPackets, status, handle));
1444 }
1445 
WriteLinkSupervisionTimeout(CommandView command)1446 void DualModeController::WriteLinkSupervisionTimeout(CommandView command) {
1447   auto command_view =
1448       bluetooth::hci::WriteLinkSupervisionTimeoutView::Create(command);
1449   CHECK_PACKET_VIEW(command_view);
1450   uint16_t handle = command_view.GetConnectionHandle();
1451   uint16_t timeout = command_view.GetLinkSupervisionTimeout();
1452 
1453   DEBUG(id_, "<< Write Link Supervision Timeout");
1454   DEBUG(id_, "   connection_handle=0x{:x}", handle);
1455   DEBUG(id_, "   link_supervision_timeout={}", timeout);
1456 
1457   auto status =
1458       link_layer_controller_.WriteLinkSupervisionTimeout(handle, timeout);
1459   send_event_(
1460       bluetooth::hci::WriteLinkSupervisionTimeoutCompleteBuilder::Create(
1461           kNumCommandPackets, status, handle));
1462 }
1463 
ReadLocalName(CommandView command)1464 void DualModeController::ReadLocalName(CommandView command) {
1465   auto command_view = bluetooth::hci::ReadLocalNameView::Create(command);
1466   CHECK_PACKET_VIEW(command_view);
1467 
1468   DEBUG(id_, "<< Read Local Name");
1469 
1470   send_event_(bluetooth::hci::ReadLocalNameCompleteBuilder::Create(
1471       kNumCommandPackets, ErrorCode::SUCCESS,
1472       link_layer_controller_.GetLocalName()));
1473 }
1474 
WriteLocalName(CommandView command)1475 void DualModeController::WriteLocalName(CommandView command) {
1476   auto command_view = bluetooth::hci::WriteLocalNameView::Create(command);
1477   CHECK_PACKET_VIEW(command_view);
1478 
1479   DEBUG(id_, "<< Write Local Name");
1480 
1481   link_layer_controller_.SetLocalName(command_view.GetLocalName());
1482   send_event_(bluetooth::hci::WriteLocalNameCompleteBuilder::Create(
1483       kNumCommandPackets, ErrorCode::SUCCESS));
1484 }
1485 
WriteExtendedInquiryResponse(CommandView command)1486 void DualModeController::WriteExtendedInquiryResponse(CommandView command) {
1487   auto command_view =
1488       bluetooth::hci::WriteExtendedInquiryResponseView::Create(command);
1489   CHECK_PACKET_VIEW(command_view);
1490 
1491   DEBUG(id_, "<< Write Extended Inquiry Response");
1492 
1493   link_layer_controller_.SetExtendedInquiryResponse(
1494       command_view.GetExtendedInquiryResponse());
1495   send_event_(
1496       bluetooth::hci::WriteExtendedInquiryResponseCompleteBuilder::Create(
1497           kNumCommandPackets, ErrorCode::SUCCESS));
1498 }
1499 
RefreshEncryptionKey(CommandView command)1500 void DualModeController::RefreshEncryptionKey(CommandView command) {
1501   auto command_view = bluetooth::hci::RefreshEncryptionKeyView::Create(command);
1502   CHECK_PACKET_VIEW(command_view);
1503   uint16_t handle = command_view.GetConnectionHandle();
1504 
1505   DEBUG(id_, "<< Refresh Encryption Key");
1506   DEBUG(id_, "   connection_handle=0x{:x}", handle);
1507 
1508   send_event_(bluetooth::hci::RefreshEncryptionKeyStatusBuilder::Create(
1509       ErrorCode::SUCCESS, kNumCommandPackets));
1510   // TODO: Support this in the link layer
1511   send_event_(bluetooth::hci::EncryptionKeyRefreshCompleteBuilder::Create(
1512       ErrorCode::SUCCESS, handle));
1513 }
1514 
ReadVoiceSetting(CommandView command)1515 void DualModeController::ReadVoiceSetting(CommandView command) {
1516   auto command_view = bluetooth::hci::ReadVoiceSettingView::Create(command);
1517   CHECK_PACKET_VIEW(command_view);
1518 
1519   DEBUG(id_, "<< Read Voice Setting");
1520 
1521   send_event_(bluetooth::hci::ReadVoiceSettingCompleteBuilder::Create(
1522       kNumCommandPackets, ErrorCode::SUCCESS,
1523       link_layer_controller_.GetVoiceSetting()));
1524 }
1525 
WriteVoiceSetting(CommandView command)1526 void DualModeController::WriteVoiceSetting(CommandView command) {
1527   auto command_view = bluetooth::hci::WriteVoiceSettingView::Create(command);
1528   CHECK_PACKET_VIEW(command_view);
1529 
1530   DEBUG(id_, "<< Write Voice Setting");
1531   DEBUG(id_, "   voice_setting=0x{:x}", command_view.GetVoiceSetting());
1532 
1533   link_layer_controller_.SetVoiceSetting(command_view.GetVoiceSetting());
1534 
1535   send_event_(bluetooth::hci::WriteVoiceSettingCompleteBuilder::Create(
1536       kNumCommandPackets, ErrorCode::SUCCESS));
1537 }
1538 
ReadNumberOfSupportedIac(CommandView command)1539 void DualModeController::ReadNumberOfSupportedIac(CommandView command) {
1540   auto command_view =
1541       bluetooth::hci::ReadNumberOfSupportedIacView::Create(command);
1542   CHECK_PACKET_VIEW(command_view);
1543 
1544   DEBUG(id_, "<< Read Number of Supported Iac");
1545 
1546   send_event_(bluetooth::hci::ReadNumberOfSupportedIacCompleteBuilder::Create(
1547       kNumCommandPackets, ErrorCode::SUCCESS, properties_.num_supported_iac));
1548 }
1549 
ReadCurrentIacLap(CommandView command)1550 void DualModeController::ReadCurrentIacLap(CommandView command) {
1551   auto command_view = bluetooth::hci::ReadCurrentIacLapView::Create(command);
1552   CHECK_PACKET_VIEW(command_view);
1553 
1554   DEBUG(id_, "<< Read Current Iac Lap");
1555 
1556   send_event_(bluetooth::hci::ReadCurrentIacLapCompleteBuilder::Create(
1557       kNumCommandPackets, ErrorCode::SUCCESS,
1558       link_layer_controller_.ReadCurrentIacLap()));
1559 }
1560 
WriteCurrentIacLap(CommandView command)1561 void DualModeController::WriteCurrentIacLap(CommandView command) {
1562   auto command_view = bluetooth::hci::WriteCurrentIacLapView::Create(command);
1563   CHECK_PACKET_VIEW(command_view);
1564 
1565   DEBUG(id_, "<< Write Current Iac Lap");
1566 
1567   link_layer_controller_.WriteCurrentIacLap(command_view.GetLapsToWrite());
1568   send_event_(bluetooth::hci::WriteCurrentIacLapCompleteBuilder::Create(
1569       kNumCommandPackets, ErrorCode::SUCCESS));
1570 }
1571 
ReadPageScanActivity(CommandView command)1572 void DualModeController::ReadPageScanActivity(CommandView command) {
1573   auto command_view = bluetooth::hci::ReadPageScanActivityView::Create(command);
1574   CHECK_PACKET_VIEW(command_view);
1575 
1576   DEBUG(id_, "<< Read Page Scan Activity");
1577 
1578   uint16_t interval = 0x1000;
1579   uint16_t window = 0x0012;
1580   send_event_(bluetooth::hci::ReadPageScanActivityCompleteBuilder::Create(
1581       kNumCommandPackets, ErrorCode::SUCCESS, interval, window));
1582 }
1583 
WritePageScanActivity(CommandView command)1584 void DualModeController::WritePageScanActivity(CommandView command) {
1585   auto command_view =
1586       bluetooth::hci::WritePageScanActivityView::Create(command);
1587   CHECK_PACKET_VIEW(command_view);
1588 
1589   DEBUG(id_, "<< Write Page Scan Activity");
1590 
1591   send_event_(bluetooth::hci::WritePageScanActivityCompleteBuilder::Create(
1592       kNumCommandPackets, ErrorCode::SUCCESS));
1593 }
1594 
ReadInquiryScanActivity(CommandView command)1595 void DualModeController::ReadInquiryScanActivity(CommandView command) {
1596   auto command_view =
1597       bluetooth::hci::ReadInquiryScanActivityView::Create(command);
1598   CHECK_PACKET_VIEW(command_view);
1599 
1600   DEBUG(id_, "<< Read Inquiry Scan Activity");
1601 
1602   uint16_t interval = 0x1000;
1603   uint16_t window = 0x0012;
1604   send_event_(bluetooth::hci::ReadInquiryScanActivityCompleteBuilder::Create(
1605       kNumCommandPackets, ErrorCode::SUCCESS, interval, window));
1606 }
1607 
WriteInquiryScanActivity(CommandView command)1608 void DualModeController::WriteInquiryScanActivity(CommandView command) {
1609   auto command_view =
1610       bluetooth::hci::WriteInquiryScanActivityView::Create(command);
1611   CHECK_PACKET_VIEW(command_view);
1612 
1613   DEBUG(id_, "<< Write Inquiry Scan Activity");
1614 
1615   send_event_(bluetooth::hci::WriteInquiryScanActivityCompleteBuilder::Create(
1616       kNumCommandPackets, ErrorCode::SUCCESS));
1617 }
1618 
ReadScanEnable(CommandView command)1619 void DualModeController::ReadScanEnable(CommandView command) {
1620   auto command_view = bluetooth::hci::ReadScanEnableView::Create(command);
1621   CHECK_PACKET_VIEW(command_view);
1622 
1623   DEBUG(id_, "<< Read Scan Enable");
1624 
1625   bool inquiry_scan = link_layer_controller_.GetInquiryScanEnable();
1626   bool page_scan = link_layer_controller_.GetPageScanEnable();
1627 
1628   bluetooth::hci::ScanEnable scan_enable =
1629       inquiry_scan && page_scan
1630           ? bluetooth::hci::ScanEnable::INQUIRY_AND_PAGE_SCAN
1631       : inquiry_scan ? bluetooth::hci::ScanEnable::INQUIRY_SCAN_ONLY
1632       : page_scan    ? bluetooth::hci::ScanEnable::PAGE_SCAN_ONLY
1633                      : bluetooth::hci::ScanEnable::NO_SCANS;
1634 
1635   send_event_(bluetooth::hci::ReadScanEnableCompleteBuilder::Create(
1636       kNumCommandPackets, ErrorCode::SUCCESS, scan_enable));
1637 }
1638 
WriteScanEnable(CommandView command)1639 void DualModeController::WriteScanEnable(CommandView command) {
1640   auto command_view = bluetooth::hci::WriteScanEnableView::Create(command);
1641   CHECK_PACKET_VIEW(command_view);
1642   bluetooth::hci::ScanEnable scan_enable = command_view.GetScanEnable();
1643   bool inquiry_scan =
1644       scan_enable == bluetooth::hci::ScanEnable::INQUIRY_AND_PAGE_SCAN ||
1645       scan_enable == bluetooth::hci::ScanEnable::INQUIRY_SCAN_ONLY;
1646   bool page_scan =
1647       scan_enable == bluetooth::hci::ScanEnable::INQUIRY_AND_PAGE_SCAN ||
1648       scan_enable == bluetooth::hci::ScanEnable::PAGE_SCAN_ONLY;
1649 
1650   DEBUG(id_, "<< Write Scan Enable");
1651   DEBUG(id_, "   scan_enable={}", bluetooth::hci::ScanEnableText(scan_enable));
1652 
1653   link_layer_controller_.SetInquiryScanEnable(inquiry_scan);
1654   link_layer_controller_.SetPageScanEnable(page_scan);
1655   send_event_(bluetooth::hci::WriteScanEnableCompleteBuilder::Create(
1656       kNumCommandPackets, ErrorCode::SUCCESS));
1657 }
1658 
ReadTransmitPowerLevel(CommandView command)1659 void DualModeController::ReadTransmitPowerLevel(CommandView command) {
1660   auto command_view = bluetooth::hci::ReadTransmitPowerLevelView::Create(command);
1661   CHECK_PACKET_VIEW(command_view);
1662   uint16_t connection_handle = command_view.GetConnectionHandle();
1663 
1664   DEBUG(id_, "<< Read Transmit Power Level");
1665   DEBUG(id_, "   connection_handle=0x{:x}", connection_handle);
1666 
1667   ErrorCode status = link_layer_controller_.HasAclConnection(connection_handle)
1668                          ? ErrorCode::SUCCESS
1669                          : ErrorCode::UNKNOWN_CONNECTION;
1670 
1671   send_event_(bluetooth::hci::ReadTransmitPowerLevelCompleteBuilder::Create(
1672       kNumCommandPackets, status, connection_handle, kTransmitPowerLevel));
1673 }
1674 
ReadEnhancedTransmitPowerLevel(CommandView command)1675 void DualModeController::ReadEnhancedTransmitPowerLevel(CommandView command) {
1676   auto command_view = bluetooth::hci::ReadEnhancedTransmitPowerLevelView::Create(command);
1677   CHECK_PACKET_VIEW(command_view);
1678   uint16_t connection_handle = command_view.GetConnectionHandle();
1679 
1680   DEBUG(id_, "<< Read Enhanced Transmit Power Level");
1681   DEBUG(id_, "   connection_handle=0x{:x}", connection_handle);
1682 
1683   ErrorCode status = link_layer_controller_.HasAclConnection(connection_handle)
1684                          ? ErrorCode::SUCCESS
1685                          : ErrorCode::UNKNOWN_CONNECTION;
1686 
1687   send_event_(bluetooth::hci::ReadEnhancedTransmitPowerLevelCompleteBuilder::Create(
1688       kNumCommandPackets, status, connection_handle, kTransmitPowerLevel,
1689       kTransmitPowerLevel, kTransmitPowerLevel));
1690 }
1691 
ReadSynchronousFlowControlEnable(CommandView command)1692 void DualModeController::ReadSynchronousFlowControlEnable(CommandView command) {
1693   auto command_view =
1694       bluetooth::hci::ReadSynchronousFlowControlEnableView::Create(command);
1695   CHECK_PACKET_VIEW(command_view);
1696 
1697   DEBUG(id_, "<< Read Synchronous Flow Control Enable");
1698 
1699   auto enabled = bluetooth::hci::Enable::DISABLED;
1700   if (link_layer_controller_.GetScoFlowControlEnable()) {
1701     enabled = bluetooth::hci::Enable::ENABLED;
1702   }
1703   send_event_(
1704       bluetooth::hci::ReadSynchronousFlowControlEnableCompleteBuilder::Create(
1705           kNumCommandPackets, ErrorCode::SUCCESS, enabled));
1706 }
1707 
WriteSynchronousFlowControlEnable(CommandView command)1708 void DualModeController::WriteSynchronousFlowControlEnable(
1709     CommandView command) {
1710   auto command_view =
1711       bluetooth::hci::WriteSynchronousFlowControlEnableView::Create(command);
1712   CHECK_PACKET_VIEW(command_view);
1713   auto enabled = command_view.GetEnable() == bluetooth::hci::Enable::ENABLED;
1714 
1715   DEBUG(id_, "<< Write Synchronous Flow Control Enable");
1716   DEBUG(id_, "   enable={}", enabled);
1717 
1718   link_layer_controller_.SetScoFlowControlEnable(enabled);
1719   send_event_(
1720       bluetooth::hci::WriteSynchronousFlowControlEnableCompleteBuilder::Create(
1721           kNumCommandPackets, ErrorCode::SUCCESS));
1722 }
1723 
SetEventFilter(CommandView command)1724 void DualModeController::SetEventFilter(CommandView command) {
1725   auto command_view = bluetooth::hci::SetEventFilterView::Create(command);
1726   CHECK_PACKET_VIEW(command_view);
1727 
1728   DEBUG(id_, "<< Set Event Filter");
1729   DEBUG(id_, "   filter_type={}",
1730         bluetooth::hci::FilterTypeText(command_view.GetFilterType()));
1731 
1732   if (command_view.GetFilterType() != bluetooth::hci::FilterType::CLEAR_ALL_FILTERS) {
1733     FATAL("unsupported event filter type");
1734   }
1735 
1736   send_event_(bluetooth::hci::SetEventFilterCompleteBuilder::Create(
1737       kNumCommandPackets, ErrorCode::SUCCESS));
1738 }
1739 
Inquiry(CommandView command)1740 void DualModeController::Inquiry(CommandView command) {
1741   auto command_view = bluetooth::hci::InquiryView::Create(command);
1742   CHECK_PACKET_VIEW(command_view);
1743   auto max_responses = command_view.GetNumResponses();
1744   auto length = command_view.GetInquiryLength();
1745 
1746   DEBUG(id_, "<< Inquiry");
1747   DEBUG(id_, "   num_responses={}", max_responses);
1748   DEBUG(id_, "   inquiry_length={}", length);
1749 
1750   if (max_responses > 0xff || length < 1 || length > 0x30) {
1751     send_event_(bluetooth::hci::InquiryStatusBuilder::Create(
1752         ErrorCode::INVALID_HCI_COMMAND_PARAMETERS, kNumCommandPackets));
1753     return;
1754   }
1755   link_layer_controller_.SetInquiryLAP(command_view.GetLap().lap_);
1756   link_layer_controller_.SetInquiryMaxResponses(max_responses);
1757   link_layer_controller_.StartInquiry(std::chrono::milliseconds(length * 1280));
1758 
1759   send_event_(bluetooth::hci::InquiryStatusBuilder::Create(ErrorCode::SUCCESS,
1760                                                            kNumCommandPackets));
1761 }
1762 
InquiryCancel(CommandView command)1763 void DualModeController::InquiryCancel(CommandView command) {
1764   auto command_view = bluetooth::hci::InquiryCancelView::Create(command);
1765   CHECK_PACKET_VIEW(command_view);
1766 
1767   DEBUG(id_, "<< Inquiry Cancel");
1768 
1769   link_layer_controller_.InquiryCancel();
1770   send_event_(bluetooth::hci::InquiryCancelCompleteBuilder::Create(
1771       kNumCommandPackets, ErrorCode::SUCCESS));
1772 }
1773 
AcceptConnectionRequest(CommandView command)1774 void DualModeController::AcceptConnectionRequest(CommandView command) {
1775   auto command_view =
1776       bluetooth::hci::AcceptConnectionRequestView::Create(command);
1777   CHECK_PACKET_VIEW(command_view);
1778   Address bd_addr = command_view.GetBdAddr();
1779   bool try_role_switch =
1780       command_view.GetRole() ==
1781       bluetooth::hci::AcceptConnectionRequestRole::BECOME_CENTRAL;
1782 
1783   DEBUG(id_, "<< Accept Connection Request");
1784   DEBUG(id_, "   bd_addr={}", bd_addr);
1785   DEBUG(id_, "   try_role_switch={}", try_role_switch);
1786 
1787   auto status =
1788       link_layer_controller_.AcceptConnectionRequest(bd_addr, try_role_switch);
1789   send_event_(bluetooth::hci::AcceptConnectionRequestStatusBuilder::Create(
1790       status, kNumCommandPackets));
1791 }
1792 
RejectConnectionRequest(CommandView command)1793 void DualModeController::RejectConnectionRequest(CommandView command) {
1794   auto command_view =
1795       bluetooth::hci::RejectConnectionRequestView::Create(command);
1796   CHECK_PACKET_VIEW(command_view);
1797   Address bd_addr = command_view.GetBdAddr();
1798   auto reason = command_view.GetReason();
1799 
1800   DEBUG(id_, "<< Reject Connection Request");
1801   DEBUG(id_, "   bd_addr={}", bd_addr);
1802   DEBUG(id_, "   reason={}",
1803         bluetooth::hci::RejectConnectionReasonText(reason));
1804 
1805   auto status = link_layer_controller_.RejectConnectionRequest(
1806       bd_addr, static_cast<uint8_t>(reason));
1807   send_event_(bluetooth::hci::RejectConnectionRequestStatusBuilder::Create(
1808       status, kNumCommandPackets));
1809 }
1810 
DeleteStoredLinkKey(CommandView command)1811 void DualModeController::DeleteStoredLinkKey(CommandView command) {
1812   auto command_view = bluetooth::hci::DeleteStoredLinkKeyView::Create(command);
1813   CHECK_PACKET_VIEW(command_view);
1814 
1815   DEBUG(id_, "<< Delete Stored Link Key");
1816 
1817   send_event_(bluetooth::hci::DeleteStoredLinkKeyCompleteBuilder::Create(
1818       kNumCommandPackets, ErrorCode::SUCCESS, 0));
1819 }
1820 
RemoteNameRequest(CommandView command)1821 void DualModeController::RemoteNameRequest(CommandView command) {
1822   auto command_view = bluetooth::hci::RemoteNameRequestView::Create(command);
1823   CHECK_PACKET_VIEW(command_view);
1824   Address bd_addr = command_view.GetBdAddr();
1825 
1826   DEBUG(id_, "<< Remote Name Request");
1827   DEBUG(id_, "   bd_addr={}", bd_addr);
1828 
1829   auto status = link_layer_controller_.SendCommandToRemoteByAddress(
1830       OpCode::REMOTE_NAME_REQUEST, command_view.bytes(), GetAddress(), bd_addr);
1831 
1832   send_event_(bluetooth::hci::RemoteNameRequestStatusBuilder::Create(
1833       status, kNumCommandPackets));
1834 }
1835 
LeSetEventMask(CommandView command)1836 void DualModeController::LeSetEventMask(CommandView command) {
1837   auto command_view = bluetooth::hci::LeSetEventMaskView::Create(command);
1838   CHECK_PACKET_VIEW(command_view);
1839 
1840   DEBUG(id_, "<< LE Set Event Mask");
1841   DEBUG(id_, "   le_event_mask=0x{:x}", command_view.GetLeEventMask());
1842 
1843   link_layer_controller_.SetLeEventMask(command_view.GetLeEventMask());
1844   send_event_(bluetooth::hci::LeSetEventMaskCompleteBuilder::Create(
1845       kNumCommandPackets, ErrorCode::SUCCESS));
1846 }
1847 
LeRequestPeerSca(CommandView command)1848 void DualModeController::LeRequestPeerSca(CommandView command) {
1849   auto command_view = bluetooth::hci::LeRequestPeerScaView::Create(command);
1850   CHECK_PACKET_VIEW(command_view);
1851   uint16_t connection_handle = command_view.GetConnectionHandle();
1852 
1853   DEBUG(id_, "<< LE Request Peer SCA");
1854   DEBUG(id_, "   connection_handle=0x{:x}", connection_handle);
1855 
1856   // If the Host sends this command and the peer device does not support the
1857   // Sleep Clock Accuracy Updates feature, the Controller shall return the error
1858   // code Unsupported Feature or Parameter Value (0x11) in the HCI_LE_-
1859   // Request_Peer_SCA_Complete event.
1860   // TODO
1861 
1862   // If the Host issues this command when the Controller is aware (e.g., through
1863   // a previous feature exchange) that the peer device's Link Layer does not
1864   // support the Sleep Clock Accuracy Updates feature, the Controller shall
1865   // return the error code Unsupported Remote Feature (0x1A).
1866   // TODO
1867 
1868   if (link_layer_controller_.HasAclConnection(connection_handle)) {
1869     send_event_(bluetooth::hci::LeRequestPeerScaStatusBuilder::Create(
1870         ErrorCode::SUCCESS, kNumCommandPackets));
1871     send_event_(bluetooth::hci::LeRequestPeerScaCompleteBuilder::Create(
1872         ErrorCode::SUCCESS, connection_handle,
1873         bluetooth::hci::ClockAccuracy::PPM_500));
1874   } else {
1875     send_event_(bluetooth::hci::LeRequestPeerScaStatusBuilder::Create(
1876         ErrorCode::UNKNOWN_CONNECTION, kNumCommandPackets));
1877   }
1878 }
1879 
LeSetHostFeature(CommandView command)1880 void DualModeController::LeSetHostFeature(CommandView command) {
1881   auto command_view = bluetooth::hci::LeSetHostFeatureView::Create(command);
1882   CHECK_PACKET_VIEW(command_view);
1883   uint8_t bit_number = static_cast<uint8_t>(command_view.GetBitNumber());
1884   uint8_t bit_value = static_cast<uint8_t>(command_view.GetBitValue());
1885 
1886   DEBUG(id_, "<< LE Set Host Feature");
1887   DEBUG(id_, "   bit_number={}", bit_number);
1888   DEBUG(id_, "   bit_value={}", bit_value);
1889 
1890   ErrorCode status =
1891       link_layer_controller_.LeSetHostFeature(bit_number, bit_value);
1892   send_event_(bluetooth::hci::LeSetHostFeatureCompleteBuilder::Create(
1893       kNumCommandPackets, status));
1894 }
1895 
LeReadBufferSizeV1(CommandView command)1896 void DualModeController::LeReadBufferSizeV1(CommandView command) {
1897   auto command_view = bluetooth::hci::LeReadBufferSizeV1View::Create(command);
1898   CHECK_PACKET_VIEW(command_view);
1899 
1900   DEBUG(id_, "<< LE Read Buffer Size V1");
1901 
1902   bluetooth::hci::LeBufferSize le_buffer_size;
1903   le_buffer_size.le_data_packet_length_ = properties_.le_acl_data_packet_length;
1904   le_buffer_size.total_num_le_packets_ =
1905       properties_.total_num_le_acl_data_packets;
1906 
1907   send_event_(bluetooth::hci::LeReadBufferSizeV1CompleteBuilder::Create(
1908       kNumCommandPackets, ErrorCode::SUCCESS, le_buffer_size));
1909 }
1910 
LeReadBufferSizeV2(CommandView command)1911 void DualModeController::LeReadBufferSizeV2(CommandView command) {
1912   auto command_view = bluetooth::hci::LeReadBufferSizeV2View::Create(command);
1913   CHECK_PACKET_VIEW(command_view);
1914 
1915   DEBUG(id_, "<< LE Read Buffer Size V2");
1916 
1917   bluetooth::hci::LeBufferSize le_buffer_size;
1918   le_buffer_size.le_data_packet_length_ = properties_.le_acl_data_packet_length;
1919   le_buffer_size.total_num_le_packets_ =
1920       properties_.total_num_le_acl_data_packets;
1921   bluetooth::hci::LeBufferSize iso_buffer_size;
1922   iso_buffer_size.le_data_packet_length_ = properties_.iso_data_packet_length;
1923   iso_buffer_size.total_num_le_packets_ =
1924       properties_.total_num_iso_data_packets;
1925 
1926   send_event_(bluetooth::hci::LeReadBufferSizeV2CompleteBuilder::Create(
1927       kNumCommandPackets, ErrorCode::SUCCESS, le_buffer_size, iso_buffer_size));
1928 }
1929 
LeSetAddressResolutionEnable(CommandView command)1930 void DualModeController::LeSetAddressResolutionEnable(CommandView command) {
1931   auto command_view =
1932       bluetooth::hci::LeSetAddressResolutionEnableView::Create(command);
1933   CHECK_PACKET_VIEW(command_view);
1934 
1935   DEBUG(id_, "<< LE Set Address Resolution Enable");
1936   DEBUG(id_, "   address_resolution_enable={}",
1937         command_view.GetAddressResolutionEnable() ==
1938             bluetooth::hci::Enable::ENABLED);
1939 
1940   ErrorCode status = link_layer_controller_.LeSetAddressResolutionEnable(
1941       command_view.GetAddressResolutionEnable() ==
1942       bluetooth::hci::Enable::ENABLED);
1943   send_event_(
1944       bluetooth::hci::LeSetAddressResolutionEnableCompleteBuilder::Create(
1945           kNumCommandPackets, status));
1946 }
1947 
LeSetResolvablePrivateAddressTimeout(CommandView command)1948 void DualModeController::LeSetResolvablePrivateAddressTimeout(
1949     CommandView command) {
1950   auto command_view =
1951       bluetooth::hci::LeSetResolvablePrivateAddressTimeoutView::Create(command);
1952   CHECK_PACKET_VIEW(command_view);
1953 
1954   DEBUG(id_, "<< LE Set Resolvable Private Address Timeout");
1955 
1956   ErrorCode status =
1957       link_layer_controller_.LeSetResolvablePrivateAddressTimeout(
1958           command_view.GetRpaTimeout());
1959   send_event_(
1960       bluetooth::hci::LeSetResolvablePrivateAddressTimeoutCompleteBuilder::
1961           Create(kNumCommandPackets, status));
1962 }
1963 
LeReadLocalSupportedFeatures(CommandView command)1964 void DualModeController::LeReadLocalSupportedFeatures(CommandView command) {
1965   auto command_view =
1966       bluetooth::hci::LeReadLocalSupportedFeaturesView::Create(command);
1967   CHECK_PACKET_VIEW(command_view);
1968 
1969   DEBUG(id_, "<< LE Read Local Supported Features");
1970 
1971   uint64_t le_features = link_layer_controller_.GetLeSupportedFeatures();
1972   send_event_(
1973       bluetooth::hci::LeReadLocalSupportedFeaturesCompleteBuilder::Create(
1974           kNumCommandPackets, ErrorCode::SUCCESS, le_features));
1975 }
1976 
LeSetRandomAddress(CommandView command)1977 void DualModeController::LeSetRandomAddress(CommandView command) {
1978   auto command_view = bluetooth::hci::LeSetRandomAddressView::Create(command);
1979   CHECK_PACKET_VIEW(command_view);
1980 
1981   DEBUG(id_, "<< LE Set Random Address");
1982   DEBUG(id_, "   random_address={}", command_view.GetRandomAddress());
1983 
1984   ErrorCode status = link_layer_controller_.LeSetRandomAddress(
1985       command_view.GetRandomAddress());
1986   send_event_(bluetooth::hci::LeSetRandomAddressCompleteBuilder::Create(
1987       kNumCommandPackets, status));
1988 }
1989 
LeSetAdvertisingParameters(CommandView command)1990 void DualModeController::LeSetAdvertisingParameters(CommandView command) {
1991   auto command_view =
1992       bluetooth::hci::LeSetAdvertisingParametersView::Create(command);
1993   CHECK_PACKET_VIEW(command_view);
1994 
1995   DEBUG(id_, "<< LE Set Advertising Parameters");
1996 
1997   ErrorCode status = link_layer_controller_.LeSetAdvertisingParameters(
1998       command_view.GetAdvertisingIntervalMin(),
1999       command_view.GetAdvertisingIntervalMax(),
2000       command_view.GetAdvertisingType(), command_view.GetOwnAddressType(),
2001       command_view.GetPeerAddressType(), command_view.GetPeerAddress(),
2002       command_view.GetAdvertisingChannelMap(),
2003       command_view.GetAdvertisingFilterPolicy());
2004   send_event_(bluetooth::hci::LeSetAdvertisingParametersCompleteBuilder::Create(
2005       kNumCommandPackets, status));
2006 }
2007 
LeReadAdvertisingPhysicalChannelTxPower(CommandView command)2008 void DualModeController::LeReadAdvertisingPhysicalChannelTxPower(
2009     CommandView command) {
2010   auto command_view =
2011       bluetooth::hci::LeReadAdvertisingPhysicalChannelTxPowerView::Create(
2012           command);
2013   CHECK_PACKET_VIEW(command_view);
2014 
2015   DEBUG(id_, "<< LE Read Physical Channel Tx Power");
2016 
2017   send_event_(
2018       bluetooth::hci::LeReadAdvertisingPhysicalChannelTxPowerCompleteBuilder::
2019           Create(kNumCommandPackets, ErrorCode::SUCCESS,
2020                  properties_.le_advertising_physical_channel_tx_power));
2021 }
2022 
LeSetAdvertisingData(CommandView command)2023 void DualModeController::LeSetAdvertisingData(CommandView command) {
2024   auto command_view = bluetooth::hci::LeSetAdvertisingDataView::Create(command);
2025   CHECK_PACKET_VIEW(command_view);
2026 
2027   DEBUG(id_, "<< LE Set Advertising Data");
2028 
2029   ErrorCode status = link_layer_controller_.LeSetAdvertisingData(
2030       command_view.GetAdvertisingData());
2031   send_event_(bluetooth::hci::LeSetAdvertisingDataCompleteBuilder::Create(
2032       kNumCommandPackets, status));
2033 }
2034 
LeSetScanResponseData(CommandView command)2035 void DualModeController::LeSetScanResponseData(CommandView command) {
2036   auto command_view =
2037       bluetooth::hci::LeSetScanResponseDataView::Create(command);
2038   CHECK_PACKET_VIEW(command_view);
2039 
2040   DEBUG(id_, "<< LE Set Scan Response Data");
2041 
2042   ErrorCode status = link_layer_controller_.LeSetScanResponseData(
2043       command_view.GetAdvertisingData());
2044   send_event_(bluetooth::hci::LeSetScanResponseDataCompleteBuilder::Create(
2045       kNumCommandPackets, status));
2046 }
2047 
LeSetAdvertisingEnable(CommandView command)2048 void DualModeController::LeSetAdvertisingEnable(CommandView command) {
2049   auto command_view =
2050       bluetooth::hci::LeSetAdvertisingEnableView::Create(command);
2051   CHECK_PACKET_VIEW(command_view);
2052 
2053   DEBUG(id_, "<< LE Set Advertising Enable");
2054   DEBUG(id_, "   advertising_enable={}",
2055         command_view.GetAdvertisingEnable() == bluetooth::hci::Enable::ENABLED);
2056 
2057   ErrorCode status = link_layer_controller_.LeSetAdvertisingEnable(
2058       command_view.GetAdvertisingEnable() == bluetooth::hci::Enable::ENABLED);
2059   send_event_(bluetooth::hci::LeSetAdvertisingEnableCompleteBuilder::Create(
2060       kNumCommandPackets, status));
2061 }
2062 
LeSetScanParameters(CommandView command)2063 void DualModeController::LeSetScanParameters(CommandView command) {
2064   auto command_view = bluetooth::hci::LeSetScanParametersView::Create(command);
2065   CHECK_PACKET_VIEW(command_view);
2066 
2067   DEBUG(id_, "<< LE Set Scan Parameters");
2068 
2069   ErrorCode status = link_layer_controller_.LeSetScanParameters(
2070       command_view.GetLeScanType(), command_view.GetLeScanInterval(),
2071       command_view.GetLeScanWindow(), command_view.GetOwnAddressType(),
2072       command_view.GetScanningFilterPolicy());
2073   send_event_(bluetooth::hci::LeSetScanParametersCompleteBuilder::Create(
2074       kNumCommandPackets, status));
2075 }
2076 
LeSetScanEnable(CommandView command)2077 void DualModeController::LeSetScanEnable(CommandView command) {
2078   auto command_view = bluetooth::hci::LeSetScanEnableView::Create(command);
2079   CHECK_PACKET_VIEW(command_view);
2080 
2081   DEBUG(id_, "<< LE Set Scan Enable");
2082   DEBUG(id_, "   scan_enable={}",
2083         command_view.GetLeScanEnable() == bluetooth::hci::Enable::ENABLED);
2084 
2085   ErrorCode status = link_layer_controller_.LeSetScanEnable(
2086       command_view.GetLeScanEnable() == bluetooth::hci::Enable::ENABLED,
2087       command_view.GetFilterDuplicates() == bluetooth::hci::Enable::ENABLED);
2088   send_event_(bluetooth::hci::LeSetScanEnableCompleteBuilder::Create(
2089       kNumCommandPackets, status));
2090 }
2091 
LeCreateConnection(CommandView command)2092 void DualModeController::LeCreateConnection(CommandView command) {
2093   auto command_view = bluetooth::hci::LeCreateConnectionView::Create(command);
2094   CHECK_PACKET_VIEW(command_view);
2095 
2096   DEBUG(id_, "<< LE Create Connection");
2097   DEBUG(id_, "   peer_address={}", command_view.GetPeerAddress());
2098   DEBUG(id_, "   peer_address_type={}",
2099         bluetooth::hci::AddressTypeText(command_view.GetPeerAddressType()));
2100   DEBUG(id_, "   own_address_type={}",
2101         bluetooth::hci::OwnAddressTypeText(command_view.GetOwnAddressType()));
2102   DEBUG(id_, "   initiator_filter_policy={}",
2103         bluetooth::hci::InitiatorFilterPolicyText(
2104             command_view.GetInitiatorFilterPolicy()));
2105 
2106   ErrorCode status = link_layer_controller_.LeCreateConnection(
2107       command_view.GetLeScanInterval(), command_view.GetLeScanWindow(),
2108       command_view.GetInitiatorFilterPolicy(),
2109       AddressWithType{
2110           command_view.GetPeerAddress(),
2111           command_view.GetPeerAddressType(),
2112       },
2113       command_view.GetOwnAddressType(), command_view.GetConnectionIntervalMin(),
2114       command_view.GetConnectionIntervalMax(), command_view.GetMaxLatency(),
2115       command_view.GetSupervisionTimeout(), command_view.GetMinCeLength(),
2116       command_view.GetMaxCeLength());
2117   send_event_(bluetooth::hci::LeCreateConnectionStatusBuilder::Create(
2118       status, kNumCommandPackets));
2119 }
2120 
LeCreateConnectionCancel(CommandView command)2121 void DualModeController::LeCreateConnectionCancel(CommandView command) {
2122   auto command_view =
2123       bluetooth::hci::LeCreateConnectionCancelView::Create(command);
2124   CHECK_PACKET_VIEW(command_view);
2125 
2126   DEBUG(id_, "<< LE Create Connection Cancel");
2127 
2128   ErrorCode status = link_layer_controller_.LeCreateConnectionCancel();
2129   send_event_(bluetooth::hci::LeCreateConnectionCancelCompleteBuilder::Create(
2130       kNumCommandPackets, status));
2131 }
2132 
LeConnectionUpdate(CommandView command)2133 void DualModeController::LeConnectionUpdate(CommandView command) {
2134   auto command_view = bluetooth::hci::LeConnectionUpdateView::Create(command);
2135   CHECK_PACKET_VIEW(command_view);
2136 
2137   DEBUG(id_, "<< LE Connection Update");
2138   DEBUG(id_, "   connection_handle=0x{:x}", command_view.GetConnectionHandle());
2139 
2140   ErrorCode status = link_layer_controller_.LeConnectionUpdate(
2141       command_view.GetConnectionHandle(),
2142       command_view.GetConnectionIntervalMin(),
2143       command_view.GetConnectionIntervalMax(), command_view.GetMaxLatency(),
2144       command_view.GetSupervisionTimeout());
2145 
2146   send_event_(bluetooth::hci::LeConnectionUpdateStatusBuilder::Create(
2147       status, kNumCommandPackets));
2148 }
2149 
CreateConnection(CommandView command)2150 void DualModeController::CreateConnection(CommandView command) {
2151   auto command_view = bluetooth::hci::CreateConnectionView::Create(command);
2152   CHECK_PACKET_VIEW(command_view);
2153   Address bd_addr = command_view.GetBdAddr();
2154   uint16_t packet_type = command_view.GetPacketType();
2155   uint8_t page_scan_mode =
2156       static_cast<uint8_t>(command_view.GetPageScanRepetitionMode());
2157   uint16_t clock_offset = (command_view.GetClockOffsetValid() ==
2158                                    bluetooth::hci::ClockOffsetValid::VALID
2159                                ? command_view.GetClockOffset()
2160                                : 0);
2161   uint8_t allow_role_switch =
2162       static_cast<uint8_t>(command_view.GetAllowRoleSwitch());
2163 
2164   DEBUG(id_, "<< Create Connection");
2165   DEBUG(id_, "   bd_addr={}", bd_addr);
2166   DEBUG(id_, "   allow_role_switch={}",
2167         command_view.GetAllowRoleSwitch() ==
2168             bluetooth::hci::CreateConnectionRoleSwitch::ALLOW_ROLE_SWITCH);
2169 
2170   auto status = link_layer_controller_.CreateConnection(
2171       bd_addr, packet_type, page_scan_mode, clock_offset, allow_role_switch);
2172 
2173   send_event_(bluetooth::hci::CreateConnectionStatusBuilder::Create(
2174       status, kNumCommandPackets));
2175 }
2176 
CreateConnectionCancel(CommandView command)2177 void DualModeController::CreateConnectionCancel(CommandView command) {
2178   auto command_view =
2179       bluetooth::hci::CreateConnectionCancelView::Create(command);
2180   CHECK_PACKET_VIEW(command_view);
2181   Address address = command_view.GetBdAddr();
2182 
2183   DEBUG(id_, "<< Create Connection Cancel");
2184   DEBUG(id_, "   bd_addr={}", address);
2185 
2186   auto status = link_layer_controller_.CreateConnectionCancel(address);
2187 
2188   send_event_(bluetooth::hci::CreateConnectionCancelCompleteBuilder::Create(
2189       kNumCommandPackets, status, address));
2190 }
2191 
Disconnect(CommandView command)2192 void DualModeController::Disconnect(CommandView command) {
2193   auto command_view = bluetooth::hci::DisconnectView::Create(command);
2194   CHECK_PACKET_VIEW(command_view);
2195   uint16_t connection_handle = command_view.GetConnectionHandle();
2196 
2197   DEBUG(id_, "<< Disconnect");
2198   DEBUG(id_, "   connection_handle=0x{:x}", connection_handle);
2199 
2200   if (connection_handle >= kCisHandleRangeStart &&
2201       connection_handle < kCisHandleRangeEnd) {
2202     link_layer_controller_.ForwardToLl(command);
2203   } else {
2204     auto status = link_layer_controller_.Disconnect(
2205         connection_handle, ErrorCode(command_view.GetReason()));
2206 
2207     send_event_(bluetooth::hci::DisconnectStatusBuilder::Create(
2208         status, kNumCommandPackets));
2209   }
2210 }
2211 
LeReadFilterAcceptListSize(CommandView command)2212 void DualModeController::LeReadFilterAcceptListSize(CommandView command) {
2213   auto command_view =
2214       bluetooth::hci::LeReadFilterAcceptListSizeView::Create(command);
2215   CHECK_PACKET_VIEW(command_view);
2216 
2217   DEBUG(id_, "<< LE Read Filter Accept List Size");
2218 
2219   send_event_(bluetooth::hci::LeReadFilterAcceptListSizeCompleteBuilder::Create(
2220       kNumCommandPackets, ErrorCode::SUCCESS,
2221       properties_.le_filter_accept_list_size));
2222 }
2223 
LeClearFilterAcceptList(CommandView command)2224 void DualModeController::LeClearFilterAcceptList(CommandView command) {
2225   auto command_view =
2226       bluetooth::hci::LeClearFilterAcceptListView::Create(command);
2227   CHECK_PACKET_VIEW(command_view);
2228 
2229   DEBUG(id_, "<< LE Clear Filter Accept List");
2230 
2231   ErrorCode status = link_layer_controller_.LeClearFilterAcceptList();
2232   send_event_(bluetooth::hci::LeClearFilterAcceptListCompleteBuilder::Create(
2233       kNumCommandPackets, status));
2234 }
2235 
LeAddDeviceToFilterAcceptList(CommandView command)2236 void DualModeController::LeAddDeviceToFilterAcceptList(CommandView command) {
2237   auto command_view =
2238       bluetooth::hci::LeAddDeviceToFilterAcceptListView::Create(command);
2239   CHECK_PACKET_VIEW(command_view);
2240 
2241   DEBUG(id_, "<< LE Add Device To Filter Accept List");
2242   DEBUG(id_, "   address={}", command_view.GetAddress());
2243   DEBUG(id_, "   address_type={}",
2244         bluetooth::hci::FilterAcceptListAddressTypeText(
2245             command_view.GetAddressType()));
2246 
2247   ErrorCode status = link_layer_controller_.LeAddDeviceToFilterAcceptList(
2248       command_view.GetAddressType(), command_view.GetAddress());
2249   send_event_(
2250       bluetooth::hci::LeAddDeviceToFilterAcceptListCompleteBuilder::Create(
2251           kNumCommandPackets, status));
2252 }
2253 
LeRemoveDeviceFromFilterAcceptList(CommandView command)2254 void DualModeController::LeRemoveDeviceFromFilterAcceptList(
2255     CommandView command) {
2256   auto command_view =
2257       bluetooth::hci::LeRemoveDeviceFromFilterAcceptListView::Create(command);
2258   CHECK_PACKET_VIEW(command_view);
2259 
2260   DEBUG(id_, "<< LE Remove Device From Filter Accept List");
2261   DEBUG(id_, "   address={}", command_view.GetAddress());
2262   DEBUG(id_, "   address_type={}",
2263         bluetooth::hci::FilterAcceptListAddressTypeText(
2264             command_view.GetAddressType()));
2265 
2266   ErrorCode status = link_layer_controller_.LeRemoveDeviceFromFilterAcceptList(
2267       command_view.GetAddressType(), command_view.GetAddress());
2268   send_event_(
2269       bluetooth::hci::LeRemoveDeviceFromFilterAcceptListCompleteBuilder::Create(
2270           kNumCommandPackets, status));
2271 }
2272 
LeClearResolvingList(CommandView command)2273 void DualModeController::LeClearResolvingList(CommandView command) {
2274   auto command_view = bluetooth::hci::LeClearResolvingListView::Create(command);
2275   CHECK_PACKET_VIEW(command_view);
2276 
2277   DEBUG(id_, "<< LE Clear Resolving List");
2278 
2279   ErrorCode status = link_layer_controller_.LeClearResolvingList();
2280   send_event_(bluetooth::hci::LeClearResolvingListCompleteBuilder::Create(
2281       kNumCommandPackets, status));
2282 }
2283 
LeReadResolvingListSize(CommandView command)2284 void DualModeController::LeReadResolvingListSize(CommandView command) {
2285   auto command_view =
2286       bluetooth::hci::LeReadResolvingListSizeView::Create(command);
2287   CHECK_PACKET_VIEW(command_view);
2288 
2289   DEBUG(id_, "<< LE Read Resolving List Size");
2290 
2291   send_event_(bluetooth::hci::LeReadResolvingListSizeCompleteBuilder::Create(
2292       kNumCommandPackets, ErrorCode::SUCCESS,
2293       properties_.le_resolving_list_size));
2294 }
2295 
LeReadPeerResolvableAddress(CommandView command)2296 void DualModeController::LeReadPeerResolvableAddress(CommandView command) {
2297   auto command_view =
2298       bluetooth::hci::LeReadPeerResolvableAddressView::Create(command);
2299   CHECK_PACKET_VIEW(command_view);
2300 
2301   DEBUG(id_, "<< LE Read Peer Resolvable Address");
2302   DEBUG(id_, "   peer_identity_address={}",
2303         command_view.GetPeerIdentityAddress());
2304   DEBUG(id_, "   peer_identity_address_type={}",
2305         bluetooth::hci::PeerAddressTypeText(
2306             command_view.GetPeerIdentityAddressType()));
2307 
2308   Address peer_resolvable_address;
2309   ErrorCode status = link_layer_controller_.LeReadPeerResolvableAddress(
2310       command_view.GetPeerIdentityAddressType(),
2311       command_view.GetPeerIdentityAddress(), &peer_resolvable_address);
2312   send_event_(
2313       bluetooth::hci::LeReadPeerResolvableAddressCompleteBuilder::Create(
2314           kNumCommandPackets, status, peer_resolvable_address));
2315 }
2316 
LeReadLocalResolvableAddress(CommandView command)2317 void DualModeController::LeReadLocalResolvableAddress(CommandView command) {
2318   auto command_view =
2319       bluetooth::hci::LeReadLocalResolvableAddressView::Create(command);
2320   CHECK_PACKET_VIEW(command_view);
2321 
2322   DEBUG(id_, "<< LE Read Local Resolvable Address");
2323   DEBUG(id_, "   peer_identity_address={}",
2324         command_view.GetPeerIdentityAddress());
2325   DEBUG(id_, "   peer_identity_address_type={}",
2326         bluetooth::hci::PeerAddressTypeText(
2327             command_view.GetPeerIdentityAddressType()));
2328 
2329   Address local_resolvable_address;
2330   ErrorCode status = link_layer_controller_.LeReadLocalResolvableAddress(
2331       command_view.GetPeerIdentityAddressType(),
2332       command_view.GetPeerIdentityAddress(), &local_resolvable_address);
2333   send_event_(
2334       bluetooth::hci::LeReadLocalResolvableAddressCompleteBuilder::Create(
2335           kNumCommandPackets, status, local_resolvable_address));
2336 }
2337 
LeReadMaximumDataLength(CommandView command)2338 void DualModeController::LeReadMaximumDataLength(CommandView command) {
2339   auto command_view =
2340       bluetooth::hci::LeReadMaximumDataLengthView::Create(command);
2341   CHECK_PACKET_VIEW(command_view);
2342 
2343   DEBUG(id_, "<< LE Read Maximum Data Length");
2344 
2345   bluetooth::hci::LeMaximumDataLength data_length;
2346   data_length.supported_max_rx_octets_ = kLeMaximumDataLength;
2347   data_length.supported_max_rx_time_ = kLeMaximumDataTime;
2348   data_length.supported_max_tx_octets_ = kLeMaximumDataLength + 10;
2349   data_length.supported_max_tx_time_ = kLeMaximumDataTime + 10;
2350   send_event_(bluetooth::hci::LeReadMaximumDataLengthCompleteBuilder::Create(
2351       kNumCommandPackets, ErrorCode::SUCCESS, data_length));
2352 }
2353 
LeReadPhy(CommandView command)2354 void DualModeController::LeReadPhy(CommandView command) {
2355   auto command_view = bluetooth::hci::LeReadPhyView::Create(command);
2356   CHECK_PACKET_VIEW(command_view);
2357   uint16_t connection_handle = command_view.GetConnectionHandle();
2358 
2359   DEBUG(id_, "<< LE Read Phy");
2360   DEBUG(id_, "   connection_handle=0x{:x}", command_view.GetConnectionHandle());
2361 
2362   bluetooth::hci::PhyType tx_phy{};
2363   bluetooth::hci::PhyType rx_phy{};
2364   ErrorCode status =
2365       link_layer_controller_.LeReadPhy(connection_handle, &tx_phy, &rx_phy);
2366   send_event_(bluetooth::hci::LeReadPhyCompleteBuilder::Create(
2367       kNumCommandPackets, status, connection_handle, tx_phy, rx_phy));
2368 }
2369 
LeSetDefaultPhy(CommandView command)2370 void DualModeController::LeSetDefaultPhy(CommandView command) {
2371   auto command_view = bluetooth::hci::LeSetDefaultPhyView::Create(command);
2372   CHECK_PACKET_VIEW(command_view);
2373 
2374   DEBUG(id_, "<< LE Set Default Phy");
2375 
2376   ErrorCode status = link_layer_controller_.LeSetDefaultPhy(
2377       command_view.GetAllPhysNoTransmitPreference(),
2378       command_view.GetAllPhysNoReceivePreference(), command_view.GetTxPhys(),
2379       command_view.GetRxPhys());
2380   send_event_(bluetooth::hci::LeSetDefaultPhyCompleteBuilder::Create(
2381       kNumCommandPackets, status));
2382 }
2383 
LeSetPhy(CommandView command)2384 void DualModeController::LeSetPhy(CommandView command) {
2385   auto command_view = bluetooth::hci::LeSetPhyView::Create(command);
2386   CHECK_PACKET_VIEW(command_view);
2387 
2388   DEBUG(id_, "<< LE Set Phy");
2389   DEBUG(id_, "   connection_handle=0x{:x}", command_view.GetConnectionHandle());
2390 
2391   ErrorCode status = link_layer_controller_.LeSetPhy(
2392       command_view.GetConnectionHandle(),
2393       command_view.GetAllPhysNoTransmitPreference(),
2394       command_view.GetAllPhysNoReceivePreference(), command_view.GetTxPhys(),
2395       command_view.GetRxPhys(), command_view.GetPhyOptions());
2396   send_event_(bluetooth::hci::LeSetPhyStatusBuilder::Create(
2397       status, kNumCommandPackets));
2398 }
2399 
LeReadSuggestedDefaultDataLength(CommandView command)2400 void DualModeController::LeReadSuggestedDefaultDataLength(CommandView command) {
2401   auto command_view =
2402       bluetooth::hci::LeReadSuggestedDefaultDataLengthView::Create(command);
2403   CHECK_PACKET_VIEW(command_view);
2404 
2405   DEBUG(id_, "<< LE Read Suggested Default Data Length");
2406 
2407   send_event_(
2408       bluetooth::hci::LeReadSuggestedDefaultDataLengthCompleteBuilder::Create(
2409           kNumCommandPackets, ErrorCode::SUCCESS,
2410           link_layer_controller_.GetLeSuggestedMaxTxOctets(),
2411           link_layer_controller_.GetLeSuggestedMaxTxTime()));
2412 }
2413 
LeWriteSuggestedDefaultDataLength(CommandView command)2414 void DualModeController::LeWriteSuggestedDefaultDataLength(
2415     CommandView command) {
2416   auto command_view =
2417       bluetooth::hci::LeWriteSuggestedDefaultDataLengthView::Create(command);
2418   CHECK_PACKET_VIEW(command_view);
2419 
2420   DEBUG(id_, "<< LE Write Suggested Default Data Length");
2421 
2422   uint16_t max_tx_octets = command_view.GetTxOctets();
2423   uint16_t max_tx_time = command_view.GetTxTime();
2424   ErrorCode status = ErrorCode::SUCCESS;
2425   if (max_tx_octets > 0xFB || max_tx_octets < 0x1B || max_tx_time < 0x148 ||
2426       max_tx_time > 0x4290) {
2427     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
2428   } else {
2429     link_layer_controller_.SetLeSuggestedMaxTxOctets(max_tx_octets);
2430     link_layer_controller_.SetLeSuggestedMaxTxTime(max_tx_time);
2431   }
2432 
2433   send_event_(
2434       bluetooth::hci::LeWriteSuggestedDefaultDataLengthCompleteBuilder::Create(
2435           kNumCommandPackets, status));
2436 }
2437 
LeAddDeviceToResolvingList(CommandView command)2438 void DualModeController::LeAddDeviceToResolvingList(CommandView command) {
2439   auto command_view =
2440       bluetooth::hci::LeAddDeviceToResolvingListView::Create(command);
2441   CHECK_PACKET_VIEW(command_view);
2442 
2443   DEBUG(id_, "<< LE Add Device to Resolving List");
2444   DEBUG(id_, "   peer_identity_address={}",
2445         command_view.GetPeerIdentityAddress());
2446   DEBUG(id_, "   peer_identity_address_type={}",
2447         bluetooth::hci::PeerAddressTypeText(
2448             command_view.GetPeerIdentityAddressType()));
2449 
2450   ErrorCode status = link_layer_controller_.LeAddDeviceToResolvingList(
2451       command_view.GetPeerIdentityAddressType(),
2452       command_view.GetPeerIdentityAddress(), command_view.GetPeerIrk(),
2453       command_view.GetLocalIrk());
2454   send_event_(bluetooth::hci::LeAddDeviceToResolvingListCompleteBuilder::Create(
2455       kNumCommandPackets, status));
2456 }
2457 
LeRemoveDeviceFromResolvingList(CommandView command)2458 void DualModeController::LeRemoveDeviceFromResolvingList(CommandView command) {
2459   auto command_view =
2460       bluetooth::hci::LeRemoveDeviceFromResolvingListView::Create(command);
2461   CHECK_PACKET_VIEW(command_view);
2462 
2463   DEBUG(id_, "<< LE Remove Device from Resolving List");
2464   DEBUG(id_, "   peer_identity_address={}",
2465         command_view.GetPeerIdentityAddress());
2466   DEBUG(id_, "   peer_identity_address_type={}",
2467         bluetooth::hci::PeerAddressTypeText(
2468             command_view.GetPeerIdentityAddressType()));
2469 
2470   ErrorCode status = link_layer_controller_.LeRemoveDeviceFromResolvingList(
2471       command_view.GetPeerIdentityAddressType(),
2472       command_view.GetPeerIdentityAddress());
2473   send_event_(
2474       bluetooth::hci::LeRemoveDeviceFromResolvingListCompleteBuilder::Create(
2475           kNumCommandPackets, status));
2476 }
2477 
LeSetPeriodicAdvertisingParameters(CommandView command)2478 void DualModeController::LeSetPeriodicAdvertisingParameters(
2479     CommandView command) {
2480   auto command_view =
2481       bluetooth::hci::LeSetPeriodicAdvertisingParametersView::Create(command);
2482   CHECK_PACKET_VIEW(command_view);
2483 
2484   DEBUG(id_, "<< LE Set Periodic Advertising Parameters");
2485   DEBUG(id_, "   advertising_handle={}", command_view.GetAdvertisingHandle());
2486 
2487   ErrorCode status = link_layer_controller_.LeSetPeriodicAdvertisingParameters(
2488       command_view.GetAdvertisingHandle(),
2489       command_view.GetPeriodicAdvertisingIntervalMin(),
2490       command_view.GetPeriodicAdvertisingIntervalMax(),
2491       command_view.GetIncludeTxPower());
2492   send_event_(
2493       bluetooth::hci::LeSetPeriodicAdvertisingParametersCompleteBuilder::Create(
2494           kNumCommandPackets, status));
2495 }
2496 
LeSetPeriodicAdvertisingData(CommandView command)2497 void DualModeController::LeSetPeriodicAdvertisingData(CommandView command) {
2498   auto command_view =
2499       bluetooth::hci::LeSetPeriodicAdvertisingDataView::Create(command);
2500   CHECK_PACKET_VIEW(command_view);
2501 
2502   DEBUG(id_, "<< LE Set Periodic Advertising Data");
2503   DEBUG(id_, "   advertising_handle={}", command_view.GetAdvertisingHandle());
2504 
2505   ErrorCode status = link_layer_controller_.LeSetPeriodicAdvertisingData(
2506       command_view.GetAdvertisingHandle(), command_view.GetOperation(),
2507       command_view.GetAdvertisingData());
2508   send_event_(
2509       bluetooth::hci::LeSetPeriodicAdvertisingDataCompleteBuilder::Create(
2510           kNumCommandPackets, status));
2511 }
2512 
LeSetPeriodicAdvertisingEnable(CommandView command)2513 void DualModeController::LeSetPeriodicAdvertisingEnable(CommandView command) {
2514   auto command_view =
2515       bluetooth::hci::LeSetPeriodicAdvertisingEnableView::Create(command);
2516   CHECK_PACKET_VIEW(command_view);
2517 
2518   DEBUG(id_, "<< LE Set Periodic Advertising Enable");
2519   DEBUG(id_, "   advertising_handle={}", command_view.GetAdvertisingHandle());
2520   DEBUG(id_, "   enable={}", command_view.GetEnable() != 0);
2521 
2522   ErrorCode status = link_layer_controller_.LeSetPeriodicAdvertisingEnable(
2523       command_view.GetEnable(), command_view.GetIncludeAdi(),
2524       command_view.GetAdvertisingHandle());
2525   send_event_(
2526       bluetooth::hci::LeSetPeriodicAdvertisingEnableCompleteBuilder::Create(
2527           kNumCommandPackets, status));
2528 }
2529 
LePeriodicAdvertisingCreateSync(CommandView command)2530 void DualModeController::LePeriodicAdvertisingCreateSync(CommandView command) {
2531   auto command_view =
2532       bluetooth::hci::LePeriodicAdvertisingCreateSyncView::Create(command);
2533   CHECK_PACKET_VIEW(command_view);
2534 
2535   DEBUG(id_, "<< LE Periodic Advertising Create Sync");
2536   DEBUG(id_, "   advertiser_address={}", command_view.GetAdvertiserAddress());
2537   DEBUG(id_, "   advertiser_address_type={}",
2538         bluetooth::hci::AdvertiserAddressTypeText(
2539             command_view.GetAdvertiserAddressType()));
2540 
2541   ErrorCode status = link_layer_controller_.LePeriodicAdvertisingCreateSync(
2542       command_view.GetOptions(), command_view.GetAdvertisingSid(),
2543       command_view.GetAdvertiserAddressType(),
2544       command_view.GetAdvertiserAddress(), command_view.GetSkip(),
2545       command_view.GetSyncTimeout(), command_view.GetSyncCteType());
2546   send_event_(
2547       bluetooth::hci::LePeriodicAdvertisingCreateSyncStatusBuilder::Create(
2548           status, kNumCommandPackets));
2549 }
2550 
LePeriodicAdvertisingCreateSyncCancel(CommandView command)2551 void DualModeController::LePeriodicAdvertisingCreateSyncCancel(
2552     CommandView command) {
2553   auto command_view =
2554       bluetooth::hci::LePeriodicAdvertisingCreateSyncCancelView::Create(
2555           command);
2556   CHECK_PACKET_VIEW(command_view);
2557 
2558   DEBUG(id_, "<< LE Periodic Advertising Create Sync Cancel");
2559 
2560   ErrorCode status =
2561       link_layer_controller_.LePeriodicAdvertisingCreateSyncCancel();
2562   send_event_(
2563       bluetooth::hci::LePeriodicAdvertisingCreateSyncCancelCompleteBuilder::
2564           Create(kNumCommandPackets, status));
2565 }
2566 
LePeriodicAdvertisingTerminateSync(CommandView command)2567 void DualModeController::LePeriodicAdvertisingTerminateSync(
2568     CommandView command) {
2569   auto command_view =
2570       bluetooth::hci::LePeriodicAdvertisingTerminateSyncView::Create(command);
2571   CHECK_PACKET_VIEW(command_view);
2572 
2573   DEBUG(id_, "<< LE Periodic Advertising Terminate Sync");
2574   DEBUG(id_, "   sync_handle=0x{:x}", command_view.GetSyncHandle());
2575 
2576   ErrorCode status = link_layer_controller_.LePeriodicAdvertisingTerminateSync(
2577       command_view.GetSyncHandle());
2578   send_event_(
2579       bluetooth::hci::LePeriodicAdvertisingTerminateSyncCompleteBuilder::Create(
2580           kNumCommandPackets, status));
2581 }
2582 
LeAddDeviceToPeriodicAdvertiserList(CommandView command)2583 void DualModeController::LeAddDeviceToPeriodicAdvertiserList(
2584     CommandView command) {
2585   auto command_view =
2586       bluetooth::hci::LeAddDeviceToPeriodicAdvertiserListView::Create(command);
2587   CHECK_PACKET_VIEW(command_view);
2588 
2589   DEBUG(id_, "<< LE Add Device to Periodic Advertiser List");
2590   DEBUG(id_, "   advertiser_address={}", command_view.GetAdvertiserAddress());
2591   DEBUG(id_, "   advertiser_address_type={}",
2592         bluetooth::hci::AdvertiserAddressTypeText(
2593             command_view.GetAdvertiserAddressType()));
2594 
2595   ErrorCode status = link_layer_controller_.LeAddDeviceToPeriodicAdvertiserList(
2596       command_view.GetAdvertiserAddressType(),
2597       command_view.GetAdvertiserAddress(), command_view.GetAdvertisingSid());
2598   send_event_(
2599       bluetooth::hci::LeAddDeviceToPeriodicAdvertiserListCompleteBuilder::
2600           Create(kNumCommandPackets, status));
2601 }
2602 
LeRemoveDeviceFromPeriodicAdvertiserList(CommandView command)2603 void DualModeController::LeRemoveDeviceFromPeriodicAdvertiserList(
2604     CommandView command) {
2605   auto command_view =
2606       bluetooth::hci::LeRemoveDeviceFromPeriodicAdvertiserListView::Create(
2607           command);
2608   CHECK_PACKET_VIEW(command_view);
2609 
2610   DEBUG(id_, "<< LE Remove Device from Periodic Advertiser List");
2611   DEBUG(id_, "   advertiser_address={}", command_view.GetAdvertiserAddress());
2612   DEBUG(id_, "   advertiser_address_type={}",
2613         bluetooth::hci::AdvertiserAddressTypeText(
2614             command_view.GetAdvertiserAddressType()));
2615 
2616   ErrorCode status =
2617       link_layer_controller_.LeRemoveDeviceFromPeriodicAdvertiserList(
2618           command_view.GetAdvertiserAddressType(),
2619           command_view.GetAdvertiserAddress(),
2620           command_view.GetAdvertisingSid());
2621   send_event_(
2622       bluetooth::hci::LeRemoveDeviceFromPeriodicAdvertiserListCompleteBuilder::
2623           Create(kNumCommandPackets, status));
2624 }
2625 
LeClearPeriodicAdvertiserList(CommandView command)2626 void DualModeController::LeClearPeriodicAdvertiserList(CommandView command) {
2627   auto command_view =
2628       bluetooth::hci::LeClearPeriodicAdvertiserListView::Create(command);
2629   CHECK_PACKET_VIEW(command_view);
2630 
2631   DEBUG(id_, "<< LE Clear Periodic Advertiser List");
2632 
2633   ErrorCode status = link_layer_controller_.LeClearPeriodicAdvertiserList();
2634   send_event_(
2635       bluetooth::hci::LeClearPeriodicAdvertiserListCompleteBuilder::Create(
2636           kNumCommandPackets, status));
2637 }
2638 
LeReadPeriodicAdvertiserListSize(CommandView command)2639 void DualModeController::LeReadPeriodicAdvertiserListSize(CommandView command) {
2640   auto command_view =
2641       bluetooth::hci::LeReadPeriodicAdvertiserListSizeView::Create(command);
2642   CHECK_PACKET_VIEW(command_view);
2643 
2644   DEBUG(id_, "<< LE Read Periodic Advertiser List Size");
2645 
2646   send_event_(
2647       bluetooth::hci::LeReadPeriodicAdvertiserListSizeCompleteBuilder::Create(
2648           kNumCommandPackets, ErrorCode::SUCCESS,
2649           properties_.le_periodic_advertiser_list_size));
2650 }
2651 
LeSetExtendedScanParameters(CommandView command)2652 void DualModeController::LeSetExtendedScanParameters(CommandView command) {
2653   auto command_view =
2654       bluetooth::hci::LeSetExtendedScanParametersView::Create(command);
2655   CHECK_PACKET_VIEW(command_view);
2656 
2657   DEBUG(id_, "<< LE Set Extended Scan Parameters");
2658 
2659   ErrorCode status = link_layer_controller_.LeSetExtendedScanParameters(
2660       command_view.GetOwnAddressType(), command_view.GetScanningFilterPolicy(),
2661       command_view.GetScanningPhys(), command_view.GetScanningPhyParameters());
2662   send_event_(
2663       bluetooth::hci::LeSetExtendedScanParametersCompleteBuilder::Create(
2664           kNumCommandPackets, status));
2665 }
2666 
LeSetExtendedScanEnable(CommandView command)2667 void DualModeController::LeSetExtendedScanEnable(CommandView command) {
2668   auto command_view =
2669       bluetooth::hci::LeSetExtendedScanEnableView::Create(command);
2670   CHECK_PACKET_VIEW(command_view);
2671 
2672   DEBUG(id_, "<< LE Set Extended Scan Enable");
2673   DEBUG(id_, "   enable={}",
2674         command_view.GetEnable() == bluetooth::hci::Enable::ENABLED);
2675 
2676   ErrorCode status = link_layer_controller_.LeSetExtendedScanEnable(
2677       command_view.GetEnable() == bluetooth::hci::Enable::ENABLED,
2678       command_view.GetFilterDuplicates(), command_view.GetDuration(),
2679       command_view.GetPeriod());
2680   send_event_(bluetooth::hci::LeSetExtendedScanEnableCompleteBuilder::Create(
2681       kNumCommandPackets, status));
2682 }
2683 
LeExtendedCreateConnection(CommandView command)2684 void DualModeController::LeExtendedCreateConnection(CommandView command) {
2685   auto command_view =
2686       bluetooth::hci::LeExtendedCreateConnectionView::Create(command);
2687   CHECK_PACKET_VIEW(command_view);
2688 
2689   DEBUG(id_, "<< LE Extended Create Connection");
2690   DEBUG(id_, "   peer_address={}", command_view.GetPeerAddress());
2691   DEBUG(id_, "   peer_address_type={}",
2692         bluetooth::hci::PeerAddressTypeText(command_view.GetPeerAddressType()));
2693   DEBUG(id_, "   initiator_filter_policy={}",
2694         bluetooth::hci::InitiatorFilterPolicyText(
2695             command_view.GetInitiatorFilterPolicy()));
2696 
2697   AddressType peer_address_type;
2698   switch (command_view.GetPeerAddressType()) {
2699     case PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS:
2700     default:
2701       peer_address_type = AddressType::PUBLIC_DEVICE_ADDRESS;
2702       break;
2703     case PeerAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS:
2704       peer_address_type = AddressType::RANDOM_DEVICE_ADDRESS;
2705       break;
2706   }
2707 
2708   ErrorCode status = link_layer_controller_.LeExtendedCreateConnection(
2709       command_view.GetInitiatorFilterPolicy(), command_view.GetOwnAddressType(),
2710       AddressWithType{
2711           command_view.GetPeerAddress(),
2712           peer_address_type,
2713       },
2714       command_view.GetInitiatingPhys(),
2715       command_view.GetInitiatingPhyParameters());
2716   send_event_(bluetooth::hci::LeExtendedCreateConnectionStatusBuilder::Create(
2717       status, kNumCommandPackets));
2718 }
2719 
LeSetPrivacyMode(CommandView command)2720 void DualModeController::LeSetPrivacyMode(CommandView command) {
2721   auto command_view = bluetooth::hci::LeSetPrivacyModeView::Create(command);
2722   CHECK_PACKET_VIEW(command_view);
2723 
2724   DEBUG(id_, "<< LE Set Privacy Mode");
2725   DEBUG(id_, "   peer_identity_address={}",
2726         command_view.GetPeerIdentityAddress());
2727   DEBUG(id_, "   peer_identity_address_type={}",
2728         bluetooth::hci::PeerAddressTypeText(
2729             command_view.GetPeerIdentityAddressType()));
2730   DEBUG(id_, "   privacy_mode={}",
2731         bluetooth::hci::PrivacyModeText(command_view.GetPrivacyMode()));
2732 
2733   ErrorCode status = link_layer_controller_.LeSetPrivacyMode(
2734       command_view.GetPeerIdentityAddressType(),
2735       command_view.GetPeerIdentityAddress(), command_view.GetPrivacyMode());
2736   send_event_(bluetooth::hci::LeSetPrivacyModeCompleteBuilder::Create(
2737       kNumCommandPackets, status));
2738 }
2739 
LeReadRemoteFeatures(CommandView command)2740 void DualModeController::LeReadRemoteFeatures(CommandView command) {
2741   auto command_view = bluetooth::hci::LeReadRemoteFeaturesView::Create(command);
2742   CHECK_PACKET_VIEW(command_view);
2743   uint16_t handle = command_view.GetConnectionHandle();
2744 
2745   DEBUG(id_, "<< LE Read Remote Features");
2746   DEBUG(id_, "   connection_handle=0x{:x}", handle);
2747 
2748   auto status = link_layer_controller_.SendCommandToRemoteByHandle(
2749       OpCode::LE_READ_REMOTE_FEATURES, command_view.bytes(), handle);
2750 
2751   send_event_(bluetooth::hci::LeReadRemoteFeaturesStatusBuilder::Create(
2752       status, kNumCommandPackets));
2753 }
2754 
LeEncrypt(CommandView command)2755 void DualModeController::LeEncrypt(CommandView command) {
2756   auto command_view = bluetooth::hci::LeEncryptView::Create(command);
2757   CHECK_PACKET_VIEW(command_view);
2758 
2759   DEBUG(id_, "<< LE Encrypt");
2760 
2761   auto encrypted_data = rootcanal::crypto::aes_128(
2762       command_view.GetKey(), command_view.GetPlaintextData());
2763 
2764   send_event_(bluetooth::hci::LeEncryptCompleteBuilder::Create(
2765       kNumCommandPackets, ErrorCode::SUCCESS, encrypted_data));
2766 }
2767 
LeRand(CommandView command)2768 void DualModeController::LeRand(CommandView command) {
2769   auto command_view = bluetooth::hci::LeRandView::Create(command);
2770   CHECK_PACKET_VIEW(command_view);
2771 
2772   DEBUG(id_, "<< LE Rand");
2773 
2774   send_event_(bluetooth::hci::LeRandCompleteBuilder::Create(
2775       kNumCommandPackets, ErrorCode::SUCCESS, random_generator_()));
2776 }
2777 
LeReadSupportedStates(CommandView command)2778 void DualModeController::LeReadSupportedStates(CommandView command) {
2779   auto command_view =
2780       bluetooth::hci::LeReadSupportedStatesView::Create(command);
2781   CHECK_PACKET_VIEW(command_view);
2782 
2783   DEBUG(id_, "<< LE Read Supported States");
2784 
2785   send_event_(bluetooth::hci::LeReadSupportedStatesCompleteBuilder::Create(
2786       kNumCommandPackets, ErrorCode::SUCCESS, properties_.le_supported_states));
2787 }
2788 
LeRemoteConnectionParameterRequestReply(CommandView command)2789 void DualModeController::LeRemoteConnectionParameterRequestReply(
2790     CommandView command) {
2791   auto command_view =
2792       bluetooth::hci::LeRemoteConnectionParameterRequestReplyView::Create(
2793           command);
2794   CHECK_PACKET_VIEW(command_view);
2795 
2796   DEBUG(id_, "<< LE Remote Connection Parameters Request Reply");
2797   DEBUG(id_, "   connection_handle=0x{:x}", command_view.GetConnectionHandle());
2798 
2799   auto status = link_layer_controller_.LeRemoteConnectionParameterRequestReply(
2800       command_view.GetConnectionHandle(), command_view.GetIntervalMin(),
2801       command_view.GetIntervalMax(), command_view.GetTimeout(),
2802       command_view.GetLatency(), command_view.GetMinimumCeLength(),
2803       command_view.GetMaximumCeLength());
2804   send_event_(
2805       bluetooth::hci::LeRemoteConnectionParameterRequestReplyCompleteBuilder::
2806           Create(kNumCommandPackets, status,
2807                  command_view.GetConnectionHandle()));
2808 }
2809 
LeRemoteConnectionParameterRequestNegativeReply(CommandView command)2810 void DualModeController::LeRemoteConnectionParameterRequestNegativeReply(
2811     CommandView command) {
2812   auto command_view = bluetooth::hci::
2813       LeRemoteConnectionParameterRequestNegativeReplyView::Create(command);
2814   CHECK_PACKET_VIEW(command_view);
2815 
2816   DEBUG(id_, "<< LE Remote Connection Parameters Request Negative Reply");
2817   DEBUG(id_, "   connection_handle=0x{:x}", command_view.GetConnectionHandle());
2818 
2819   auto status =
2820       link_layer_controller_.LeRemoteConnectionParameterRequestNegativeReply(
2821           command_view.GetConnectionHandle(), command_view.GetReason());
2822   send_event_(
2823       bluetooth::hci::
2824           LeRemoteConnectionParameterRequestNegativeReplyCompleteBuilder::
2825               Create(kNumCommandPackets, status,
2826                      command_view.GetConnectionHandle()));
2827 }
2828 
LeGetVendorCapabilities(CommandView command)2829 void DualModeController::LeGetVendorCapabilities(CommandView command) {
2830   auto command_view =
2831       bluetooth::hci::LeGetVendorCapabilitiesView::Create(command);
2832   CHECK_PACKET_VIEW(command_view);
2833 
2834   if (!properties_.supports_le_get_vendor_capabilities_command) {
2835     SendCommandCompleteUnknownOpCodeEvent(OpCode::LE_GET_VENDOR_CAPABILITIES);
2836     return;
2837   }
2838 
2839   DEBUG(id_, "<< LE Get Vendor Capabilities");
2840 
2841   bluetooth::hci::VendorCapabilities_V_0_98 vendor_capabilities;
2842   vendor_capabilities.total_scan_results_storage_ = 0;
2843   vendor_capabilities.max_irk_list_sz_ = 16;
2844   vendor_capabilities.filtering_support_ =
2845       properties_.supports_le_apcf_vendor_command;
2846   vendor_capabilities.max_filter_ = properties_.le_apcf_filter_list_size;
2847   vendor_capabilities.activity_energy_info_support_ = 0;
2848   vendor_capabilities.total_num_of_advt_tracked_ =
2849       properties_.le_apcf_num_of_tracked_advertisers;
2850   vendor_capabilities.extended_scan_support_ = 0;
2851   vendor_capabilities.debug_logging_supported_ = 0;
2852   vendor_capabilities.a2dp_source_offload_capability_mask_ = 0;
2853   vendor_capabilities.bluetooth_quality_report_support_ = 0;
2854 
2855   send_event_(bluetooth::hci::LeGetVendorCapabilitiesCompleteBuilder::Create(
2856       kNumCommandPackets, ErrorCode::SUCCESS,
2857       vendor_capabilities.SerializeToBytes()));
2858 }
2859 
LeBatchScan(CommandView command)2860 void DualModeController::LeBatchScan(CommandView command) {
2861   auto command_view = bluetooth::hci::LeBatchScanView::Create(command);
2862   CHECK_PACKET_VIEW(command_view);
2863   SendCommandCompleteUnknownOpCodeEvent(OpCode::LE_BATCH_SCAN);
2864 }
2865 
LeApcf(CommandView command)2866 void DualModeController::LeApcf(CommandView command) {
2867   auto command_view = bluetooth::hci::LeApcfView::Create(command);
2868   CHECK_PACKET_VIEW(command_view);
2869 
2870   if (!properties_.supports_le_apcf_vendor_command) {
2871     SendCommandCompleteUnknownOpCodeEvent(OpCode::LE_APCF);
2872     return;
2873   }
2874 
2875   switch (command_view.GetApcfOpcode()) {
2876     case bluetooth::hci::ApcfOpcode::ENABLE: {
2877       auto subcommand_view =
2878           bluetooth::hci::LeApcfEnableView::Create(command_view);
2879       CHECK_PACKET_VIEW(subcommand_view);
2880 
2881       DEBUG(id_, "<< LE APCF Enable");
2882       DEBUG(id_, "   enable={}",
2883             bluetooth::hci::EnableText(subcommand_view.GetApcfEnable()));
2884 
2885       ErrorCode status = link_layer_controller_.LeApcfEnable(
2886           subcommand_view.GetApcfEnable() == bluetooth::hci::Enable::ENABLED);
2887       send_event_(bluetooth::hci::LeApcfEnableCompleteBuilder::Create(
2888           kNumCommandPackets, status, subcommand_view.GetApcfEnable()));
2889       break;
2890     }
2891     case bluetooth::hci::ApcfOpcode::SET_FILTERING_PARAMETERS: {
2892       auto subcommand_view =
2893           bluetooth::hci::LeApcfSetFilteringParametersView::Create(
2894               command_view);
2895       CHECK_PACKET_VIEW(subcommand_view);
2896 
2897       DEBUG(id_, "<< LE APCF Set Filtering Parameters");
2898       DEBUG(id_, "   action={}",
2899             bluetooth::hci::ApcfActionText(subcommand_view.GetApcfAction()));
2900 
2901       ErrorCode status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
2902       uint8_t apcf_available_spaces = 0;
2903 
2904       switch (subcommand_view.GetApcfAction()) {
2905         case bluetooth::hci::ApcfAction::ADD: {
2906           auto subsubcommand_view =
2907               bluetooth::hci::LeApcfAddFilteringParametersView::Create(
2908                   subcommand_view);
2909           CHECK_PACKET_VIEW(subcommand_view);
2910           status = link_layer_controller_.LeApcfAddFilteringParameters(
2911               subsubcommand_view.GetApcfFilterIndex(),
2912               subsubcommand_view.GetApcfFeatureSelection(),
2913               subsubcommand_view.GetApcfListLogicType(),
2914               subsubcommand_view.GetApcfFilterLogicType(),
2915               subsubcommand_view.GetRssiHighThresh(),
2916               subsubcommand_view.GetDeliveryMode(),
2917               subsubcommand_view.GetOnfoundTimeout(),
2918               subsubcommand_view.GetOnfoundTimeoutCnt(),
2919               subsubcommand_view.GetRssiLowThresh(),
2920               subsubcommand_view.GetOnlostTimeout(),
2921               subsubcommand_view.GetNumOfTrackingEntries(),
2922               &apcf_available_spaces);
2923           break;
2924         }
2925         case bluetooth::hci::ApcfAction::DELETE: {
2926           auto subsubcommand_view =
2927               bluetooth::hci::LeApcfDeleteFilteringParametersView::Create(
2928                   subcommand_view);
2929           CHECK_PACKET_VIEW(subcommand_view);
2930           status = link_layer_controller_.LeApcfDeleteFilteringParameters(
2931               subsubcommand_view.GetApcfFilterIndex(), &apcf_available_spaces);
2932           break;
2933         }
2934         case bluetooth::hci::ApcfAction::CLEAR: {
2935           auto subsubcommand_view =
2936               bluetooth::hci::LeApcfClearFilteringParametersView::Create(
2937                   subcommand_view);
2938           CHECK_PACKET_VIEW(subcommand_view);
2939           status = link_layer_controller_.LeApcfClearFilteringParameters(
2940               &apcf_available_spaces);
2941           break;
2942         }
2943         default:
2944           INFO(id_, "unknown apcf action {}",
2945                bluetooth::hci::ApcfActionText(subcommand_view.GetApcfAction()));
2946           break;
2947       }
2948 
2949       send_event_(
2950           bluetooth::hci::LeApcfSetFilteringParametersCompleteBuilder::Create(
2951               kNumCommandPackets, status, subcommand_view.GetApcfAction(),
2952               apcf_available_spaces));
2953       break;
2954     }
2955     case bluetooth::hci::ApcfOpcode::BROADCASTER_ADDRESS: {
2956       auto subcommand_view =
2957           bluetooth::hci::LeApcfBroadcasterAddressView::Create(command_view);
2958       CHECK_PACKET_VIEW(subcommand_view);
2959 
2960       DEBUG(id_, "<< LE APCF Broadcaster Address");
2961       DEBUG(id_, "   action={}",
2962             bluetooth::hci::ApcfActionText(subcommand_view.GetApcfAction()));
2963 
2964       ErrorCode status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
2965       uint8_t apcf_available_spaces = 0;
2966 
2967       switch (subcommand_view.GetApcfAction()) {
2968         case bluetooth::hci::ApcfAction::ADD: {
2969           auto subsubcommand_view =
2970               bluetooth::hci::LeApcfAddBroadcasterAddressView::Create(
2971                   subcommand_view);
2972           CHECK_PACKET_VIEW(subcommand_view);
2973           status = link_layer_controller_.LeApcfBroadcasterAddress(
2974               bluetooth::hci::ApcfAction::ADD,
2975               subsubcommand_view.GetApcfFilterIndex(),
2976               subsubcommand_view.GetApcfBroadcasterAddress(),
2977               subsubcommand_view.GetApcfApplicationAddressType(),
2978               &apcf_available_spaces);
2979           break;
2980         }
2981         case bluetooth::hci::ApcfAction::DELETE: {
2982           auto subsubcommand_view =
2983               bluetooth::hci::LeApcfDeleteBroadcasterAddressView::Create(
2984                   subcommand_view);
2985           CHECK_PACKET_VIEW(subcommand_view);
2986           status = link_layer_controller_.LeApcfBroadcasterAddress(
2987               bluetooth::hci::ApcfAction::DELETE,
2988               subsubcommand_view.GetApcfFilterIndex(),
2989               subsubcommand_view.GetApcfBroadcasterAddress(),
2990               subsubcommand_view.GetApcfApplicationAddressType(),
2991               &apcf_available_spaces);
2992           break;
2993         }
2994         case bluetooth::hci::ApcfAction::CLEAR: {
2995           auto subsubcommand_view =
2996               bluetooth::hci::LeApcfClearBroadcasterAddressView::Create(
2997                   subcommand_view);
2998           CHECK_PACKET_VIEW(subcommand_view);
2999           status = link_layer_controller_.LeApcfBroadcasterAddress(
3000               bluetooth::hci::ApcfAction::CLEAR,
3001               subsubcommand_view.GetApcfFilterIndex(), Address(),
3002               bluetooth::hci::ApcfApplicationAddressType::NOT_APPLICABLE,
3003               &apcf_available_spaces);
3004           break;
3005         }
3006         default:
3007           INFO(id_, "unknown apcf action {}",
3008                bluetooth::hci::ApcfActionText(subcommand_view.GetApcfAction()));
3009           break;
3010       }
3011 
3012       send_event_(
3013           bluetooth::hci::LeApcfBroadcasterAddressCompleteBuilder::Create(
3014               kNumCommandPackets, status, subcommand_view.GetApcfAction(),
3015               apcf_available_spaces));
3016       break;
3017     }
3018     case bluetooth::hci::ApcfOpcode::SERVICE_UUID: {
3019       auto subcommand_view =
3020           bluetooth::hci::LeApcfServiceUuidView::Create(command_view);
3021       CHECK_PACKET_VIEW(subcommand_view);
3022 
3023       DEBUG(id_, "<< LE APCF Service UUID");
3024       DEBUG(id_, "   action={}",
3025             bluetooth::hci::ApcfActionText(subcommand_view.GetApcfAction()));
3026 
3027       uint8_t apcf_available_spaces = 0;
3028       ErrorCode status = link_layer_controller_.LeApcfServiceUuid(
3029           subcommand_view.GetApcfAction(), subcommand_view.GetApcfFilterIndex(),
3030           subcommand_view.GetAcpfUuidData(), &apcf_available_spaces);
3031       send_event_(bluetooth::hci::LeApcfServiceUuidCompleteBuilder::Create(
3032           kNumCommandPackets, status, subcommand_view.GetApcfAction(),
3033           apcf_available_spaces));
3034       break;
3035     }
3036     case bluetooth::hci::ApcfOpcode::SERVICE_SOLICITATION_UUID: {
3037       auto subcommand_view =
3038           bluetooth::hci::LeApcfServiceSolicitationUuidView::Create(
3039               command_view);
3040       CHECK_PACKET_VIEW(subcommand_view);
3041 
3042       DEBUG(id_, "<< LE APCF Service Solicitation UUID");
3043       DEBUG(id_, "   action={}",
3044             bluetooth::hci::ApcfActionText(subcommand_view.GetApcfAction()));
3045 
3046       uint8_t apcf_available_spaces = 0;
3047       ErrorCode status = link_layer_controller_.LeApcfServiceSolicitationUuid(
3048           subcommand_view.GetApcfAction(), subcommand_view.GetApcfFilterIndex(),
3049           subcommand_view.GetAcpfUuidData(), &apcf_available_spaces);
3050       send_event_(
3051           bluetooth::hci::LeApcfServiceSolicitationUuidCompleteBuilder::Create(
3052               kNumCommandPackets, status, subcommand_view.GetApcfAction(),
3053               apcf_available_spaces));
3054       break;
3055     }
3056     case bluetooth::hci::ApcfOpcode::LOCAL_NAME: {
3057       auto subcommand_view =
3058           bluetooth::hci::LeApcfLocalNameView::Create(command_view);
3059       CHECK_PACKET_VIEW(subcommand_view);
3060 
3061       DEBUG(id_, "<< LE APCF Local Name");
3062       DEBUG(id_, "   action={}",
3063             bluetooth::hci::ApcfActionText(subcommand_view.GetApcfAction()));
3064 
3065       uint8_t apcf_available_spaces = 0;
3066       ErrorCode status = link_layer_controller_.LeApcfLocalName(
3067           subcommand_view.GetApcfAction(), subcommand_view.GetApcfFilterIndex(),
3068           subcommand_view.GetApcfLocalName(), &apcf_available_spaces);
3069       send_event_(bluetooth::hci::LeApcfLocalNameCompleteBuilder::Create(
3070           kNumCommandPackets, status, subcommand_view.GetApcfAction(),
3071           apcf_available_spaces));
3072       break;
3073     }
3074     case bluetooth::hci::ApcfOpcode::MANUFACTURER_DATA: {
3075       auto subcommand_view =
3076           bluetooth::hci::LeApcfManufacturerDataView::Create(command_view);
3077       CHECK_PACKET_VIEW(subcommand_view);
3078 
3079       DEBUG(id_, "<< LE APCF Manufacturer Data");
3080       DEBUG(id_, "   action={}",
3081             bluetooth::hci::ApcfActionText(subcommand_view.GetApcfAction()));
3082 
3083       uint8_t apcf_available_spaces = 0;
3084       ErrorCode status = link_layer_controller_.LeApcfManufacturerData(
3085           subcommand_view.GetApcfAction(), subcommand_view.GetApcfFilterIndex(),
3086           subcommand_view.GetApcfManufacturerData(), &apcf_available_spaces);
3087       send_event_(bluetooth::hci::LeApcfManufacturerDataCompleteBuilder::Create(
3088           kNumCommandPackets, status, subcommand_view.GetApcfAction(),
3089           apcf_available_spaces));
3090       break;
3091     }
3092     case bluetooth::hci::ApcfOpcode::SERVICE_DATA: {
3093       auto subcommand_view =
3094           bluetooth::hci::LeApcfServiceDataView::Create(command_view);
3095       CHECK_PACKET_VIEW(subcommand_view);
3096 
3097       DEBUG(id_, "<< LE APCF Service Data");
3098       DEBUG(id_, "   action={}",
3099             bluetooth::hci::ApcfActionText(subcommand_view.GetApcfAction()));
3100 
3101       uint8_t apcf_available_spaces = 0;
3102       ErrorCode status = link_layer_controller_.LeApcfServiceData(
3103           subcommand_view.GetApcfAction(), subcommand_view.GetApcfFilterIndex(),
3104           subcommand_view.GetApcfServiceData(), &apcf_available_spaces);
3105       send_event_(bluetooth::hci::LeApcfServiceDataCompleteBuilder::Create(
3106           kNumCommandPackets, status, subcommand_view.GetApcfAction(),
3107           apcf_available_spaces));
3108       break;
3109     }
3110     case bluetooth::hci::ApcfOpcode::TRANSPORT_DISCOVERY_SERVICE: {
3111       auto subcommand_view =
3112           bluetooth::hci::LeApcfTransportDiscoveryServiceView::Create(command_view);
3113       CHECK_PACKET_VIEW(subcommand_view);
3114 
3115       DEBUG(id_, "<< LE APCF Transport Discovery Service");
3116       DEBUG(id_, "   action={}",
3117             bluetooth::hci::ApcfActionText(subcommand_view.GetApcfAction()));
3118 
3119       send_event_(bluetooth::hci::LeApcfTransportDiscoveryServiceCompleteBuilder::Create(
3120           kNumCommandPackets, ErrorCode::INVALID_HCI_COMMAND_PARAMETERS,
3121           subcommand_view.GetApcfAction(), 0));
3122       break;
3123     }
3124     case bluetooth::hci::ApcfOpcode::AD_TYPE_FILTER: {
3125       auto subcommand_view =
3126           bluetooth::hci::LeApcfAdTypeFilterView::Create(command_view);
3127       CHECK_PACKET_VIEW(subcommand_view);
3128 
3129       DEBUG(id_, "<< LE APCF AD Type Filter");
3130       DEBUG(id_, "   action={}",
3131             bluetooth::hci::ApcfActionText(subcommand_view.GetApcfAction()));
3132 
3133       uint8_t apcf_available_spaces = 0;
3134       ErrorCode status = link_layer_controller_.LeApcfAdTypeFilter(
3135           subcommand_view.GetApcfAction(), subcommand_view.GetApcfFilterIndex(),
3136           subcommand_view.GetApcfAdType(), subcommand_view.GetApcfAdData(),
3137           subcommand_view.GetApcfAdDataMask(), &apcf_available_spaces);
3138       send_event_(bluetooth::hci::LeApcfAdTypeFilterCompleteBuilder::Create(
3139           kNumCommandPackets, status, subcommand_view.GetApcfAction(),
3140           apcf_available_spaces));
3141       break;
3142     }
3143     case bluetooth::hci::ApcfOpcode::READ_EXTENDED_FEATURES: {
3144       auto subcommand_view =
3145           bluetooth::hci::LeApcfReadExtendedFeaturesView::Create(command_view);
3146       CHECK_PACKET_VIEW(subcommand_view);
3147 
3148       DEBUG(id_, "<< LE APCF Read Extended Features");
3149 
3150       send_event_(
3151           bluetooth::hci::LeApcfReadExtendedFeaturesCompleteBuilder::Create(
3152               kNumCommandPackets, ErrorCode::SUCCESS,
3153               kLeApcfTransportDiscoveryDataFilterSupported,
3154               kLeApcfAdTypeFilterSupported));
3155       break;
3156     }
3157     default:
3158       ERROR(id_, "unknown APCF opcode {:#x}",
3159             static_cast<uint8_t>(command_view.GetApcfOpcode()));
3160 
3161       send_event_(bluetooth::hci::LeApcfCompleteBuilder::Create(
3162           kNumCommandPackets, ErrorCode::INVALID_HCI_COMMAND_PARAMETERS,
3163           command_view.GetApcfOpcode(), std::vector<uint8_t>{}));
3164 
3165       invalid_packet_handler_(
3166           id_, InvalidPacketReason::kUnsupported,
3167           fmt::format("unsupported APCF opcode {:#x}",
3168                       static_cast<uint8_t>(command_view.GetApcfOpcode())),
3169           command_view.bytes().bytes());
3170   }
3171 }
3172 
LeGetControllerActivityEnergyInfo(CommandView command)3173 void DualModeController::LeGetControllerActivityEnergyInfo(
3174     CommandView command) {
3175   auto command_view =
3176       bluetooth::hci::LeGetControllerActivityEnergyInfoView::Create(command);
3177   CHECK_PACKET_VIEW(command_view);
3178   SendCommandCompleteUnknownOpCodeEvent(
3179       OpCode::LE_GET_CONTROLLER_ACTIVITY_ENERGY_INFO);
3180 }
3181 
LeExSetScanParameters(CommandView command)3182 void DualModeController::LeExSetScanParameters(CommandView command) {
3183   auto command_view =
3184       bluetooth::hci::LeExSetScanParametersView::Create(command);
3185   CHECK_PACKET_VIEW(command_view);
3186   SendCommandCompleteUnknownOpCodeEvent(OpCode::LE_EX_SET_SCAN_PARAMETERS);
3187 }
3188 
GetControllerDebugInfo(CommandView command)3189 void DualModeController::GetControllerDebugInfo(CommandView command) {
3190   auto command_view =
3191       bluetooth::hci::GetControllerDebugInfoView::Create(command);
3192   CHECK_PACKET_VIEW(command_view);
3193 
3194   DEBUG(id_, "<< Get Controller Debug Info");
3195 
3196   send_event_(bluetooth::hci::GetControllerDebugInfoCompleteBuilder::Create(
3197       kNumCommandPackets, ErrorCode::SUCCESS));
3198 }
3199 
3200 // CSR vendor command.
3201 // Implement the command specific to the CSR controller
3202 // used specifically by the PTS tool to pass certification tests.
CsrVendorCommand(CommandView command)3203 void DualModeController::CsrVendorCommand(CommandView command) {
3204   if (!properties_.supports_csr_vendor_command) {
3205     SendCommandCompleteUnknownOpCodeEvent(OpCode(CSR_VENDOR));
3206     return;
3207   }
3208 
3209   DEBUG(id_, "<< CSR");
3210 
3211   // The byte order is little endian.
3212   // The command parameters are formatted as
3213   //
3214   //  00    | 0xc2
3215   //  01 02 | action
3216   //          read = 0
3217   //          write = 2
3218   //  03 04 | (value length / 2) + 5
3219   //  04 05 | sequence number
3220   //  06 07 | varid
3221   //  08 09 | 00 00
3222   //  0a .. | value
3223   //
3224   // BlueZ has a reference implementation of the CSR vendor command.
3225 
3226   std::vector<uint8_t> parameters(command.GetPayload());
3227 
3228   uint16_t type = 0;
3229   uint16_t length = 0;
3230   uint16_t varid = 0;
3231 
3232   if (parameters.empty()) {
3233     INFO(id_, "Empty CSR vendor command");
3234     goto complete;
3235   }
3236 
3237   if (parameters[0] != 0xc2 || parameters.size() < 11) {
3238     INFO(id_,
3239          "Unsupported CSR vendor command with code {:02x} "
3240          "and parameter length {}",
3241          static_cast<int>(parameters[0]), parameters.size());
3242     goto complete;
3243   }
3244 
3245   type = (uint16_t)parameters[1] | ((uint16_t)parameters[2] << 8);
3246   length = (uint16_t)parameters[3] | ((uint16_t)parameters[4] << 8);
3247   varid = (uint16_t)parameters[7] | ((uint16_t)parameters[8] << 8);
3248   length = 2 * (length - 5);
3249 
3250   if (parameters.size() < (11 + length) ||
3251       (varid == CsrVarid::CSR_VARID_PS && length < 6)) {
3252     INFO(id_, "Invalid CSR vendor command parameter length {}, expected {}",
3253          parameters.size(), 11 + length);
3254     goto complete;
3255   }
3256 
3257   if (varid == CsrVarid::CSR_VARID_PS) {
3258     // Subcommand to read or write PSKEY of the selected identifier
3259     // instead of VARID.
3260     uint16_t pskey = (uint16_t)parameters[11] | ((uint16_t)parameters[12] << 8);
3261     uint16_t length =
3262         (uint16_t)parameters[13] | ((uint16_t)parameters[14] << 8);
3263     length = 2 * length;
3264 
3265     if (parameters.size() < (17 + length)) {
3266       INFO(id_, "Invalid CSR vendor command parameter length {}, expected {}",
3267            parameters.size(), 17 + length);
3268       goto complete;
3269     }
3270 
3271     std::vector<uint8_t> value(parameters.begin() + 17,
3272                                parameters.begin() + 17 + length);
3273 
3274     INFO(id_, "CSR vendor command type={:04x} length={:04x} pskey={:04x}", type,
3275          length, pskey);
3276 
3277     if (type == 0) {
3278       CsrReadPskey(static_cast<CsrPskey>(pskey), value);
3279       std::copy(value.begin(), value.end(), parameters.begin() + 17);
3280     } else {
3281       CsrWritePskey(static_cast<CsrPskey>(pskey), value);
3282     }
3283 
3284   } else {
3285     // Subcommand to read or write VARID of the selected identifier.
3286     std::vector<uint8_t> value(parameters.begin() + 11,
3287                                parameters.begin() + 11 + length);
3288 
3289     INFO(id_, "CSR vendor command type={:04x} length={:04x} varid={:04x}", type,
3290          length, varid);
3291 
3292     if (type == 0) {
3293       CsrReadVarid(static_cast<CsrVarid>(varid), value);
3294       std::copy(value.begin(), value.end(), parameters.begin() + 11);
3295     } else {
3296       CsrWriteVarid(static_cast<CsrVarid>(varid), value);
3297     }
3298   }
3299 
3300 complete:
3301   // Overwrite the command type.
3302   parameters[1] = 0x1;
3303   parameters[2] = 0x0;
3304   send_event_(bluetooth::hci::EventBuilder::Create(
3305       bluetooth::hci::EventCode::VENDOR_SPECIFIC, std::move(parameters)));
3306 }
3307 
CsrReadVarid(CsrVarid varid,std::vector<uint8_t> & value) const3308 void DualModeController::CsrReadVarid(CsrVarid varid,
3309                                       std::vector<uint8_t>& value) const {
3310   switch (varid) {
3311     case CsrVarid::CSR_VARID_BUILDID:
3312       // Return the extact Build ID returned by the official PTS dongle.
3313       ASSERT(value.size() >= 2);
3314       value[0] = 0xe8;
3315       value[1] = 0x30;
3316       break;
3317 
3318     default:
3319       INFO(id_, "Unsupported read of CSR varid 0x{:04x}",
3320            static_cast<uint16_t>(varid));
3321       break;
3322   }
3323 }
3324 
CsrWriteVarid(CsrVarid varid,std::vector<uint8_t> const &) const3325 void DualModeController::CsrWriteVarid(
3326     CsrVarid varid, std::vector<uint8_t> const& /*value*/) const {
3327   INFO(id_, "Unsupported write of CSR varid 0x{:04x}",
3328        static_cast<uint16_t>(varid));
3329 }
3330 
CsrReadPskey(CsrPskey pskey,std::vector<uint8_t> & value) const3331 void DualModeController::CsrReadPskey(CsrPskey pskey,
3332                                       std::vector<uint8_t>& value) const {
3333   switch (pskey) {
3334     case CsrPskey::CSR_PSKEY_ENC_KEY_LMIN:
3335       ASSERT(!value.empty());
3336       value[0] = 7;
3337       break;
3338 
3339     case CsrPskey::CSR_PSKEY_ENC_KEY_LMAX:
3340       ASSERT(!value.empty());
3341       value[0] = 16;
3342       break;
3343 
3344     case CSR_PSKEY_HCI_LMP_LOCAL_VERSION:
3345       // Return the extact version returned by the official PTS dongle.
3346       ASSERT(value.size() >= 2);
3347       value[0] = 0x08;
3348       value[1] = 0x08;
3349       break;
3350 
3351     default:
3352       INFO(id_, "Unsupported read of CSR pskey 0x{:04x}",
3353            static_cast<uint16_t>(pskey));
3354       break;
3355   }
3356 }
3357 
CsrWritePskey(CsrPskey pskey,std::vector<uint8_t> const & value)3358 void DualModeController::CsrWritePskey(CsrPskey pskey,
3359                                        std::vector<uint8_t> const& value) {
3360   switch (pskey) {
3361     case CsrPskey::CSR_PSKEY_LOCAL_SUPPORTED_FEATURES:
3362       ASSERT(value.size() >= 8);
3363       INFO(id_, "CSR Vendor updating the Local Supported Features");
3364       properties_.lmp_features[0] =
3365           ((uint64_t)value[0] << 0) | ((uint64_t)value[1] << 8) |
3366           ((uint64_t)value[2] << 16) | ((uint64_t)value[3] << 24) |
3367           ((uint64_t)value[4] << 32) | ((uint64_t)value[5] << 40) |
3368           ((uint64_t)value[6] << 48) | ((uint64_t)value[7] << 56);
3369       break;
3370 
3371     default:
3372       INFO(id_, "Unsupported write of CSR pskey 0x{:04x}",
3373            static_cast<uint16_t>(pskey));
3374       break;
3375   }
3376 }
3377 
LeSetAdvertisingSetRandomAddress(CommandView command)3378 void DualModeController::LeSetAdvertisingSetRandomAddress(CommandView command) {
3379   auto command_view =
3380       bluetooth::hci::LeSetAdvertisingSetRandomAddressView::Create(command);
3381   CHECK_PACKET_VIEW(command_view);
3382 
3383   DEBUG(id_, "<< LE Set Advertising Set Random Address");
3384   DEBUG(id_, "   advertising_handle={}", command_view.GetAdvertisingHandle());
3385   DEBUG(id_, "   random_address={}", command_view.GetRandomAddress());
3386 
3387   ErrorCode status = link_layer_controller_.LeSetAdvertisingSetRandomAddress(
3388       command_view.GetAdvertisingHandle(), command_view.GetRandomAddress());
3389   send_event_(
3390       bluetooth::hci::LeSetAdvertisingSetRandomAddressCompleteBuilder::Create(
3391           kNumCommandPackets, status));
3392 }
3393 
LeSetExtendedAdvertisingParameters(CommandView command)3394 void DualModeController::LeSetExtendedAdvertisingParameters(
3395     CommandView command) {
3396   auto command_view =
3397       bluetooth::hci::LeSetExtendedAdvertisingParametersView::Create(command);
3398   CHECK_PACKET_VIEW(command_view);
3399 
3400   DEBUG(id_, "<< LE Set Extended Advertising Parameters");
3401   DEBUG(id_, "   advertising_handle={}", command_view.GetAdvertisingHandle());
3402 
3403   ErrorCode status = link_layer_controller_.LeSetExtendedAdvertisingParameters(
3404       command_view.GetAdvertisingHandle(),
3405       command_view.GetAdvertisingEventProperties(),
3406       command_view.GetPrimaryAdvertisingIntervalMin(),
3407       command_view.GetPrimaryAdvertisingIntervalMax(),
3408       command_view.GetPrimaryAdvertisingChannelMap(),
3409       command_view.GetOwnAddressType(), command_view.GetPeerAddressType(),
3410       command_view.GetPeerAddress(), command_view.GetAdvertisingFilterPolicy(),
3411       command_view.GetAdvertisingTxPower(),
3412       command_view.GetPrimaryAdvertisingPhy(),
3413       command_view.GetSecondaryAdvertisingMaxSkip(),
3414       command_view.GetSecondaryAdvertisingPhy(),
3415       command_view.GetAdvertisingSid(),
3416       command_view.GetScanRequestNotificationEnable() == Enable::ENABLED);
3417   // The selected TX power is always the requested TX power
3418   // at the moment.
3419   send_event_(
3420       bluetooth::hci::LeSetExtendedAdvertisingParametersCompleteBuilder::Create(
3421           kNumCommandPackets, status, command_view.GetAdvertisingTxPower()));
3422 }
3423 
LeSetExtendedAdvertisingData(CommandView command)3424 void DualModeController::LeSetExtendedAdvertisingData(CommandView command) {
3425   auto command_view =
3426       bluetooth::hci::LeSetExtendedAdvertisingDataView::Create(command);
3427   CHECK_PACKET_VIEW(command_view);
3428 
3429   DEBUG(id_, "<< LE Set Extended Advertising Data");
3430   DEBUG(id_, "   advertising_handle={}", command_view.GetAdvertisingHandle());
3431 
3432   ErrorCode status = link_layer_controller_.LeSetExtendedAdvertisingData(
3433       command_view.GetAdvertisingHandle(), command_view.GetOperation(),
3434       command_view.GetFragmentPreference(), command_view.GetAdvertisingData());
3435   send_event_(
3436       bluetooth::hci::LeSetExtendedAdvertisingDataCompleteBuilder::Create(
3437           kNumCommandPackets, status));
3438 }
3439 
LeSetExtendedScanResponseData(CommandView command)3440 void DualModeController::LeSetExtendedScanResponseData(CommandView command) {
3441   auto command_view =
3442       bluetooth::hci::LeSetExtendedScanResponseDataView::Create(command);
3443   CHECK_PACKET_VIEW(command_view);
3444 
3445   DEBUG(id_, "<< LE Set Extended Scan Response Data");
3446   DEBUG(id_, "   advertising_handle={}", command_view.GetAdvertisingHandle());
3447 
3448   ErrorCode status = link_layer_controller_.LeSetExtendedScanResponseData(
3449       command_view.GetAdvertisingHandle(), command_view.GetOperation(),
3450       command_view.GetFragmentPreference(), command_view.GetScanResponseData());
3451   send_event_(
3452       bluetooth::hci::LeSetExtendedScanResponseDataCompleteBuilder::Create(
3453           kNumCommandPackets, status));
3454 }
3455 
LeSetExtendedAdvertisingEnable(CommandView command)3456 void DualModeController::LeSetExtendedAdvertisingEnable(CommandView command) {
3457   auto command_view =
3458       bluetooth::hci::LeSetExtendedAdvertisingEnableView::Create(command);
3459   CHECK_PACKET_VIEW(command_view);
3460 
3461   DEBUG(id_, "<< LE Set Extended Advertising Enable");
3462   DEBUG(id_, "   enable={}",
3463         command_view.GetEnable() == bluetooth::hci::Enable::ENABLED);
3464   for (auto const& set : command_view.GetEnabledSets()) {
3465     DEBUG(id_, "   advertising_handle={}", set.advertising_handle_);
3466   }
3467 
3468   ErrorCode status = link_layer_controller_.LeSetExtendedAdvertisingEnable(
3469       command_view.GetEnable() == bluetooth::hci::Enable::ENABLED,
3470       command_view.GetEnabledSets());
3471   send_event_(
3472       bluetooth::hci::LeSetExtendedAdvertisingEnableCompleteBuilder::Create(
3473           kNumCommandPackets, status));
3474 }
3475 
LeReadMaximumAdvertisingDataLength(CommandView command)3476 void DualModeController::LeReadMaximumAdvertisingDataLength(
3477     CommandView command) {
3478   auto command_view =
3479       bluetooth::hci::LeReadMaximumAdvertisingDataLengthView::Create(command);
3480   CHECK_PACKET_VIEW(command_view);
3481 
3482   DEBUG(id_, "<< LE Read Maximum Advertising Data Length");
3483 
3484   send_event_(
3485       bluetooth::hci::LeReadMaximumAdvertisingDataLengthCompleteBuilder::Create(
3486           kNumCommandPackets, ErrorCode::SUCCESS,
3487           properties_.le_max_advertising_data_length));
3488 }
3489 
LeReadNumberOfSupportedAdvertisingSets(CommandView command)3490 void DualModeController::LeReadNumberOfSupportedAdvertisingSets(
3491     CommandView command) {
3492   auto command_view =
3493       bluetooth::hci::LeReadNumberOfSupportedAdvertisingSetsView::Create(
3494           command);
3495   CHECK_PACKET_VIEW(command_view);
3496 
3497   DEBUG(id_, "<< LE Read Number of Supported Advertising Sets");
3498 
3499   send_event_(
3500       bluetooth::hci::LeReadNumberOfSupportedAdvertisingSetsCompleteBuilder::
3501           Create(kNumCommandPackets, ErrorCode::SUCCESS,
3502                  properties_.le_num_supported_advertising_sets));
3503 }
3504 
LeRemoveAdvertisingSet(CommandView command)3505 void DualModeController::LeRemoveAdvertisingSet(CommandView command) {
3506   auto command_view =
3507       bluetooth::hci::LeRemoveAdvertisingSetView::Create(command);
3508   CHECK_PACKET_VIEW(command_view);
3509 
3510   DEBUG(id_, "<< LE Remove Advertising Set");
3511   DEBUG(id_, "   advertising_handle={}", command_view.GetAdvertisingHandle());
3512 
3513   auto status = link_layer_controller_.LeRemoveAdvertisingSet(
3514       command_view.GetAdvertisingHandle());
3515   send_event_(bluetooth::hci::LeRemoveAdvertisingSetCompleteBuilder::Create(
3516       kNumCommandPackets, status));
3517 }
3518 
LeClearAdvertisingSets(CommandView command)3519 void DualModeController::LeClearAdvertisingSets(CommandView command) {
3520   auto command_view =
3521       bluetooth::hci::LeClearAdvertisingSetsView::Create(command);
3522   CHECK_PACKET_VIEW(command_view);
3523 
3524   DEBUG(id_, "<< LE Clear Advertising Sets");
3525 
3526   auto status = link_layer_controller_.LeClearAdvertisingSets();
3527   send_event_(bluetooth::hci::LeClearAdvertisingSetsCompleteBuilder::Create(
3528       kNumCommandPackets, status));
3529 }
3530 
LeStartEncryption(CommandView command)3531 void DualModeController::LeStartEncryption(CommandView command) {
3532   auto command_view = bluetooth::hci::LeStartEncryptionView::Create(command);
3533   CHECK_PACKET_VIEW(command_view);
3534 
3535   DEBUG(id_, "<< LE Start Encryption");
3536   DEBUG(id_, "   connection_handle=0x{:x}", command_view.GetConnectionHandle());
3537 
3538   ErrorCode status = link_layer_controller_.LeEnableEncryption(
3539       command_view.GetConnectionHandle(), command_view.GetRand(),
3540       command_view.GetEdiv(), command_view.GetLtk());
3541 
3542   send_event_(bluetooth::hci::LeStartEncryptionStatusBuilder::Create(
3543       status, kNumCommandPackets));
3544 }
3545 
LeLongTermKeyRequestReply(CommandView command)3546 void DualModeController::LeLongTermKeyRequestReply(CommandView command) {
3547   auto command_view =
3548       bluetooth::hci::LeLongTermKeyRequestReplyView::Create(command);
3549   CHECK_PACKET_VIEW(command_view);
3550   uint16_t handle = command_view.GetConnectionHandle();
3551 
3552   DEBUG(id_, "<< LE Long Term Key Request Reply");
3553   DEBUG(id_, "   connection_handle=0x{:x}", handle);
3554 
3555   ErrorCode status = link_layer_controller_.LeLongTermKeyRequestReply(
3556       handle, command_view.GetLongTermKey());
3557 
3558   send_event_(bluetooth::hci::LeLongTermKeyRequestReplyCompleteBuilder::Create(
3559       kNumCommandPackets, status, handle));
3560 }
3561 
LeLongTermKeyRequestNegativeReply(CommandView command)3562 void DualModeController::LeLongTermKeyRequestNegativeReply(
3563     CommandView command) {
3564   auto command_view =
3565       bluetooth::hci::LeLongTermKeyRequestNegativeReplyView::Create(command);
3566   CHECK_PACKET_VIEW(command_view);
3567   uint16_t handle = command_view.GetConnectionHandle();
3568 
3569   DEBUG(id_, "<< LE Long Term Key Request Negative Reply");
3570   DEBUG(id_, "   connection_handle=0x{:x}", handle);
3571 
3572   ErrorCode status =
3573       link_layer_controller_.LeLongTermKeyRequestNegativeReply(handle);
3574 
3575   send_event_(
3576       bluetooth::hci::LeLongTermKeyRequestNegativeReplyCompleteBuilder::Create(
3577           kNumCommandPackets, status, handle));
3578 }
3579 
ReadConnectionAcceptTimeout(CommandView command)3580 void DualModeController::ReadConnectionAcceptTimeout(CommandView command) {
3581   auto command_view =
3582       bluetooth::hci::ReadConnectionAcceptTimeoutView::Create(command);
3583   CHECK_PACKET_VIEW(command_view);
3584 
3585   DEBUG(id_, "<< Read Connection Accept Timeout");
3586 
3587   send_event_(
3588       bluetooth::hci::ReadConnectionAcceptTimeoutCompleteBuilder::Create(
3589           kNumCommandPackets, ErrorCode::SUCCESS,
3590           link_layer_controller_.GetConnectionAcceptTimeout()));
3591 }
3592 
WriteConnectionAcceptTimeout(CommandView command)3593 void DualModeController::WriteConnectionAcceptTimeout(CommandView command) {
3594   auto command_view =
3595       bluetooth::hci::WriteConnectionAcceptTimeoutView::Create(command);
3596   CHECK_PACKET_VIEW(command_view);
3597 
3598   DEBUG(id_, "<< Write Connection Accept Timeout");
3599 
3600   link_layer_controller_.SetConnectionAcceptTimeout(
3601       command_view.GetConnAcceptTimeout());
3602 
3603   send_event_(
3604       bluetooth::hci::WriteConnectionAcceptTimeoutCompleteBuilder::Create(
3605           kNumCommandPackets, ErrorCode::SUCCESS));
3606 }
3607 
ReadLoopbackMode(CommandView command)3608 void DualModeController::ReadLoopbackMode(CommandView command) {
3609   auto command_view = bluetooth::hci::ReadLoopbackModeView::Create(command);
3610   CHECK_PACKET_VIEW(command_view);
3611 
3612   DEBUG(id_, "<< Read Loopback Mode");
3613 
3614   send_event_(bluetooth::hci::ReadLoopbackModeCompleteBuilder::Create(
3615       kNumCommandPackets, ErrorCode::SUCCESS, loopback_mode_));
3616 }
3617 
WriteLoopbackMode(CommandView command)3618 void DualModeController::WriteLoopbackMode(CommandView command) {
3619   auto command_view = bluetooth::hci::WriteLoopbackModeView::Create(command);
3620   CHECK_PACKET_VIEW(command_view);
3621 
3622   DEBUG(id_, "<< Write Loopback Mode");
3623   DEBUG(id_, "   loopback_mode={}",
3624         bluetooth::hci::LoopbackModeText(command_view.GetLoopbackMode()));
3625 
3626   loopback_mode_ = command_view.GetLoopbackMode();
3627   // ACL channel
3628   uint16_t acl_handle = 0x123;
3629   send_event_(bluetooth::hci::ConnectionCompleteBuilder::Create(
3630       ErrorCode::SUCCESS, acl_handle, GetAddress(),
3631       bluetooth::hci::LinkType::ACL, bluetooth::hci::Enable::DISABLED));
3632   // SCO channel
3633   uint16_t sco_handle = 0x345;
3634   send_event_(bluetooth::hci::ConnectionCompleteBuilder::Create(
3635       ErrorCode::SUCCESS, sco_handle, GetAddress(),
3636       bluetooth::hci::LinkType::SCO, bluetooth::hci::Enable::DISABLED));
3637   send_event_(bluetooth::hci::WriteLoopbackModeCompleteBuilder::Create(
3638       kNumCommandPackets, ErrorCode::SUCCESS));
3639 }
3640 
3641 // Note: the list does not contain all defined opcodes.
3642 // Notable exceptions:
3643 // - Vendor commands
3644 // - Read Local Supported Commands command
3645 const std::unordered_map<OpCode, OpCodeIndex>
3646     DualModeController::hci_command_op_code_to_index_{
3647         // LINK_CONTROL
3648         {OpCode::INQUIRY, OpCodeIndex::INQUIRY},
3649         {OpCode::INQUIRY_CANCEL, OpCodeIndex::INQUIRY_CANCEL},
3650         {OpCode::PERIODIC_INQUIRY_MODE, OpCodeIndex::PERIODIC_INQUIRY_MODE},
3651         {OpCode::EXIT_PERIODIC_INQUIRY_MODE,
3652          OpCodeIndex::EXIT_PERIODIC_INQUIRY_MODE},
3653         {OpCode::CREATE_CONNECTION, OpCodeIndex::CREATE_CONNECTION},
3654         {OpCode::DISCONNECT, OpCodeIndex::DISCONNECT},
3655         {OpCode::ADD_SCO_CONNECTION, OpCodeIndex::ADD_SCO_CONNECTION},
3656         {OpCode::CREATE_CONNECTION_CANCEL,
3657          OpCodeIndex::CREATE_CONNECTION_CANCEL},
3658         {OpCode::ACCEPT_CONNECTION_REQUEST,
3659          OpCodeIndex::ACCEPT_CONNECTION_REQUEST},
3660         {OpCode::REJECT_CONNECTION_REQUEST,
3661          OpCodeIndex::REJECT_CONNECTION_REQUEST},
3662         {OpCode::LINK_KEY_REQUEST_REPLY, OpCodeIndex::LINK_KEY_REQUEST_REPLY},
3663         {OpCode::LINK_KEY_REQUEST_NEGATIVE_REPLY,
3664          OpCodeIndex::LINK_KEY_REQUEST_NEGATIVE_REPLY},
3665         {OpCode::PIN_CODE_REQUEST_REPLY, OpCodeIndex::PIN_CODE_REQUEST_REPLY},
3666         {OpCode::PIN_CODE_REQUEST_NEGATIVE_REPLY,
3667          OpCodeIndex::PIN_CODE_REQUEST_NEGATIVE_REPLY},
3668         {OpCode::CHANGE_CONNECTION_PACKET_TYPE,
3669          OpCodeIndex::CHANGE_CONNECTION_PACKET_TYPE},
3670         {OpCode::AUTHENTICATION_REQUESTED,
3671          OpCodeIndex::AUTHENTICATION_REQUESTED},
3672         {OpCode::SET_CONNECTION_ENCRYPTION,
3673          OpCodeIndex::SET_CONNECTION_ENCRYPTION},
3674         {OpCode::CHANGE_CONNECTION_LINK_KEY,
3675          OpCodeIndex::CHANGE_CONNECTION_LINK_KEY},
3676         {OpCode::CENTRAL_LINK_KEY, OpCodeIndex::CENTRAL_LINK_KEY},
3677         {OpCode::REMOTE_NAME_REQUEST, OpCodeIndex::REMOTE_NAME_REQUEST},
3678         {OpCode::REMOTE_NAME_REQUEST_CANCEL,
3679          OpCodeIndex::REMOTE_NAME_REQUEST_CANCEL},
3680         {OpCode::READ_REMOTE_SUPPORTED_FEATURES,
3681          OpCodeIndex::READ_REMOTE_SUPPORTED_FEATURES},
3682         {OpCode::READ_REMOTE_EXTENDED_FEATURES,
3683          OpCodeIndex::READ_REMOTE_EXTENDED_FEATURES},
3684         {OpCode::READ_REMOTE_VERSION_INFORMATION,
3685          OpCodeIndex::READ_REMOTE_VERSION_INFORMATION},
3686         {OpCode::READ_CLOCK_OFFSET, OpCodeIndex::READ_CLOCK_OFFSET},
3687         {OpCode::READ_LMP_HANDLE, OpCodeIndex::READ_LMP_HANDLE},
3688         {OpCode::SETUP_SYNCHRONOUS_CONNECTION,
3689          OpCodeIndex::SETUP_SYNCHRONOUS_CONNECTION},
3690         {OpCode::ACCEPT_SYNCHRONOUS_CONNECTION,
3691          OpCodeIndex::ACCEPT_SYNCHRONOUS_CONNECTION},
3692         {OpCode::REJECT_SYNCHRONOUS_CONNECTION,
3693          OpCodeIndex::REJECT_SYNCHRONOUS_CONNECTION},
3694         {OpCode::IO_CAPABILITY_REQUEST_REPLY,
3695          OpCodeIndex::IO_CAPABILITY_REQUEST_REPLY},
3696         {OpCode::USER_CONFIRMATION_REQUEST_REPLY,
3697          OpCodeIndex::USER_CONFIRMATION_REQUEST_REPLY},
3698         {OpCode::USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY,
3699          OpCodeIndex::USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY},
3700         {OpCode::USER_PASSKEY_REQUEST_REPLY,
3701          OpCodeIndex::USER_PASSKEY_REQUEST_REPLY},
3702         {OpCode::USER_PASSKEY_REQUEST_NEGATIVE_REPLY,
3703          OpCodeIndex::USER_PASSKEY_REQUEST_NEGATIVE_REPLY},
3704         {OpCode::REMOTE_OOB_DATA_REQUEST_REPLY,
3705          OpCodeIndex::REMOTE_OOB_DATA_REQUEST_REPLY},
3706         {OpCode::REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY,
3707          OpCodeIndex::REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY},
3708         {OpCode::IO_CAPABILITY_REQUEST_NEGATIVE_REPLY,
3709          OpCodeIndex::IO_CAPABILITY_REQUEST_NEGATIVE_REPLY},
3710         {OpCode::ENHANCED_SETUP_SYNCHRONOUS_CONNECTION,
3711          OpCodeIndex::ENHANCED_SETUP_SYNCHRONOUS_CONNECTION},
3712         {OpCode::ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION,
3713          OpCodeIndex::ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION},
3714         {OpCode::TRUNCATED_PAGE, OpCodeIndex::TRUNCATED_PAGE},
3715         {OpCode::TRUNCATED_PAGE_CANCEL, OpCodeIndex::TRUNCATED_PAGE_CANCEL},
3716         {OpCode::SET_CONNECTIONLESS_PERIPHERAL_BROADCAST,
3717          OpCodeIndex::SET_CONNECTIONLESS_PERIPHERAL_BROADCAST},
3718         {OpCode::SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVE,
3719          OpCodeIndex::SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVE},
3720         {OpCode::START_SYNCHRONIZATION_TRAIN,
3721          OpCodeIndex::START_SYNCHRONIZATION_TRAIN},
3722         {OpCode::RECEIVE_SYNCHRONIZATION_TRAIN,
3723          OpCodeIndex::RECEIVE_SYNCHRONIZATION_TRAIN},
3724         {OpCode::REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY,
3725          OpCodeIndex::REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY},
3726 
3727         // LINK_POLICY
3728         {OpCode::HOLD_MODE, OpCodeIndex::HOLD_MODE},
3729         {OpCode::SNIFF_MODE, OpCodeIndex::SNIFF_MODE},
3730         {OpCode::EXIT_SNIFF_MODE, OpCodeIndex::EXIT_SNIFF_MODE},
3731         {OpCode::QOS_SETUP, OpCodeIndex::QOS_SETUP},
3732         {OpCode::ROLE_DISCOVERY, OpCodeIndex::ROLE_DISCOVERY},
3733         {OpCode::SWITCH_ROLE, OpCodeIndex::SWITCH_ROLE},
3734         {OpCode::READ_LINK_POLICY_SETTINGS,
3735          OpCodeIndex::READ_LINK_POLICY_SETTINGS},
3736         {OpCode::WRITE_LINK_POLICY_SETTINGS,
3737          OpCodeIndex::WRITE_LINK_POLICY_SETTINGS},
3738         {OpCode::READ_DEFAULT_LINK_POLICY_SETTINGS,
3739          OpCodeIndex::READ_DEFAULT_LINK_POLICY_SETTINGS},
3740         {OpCode::WRITE_DEFAULT_LINK_POLICY_SETTINGS,
3741          OpCodeIndex::WRITE_DEFAULT_LINK_POLICY_SETTINGS},
3742         {OpCode::FLOW_SPECIFICATION, OpCodeIndex::FLOW_SPECIFICATION},
3743         {OpCode::SNIFF_SUBRATING, OpCodeIndex::SNIFF_SUBRATING},
3744 
3745         // CONTROLLER_AND_BASEBAND
3746         {OpCode::SET_EVENT_MASK, OpCodeIndex::SET_EVENT_MASK},
3747         {OpCode::RESET, OpCodeIndex::RESET},
3748         {OpCode::SET_EVENT_FILTER, OpCodeIndex::SET_EVENT_FILTER},
3749         {OpCode::FLUSH, OpCodeIndex::FLUSH},
3750         {OpCode::READ_PIN_TYPE, OpCodeIndex::READ_PIN_TYPE},
3751         {OpCode::WRITE_PIN_TYPE, OpCodeIndex::WRITE_PIN_TYPE},
3752         {OpCode::READ_STORED_LINK_KEY, OpCodeIndex::READ_STORED_LINK_KEY},
3753         {OpCode::WRITE_STORED_LINK_KEY, OpCodeIndex::WRITE_STORED_LINK_KEY},
3754         {OpCode::DELETE_STORED_LINK_KEY, OpCodeIndex::DELETE_STORED_LINK_KEY},
3755         {OpCode::WRITE_LOCAL_NAME, OpCodeIndex::WRITE_LOCAL_NAME},
3756         {OpCode::READ_LOCAL_NAME, OpCodeIndex::READ_LOCAL_NAME},
3757         {OpCode::READ_CONNECTION_ACCEPT_TIMEOUT,
3758          OpCodeIndex::READ_CONNECTION_ACCEPT_TIMEOUT},
3759         {OpCode::WRITE_CONNECTION_ACCEPT_TIMEOUT,
3760          OpCodeIndex::WRITE_CONNECTION_ACCEPT_TIMEOUT},
3761         {OpCode::READ_PAGE_TIMEOUT, OpCodeIndex::READ_PAGE_TIMEOUT},
3762         {OpCode::WRITE_PAGE_TIMEOUT, OpCodeIndex::WRITE_PAGE_TIMEOUT},
3763         {OpCode::READ_SCAN_ENABLE, OpCodeIndex::READ_SCAN_ENABLE},
3764         {OpCode::WRITE_SCAN_ENABLE, OpCodeIndex::WRITE_SCAN_ENABLE},
3765         {OpCode::READ_PAGE_SCAN_ACTIVITY, OpCodeIndex::READ_PAGE_SCAN_ACTIVITY},
3766         {OpCode::WRITE_PAGE_SCAN_ACTIVITY,
3767          OpCodeIndex::WRITE_PAGE_SCAN_ACTIVITY},
3768         {OpCode::READ_INQUIRY_SCAN_ACTIVITY,
3769          OpCodeIndex::READ_INQUIRY_SCAN_ACTIVITY},
3770         {OpCode::WRITE_INQUIRY_SCAN_ACTIVITY,
3771          OpCodeIndex::WRITE_INQUIRY_SCAN_ACTIVITY},
3772         {OpCode::READ_AUTHENTICATION_ENABLE,
3773          OpCodeIndex::READ_AUTHENTICATION_ENABLE},
3774         {OpCode::WRITE_AUTHENTICATION_ENABLE,
3775          OpCodeIndex::WRITE_AUTHENTICATION_ENABLE},
3776         {OpCode::READ_CLASS_OF_DEVICE, OpCodeIndex::READ_CLASS_OF_DEVICE},
3777         {OpCode::WRITE_CLASS_OF_DEVICE, OpCodeIndex::WRITE_CLASS_OF_DEVICE},
3778         {OpCode::READ_VOICE_SETTING, OpCodeIndex::READ_VOICE_SETTING},
3779         {OpCode::WRITE_VOICE_SETTING, OpCodeIndex::WRITE_VOICE_SETTING},
3780         {OpCode::READ_AUTOMATIC_FLUSH_TIMEOUT,
3781          OpCodeIndex::READ_AUTOMATIC_FLUSH_TIMEOUT},
3782         {OpCode::WRITE_AUTOMATIC_FLUSH_TIMEOUT,
3783          OpCodeIndex::WRITE_AUTOMATIC_FLUSH_TIMEOUT},
3784         {OpCode::READ_NUM_BROADCAST_RETRANSMITS,
3785          OpCodeIndex::READ_NUM_BROADCAST_RETRANSMITS},
3786         {OpCode::WRITE_NUM_BROADCAST_RETRANSMITS,
3787          OpCodeIndex::WRITE_NUM_BROADCAST_RETRANSMITS},
3788         {OpCode::READ_HOLD_MODE_ACTIVITY, OpCodeIndex::READ_HOLD_MODE_ACTIVITY},
3789         {OpCode::WRITE_HOLD_MODE_ACTIVITY,
3790          OpCodeIndex::WRITE_HOLD_MODE_ACTIVITY},
3791         {OpCode::READ_TRANSMIT_POWER_LEVEL,
3792          OpCodeIndex::READ_TRANSMIT_POWER_LEVEL},
3793         {OpCode::READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE,
3794          OpCodeIndex::READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE},
3795         {OpCode::WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE,
3796          OpCodeIndex::WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE},
3797         {OpCode::SET_CONTROLLER_TO_HOST_FLOW_CONTROL,
3798          OpCodeIndex::SET_CONTROLLER_TO_HOST_FLOW_CONTROL},
3799         {OpCode::HOST_BUFFER_SIZE, OpCodeIndex::HOST_BUFFER_SIZE},
3800         {OpCode::HOST_NUMBER_OF_COMPLETED_PACKETS,
3801          OpCodeIndex::HOST_NUMBER_OF_COMPLETED_PACKETS},
3802         {OpCode::READ_LINK_SUPERVISION_TIMEOUT,
3803          OpCodeIndex::READ_LINK_SUPERVISION_TIMEOUT},
3804         {OpCode::WRITE_LINK_SUPERVISION_TIMEOUT,
3805          OpCodeIndex::WRITE_LINK_SUPERVISION_TIMEOUT},
3806         {OpCode::READ_NUMBER_OF_SUPPORTED_IAC,
3807          OpCodeIndex::READ_NUMBER_OF_SUPPORTED_IAC},
3808         {OpCode::READ_CURRENT_IAC_LAP, OpCodeIndex::READ_CURRENT_IAC_LAP},
3809         {OpCode::WRITE_CURRENT_IAC_LAP, OpCodeIndex::WRITE_CURRENT_IAC_LAP},
3810         {OpCode::SET_AFH_HOST_CHANNEL_CLASSIFICATION,
3811          OpCodeIndex::SET_AFH_HOST_CHANNEL_CLASSIFICATION},
3812         {OpCode::READ_INQUIRY_SCAN_TYPE, OpCodeIndex::READ_INQUIRY_SCAN_TYPE},
3813         {OpCode::WRITE_INQUIRY_SCAN_TYPE, OpCodeIndex::WRITE_INQUIRY_SCAN_TYPE},
3814         {OpCode::READ_INQUIRY_MODE, OpCodeIndex::READ_INQUIRY_MODE},
3815         {OpCode::WRITE_INQUIRY_MODE, OpCodeIndex::WRITE_INQUIRY_MODE},
3816         {OpCode::READ_PAGE_SCAN_TYPE, OpCodeIndex::READ_PAGE_SCAN_TYPE},
3817         {OpCode::WRITE_PAGE_SCAN_TYPE, OpCodeIndex::WRITE_PAGE_SCAN_TYPE},
3818         {OpCode::READ_AFH_CHANNEL_ASSESSMENT_MODE,
3819          OpCodeIndex::READ_AFH_CHANNEL_ASSESSMENT_MODE},
3820         {OpCode::WRITE_AFH_CHANNEL_ASSESSMENT_MODE,
3821          OpCodeIndex::WRITE_AFH_CHANNEL_ASSESSMENT_MODE},
3822         {OpCode::READ_EXTENDED_INQUIRY_RESPONSE,
3823          OpCodeIndex::READ_EXTENDED_INQUIRY_RESPONSE},
3824         {OpCode::WRITE_EXTENDED_INQUIRY_RESPONSE,
3825          OpCodeIndex::WRITE_EXTENDED_INQUIRY_RESPONSE},
3826         {OpCode::REFRESH_ENCRYPTION_KEY, OpCodeIndex::REFRESH_ENCRYPTION_KEY},
3827         {OpCode::READ_SIMPLE_PAIRING_MODE,
3828          OpCodeIndex::READ_SIMPLE_PAIRING_MODE},
3829         {OpCode::WRITE_SIMPLE_PAIRING_MODE,
3830          OpCodeIndex::WRITE_SIMPLE_PAIRING_MODE},
3831         {OpCode::READ_LOCAL_OOB_DATA, OpCodeIndex::READ_LOCAL_OOB_DATA},
3832         {OpCode::READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL,
3833          OpCodeIndex::READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL},
3834         {OpCode::WRITE_INQUIRY_TRANSMIT_POWER_LEVEL,
3835          OpCodeIndex::WRITE_INQUIRY_TRANSMIT_POWER_LEVEL},
3836         {OpCode::READ_DEFAULT_ERRONEOUS_DATA_REPORTING,
3837          OpCodeIndex::READ_DEFAULT_ERRONEOUS_DATA_REPORTING},
3838         {OpCode::WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING,
3839          OpCodeIndex::WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING},
3840         {OpCode::ENHANCED_FLUSH, OpCodeIndex::ENHANCED_FLUSH},
3841         {OpCode::SEND_KEYPRESS_NOTIFICATION,
3842          OpCodeIndex::SEND_KEYPRESS_NOTIFICATION},
3843         {OpCode::SET_EVENT_MASK_PAGE_2, OpCodeIndex::SET_EVENT_MASK_PAGE_2},
3844         {OpCode::READ_FLOW_CONTROL_MODE, OpCodeIndex::READ_FLOW_CONTROL_MODE},
3845         {OpCode::WRITE_FLOW_CONTROL_MODE, OpCodeIndex::WRITE_FLOW_CONTROL_MODE},
3846         {OpCode::READ_ENHANCED_TRANSMIT_POWER_LEVEL,
3847          OpCodeIndex::READ_ENHANCED_TRANSMIT_POWER_LEVEL},
3848         {OpCode::READ_LE_HOST_SUPPORT, OpCodeIndex::READ_LE_HOST_SUPPORT},
3849         {OpCode::WRITE_LE_HOST_SUPPORT, OpCodeIndex::WRITE_LE_HOST_SUPPORT},
3850         {OpCode::SET_MWS_CHANNEL_PARAMETERS,
3851          OpCodeIndex::SET_MWS_CHANNEL_PARAMETERS},
3852         {OpCode::SET_EXTERNAL_FRAME_CONFIGURATION,
3853          OpCodeIndex::SET_EXTERNAL_FRAME_CONFIGURATION},
3854         {OpCode::SET_MWS_SIGNALING, OpCodeIndex::SET_MWS_SIGNALING},
3855         {OpCode::SET_MWS_TRANSPORT_LAYER, OpCodeIndex::SET_MWS_TRANSPORT_LAYER},
3856         {OpCode::SET_MWS_SCAN_FREQUENCY_TABLE,
3857          OpCodeIndex::SET_MWS_SCAN_FREQUENCY_TABLE},
3858         {OpCode::SET_MWS_PATTERN_CONFIGURATION,
3859          OpCodeIndex::SET_MWS_PATTERN_CONFIGURATION},
3860         {OpCode::SET_RESERVED_LT_ADDR, OpCodeIndex::SET_RESERVED_LT_ADDR},
3861         {OpCode::DELETE_RESERVED_LT_ADDR, OpCodeIndex::DELETE_RESERVED_LT_ADDR},
3862         {OpCode::SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_DATA,
3863          OpCodeIndex::SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_DATA},
3864         {OpCode::READ_SYNCHRONIZATION_TRAIN_PARAMETERS,
3865          OpCodeIndex::READ_SYNCHRONIZATION_TRAIN_PARAMETERS},
3866         {OpCode::WRITE_SYNCHRONIZATION_TRAIN_PARAMETERS,
3867          OpCodeIndex::WRITE_SYNCHRONIZATION_TRAIN_PARAMETERS},
3868         {OpCode::READ_SECURE_CONNECTIONS_HOST_SUPPORT,
3869          OpCodeIndex::READ_SECURE_CONNECTIONS_HOST_SUPPORT},
3870         {OpCode::WRITE_SECURE_CONNECTIONS_HOST_SUPPORT,
3871          OpCodeIndex::WRITE_SECURE_CONNECTIONS_HOST_SUPPORT},
3872         {OpCode::READ_AUTHENTICATED_PAYLOAD_TIMEOUT,
3873          OpCodeIndex::READ_AUTHENTICATED_PAYLOAD_TIMEOUT},
3874         {OpCode::WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT,
3875          OpCodeIndex::WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT},
3876         {OpCode::READ_LOCAL_OOB_EXTENDED_DATA,
3877          OpCodeIndex::READ_LOCAL_OOB_EXTENDED_DATA},
3878         {OpCode::READ_EXTENDED_PAGE_TIMEOUT,
3879          OpCodeIndex::READ_EXTENDED_PAGE_TIMEOUT},
3880         {OpCode::WRITE_EXTENDED_PAGE_TIMEOUT,
3881          OpCodeIndex::WRITE_EXTENDED_PAGE_TIMEOUT},
3882         {OpCode::READ_EXTENDED_INQUIRY_LENGTH,
3883          OpCodeIndex::READ_EXTENDED_INQUIRY_LENGTH},
3884         {OpCode::WRITE_EXTENDED_INQUIRY_LENGTH,
3885          OpCodeIndex::WRITE_EXTENDED_INQUIRY_LENGTH},
3886         {OpCode::SET_ECOSYSTEM_BASE_INTERVAL,
3887          OpCodeIndex::SET_ECOSYSTEM_BASE_INTERVAL},
3888         {OpCode::CONFIGURE_DATA_PATH, OpCodeIndex::CONFIGURE_DATA_PATH},
3889         {OpCode::SET_MIN_ENCRYPTION_KEY_SIZE,
3890          OpCodeIndex::SET_MIN_ENCRYPTION_KEY_SIZE},
3891 
3892         // INFORMATIONAL_PARAMETERS
3893         {OpCode::READ_LOCAL_VERSION_INFORMATION,
3894          OpCodeIndex::READ_LOCAL_VERSION_INFORMATION},
3895         {OpCode::READ_LOCAL_SUPPORTED_FEATURES,
3896          OpCodeIndex::READ_LOCAL_SUPPORTED_FEATURES},
3897         {OpCode::READ_LOCAL_EXTENDED_FEATURES,
3898          OpCodeIndex::READ_LOCAL_EXTENDED_FEATURES},
3899         {OpCode::READ_BUFFER_SIZE, OpCodeIndex::READ_BUFFER_SIZE},
3900         {OpCode::READ_BD_ADDR, OpCodeIndex::READ_BD_ADDR},
3901         {OpCode::READ_DATA_BLOCK_SIZE, OpCodeIndex::READ_DATA_BLOCK_SIZE},
3902         {OpCode::READ_LOCAL_SUPPORTED_CODECS_V1,
3903          OpCodeIndex::READ_LOCAL_SUPPORTED_CODECS_V1},
3904         {OpCode::READ_LOCAL_SIMPLE_PAIRING_OPTIONS,
3905          OpCodeIndex::READ_LOCAL_SIMPLE_PAIRING_OPTIONS},
3906         {OpCode::READ_LOCAL_SUPPORTED_CODECS_V2,
3907          OpCodeIndex::READ_LOCAL_SUPPORTED_CODECS_V2},
3908         {OpCode::READ_LOCAL_SUPPORTED_CODEC_CAPABILITIES,
3909          OpCodeIndex::READ_LOCAL_SUPPORTED_CODEC_CAPABILITIES},
3910         {OpCode::READ_LOCAL_SUPPORTED_CONTROLLER_DELAY,
3911          OpCodeIndex::READ_LOCAL_SUPPORTED_CONTROLLER_DELAY},
3912 
3913         // STATUS_PARAMETERS
3914         {OpCode::READ_FAILED_CONTACT_COUNTER,
3915          OpCodeIndex::READ_FAILED_CONTACT_COUNTER},
3916         {OpCode::RESET_FAILED_CONTACT_COUNTER,
3917          OpCodeIndex::RESET_FAILED_CONTACT_COUNTER},
3918         {OpCode::READ_LINK_QUALITY, OpCodeIndex::READ_LINK_QUALITY},
3919         {OpCode::READ_RSSI, OpCodeIndex::READ_RSSI},
3920         {OpCode::READ_AFH_CHANNEL_MAP, OpCodeIndex::READ_AFH_CHANNEL_MAP},
3921         {OpCode::READ_CLOCK, OpCodeIndex::READ_CLOCK},
3922         {OpCode::READ_ENCRYPTION_KEY_SIZE,
3923          OpCodeIndex::READ_ENCRYPTION_KEY_SIZE},
3924         {OpCode::GET_MWS_TRANSPORT_LAYER_CONFIGURATION,
3925          OpCodeIndex::GET_MWS_TRANSPORT_LAYER_CONFIGURATION},
3926         {OpCode::SET_TRIGGERED_CLOCK_CAPTURE,
3927          OpCodeIndex::SET_TRIGGERED_CLOCK_CAPTURE},
3928 
3929         // TESTING
3930         {OpCode::READ_LOOPBACK_MODE, OpCodeIndex::READ_LOOPBACK_MODE},
3931         {OpCode::WRITE_LOOPBACK_MODE, OpCodeIndex::WRITE_LOOPBACK_MODE},
3932         {OpCode::ENABLE_DEVICE_UNDER_TEST_MODE,
3933          OpCodeIndex::ENABLE_DEVICE_UNDER_TEST_MODE},
3934         {OpCode::WRITE_SIMPLE_PAIRING_DEBUG_MODE,
3935          OpCodeIndex::WRITE_SIMPLE_PAIRING_DEBUG_MODE},
3936         {OpCode::WRITE_SECURE_CONNECTIONS_TEST_MODE,
3937          OpCodeIndex::WRITE_SECURE_CONNECTIONS_TEST_MODE},
3938 
3939         // LE_CONTROLLER
3940         {OpCode::LE_SET_EVENT_MASK, OpCodeIndex::LE_SET_EVENT_MASK},
3941         {OpCode::LE_READ_BUFFER_SIZE_V1, OpCodeIndex::LE_READ_BUFFER_SIZE_V1},
3942         {OpCode::LE_READ_LOCAL_SUPPORTED_FEATURES,
3943          OpCodeIndex::LE_READ_LOCAL_SUPPORTED_FEATURES},
3944         {OpCode::LE_SET_RANDOM_ADDRESS, OpCodeIndex::LE_SET_RANDOM_ADDRESS},
3945         {OpCode::LE_SET_ADVERTISING_PARAMETERS,
3946          OpCodeIndex::LE_SET_ADVERTISING_PARAMETERS},
3947         {OpCode::LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER,
3948          OpCodeIndex::LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER},
3949         {OpCode::LE_SET_ADVERTISING_DATA, OpCodeIndex::LE_SET_ADVERTISING_DATA},
3950         {OpCode::LE_SET_SCAN_RESPONSE_DATA,
3951          OpCodeIndex::LE_SET_SCAN_RESPONSE_DATA},
3952         {OpCode::LE_SET_ADVERTISING_ENABLE,
3953          OpCodeIndex::LE_SET_ADVERTISING_ENABLE},
3954         {OpCode::LE_SET_SCAN_PARAMETERS, OpCodeIndex::LE_SET_SCAN_PARAMETERS},
3955         {OpCode::LE_SET_SCAN_ENABLE, OpCodeIndex::LE_SET_SCAN_ENABLE},
3956         {OpCode::LE_CREATE_CONNECTION, OpCodeIndex::LE_CREATE_CONNECTION},
3957         {OpCode::LE_CREATE_CONNECTION_CANCEL,
3958          OpCodeIndex::LE_CREATE_CONNECTION_CANCEL},
3959         {OpCode::LE_READ_FILTER_ACCEPT_LIST_SIZE,
3960          OpCodeIndex::LE_READ_FILTER_ACCEPT_LIST_SIZE},
3961         {OpCode::LE_CLEAR_FILTER_ACCEPT_LIST,
3962          OpCodeIndex::LE_CLEAR_FILTER_ACCEPT_LIST},
3963         {OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST,
3964          OpCodeIndex::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST},
3965         {OpCode::LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST,
3966          OpCodeIndex::LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST},
3967         {OpCode::LE_CONNECTION_UPDATE, OpCodeIndex::LE_CONNECTION_UPDATE},
3968         {OpCode::LE_SET_HOST_CHANNEL_CLASSIFICATION,
3969          OpCodeIndex::LE_SET_HOST_CHANNEL_CLASSIFICATION},
3970         {OpCode::LE_READ_CHANNEL_MAP, OpCodeIndex::LE_READ_CHANNEL_MAP},
3971         {OpCode::LE_READ_REMOTE_FEATURES, OpCodeIndex::LE_READ_REMOTE_FEATURES},
3972         {OpCode::LE_ENCRYPT, OpCodeIndex::LE_ENCRYPT},
3973         {OpCode::LE_RAND, OpCodeIndex::LE_RAND},
3974         {OpCode::LE_START_ENCRYPTION, OpCodeIndex::LE_START_ENCRYPTION},
3975         {OpCode::LE_LONG_TERM_KEY_REQUEST_REPLY,
3976          OpCodeIndex::LE_LONG_TERM_KEY_REQUEST_REPLY},
3977         {OpCode::LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY,
3978          OpCodeIndex::LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY},
3979         {OpCode::LE_READ_SUPPORTED_STATES,
3980          OpCodeIndex::LE_READ_SUPPORTED_STATES},
3981         {OpCode::LE_RECEIVER_TEST_V1, OpCodeIndex::LE_RECEIVER_TEST_V1},
3982         {OpCode::LE_TRANSMITTER_TEST_V1, OpCodeIndex::LE_TRANSMITTER_TEST_V1},
3983         {OpCode::LE_TEST_END, OpCodeIndex::LE_TEST_END},
3984         {OpCode::LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY,
3985          OpCodeIndex::LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY},
3986         {OpCode::LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY,
3987          OpCodeIndex::LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY},
3988         {OpCode::LE_SET_DATA_LENGTH, OpCodeIndex::LE_SET_DATA_LENGTH},
3989         {OpCode::LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH,
3990          OpCodeIndex::LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH},
3991         {OpCode::LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH,
3992          OpCodeIndex::LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH},
3993         {OpCode::LE_READ_LOCAL_P_256_PUBLIC_KEY,
3994          OpCodeIndex::LE_READ_LOCAL_P_256_PUBLIC_KEY},
3995         {OpCode::LE_GENERATE_DHKEY_V1, OpCodeIndex::LE_GENERATE_DHKEY_V1},
3996         {OpCode::LE_ADD_DEVICE_TO_RESOLVING_LIST,
3997          OpCodeIndex::LE_ADD_DEVICE_TO_RESOLVING_LIST},
3998         {OpCode::LE_REMOVE_DEVICE_FROM_RESOLVING_LIST,
3999          OpCodeIndex::LE_REMOVE_DEVICE_FROM_RESOLVING_LIST},
4000         {OpCode::LE_CLEAR_RESOLVING_LIST, OpCodeIndex::LE_CLEAR_RESOLVING_LIST},
4001         {OpCode::LE_READ_RESOLVING_LIST_SIZE,
4002          OpCodeIndex::LE_READ_RESOLVING_LIST_SIZE},
4003         {OpCode::LE_READ_PEER_RESOLVABLE_ADDRESS,
4004          OpCodeIndex::LE_READ_PEER_RESOLVABLE_ADDRESS},
4005         {OpCode::LE_READ_LOCAL_RESOLVABLE_ADDRESS,
4006          OpCodeIndex::LE_READ_LOCAL_RESOLVABLE_ADDRESS},
4007         {OpCode::LE_SET_ADDRESS_RESOLUTION_ENABLE,
4008          OpCodeIndex::LE_SET_ADDRESS_RESOLUTION_ENABLE},
4009         {OpCode::LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT,
4010          OpCodeIndex::LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT},
4011         {OpCode::LE_READ_MAXIMUM_DATA_LENGTH,
4012          OpCodeIndex::LE_READ_MAXIMUM_DATA_LENGTH},
4013         {OpCode::LE_READ_PHY, OpCodeIndex::LE_READ_PHY},
4014         {OpCode::LE_SET_DEFAULT_PHY, OpCodeIndex::LE_SET_DEFAULT_PHY},
4015         {OpCode::LE_SET_PHY, OpCodeIndex::LE_SET_PHY},
4016         {OpCode::LE_RECEIVER_TEST_V2, OpCodeIndex::LE_RECEIVER_TEST_V2},
4017         {OpCode::LE_TRANSMITTER_TEST_V2, OpCodeIndex::LE_TRANSMITTER_TEST_V2},
4018         {OpCode::LE_SET_ADVERTISING_SET_RANDOM_ADDRESS,
4019          OpCodeIndex::LE_SET_ADVERTISING_SET_RANDOM_ADDRESS},
4020         {OpCode::LE_SET_EXTENDED_ADVERTISING_PARAMETERS,
4021          OpCodeIndex::LE_SET_EXTENDED_ADVERTISING_PARAMETERS},
4022         {OpCode::LE_SET_EXTENDED_ADVERTISING_DATA,
4023          OpCodeIndex::LE_SET_EXTENDED_ADVERTISING_DATA},
4024         {OpCode::LE_SET_EXTENDED_SCAN_RESPONSE_DATA,
4025          OpCodeIndex::LE_SET_EXTENDED_SCAN_RESPONSE_DATA},
4026         {OpCode::LE_SET_EXTENDED_ADVERTISING_ENABLE,
4027          OpCodeIndex::LE_SET_EXTENDED_ADVERTISING_ENABLE},
4028         {OpCode::LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH,
4029          OpCodeIndex::LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH},
4030         {OpCode::LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS,
4031          OpCodeIndex::LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS},
4032         {OpCode::LE_REMOVE_ADVERTISING_SET,
4033          OpCodeIndex::LE_REMOVE_ADVERTISING_SET},
4034         {OpCode::LE_CLEAR_ADVERTISING_SETS,
4035          OpCodeIndex::LE_CLEAR_ADVERTISING_SETS},
4036         {OpCode::LE_SET_PERIODIC_ADVERTISING_PARAMETERS,
4037          OpCodeIndex::LE_SET_PERIODIC_ADVERTISING_PARAMETERS},
4038         {OpCode::LE_SET_PERIODIC_ADVERTISING_DATA,
4039          OpCodeIndex::LE_SET_PERIODIC_ADVERTISING_DATA},
4040         {OpCode::LE_SET_PERIODIC_ADVERTISING_ENABLE,
4041          OpCodeIndex::LE_SET_PERIODIC_ADVERTISING_ENABLE},
4042         {OpCode::LE_SET_EXTENDED_SCAN_PARAMETERS,
4043          OpCodeIndex::LE_SET_EXTENDED_SCAN_PARAMETERS},
4044         {OpCode::LE_SET_EXTENDED_SCAN_ENABLE,
4045          OpCodeIndex::LE_SET_EXTENDED_SCAN_ENABLE},
4046         {OpCode::LE_EXTENDED_CREATE_CONNECTION,
4047          OpCodeIndex::LE_EXTENDED_CREATE_CONNECTION},
4048         {OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC,
4049          OpCodeIndex::LE_PERIODIC_ADVERTISING_CREATE_SYNC},
4050         {OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL,
4051          OpCodeIndex::LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL},
4052         {OpCode::LE_PERIODIC_ADVERTISING_TERMINATE_SYNC,
4053          OpCodeIndex::LE_PERIODIC_ADVERTISING_TERMINATE_SYNC},
4054         {OpCode::LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST,
4055          OpCodeIndex::LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST},
4056         {OpCode::LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST,
4057          OpCodeIndex::LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST},
4058         {OpCode::LE_CLEAR_PERIODIC_ADVERTISER_LIST,
4059          OpCodeIndex::LE_CLEAR_PERIODIC_ADVERTISER_LIST},
4060         {OpCode::LE_READ_PERIODIC_ADVERTISER_LIST_SIZE,
4061          OpCodeIndex::LE_READ_PERIODIC_ADVERTISER_LIST_SIZE},
4062         {OpCode::LE_READ_TRANSMIT_POWER, OpCodeIndex::LE_READ_TRANSMIT_POWER},
4063         {OpCode::LE_READ_RF_PATH_COMPENSATION_POWER,
4064          OpCodeIndex::LE_READ_RF_PATH_COMPENSATION_POWER},
4065         {OpCode::LE_WRITE_RF_PATH_COMPENSATION_POWER,
4066          OpCodeIndex::LE_WRITE_RF_PATH_COMPENSATION_POWER},
4067         {OpCode::LE_SET_PRIVACY_MODE, OpCodeIndex::LE_SET_PRIVACY_MODE},
4068         {OpCode::LE_RECEIVER_TEST_V3, OpCodeIndex::LE_RECEIVER_TEST_V3},
4069         {OpCode::LE_TRANSMITTER_TEST_V3, OpCodeIndex::LE_TRANSMITTER_TEST_V3},
4070         {OpCode::LE_SET_CONNECTIONLESS_CTE_TRANSMIT_PARAMETERS,
4071          OpCodeIndex::LE_SET_CONNECTIONLESS_CTE_TRANSMIT_PARAMETERS},
4072         {OpCode::LE_SET_CONNECTIONLESS_CTE_TRANSMIT_ENABLE,
4073          OpCodeIndex::LE_SET_CONNECTIONLESS_CTE_TRANSMIT_ENABLE},
4074         {OpCode::LE_SET_CONNECTIONLESS_IQ_SAMPLING_ENABLE,
4075          OpCodeIndex::LE_SET_CONNECTIONLESS_IQ_SAMPLING_ENABLE},
4076         {OpCode::LE_SET_CONNECTION_CTE_RECEIVE_PARAMETERS,
4077          OpCodeIndex::LE_SET_CONNECTION_CTE_RECEIVE_PARAMETERS},
4078         {OpCode::LE_SET_CONNECTION_CTE_TRANSMIT_PARAMETERS,
4079          OpCodeIndex::LE_SET_CONNECTION_CTE_TRANSMIT_PARAMETERS},
4080         {OpCode::LE_CONNECTION_CTE_REQUEST_ENABLE,
4081          OpCodeIndex::LE_CONNECTION_CTE_REQUEST_ENABLE},
4082         {OpCode::LE_CONNECTION_CTE_RESPONSE_ENABLE,
4083          OpCodeIndex::LE_CONNECTION_CTE_RESPONSE_ENABLE},
4084         {OpCode::LE_READ_ANTENNA_INFORMATION,
4085          OpCodeIndex::LE_READ_ANTENNA_INFORMATION},
4086         {OpCode::LE_SET_PERIODIC_ADVERTISING_RECEIVE_ENABLE,
4087          OpCodeIndex::LE_SET_PERIODIC_ADVERTISING_RECEIVE_ENABLE},
4088         {OpCode::LE_PERIODIC_ADVERTISING_SYNC_TRANSFER,
4089          OpCodeIndex::LE_PERIODIC_ADVERTISING_SYNC_TRANSFER},
4090         {OpCode::LE_PERIODIC_ADVERTISING_SET_INFO_TRANSFER,
4091          OpCodeIndex::LE_PERIODIC_ADVERTISING_SET_INFO_TRANSFER},
4092         {OpCode::LE_SET_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS,
4093          OpCodeIndex::LE_SET_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS},
4094         {OpCode::LE_SET_DEFAULT_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS,
4095          OpCodeIndex::
4096              LE_SET_DEFAULT_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS},
4097         {OpCode::LE_GENERATE_DHKEY_V2, OpCodeIndex::LE_GENERATE_DHKEY_V2},
4098         {OpCode::LE_MODIFY_SLEEP_CLOCK_ACCURACY,
4099          OpCodeIndex::LE_MODIFY_SLEEP_CLOCK_ACCURACY},
4100         {OpCode::LE_READ_BUFFER_SIZE_V2, OpCodeIndex::LE_READ_BUFFER_SIZE_V2},
4101         {OpCode::LE_READ_ISO_TX_SYNC, OpCodeIndex::LE_READ_ISO_TX_SYNC},
4102         {OpCode::LE_SET_CIG_PARAMETERS, OpCodeIndex::LE_SET_CIG_PARAMETERS},
4103         {OpCode::LE_SET_CIG_PARAMETERS_TEST,
4104          OpCodeIndex::LE_SET_CIG_PARAMETERS_TEST},
4105         {OpCode::LE_CREATE_CIS, OpCodeIndex::LE_CREATE_CIS},
4106         {OpCode::LE_REMOVE_CIG, OpCodeIndex::LE_REMOVE_CIG},
4107         {OpCode::LE_ACCEPT_CIS_REQUEST, OpCodeIndex::LE_ACCEPT_CIS_REQUEST},
4108         {OpCode::LE_REJECT_CIS_REQUEST, OpCodeIndex::LE_REJECT_CIS_REQUEST},
4109         {OpCode::LE_CREATE_BIG, OpCodeIndex::LE_CREATE_BIG},
4110         {OpCode::LE_CREATE_BIG_TEST, OpCodeIndex::LE_CREATE_BIG_TEST},
4111         {OpCode::LE_TERMINATE_BIG, OpCodeIndex::LE_TERMINATE_BIG},
4112         {OpCode::LE_BIG_CREATE_SYNC, OpCodeIndex::LE_BIG_CREATE_SYNC},
4113         {OpCode::LE_BIG_TERMINATE_SYNC, OpCodeIndex::LE_BIG_TERMINATE_SYNC},
4114         {OpCode::LE_REQUEST_PEER_SCA, OpCodeIndex::LE_REQUEST_PEER_SCA},
4115         {OpCode::LE_SETUP_ISO_DATA_PATH, OpCodeIndex::LE_SETUP_ISO_DATA_PATH},
4116         {OpCode::LE_REMOVE_ISO_DATA_PATH, OpCodeIndex::LE_REMOVE_ISO_DATA_PATH},
4117         {OpCode::LE_ISO_TRANSMIT_TEST, OpCodeIndex::LE_ISO_TRANSMIT_TEST},
4118         {OpCode::LE_ISO_RECEIVE_TEST, OpCodeIndex::LE_ISO_RECEIVE_TEST},
4119         {OpCode::LE_ISO_READ_TEST_COUNTERS,
4120          OpCodeIndex::LE_ISO_READ_TEST_COUNTERS},
4121         {OpCode::LE_ISO_TEST_END, OpCodeIndex::LE_ISO_TEST_END},
4122         {OpCode::LE_SET_HOST_FEATURE, OpCodeIndex::LE_SET_HOST_FEATURE},
4123         {OpCode::LE_READ_ISO_LINK_QUALITY,
4124          OpCodeIndex::LE_READ_ISO_LINK_QUALITY},
4125         {OpCode::LE_ENHANCED_READ_TRANSMIT_POWER_LEVEL,
4126          OpCodeIndex::LE_ENHANCED_READ_TRANSMIT_POWER_LEVEL},
4127         {OpCode::LE_READ_REMOTE_TRANSMIT_POWER_LEVEL,
4128          OpCodeIndex::LE_READ_REMOTE_TRANSMIT_POWER_LEVEL},
4129         {OpCode::LE_SET_PATH_LOSS_REPORTING_PARAMETERS,
4130          OpCodeIndex::LE_SET_PATH_LOSS_REPORTING_PARAMETERS},
4131         {OpCode::LE_SET_PATH_LOSS_REPORTING_ENABLE,
4132          OpCodeIndex::LE_SET_PATH_LOSS_REPORTING_ENABLE},
4133         {OpCode::LE_SET_TRANSMIT_POWER_REPORTING_ENABLE,
4134          OpCodeIndex::LE_SET_TRANSMIT_POWER_REPORTING_ENABLE},
4135         {OpCode::LE_TRANSMITTER_TEST_V4, OpCodeIndex::LE_TRANSMITTER_TEST_V4},
4136         {OpCode::LE_SET_DATA_RELATED_ADDRESS_CHANGES,
4137          OpCodeIndex::LE_SET_DATA_RELATED_ADDRESS_CHANGES},
4138         {OpCode::LE_SET_DEFAULT_SUBRATE, OpCodeIndex::LE_SET_DEFAULT_SUBRATE},
4139         {OpCode::LE_SUBRATE_REQUEST, OpCodeIndex::LE_SUBRATE_REQUEST},
4140     };
4141 
4142 const std::unordered_map<OpCode, DualModeController::CommandHandler>
4143     DualModeController::hci_command_handlers_{
4144         // LINK_CONTROL
4145         {OpCode::INQUIRY, &DualModeController::Inquiry},
4146         {OpCode::INQUIRY_CANCEL, &DualModeController::InquiryCancel},
4147         //{OpCode::PERIODIC_INQUIRY_MODE,
4148         //&DualModeController::PeriodicInquiryMode},
4149         //{OpCode::EXIT_PERIODIC_INQUIRY_MODE,
4150         //&DualModeController::ExitPeriodicInquiryMode},
4151         {OpCode::CREATE_CONNECTION, &DualModeController::CreateConnection},
4152         {OpCode::DISCONNECT, &DualModeController::Disconnect},
4153         {OpCode::ADD_SCO_CONNECTION, &DualModeController::AddScoConnection},
4154         {OpCode::CREATE_CONNECTION_CANCEL,
4155          &DualModeController::CreateConnectionCancel},
4156         {OpCode::ACCEPT_CONNECTION_REQUEST,
4157          &DualModeController::AcceptConnectionRequest},
4158         {OpCode::REJECT_CONNECTION_REQUEST,
4159          &DualModeController::RejectConnectionRequest},
4160         {OpCode::LINK_KEY_REQUEST_REPLY, &DualModeController::ForwardToLm},
4161         {OpCode::LINK_KEY_REQUEST_NEGATIVE_REPLY,
4162          &DualModeController::ForwardToLm},
4163         {OpCode::PIN_CODE_REQUEST_REPLY, &DualModeController::ForwardToLm},
4164         {OpCode::PIN_CODE_REQUEST_NEGATIVE_REPLY,
4165          &DualModeController::ForwardToLm},
4166         {OpCode::CHANGE_CONNECTION_PACKET_TYPE,
4167          &DualModeController::ChangeConnectionPacketType},
4168         {OpCode::AUTHENTICATION_REQUESTED, &DualModeController::ForwardToLm},
4169         {OpCode::SET_CONNECTION_ENCRYPTION, &DualModeController::ForwardToLm},
4170         {OpCode::CHANGE_CONNECTION_LINK_KEY,
4171          &DualModeController::ChangeConnectionLinkKey},
4172         {OpCode::CENTRAL_LINK_KEY, &DualModeController::CentralLinkKey},
4173         {OpCode::REMOTE_NAME_REQUEST, &DualModeController::RemoteNameRequest},
4174         //{OpCode::REMOTE_NAME_REQUEST_CANCEL,
4175         //&DualModeController::RemoteNameRequestCancel},
4176         {OpCode::READ_REMOTE_SUPPORTED_FEATURES,
4177          &DualModeController::ReadRemoteSupportedFeatures},
4178         {OpCode::READ_REMOTE_EXTENDED_FEATURES,
4179          &DualModeController::ReadRemoteExtendedFeatures},
4180         {OpCode::READ_REMOTE_VERSION_INFORMATION,
4181          &DualModeController::ReadRemoteVersionInformation},
4182         {OpCode::READ_CLOCK_OFFSET, &DualModeController::ReadClockOffset},
4183         //{OpCode::READ_LMP_HANDLE, &DualModeController::ReadLmpHandle},
4184         {OpCode::SETUP_SYNCHRONOUS_CONNECTION,
4185          &DualModeController::SetupSynchronousConnection},
4186         {OpCode::ACCEPT_SYNCHRONOUS_CONNECTION,
4187          &DualModeController::AcceptSynchronousConnection},
4188         {OpCode::REJECT_SYNCHRONOUS_CONNECTION,
4189          &DualModeController::RejectSynchronousConnection},
4190         {OpCode::IO_CAPABILITY_REQUEST_REPLY, &DualModeController::ForwardToLm},
4191         {OpCode::USER_CONFIRMATION_REQUEST_REPLY,
4192          &DualModeController::ForwardToLm},
4193         {OpCode::USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY,
4194          &DualModeController::ForwardToLm},
4195         {OpCode::USER_PASSKEY_REQUEST_REPLY, &DualModeController::ForwardToLm},
4196         {OpCode::USER_PASSKEY_REQUEST_NEGATIVE_REPLY,
4197          &DualModeController::ForwardToLm},
4198         {OpCode::REMOTE_OOB_DATA_REQUEST_REPLY,
4199          &DualModeController::ForwardToLm},
4200         {OpCode::REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY,
4201          &DualModeController::ForwardToLm},
4202         {OpCode::IO_CAPABILITY_REQUEST_NEGATIVE_REPLY,
4203          &DualModeController::ForwardToLm},
4204         {OpCode::ENHANCED_SETUP_SYNCHRONOUS_CONNECTION,
4205          &DualModeController::EnhancedSetupSynchronousConnection},
4206         {OpCode::ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION,
4207          &DualModeController::EnhancedAcceptSynchronousConnection},
4208         //{OpCode::TRUNCATED_PAGE, &DualModeController::TruncatedPage},
4209         //{OpCode::TRUNCATED_PAGE_CANCEL,
4210         //&DualModeController::TruncatedPageCancel},
4211         //{OpCode::SET_CONNECTIONLESS_PERIPHERAL_BROADCAST,
4212         //&DualModeController::SetConnectionlessPeripheralBroadcast},
4213         //{OpCode::SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVE,
4214         //&DualModeController::SetConnectionlessPeripheralBroadcastReceive},
4215         //{OpCode::START_SYNCHRONIZATION_TRAIN,
4216         //&DualModeController::StartSynchronizationTrain},
4217         //{OpCode::RECEIVE_SYNCHRONIZATION_TRAIN,
4218         //&DualModeController::ReceiveSynchronizationTrain},
4219         {OpCode::REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY,
4220          &DualModeController::ForwardToLm},
4221 
4222         // LINK_POLICY
4223         {OpCode::HOLD_MODE, &DualModeController::HoldMode},
4224         {OpCode::SNIFF_MODE, &DualModeController::SniffMode},
4225         {OpCode::EXIT_SNIFF_MODE, &DualModeController::ExitSniffMode},
4226         {OpCode::QOS_SETUP, &DualModeController::QosSetup},
4227         {OpCode::ROLE_DISCOVERY, &DualModeController::RoleDiscovery},
4228         {OpCode::SWITCH_ROLE, &DualModeController::SwitchRole},
4229         {OpCode::READ_LINK_POLICY_SETTINGS,
4230          &DualModeController::ReadLinkPolicySettings},
4231         {OpCode::WRITE_LINK_POLICY_SETTINGS,
4232          &DualModeController::WriteLinkPolicySettings},
4233         {OpCode::READ_DEFAULT_LINK_POLICY_SETTINGS,
4234          &DualModeController::ReadDefaultLinkPolicySettings},
4235         {OpCode::WRITE_DEFAULT_LINK_POLICY_SETTINGS,
4236          &DualModeController::WriteDefaultLinkPolicySettings},
4237         {OpCode::FLOW_SPECIFICATION, &DualModeController::FlowSpecification},
4238         {OpCode::SNIFF_SUBRATING, &DualModeController::SniffSubrating},
4239 
4240         // CONTROLLER_AND_BASEBAND
4241         {OpCode::SET_EVENT_MASK, &DualModeController::SetEventMask},
4242         {OpCode::RESET, &DualModeController::Reset},
4243         {OpCode::SET_EVENT_FILTER, &DualModeController::SetEventFilter},
4244         //{OpCode::FLUSH, &DualModeController::Flush},
4245         //{OpCode::READ_PIN_TYPE, &DualModeController::ReadPinType},
4246         //{OpCode::WRITE_PIN_TYPE, &DualModeController::WritePinType},
4247         //{OpCode::READ_STORED_LINK_KEY,
4248         //&DualModeController::ReadStoredLinkKey},
4249         //{OpCode::WRITE_STORED_LINK_KEY,
4250         //&DualModeController::WriteStoredLinkKey},
4251         {OpCode::DELETE_STORED_LINK_KEY,
4252          &DualModeController::DeleteStoredLinkKey},
4253         {OpCode::WRITE_LOCAL_NAME, &DualModeController::WriteLocalName},
4254         {OpCode::READ_LOCAL_NAME, &DualModeController::ReadLocalName},
4255         {OpCode::READ_CONNECTION_ACCEPT_TIMEOUT,
4256          &DualModeController::ReadConnectionAcceptTimeout},
4257         {OpCode::WRITE_CONNECTION_ACCEPT_TIMEOUT,
4258          &DualModeController::WriteConnectionAcceptTimeout},
4259         {OpCode::READ_PAGE_TIMEOUT, &DualModeController::ReadPageTimeout},
4260         {OpCode::WRITE_PAGE_TIMEOUT, &DualModeController::WritePageTimeout},
4261         {OpCode::READ_SCAN_ENABLE, &DualModeController::ReadScanEnable},
4262         {OpCode::WRITE_SCAN_ENABLE, &DualModeController::WriteScanEnable},
4263         {OpCode::READ_PAGE_SCAN_ACTIVITY,
4264          &DualModeController::ReadPageScanActivity},
4265         {OpCode::WRITE_PAGE_SCAN_ACTIVITY,
4266          &DualModeController::WritePageScanActivity},
4267         {OpCode::READ_INQUIRY_SCAN_ACTIVITY,
4268          &DualModeController::ReadInquiryScanActivity},
4269         {OpCode::WRITE_INQUIRY_SCAN_ACTIVITY,
4270          &DualModeController::WriteInquiryScanActivity},
4271         {OpCode::READ_AUTHENTICATION_ENABLE,
4272          &DualModeController::ReadAuthenticationEnable},
4273         {OpCode::WRITE_AUTHENTICATION_ENABLE,
4274          &DualModeController::WriteAuthenticationEnable},
4275         {OpCode::READ_CLASS_OF_DEVICE, &DualModeController::ReadClassOfDevice},
4276         {OpCode::WRITE_CLASS_OF_DEVICE,
4277          &DualModeController::WriteClassOfDevice},
4278         {OpCode::READ_VOICE_SETTING, &DualModeController::ReadVoiceSetting},
4279         {OpCode::WRITE_VOICE_SETTING, &DualModeController::WriteVoiceSetting},
4280         //{OpCode::READ_AUTOMATIC_FLUSH_TIMEOUT,
4281         //&DualModeController::ReadAutomaticFlushTimeout},
4282         //{OpCode::WRITE_AUTOMATIC_FLUSH_TIMEOUT,
4283         //&DualModeController::WriteAutomaticFlushTimeout},
4284         //{OpCode::READ_NUM_BROADCAST_RETRANSMITS,
4285         //&DualModeController::ReadNumBroadcastRetransmits},
4286         //{OpCode::WRITE_NUM_BROADCAST_RETRANSMITS,
4287         //&DualModeController::WriteNumBroadcastRetransmits},
4288         //{OpCode::READ_HOLD_MODE_ACTIVITY,
4289         //&DualModeController::ReadHoldModeActivity},
4290         //{OpCode::WRITE_HOLD_MODE_ACTIVITY,
4291         //&DualModeController::WriteHoldModeActivity},
4292         {OpCode::READ_TRANSMIT_POWER_LEVEL,
4293          &DualModeController::ReadTransmitPowerLevel},
4294         {OpCode::READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE,
4295          &DualModeController::ReadSynchronousFlowControlEnable},
4296         {OpCode::WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE,
4297          &DualModeController::WriteSynchronousFlowControlEnable},
4298         //{OpCode::SET_CONTROLLER_TO_HOST_FLOW_CONTROL,
4299         //&DualModeController::SetControllerToHostFlowControl},
4300         {OpCode::HOST_BUFFER_SIZE, &DualModeController::HostBufferSize},
4301         //{OpCode::HOST_NUMBER_OF_COMPLETED_PACKETS,
4302         //&DualModeController::HostNumberOfCompletedPackets},
4303         //{OpCode::READ_LINK_SUPERVISION_TIMEOUT,
4304         //&DualModeController::ReadLinkSupervisionTimeout},
4305         {OpCode::WRITE_LINK_SUPERVISION_TIMEOUT,
4306          &DualModeController::WriteLinkSupervisionTimeout},
4307         {OpCode::READ_NUMBER_OF_SUPPORTED_IAC,
4308          &DualModeController::ReadNumberOfSupportedIac},
4309         {OpCode::READ_CURRENT_IAC_LAP, &DualModeController::ReadCurrentIacLap},
4310         {OpCode::WRITE_CURRENT_IAC_LAP,
4311          &DualModeController::WriteCurrentIacLap},
4312         //{OpCode::SET_AFH_HOST_CHANNEL_CLASSIFICATION,
4313         //&DualModeController::SetAfhHostChannelClassification},
4314         {OpCode::READ_INQUIRY_SCAN_TYPE,
4315          &DualModeController::ReadInquiryScanType},
4316         {OpCode::WRITE_INQUIRY_SCAN_TYPE,
4317          &DualModeController::WriteInquiryScanType},
4318         {OpCode::READ_INQUIRY_MODE, &DualModeController::ReadInquiryMode},
4319         {OpCode::WRITE_INQUIRY_MODE, &DualModeController::WriteInquiryMode},
4320         {OpCode::READ_PAGE_SCAN_TYPE, &DualModeController::ReadPageScanType},
4321         {OpCode::WRITE_PAGE_SCAN_TYPE, &DualModeController::WritePageScanType},
4322         //{OpCode::READ_AFH_CHANNEL_ASSESSMENT_MODE,
4323         //&DualModeController::ReadAfhChannelAssessmentMode},
4324         //{OpCode::WRITE_AFH_CHANNEL_ASSESSMENT_MODE,
4325         //&DualModeController::WriteAfhChannelAssessmentMode},
4326         //{OpCode::READ_EXTENDED_INQUIRY_RESPONSE,
4327         //&DualModeController::ReadExtendedInquiryResponse},
4328         {OpCode::WRITE_EXTENDED_INQUIRY_RESPONSE,
4329          &DualModeController::WriteExtendedInquiryResponse},
4330         {OpCode::REFRESH_ENCRYPTION_KEY,
4331          &DualModeController::RefreshEncryptionKey},
4332         //{OpCode::READ_SIMPLE_PAIRING_MODE,
4333         //&DualModeController::ReadSimplePairingMode},
4334         {OpCode::WRITE_SIMPLE_PAIRING_MODE,
4335          &DualModeController::WriteSimplePairingMode},
4336         {OpCode::READ_LOCAL_OOB_DATA, &DualModeController::ReadLocalOobData},
4337         {OpCode::READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL,
4338          &DualModeController::ReadInquiryResponseTransmitPowerLevel},
4339         //{OpCode::WRITE_INQUIRY_TRANSMIT_POWER_LEVEL,
4340         //&DualModeController::WriteInquiryTransmitPowerLevel},
4341         //{OpCode::READ_DEFAULT_ERRONEOUS_DATA_REPORTING,
4342         //&DualModeController::ReadDefaultErroneousDataReporting},
4343         //{OpCode::WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING,
4344         //&DualModeController::WriteDefaultErroneousDataReporting},
4345         {OpCode::ENHANCED_FLUSH, &DualModeController::EnhancedFlush},
4346         {OpCode::SEND_KEYPRESS_NOTIFICATION, &DualModeController::ForwardToLm},
4347         {OpCode::SET_EVENT_MASK_PAGE_2, &DualModeController::SetEventMaskPage2},
4348         //{OpCode::READ_FLOW_CONTROL_MODE,
4349         //&DualModeController::ReadFlowControlMode},
4350         //{OpCode::WRITE_FLOW_CONTROL_MODE,
4351         //&DualModeController::WriteFlowControlMode},
4352         {OpCode::READ_ENHANCED_TRANSMIT_POWER_LEVEL,
4353          &DualModeController::ReadEnhancedTransmitPowerLevel},
4354         //{OpCode::READ_LE_HOST_SUPPORT,
4355         //&DualModeController::ReadLeHostSupport},
4356         {OpCode::WRITE_LE_HOST_SUPPORT,
4357          &DualModeController::WriteLeHostSupport},
4358         //{OpCode::SET_MWS_CHANNEL_PARAMETERS,
4359         //&DualModeController::SetMwsChannelParameters},
4360         //{OpCode::SET_EXTERNAL_FRAME_CONFIGURATION,
4361         //&DualModeController::SetExternalFrameConfiguration},
4362         //{OpCode::SET_MWS_SIGNALING, &DualModeController::SetMwsSignaling},
4363         //{OpCode::SET_MWS_TRANSPORT_LAYER,
4364         //&DualModeController::SetMwsTransportLayer},
4365         //{OpCode::SET_MWS_SCAN_FREQUENCY_TABLE,
4366         //&DualModeController::SetMwsScanFrequencyTable},
4367         //{OpCode::SET_MWS_PATTERN_CONFIGURATION,
4368         //&DualModeController::SetMwsPatternConfiguration},
4369         //{OpCode::SET_RESERVED_LT_ADDR,
4370         //&DualModeController::SetReservedLtAddr},
4371         //{OpCode::DELETE_RESERVED_LT_ADDR,
4372         //&DualModeController::DeleteReservedLtAddr},
4373         //{OpCode::SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_DATA,
4374         //&DualModeController::SetConnectionlessPeripheralBroadcastData},
4375         //{OpCode::READ_SYNCHRONIZATION_TRAIN_PARAMETERS,
4376         //&DualModeController::ReadSynchronizationTrainParameters},
4377         //{OpCode::WRITE_SYNCHRONIZATION_TRAIN_PARAMETERS,
4378         //&DualModeController::WriteSynchronizationTrainParameters},
4379         //{OpCode::READ_SECURE_CONNECTIONS_HOST_SUPPORT,
4380         //&DualModeController::ReadSecureConnectionsHostSupport},
4381         {OpCode::WRITE_SECURE_CONNECTIONS_HOST_SUPPORT,
4382          &DualModeController::WriteSecureConnectionsHostSupport},
4383         //{OpCode::READ_AUTHENTICATED_PAYLOAD_TIMEOUT,
4384         //&DualModeController::ReadAuthenticatedPayloadTimeout},
4385         //{OpCode::WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT,
4386         //&DualModeController::WriteAuthenticatedPayloadTimeout},
4387         {OpCode::READ_LOCAL_OOB_EXTENDED_DATA,
4388          &DualModeController::ReadLocalOobExtendedData},
4389         //{OpCode::READ_EXTENDED_PAGE_TIMEOUT,
4390         //&DualModeController::ReadExtendedPageTimeout},
4391         //{OpCode::WRITE_EXTENDED_PAGE_TIMEOUT,
4392         //&DualModeController::WriteExtendedPageTimeout},
4393         //{OpCode::READ_EXTENDED_INQUIRY_LENGTH,
4394         //&DualModeController::ReadExtendedInquiryLength},
4395         //{OpCode::WRITE_EXTENDED_INQUIRY_LENGTH,
4396         //&DualModeController::WriteExtendedInquiryLength},
4397         //{OpCode::SET_ECOSYSTEM_BASE_INTERVAL,
4398         //&DualModeController::SetEcosystemBaseInterval},
4399         //{OpCode::CONFIGURE_DATA_PATH, &DualModeController::ConfigureDataPath},
4400         //{OpCode::SET_MIN_ENCRYPTION_KEY_SIZE,
4401         //&DualModeController::SetMinEncryptionKeySize},
4402 
4403         // INFORMATIONAL_PARAMETERS
4404         {OpCode::READ_LOCAL_VERSION_INFORMATION,
4405          &DualModeController::ReadLocalVersionInformation},
4406         {OpCode::READ_LOCAL_SUPPORTED_COMMANDS,
4407          &DualModeController::ReadLocalSupportedCommands},
4408         {OpCode::READ_LOCAL_SUPPORTED_FEATURES,
4409          &DualModeController::ReadLocalSupportedFeatures},
4410         {OpCode::READ_LOCAL_EXTENDED_FEATURES,
4411          &DualModeController::ReadLocalExtendedFeatures},
4412         {OpCode::READ_BUFFER_SIZE, &DualModeController::ReadBufferSize},
4413         {OpCode::READ_BD_ADDR, &DualModeController::ReadBdAddr},
4414         //{OpCode::READ_DATA_BLOCK_SIZE,
4415         //&DualModeController::ReadDataBlockSize},
4416         {OpCode::READ_LOCAL_SUPPORTED_CODECS_V1,
4417          &DualModeController::ReadLocalSupportedCodecsV1},
4418         //{OpCode::READ_LOCAL_SIMPLE_PAIRING_OPTIONS,
4419         //&DualModeController::ReadLocalSimplePairingOptions},
4420         //{OpCode::READ_LOCAL_SUPPORTED_CODECS_V2,
4421         //&DualModeController::ReadLocalSupportedCodecsV2},
4422         //{OpCode::READ_LOCAL_SUPPORTED_CODEC_CAPABILITIES,
4423         //&DualModeController::ReadLocalSupportedCodecCapabilities},
4424         //{OpCode::READ_LOCAL_SUPPORTED_CONTROLLER_DELAY,
4425         //&DualModeController::ReadLocalSupportedControllerDelay},
4426 
4427         // STATUS_PARAMETERS
4428         {OpCode::READ_FAILED_CONTACT_COUNTER,
4429          &DualModeController::ReadFailedContactCounter},
4430         {OpCode::RESET_FAILED_CONTACT_COUNTER,
4431          &DualModeController::ResetFailedContactCounter},
4432         //{OpCode::READ_LINK_QUALITY, &DualModeController::ReadLinkQuality},
4433         {OpCode::READ_RSSI, &DualModeController::ReadRssi},
4434         //{OpCode::READ_AFH_CHANNEL_MAP,
4435         //&DualModeController::ReadAfhChannelMap},
4436         //{OpCode::READ_CLOCK, &DualModeController::ReadClock},
4437         {OpCode::READ_ENCRYPTION_KEY_SIZE,
4438          &DualModeController::ReadEncryptionKeySize},
4439         //{OpCode::GET_MWS_TRANSPORT_LAYER_CONFIGURATION,
4440         //&DualModeController::GetMwsTransportLayerConfiguration},
4441         //{OpCode::SET_TRIGGERED_CLOCK_CAPTURE,
4442         //&DualModeController::SetTriggeredClockCapture},
4443 
4444         // TESTING
4445         {OpCode::READ_LOOPBACK_MODE, &DualModeController::ReadLoopbackMode},
4446         {OpCode::WRITE_LOOPBACK_MODE, &DualModeController::WriteLoopbackMode},
4447         //{OpCode::ENABLE_DEVICE_UNDER_TEST_MODE,
4448         //&DualModeController::EnableDeviceUnderTestMode},
4449         //{OpCode::WRITE_SIMPLE_PAIRING_DEBUG_MODE,
4450         //&DualModeController::WriteSimplePairingDebugMode},
4451         //{OpCode::WRITE_SECURE_CONNECTIONS_TEST_MODE,
4452         //&DualModeController::WriteSecureConnectionsTestMode},
4453 
4454         // LE_CONTROLLER
4455         {OpCode::LE_SET_EVENT_MASK, &DualModeController::LeSetEventMask},
4456         {OpCode::LE_READ_BUFFER_SIZE_V1,
4457          &DualModeController::LeReadBufferSizeV1},
4458         {OpCode::LE_READ_LOCAL_SUPPORTED_FEATURES,
4459          &DualModeController::LeReadLocalSupportedFeatures},
4460         {OpCode::LE_SET_RANDOM_ADDRESS,
4461          &DualModeController::LeSetRandomAddress},
4462         {OpCode::LE_SET_ADVERTISING_PARAMETERS,
4463          &DualModeController::LeSetAdvertisingParameters},
4464         {OpCode::LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER,
4465          &DualModeController::LeReadAdvertisingPhysicalChannelTxPower},
4466         {OpCode::LE_SET_ADVERTISING_DATA,
4467          &DualModeController::LeSetAdvertisingData},
4468         {OpCode::LE_SET_SCAN_RESPONSE_DATA,
4469          &DualModeController::LeSetScanResponseData},
4470         {OpCode::LE_SET_ADVERTISING_ENABLE,
4471          &DualModeController::LeSetAdvertisingEnable},
4472         {OpCode::LE_SET_SCAN_PARAMETERS,
4473          &DualModeController::LeSetScanParameters},
4474         {OpCode::LE_SET_SCAN_ENABLE, &DualModeController::LeSetScanEnable},
4475         {OpCode::LE_CREATE_CONNECTION, &DualModeController::LeCreateConnection},
4476         {OpCode::LE_CREATE_CONNECTION_CANCEL,
4477          &DualModeController::LeCreateConnectionCancel},
4478         {OpCode::LE_READ_FILTER_ACCEPT_LIST_SIZE,
4479          &DualModeController::LeReadFilterAcceptListSize},
4480         {OpCode::LE_CLEAR_FILTER_ACCEPT_LIST,
4481          &DualModeController::LeClearFilterAcceptList},
4482         {OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST,
4483          &DualModeController::LeAddDeviceToFilterAcceptList},
4484         {OpCode::LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST,
4485          &DualModeController::LeRemoveDeviceFromFilterAcceptList},
4486         {OpCode::LE_CONNECTION_UPDATE, &DualModeController::LeConnectionUpdate},
4487         //{OpCode::LE_SET_HOST_CHANNEL_CLASSIFICATION,
4488         //&DualModeController::LeSetHostChannelClassification},
4489         //{OpCode::LE_READ_CHANNEL_MAP, &DualModeController::LeReadChannelMap},
4490         {OpCode::LE_READ_REMOTE_FEATURES,
4491          &DualModeController::LeReadRemoteFeatures},
4492         {OpCode::LE_ENCRYPT, &DualModeController::LeEncrypt},
4493         {OpCode::LE_RAND, &DualModeController::LeRand},
4494         {OpCode::LE_START_ENCRYPTION, &DualModeController::LeStartEncryption},
4495         {OpCode::LE_LONG_TERM_KEY_REQUEST_REPLY,
4496          &DualModeController::LeLongTermKeyRequestReply},
4497         {OpCode::LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY,
4498          &DualModeController::LeLongTermKeyRequestNegativeReply},
4499         {OpCode::LE_READ_SUPPORTED_STATES,
4500          &DualModeController::LeReadSupportedStates},
4501         //{OpCode::LE_RECEIVER_TEST_V1, &DualModeController::LeReceiverTestV1},
4502         //{OpCode::LE_TRANSMITTER_TEST_V1,
4503         //&DualModeController::LeTransmitterTestV1},
4504         //{OpCode::LE_TEST_END, &DualModeController::LeTestEnd},
4505         {OpCode::LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY,
4506          &DualModeController::LeRemoteConnectionParameterRequestReply},
4507         {OpCode::LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY,
4508          &DualModeController::LeRemoteConnectionParameterRequestNegativeReply},
4509         //{OpCode::LE_SET_DATA_LENGTH, &DualModeController::LeSetDataLength},
4510         {OpCode::LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH,
4511          &DualModeController::LeReadSuggestedDefaultDataLength},
4512         {OpCode::LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH,
4513          &DualModeController::LeWriteSuggestedDefaultDataLength},
4514         //{OpCode::LE_READ_LOCAL_P_256_PUBLIC_KEY,
4515         //&DualModeController::LeReadLocalP256PublicKey},
4516         //{OpCode::LE_GENERATE_DHKEY_V1,
4517         //&DualModeController::LeGenerateDhkeyV1},
4518         {OpCode::LE_ADD_DEVICE_TO_RESOLVING_LIST,
4519          &DualModeController::LeAddDeviceToResolvingList},
4520         {OpCode::LE_REMOVE_DEVICE_FROM_RESOLVING_LIST,
4521          &DualModeController::LeRemoveDeviceFromResolvingList},
4522         {OpCode::LE_CLEAR_RESOLVING_LIST,
4523          &DualModeController::LeClearResolvingList},
4524         {OpCode::LE_READ_RESOLVING_LIST_SIZE,
4525          &DualModeController::LeReadResolvingListSize},
4526         {OpCode::LE_READ_PEER_RESOLVABLE_ADDRESS,
4527          &DualModeController::LeReadPeerResolvableAddress},
4528         {OpCode::LE_READ_LOCAL_RESOLVABLE_ADDRESS,
4529          &DualModeController::LeReadLocalResolvableAddress},
4530         {OpCode::LE_SET_ADDRESS_RESOLUTION_ENABLE,
4531          &DualModeController::LeSetAddressResolutionEnable},
4532         {OpCode::LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT,
4533          &DualModeController::LeSetResolvablePrivateAddressTimeout},
4534         {OpCode::LE_READ_MAXIMUM_DATA_LENGTH,
4535          &DualModeController::LeReadMaximumDataLength},
4536         {OpCode::LE_READ_PHY, &DualModeController::LeReadPhy},
4537         {OpCode::LE_SET_DEFAULT_PHY, &DualModeController::LeSetDefaultPhy},
4538         {OpCode::LE_SET_PHY, &DualModeController::LeSetPhy},
4539         //{OpCode::LE_RECEIVER_TEST_V2, &DualModeController::LeReceiverTestV2},
4540         //{OpCode::LE_TRANSMITTER_TEST_V2,
4541         //&DualModeController::LeTransmitterTestV2},
4542         {OpCode::LE_SET_ADVERTISING_SET_RANDOM_ADDRESS,
4543          &DualModeController::LeSetAdvertisingSetRandomAddress},
4544         {OpCode::LE_SET_EXTENDED_ADVERTISING_PARAMETERS,
4545          &DualModeController::LeSetExtendedAdvertisingParameters},
4546         {OpCode::LE_SET_EXTENDED_ADVERTISING_DATA,
4547          &DualModeController::LeSetExtendedAdvertisingData},
4548         {OpCode::LE_SET_EXTENDED_SCAN_RESPONSE_DATA,
4549          &DualModeController::LeSetExtendedScanResponseData},
4550         {OpCode::LE_SET_EXTENDED_ADVERTISING_ENABLE,
4551          &DualModeController::LeSetExtendedAdvertisingEnable},
4552         {OpCode::LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH,
4553          &DualModeController::LeReadMaximumAdvertisingDataLength},
4554         {OpCode::LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS,
4555          &DualModeController::LeReadNumberOfSupportedAdvertisingSets},
4556         {OpCode::LE_REMOVE_ADVERTISING_SET,
4557          &DualModeController::LeRemoveAdvertisingSet},
4558         {OpCode::LE_CLEAR_ADVERTISING_SETS,
4559          &DualModeController::LeClearAdvertisingSets},
4560         {OpCode::LE_SET_PERIODIC_ADVERTISING_PARAMETERS,
4561          &DualModeController::LeSetPeriodicAdvertisingParameters},
4562         {OpCode::LE_SET_PERIODIC_ADVERTISING_DATA,
4563          &DualModeController::LeSetPeriodicAdvertisingData},
4564         {OpCode::LE_SET_PERIODIC_ADVERTISING_ENABLE,
4565          &DualModeController::LeSetPeriodicAdvertisingEnable},
4566         {OpCode::LE_SET_EXTENDED_SCAN_PARAMETERS,
4567          &DualModeController::LeSetExtendedScanParameters},
4568         {OpCode::LE_SET_EXTENDED_SCAN_ENABLE,
4569          &DualModeController::LeSetExtendedScanEnable},
4570         {OpCode::LE_EXTENDED_CREATE_CONNECTION,
4571          &DualModeController::LeExtendedCreateConnection},
4572         {OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC,
4573          &DualModeController::LePeriodicAdvertisingCreateSync},
4574         {OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL,
4575          &DualModeController::LePeriodicAdvertisingCreateSyncCancel},
4576         {OpCode::LE_PERIODIC_ADVERTISING_TERMINATE_SYNC,
4577          &DualModeController::LePeriodicAdvertisingTerminateSync},
4578         {OpCode::LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST,
4579          &DualModeController::LeAddDeviceToPeriodicAdvertiserList},
4580         {OpCode::LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST,
4581          &DualModeController::LeRemoveDeviceFromPeriodicAdvertiserList},
4582         {OpCode::LE_CLEAR_PERIODIC_ADVERTISER_LIST,
4583          &DualModeController::LeClearPeriodicAdvertiserList},
4584         {OpCode::LE_READ_PERIODIC_ADVERTISER_LIST_SIZE,
4585          &DualModeController::LeReadPeriodicAdvertiserListSize},
4586         //{OpCode::LE_READ_TRANSMIT_POWER,
4587         //&DualModeController::LeReadTransmitPower},
4588         //{OpCode::LE_READ_RF_PATH_COMPENSATION_POWER,
4589         //&DualModeController::LeReadRfPathCompensationPower},
4590         //{OpCode::LE_WRITE_RF_PATH_COMPENSATION_POWER,
4591         //&DualModeController::LeWriteRfPathCompensationPower},
4592         {OpCode::LE_SET_PRIVACY_MODE, &DualModeController::LeSetPrivacyMode},
4593         //{OpCode::LE_RECEIVER_TEST_V3, &DualModeController::LeReceiverTestV3},
4594         //{OpCode::LE_TRANSMITTER_TEST_V3,
4595         //&DualModeController::LeTransmitterTestV3},
4596         //{OpCode::LE_SET_CONNECTIONLESS_CTE_TRANSMIT_PARAMETERS,
4597         //&DualModeController::LeSetConnectionlessCteTransmitParameters},
4598         //{OpCode::LE_SET_CONNECTIONLESS_CTE_TRANSMIT_ENABLE,
4599         //&DualModeController::LeSetConnectionlessCteTransmitEnable},
4600         //{OpCode::LE_SET_CONNECTIONLESS_IQ_SAMPLING_ENABLE,
4601         //&DualModeController::LeSetConnectionlessIqSamplingEnable},
4602         //{OpCode::LE_SET_CONNECTION_CTE_RECEIVE_PARAMETERS,
4603         //&DualModeController::LeSetConnectionCteReceiveParameters},
4604         //{OpCode::LE_SET_CONNECTION_CTE_TRANSMIT_PARAMETERS,
4605         //&DualModeController::LeSetConnectionCteTransmitParameters},
4606         //{OpCode::LE_CONNECTION_CTE_REQUEST_ENABLE,
4607         //&DualModeController::LeConnectionCteRequestEnable},
4608         //{OpCode::LE_CONNECTION_CTE_RESPONSE_ENABLE,
4609         //&DualModeController::LeConnectionCteResponseEnable},
4610         //{OpCode::LE_READ_ANTENNA_INFORMATION,
4611         //&DualModeController::LeReadAntennaInformation},
4612         //{OpCode::LE_SET_PERIODIC_ADVERTISING_RECEIVE_ENABLE,
4613         //&DualModeController::LeSetPeriodicAdvertisingReceiveEnable},
4614         //{OpCode::LE_PERIODIC_ADVERTISING_SYNC_TRANSFER,
4615         //&DualModeController::LePeriodicAdvertisingSyncTransfer},
4616         //{OpCode::LE_PERIODIC_ADVERTISING_SET_INFO_TRANSFER,
4617         //&DualModeController::LePeriodicAdvertisingSetInfoTransfer},
4618         //{OpCode::LE_SET_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS,
4619         //&DualModeController::LeSetPeriodicAdvertisingSyncTransferParameters},
4620         //{OpCode::LE_SET_DEFAULT_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS,
4621         //&DualModeController::LeSetDefaultPeriodicAdvertisingSyncTransferParameters},
4622         //{OpCode::LE_GENERATE_DHKEY_V2,
4623         //&DualModeController::LeGenerateDhkeyV2},
4624         //{OpCode::LE_MODIFY_SLEEP_CLOCK_ACCURACY,
4625         //&DualModeController::LeModifySleepClockAccuracy},
4626         {OpCode::LE_READ_BUFFER_SIZE_V2,
4627          &DualModeController::LeReadBufferSizeV2},
4628         //{OpCode::LE_READ_ISO_TX_SYNC, &DualModeController::LeReadIsoTxSync},
4629         {OpCode::LE_SET_CIG_PARAMETERS, &DualModeController::ForwardToLl},
4630         {OpCode::LE_SET_CIG_PARAMETERS_TEST, &DualModeController::ForwardToLl},
4631         {OpCode::LE_CREATE_CIS, &DualModeController::ForwardToLl},
4632         {OpCode::LE_REMOVE_CIG, &DualModeController::ForwardToLl},
4633         {OpCode::LE_ACCEPT_CIS_REQUEST, &DualModeController::ForwardToLl},
4634         {OpCode::LE_REJECT_CIS_REQUEST, &DualModeController::ForwardToLl},
4635         //{OpCode::LE_CREATE_BIG, &DualModeController::LeCreateBig},
4636         //{OpCode::LE_CREATE_BIG_TEST, &DualModeController::LeCreateBigTest},
4637         //{OpCode::LE_TERMINATE_BIG, &DualModeController::LeTerminateBig},
4638         //{OpCode::LE_BIG_CREATE_SYNC, &DualModeController::LeBigCreateSync},
4639         //{OpCode::LE_BIG_TERMINATE_SYNC,
4640         //&DualModeController::LeBigTerminateSync},
4641         {OpCode::LE_REQUEST_PEER_SCA, &DualModeController::LeRequestPeerSca},
4642         {OpCode::LE_SETUP_ISO_DATA_PATH, &DualModeController::ForwardToLl},
4643         {OpCode::LE_REMOVE_ISO_DATA_PATH, &DualModeController::ForwardToLl},
4644         //{OpCode::LE_ISO_TRANSMIT_TEST,
4645         //&DualModeController::LeIsoTransmitTest},
4646         //{OpCode::LE_ISO_RECEIVE_TEST, &DualModeController::LeIsoReceiveTest},
4647         //{OpCode::LE_ISO_READ_TEST_COUNTERS,
4648         //&DualModeController::LeIsoReadTestCounters},
4649         //{OpCode::LE_ISO_TEST_END, &DualModeController::LeIsoTestEnd},
4650         {OpCode::LE_SET_HOST_FEATURE, &DualModeController::LeSetHostFeature},
4651         //{OpCode::LE_READ_ISO_LINK_QUALITY,
4652         //&DualModeController::LeReadIsoLinkQuality},
4653         //{OpCode::LE_ENHANCED_READ_TRANSMIT_POWER_LEVEL,
4654         //&DualModeController::LeEnhancedReadTransmitPowerLevel},
4655         //{OpCode::LE_READ_REMOTE_TRANSMIT_POWER_LEVEL,
4656         //&DualModeController::LeReadRemoteTransmitPowerLevel},
4657         //{OpCode::LE_SET_PATH_LOSS_REPORTING_PARAMETERS,
4658         //&DualModeController::LeSetPathLossReportingParameters},
4659         //{OpCode::LE_SET_PATH_LOSS_REPORTING_ENABLE,
4660         //&DualModeController::LeSetPathLossReportingEnable},
4661         //{OpCode::LE_SET_TRANSMIT_POWER_REPORTING_ENABLE,
4662         //&DualModeController::LeSetTransmitPowerReportingEnable},
4663         //{OpCode::LE_TRANSMITTER_TEST_V4,
4664         //&DualModeController::LeTransmitterTestV4},
4665         //{OpCode::LE_SET_DATA_RELATED_ADDRESS_CHANGES,
4666         //&DualModeController::LeSetDataRelatedAddressChanges},
4667         //{OpCode::LE_SET_DEFAULT_SUBRATE,
4668         //&DualModeController::LeSetDefaultSubrate},
4669         //{OpCode::LE_SUBRATE_REQUEST, &DualModeController::LeSubrateRequest},
4670 
4671         // VENDOR
4672         {OpCode(CSR_VENDOR), &DualModeController::CsrVendorCommand},
4673         {OpCode::LE_GET_VENDOR_CAPABILITIES,
4674          &DualModeController::LeGetVendorCapabilities},
4675         {OpCode::LE_BATCH_SCAN, &DualModeController::LeBatchScan},
4676         {OpCode::LE_APCF, &DualModeController::LeApcf},
4677         {OpCode::LE_GET_CONTROLLER_ACTIVITY_ENERGY_INFO,
4678          &DualModeController::LeGetControllerActivityEnergyInfo},
4679         {OpCode::LE_EX_SET_SCAN_PARAMETERS,
4680          &DualModeController::LeExSetScanParameters},
4681         {OpCode::GET_CONTROLLER_DEBUG_INFO,
4682          &DualModeController::GetControllerDebugInfo}};
4683 
4684 }  // namespace rootcanal
4685