• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "dual_mode_controller.h"
18 
19 #include <algorithm>
20 #include <memory>
21 #include <random>
22 
23 #include "crypto/crypto.h"
24 #include "log.h"
25 #include "packet/raw_builder.h"
26 
27 using bluetooth::hci::ErrorCode;
28 using bluetooth::hci::LoopbackMode;
29 using bluetooth::hci::OpCode;
30 using std::vector;
31 
32 namespace rootcanal {
33 constexpr uint16_t kNumCommandPackets = 0x01;
34 constexpr uint16_t kLeMaximumDataLength = 64;
35 constexpr uint16_t kLeMaximumDataTime = 0x148;
36 
37 // Device methods.
GetTypeString() const38 std::string DualModeController::GetTypeString() const {
39   return "Simulated Bluetooth Controller";
40 }
41 
ReceiveLinkLayerPacket(model::packets::LinkLayerPacketView incoming,Phy::Type,int8_t rssi)42 void DualModeController::ReceiveLinkLayerPacket(
43     model::packets::LinkLayerPacketView incoming, Phy::Type /*type*/,
44     int8_t rssi) {
45   link_layer_controller_.IncomingPacket(incoming, rssi);
46 }
47 
Tick()48 void DualModeController::Tick() { link_layer_controller_.Tick(); }
49 
Close()50 void DualModeController::Close() {
51   link_layer_controller_.Close();
52   Device::Close();
53 }
54 
SendCommandCompleteUnknownOpCodeEvent(bluetooth::hci::OpCode op_code) const55 void DualModeController::SendCommandCompleteUnknownOpCodeEvent(
56     bluetooth::hci::OpCode op_code) const {
57   send_event_(bluetooth::hci::CommandCompleteBuilder::Create(
58       kNumCommandPackets, op_code,
59       std::make_unique<bluetooth::packet::RawBuilder>(std::vector<uint8_t>{
60           static_cast<uint8_t>(ErrorCode::UNKNOWN_HCI_COMMAND)})));
61 }
62 
DualModeController(ControllerProperties properties)63 DualModeController::DualModeController(ControllerProperties properties)
64     : properties_(std::move(properties)) {
65   Address public_address{};
66   ASSERT(Address::FromString("3C:5A:B4:04:05:06", public_address));
67   SetAddress(public_address);
68 
69   link_layer_controller_.RegisterRemoteChannel(
70       [this](std::shared_ptr<model::packets::LinkLayerPacketBuilder> packet,
71              Phy::Type phy_type, int8_t tx_power) {
72         this->SendLinkLayerPacket(packet, phy_type, tx_power);
73       });
74 }
75 
ForwardToLm(CommandView command)76 void DualModeController::ForwardToLm(CommandView command) {
77   link_layer_controller_.ForwardToLm(command);
78 }
79 
SniffSubrating(CommandView command)80 void DualModeController::SniffSubrating(CommandView command) {
81   auto command_view = bluetooth::hci::SniffSubratingView::Create(command);
82   ASSERT(command_view.IsValid());
83 
84   send_event_(bluetooth::hci::SniffSubratingCompleteBuilder::Create(
85       kNumCommandPackets, ErrorCode::SUCCESS,
86       command_view.GetConnectionHandle()));
87 }
88 
HandleAcl(std::shared_ptr<std::vector<uint8_t>> packet)89 void DualModeController::HandleAcl(
90     std::shared_ptr<std::vector<uint8_t>> packet) {
91   bluetooth::hci::PacketView<bluetooth::hci::kLittleEndian> raw_packet(packet);
92   auto acl_packet = bluetooth::hci::AclView::Create(raw_packet);
93   ASSERT(acl_packet.IsValid());
94   if (loopback_mode_ == LoopbackMode::ENABLE_LOCAL) {
95     uint16_t handle = acl_packet.GetHandle();
96 
97     std::vector<uint8_t> payload{acl_packet.GetPayload().begin(),
98                                  acl_packet.GetPayload().end()};
99     send_acl_(bluetooth::hci::AclBuilder::Create(
100         handle, acl_packet.GetPacketBoundaryFlag(),
101         acl_packet.GetBroadcastFlag(),
102         std::make_unique<bluetooth::packet::RawBuilder>(payload)));
103 
104     std::vector<bluetooth::hci::CompletedPackets> completed_packets;
105     bluetooth::hci::CompletedPackets cp;
106     cp.connection_handle_ = handle;
107     cp.host_num_of_completed_packets_ = 1;
108     completed_packets.push_back(cp);
109     send_event_(bluetooth::hci::NumberOfCompletedPacketsBuilder::Create(
110         completed_packets));
111     return;
112   }
113 
114   link_layer_controller_.SendAclToRemote(acl_packet);
115 }
116 
HandleSco(std::shared_ptr<std::vector<uint8_t>> packet)117 void DualModeController::HandleSco(
118     std::shared_ptr<std::vector<uint8_t>> packet) {
119   bluetooth::hci::PacketView<bluetooth::hci::kLittleEndian> raw_packet(packet);
120   auto sco_packet = bluetooth::hci::ScoView::Create(raw_packet);
121   ASSERT(sco_packet.IsValid());
122   if (loopback_mode_ == LoopbackMode::ENABLE_LOCAL) {
123     uint16_t handle = sco_packet.GetHandle();
124 
125     send_sco_(bluetooth::hci::ScoBuilder::Create(
126         handle, sco_packet.GetPacketStatusFlag(), sco_packet.GetData()));
127 
128     std::vector<bluetooth::hci::CompletedPackets> completed_packets;
129     bluetooth::hci::CompletedPackets cp;
130     cp.connection_handle_ = handle;
131     cp.host_num_of_completed_packets_ = 1;
132     completed_packets.push_back(cp);
133     if (link_layer_controller_.GetScoFlowControlEnable()) {
134       send_event_(bluetooth::hci::NumberOfCompletedPacketsBuilder::Create(
135           completed_packets));
136     }
137     return;
138   }
139 
140   link_layer_controller_.SendScoToRemote(sco_packet);
141 }
142 
HandleIso(std::shared_ptr<std::vector<uint8_t>> packet)143 void DualModeController::HandleIso(
144     std::shared_ptr<std::vector<uint8_t>> packet) {
145   bluetooth::hci::PacketView<bluetooth::hci::kLittleEndian> raw_packet(packet);
146   auto iso = bluetooth::hci::IsoView::Create(raw_packet);
147   ASSERT(iso.IsValid());
148   link_layer_controller_.HandleIso(iso);
149 }
150 
HandleCommand(std::shared_ptr<std::vector<uint8_t>> packet)151 void DualModeController::HandleCommand(
152     std::shared_ptr<std::vector<uint8_t>> packet) {
153   auto command_packet = bluetooth::hci::CommandView::Create(
154       bluetooth::hci::PacketView<bluetooth::hci::kLittleEndian>(packet));
155   ASSERT(command_packet.IsValid());
156 
157   OpCode op_code = command_packet.GetOpCode();
158   const bool is_vendor_command = (static_cast<uint16_t>(op_code) >> 10) == 0x3f;
159   const bool is_known_command =
160       hci_command_op_code_to_index_.count(op_code) > 0;
161   const bool is_implemented_command = hci_command_handlers_.count(op_code) > 0;
162 
163   // HCI Read Local Supported Commands is supported by default.
164   // Vendor commands are supported when implemented.
165   bool is_supported_command =
166       (op_code == OpCode::READ_LOCAL_SUPPORTED_COMMANDS) ||
167       (is_vendor_command && is_implemented_command);
168 
169   // For other commands, query the Support Commands bit mask in
170   // the controller properties.
171   if (!is_supported_command && is_known_command) {
172     int index = static_cast<int>(hci_command_op_code_to_index_.at(op_code));
173     is_supported_command = (properties_.supported_commands[index / 10] &
174                             (1U << (index % 10))) != 0;
175   }
176 
177   // Loopback mode, the commands are sent back to the host.
178   if (loopback_mode_ == LoopbackMode::ENABLE_LOCAL &&
179       op_code != OpCode::RESET &&
180       op_code != OpCode::SET_CONTROLLER_TO_HOST_FLOW_CONTROL &&
181       op_code != OpCode::HOST_BUFFER_SIZE &&
182       op_code != OpCode::HOST_NUMBER_OF_COMPLETED_PACKETS &&
183       op_code != OpCode::READ_BUFFER_SIZE &&
184       op_code != OpCode::READ_LOOPBACK_MODE &&
185       op_code != OpCode::WRITE_LOOPBACK_MODE) {
186     std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
187         std::make_unique<bluetooth::packet::RawBuilder>(255);
188     raw_builder_ptr->AddOctets(*packet);
189     send_event_(bluetooth::hci::LoopbackCommandBuilder::Create(
190         std::move(raw_builder_ptr)));
191   }
192   // Quirk to reset the host stack when a command is received before the Hci
193   // Reset command.
194   else if (properties_.quirks.hardware_error_before_reset &&
195            !controller_reset_ &&
196            op_code != OpCode::RESET) {
197     LOG_WARN("Received command %s before HCI Reset; sending the Hardware"
198              " Error event", OpCodeText(op_code).c_str());
199     send_event_(bluetooth::hci::HardwareErrorBuilder::Create(0x42));
200   }
201   // Command is both supported and implemented.
202   // Invoke the registered handler.
203   else if (is_supported_command && is_implemented_command) {
204     hci_command_handlers_.at(op_code)(this, command_packet);
205   }
206   // Command is supported but not implemented:
207   // the command needs to be implemented to fix this.
208   else if (is_supported_command) {
209     LOG_ALWAYS_FATAL(
210         "Unimplemented command %s;\n"
211         "This message will be displayed if the command is set as supported\n"
212         "in the command mask but no implementation was provided.\n"
213         "This warning will be fixed by implementing the command in "
214         "DualModeController",
215         OpCodeText(op_code).c_str());
216   }
217   // The command is not supported.
218   // Respond with the status code Unknown Command.
219   else {
220     SendCommandCompleteUnknownOpCodeEvent(op_code);
221     uint16_t raw_op_code = static_cast<uint16_t>(op_code);
222     LOG_INFO("Unknown command, opcode: 0x%04X, OGF: 0x%04X, OCF: 0x%04X",
223              raw_op_code, (raw_op_code & 0xFC00) >> 10, raw_op_code & 0x03FF);
224   }
225 }
226 
RegisterEventChannel(const std::function<void (std::shared_ptr<std::vector<uint8_t>>)> & send_event)227 void DualModeController::RegisterEventChannel(
228     const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>&
229         send_event) {
230   send_event_ =
231       [send_event](std::shared_ptr<bluetooth::hci::EventBuilder> event) {
232         auto bytes = std::make_shared<std::vector<uint8_t>>();
233         bluetooth::packet::BitInserter bit_inserter(*bytes);
234         bytes->reserve(event->size());
235         event->Serialize(bit_inserter);
236         send_event(std::move(bytes));
237       };
238   link_layer_controller_.RegisterEventChannel(send_event_);
239 }
240 
RegisterAclChannel(const std::function<void (std::shared_ptr<std::vector<uint8_t>>)> & send_acl)241 void DualModeController::RegisterAclChannel(
242     const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>&
243         send_acl) {
244   send_acl_ = [send_acl](std::shared_ptr<bluetooth::hci::AclBuilder> acl_data) {
245     auto bytes = std::make_shared<std::vector<uint8_t>>();
246     bluetooth::packet::BitInserter bit_inserter(*bytes);
247     bytes->reserve(acl_data->size());
248     acl_data->Serialize(bit_inserter);
249     send_acl(std::move(bytes));
250   };
251   link_layer_controller_.RegisterAclChannel(send_acl_);
252 }
253 
RegisterScoChannel(const std::function<void (std::shared_ptr<std::vector<uint8_t>>)> & send_sco)254 void DualModeController::RegisterScoChannel(
255     const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>&
256         send_sco) {
257   send_sco_ = [send_sco](std::shared_ptr<bluetooth::hci::ScoBuilder> sco_data) {
258     auto bytes = std::make_shared<std::vector<uint8_t>>();
259     bluetooth::packet::BitInserter bit_inserter(*bytes);
260     bytes->reserve(sco_data->size());
261     sco_data->Serialize(bit_inserter);
262     send_sco(std::move(bytes));
263   };
264   link_layer_controller_.RegisterScoChannel(send_sco_);
265 }
266 
RegisterIsoChannel(const std::function<void (std::shared_ptr<std::vector<uint8_t>>)> & send_iso)267 void DualModeController::RegisterIsoChannel(
268     const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>&
269         send_iso) {
270   send_iso_ = [send_iso](std::shared_ptr<bluetooth::hci::IsoBuilder> iso_data) {
271     auto bytes = std::make_shared<std::vector<uint8_t>>();
272     bluetooth::packet::BitInserter bit_inserter(*bytes);
273     bytes->reserve(iso_data->size());
274     iso_data->Serialize(bit_inserter);
275     send_iso(std::move(bytes));
276   };
277   link_layer_controller_.RegisterIsoChannel(send_iso_);
278 }
279 
Reset(CommandView command)280 void DualModeController::Reset(CommandView command) {
281   auto command_view = bluetooth::hci::ResetView::Create(command);
282   ASSERT(command_view.IsValid());
283   link_layer_controller_.Reset();
284   if (loopback_mode_ == LoopbackMode::ENABLE_LOCAL) {
285     loopback_mode_ = LoopbackMode::NO_LOOPBACK;
286   }
287 
288   controller_reset_ = true;
289   send_event_(bluetooth::hci::ResetCompleteBuilder::Create(kNumCommandPackets,
290                                                            ErrorCode::SUCCESS));
291 }
292 
ReadBufferSize(CommandView command)293 void DualModeController::ReadBufferSize(CommandView command) {
294   auto command_view = bluetooth::hci::ReadBufferSizeView::Create(command);
295   ASSERT(command_view.IsValid());
296 
297   send_event_(bluetooth::hci::ReadBufferSizeCompleteBuilder::Create(
298       kNumCommandPackets, ErrorCode::SUCCESS,
299       properties_.acl_data_packet_length, properties_.sco_data_packet_length,
300       properties_.total_num_acl_data_packets,
301       properties_.total_num_sco_data_packets));
302 }
303 
ReadRssi(CommandView command)304 void DualModeController::ReadRssi(CommandView command) {
305   auto command_view = bluetooth::hci::ReadRssiView::Create(command);
306   ASSERT(command_view.IsValid());
307 
308   uint16_t connection_handle = command_view.GetConnectionHandle();
309   int8_t rssi = 0;
310 
311   ErrorCode status = link_layer_controller_.ReadRssi(connection_handle, &rssi);
312   send_event_(bluetooth::hci::ReadRssiCompleteBuilder::Create(
313       kNumCommandPackets, status, connection_handle, rssi));
314 }
315 
ReadEncryptionKeySize(CommandView command)316 void DualModeController::ReadEncryptionKeySize(CommandView command) {
317   auto command_view =
318       bluetooth::hci::ReadEncryptionKeySizeView::Create(command);
319   ASSERT(command_view.IsValid());
320 
321   send_event_(bluetooth::hci::ReadEncryptionKeySizeCompleteBuilder::Create(
322       kNumCommandPackets, ErrorCode::SUCCESS,
323       command_view.GetConnectionHandle(),
324       link_layer_controller_.GetEncryptionKeySize()));
325 }
326 
HostBufferSize(CommandView command)327 void DualModeController::HostBufferSize(CommandView command) {
328   auto command_view = bluetooth::hci::HostBufferSizeView::Create(command);
329   ASSERT(command_view.IsValid());
330   send_event_(bluetooth::hci::HostBufferSizeCompleteBuilder::Create(
331       kNumCommandPackets, ErrorCode::SUCCESS));
332 }
333 
ReadLocalVersionInformation(CommandView command)334 void DualModeController::ReadLocalVersionInformation(CommandView command) {
335   auto command_view =
336       bluetooth::hci::ReadLocalVersionInformationView::Create(command);
337   ASSERT(command_view.IsValid());
338 
339   bluetooth::hci::LocalVersionInformation local_version_information;
340   local_version_information.hci_version_ = properties_.hci_version;
341   local_version_information.lmp_version_ = properties_.lmp_version;
342   local_version_information.hci_revision_ = properties_.hci_subversion;
343   local_version_information.lmp_subversion_ = properties_.lmp_subversion;
344   local_version_information.manufacturer_name_ = properties_.company_identifier;
345 
346   send_event_(
347       bluetooth::hci::ReadLocalVersionInformationCompleteBuilder::Create(
348           kNumCommandPackets, ErrorCode::SUCCESS, local_version_information));
349 }
350 
ReadRemoteVersionInformation(CommandView command)351 void DualModeController::ReadRemoteVersionInformation(CommandView command) {
352   auto command_view =
353       bluetooth::hci::ReadRemoteVersionInformationView::Create(command);
354   ASSERT(command_view.IsValid());
355 
356   auto status = link_layer_controller_.SendCommandToRemoteByHandle(
357       OpCode::READ_REMOTE_VERSION_INFORMATION, command.GetPayload(),
358       command_view.GetConnectionHandle());
359 
360   send_event_(bluetooth::hci::ReadRemoteVersionInformationStatusBuilder::Create(
361       status, kNumCommandPackets));
362 }
363 
ReadBdAddr(CommandView command)364 void DualModeController::ReadBdAddr(CommandView command) {
365   auto command_view = bluetooth::hci::ReadBdAddrView::Create(command);
366   ASSERT(command_view.IsValid());
367   send_event_(bluetooth::hci::ReadBdAddrCompleteBuilder::Create(
368       kNumCommandPackets, ErrorCode::SUCCESS, GetAddress()));
369 }
370 
ReadLocalSupportedCommands(CommandView command)371 void DualModeController::ReadLocalSupportedCommands(CommandView command) {
372   auto command_view =
373       bluetooth::hci::ReadLocalSupportedCommandsView::Create(command);
374   ASSERT(command_view.IsValid());
375   send_event_(bluetooth::hci::ReadLocalSupportedCommandsCompleteBuilder::Create(
376       kNumCommandPackets, ErrorCode::SUCCESS, properties_.supported_commands));
377 }
378 
ReadLocalSupportedFeatures(CommandView command)379 void DualModeController::ReadLocalSupportedFeatures(CommandView command) {
380   auto command_view =
381       bluetooth::hci::ReadLocalSupportedFeaturesView::Create(command);
382   ASSERT(command_view.IsValid());
383 
384   send_event_(bluetooth::hci::ReadLocalSupportedFeaturesCompleteBuilder::Create(
385       kNumCommandPackets, ErrorCode::SUCCESS,
386       link_layer_controller_.GetLmpFeatures()));
387 }
388 
ReadLocalSupportedCodecsV1(CommandView command)389 void DualModeController::ReadLocalSupportedCodecsV1(CommandView command) {
390   auto command_view =
391       bluetooth::hci::ReadLocalSupportedCodecsV1View::Create(command);
392   ASSERT(command_view.IsValid());
393   send_event_(bluetooth::hci::ReadLocalSupportedCodecsV1CompleteBuilder::Create(
394       kNumCommandPackets, ErrorCode::SUCCESS,
395       properties_.supported_standard_codecs,
396       properties_.supported_vendor_specific_codecs));
397 }
398 
ReadLocalExtendedFeatures(CommandView command)399 void DualModeController::ReadLocalExtendedFeatures(CommandView command) {
400   auto command_view =
401       bluetooth::hci::ReadLocalExtendedFeaturesView::Create(command);
402   ASSERT(command_view.IsValid());
403   uint8_t page_number = command_view.GetPageNumber();
404 
405   send_event_(bluetooth::hci::ReadLocalExtendedFeaturesCompleteBuilder::Create(
406       kNumCommandPackets, ErrorCode::SUCCESS, page_number,
407       link_layer_controller_.GetMaxLmpFeaturesPageNumber(),
408       link_layer_controller_.GetLmpFeatures(page_number)));
409 }
410 
ReadRemoteExtendedFeatures(CommandView command)411 void DualModeController::ReadRemoteExtendedFeatures(CommandView command) {
412   auto command_view =
413       bluetooth::hci::ReadRemoteExtendedFeaturesView::Create(command);
414   ASSERT(command_view.IsValid());
415 
416   auto status = link_layer_controller_.SendCommandToRemoteByHandle(
417       OpCode::READ_REMOTE_EXTENDED_FEATURES, command_view.GetPayload(),
418       command_view.GetConnectionHandle());
419 
420   send_event_(bluetooth::hci::ReadRemoteExtendedFeaturesStatusBuilder::Create(
421       status, kNumCommandPackets));
422 }
423 
SwitchRole(CommandView command)424 void DualModeController::SwitchRole(CommandView command) {
425   auto command_view = bluetooth::hci::SwitchRoleView::Create(command);
426   ASSERT(command_view.IsValid());
427 
428   auto status = link_layer_controller_.SwitchRole(command_view.GetBdAddr(),
429                                                   command_view.GetRole());
430 
431   send_event_(bluetooth::hci::SwitchRoleStatusBuilder::Create(
432       status, kNumCommandPackets));
433 }
434 
ReadRemoteSupportedFeatures(CommandView command)435 void DualModeController::ReadRemoteSupportedFeatures(CommandView command) {
436   auto command_view =
437       bluetooth::hci::ReadRemoteSupportedFeaturesView::Create(command);
438   ASSERT(command_view.IsValid());
439 
440   auto status = link_layer_controller_.SendCommandToRemoteByHandle(
441       OpCode::READ_REMOTE_SUPPORTED_FEATURES, command_view.GetPayload(),
442       command_view.GetConnectionHandle());
443 
444   send_event_(bluetooth::hci::ReadRemoteSupportedFeaturesStatusBuilder::Create(
445       status, kNumCommandPackets));
446 }
447 
ReadClockOffset(CommandView command)448 void DualModeController::ReadClockOffset(CommandView command) {
449   auto command_view = bluetooth::hci::ReadClockOffsetView::Create(command);
450   ASSERT(command_view.IsValid());
451 
452   uint16_t handle = command_view.GetConnectionHandle();
453 
454   auto status = link_layer_controller_.SendCommandToRemoteByHandle(
455       OpCode::READ_CLOCK_OFFSET, command_view.GetPayload(), handle);
456 
457   send_event_(bluetooth::hci::ReadClockOffsetStatusBuilder::Create(
458       status, kNumCommandPackets));
459 }
460 
461 // Deprecated command, removed in v4.2.
462 // Support is provided to satisfy PTS tester requirements.
AddScoConnection(CommandView command)463 void DualModeController::AddScoConnection(CommandView command) {
464   auto command_view = bluetooth::hci::AddScoConnectionView::Create(command);
465   ASSERT(command_view.IsValid());
466 
467   auto status = link_layer_controller_.AddScoConnection(
468       command_view.GetConnectionHandle(), command_view.GetPacketType(),
469       ScoDatapath::NORMAL);
470 
471   send_event_(bluetooth::hci::AddScoConnectionStatusBuilder::Create(
472       status, kNumCommandPackets));
473 }
474 
SetupSynchronousConnection(CommandView command)475 void DualModeController::SetupSynchronousConnection(CommandView command) {
476   auto command_view =
477       bluetooth::hci::SetupSynchronousConnectionView::Create(command);
478   ASSERT(command_view.IsValid());
479 
480   auto status = link_layer_controller_.SetupSynchronousConnection(
481       command_view.GetConnectionHandle(), command_view.GetTransmitBandwidth(),
482       command_view.GetReceiveBandwidth(), command_view.GetMaxLatency(),
483       command_view.GetVoiceSetting(),
484       static_cast<uint8_t>(command_view.GetRetransmissionEffort()),
485       command_view.GetPacketType(), ScoDatapath::NORMAL);
486 
487   send_event_(bluetooth::hci::SetupSynchronousConnectionStatusBuilder::Create(
488       status, kNumCommandPackets));
489 }
490 
AcceptSynchronousConnection(CommandView command)491 void DualModeController::AcceptSynchronousConnection(CommandView command) {
492   auto command_view =
493       bluetooth::hci::AcceptSynchronousConnectionView::Create(command);
494   ASSERT(command_view.IsValid());
495 
496   auto status = link_layer_controller_.AcceptSynchronousConnection(
497       command_view.GetBdAddr(), command_view.GetTransmitBandwidth(),
498       command_view.GetReceiveBandwidth(), command_view.GetMaxLatency(),
499       command_view.GetVoiceSetting(),
500       static_cast<uint8_t>(command_view.GetRetransmissionEffort()),
501       command_view.GetPacketType());
502 
503   send_event_(bluetooth::hci::AcceptSynchronousConnectionStatusBuilder::Create(
504       status, kNumCommandPackets));
505 }
506 
EnhancedSetupSynchronousConnection(CommandView command)507 void DualModeController::EnhancedSetupSynchronousConnection(
508     CommandView command) {
509   auto command_view =
510       bluetooth::hci::EnhancedSetupSynchronousConnectionView::Create(command);
511   auto status = ErrorCode::SUCCESS;
512   ASSERT(command_view.IsValid());
513 
514   // The Host shall set the Transmit_Coding_Format and Receive_Coding_Formats
515   // to be equal.
516   auto transmit_coding_format = command_view.GetTransmitCodingFormat();
517   auto receive_coding_format = command_view.GetReceiveCodingFormat();
518   if (transmit_coding_format.coding_format_ !=
519           receive_coding_format.coding_format_ ||
520       transmit_coding_format.company_id_ != receive_coding_format.company_id_ ||
521       transmit_coding_format.vendor_specific_codec_id_ !=
522           receive_coding_format.vendor_specific_codec_id_) {
523     LOG_INFO(
524         "EnhancedSetupSynchronousConnection: rejected Transmit_Coding_Format "
525         "(%s)"
526         " and Receive_Coding_Format (%s) as they are not equal",
527         transmit_coding_format.ToString().c_str(),
528         receive_coding_format.ToString().c_str());
529     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
530   }
531 
532   // The Host shall either set the Input_Bandwidth and Output_Bandwidth
533   // to be equal, or shall set one of them to be zero and the other non-zero.
534   auto input_bandwidth = command_view.GetInputBandwidth();
535   auto output_bandwidth = command_view.GetOutputBandwidth();
536   if (input_bandwidth != output_bandwidth && input_bandwidth != 0 &&
537       output_bandwidth != 0) {
538     LOG_INFO(
539         "EnhancedSetupSynchronousConnection: rejected Input_Bandwidth (%u)"
540         " and Output_Bandwidth (%u) as they are not equal and different from 0",
541         input_bandwidth, output_bandwidth);
542     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
543   }
544 
545   // The Host shall set the Input_Coding_Format and Output_Coding_Format
546   // to be equal.
547   auto input_coding_format = command_view.GetInputCodingFormat();
548   auto output_coding_format = command_view.GetOutputCodingFormat();
549   if (input_coding_format.coding_format_ !=
550           output_coding_format.coding_format_ ||
551       input_coding_format.company_id_ != output_coding_format.company_id_ ||
552       input_coding_format.vendor_specific_codec_id_ !=
553           output_coding_format.vendor_specific_codec_id_) {
554     LOG_INFO(
555         "EnhancedSetupSynchronousConnection: rejected Input_Coding_Format (%s)"
556         " and Output_Coding_Format (%s) as they are not equal",
557         input_coding_format.ToString().c_str(),
558         output_coding_format.ToString().c_str());
559     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
560   }
561 
562   // Root-Canal does not implement audio data transport paths other than the
563   // default HCI transport - other transports will receive spoofed data
564   ScoDatapath datapath = ScoDatapath::NORMAL;
565   if (command_view.GetInputDataPath() != bluetooth::hci::ScoDataPath::HCI ||
566       command_view.GetOutputDataPath() != bluetooth::hci::ScoDataPath::HCI) {
567     LOG_WARN(
568         "EnhancedSetupSynchronousConnection: Input_Data_Path (%u)"
569         " and/or Output_Data_Path (%u) are not over HCI, so data will be "
570         "spoofed",
571         static_cast<unsigned>(command_view.GetInputDataPath()),
572         static_cast<unsigned>(command_view.GetOutputDataPath()));
573     datapath = ScoDatapath::SPOOFED;
574   }
575 
576   // Either both the Transmit_Coding_Format and Input_Coding_Format shall be
577   // “transparent” or neither shall be. If both are “transparent”, the
578   // Transmit_Bandwidth and the Input_Bandwidth shall be the same and the
579   // Controller shall not modify the data sent to the remote device.
580   auto transmit_bandwidth = command_view.GetTransmitBandwidth();
581   auto receive_bandwidth = command_view.GetReceiveBandwidth();
582   if (transmit_coding_format.coding_format_ ==
583           bluetooth::hci::ScoCodingFormatValues::TRANSPARENT &&
584       input_coding_format.coding_format_ ==
585           bluetooth::hci::ScoCodingFormatValues::TRANSPARENT &&
586       transmit_bandwidth != input_bandwidth) {
587     LOG_INFO(
588         "EnhancedSetupSynchronousConnection: rejected Transmit_Bandwidth (%u)"
589         " and Input_Bandwidth (%u) as they are not equal",
590         transmit_bandwidth, input_bandwidth);
591     LOG_INFO(
592         "EnhancedSetupSynchronousConnection: the Transmit_Bandwidth and "
593         "Input_Bandwidth shall be equal when both Transmit_Coding_Format "
594         "and Input_Coding_Format are 'transparent'");
595     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
596   }
597   if ((transmit_coding_format.coding_format_ ==
598        bluetooth::hci::ScoCodingFormatValues::TRANSPARENT) !=
599       (input_coding_format.coding_format_ ==
600        bluetooth::hci::ScoCodingFormatValues::TRANSPARENT)) {
601     LOG_INFO(
602         "EnhancedSetupSynchronousConnection: rejected Transmit_Coding_Format "
603         "(%s) and Input_Coding_Format (%s) as they are incompatible",
604         transmit_coding_format.ToString().c_str(),
605         input_coding_format.ToString().c_str());
606     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
607   }
608 
609   // Either both the Receive_Coding_Format and Output_Coding_Format shall
610   // be “transparent” or neither shall be. If both are “transparent”, the
611   // Receive_Bandwidth and the Output_Bandwidth shall be the same and the
612   // Controller shall not modify the data sent to the Host.
613   if (receive_coding_format.coding_format_ ==
614           bluetooth::hci::ScoCodingFormatValues::TRANSPARENT &&
615       output_coding_format.coding_format_ ==
616           bluetooth::hci::ScoCodingFormatValues::TRANSPARENT &&
617       receive_bandwidth != output_bandwidth) {
618     LOG_INFO(
619         "EnhancedSetupSynchronousConnection: rejected Receive_Bandwidth (%u)"
620         " and Output_Bandwidth (%u) as they are not equal",
621         receive_bandwidth, output_bandwidth);
622     LOG_INFO(
623         "EnhancedSetupSynchronousConnection: the Receive_Bandwidth and "
624         "Output_Bandwidth shall be equal when both Receive_Coding_Format "
625         "and Output_Coding_Format are 'transparent'");
626     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
627   }
628   if ((receive_coding_format.coding_format_ ==
629        bluetooth::hci::ScoCodingFormatValues::TRANSPARENT) !=
630       (output_coding_format.coding_format_ ==
631        bluetooth::hci::ScoCodingFormatValues::TRANSPARENT)) {
632     LOG_INFO(
633         "EnhancedSetupSynchronousConnection: rejected Receive_Coding_Format "
634         "(%s) and Output_Coding_Format (%s) as they are incompatible",
635         receive_coding_format.ToString().c_str(),
636         output_coding_format.ToString().c_str());
637     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
638   }
639 
640   if (status == ErrorCode::SUCCESS) {
641     status = link_layer_controller_.SetupSynchronousConnection(
642         command_view.GetConnectionHandle(), transmit_bandwidth,
643         receive_bandwidth, command_view.GetMaxLatency(),
644         link_layer_controller_.GetVoiceSetting(),
645         static_cast<uint8_t>(command_view.GetRetransmissionEffort()),
646         command_view.GetPacketType(), datapath);
647   }
648 
649   send_event_(
650       bluetooth::hci::EnhancedSetupSynchronousConnectionStatusBuilder::Create(
651           status, kNumCommandPackets));
652 }
653 
EnhancedAcceptSynchronousConnection(CommandView command)654 void DualModeController::EnhancedAcceptSynchronousConnection(
655     CommandView command) {
656   auto command_view =
657       bluetooth::hci::EnhancedAcceptSynchronousConnectionView::Create(command);
658   auto status = ErrorCode::SUCCESS;
659   ASSERT(command_view.IsValid());
660 
661   // The Host shall set the Transmit_Coding_Format and Receive_Coding_Formats
662   // to be equal.
663   auto transmit_coding_format = command_view.GetTransmitCodingFormat();
664   auto receive_coding_format = command_view.GetReceiveCodingFormat();
665   if (transmit_coding_format.coding_format_ !=
666           receive_coding_format.coding_format_ ||
667       transmit_coding_format.company_id_ != receive_coding_format.company_id_ ||
668       transmit_coding_format.vendor_specific_codec_id_ !=
669           receive_coding_format.vendor_specific_codec_id_) {
670     LOG_INFO(
671         "EnhancedAcceptSynchronousConnection: rejected Transmit_Coding_Format "
672         "(%s)"
673         " and Receive_Coding_Format (%s) as they are not equal",
674         transmit_coding_format.ToString().c_str(),
675         receive_coding_format.ToString().c_str());
676     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
677   }
678 
679   // The Host shall either set the Input_Bandwidth and Output_Bandwidth
680   // to be equal, or shall set one of them to be zero and the other non-zero.
681   auto input_bandwidth = command_view.GetInputBandwidth();
682   auto output_bandwidth = command_view.GetOutputBandwidth();
683   if (input_bandwidth != output_bandwidth && input_bandwidth != 0 &&
684       output_bandwidth != 0) {
685     LOG_INFO(
686         "EnhancedAcceptSynchronousConnection: rejected Input_Bandwidth (%u)"
687         " and Output_Bandwidth (%u) as they are not equal and different from 0",
688         input_bandwidth, output_bandwidth);
689     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
690   }
691 
692   // The Host shall set the Input_Coding_Format and Output_Coding_Format
693   // to be equal.
694   auto input_coding_format = command_view.GetInputCodingFormat();
695   auto output_coding_format = command_view.GetOutputCodingFormat();
696   if (input_coding_format.coding_format_ !=
697           output_coding_format.coding_format_ ||
698       input_coding_format.company_id_ != output_coding_format.company_id_ ||
699       input_coding_format.vendor_specific_codec_id_ !=
700           output_coding_format.vendor_specific_codec_id_) {
701     LOG_INFO(
702         "EnhancedAcceptSynchronousConnection: rejected Input_Coding_Format (%s)"
703         " and Output_Coding_Format (%s) as they are not equal",
704         input_coding_format.ToString().c_str(),
705         output_coding_format.ToString().c_str());
706     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
707   }
708 
709   // Root-Canal does not implement audio data transport paths other than the
710   // default HCI transport.
711   if (command_view.GetInputDataPath() != bluetooth::hci::ScoDataPath::HCI ||
712       command_view.GetOutputDataPath() != bluetooth::hci::ScoDataPath::HCI) {
713     LOG_INFO(
714         "EnhancedSetupSynchronousConnection: Input_Data_Path (%u)"
715         " and/or Output_Data_Path (%u) are not over HCI, so data will be "
716         "spoofed",
717         static_cast<unsigned>(command_view.GetInputDataPath()),
718         static_cast<unsigned>(command_view.GetOutputDataPath()));
719   }
720 
721   // Either both the Transmit_Coding_Format and Input_Coding_Format shall be
722   // “transparent” or neither shall be. If both are “transparent”, the
723   // Transmit_Bandwidth and the Input_Bandwidth shall be the same and the
724   // Controller shall not modify the data sent to the remote device.
725   auto transmit_bandwidth = command_view.GetTransmitBandwidth();
726   auto receive_bandwidth = command_view.GetReceiveBandwidth();
727   if (transmit_coding_format.coding_format_ ==
728           bluetooth::hci::ScoCodingFormatValues::TRANSPARENT &&
729       input_coding_format.coding_format_ ==
730           bluetooth::hci::ScoCodingFormatValues::TRANSPARENT &&
731       transmit_bandwidth != input_bandwidth) {
732     LOG_INFO(
733         "EnhancedSetupSynchronousConnection: rejected Transmit_Bandwidth (%u)"
734         " and Input_Bandwidth (%u) as they are not equal",
735         transmit_bandwidth, input_bandwidth);
736     LOG_INFO(
737         "EnhancedSetupSynchronousConnection: the Transmit_Bandwidth and "
738         "Input_Bandwidth shall be equal when both Transmit_Coding_Format "
739         "and Input_Coding_Format are 'transparent'");
740     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
741   }
742   if ((transmit_coding_format.coding_format_ ==
743        bluetooth::hci::ScoCodingFormatValues::TRANSPARENT) !=
744       (input_coding_format.coding_format_ ==
745        bluetooth::hci::ScoCodingFormatValues::TRANSPARENT)) {
746     LOG_INFO(
747         "EnhancedSetupSynchronousConnection: rejected Transmit_Coding_Format "
748         "(%s) and Input_Coding_Format (%s) as they are incompatible",
749         transmit_coding_format.ToString().c_str(),
750         input_coding_format.ToString().c_str());
751     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
752   }
753 
754   // Either both the Receive_Coding_Format and Output_Coding_Format shall
755   // be “transparent” or neither shall be. If both are “transparent”, the
756   // Receive_Bandwidth and the Output_Bandwidth shall be the same and the
757   // Controller shall not modify the data sent to the Host.
758   if (receive_coding_format.coding_format_ ==
759           bluetooth::hci::ScoCodingFormatValues::TRANSPARENT &&
760       output_coding_format.coding_format_ ==
761           bluetooth::hci::ScoCodingFormatValues::TRANSPARENT &&
762       receive_bandwidth != output_bandwidth) {
763     LOG_INFO(
764         "EnhancedSetupSynchronousConnection: rejected Receive_Bandwidth (%u)"
765         " and Output_Bandwidth (%u) as they are not equal",
766         receive_bandwidth, output_bandwidth);
767     LOG_INFO(
768         "EnhancedSetupSynchronousConnection: the Receive_Bandwidth and "
769         "Output_Bandwidth shall be equal when both Receive_Coding_Format "
770         "and Output_Coding_Format are 'transparent'");
771     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
772   }
773   if ((receive_coding_format.coding_format_ ==
774        bluetooth::hci::ScoCodingFormatValues::TRANSPARENT) !=
775       (output_coding_format.coding_format_ ==
776        bluetooth::hci::ScoCodingFormatValues::TRANSPARENT)) {
777     LOG_INFO(
778         "EnhancedSetupSynchronousConnection: rejected Receive_Coding_Format "
779         "(%s) and Output_Coding_Format (%s) as they are incompatible",
780         receive_coding_format.ToString().c_str(),
781         output_coding_format.ToString().c_str());
782     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
783   }
784 
785   if (status == ErrorCode::SUCCESS) {
786     status = link_layer_controller_.AcceptSynchronousConnection(
787         command_view.GetBdAddr(), transmit_bandwidth, receive_bandwidth,
788         command_view.GetMaxLatency(), link_layer_controller_.GetVoiceSetting(),
789         static_cast<uint8_t>(command_view.GetRetransmissionEffort()),
790         command_view.GetPacketType());
791   }
792 
793   send_event_(
794       bluetooth::hci::EnhancedAcceptSynchronousConnectionStatusBuilder::Create(
795           status, kNumCommandPackets));
796 }
797 
RejectSynchronousConnection(CommandView command)798 void DualModeController::RejectSynchronousConnection(CommandView command) {
799   auto command_view =
800       bluetooth::hci::RejectSynchronousConnectionView::Create(command);
801   ASSERT(command_view.IsValid());
802 
803   auto status = link_layer_controller_.RejectSynchronousConnection(
804       command_view.GetBdAddr(), (uint16_t)command_view.GetReason());
805 
806   send_event_(bluetooth::hci::RejectSynchronousConnectionStatusBuilder::Create(
807       status, kNumCommandPackets));
808 }
809 
ReadInquiryResponseTransmitPowerLevel(CommandView command)810 void DualModeController::ReadInquiryResponseTransmitPowerLevel(
811     CommandView command) {
812   auto command_view =
813       bluetooth::hci::ReadInquiryResponseTransmitPowerLevelView::Create(
814           command);
815   ASSERT(command_view.IsValid());
816 
817   uint8_t tx_power = 20;  // maximum
818   send_event_(
819       bluetooth::hci::ReadInquiryResponseTransmitPowerLevelCompleteBuilder::
820           Create(kNumCommandPackets, ErrorCode::SUCCESS, tx_power));
821 }
822 
EnhancedFlush(CommandView command)823 void DualModeController::EnhancedFlush(CommandView command) {
824   auto command_view = bluetooth::hci::EnhancedFlushView::Create(command);
825   ASSERT(command_view.IsValid());
826 
827   auto handle = command_view.GetConnectionHandle();
828   send_event_(bluetooth::hci::EnhancedFlushStatusBuilder::Create(
829       ErrorCode::SUCCESS, kNumCommandPackets));
830 
831   // TODO: When adding a queue of ACL packets.
832   // Send the Enhanced Flush Complete event after discarding
833   // all L2CAP packets identified by the Packet Type.
834   if (link_layer_controller_.IsEventUnmasked(
835           bluetooth::hci::EventCode::ENHANCED_FLUSH_COMPLETE)) {
836     send_event_(bluetooth::hci::EnhancedFlushCompleteBuilder::Create(handle));
837   }
838 }
839 
SetEventMaskPage2(CommandView command)840 void DualModeController::SetEventMaskPage2(CommandView command) {
841   auto command_view = bluetooth::hci::SetEventMaskPage2View::Create(command);
842   ASSERT(command_view.IsValid());
843   link_layer_controller_.SetEventMaskPage2(command_view.GetEventMaskPage2());
844   send_event_(bluetooth::hci::SetEventMaskPage2CompleteBuilder::Create(
845       kNumCommandPackets, ErrorCode::SUCCESS));
846 }
847 
ReadLocalOobData(CommandView command)848 void DualModeController::ReadLocalOobData(CommandView command) {
849   auto command_view = bluetooth::hci::ReadLocalOobDataView::Create(command);
850   link_layer_controller_.ReadLocalOobData();
851 }
852 
ReadLocalOobExtendedData(CommandView command)853 void DualModeController::ReadLocalOobExtendedData(CommandView command) {
854   auto command_view =
855       bluetooth::hci::ReadLocalOobExtendedDataView::Create(command);
856   link_layer_controller_.ReadLocalOobExtendedData();
857 }
858 
WriteSimplePairingMode(CommandView command)859 void DualModeController::WriteSimplePairingMode(CommandView command) {
860   auto command_view =
861       bluetooth::hci::WriteSimplePairingModeView::Create(command);
862   ASSERT(command_view.IsValid());
863 
864   auto enabled =
865       command_view.GetSimplePairingMode() == bluetooth::hci::Enable::ENABLED;
866   link_layer_controller_.SetSecureSimplePairingSupport(enabled);
867   send_event_(bluetooth::hci::WriteSimplePairingModeCompleteBuilder::Create(
868       kNumCommandPackets, ErrorCode::SUCCESS));
869 }
870 
ChangeConnectionPacketType(CommandView command)871 void DualModeController::ChangeConnectionPacketType(CommandView command) {
872   auto command_view =
873       bluetooth::hci::ChangeConnectionPacketTypeView::Create(command);
874   ASSERT(command_view.IsValid());
875 
876   uint16_t handle = command_view.GetConnectionHandle();
877   uint16_t packet_type = static_cast<uint16_t>(command_view.GetPacketType());
878 
879   auto status =
880       link_layer_controller_.ChangeConnectionPacketType(handle, packet_type);
881   send_event_(bluetooth::hci::ChangeConnectionPacketTypeStatusBuilder::Create(
882       status, kNumCommandPackets));
883 }
884 
WriteLeHostSupport(CommandView command)885 void DualModeController::WriteLeHostSupport(CommandView command) {
886   auto command_view = bluetooth::hci::WriteLeHostSupportView::Create(command);
887   ASSERT(command_view.IsValid());
888   auto le_support =
889       command_view.GetLeSupportedHost() == bluetooth::hci::Enable::ENABLED;
890   link_layer_controller_.SetLeHostSupport(le_support);
891   send_event_(bluetooth::hci::WriteLeHostSupportCompleteBuilder::Create(
892       kNumCommandPackets, ErrorCode::SUCCESS));
893 }
894 
WriteSecureConnectionsHostSupport(CommandView command)895 void DualModeController::WriteSecureConnectionsHostSupport(
896     CommandView command) {
897   auto command_view =
898       bluetooth::hci::WriteSecureConnectionsHostSupportView::Create(command);
899   ASSERT(command_view.IsValid());
900   link_layer_controller_.SetSecureConnectionsSupport(
901       command_view.GetSecureConnectionsHostSupport() ==
902       bluetooth::hci::Enable::ENABLED);
903   send_event_(
904       bluetooth::hci::WriteSecureConnectionsHostSupportCompleteBuilder::Create(
905           kNumCommandPackets, ErrorCode::SUCCESS));
906 }
907 
SetEventMask(CommandView command)908 void DualModeController::SetEventMask(CommandView command) {
909   auto command_view = bluetooth::hci::SetEventMaskView::Create(command);
910   ASSERT(command_view.IsValid());
911   link_layer_controller_.SetEventMask(command_view.GetEventMask());
912   send_event_(bluetooth::hci::SetEventMaskCompleteBuilder::Create(
913       kNumCommandPackets, ErrorCode::SUCCESS));
914 }
915 
ReadInquiryMode(CommandView command)916 void DualModeController::ReadInquiryMode(CommandView command) {
917   auto command_view = bluetooth::hci::ReadInquiryModeView::Create(command);
918   ASSERT(command_view.IsValid());
919   bluetooth::hci::InquiryMode inquiry_mode =
920       bluetooth::hci::InquiryMode::STANDARD;
921   send_event_(bluetooth::hci::ReadInquiryModeCompleteBuilder::Create(
922       kNumCommandPackets, ErrorCode::SUCCESS, inquiry_mode));
923 }
924 
WriteInquiryMode(CommandView command)925 void DualModeController::WriteInquiryMode(CommandView command) {
926   auto command_view = bluetooth::hci::WriteInquiryModeView::Create(command);
927   ASSERT(command_view.IsValid());
928   link_layer_controller_.SetInquiryMode(
929       static_cast<uint8_t>(command_view.GetInquiryMode()));
930   send_event_(bluetooth::hci::WriteInquiryModeCompleteBuilder::Create(
931       kNumCommandPackets, ErrorCode::SUCCESS));
932 }
933 
ReadPageScanType(CommandView command)934 void DualModeController::ReadPageScanType(CommandView command) {
935   auto command_view = bluetooth::hci::ReadPageScanTypeView::Create(command);
936   ASSERT(command_view.IsValid());
937   bluetooth::hci::PageScanType page_scan_type =
938       bluetooth::hci::PageScanType::STANDARD;
939   send_event_(bluetooth::hci::ReadPageScanTypeCompleteBuilder::Create(
940       kNumCommandPackets, ErrorCode::SUCCESS, page_scan_type));
941 }
942 
WritePageScanType(CommandView command)943 void DualModeController::WritePageScanType(CommandView command) {
944   auto command_view = bluetooth::hci::WritePageScanTypeView::Create(command);
945   ASSERT(command_view.IsValid());
946   send_event_(bluetooth::hci::WritePageScanTypeCompleteBuilder::Create(
947       kNumCommandPackets, ErrorCode::SUCCESS));
948 }
949 
ReadInquiryScanType(CommandView command)950 void DualModeController::ReadInquiryScanType(CommandView command) {
951   auto command_view = bluetooth::hci::ReadInquiryScanTypeView::Create(command);
952   ASSERT(command_view.IsValid());
953   bluetooth::hci::InquiryScanType inquiry_scan_type =
954       bluetooth::hci::InquiryScanType::STANDARD;
955   send_event_(bluetooth::hci::ReadInquiryScanTypeCompleteBuilder::Create(
956       kNumCommandPackets, ErrorCode::SUCCESS, inquiry_scan_type));
957 }
958 
WriteInquiryScanType(CommandView command)959 void DualModeController::WriteInquiryScanType(CommandView command) {
960   auto command_view = bluetooth::hci::WriteInquiryScanTypeView::Create(command);
961   ASSERT(command_view.IsValid());
962   send_event_(bluetooth::hci::WriteInquiryScanTypeCompleteBuilder::Create(
963       kNumCommandPackets, ErrorCode::SUCCESS));
964 }
965 
ChangeConnectionLinkKey(CommandView command)966 void DualModeController::ChangeConnectionLinkKey(CommandView command) {
967   auto command_view =
968       bluetooth::hci::ChangeConnectionLinkKeyView::Create(command);
969   ASSERT(command_view.IsValid());
970   uint16_t handle = command_view.GetConnectionHandle();
971 
972   auto status = link_layer_controller_.ChangeConnectionLinkKey(handle);
973 
974   send_event_(bluetooth::hci::ChangeConnectionLinkKeyStatusBuilder::Create(
975       status, kNumCommandPackets));
976 }
977 
CentralLinkKey(CommandView command)978 void DualModeController::CentralLinkKey(CommandView command) {
979   auto command_view = bluetooth::hci::CentralLinkKeyView::Create(command);
980   ASSERT(command_view.IsValid());
981   uint8_t key_flag = static_cast<uint8_t>(command_view.GetKeyFlag());
982 
983   auto status = link_layer_controller_.CentralLinkKey(key_flag);
984 
985   send_event_(bluetooth::hci::CentralLinkKeyStatusBuilder::Create(
986       status, kNumCommandPackets));
987 }
988 
WriteAuthenticationEnable(CommandView command)989 void DualModeController::WriteAuthenticationEnable(CommandView command) {
990   auto command_view =
991       bluetooth::hci::WriteAuthenticationEnableView::Create(command);
992   ASSERT(command_view.IsValid());
993   link_layer_controller_.SetAuthenticationEnable(
994       command_view.GetAuthenticationEnable());
995   send_event_(bluetooth::hci::WriteAuthenticationEnableCompleteBuilder::Create(
996       kNumCommandPackets, ErrorCode::SUCCESS));
997 }
998 
ReadAuthenticationEnable(CommandView command)999 void DualModeController::ReadAuthenticationEnable(CommandView command) {
1000   auto command_view =
1001       bluetooth::hci::ReadAuthenticationEnableView::Create(command);
1002   ASSERT(command_view.IsValid());
1003   send_event_(bluetooth::hci::ReadAuthenticationEnableCompleteBuilder::Create(
1004       kNumCommandPackets, ErrorCode::SUCCESS,
1005       static_cast<bluetooth::hci::AuthenticationEnable>(
1006           link_layer_controller_.GetAuthenticationEnable())));
1007 }
1008 
WriteClassOfDevice(CommandView command)1009 void DualModeController::WriteClassOfDevice(CommandView command) {
1010   auto command_view = bluetooth::hci::WriteClassOfDeviceView::Create(command);
1011   ASSERT(command_view.IsValid());
1012   link_layer_controller_.SetClassOfDevice(command_view.GetClassOfDevice());
1013   send_event_(bluetooth::hci::WriteClassOfDeviceCompleteBuilder::Create(
1014       kNumCommandPackets, ErrorCode::SUCCESS));
1015 }
1016 
ReadPageTimeout(CommandView command)1017 void DualModeController::ReadPageTimeout(CommandView command) {
1018   auto command_view = bluetooth::hci::ReadPageTimeoutView::Create(command);
1019   ASSERT(command_view.IsValid());
1020   uint16_t page_timeout = link_layer_controller_.GetPageTimeout();
1021   send_event_(bluetooth::hci::ReadPageTimeoutCompleteBuilder::Create(
1022       kNumCommandPackets, ErrorCode::SUCCESS, page_timeout));
1023 }
1024 
WritePageTimeout(CommandView command)1025 void DualModeController::WritePageTimeout(CommandView command) {
1026   auto command_view = bluetooth::hci::WritePageTimeoutView::Create(command);
1027   ASSERT(command_view.IsValid());
1028   link_layer_controller_.SetPageTimeout(command_view.GetPageTimeout());
1029   send_event_(bluetooth::hci::WritePageTimeoutCompleteBuilder::Create(
1030       kNumCommandPackets, ErrorCode::SUCCESS));
1031 }
1032 
HoldMode(CommandView command)1033 void DualModeController::HoldMode(CommandView command) {
1034   auto command_view = bluetooth::hci::HoldModeView::Create(command);
1035   ASSERT(command_view.IsValid());
1036   uint16_t handle = command_view.GetConnectionHandle();
1037   uint16_t hold_mode_max_interval = command_view.GetHoldModeMaxInterval();
1038   uint16_t hold_mode_min_interval = command_view.GetHoldModeMinInterval();
1039 
1040   auto status = link_layer_controller_.HoldMode(handle, hold_mode_max_interval,
1041                                                 hold_mode_min_interval);
1042 
1043   send_event_(bluetooth::hci::HoldModeStatusBuilder::Create(
1044       status, kNumCommandPackets));
1045 }
1046 
SniffMode(CommandView command)1047 void DualModeController::SniffMode(CommandView command) {
1048   auto command_view = bluetooth::hci::SniffModeView::Create(command);
1049   ASSERT(command_view.IsValid());
1050   uint16_t handle = command_view.GetConnectionHandle();
1051   uint16_t sniff_max_interval = command_view.GetSniffMaxInterval();
1052   uint16_t sniff_min_interval = command_view.GetSniffMinInterval();
1053   uint16_t sniff_attempt = command_view.GetSniffAttempt();
1054   uint16_t sniff_timeout = command_view.GetSniffTimeout();
1055 
1056   auto status = link_layer_controller_.SniffMode(handle, sniff_max_interval,
1057                                                  sniff_min_interval,
1058                                                  sniff_attempt, sniff_timeout);
1059 
1060   send_event_(bluetooth::hci::SniffModeStatusBuilder::Create(
1061       status, kNumCommandPackets));
1062 }
1063 
ExitSniffMode(CommandView command)1064 void DualModeController::ExitSniffMode(CommandView command) {
1065   auto command_view = bluetooth::hci::ExitSniffModeView::Create(command);
1066   ASSERT(command_view.IsValid());
1067 
1068   auto status =
1069       link_layer_controller_.ExitSniffMode(command_view.GetConnectionHandle());
1070 
1071   send_event_(bluetooth::hci::ExitSniffModeStatusBuilder::Create(
1072       status, kNumCommandPackets));
1073 }
1074 
QosSetup(CommandView command)1075 void DualModeController::QosSetup(CommandView command) {
1076   auto command_view = bluetooth::hci::QosSetupView::Create(command);
1077   ASSERT(command_view.IsValid());
1078   uint16_t handle = command_view.GetConnectionHandle();
1079   uint8_t service_type = static_cast<uint8_t>(command_view.GetServiceType());
1080   uint32_t token_rate = command_view.GetTokenRate();
1081   uint32_t peak_bandwidth = command_view.GetPeakBandwidth();
1082   uint32_t latency = command_view.GetLatency();
1083   uint32_t delay_variation = command_view.GetDelayVariation();
1084 
1085   auto status =
1086       link_layer_controller_.QosSetup(handle, service_type, token_rate,
1087                                       peak_bandwidth, latency, delay_variation);
1088 
1089   send_event_(bluetooth::hci::QosSetupStatusBuilder::Create(
1090       status, kNumCommandPackets));
1091 }
1092 
RoleDiscovery(CommandView command)1093 void DualModeController::RoleDiscovery(CommandView command) {
1094   auto command_view = bluetooth::hci::RoleDiscoveryView::Create(command);
1095   ASSERT(command_view.IsValid());
1096   uint16_t handle = command_view.GetConnectionHandle();
1097 
1098   auto role = bluetooth::hci::Role::CENTRAL;
1099   auto status = link_layer_controller_.RoleDiscovery(handle, &role);
1100 
1101   send_event_(bluetooth::hci::RoleDiscoveryCompleteBuilder::Create(
1102       kNumCommandPackets, status, handle, role));
1103 }
1104 
ReadDefaultLinkPolicySettings(CommandView command)1105 void DualModeController::ReadDefaultLinkPolicySettings(CommandView command) {
1106   auto command_view =
1107       bluetooth::hci::ReadDefaultLinkPolicySettingsView::Create(command);
1108   ASSERT(command_view.IsValid());
1109   uint16_t settings = link_layer_controller_.ReadDefaultLinkPolicySettings();
1110   send_event_(
1111       bluetooth::hci::ReadDefaultLinkPolicySettingsCompleteBuilder::Create(
1112           kNumCommandPackets, ErrorCode::SUCCESS, settings));
1113 }
1114 
WriteDefaultLinkPolicySettings(CommandView command)1115 void DualModeController::WriteDefaultLinkPolicySettings(CommandView command) {
1116   auto command_view =
1117       bluetooth::hci::WriteDefaultLinkPolicySettingsView::Create(command);
1118   ASSERT(command_view.IsValid());
1119   ErrorCode status = link_layer_controller_.WriteDefaultLinkPolicySettings(
1120       command_view.GetDefaultLinkPolicySettings());
1121   send_event_(
1122       bluetooth::hci::WriteDefaultLinkPolicySettingsCompleteBuilder::Create(
1123           kNumCommandPackets, status));
1124 }
1125 
FlowSpecification(CommandView command)1126 void DualModeController::FlowSpecification(CommandView command) {
1127   auto command_view = bluetooth::hci::FlowSpecificationView::Create(command);
1128   ASSERT(command_view.IsValid());
1129   uint16_t handle = command_view.GetConnectionHandle();
1130   uint8_t flow_direction =
1131       static_cast<uint8_t>(command_view.GetFlowDirection());
1132   uint8_t service_type = static_cast<uint8_t>(command_view.GetServiceType());
1133   uint32_t token_rate = command_view.GetTokenRate();
1134   uint32_t token_bucket_size = command_view.GetTokenBucketSize();
1135   uint32_t peak_bandwidth = command_view.GetPeakBandwidth();
1136   uint32_t access_latency = command_view.GetAccessLatency();
1137 
1138   auto status = link_layer_controller_.FlowSpecification(
1139       handle, flow_direction, service_type, token_rate, token_bucket_size,
1140       peak_bandwidth, access_latency);
1141 
1142   send_event_(bluetooth::hci::FlowSpecificationStatusBuilder::Create(
1143       status, kNumCommandPackets));
1144 }
1145 
ReadLinkPolicySettings(CommandView command)1146 void DualModeController::ReadLinkPolicySettings(CommandView command) {
1147   auto command_view =
1148       bluetooth::hci::ReadLinkPolicySettingsView::Create(command);
1149   ASSERT(command_view.IsValid());
1150 
1151   uint16_t handle = command_view.GetConnectionHandle();
1152   uint16_t settings;
1153 
1154   auto status =
1155       link_layer_controller_.ReadLinkPolicySettings(handle, &settings);
1156 
1157   send_event_(bluetooth::hci::ReadLinkPolicySettingsCompleteBuilder::Create(
1158       kNumCommandPackets, status, handle, settings));
1159 }
1160 
WriteLinkPolicySettings(CommandView command)1161 void DualModeController::WriteLinkPolicySettings(CommandView command) {
1162   auto command_view =
1163       bluetooth::hci::WriteLinkPolicySettingsView::Create(command);
1164   ASSERT(command_view.IsValid());
1165 
1166   uint16_t handle = command_view.GetConnectionHandle();
1167   uint16_t settings = command_view.GetLinkPolicySettings();
1168 
1169   auto status =
1170       link_layer_controller_.WriteLinkPolicySettings(handle, settings);
1171 
1172   send_event_(bluetooth::hci::WriteLinkPolicySettingsCompleteBuilder::Create(
1173       kNumCommandPackets, status, handle));
1174 }
1175 
WriteLinkSupervisionTimeout(CommandView command)1176 void DualModeController::WriteLinkSupervisionTimeout(CommandView command) {
1177   auto command_view =
1178       bluetooth::hci::WriteLinkSupervisionTimeoutView::Create(command);
1179   ASSERT(command_view.IsValid());
1180 
1181   uint16_t handle = command_view.GetConnectionHandle();
1182   uint16_t timeout = command_view.GetLinkSupervisionTimeout();
1183 
1184   auto status =
1185       link_layer_controller_.WriteLinkSupervisionTimeout(handle, timeout);
1186   send_event_(
1187       bluetooth::hci::WriteLinkSupervisionTimeoutCompleteBuilder::Create(
1188           kNumCommandPackets, status, handle));
1189 }
1190 
ReadLocalName(CommandView command)1191 void DualModeController::ReadLocalName(CommandView command) {
1192   auto command_view = bluetooth::hci::ReadLocalNameView::Create(command);
1193   ASSERT(command_view.IsValid());
1194   send_event_(bluetooth::hci::ReadLocalNameCompleteBuilder::Create(
1195       kNumCommandPackets, ErrorCode::SUCCESS,
1196       link_layer_controller_.GetLocalName()));
1197 }
1198 
WriteLocalName(CommandView command)1199 void DualModeController::WriteLocalName(CommandView command) {
1200   auto command_view = bluetooth::hci::WriteLocalNameView::Create(command);
1201   ASSERT(command_view.IsValid());
1202   link_layer_controller_.SetLocalName(command_view.GetLocalName());
1203   send_event_(bluetooth::hci::WriteLocalNameCompleteBuilder::Create(
1204       kNumCommandPackets, ErrorCode::SUCCESS));
1205 }
1206 
WriteExtendedInquiryResponse(CommandView command)1207 void DualModeController::WriteExtendedInquiryResponse(CommandView command) {
1208   auto command_view =
1209       bluetooth::hci::WriteExtendedInquiryResponseView::Create(command);
1210   ASSERT(command_view.IsValid());
1211   link_layer_controller_.SetExtendedInquiryResponse(std::vector<uint8_t>(
1212       command_view.GetPayload().begin() + 1, command_view.GetPayload().end()));
1213   send_event_(
1214       bluetooth::hci::WriteExtendedInquiryResponseCompleteBuilder::Create(
1215           kNumCommandPackets, ErrorCode::SUCCESS));
1216 }
1217 
RefreshEncryptionKey(CommandView command)1218 void DualModeController::RefreshEncryptionKey(CommandView command) {
1219   auto command_view = bluetooth::hci::RefreshEncryptionKeyView::Create(command);
1220   ASSERT(command_view.IsValid());
1221   uint16_t handle = command_view.GetConnectionHandle();
1222   send_event_(bluetooth::hci::RefreshEncryptionKeyStatusBuilder::Create(
1223       ErrorCode::SUCCESS, kNumCommandPackets));
1224   // TODO: Support this in the link layer
1225   send_event_(bluetooth::hci::EncryptionKeyRefreshCompleteBuilder::Create(
1226       ErrorCode::SUCCESS, handle));
1227 }
1228 
WriteVoiceSetting(CommandView command)1229 void DualModeController::WriteVoiceSetting(CommandView command) {
1230   auto command_view = bluetooth::hci::WriteVoiceSettingView::Create(command);
1231   ASSERT(command_view.IsValid());
1232 
1233   link_layer_controller_.SetVoiceSetting(command_view.GetVoiceSetting());
1234 
1235   send_event_(bluetooth::hci::WriteVoiceSettingCompleteBuilder::Create(
1236       kNumCommandPackets, ErrorCode::SUCCESS));
1237 }
1238 
ReadNumberOfSupportedIac(CommandView command)1239 void DualModeController::ReadNumberOfSupportedIac(CommandView command) {
1240   auto command_view =
1241       bluetooth::hci::ReadNumberOfSupportedIacView::Create(command);
1242   ASSERT(command_view.IsValid());
1243   send_event_(bluetooth::hci::ReadNumberOfSupportedIacCompleteBuilder::Create(
1244       kNumCommandPackets, ErrorCode::SUCCESS, properties_.num_supported_iac));
1245 }
1246 
ReadCurrentIacLap(CommandView command)1247 void DualModeController::ReadCurrentIacLap(CommandView command) {
1248   auto command_view = bluetooth::hci::ReadCurrentIacLapView::Create(command);
1249   ASSERT(command_view.IsValid());
1250   send_event_(bluetooth::hci::ReadCurrentIacLapCompleteBuilder::Create(
1251       kNumCommandPackets, ErrorCode::SUCCESS,
1252       link_layer_controller_.ReadCurrentIacLap()));
1253 }
1254 
WriteCurrentIacLap(CommandView command)1255 void DualModeController::WriteCurrentIacLap(CommandView command) {
1256   auto command_view = bluetooth::hci::WriteCurrentIacLapView::Create(command);
1257   ASSERT(command_view.IsValid());
1258   link_layer_controller_.WriteCurrentIacLap(command_view.GetLapsToWrite());
1259   send_event_(bluetooth::hci::WriteCurrentIacLapCompleteBuilder::Create(
1260       kNumCommandPackets, ErrorCode::SUCCESS));
1261 }
1262 
ReadPageScanActivity(CommandView command)1263 void DualModeController::ReadPageScanActivity(CommandView command) {
1264   auto command_view = bluetooth::hci::ReadPageScanActivityView::Create(command);
1265   ASSERT(command_view.IsValid());
1266   uint16_t interval = 0x1000;
1267   uint16_t window = 0x0012;
1268   send_event_(bluetooth::hci::ReadPageScanActivityCompleteBuilder::Create(
1269       kNumCommandPackets, ErrorCode::SUCCESS, interval, window));
1270 }
1271 
WritePageScanActivity(CommandView command)1272 void DualModeController::WritePageScanActivity(CommandView command) {
1273   auto command_view =
1274       bluetooth::hci::WritePageScanActivityView::Create(command);
1275   ASSERT(command_view.IsValid());
1276   send_event_(bluetooth::hci::WritePageScanActivityCompleteBuilder::Create(
1277       kNumCommandPackets, ErrorCode::SUCCESS));
1278 }
1279 
ReadInquiryScanActivity(CommandView command)1280 void DualModeController::ReadInquiryScanActivity(CommandView command) {
1281   auto command_view =
1282       bluetooth::hci::ReadInquiryScanActivityView::Create(command);
1283   ASSERT(command_view.IsValid());
1284   uint16_t interval = 0x1000;
1285   uint16_t window = 0x0012;
1286   send_event_(bluetooth::hci::ReadInquiryScanActivityCompleteBuilder::Create(
1287       kNumCommandPackets, ErrorCode::SUCCESS, interval, window));
1288 }
1289 
WriteInquiryScanActivity(CommandView command)1290 void DualModeController::WriteInquiryScanActivity(CommandView command) {
1291   auto command_view =
1292       bluetooth::hci::WriteInquiryScanActivityView::Create(command);
1293   ASSERT(command_view.IsValid());
1294   send_event_(bluetooth::hci::WriteInquiryScanActivityCompleteBuilder::Create(
1295       kNumCommandPackets, ErrorCode::SUCCESS));
1296 }
1297 
ReadScanEnable(CommandView command)1298 void DualModeController::ReadScanEnable(CommandView command) {
1299   auto command_view = bluetooth::hci::ReadScanEnableView::Create(command);
1300   ASSERT(command_view.IsValid());
1301 
1302   bool inquiry_scan = link_layer_controller_.GetInquiryScanEnable();
1303   bool page_scan = link_layer_controller_.GetPageScanEnable();
1304 
1305   bluetooth::hci::ScanEnable scan_enable =
1306       inquiry_scan && page_scan
1307           ? bluetooth::hci::ScanEnable::INQUIRY_AND_PAGE_SCAN
1308       : inquiry_scan ? bluetooth::hci::ScanEnable::INQUIRY_SCAN_ONLY
1309       : page_scan    ? bluetooth::hci::ScanEnable::PAGE_SCAN_ONLY
1310                      : bluetooth::hci::ScanEnable::NO_SCANS;
1311 
1312   send_event_(bluetooth::hci::ReadScanEnableCompleteBuilder::Create(
1313       kNumCommandPackets, ErrorCode::SUCCESS, scan_enable));
1314 }
1315 
WriteScanEnable(CommandView command)1316 void DualModeController::WriteScanEnable(CommandView command) {
1317   auto command_view = bluetooth::hci::WriteScanEnableView::Create(command);
1318   ASSERT(command_view.IsValid());
1319 
1320   bluetooth::hci::ScanEnable scan_enable = command_view.GetScanEnable();
1321   bool inquiry_scan =
1322       scan_enable == bluetooth::hci::ScanEnable::INQUIRY_AND_PAGE_SCAN ||
1323       scan_enable == bluetooth::hci::ScanEnable::INQUIRY_SCAN_ONLY;
1324   bool page_scan =
1325       scan_enable == bluetooth::hci::ScanEnable::INQUIRY_AND_PAGE_SCAN ||
1326       scan_enable == bluetooth::hci::ScanEnable::PAGE_SCAN_ONLY;
1327 
1328   LOG_INFO("%s | WriteScanEnable %s", GetAddress().ToString().c_str(),
1329            bluetooth::hci::ScanEnableText(scan_enable).c_str());
1330 
1331   link_layer_controller_.SetInquiryScanEnable(inquiry_scan);
1332   link_layer_controller_.SetPageScanEnable(page_scan);
1333   send_event_(bluetooth::hci::WriteScanEnableCompleteBuilder::Create(
1334       kNumCommandPackets, ErrorCode::SUCCESS));
1335 }
1336 
ReadSynchronousFlowControlEnable(CommandView command)1337 void DualModeController::ReadSynchronousFlowControlEnable(CommandView command) {
1338   auto command_view =
1339       bluetooth::hci::ReadSynchronousFlowControlEnableView::Create(command);
1340   ASSERT(command_view.IsValid());
1341   auto enabled = bluetooth::hci::Enable::DISABLED;
1342   if (link_layer_controller_.GetScoFlowControlEnable()) {
1343     enabled = bluetooth::hci::Enable::ENABLED;
1344   }
1345   send_event_(
1346       bluetooth::hci::ReadSynchronousFlowControlEnableCompleteBuilder::Create(
1347           kNumCommandPackets, ErrorCode::SUCCESS, enabled));
1348 }
1349 
WriteSynchronousFlowControlEnable(CommandView command)1350 void DualModeController::WriteSynchronousFlowControlEnable(
1351     CommandView command) {
1352   auto command_view =
1353       bluetooth::hci::WriteSynchronousFlowControlEnableView::Create(command);
1354   ASSERT(command_view.IsValid());
1355   auto enabled = command_view.GetEnable() == bluetooth::hci::Enable::ENABLED;
1356   link_layer_controller_.SetScoFlowControlEnable(enabled);
1357   send_event_(
1358       bluetooth::hci::WriteSynchronousFlowControlEnableCompleteBuilder::Create(
1359           kNumCommandPackets, ErrorCode::SUCCESS));
1360 }
1361 
SetEventFilter(CommandView command)1362 void DualModeController::SetEventFilter(CommandView command) {
1363   auto command_view = bluetooth::hci::SetEventFilterView::Create(command);
1364   ASSERT(command_view.IsValid());
1365   send_event_(bluetooth::hci::SetEventFilterCompleteBuilder::Create(
1366       kNumCommandPackets, ErrorCode::SUCCESS));
1367 }
1368 
Inquiry(CommandView command)1369 void DualModeController::Inquiry(CommandView command) {
1370   auto command_view = bluetooth::hci::InquiryView::Create(command);
1371   ASSERT(command_view.IsValid());
1372   auto max_responses = command_view.GetNumResponses();
1373   auto length = command_view.GetInquiryLength();
1374   if (max_responses > 0xff || length < 1 || length > 0x30) {
1375     send_event_(bluetooth::hci::InquiryStatusBuilder::Create(
1376         ErrorCode::INVALID_HCI_COMMAND_PARAMETERS, kNumCommandPackets));
1377     return;
1378   }
1379   link_layer_controller_.SetInquiryLAP(command_view.GetLap().lap_);
1380   link_layer_controller_.SetInquiryMaxResponses(max_responses);
1381   link_layer_controller_.StartInquiry(std::chrono::milliseconds(length * 1280));
1382 
1383   send_event_(bluetooth::hci::InquiryStatusBuilder::Create(ErrorCode::SUCCESS,
1384                                                            kNumCommandPackets));
1385 }
1386 
InquiryCancel(CommandView command)1387 void DualModeController::InquiryCancel(CommandView command) {
1388   auto command_view = bluetooth::hci::InquiryCancelView::Create(command);
1389   ASSERT(command_view.IsValid());
1390   link_layer_controller_.InquiryCancel();
1391   send_event_(bluetooth::hci::InquiryCancelCompleteBuilder::Create(
1392       kNumCommandPackets, ErrorCode::SUCCESS));
1393 }
1394 
AcceptConnectionRequest(CommandView command)1395 void DualModeController::AcceptConnectionRequest(CommandView command) {
1396   auto command_view =
1397       bluetooth::hci::AcceptConnectionRequestView::Create(command);
1398   ASSERT(command_view.IsValid());
1399   Address addr = command_view.GetBdAddr();
1400   bool try_role_switch =
1401       command_view.GetRole() ==
1402       bluetooth::hci::AcceptConnectionRequestRole::BECOME_CENTRAL;
1403   auto status =
1404       link_layer_controller_.AcceptConnectionRequest(addr, try_role_switch);
1405   send_event_(bluetooth::hci::AcceptConnectionRequestStatusBuilder::Create(
1406       status, kNumCommandPackets));
1407 }
1408 
RejectConnectionRequest(CommandView command)1409 void DualModeController::RejectConnectionRequest(CommandView command) {
1410   auto command_view =
1411       bluetooth::hci::RejectConnectionRequestView::Create(command);
1412   ASSERT(command_view.IsValid());
1413   Address addr = command_view.GetBdAddr();
1414   uint8_t reason = static_cast<uint8_t>(command_view.GetReason());
1415   auto status = link_layer_controller_.RejectConnectionRequest(addr, reason);
1416   send_event_(bluetooth::hci::RejectConnectionRequestStatusBuilder::Create(
1417       status, kNumCommandPackets));
1418 }
1419 
DeleteStoredLinkKey(CommandView command)1420 void DualModeController::DeleteStoredLinkKey(CommandView command) {
1421   auto command_view = bluetooth::hci::DeleteStoredLinkKeyView::Create(command);
1422   ASSERT(command_view.IsValid());
1423 
1424   send_event_(bluetooth::hci::DeleteStoredLinkKeyCompleteBuilder::Create(
1425       kNumCommandPackets, ErrorCode::SUCCESS, 0));
1426 }
1427 
RemoteNameRequest(CommandView command)1428 void DualModeController::RemoteNameRequest(CommandView command) {
1429   auto command_view = bluetooth::hci::RemoteNameRequestView::Create(command);
1430   ASSERT(command_view.IsValid());
1431 
1432   Address remote_addr = command_view.GetBdAddr();
1433 
1434   auto status = link_layer_controller_.SendCommandToRemoteByAddress(
1435       OpCode::REMOTE_NAME_REQUEST, command_view.GetPayload(), GetAddress(),
1436       remote_addr);
1437 
1438   send_event_(bluetooth::hci::RemoteNameRequestStatusBuilder::Create(
1439       status, kNumCommandPackets));
1440 }
1441 
LeSetEventMask(CommandView command)1442 void DualModeController::LeSetEventMask(CommandView command) {
1443   auto command_view = bluetooth::hci::LeSetEventMaskView::Create(command);
1444   ASSERT(command_view.IsValid());
1445   link_layer_controller_.SetLeEventMask(command_view.GetLeEventMask());
1446   send_event_(bluetooth::hci::LeSetEventMaskCompleteBuilder::Create(
1447       kNumCommandPackets, ErrorCode::SUCCESS));
1448 }
1449 
LeSetHostFeature(CommandView command)1450 void DualModeController::LeSetHostFeature(CommandView command) {
1451   auto command_view = bluetooth::hci::LeSetHostFeatureView::Create(command);
1452   ASSERT(command_view.IsValid());
1453 
1454   ErrorCode status = link_layer_controller_.LeSetHostFeature(
1455       static_cast<uint8_t>(command_view.GetBitNumber()),
1456       static_cast<uint8_t>(command_view.GetBitValue()));
1457   send_event_(bluetooth::hci::LeSetHostFeatureCompleteBuilder::Create(
1458       kNumCommandPackets, status));
1459 }
1460 
LeReadBufferSizeV1(CommandView command)1461 void DualModeController::LeReadBufferSizeV1(CommandView command) {
1462   auto command_view = bluetooth::hci::LeReadBufferSizeV1View::Create(command);
1463   ASSERT(command_view.IsValid());
1464 
1465   bluetooth::hci::LeBufferSize le_buffer_size;
1466   le_buffer_size.le_data_packet_length_ = properties_.le_acl_data_packet_length;
1467   le_buffer_size.total_num_le_packets_ =
1468       properties_.total_num_le_acl_data_packets;
1469 
1470   send_event_(bluetooth::hci::LeReadBufferSizeV1CompleteBuilder::Create(
1471       kNumCommandPackets, ErrorCode::SUCCESS, le_buffer_size));
1472 }
1473 
LeReadBufferSizeV2(CommandView command)1474 void DualModeController::LeReadBufferSizeV2(CommandView command) {
1475   auto command_view = bluetooth::hci::LeReadBufferSizeV2View::Create(command);
1476   ASSERT(command_view.IsValid());
1477 
1478   bluetooth::hci::LeBufferSize le_buffer_size;
1479   le_buffer_size.le_data_packet_length_ = properties_.le_acl_data_packet_length;
1480   le_buffer_size.total_num_le_packets_ =
1481       properties_.total_num_le_acl_data_packets;
1482   bluetooth::hci::LeBufferSize iso_buffer_size;
1483   iso_buffer_size.le_data_packet_length_ = properties_.iso_data_packet_length;
1484   iso_buffer_size.total_num_le_packets_ =
1485       properties_.total_num_iso_data_packets;
1486 
1487   send_event_(bluetooth::hci::LeReadBufferSizeV2CompleteBuilder::Create(
1488       kNumCommandPackets, ErrorCode::SUCCESS, le_buffer_size, iso_buffer_size));
1489 }
1490 
LeSetAddressResolutionEnable(CommandView command)1491 void DualModeController::LeSetAddressResolutionEnable(CommandView command) {
1492   auto command_view =
1493       bluetooth::hci::LeSetAddressResolutionEnableView::Create(command);
1494   ASSERT(command_view.IsValid());
1495   ErrorCode status = link_layer_controller_.LeSetAddressResolutionEnable(
1496       command_view.GetAddressResolutionEnable() ==
1497       bluetooth::hci::Enable::ENABLED);
1498   send_event_(
1499       bluetooth::hci::LeSetAddressResolutionEnableCompleteBuilder::Create(
1500           kNumCommandPackets, status));
1501 }
1502 
LeSetResolvablePrivateAddressTimeout(CommandView command)1503 void DualModeController::LeSetResolvablePrivateAddressTimeout(
1504     CommandView command) {
1505   auto command_view =
1506       bluetooth::hci::LeSetResolvablePrivateAddressTimeoutView::Create(command);
1507   ASSERT(command_view.IsValid());
1508   ErrorCode status =
1509       link_layer_controller_.LeSetResolvablePrivateAddressTimeout(
1510           command_view.GetRpaTimeout());
1511   send_event_(
1512       bluetooth::hci::LeSetResolvablePrivateAddressTimeoutCompleteBuilder::
1513           Create(kNumCommandPackets, status));
1514 }
1515 
LeReadLocalSupportedFeatures(CommandView command)1516 void DualModeController::LeReadLocalSupportedFeatures(CommandView command) {
1517   auto command_view =
1518       bluetooth::hci::LeReadLocalSupportedFeaturesView::Create(command);
1519   ASSERT(command_view.IsValid());
1520   LOG_INFO("%s | LeReadLocalSupportedFeatures (%016llx)",
1521            GetAddress().ToString().c_str(),
1522            static_cast<unsigned long long>(properties_.le_features));
1523 
1524   send_event_(
1525       bluetooth::hci::LeReadLocalSupportedFeaturesCompleteBuilder::Create(
1526           kNumCommandPackets, ErrorCode::SUCCESS, properties_.le_features));
1527 }
1528 
LeSetRandomAddress(CommandView command)1529 void DualModeController::LeSetRandomAddress(CommandView command) {
1530   auto command_view = bluetooth::hci::LeSetRandomAddressView::Create(command);
1531   ASSERT(command_view.IsValid());
1532   ErrorCode status = link_layer_controller_.LeSetRandomAddress(
1533       command_view.GetRandomAddress());
1534   send_event_(bluetooth::hci::LeSetRandomAddressCompleteBuilder::Create(
1535       kNumCommandPackets, status));
1536 }
1537 
LeSetAdvertisingParameters(CommandView command)1538 void DualModeController::LeSetAdvertisingParameters(CommandView command) {
1539   auto command_view =
1540       bluetooth::hci::LeSetAdvertisingParametersView::Create(command);
1541   ASSERT(command_view.IsValid());
1542   ErrorCode status = link_layer_controller_.LeSetAdvertisingParameters(
1543       command_view.GetAdvertisingIntervalMin(),
1544       command_view.GetAdvertisingIntervalMax(),
1545       command_view.GetAdvertisingType(), command_view.GetOwnAddressType(),
1546       command_view.GetPeerAddressType(), command_view.GetPeerAddress(),
1547       command_view.GetAdvertisingChannelMap(),
1548       command_view.GetAdvertisingFilterPolicy());
1549   send_event_(bluetooth::hci::LeSetAdvertisingParametersCompleteBuilder::Create(
1550       kNumCommandPackets, status));
1551 }
1552 
LeReadAdvertisingPhysicalChannelTxPower(CommandView command)1553 void DualModeController::LeReadAdvertisingPhysicalChannelTxPower(
1554     CommandView command) {
1555   auto command_view =
1556       bluetooth::hci::LeReadAdvertisingPhysicalChannelTxPowerView::Create(
1557           command);
1558   ASSERT(command_view.IsValid());
1559   send_event_(
1560       bluetooth::hci::LeReadAdvertisingPhysicalChannelTxPowerCompleteBuilder::
1561           Create(kNumCommandPackets, ErrorCode::SUCCESS,
1562                  properties_.le_advertising_physical_channel_tx_power));
1563 }
1564 
LeSetAdvertisingData(CommandView command)1565 void DualModeController::LeSetAdvertisingData(CommandView command) {
1566   auto command_view =
1567       bluetooth::hci::LeSetAdvertisingDataRawView::Create(command);
1568   ASSERT(command_view.IsValid());
1569   ErrorCode status = link_layer_controller_.LeSetAdvertisingData(
1570       command_view.GetAdvertisingData());
1571   send_event_(bluetooth::hci::LeSetAdvertisingDataCompleteBuilder::Create(
1572       kNumCommandPackets, status));
1573 }
1574 
LeSetScanResponseData(CommandView command)1575 void DualModeController::LeSetScanResponseData(CommandView command) {
1576   auto command_view =
1577       bluetooth::hci::LeSetScanResponseDataRawView::Create(command);
1578   ASSERT(command_view.IsValid());
1579   ErrorCode status = link_layer_controller_.LeSetScanResponseData(
1580       command_view.GetAdvertisingData());
1581   send_event_(bluetooth::hci::LeSetScanResponseDataCompleteBuilder::Create(
1582       kNumCommandPackets, status));
1583 }
1584 
LeSetAdvertisingEnable(CommandView command)1585 void DualModeController::LeSetAdvertisingEnable(CommandView command) {
1586   auto command_view =
1587       bluetooth::hci::LeSetAdvertisingEnableView::Create(command);
1588   ASSERT(command_view.IsValid());
1589 
1590   LOG_INFO(
1591       "%s | LeSetAdvertisingEnable (%d)", GetAddress().ToString().c_str(),
1592       command_view.GetAdvertisingEnable() == bluetooth::hci::Enable::ENABLED);
1593 
1594   ErrorCode status = link_layer_controller_.LeSetAdvertisingEnable(
1595       command_view.GetAdvertisingEnable() == bluetooth::hci::Enable::ENABLED);
1596   send_event_(bluetooth::hci::LeSetAdvertisingEnableCompleteBuilder::Create(
1597       kNumCommandPackets, status));
1598 }
1599 
LeSetScanParameters(CommandView command)1600 void DualModeController::LeSetScanParameters(CommandView command) {
1601   auto command_view = bluetooth::hci::LeSetScanParametersView::Create(command);
1602   ASSERT(command_view.IsValid());
1603 
1604   ErrorCode status = link_layer_controller_.LeSetScanParameters(
1605       command_view.GetLeScanType(), command_view.GetLeScanInterval(),
1606       command_view.GetLeScanWindow(), command_view.GetOwnAddressType(),
1607       command_view.GetScanningFilterPolicy());
1608   send_event_(bluetooth::hci::LeSetScanParametersCompleteBuilder::Create(
1609       kNumCommandPackets, status));
1610 }
1611 
LeSetScanEnable(CommandView command)1612 void DualModeController::LeSetScanEnable(CommandView command) {
1613   auto command_view = bluetooth::hci::LeSetScanEnableView::Create(command);
1614   ASSERT(command_view.IsValid());
1615 
1616   LOG_INFO("%s | LeSetScanEnable (%d)", GetAddress().ToString().c_str(),
1617            command_view.GetLeScanEnable() == bluetooth::hci::Enable::ENABLED);
1618 
1619   ErrorCode status = link_layer_controller_.LeSetScanEnable(
1620       command_view.GetLeScanEnable() == bluetooth::hci::Enable::ENABLED,
1621       command_view.GetFilterDuplicates() == bluetooth::hci::Enable::ENABLED);
1622   send_event_(bluetooth::hci::LeSetScanEnableCompleteBuilder::Create(
1623       kNumCommandPackets, status));
1624 }
1625 
LeCreateConnection(CommandView command)1626 void DualModeController::LeCreateConnection(CommandView command) {
1627   auto command_view = bluetooth::hci::LeCreateConnectionView::Create(command);
1628   ASSERT(command_view.IsValid());
1629   ErrorCode status = link_layer_controller_.LeCreateConnection(
1630       command_view.GetLeScanInterval(), command_view.GetLeScanWindow(),
1631       command_view.GetInitiatorFilterPolicy(),
1632       AddressWithType{
1633           command_view.GetPeerAddress(),
1634           command_view.GetPeerAddressType(),
1635       },
1636       command_view.GetOwnAddressType(), command_view.GetConnIntervalMin(),
1637       command_view.GetConnIntervalMax(), command_view.GetConnLatency(),
1638       command_view.GetSupervisionTimeout(), command_view.GetMinimumCeLength(),
1639       command_view.GetMaximumCeLength());
1640   send_event_(bluetooth::hci::LeCreateConnectionStatusBuilder::Create(
1641       status, kNumCommandPackets));
1642 }
1643 
LeCreateConnectionCancel(CommandView command)1644 void DualModeController::LeCreateConnectionCancel(CommandView command) {
1645   auto command_view =
1646       bluetooth::hci::LeCreateConnectionCancelView::Create(command);
1647   ASSERT(command_view.IsValid());
1648   ErrorCode status = link_layer_controller_.LeCreateConnectionCancel();
1649   send_event_(bluetooth::hci::LeCreateConnectionCancelCompleteBuilder::Create(
1650       kNumCommandPackets, status));
1651 }
1652 
LeConnectionUpdate(CommandView command)1653 void DualModeController::LeConnectionUpdate(CommandView command) {
1654   auto command_view = bluetooth::hci::LeConnectionUpdateView::Create(command);
1655   ASSERT(command_view.IsValid());
1656   ErrorCode status = link_layer_controller_.LeConnectionUpdate(
1657       command_view.GetConnectionHandle(), command_view.GetConnIntervalMin(),
1658       command_view.GetConnIntervalMax(), command_view.GetConnLatency(),
1659       command_view.GetSupervisionTimeout());
1660 
1661   send_event_(bluetooth::hci::LeConnectionUpdateStatusBuilder::Create(
1662       status, kNumCommandPackets));
1663 }
1664 
CreateConnection(CommandView command)1665 void DualModeController::CreateConnection(CommandView command) {
1666   auto command_view = bluetooth::hci::CreateConnectionView::Create(command);
1667   ASSERT(command_view.IsValid());
1668 
1669   Address address = command_view.GetBdAddr();
1670   uint16_t packet_type = command_view.GetPacketType();
1671   uint8_t page_scan_mode =
1672       static_cast<uint8_t>(command_view.GetPageScanRepetitionMode());
1673   uint16_t clock_offset = (command_view.GetClockOffsetValid() ==
1674                                    bluetooth::hci::ClockOffsetValid::VALID
1675                                ? command_view.GetClockOffset()
1676                                : 0);
1677   uint8_t allow_role_switch =
1678       static_cast<uint8_t>(command_view.GetAllowRoleSwitch());
1679 
1680   auto status = link_layer_controller_.CreateConnection(
1681       address, packet_type, page_scan_mode, clock_offset, allow_role_switch);
1682 
1683   send_event_(bluetooth::hci::CreateConnectionStatusBuilder::Create(
1684       status, kNumCommandPackets));
1685 }
1686 
CreateConnectionCancel(CommandView command)1687 void DualModeController::CreateConnectionCancel(CommandView command) {
1688   auto command_view =
1689       bluetooth::hci::CreateConnectionCancelView::Create(command);
1690   ASSERT(command_view.IsValid());
1691 
1692   Address address = command_view.GetBdAddr();
1693 
1694   auto status = link_layer_controller_.CreateConnectionCancel(address);
1695 
1696   send_event_(bluetooth::hci::CreateConnectionCancelCompleteBuilder::Create(
1697       kNumCommandPackets, status, address));
1698 }
1699 
Disconnect(CommandView command)1700 void DualModeController::Disconnect(CommandView command) {
1701   auto command_view = bluetooth::hci::DisconnectView::Create(command);
1702   ASSERT(command_view.IsValid());
1703 
1704   uint16_t handle = command_view.GetConnectionHandle();
1705 
1706   auto status = link_layer_controller_.Disconnect(
1707       handle, ErrorCode(command_view.GetReason()));
1708 
1709   send_event_(bluetooth::hci::DisconnectStatusBuilder::Create(
1710       status, kNumCommandPackets));
1711 }
1712 
LeReadFilterAcceptListSize(CommandView command)1713 void DualModeController::LeReadFilterAcceptListSize(CommandView command) {
1714   auto command_view =
1715       bluetooth::hci::LeReadFilterAcceptListSizeView::Create(command);
1716   ASSERT(command_view.IsValid());
1717   send_event_(bluetooth::hci::LeReadFilterAcceptListSizeCompleteBuilder::Create(
1718       kNumCommandPackets, ErrorCode::SUCCESS,
1719       properties_.le_filter_accept_list_size));
1720 }
1721 
LeClearFilterAcceptList(CommandView command)1722 void DualModeController::LeClearFilterAcceptList(CommandView command) {
1723   auto command_view =
1724       bluetooth::hci::LeClearFilterAcceptListView::Create(command);
1725   ASSERT(command_view.IsValid());
1726   ErrorCode status = link_layer_controller_.LeClearFilterAcceptList();
1727   send_event_(bluetooth::hci::LeClearFilterAcceptListCompleteBuilder::Create(
1728       kNumCommandPackets, status));
1729 }
1730 
LeAddDeviceToFilterAcceptList(CommandView command)1731 void DualModeController::LeAddDeviceToFilterAcceptList(CommandView command) {
1732   auto command_view =
1733       bluetooth::hci::LeAddDeviceToFilterAcceptListView::Create(command);
1734   ASSERT(command_view.IsValid());
1735   ErrorCode status = link_layer_controller_.LeAddDeviceToFilterAcceptList(
1736       command_view.GetAddressType(), command_view.GetAddress());
1737   send_event_(
1738       bluetooth::hci::LeAddDeviceToFilterAcceptListCompleteBuilder::Create(
1739           kNumCommandPackets, status));
1740 }
1741 
LeRemoveDeviceFromFilterAcceptList(CommandView command)1742 void DualModeController::LeRemoveDeviceFromFilterAcceptList(
1743     CommandView command) {
1744   auto command_view =
1745       bluetooth::hci::LeRemoveDeviceFromFilterAcceptListView::Create(command);
1746   ASSERT(command_view.IsValid());
1747   ErrorCode status = link_layer_controller_.LeRemoveDeviceFromFilterAcceptList(
1748       command_view.GetAddressType(), command_view.GetAddress());
1749   send_event_(
1750       bluetooth::hci::LeRemoveDeviceFromFilterAcceptListCompleteBuilder::Create(
1751           kNumCommandPackets, status));
1752 }
1753 
LeClearResolvingList(CommandView command)1754 void DualModeController::LeClearResolvingList(CommandView command) {
1755   auto command_view = bluetooth::hci::LeClearResolvingListView::Create(command);
1756   ASSERT(command_view.IsValid());
1757   ErrorCode status = link_layer_controller_.LeClearResolvingList();
1758   send_event_(bluetooth::hci::LeClearResolvingListCompleteBuilder::Create(
1759       kNumCommandPackets, status));
1760 }
1761 
LeReadResolvingListSize(CommandView command)1762 void DualModeController::LeReadResolvingListSize(CommandView command) {
1763   auto command_view =
1764       bluetooth::hci::LeReadResolvingListSizeView::Create(command);
1765   ASSERT(command_view.IsValid());
1766   send_event_(bluetooth::hci::LeReadResolvingListSizeCompleteBuilder::Create(
1767       kNumCommandPackets, ErrorCode::SUCCESS,
1768       properties_.le_resolving_list_size));
1769 }
1770 
LeReadPeerResolvableAddress(CommandView command)1771 void DualModeController::LeReadPeerResolvableAddress(CommandView command) {
1772   auto command_view =
1773       bluetooth::hci::LeReadPeerResolvableAddressView::Create(command);
1774   ASSERT(command_view.IsValid());
1775   Address peer_resolvable_address;
1776   ErrorCode status = link_layer_controller_.LeReadPeerResolvableAddress(
1777       command_view.GetPeerIdentityAddressType(),
1778       command_view.GetPeerIdentityAddress(), &peer_resolvable_address);
1779   send_event_(
1780       bluetooth::hci::LeReadPeerResolvableAddressCompleteBuilder::Create(
1781           kNumCommandPackets, status, peer_resolvable_address));
1782 }
1783 
LeReadLocalResolvableAddress(CommandView command)1784 void DualModeController::LeReadLocalResolvableAddress(CommandView command) {
1785   auto command_view =
1786       bluetooth::hci::LeReadLocalResolvableAddressView::Create(command);
1787   ASSERT(command_view.IsValid());
1788   Address local_resolvable_address;
1789   ErrorCode status = link_layer_controller_.LeReadLocalResolvableAddress(
1790       command_view.GetPeerIdentityAddressType(),
1791       command_view.GetPeerIdentityAddress(), &local_resolvable_address);
1792   send_event_(
1793       bluetooth::hci::LeReadLocalResolvableAddressCompleteBuilder::Create(
1794           kNumCommandPackets, status, local_resolvable_address));
1795 }
1796 
LeReadMaximumDataLength(CommandView command)1797 void DualModeController::LeReadMaximumDataLength(CommandView command) {
1798   auto command_view =
1799       bluetooth::hci::LeReadMaximumDataLengthView::Create(command);
1800   ASSERT(command_view.IsValid());
1801   bluetooth::hci::LeMaximumDataLength data_length;
1802   data_length.supported_max_rx_octets_ = kLeMaximumDataLength;
1803   data_length.supported_max_rx_time_ = kLeMaximumDataTime;
1804   data_length.supported_max_tx_octets_ = kLeMaximumDataLength + 10;
1805   data_length.supported_max_tx_time_ = kLeMaximumDataTime + 10;
1806   send_event_(bluetooth::hci::LeReadMaximumDataLengthCompleteBuilder::Create(
1807       kNumCommandPackets, ErrorCode::SUCCESS, data_length));
1808 }
1809 
LeReadPhy(CommandView command)1810 void DualModeController::LeReadPhy(CommandView command) {
1811   auto command_view = bluetooth::hci::LeReadPhyView::Create(command);
1812   ASSERT(command_view.IsValid());
1813   uint16_t connection_handle = command_view.GetConnectionHandle();
1814   bluetooth::hci::PhyType tx_phy{};
1815   bluetooth::hci::PhyType rx_phy{};
1816   ErrorCode status =
1817       link_layer_controller_.LeReadPhy(connection_handle, &tx_phy, &rx_phy);
1818   send_event_(bluetooth::hci::LeReadPhyCompleteBuilder::Create(
1819       kNumCommandPackets, status, connection_handle, tx_phy, rx_phy));
1820 }
1821 
LeSetDefaultPhy(CommandView command)1822 void DualModeController::LeSetDefaultPhy(CommandView command) {
1823   auto command_view = bluetooth::hci::LeSetDefaultPhyView::Create(command);
1824   ASSERT(command_view.IsValid());
1825   ErrorCode status = link_layer_controller_.LeSetDefaultPhy(
1826       command_view.GetAllPhysNoTransmitPreference(),
1827       command_view.GetAllPhysNoReceivePreference(), command_view.GetTxPhys(),
1828       command_view.GetRxPhys());
1829   send_event_(bluetooth::hci::LeSetDefaultPhyCompleteBuilder::Create(
1830       kNumCommandPackets, status));
1831 }
1832 
LeSetPhy(CommandView command)1833 void DualModeController::LeSetPhy(CommandView command) {
1834   auto command_view = bluetooth::hci::LeSetPhyView::Create(command);
1835   ASSERT(command_view.IsValid());
1836   ErrorCode status = link_layer_controller_.LeSetPhy(
1837       command_view.GetConnectionHandle(),
1838       command_view.GetAllPhysNoTransmitPreference(),
1839       command_view.GetAllPhysNoReceivePreference(), command_view.GetTxPhys(),
1840       command_view.GetRxPhys(), command_view.GetPhyOptions());
1841   send_event_(bluetooth::hci::LeSetPhyStatusBuilder::Create(
1842       status, kNumCommandPackets));
1843 }
1844 
LeReadSuggestedDefaultDataLength(CommandView command)1845 void DualModeController::LeReadSuggestedDefaultDataLength(CommandView command) {
1846   auto command_view =
1847       bluetooth::hci::LeReadSuggestedDefaultDataLengthView::Create(command);
1848   ASSERT(command_view.IsValid());
1849   send_event_(
1850       bluetooth::hci::LeReadSuggestedDefaultDataLengthCompleteBuilder::Create(
1851           kNumCommandPackets, ErrorCode::SUCCESS,
1852           link_layer_controller_.GetLeSuggestedMaxTxOctets(),
1853           link_layer_controller_.GetLeSuggestedMaxTxTime()));
1854 }
1855 
LeWriteSuggestedDefaultDataLength(CommandView command)1856 void DualModeController::LeWriteSuggestedDefaultDataLength(
1857     CommandView command) {
1858   auto command_view =
1859       bluetooth::hci::LeWriteSuggestedDefaultDataLengthView::Create(command);
1860   ASSERT(command_view.IsValid());
1861 
1862   uint16_t max_tx_octets = command_view.GetTxOctets();
1863   uint16_t max_tx_time = command_view.GetTxTime();
1864   ErrorCode status = ErrorCode::SUCCESS;
1865   if (max_tx_octets > 0xFB || max_tx_octets < 0x1B || max_tx_time < 0x148 ||
1866       max_tx_time > 0x4290) {
1867     status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1868   } else {
1869     link_layer_controller_.SetLeSuggestedMaxTxOctets(max_tx_octets);
1870     link_layer_controller_.SetLeSuggestedMaxTxTime(max_tx_time);
1871   }
1872 
1873   send_event_(
1874       bluetooth::hci::LeWriteSuggestedDefaultDataLengthCompleteBuilder::Create(
1875           kNumCommandPackets, status));
1876 }
1877 
LeAddDeviceToResolvingList(CommandView command)1878 void DualModeController::LeAddDeviceToResolvingList(CommandView command) {
1879   auto command_view =
1880       bluetooth::hci::LeAddDeviceToResolvingListView::Create(command);
1881   ASSERT(command_view.IsValid());
1882   ErrorCode status = link_layer_controller_.LeAddDeviceToResolvingList(
1883       command_view.GetPeerIdentityAddressType(),
1884       command_view.GetPeerIdentityAddress(), command_view.GetPeerIrk(),
1885       command_view.GetLocalIrk());
1886   send_event_(bluetooth::hci::LeAddDeviceToResolvingListCompleteBuilder::Create(
1887       kNumCommandPackets, status));
1888 }
1889 
LeRemoveDeviceFromResolvingList(CommandView command)1890 void DualModeController::LeRemoveDeviceFromResolvingList(CommandView command) {
1891   auto command_view =
1892       bluetooth::hci::LeRemoveDeviceFromResolvingListView::Create(command);
1893   ASSERT(command_view.IsValid());
1894   ErrorCode status = link_layer_controller_.LeRemoveDeviceFromResolvingList(
1895       command_view.GetPeerIdentityAddressType(),
1896       command_view.GetPeerIdentityAddress());
1897   send_event_(
1898       bluetooth::hci::LeRemoveDeviceFromResolvingListCompleteBuilder::Create(
1899           kNumCommandPackets, status));
1900 }
1901 
LeSetPeriodicAdvertisingParameters(CommandView command)1902 void DualModeController::LeSetPeriodicAdvertisingParameters(
1903     CommandView command) {
1904   auto command_view =
1905       bluetooth::hci::LeSetPeriodicAdvertisingParametersView::Create(command);
1906   ASSERT(command_view.IsValid());
1907   ErrorCode status = link_layer_controller_.LeSetPeriodicAdvertisingParameters(
1908       command_view.GetAdvertisingHandle(),
1909       command_view.GetPeriodicAdvertisingIntervalMin(),
1910       command_view.GetPeriodicAdvertisingIntervalMax(),
1911       command_view.GetIncludeTxPower());
1912   send_event_(
1913       bluetooth::hci::LeSetPeriodicAdvertisingParametersCompleteBuilder::Create(
1914           kNumCommandPackets, status));
1915 }
1916 
LeSetPeriodicAdvertisingData(CommandView command)1917 void DualModeController::LeSetPeriodicAdvertisingData(CommandView command) {
1918   auto command_view =
1919       bluetooth::hci::LeSetPeriodicAdvertisingDataRawView::Create(command);
1920   ASSERT(command_view.IsValid());
1921   ErrorCode status = link_layer_controller_.LeSetPeriodicAdvertisingData(
1922       command_view.GetAdvertisingHandle(), command_view.GetOperation(),
1923       command_view.GetAdvertisingData());
1924   send_event_(
1925       bluetooth::hci::LeSetPeriodicAdvertisingDataCompleteBuilder::Create(
1926           kNumCommandPackets, status));
1927 }
1928 
LeSetPeriodicAdvertisingEnable(CommandView command)1929 void DualModeController::LeSetPeriodicAdvertisingEnable(CommandView command) {
1930   auto command_view =
1931       bluetooth::hci::LeSetPeriodicAdvertisingEnableView::Create(command);
1932   ASSERT(command_view.IsValid());
1933   ErrorCode status = link_layer_controller_.LeSetPeriodicAdvertisingEnable(
1934       command_view.GetEnable(), command_view.GetIncludeAdi(),
1935       command_view.GetAdvertisingHandle());
1936   send_event_(
1937       bluetooth::hci::LeSetPeriodicAdvertisingEnableCompleteBuilder::Create(
1938           kNumCommandPackets, status));
1939 }
1940 
LePeriodicAdvertisingCreateSync(CommandView command)1941 void DualModeController::LePeriodicAdvertisingCreateSync(CommandView command) {
1942   auto command_view =
1943       bluetooth::hci::LePeriodicAdvertisingCreateSyncView::Create(command);
1944   ASSERT(command_view.IsValid());
1945   ErrorCode status = link_layer_controller_.LePeriodicAdvertisingCreateSync(
1946       command_view.GetOptions(), command_view.GetAdvertisingSid(),
1947       command_view.GetAdvertiserAddressType(),
1948       command_view.GetAdvertiserAddress(), command_view.GetSkip(),
1949       command_view.GetSyncTimeout(), command_view.GetSyncCteType());
1950   send_event_(
1951       bluetooth::hci::LePeriodicAdvertisingCreateSyncStatusBuilder::Create(
1952           status, kNumCommandPackets));
1953 }
1954 
LePeriodicAdvertisingCreateSyncCancel(CommandView command)1955 void DualModeController::LePeriodicAdvertisingCreateSyncCancel(
1956     CommandView command) {
1957   auto command_view =
1958       bluetooth::hci::LePeriodicAdvertisingCreateSyncCancelView::Create(
1959           command);
1960   ASSERT(command_view.IsValid());
1961   ErrorCode status =
1962       link_layer_controller_.LePeriodicAdvertisingCreateSyncCancel();
1963   send_event_(
1964       bluetooth::hci::LePeriodicAdvertisingCreateSyncCancelCompleteBuilder::
1965           Create(kNumCommandPackets, status));
1966 }
1967 
LePeriodicAdvertisingTerminateSync(CommandView command)1968 void DualModeController::LePeriodicAdvertisingTerminateSync(
1969     CommandView command) {
1970   auto command_view =
1971       bluetooth::hci::LePeriodicAdvertisingTerminateSyncView::Create(command);
1972   ASSERT(command_view.IsValid());
1973   ErrorCode status = link_layer_controller_.LePeriodicAdvertisingTerminateSync(
1974       command_view.GetSyncHandle());
1975   send_event_(
1976       bluetooth::hci::LePeriodicAdvertisingTerminateSyncCompleteBuilder::Create(
1977           kNumCommandPackets, status));
1978 }
1979 
LeAddDeviceToPeriodicAdvertiserList(CommandView command)1980 void DualModeController::LeAddDeviceToPeriodicAdvertiserList(
1981     CommandView command) {
1982   auto command_view =
1983       bluetooth::hci::LeAddDeviceToPeriodicAdvertiserListView::Create(command);
1984   ASSERT(command_view.IsValid());
1985   ErrorCode status = link_layer_controller_.LeAddDeviceToPeriodicAdvertiserList(
1986       command_view.GetAdvertiserAddressType(),
1987       command_view.GetAdvertiserAddress(), command_view.GetAdvertisingSid());
1988   send_event_(
1989       bluetooth::hci::LeAddDeviceToPeriodicAdvertiserListCompleteBuilder::
1990           Create(kNumCommandPackets, status));
1991 }
1992 
LeRemoveDeviceFromPeriodicAdvertiserList(CommandView command)1993 void DualModeController::LeRemoveDeviceFromPeriodicAdvertiserList(
1994     CommandView command) {
1995   auto command_view =
1996       bluetooth::hci::LeRemoveDeviceFromPeriodicAdvertiserListView::Create(
1997           command);
1998   ASSERT(command_view.IsValid());
1999   ErrorCode status =
2000       link_layer_controller_.LeRemoveDeviceFromPeriodicAdvertiserList(
2001           command_view.GetAdvertiserAddressType(),
2002           command_view.GetAdvertiserAddress(),
2003           command_view.GetAdvertisingSid());
2004   send_event_(
2005       bluetooth::hci::LeRemoveDeviceFromPeriodicAdvertiserListCompleteBuilder::
2006           Create(kNumCommandPackets, status));
2007 }
2008 
LeClearPeriodicAdvertiserList(CommandView command)2009 void DualModeController::LeClearPeriodicAdvertiserList(CommandView command) {
2010   auto command_view =
2011       bluetooth::hci::LeClearPeriodicAdvertiserListView::Create(command);
2012   ASSERT(command_view.IsValid());
2013   ErrorCode status = link_layer_controller_.LeClearPeriodicAdvertiserList();
2014   send_event_(
2015       bluetooth::hci::LeClearPeriodicAdvertiserListCompleteBuilder::Create(
2016           kNumCommandPackets, status));
2017 }
2018 
LeReadPeriodicAdvertiserListSize(CommandView command)2019 void DualModeController::LeReadPeriodicAdvertiserListSize(CommandView command) {
2020   auto command_view =
2021       bluetooth::hci::LeReadPeriodicAdvertiserListSizeView::Create(command);
2022   ASSERT(command_view.IsValid());
2023   send_event_(
2024       bluetooth::hci::LeReadPeriodicAdvertiserListSizeCompleteBuilder::Create(
2025           kNumCommandPackets, ErrorCode::SUCCESS,
2026           properties_.le_periodic_advertiser_list_size));
2027 }
2028 
LeSetExtendedScanParameters(CommandView command)2029 void DualModeController::LeSetExtendedScanParameters(CommandView command) {
2030   auto command_view =
2031       bluetooth::hci::LeSetExtendedScanParametersView::Create(command);
2032   ASSERT(command_view.IsValid());
2033   ErrorCode status = link_layer_controller_.LeSetExtendedScanParameters(
2034       command_view.GetOwnAddressType(), command_view.GetScanningFilterPolicy(),
2035       command_view.GetScanningPhys(), command_view.GetParameters());
2036   send_event_(
2037       bluetooth::hci::LeSetExtendedScanParametersCompleteBuilder::Create(
2038           kNumCommandPackets, status));
2039 }
2040 
LeSetExtendedScanEnable(CommandView command)2041 void DualModeController::LeSetExtendedScanEnable(CommandView command) {
2042   auto command_view =
2043       bluetooth::hci::LeSetExtendedScanEnableView::Create(command);
2044   ASSERT(command_view.IsValid());
2045   ErrorCode status = link_layer_controller_.LeSetExtendedScanEnable(
2046       command_view.GetEnable() == bluetooth::hci::Enable::ENABLED,
2047       command_view.GetFilterDuplicates(), command_view.GetDuration(),
2048       command_view.GetPeriod());
2049   send_event_(bluetooth::hci::LeSetExtendedScanEnableCompleteBuilder::Create(
2050       kNumCommandPackets, status));
2051 }
2052 
LeExtendedCreateConnection(CommandView command)2053 void DualModeController::LeExtendedCreateConnection(CommandView command) {
2054   auto command_view =
2055       bluetooth::hci::LeExtendedCreateConnectionView::Create(command);
2056   ASSERT(command_view.IsValid());
2057   ErrorCode status = link_layer_controller_.LeExtendedCreateConnection(
2058       command_view.GetInitiatorFilterPolicy(), command_view.GetOwnAddressType(),
2059       AddressWithType{
2060           command_view.GetPeerAddress(),
2061           command_view.GetPeerAddressType(),
2062       },
2063       command_view.GetInitiatingPhys(), command_view.GetPhyScanParameters());
2064   send_event_(bluetooth::hci::LeExtendedCreateConnectionStatusBuilder::Create(
2065       status, kNumCommandPackets));
2066 }
2067 
LeSetPrivacyMode(CommandView command)2068 void DualModeController::LeSetPrivacyMode(CommandView command) {
2069   auto command_view = bluetooth::hci::LeSetPrivacyModeView::Create(command);
2070   ASSERT(command_view.IsValid());
2071   ErrorCode status = link_layer_controller_.LeSetPrivacyMode(
2072       command_view.GetPeerIdentityAddressType(),
2073       command_view.GetPeerIdentityAddress(), command_view.GetPrivacyMode());
2074   send_event_(bluetooth::hci::LeSetPrivacyModeCompleteBuilder::Create(
2075       kNumCommandPackets, status));
2076 }
2077 
LeReadIsoTxSync(CommandView command)2078 void DualModeController::LeReadIsoTxSync(CommandView command) {
2079   auto command_view = bluetooth::hci::LeReadIsoTxSyncView::Create(command);
2080   ASSERT(command_view.IsValid());
2081   link_layer_controller_.LeReadIsoTxSync(command_view.GetConnectionHandle());
2082 }
2083 
LeSetCigParameters(CommandView command)2084 void DualModeController::LeSetCigParameters(CommandView command) {
2085   auto command_view = bluetooth::hci::LeSetCigParametersView::Create(command);
2086   ASSERT(command_view.IsValid());
2087   link_layer_controller_.LeSetCigParameters(
2088       command_view.GetCigId(), command_view.GetSduIntervalMToS(),
2089       command_view.GetSduIntervalSToM(),
2090       command_view.GetPeripheralsClockAccuracy(), command_view.GetPacking(),
2091       command_view.GetFraming(), command_view.GetMaxTransportLatencyMToS(),
2092       command_view.GetMaxTransportLatencySToM(), command_view.GetCisConfig());
2093 }
2094 
LeCreateCis(CommandView command)2095 void DualModeController::LeCreateCis(CommandView command) {
2096   auto command_view = bluetooth::hci::LeCreateCisView::Create(command);
2097   ASSERT(command_view.IsValid());
2098   ErrorCode status =
2099       link_layer_controller_.LeCreateCis(command_view.GetCisConfig());
2100   send_event_(bluetooth::hci::LeCreateCisStatusBuilder::Create(
2101       status, kNumCommandPackets));
2102 }
2103 
LeRemoveCig(CommandView command)2104 void DualModeController::LeRemoveCig(CommandView command) {
2105   auto command_view = bluetooth::hci::LeRemoveCigView::Create(command);
2106   ASSERT(command_view.IsValid());
2107   uint8_t cig = command_view.GetCigId();
2108   ErrorCode status = link_layer_controller_.LeRemoveCig(cig);
2109   send_event_(bluetooth::hci::LeRemoveCigCompleteBuilder::Create(
2110       kNumCommandPackets, status, cig));
2111 }
2112 
LeAcceptCisRequest(CommandView command)2113 void DualModeController::LeAcceptCisRequest(CommandView command) {
2114   auto command_view = bluetooth::hci::LeAcceptCisRequestView::Create(command);
2115   ASSERT(command_view.IsValid());
2116   ErrorCode status = link_layer_controller_.LeAcceptCisRequest(
2117       command_view.GetConnectionHandle());
2118   send_event_(bluetooth::hci::LeAcceptCisRequestStatusBuilder::Create(
2119       status, kNumCommandPackets));
2120 }
2121 
LeRejectCisRequest(CommandView command)2122 void DualModeController::LeRejectCisRequest(CommandView command) {
2123   auto command_view = bluetooth::hci::LeRejectCisRequestView::Create(command);
2124   ASSERT(command_view.IsValid());
2125   link_layer_controller_.LeRejectCisRequest(command_view.GetConnectionHandle(),
2126                                             command_view.GetReason());
2127 }
2128 
LeCreateBig(CommandView command)2129 void DualModeController::LeCreateBig(CommandView command) {
2130   auto command_view = bluetooth::hci::LeCreateBigView::Create(command);
2131   ASSERT(command_view.IsValid());
2132   ErrorCode status = link_layer_controller_.LeCreateBig(
2133       command_view.GetBigHandle(), command_view.GetAdvertisingHandle(),
2134       command_view.GetNumBis(), command_view.GetSduInterval(),
2135       command_view.GetMaxSdu(), command_view.GetMaxTransportLatency(),
2136       command_view.GetRtn(), command_view.GetPhy(), command_view.GetPacking(),
2137       command_view.GetFraming(), command_view.GetEncryption(),
2138       command_view.GetBroadcastCode());
2139   send_event_(bluetooth::hci::LeCreateBigStatusBuilder::Create(
2140       status, kNumCommandPackets));
2141 }
2142 
LeTerminateBig(CommandView command)2143 void DualModeController::LeTerminateBig(CommandView command) {
2144   auto command_view = bluetooth::hci::LeTerminateBigView::Create(command);
2145   ASSERT(command_view.IsValid());
2146   ErrorCode status = link_layer_controller_.LeTerminateBig(
2147       command_view.GetBigHandle(), command_view.GetReason());
2148   send_event_(bluetooth::hci::LeTerminateBigStatusBuilder::Create(
2149       status, kNumCommandPackets));
2150 }
2151 
LeBigCreateSync(CommandView command)2152 void DualModeController::LeBigCreateSync(CommandView command) {
2153   auto command_view = bluetooth::hci::LeBigCreateSyncView::Create(command);
2154   ASSERT(command_view.IsValid());
2155   ErrorCode status = link_layer_controller_.LeBigCreateSync(
2156       command_view.GetBigHandle(), command_view.GetSyncHandle(),
2157       command_view.GetEncryption(), command_view.GetBroadcastCode(),
2158       command_view.GetMse(), command_view.GetBigSyncTimeout(),
2159       command_view.GetBis());
2160   send_event_(bluetooth::hci::LeBigCreateSyncStatusBuilder::Create(
2161       status, kNumCommandPackets));
2162 }
2163 
LeBigTerminateSync(CommandView command)2164 void DualModeController::LeBigTerminateSync(CommandView command) {
2165   auto command_view = bluetooth::hci::LeBigTerminateSyncView::Create(command);
2166   ASSERT(command_view.IsValid());
2167   link_layer_controller_.LeBigTerminateSync(command_view.GetBigHandle());
2168 }
2169 
LeRequestPeerSca(CommandView command)2170 void DualModeController::LeRequestPeerSca(CommandView command) {
2171   auto command_view = bluetooth::hci::LeRequestPeerScaView::Create(command);
2172   ASSERT(command_view.IsValid());
2173   ErrorCode status = link_layer_controller_.LeRequestPeerSca(
2174       command_view.GetConnectionHandle());
2175   send_event_(bluetooth::hci::LeRequestPeerScaStatusBuilder::Create(
2176       status, kNumCommandPackets));
2177 }
2178 
LeSetupIsoDataPath(CommandView command)2179 void DualModeController::LeSetupIsoDataPath(CommandView command) {
2180   auto command_view = bluetooth::hci::LeSetupIsoDataPathView::Create(command);
2181   ASSERT(command_view.IsValid());
2182   link_layer_controller_.LeSetupIsoDataPath(
2183       command_view.GetConnectionHandle(), command_view.GetDataPathDirection(),
2184       command_view.GetDataPathId(), command_view.GetCodecId(),
2185       command_view.GetControllerDelay(), command_view.GetCodecConfiguration());
2186 }
2187 
LeRemoveIsoDataPath(CommandView command)2188 void DualModeController::LeRemoveIsoDataPath(CommandView command) {
2189   auto command_view = bluetooth::hci::LeRemoveIsoDataPathView::Create(command);
2190   ASSERT(command_view.IsValid());
2191   link_layer_controller_.LeRemoveIsoDataPath(
2192       command_view.GetConnectionHandle(),
2193       command_view.GetRemoveDataPathDirection());
2194 }
2195 
LeReadRemoteFeatures(CommandView command)2196 void DualModeController::LeReadRemoteFeatures(CommandView command) {
2197   auto command_view = bluetooth::hci::LeReadRemoteFeaturesView::Create(command);
2198   ASSERT(command_view.IsValid());
2199 
2200   uint16_t handle = command_view.GetConnectionHandle();
2201 
2202   auto status = link_layer_controller_.SendCommandToRemoteByHandle(
2203       OpCode::LE_READ_REMOTE_FEATURES, command_view.GetPayload(), handle);
2204 
2205   send_event_(bluetooth::hci::LeReadRemoteFeaturesStatusBuilder::Create(
2206       status, kNumCommandPackets));
2207 }
2208 
LeEncrypt(CommandView command)2209 void DualModeController::LeEncrypt(CommandView command) {
2210   auto command_view = bluetooth::hci::LeEncryptView::Create(command);
2211   ASSERT(command_view.IsValid());
2212 
2213   auto encrypted_data = rootcanal::crypto::aes_128(
2214       command_view.GetKey(), command_view.GetPlaintextData());
2215 
2216   send_event_(bluetooth::hci::LeEncryptCompleteBuilder::Create(
2217       kNumCommandPackets, ErrorCode::SUCCESS, encrypted_data));
2218 }
2219 
2220 static std::random_device rd{};
2221 static std::mt19937_64 s_mt{rd()};
2222 
LeRand(CommandView command)2223 void DualModeController::LeRand(CommandView command) {
2224   auto command_view = bluetooth::hci::LeRandView::Create(command);
2225   ASSERT(command_view.IsValid());
2226 
2227   uint64_t random_val = s_mt();
2228 
2229   send_event_(bluetooth::hci::LeRandCompleteBuilder::Create(
2230       kNumCommandPackets, ErrorCode::SUCCESS, random_val));
2231 }
2232 
LeReadSupportedStates(CommandView command)2233 void DualModeController::LeReadSupportedStates(CommandView command) {
2234   auto command_view =
2235       bluetooth::hci::LeReadSupportedStatesView::Create(command);
2236   ASSERT(command_view.IsValid());
2237   send_event_(bluetooth::hci::LeReadSupportedStatesCompleteBuilder::Create(
2238       kNumCommandPackets, ErrorCode::SUCCESS, properties_.le_supported_states));
2239 }
2240 
LeRemoteConnectionParameterRequestReply(CommandView command)2241 void DualModeController::LeRemoteConnectionParameterRequestReply(
2242     CommandView command) {
2243   auto command_view =
2244       bluetooth::hci::LeRemoteConnectionParameterRequestReplyView::Create(
2245           command);
2246   ASSERT(command_view.IsValid());
2247   auto status = link_layer_controller_.LeRemoteConnectionParameterRequestReply(
2248       command_view.GetConnectionHandle(), command_view.GetIntervalMin(),
2249       command_view.GetIntervalMax(), command_view.GetTimeout(),
2250       command_view.GetLatency(), command_view.GetMinimumCeLength(),
2251       command_view.GetMaximumCeLength());
2252   send_event_(
2253       bluetooth::hci::LeRemoteConnectionParameterRequestReplyCompleteBuilder::
2254           Create(kNumCommandPackets, status,
2255                  command_view.GetConnectionHandle()));
2256 }
2257 
LeRemoteConnectionParameterRequestNegativeReply(CommandView command)2258 void DualModeController::LeRemoteConnectionParameterRequestNegativeReply(
2259     CommandView command) {
2260   auto command_view = bluetooth::hci::
2261       LeRemoteConnectionParameterRequestNegativeReplyView::Create(command);
2262   ASSERT(command_view.IsValid());
2263   auto status =
2264       link_layer_controller_.LeRemoteConnectionParameterRequestNegativeReply(
2265           command_view.GetConnectionHandle(), command_view.GetReason());
2266   send_event_(
2267       bluetooth::hci::
2268           LeRemoteConnectionParameterRequestNegativeReplyCompleteBuilder::
2269               Create(kNumCommandPackets, status,
2270                      command_view.GetConnectionHandle()));
2271 }
2272 
LeGetVendorCapabilities(CommandView command)2273 void DualModeController::LeGetVendorCapabilities(CommandView command) {
2274   auto command_view = bluetooth::hci::LeGetVendorCapabilitiesView::Create(
2275       bluetooth::hci::VendorCommandView::Create(command));
2276   ASSERT(command_view.IsValid());
2277 
2278   if (!properties_.supports_le_get_vendor_capabilities_command) {
2279     SendCommandCompleteUnknownOpCodeEvent(OpCode::LE_GET_VENDOR_CAPABILITIES);
2280     return;
2281   }
2282 
2283   // Ensure a minimal size for vendor capabilities.
2284   vector<uint8_t> vendor_capabilities = properties_.le_vendor_capabilities;
2285   if (vendor_capabilities.size() < 8) {
2286     vendor_capabilities.resize(8);
2287   }
2288 
2289   std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
2290       std::make_unique<bluetooth::packet::RawBuilder>();
2291   raw_builder_ptr->AddOctets1(static_cast<uint8_t>(ErrorCode::SUCCESS));
2292   raw_builder_ptr->AddOctets(vendor_capabilities);
2293 
2294   send_event_(bluetooth::hci::CommandCompleteBuilder::Create(
2295       kNumCommandPackets, OpCode::LE_GET_VENDOR_CAPABILITIES,
2296       std::move(raw_builder_ptr)));
2297 }
2298 
LeMultiAdv(CommandView command)2299 void DualModeController::LeMultiAdv(CommandView command) {
2300   auto command_view = bluetooth::hci::LeMultiAdvtView::Create(command);
2301   ASSERT(command_view.IsValid());
2302   SendCommandCompleteUnknownOpCodeEvent(OpCode::LE_MULTI_ADVT);
2303 }
2304 
LeAdvertisingFilter(CommandView command)2305 void DualModeController::LeAdvertisingFilter(CommandView command) {
2306   auto command_view = bluetooth::hci::LeAdvFilterView::Create(command);
2307   ASSERT(command_view.IsValid());
2308   SendCommandCompleteUnknownOpCodeEvent(OpCode::LE_ADV_FILTER);
2309 }
2310 
LeEnergyInfo(CommandView command)2311 void DualModeController::LeEnergyInfo(CommandView command) {
2312   auto command_view = bluetooth::hci::LeEnergyInfoView::Create(
2313       bluetooth::hci::VendorCommandView::Create(command));
2314   ASSERT(command_view.IsValid());
2315   SendCommandCompleteUnknownOpCodeEvent(OpCode::LE_ENERGY_INFO);
2316 }
2317 
2318 // CSR vendor command.
2319 // Implement the command specific to the CSR controller
2320 // used specifically by the PTS tool to pass certification tests.
CsrVendorCommand(CommandView command)2321 void DualModeController::CsrVendorCommand(CommandView command) {
2322   // The byte order is little endian.
2323   // The command parameters are formatted as
2324   //
2325   //  00    | 0xc2
2326   //  01 02 | action
2327   //          read = 0
2328   //          write = 2
2329   //  03 04 | (value length / 2) + 5
2330   //  04 05 | sequence number
2331   //  06 07 | varid
2332   //  08 09 | 00 00
2333   //  0a .. | value
2334   //
2335   // BlueZ has a reference implementation of the CSR vendor command.
2336 
2337   std::vector<uint8_t> parameters(command.GetPayload().begin(),
2338                                   command.GetPayload().end());
2339 
2340   uint16_t type = 0;
2341   uint16_t length = 0;
2342   uint16_t varid = 0;
2343 
2344   if (parameters.empty()) {
2345     LOG_INFO("Empty CSR vendor command");
2346     goto complete;
2347   }
2348 
2349   if (parameters[0] != 0xc2 || parameters.size() < 11) {
2350     LOG_INFO(
2351         "Unsupported CSR vendor command with code %02x "
2352         "and parameter length %zu",
2353         static_cast<int>(parameters[0]), parameters.size());
2354     goto complete;
2355   }
2356 
2357   type = (uint16_t)parameters[1] | ((uint16_t)parameters[2] << 8);
2358   length = (uint16_t)parameters[3] | ((uint16_t)parameters[4] << 8);
2359   varid = (uint16_t)parameters[7] | ((uint16_t)parameters[8] << 8);
2360   length = 2 * (length - 5);
2361 
2362   if (parameters.size() < (11 + length) ||
2363       (varid == CsrVarid::CSR_VARID_PS && length < 6)) {
2364     LOG_INFO("Invalid CSR vendor command parameter length %zu, expected %u",
2365              parameters.size(), 11 + length);
2366     goto complete;
2367   }
2368 
2369   if (varid == CsrVarid::CSR_VARID_PS) {
2370     // Subcommand to read or write PSKEY of the selected identifier
2371     // instead of VARID.
2372     uint16_t pskey = (uint16_t)parameters[11] | ((uint16_t)parameters[12] << 8);
2373     uint16_t length =
2374         (uint16_t)parameters[13] | ((uint16_t)parameters[14] << 8);
2375     length = 2 * length;
2376 
2377     if (parameters.size() < (17 + length)) {
2378       LOG_INFO("Invalid CSR vendor command parameter length %zu, expected %u",
2379                parameters.size(), 17 + length);
2380       goto complete;
2381     }
2382 
2383     std::vector<uint8_t> value(parameters.begin() + 17,
2384                                parameters.begin() + 17 + length);
2385 
2386     LOG_INFO("CSR vendor command type=%04x length=%04x pskey=%04x", type,
2387              length, pskey);
2388 
2389     if (type == 0) {
2390       CsrReadPskey(static_cast<CsrPskey>(pskey), value);
2391       std::copy(value.begin(), value.end(), parameters.begin() + 17);
2392     } else {
2393       CsrWritePskey(static_cast<CsrPskey>(pskey), value);
2394     }
2395 
2396   } else {
2397     // Subcommand to read or write VARID of the selected identifier.
2398     std::vector<uint8_t> value(parameters.begin() + 11,
2399                                parameters.begin() + 11 + length);
2400 
2401     LOG_INFO("CSR vendor command type=%04x length=%04x varid=%04x", type,
2402              length, varid);
2403 
2404     if (type == 0) {
2405       CsrReadVarid(static_cast<CsrVarid>(varid), value);
2406       std::copy(value.begin(), value.end(), parameters.begin() + 11);
2407     } else {
2408       CsrWriteVarid(static_cast<CsrVarid>(varid), value);
2409     }
2410   }
2411 
2412 complete:
2413   // Overwrite the command type.
2414   parameters[1] = 0x1;
2415   parameters[2] = 0x0;
2416   send_event_(bluetooth::hci::EventBuilder::Create(
2417       bluetooth::hci::EventCode::VENDOR_SPECIFIC,
2418       std::make_unique<bluetooth::packet::RawBuilder>(std::move(parameters))));
2419 }
2420 
2421 // NOLINTNEXTLINE(readability-convert-member-functions-to-static)
CsrReadVarid(CsrVarid varid,std::vector<uint8_t> & value)2422 void DualModeController::CsrReadVarid(CsrVarid varid,
2423                                       std::vector<uint8_t>& value) {
2424   switch (varid) {
2425     case CsrVarid::CSR_VARID_BUILDID:
2426       // Return the extact Build ID returned by the official PTS dongle.
2427       ASSERT(value.size() >= 2);
2428       value[0] = 0xe8;
2429       value[1] = 0x30;
2430       break;
2431 
2432     default:
2433       LOG_INFO("Unsupported read of CSR varid 0x%04x", varid);
2434       break;
2435   }
2436 }
2437 
2438 // NOLINTNEXTLINE(readability-convert-member-functions-to-static)
CsrWriteVarid(CsrVarid varid,std::vector<uint8_t> const & value)2439 void DualModeController::CsrWriteVarid(CsrVarid varid,
2440                                        std::vector<uint8_t> const& value) {
2441   LOG_INFO("Unsupported write of CSR varid 0x%04x", varid);
2442 }
2443 
2444 // NOLINTNEXTLINE(readability-convert-member-functions-to-static)
CsrReadPskey(CsrPskey pskey,std::vector<uint8_t> & value)2445 void DualModeController::CsrReadPskey(CsrPskey pskey,
2446                                       std::vector<uint8_t>& value) {
2447   switch (pskey) {
2448     case CsrPskey::CSR_PSKEY_ENC_KEY_LMIN:
2449       ASSERT(!value.empty());
2450       value[0] = 7;
2451       break;
2452 
2453     case CsrPskey::CSR_PSKEY_ENC_KEY_LMAX:
2454       ASSERT(!value.empty());
2455       value[0] = 16;
2456       break;
2457 
2458     case CSR_PSKEY_HCI_LMP_LOCAL_VERSION:
2459       // Return the extact version returned by the official PTS dongle.
2460       ASSERT(value.size() >= 2);
2461       value[0] = 0x08;
2462       value[1] = 0x08;
2463       break;
2464 
2465     default:
2466       LOG_INFO("Unsupported read of CSR pskey 0x%04x", pskey);
2467       break;
2468   }
2469 }
2470 
CsrWritePskey(CsrPskey pskey,std::vector<uint8_t> const & value)2471 void DualModeController::CsrWritePskey(CsrPskey pskey,
2472                                        std::vector<uint8_t> const& value) {
2473   switch (pskey) {
2474     case CsrPskey::CSR_PSKEY_LOCAL_SUPPORTED_FEATURES:
2475       ASSERT(value.size() >= 8);
2476       LOG_INFO("CSR Vendor updating the Local Supported Features");
2477       properties_.lmp_features[0] =
2478           ((uint64_t)value[0] << 0) | ((uint64_t)value[1] << 8) |
2479           ((uint64_t)value[2] << 16) | ((uint64_t)value[3] << 24) |
2480           ((uint64_t)value[4] << 32) | ((uint64_t)value[5] << 40) |
2481           ((uint64_t)value[6] << 48) | ((uint64_t)value[7] << 56);
2482       break;
2483 
2484     default:
2485       LOG_INFO("Unsupported write of CSR pskey 0x%04x", pskey);
2486       break;
2487   }
2488 }
2489 
LeSetAdvertisingSetRandomAddress(CommandView command)2490 void DualModeController::LeSetAdvertisingSetRandomAddress(CommandView command) {
2491   auto command_view =
2492       bluetooth::hci::LeSetAdvertisingSetRandomAddressView::Create(command);
2493   ASSERT(command_view.IsValid());
2494   ErrorCode status = link_layer_controller_.LeSetAdvertisingSetRandomAddress(
2495       command_view.GetAdvertisingHandle(), command_view.GetRandomAddress());
2496   send_event_(
2497       bluetooth::hci::LeSetAdvertisingSetRandomAddressCompleteBuilder::Create(
2498           kNumCommandPackets, status));
2499 }
2500 
LeSetExtendedAdvertisingParameters(CommandView command)2501 void DualModeController::LeSetExtendedAdvertisingParameters(
2502     CommandView command) {
2503   auto command_view =
2504       bluetooth::hci::LeSetExtendedAdvertisingParametersView::Create(command);
2505   ASSERT(command_view.IsValid());
2506   ErrorCode status = link_layer_controller_.LeSetExtendedAdvertisingParameters(
2507       command_view.GetAdvertisingHandle(),
2508       command_view.GetAdvertisingEventProperties(),
2509       command_view.GetPrimaryAdvertisingIntervalMin(),
2510       command_view.GetPrimaryAdvertisingIntervalMax(),
2511       command_view.GetPrimaryAdvertisingChannelMap(),
2512       command_view.GetOwnAddressType(), command_view.GetPeerAddressType(),
2513       command_view.GetPeerAddress(), command_view.GetAdvertisingFilterPolicy(),
2514       command_view.GetAdvertisingTxPower(),
2515       command_view.GetPrimaryAdvertisingPhy(),
2516       command_view.GetSecondaryAdvertisingMaxSkip(),
2517       command_view.GetSecondaryAdvertisingPhy(),
2518       command_view.GetAdvertisingSid(),
2519       command_view.GetScanRequestNotificationEnable() == Enable::ENABLED);
2520   // The selected TX power is always the requested TX power
2521   // at the moment.
2522   send_event_(
2523       bluetooth::hci::LeSetExtendedAdvertisingParametersCompleteBuilder::Create(
2524           kNumCommandPackets, status, command_view.GetAdvertisingTxPower()));
2525 }
2526 
LeSetExtendedAdvertisingData(CommandView command)2527 void DualModeController::LeSetExtendedAdvertisingData(CommandView command) {
2528   auto command_view =
2529       bluetooth::hci::LeSetExtendedAdvertisingDataView::Create(command);
2530   ASSERT(command_view.IsValid());
2531   auto raw_command_view =
2532       bluetooth::hci::LeSetExtendedAdvertisingDataRawView::Create(command);
2533   ASSERT(raw_command_view.IsValid());
2534   ErrorCode status = link_layer_controller_.LeSetExtendedAdvertisingData(
2535       command_view.GetAdvertisingHandle(), command_view.GetOperation(),
2536       command_view.GetFragmentPreference(),
2537       raw_command_view.GetAdvertisingData());
2538   send_event_(
2539       bluetooth::hci::LeSetExtendedAdvertisingDataCompleteBuilder::Create(
2540           kNumCommandPackets, status));
2541 }
2542 
LeSetExtendedScanResponseData(CommandView command)2543 void DualModeController::LeSetExtendedScanResponseData(CommandView command) {
2544   auto command_view =
2545       bluetooth::hci::LeSetExtendedScanResponseDataView::Create(command);
2546   ASSERT(command_view.IsValid());
2547   auto raw_command_view =
2548       bluetooth::hci::LeSetExtendedScanResponseDataRawView::Create(command);
2549   ASSERT(raw_command_view.IsValid());
2550   ErrorCode status = link_layer_controller_.LeSetExtendedScanResponseData(
2551       command_view.GetAdvertisingHandle(), command_view.GetOperation(),
2552       command_view.GetFragmentPreference(),
2553       raw_command_view.GetScanResponseData());
2554   send_event_(
2555       bluetooth::hci::LeSetExtendedScanResponseDataCompleteBuilder::Create(
2556           kNumCommandPackets, status));
2557 }
2558 
LeSetExtendedAdvertisingEnable(CommandView command)2559 void DualModeController::LeSetExtendedAdvertisingEnable(CommandView command) {
2560   auto command_view =
2561       bluetooth::hci::LeSetExtendedAdvertisingEnableView::Create(command);
2562   ASSERT(command_view.IsValid());
2563   ErrorCode status = link_layer_controller_.LeSetExtendedAdvertisingEnable(
2564       command_view.GetEnable() == bluetooth::hci::Enable::ENABLED,
2565       command_view.GetEnabledSets());
2566   send_event_(
2567       bluetooth::hci::LeSetExtendedAdvertisingEnableCompleteBuilder::Create(
2568           kNumCommandPackets, status));
2569 }
2570 
LeReadMaximumAdvertisingDataLength(CommandView command)2571 void DualModeController::LeReadMaximumAdvertisingDataLength(
2572     CommandView command) {
2573   auto command_view =
2574       bluetooth::hci::LeReadMaximumAdvertisingDataLengthView::Create(command);
2575   ASSERT(command_view.IsValid());
2576   send_event_(
2577       bluetooth::hci::LeReadMaximumAdvertisingDataLengthCompleteBuilder::Create(
2578           kNumCommandPackets, ErrorCode::SUCCESS,
2579           properties_.le_max_advertising_data_length));
2580 }
2581 
LeReadNumberOfSupportedAdvertisingSets(CommandView command)2582 void DualModeController::LeReadNumberOfSupportedAdvertisingSets(
2583     CommandView command) {
2584   auto command_view =
2585       bluetooth::hci::LeReadNumberOfSupportedAdvertisingSetsView::Create(
2586           command);
2587   ASSERT(command_view.IsValid());
2588   send_event_(
2589       bluetooth::hci::LeReadNumberOfSupportedAdvertisingSetsCompleteBuilder::
2590           Create(kNumCommandPackets, ErrorCode::SUCCESS,
2591                  properties_.le_num_supported_advertising_sets));
2592 }
2593 
LeRemoveAdvertisingSet(CommandView command)2594 void DualModeController::LeRemoveAdvertisingSet(CommandView command) {
2595   auto command_view =
2596       bluetooth::hci::LeRemoveAdvertisingSetView::Create(command);
2597   ASSERT(command_view.IsValid());
2598   auto status = link_layer_controller_.LeRemoveAdvertisingSet(
2599       command_view.GetAdvertisingHandle());
2600   send_event_(bluetooth::hci::LeRemoveAdvertisingSetCompleteBuilder::Create(
2601       kNumCommandPackets, status));
2602 }
2603 
LeClearAdvertisingSets(CommandView command)2604 void DualModeController::LeClearAdvertisingSets(CommandView command) {
2605   auto command_view =
2606       bluetooth::hci::LeClearAdvertisingSetsView::Create(command);
2607   ASSERT(command_view.IsValid());
2608   auto status = link_layer_controller_.LeClearAdvertisingSets();
2609   send_event_(bluetooth::hci::LeClearAdvertisingSetsCompleteBuilder::Create(
2610       kNumCommandPackets, status));
2611 }
2612 
LeExtendedScanParams(CommandView command)2613 void DualModeController::LeExtendedScanParams(CommandView command) {
2614   auto command_view = bluetooth::hci::LeExtendedScanParamsView::Create(command);
2615   ASSERT(command_view.IsValid());
2616   SendCommandCompleteUnknownOpCodeEvent(OpCode::LE_EXTENDED_SCAN_PARAMS);
2617 }
2618 
LeStartEncryption(CommandView command)2619 void DualModeController::LeStartEncryption(CommandView command) {
2620   auto command_view = bluetooth::hci::LeStartEncryptionView::Create(command);
2621   ASSERT(command_view.IsValid());
2622 
2623   ErrorCode status = link_layer_controller_.LeEnableEncryption(
2624       command_view.GetConnectionHandle(), command_view.GetRand(),
2625       command_view.GetEdiv(), command_view.GetLtk());
2626 
2627   send_event_(bluetooth::hci::LeStartEncryptionStatusBuilder::Create(
2628       status, kNumCommandPackets));
2629 }
2630 
LeLongTermKeyRequestReply(CommandView command)2631 void DualModeController::LeLongTermKeyRequestReply(CommandView command) {
2632   auto command_view =
2633       bluetooth::hci::LeLongTermKeyRequestReplyView::Create(command);
2634   ASSERT(command_view.IsValid());
2635 
2636   uint16_t handle = command_view.GetConnectionHandle();
2637   ErrorCode status = link_layer_controller_.LeLongTermKeyRequestReply(
2638       handle, command_view.GetLongTermKey());
2639 
2640   send_event_(bluetooth::hci::LeLongTermKeyRequestReplyCompleteBuilder::Create(
2641       kNumCommandPackets, status, handle));
2642 }
2643 
LeLongTermKeyRequestNegativeReply(CommandView command)2644 void DualModeController::LeLongTermKeyRequestNegativeReply(
2645     CommandView command) {
2646   auto command_view =
2647       bluetooth::hci::LeLongTermKeyRequestNegativeReplyView::Create(command);
2648   ASSERT(command_view.IsValid());
2649 
2650   uint16_t handle = command_view.GetConnectionHandle();
2651   ErrorCode status =
2652       link_layer_controller_.LeLongTermKeyRequestNegativeReply(handle);
2653 
2654   send_event_(
2655       bluetooth::hci::LeLongTermKeyRequestNegativeReplyCompleteBuilder::Create(
2656           kNumCommandPackets, status, handle));
2657 }
2658 
ReadClassOfDevice(CommandView command)2659 void DualModeController::ReadClassOfDevice(CommandView command) {
2660   auto command_view = bluetooth::hci::ReadClassOfDeviceView::Create(command);
2661   ASSERT(command_view.IsValid());
2662 
2663   send_event_(bluetooth::hci::ReadClassOfDeviceCompleteBuilder::Create(
2664       kNumCommandPackets, ErrorCode::SUCCESS,
2665       link_layer_controller_.GetClassOfDevice()));
2666 }
2667 
ReadVoiceSetting(CommandView command)2668 void DualModeController::ReadVoiceSetting(CommandView command) {
2669   auto command_view = bluetooth::hci::ReadVoiceSettingView::Create(command);
2670   ASSERT(command_view.IsValid());
2671 
2672   send_event_(bluetooth::hci::ReadVoiceSettingCompleteBuilder::Create(
2673       kNumCommandPackets, ErrorCode::SUCCESS,
2674       link_layer_controller_.GetVoiceSetting()));
2675 }
2676 
ReadConnectionAcceptTimeout(CommandView command)2677 void DualModeController::ReadConnectionAcceptTimeout(CommandView command) {
2678   auto command_view =
2679       bluetooth::hci::ReadConnectionAcceptTimeoutView::Create(command);
2680   ASSERT(command_view.IsValid());
2681 
2682   send_event_(
2683       bluetooth::hci::ReadConnectionAcceptTimeoutCompleteBuilder::Create(
2684           kNumCommandPackets, ErrorCode::SUCCESS,
2685           link_layer_controller_.GetConnectionAcceptTimeout()));
2686 }
2687 
WriteConnectionAcceptTimeout(CommandView command)2688 void DualModeController::WriteConnectionAcceptTimeout(CommandView command) {
2689   auto command_view =
2690       bluetooth::hci::WriteConnectionAcceptTimeoutView::Create(command);
2691   ASSERT(command_view.IsValid());
2692 
2693   link_layer_controller_.SetConnectionAcceptTimeout(
2694       command_view.GetConnAcceptTimeout());
2695 
2696   send_event_(
2697       bluetooth::hci::WriteConnectionAcceptTimeoutCompleteBuilder::Create(
2698           kNumCommandPackets, ErrorCode::SUCCESS));
2699 }
2700 
ReadLoopbackMode(CommandView command)2701 void DualModeController::ReadLoopbackMode(CommandView command) {
2702   auto command_view = bluetooth::hci::ReadLoopbackModeView::Create(command);
2703   ASSERT(command_view.IsValid());
2704   send_event_(bluetooth::hci::ReadLoopbackModeCompleteBuilder::Create(
2705       kNumCommandPackets, ErrorCode::SUCCESS, loopback_mode_));
2706 }
2707 
WriteLoopbackMode(CommandView command)2708 void DualModeController::WriteLoopbackMode(CommandView command) {
2709   auto command_view = bluetooth::hci::WriteLoopbackModeView::Create(command);
2710   ASSERT(command_view.IsValid());
2711   loopback_mode_ = command_view.GetLoopbackMode();
2712   // ACL channel
2713   uint16_t acl_handle = 0x123;
2714   send_event_(bluetooth::hci::ConnectionCompleteBuilder::Create(
2715       ErrorCode::SUCCESS, acl_handle, GetAddress(),
2716       bluetooth::hci::LinkType::ACL, bluetooth::hci::Enable::DISABLED));
2717   // SCO channel
2718   uint16_t sco_handle = 0x345;
2719   send_event_(bluetooth::hci::ConnectionCompleteBuilder::Create(
2720       ErrorCode::SUCCESS, sco_handle, GetAddress(),
2721       bluetooth::hci::LinkType::SCO, bluetooth::hci::Enable::DISABLED));
2722   send_event_(bluetooth::hci::WriteLoopbackModeCompleteBuilder::Create(
2723       kNumCommandPackets, ErrorCode::SUCCESS));
2724 }
2725 
2726 // Note: the list does not contain all defined opcodes.
2727 // Notable exceptions:
2728 // - Vendor commands
2729 // - Read Local Supported Commands command
2730 const std::unordered_map<OpCode, OpCodeIndex>
2731     DualModeController::hci_command_op_code_to_index_{
2732         // LINK_CONTROL
2733         {OpCode::INQUIRY, OpCodeIndex::INQUIRY},
2734         {OpCode::INQUIRY_CANCEL, OpCodeIndex::INQUIRY_CANCEL},
2735         {OpCode::PERIODIC_INQUIRY_MODE, OpCodeIndex::PERIODIC_INQUIRY_MODE},
2736         {OpCode::EXIT_PERIODIC_INQUIRY_MODE,
2737          OpCodeIndex::EXIT_PERIODIC_INQUIRY_MODE},
2738         {OpCode::CREATE_CONNECTION, OpCodeIndex::CREATE_CONNECTION},
2739         {OpCode::DISCONNECT, OpCodeIndex::DISCONNECT},
2740         {OpCode::ADD_SCO_CONNECTION, OpCodeIndex::ADD_SCO_CONNECTION},
2741         {OpCode::CREATE_CONNECTION_CANCEL,
2742          OpCodeIndex::CREATE_CONNECTION_CANCEL},
2743         {OpCode::ACCEPT_CONNECTION_REQUEST,
2744          OpCodeIndex::ACCEPT_CONNECTION_REQUEST},
2745         {OpCode::REJECT_CONNECTION_REQUEST,
2746          OpCodeIndex::REJECT_CONNECTION_REQUEST},
2747         {OpCode::LINK_KEY_REQUEST_REPLY, OpCodeIndex::LINK_KEY_REQUEST_REPLY},
2748         {OpCode::LINK_KEY_REQUEST_NEGATIVE_REPLY,
2749          OpCodeIndex::LINK_KEY_REQUEST_NEGATIVE_REPLY},
2750         {OpCode::PIN_CODE_REQUEST_REPLY, OpCodeIndex::PIN_CODE_REQUEST_REPLY},
2751         {OpCode::PIN_CODE_REQUEST_NEGATIVE_REPLY,
2752          OpCodeIndex::PIN_CODE_REQUEST_NEGATIVE_REPLY},
2753         {OpCode::CHANGE_CONNECTION_PACKET_TYPE,
2754          OpCodeIndex::CHANGE_CONNECTION_PACKET_TYPE},
2755         {OpCode::AUTHENTICATION_REQUESTED,
2756          OpCodeIndex::AUTHENTICATION_REQUESTED},
2757         {OpCode::SET_CONNECTION_ENCRYPTION,
2758          OpCodeIndex::SET_CONNECTION_ENCRYPTION},
2759         {OpCode::CHANGE_CONNECTION_LINK_KEY,
2760          OpCodeIndex::CHANGE_CONNECTION_LINK_KEY},
2761         {OpCode::CENTRAL_LINK_KEY, OpCodeIndex::CENTRAL_LINK_KEY},
2762         {OpCode::REMOTE_NAME_REQUEST, OpCodeIndex::REMOTE_NAME_REQUEST},
2763         {OpCode::REMOTE_NAME_REQUEST_CANCEL,
2764          OpCodeIndex::REMOTE_NAME_REQUEST_CANCEL},
2765         {OpCode::READ_REMOTE_SUPPORTED_FEATURES,
2766          OpCodeIndex::READ_REMOTE_SUPPORTED_FEATURES},
2767         {OpCode::READ_REMOTE_EXTENDED_FEATURES,
2768          OpCodeIndex::READ_REMOTE_EXTENDED_FEATURES},
2769         {OpCode::READ_REMOTE_VERSION_INFORMATION,
2770          OpCodeIndex::READ_REMOTE_VERSION_INFORMATION},
2771         {OpCode::READ_CLOCK_OFFSET, OpCodeIndex::READ_CLOCK_OFFSET},
2772         {OpCode::READ_LMP_HANDLE, OpCodeIndex::READ_LMP_HANDLE},
2773         {OpCode::SETUP_SYNCHRONOUS_CONNECTION,
2774          OpCodeIndex::SETUP_SYNCHRONOUS_CONNECTION},
2775         {OpCode::ACCEPT_SYNCHRONOUS_CONNECTION,
2776          OpCodeIndex::ACCEPT_SYNCHRONOUS_CONNECTION},
2777         {OpCode::REJECT_SYNCHRONOUS_CONNECTION,
2778          OpCodeIndex::REJECT_SYNCHRONOUS_CONNECTION},
2779         {OpCode::IO_CAPABILITY_REQUEST_REPLY,
2780          OpCodeIndex::IO_CAPABILITY_REQUEST_REPLY},
2781         {OpCode::USER_CONFIRMATION_REQUEST_REPLY,
2782          OpCodeIndex::USER_CONFIRMATION_REQUEST_REPLY},
2783         {OpCode::USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY,
2784          OpCodeIndex::USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY},
2785         {OpCode::USER_PASSKEY_REQUEST_REPLY,
2786          OpCodeIndex::USER_PASSKEY_REQUEST_REPLY},
2787         {OpCode::USER_PASSKEY_REQUEST_NEGATIVE_REPLY,
2788          OpCodeIndex::USER_PASSKEY_REQUEST_NEGATIVE_REPLY},
2789         {OpCode::REMOTE_OOB_DATA_REQUEST_REPLY,
2790          OpCodeIndex::REMOTE_OOB_DATA_REQUEST_REPLY},
2791         {OpCode::REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY,
2792          OpCodeIndex::REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY},
2793         {OpCode::IO_CAPABILITY_REQUEST_NEGATIVE_REPLY,
2794          OpCodeIndex::IO_CAPABILITY_REQUEST_NEGATIVE_REPLY},
2795         {OpCode::ENHANCED_SETUP_SYNCHRONOUS_CONNECTION,
2796          OpCodeIndex::ENHANCED_SETUP_SYNCHRONOUS_CONNECTION},
2797         {OpCode::ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION,
2798          OpCodeIndex::ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION},
2799         {OpCode::TRUNCATED_PAGE, OpCodeIndex::TRUNCATED_PAGE},
2800         {OpCode::TRUNCATED_PAGE_CANCEL, OpCodeIndex::TRUNCATED_PAGE_CANCEL},
2801         {OpCode::SET_CONNECTIONLESS_PERIPHERAL_BROADCAST,
2802          OpCodeIndex::SET_CONNECTIONLESS_PERIPHERAL_BROADCAST},
2803         {OpCode::SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVE,
2804          OpCodeIndex::SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVE},
2805         {OpCode::START_SYNCHRONIZATION_TRAIN,
2806          OpCodeIndex::START_SYNCHRONIZATION_TRAIN},
2807         {OpCode::RECEIVE_SYNCHRONIZATION_TRAIN,
2808          OpCodeIndex::RECEIVE_SYNCHRONIZATION_TRAIN},
2809         {OpCode::REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY,
2810          OpCodeIndex::REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY},
2811 
2812         // LINK_POLICY
2813         {OpCode::HOLD_MODE, OpCodeIndex::HOLD_MODE},
2814         {OpCode::SNIFF_MODE, OpCodeIndex::SNIFF_MODE},
2815         {OpCode::EXIT_SNIFF_MODE, OpCodeIndex::EXIT_SNIFF_MODE},
2816         {OpCode::QOS_SETUP, OpCodeIndex::QOS_SETUP},
2817         {OpCode::ROLE_DISCOVERY, OpCodeIndex::ROLE_DISCOVERY},
2818         {OpCode::SWITCH_ROLE, OpCodeIndex::SWITCH_ROLE},
2819         {OpCode::READ_LINK_POLICY_SETTINGS,
2820          OpCodeIndex::READ_LINK_POLICY_SETTINGS},
2821         {OpCode::WRITE_LINK_POLICY_SETTINGS,
2822          OpCodeIndex::WRITE_LINK_POLICY_SETTINGS},
2823         {OpCode::READ_DEFAULT_LINK_POLICY_SETTINGS,
2824          OpCodeIndex::READ_DEFAULT_LINK_POLICY_SETTINGS},
2825         {OpCode::WRITE_DEFAULT_LINK_POLICY_SETTINGS,
2826          OpCodeIndex::WRITE_DEFAULT_LINK_POLICY_SETTINGS},
2827         {OpCode::FLOW_SPECIFICATION, OpCodeIndex::FLOW_SPECIFICATION},
2828         {OpCode::SNIFF_SUBRATING, OpCodeIndex::SNIFF_SUBRATING},
2829 
2830         // CONTROLLER_AND_BASEBAND
2831         {OpCode::SET_EVENT_MASK, OpCodeIndex::SET_EVENT_MASK},
2832         {OpCode::RESET, OpCodeIndex::RESET},
2833         {OpCode::SET_EVENT_FILTER, OpCodeIndex::SET_EVENT_FILTER},
2834         {OpCode::FLUSH, OpCodeIndex::FLUSH},
2835         {OpCode::READ_PIN_TYPE, OpCodeIndex::READ_PIN_TYPE},
2836         {OpCode::WRITE_PIN_TYPE, OpCodeIndex::WRITE_PIN_TYPE},
2837         {OpCode::READ_STORED_LINK_KEY, OpCodeIndex::READ_STORED_LINK_KEY},
2838         {OpCode::WRITE_STORED_LINK_KEY, OpCodeIndex::WRITE_STORED_LINK_KEY},
2839         {OpCode::DELETE_STORED_LINK_KEY, OpCodeIndex::DELETE_STORED_LINK_KEY},
2840         {OpCode::WRITE_LOCAL_NAME, OpCodeIndex::WRITE_LOCAL_NAME},
2841         {OpCode::READ_LOCAL_NAME, OpCodeIndex::READ_LOCAL_NAME},
2842         {OpCode::READ_CONNECTION_ACCEPT_TIMEOUT,
2843          OpCodeIndex::READ_CONNECTION_ACCEPT_TIMEOUT},
2844         {OpCode::WRITE_CONNECTION_ACCEPT_TIMEOUT,
2845          OpCodeIndex::WRITE_CONNECTION_ACCEPT_TIMEOUT},
2846         {OpCode::READ_PAGE_TIMEOUT, OpCodeIndex::READ_PAGE_TIMEOUT},
2847         {OpCode::WRITE_PAGE_TIMEOUT, OpCodeIndex::WRITE_PAGE_TIMEOUT},
2848         {OpCode::READ_SCAN_ENABLE, OpCodeIndex::READ_SCAN_ENABLE},
2849         {OpCode::WRITE_SCAN_ENABLE, OpCodeIndex::WRITE_SCAN_ENABLE},
2850         {OpCode::READ_PAGE_SCAN_ACTIVITY, OpCodeIndex::READ_PAGE_SCAN_ACTIVITY},
2851         {OpCode::WRITE_PAGE_SCAN_ACTIVITY,
2852          OpCodeIndex::WRITE_PAGE_SCAN_ACTIVITY},
2853         {OpCode::READ_INQUIRY_SCAN_ACTIVITY,
2854          OpCodeIndex::READ_INQUIRY_SCAN_ACTIVITY},
2855         {OpCode::WRITE_INQUIRY_SCAN_ACTIVITY,
2856          OpCodeIndex::WRITE_INQUIRY_SCAN_ACTIVITY},
2857         {OpCode::READ_AUTHENTICATION_ENABLE,
2858          OpCodeIndex::READ_AUTHENTICATION_ENABLE},
2859         {OpCode::WRITE_AUTHENTICATION_ENABLE,
2860          OpCodeIndex::WRITE_AUTHENTICATION_ENABLE},
2861         {OpCode::READ_CLASS_OF_DEVICE, OpCodeIndex::READ_CLASS_OF_DEVICE},
2862         {OpCode::WRITE_CLASS_OF_DEVICE, OpCodeIndex::WRITE_CLASS_OF_DEVICE},
2863         {OpCode::READ_VOICE_SETTING, OpCodeIndex::READ_VOICE_SETTING},
2864         {OpCode::WRITE_VOICE_SETTING, OpCodeIndex::WRITE_VOICE_SETTING},
2865         {OpCode::READ_AUTOMATIC_FLUSH_TIMEOUT,
2866          OpCodeIndex::READ_AUTOMATIC_FLUSH_TIMEOUT},
2867         {OpCode::WRITE_AUTOMATIC_FLUSH_TIMEOUT,
2868          OpCodeIndex::WRITE_AUTOMATIC_FLUSH_TIMEOUT},
2869         {OpCode::READ_NUM_BROADCAST_RETRANSMITS,
2870          OpCodeIndex::READ_NUM_BROADCAST_RETRANSMITS},
2871         {OpCode::WRITE_NUM_BROADCAST_RETRANSMITS,
2872          OpCodeIndex::WRITE_NUM_BROADCAST_RETRANSMITS},
2873         {OpCode::READ_HOLD_MODE_ACTIVITY, OpCodeIndex::READ_HOLD_MODE_ACTIVITY},
2874         {OpCode::WRITE_HOLD_MODE_ACTIVITY,
2875          OpCodeIndex::WRITE_HOLD_MODE_ACTIVITY},
2876         {OpCode::READ_TRANSMIT_POWER_LEVEL,
2877          OpCodeIndex::READ_TRANSMIT_POWER_LEVEL},
2878         {OpCode::READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE,
2879          OpCodeIndex::READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE},
2880         {OpCode::WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE,
2881          OpCodeIndex::WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE},
2882         {OpCode::SET_CONTROLLER_TO_HOST_FLOW_CONTROL,
2883          OpCodeIndex::SET_CONTROLLER_TO_HOST_FLOW_CONTROL},
2884         {OpCode::HOST_BUFFER_SIZE, OpCodeIndex::HOST_BUFFER_SIZE},
2885         {OpCode::HOST_NUMBER_OF_COMPLETED_PACKETS,
2886          OpCodeIndex::HOST_NUMBER_OF_COMPLETED_PACKETS},
2887         {OpCode::READ_LINK_SUPERVISION_TIMEOUT,
2888          OpCodeIndex::READ_LINK_SUPERVISION_TIMEOUT},
2889         {OpCode::WRITE_LINK_SUPERVISION_TIMEOUT,
2890          OpCodeIndex::WRITE_LINK_SUPERVISION_TIMEOUT},
2891         {OpCode::READ_NUMBER_OF_SUPPORTED_IAC,
2892          OpCodeIndex::READ_NUMBER_OF_SUPPORTED_IAC},
2893         {OpCode::READ_CURRENT_IAC_LAP, OpCodeIndex::READ_CURRENT_IAC_LAP},
2894         {OpCode::WRITE_CURRENT_IAC_LAP, OpCodeIndex::WRITE_CURRENT_IAC_LAP},
2895         {OpCode::SET_AFH_HOST_CHANNEL_CLASSIFICATION,
2896          OpCodeIndex::SET_AFH_HOST_CHANNEL_CLASSIFICATION},
2897         {OpCode::READ_INQUIRY_SCAN_TYPE, OpCodeIndex::READ_INQUIRY_SCAN_TYPE},
2898         {OpCode::WRITE_INQUIRY_SCAN_TYPE, OpCodeIndex::WRITE_INQUIRY_SCAN_TYPE},
2899         {OpCode::READ_INQUIRY_MODE, OpCodeIndex::READ_INQUIRY_MODE},
2900         {OpCode::WRITE_INQUIRY_MODE, OpCodeIndex::WRITE_INQUIRY_MODE},
2901         {OpCode::READ_PAGE_SCAN_TYPE, OpCodeIndex::READ_PAGE_SCAN_TYPE},
2902         {OpCode::WRITE_PAGE_SCAN_TYPE, OpCodeIndex::WRITE_PAGE_SCAN_TYPE},
2903         {OpCode::READ_AFH_CHANNEL_ASSESSMENT_MODE,
2904          OpCodeIndex::READ_AFH_CHANNEL_ASSESSMENT_MODE},
2905         {OpCode::WRITE_AFH_CHANNEL_ASSESSMENT_MODE,
2906          OpCodeIndex::WRITE_AFH_CHANNEL_ASSESSMENT_MODE},
2907         {OpCode::READ_EXTENDED_INQUIRY_RESPONSE,
2908          OpCodeIndex::READ_EXTENDED_INQUIRY_RESPONSE},
2909         {OpCode::WRITE_EXTENDED_INQUIRY_RESPONSE,
2910          OpCodeIndex::WRITE_EXTENDED_INQUIRY_RESPONSE},
2911         {OpCode::REFRESH_ENCRYPTION_KEY, OpCodeIndex::REFRESH_ENCRYPTION_KEY},
2912         {OpCode::READ_SIMPLE_PAIRING_MODE,
2913          OpCodeIndex::READ_SIMPLE_PAIRING_MODE},
2914         {OpCode::WRITE_SIMPLE_PAIRING_MODE,
2915          OpCodeIndex::WRITE_SIMPLE_PAIRING_MODE},
2916         {OpCode::READ_LOCAL_OOB_DATA, OpCodeIndex::READ_LOCAL_OOB_DATA},
2917         {OpCode::READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL,
2918          OpCodeIndex::READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL},
2919         {OpCode::WRITE_INQUIRY_TRANSMIT_POWER_LEVEL,
2920          OpCodeIndex::WRITE_INQUIRY_TRANSMIT_POWER_LEVEL},
2921         {OpCode::READ_DEFAULT_ERRONEOUS_DATA_REPORTING,
2922          OpCodeIndex::READ_DEFAULT_ERRONEOUS_DATA_REPORTING},
2923         {OpCode::WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING,
2924          OpCodeIndex::WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING},
2925         {OpCode::ENHANCED_FLUSH, OpCodeIndex::ENHANCED_FLUSH},
2926         {OpCode::SEND_KEYPRESS_NOTIFICATION,
2927          OpCodeIndex::SEND_KEYPRESS_NOTIFICATION},
2928         {OpCode::SET_EVENT_MASK_PAGE_2, OpCodeIndex::SET_EVENT_MASK_PAGE_2},
2929         {OpCode::READ_FLOW_CONTROL_MODE, OpCodeIndex::READ_FLOW_CONTROL_MODE},
2930         {OpCode::WRITE_FLOW_CONTROL_MODE, OpCodeIndex::WRITE_FLOW_CONTROL_MODE},
2931         {OpCode::READ_ENHANCED_TRANSMIT_POWER_LEVEL,
2932          OpCodeIndex::READ_ENHANCED_TRANSMIT_POWER_LEVEL},
2933         {OpCode::READ_LE_HOST_SUPPORT, OpCodeIndex::READ_LE_HOST_SUPPORT},
2934         {OpCode::WRITE_LE_HOST_SUPPORT, OpCodeIndex::WRITE_LE_HOST_SUPPORT},
2935         {OpCode::SET_MWS_CHANNEL_PARAMETERS,
2936          OpCodeIndex::SET_MWS_CHANNEL_PARAMETERS},
2937         {OpCode::SET_EXTERNAL_FRAME_CONFIGURATION,
2938          OpCodeIndex::SET_EXTERNAL_FRAME_CONFIGURATION},
2939         {OpCode::SET_MWS_SIGNALING, OpCodeIndex::SET_MWS_SIGNALING},
2940         {OpCode::SET_MWS_TRANSPORT_LAYER, OpCodeIndex::SET_MWS_TRANSPORT_LAYER},
2941         {OpCode::SET_MWS_SCAN_FREQUENCY_TABLE,
2942          OpCodeIndex::SET_MWS_SCAN_FREQUENCY_TABLE},
2943         {OpCode::SET_MWS_PATTERN_CONFIGURATION,
2944          OpCodeIndex::SET_MWS_PATTERN_CONFIGURATION},
2945         {OpCode::SET_RESERVED_LT_ADDR, OpCodeIndex::SET_RESERVED_LT_ADDR},
2946         {OpCode::DELETE_RESERVED_LT_ADDR, OpCodeIndex::DELETE_RESERVED_LT_ADDR},
2947         {OpCode::SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_DATA,
2948          OpCodeIndex::SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_DATA},
2949         {OpCode::READ_SYNCHRONIZATION_TRAIN_PARAMETERS,
2950          OpCodeIndex::READ_SYNCHRONIZATION_TRAIN_PARAMETERS},
2951         {OpCode::WRITE_SYNCHRONIZATION_TRAIN_PARAMETERS,
2952          OpCodeIndex::WRITE_SYNCHRONIZATION_TRAIN_PARAMETERS},
2953         {OpCode::READ_SECURE_CONNECTIONS_HOST_SUPPORT,
2954          OpCodeIndex::READ_SECURE_CONNECTIONS_HOST_SUPPORT},
2955         {OpCode::WRITE_SECURE_CONNECTIONS_HOST_SUPPORT,
2956          OpCodeIndex::WRITE_SECURE_CONNECTIONS_HOST_SUPPORT},
2957         {OpCode::READ_AUTHENTICATED_PAYLOAD_TIMEOUT,
2958          OpCodeIndex::READ_AUTHENTICATED_PAYLOAD_TIMEOUT},
2959         {OpCode::WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT,
2960          OpCodeIndex::WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT},
2961         {OpCode::READ_LOCAL_OOB_EXTENDED_DATA,
2962          OpCodeIndex::READ_LOCAL_OOB_EXTENDED_DATA},
2963         {OpCode::READ_EXTENDED_PAGE_TIMEOUT,
2964          OpCodeIndex::READ_EXTENDED_PAGE_TIMEOUT},
2965         {OpCode::WRITE_EXTENDED_PAGE_TIMEOUT,
2966          OpCodeIndex::WRITE_EXTENDED_PAGE_TIMEOUT},
2967         {OpCode::READ_EXTENDED_INQUIRY_LENGTH,
2968          OpCodeIndex::READ_EXTENDED_INQUIRY_LENGTH},
2969         {OpCode::WRITE_EXTENDED_INQUIRY_LENGTH,
2970          OpCodeIndex::WRITE_EXTENDED_INQUIRY_LENGTH},
2971         {OpCode::SET_ECOSYSTEM_BASE_INTERVAL,
2972          OpCodeIndex::SET_ECOSYSTEM_BASE_INTERVAL},
2973         {OpCode::CONFIGURE_DATA_PATH, OpCodeIndex::CONFIGURE_DATA_PATH},
2974         {OpCode::SET_MIN_ENCRYPTION_KEY_SIZE,
2975          OpCodeIndex::SET_MIN_ENCRYPTION_KEY_SIZE},
2976 
2977         // INFORMATIONAL_PARAMETERS
2978         {OpCode::READ_LOCAL_VERSION_INFORMATION,
2979          OpCodeIndex::READ_LOCAL_VERSION_INFORMATION},
2980         {OpCode::READ_LOCAL_SUPPORTED_FEATURES,
2981          OpCodeIndex::READ_LOCAL_SUPPORTED_FEATURES},
2982         {OpCode::READ_LOCAL_EXTENDED_FEATURES,
2983          OpCodeIndex::READ_LOCAL_EXTENDED_FEATURES},
2984         {OpCode::READ_BUFFER_SIZE, OpCodeIndex::READ_BUFFER_SIZE},
2985         {OpCode::READ_BD_ADDR, OpCodeIndex::READ_BD_ADDR},
2986         {OpCode::READ_DATA_BLOCK_SIZE, OpCodeIndex::READ_DATA_BLOCK_SIZE},
2987         {OpCode::READ_LOCAL_SUPPORTED_CODECS_V1,
2988          OpCodeIndex::READ_LOCAL_SUPPORTED_CODECS_V1},
2989         {OpCode::READ_LOCAL_SIMPLE_PAIRING_OPTIONS,
2990          OpCodeIndex::READ_LOCAL_SIMPLE_PAIRING_OPTIONS},
2991         {OpCode::READ_LOCAL_SUPPORTED_CODECS_V2,
2992          OpCodeIndex::READ_LOCAL_SUPPORTED_CODECS_V2},
2993         {OpCode::READ_LOCAL_SUPPORTED_CODEC_CAPABILITIES,
2994          OpCodeIndex::READ_LOCAL_SUPPORTED_CODEC_CAPABILITIES},
2995         {OpCode::READ_LOCAL_SUPPORTED_CONTROLLER_DELAY,
2996          OpCodeIndex::READ_LOCAL_SUPPORTED_CONTROLLER_DELAY},
2997 
2998         // STATUS_PARAMETERS
2999         {OpCode::READ_FAILED_CONTACT_COUNTER,
3000          OpCodeIndex::READ_FAILED_CONTACT_COUNTER},
3001         {OpCode::RESET_FAILED_CONTACT_COUNTER,
3002          OpCodeIndex::RESET_FAILED_CONTACT_COUNTER},
3003         {OpCode::READ_LINK_QUALITY, OpCodeIndex::READ_LINK_QUALITY},
3004         {OpCode::READ_RSSI, OpCodeIndex::READ_RSSI},
3005         {OpCode::READ_AFH_CHANNEL_MAP, OpCodeIndex::READ_AFH_CHANNEL_MAP},
3006         {OpCode::READ_CLOCK, OpCodeIndex::READ_CLOCK},
3007         {OpCode::READ_ENCRYPTION_KEY_SIZE,
3008          OpCodeIndex::READ_ENCRYPTION_KEY_SIZE},
3009         {OpCode::GET_MWS_TRANSPORT_LAYER_CONFIGURATION,
3010          OpCodeIndex::GET_MWS_TRANSPORT_LAYER_CONFIGURATION},
3011         {OpCode::SET_TRIGGERED_CLOCK_CAPTURE,
3012          OpCodeIndex::SET_TRIGGERED_CLOCK_CAPTURE},
3013 
3014         // TESTING
3015         {OpCode::READ_LOOPBACK_MODE, OpCodeIndex::READ_LOOPBACK_MODE},
3016         {OpCode::WRITE_LOOPBACK_MODE, OpCodeIndex::WRITE_LOOPBACK_MODE},
3017         {OpCode::ENABLE_DEVICE_UNDER_TEST_MODE,
3018          OpCodeIndex::ENABLE_DEVICE_UNDER_TEST_MODE},
3019         {OpCode::WRITE_SIMPLE_PAIRING_DEBUG_MODE,
3020          OpCodeIndex::WRITE_SIMPLE_PAIRING_DEBUG_MODE},
3021         {OpCode::WRITE_SECURE_CONNECTIONS_TEST_MODE,
3022          OpCodeIndex::WRITE_SECURE_CONNECTIONS_TEST_MODE},
3023 
3024         // LE_CONTROLLER
3025         {OpCode::LE_SET_EVENT_MASK, OpCodeIndex::LE_SET_EVENT_MASK},
3026         {OpCode::LE_READ_BUFFER_SIZE_V1, OpCodeIndex::LE_READ_BUFFER_SIZE_V1},
3027         {OpCode::LE_READ_LOCAL_SUPPORTED_FEATURES,
3028          OpCodeIndex::LE_READ_LOCAL_SUPPORTED_FEATURES},
3029         {OpCode::LE_SET_RANDOM_ADDRESS, OpCodeIndex::LE_SET_RANDOM_ADDRESS},
3030         {OpCode::LE_SET_ADVERTISING_PARAMETERS,
3031          OpCodeIndex::LE_SET_ADVERTISING_PARAMETERS},
3032         {OpCode::LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER,
3033          OpCodeIndex::LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER},
3034         {OpCode::LE_SET_ADVERTISING_DATA, OpCodeIndex::LE_SET_ADVERTISING_DATA},
3035         {OpCode::LE_SET_SCAN_RESPONSE_DATA,
3036          OpCodeIndex::LE_SET_SCAN_RESPONSE_DATA},
3037         {OpCode::LE_SET_ADVERTISING_ENABLE,
3038          OpCodeIndex::LE_SET_ADVERTISING_ENABLE},
3039         {OpCode::LE_SET_SCAN_PARAMETERS, OpCodeIndex::LE_SET_SCAN_PARAMETERS},
3040         {OpCode::LE_SET_SCAN_ENABLE, OpCodeIndex::LE_SET_SCAN_ENABLE},
3041         {OpCode::LE_CREATE_CONNECTION, OpCodeIndex::LE_CREATE_CONNECTION},
3042         {OpCode::LE_CREATE_CONNECTION_CANCEL,
3043          OpCodeIndex::LE_CREATE_CONNECTION_CANCEL},
3044         {OpCode::LE_READ_FILTER_ACCEPT_LIST_SIZE,
3045          OpCodeIndex::LE_READ_FILTER_ACCEPT_LIST_SIZE},
3046         {OpCode::LE_CLEAR_FILTER_ACCEPT_LIST,
3047          OpCodeIndex::LE_CLEAR_FILTER_ACCEPT_LIST},
3048         {OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST,
3049          OpCodeIndex::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST},
3050         {OpCode::LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST,
3051          OpCodeIndex::LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST},
3052         {OpCode::LE_CONNECTION_UPDATE, OpCodeIndex::LE_CONNECTION_UPDATE},
3053         {OpCode::LE_SET_HOST_CHANNEL_CLASSIFICATION,
3054          OpCodeIndex::LE_SET_HOST_CHANNEL_CLASSIFICATION},
3055         {OpCode::LE_READ_CHANNEL_MAP, OpCodeIndex::LE_READ_CHANNEL_MAP},
3056         {OpCode::LE_READ_REMOTE_FEATURES, OpCodeIndex::LE_READ_REMOTE_FEATURES},
3057         {OpCode::LE_ENCRYPT, OpCodeIndex::LE_ENCRYPT},
3058         {OpCode::LE_RAND, OpCodeIndex::LE_RAND},
3059         {OpCode::LE_START_ENCRYPTION, OpCodeIndex::LE_START_ENCRYPTION},
3060         {OpCode::LE_LONG_TERM_KEY_REQUEST_REPLY,
3061          OpCodeIndex::LE_LONG_TERM_KEY_REQUEST_REPLY},
3062         {OpCode::LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY,
3063          OpCodeIndex::LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY},
3064         {OpCode::LE_READ_SUPPORTED_STATES,
3065          OpCodeIndex::LE_READ_SUPPORTED_STATES},
3066         {OpCode::LE_RECEIVER_TEST_V1, OpCodeIndex::LE_RECEIVER_TEST_V1},
3067         {OpCode::LE_TRANSMITTER_TEST_V1, OpCodeIndex::LE_TRANSMITTER_TEST_V1},
3068         {OpCode::LE_TEST_END, OpCodeIndex::LE_TEST_END},
3069         {OpCode::LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY,
3070          OpCodeIndex::LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY},
3071         {OpCode::LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY,
3072          OpCodeIndex::LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY},
3073         {OpCode::LE_SET_DATA_LENGTH, OpCodeIndex::LE_SET_DATA_LENGTH},
3074         {OpCode::LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH,
3075          OpCodeIndex::LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH},
3076         {OpCode::LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH,
3077          OpCodeIndex::LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH},
3078         {OpCode::LE_READ_LOCAL_P_256_PUBLIC_KEY,
3079          OpCodeIndex::LE_READ_LOCAL_P_256_PUBLIC_KEY},
3080         {OpCode::LE_GENERATE_DHKEY_V1, OpCodeIndex::LE_GENERATE_DHKEY_V1},
3081         {OpCode::LE_ADD_DEVICE_TO_RESOLVING_LIST,
3082          OpCodeIndex::LE_ADD_DEVICE_TO_RESOLVING_LIST},
3083         {OpCode::LE_REMOVE_DEVICE_FROM_RESOLVING_LIST,
3084          OpCodeIndex::LE_REMOVE_DEVICE_FROM_RESOLVING_LIST},
3085         {OpCode::LE_CLEAR_RESOLVING_LIST, OpCodeIndex::LE_CLEAR_RESOLVING_LIST},
3086         {OpCode::LE_READ_RESOLVING_LIST_SIZE,
3087          OpCodeIndex::LE_READ_RESOLVING_LIST_SIZE},
3088         {OpCode::LE_READ_PEER_RESOLVABLE_ADDRESS,
3089          OpCodeIndex::LE_READ_PEER_RESOLVABLE_ADDRESS},
3090         {OpCode::LE_READ_LOCAL_RESOLVABLE_ADDRESS,
3091          OpCodeIndex::LE_READ_LOCAL_RESOLVABLE_ADDRESS},
3092         {OpCode::LE_SET_ADDRESS_RESOLUTION_ENABLE,
3093          OpCodeIndex::LE_SET_ADDRESS_RESOLUTION_ENABLE},
3094         {OpCode::LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT,
3095          OpCodeIndex::LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT},
3096         {OpCode::LE_READ_MAXIMUM_DATA_LENGTH,
3097          OpCodeIndex::LE_READ_MAXIMUM_DATA_LENGTH},
3098         {OpCode::LE_READ_PHY, OpCodeIndex::LE_READ_PHY},
3099         {OpCode::LE_SET_DEFAULT_PHY, OpCodeIndex::LE_SET_DEFAULT_PHY},
3100         {OpCode::LE_SET_PHY, OpCodeIndex::LE_SET_PHY},
3101         {OpCode::LE_RECEIVER_TEST_V2, OpCodeIndex::LE_RECEIVER_TEST_V2},
3102         {OpCode::LE_TRANSMITTER_TEST_V2, OpCodeIndex::LE_TRANSMITTER_TEST_V2},
3103         {OpCode::LE_SET_ADVERTISING_SET_RANDOM_ADDRESS,
3104          OpCodeIndex::LE_SET_ADVERTISING_SET_RANDOM_ADDRESS},
3105         {OpCode::LE_SET_EXTENDED_ADVERTISING_PARAMETERS,
3106          OpCodeIndex::LE_SET_EXTENDED_ADVERTISING_PARAMETERS},
3107         {OpCode::LE_SET_EXTENDED_ADVERTISING_DATA,
3108          OpCodeIndex::LE_SET_EXTENDED_ADVERTISING_DATA},
3109         {OpCode::LE_SET_EXTENDED_SCAN_RESPONSE_DATA,
3110          OpCodeIndex::LE_SET_EXTENDED_SCAN_RESPONSE_DATA},
3111         {OpCode::LE_SET_EXTENDED_ADVERTISING_ENABLE,
3112          OpCodeIndex::LE_SET_EXTENDED_ADVERTISING_ENABLE},
3113         {OpCode::LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH,
3114          OpCodeIndex::LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH},
3115         {OpCode::LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS,
3116          OpCodeIndex::LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS},
3117         {OpCode::LE_REMOVE_ADVERTISING_SET,
3118          OpCodeIndex::LE_REMOVE_ADVERTISING_SET},
3119         {OpCode::LE_CLEAR_ADVERTISING_SETS,
3120          OpCodeIndex::LE_CLEAR_ADVERTISING_SETS},
3121         {OpCode::LE_SET_PERIODIC_ADVERTISING_PARAMETERS,
3122          OpCodeIndex::LE_SET_PERIODIC_ADVERTISING_PARAMETERS},
3123         {OpCode::LE_SET_PERIODIC_ADVERTISING_DATA,
3124          OpCodeIndex::LE_SET_PERIODIC_ADVERTISING_DATA},
3125         {OpCode::LE_SET_PERIODIC_ADVERTISING_ENABLE,
3126          OpCodeIndex::LE_SET_PERIODIC_ADVERTISING_ENABLE},
3127         {OpCode::LE_SET_EXTENDED_SCAN_PARAMETERS,
3128          OpCodeIndex::LE_SET_EXTENDED_SCAN_PARAMETERS},
3129         {OpCode::LE_SET_EXTENDED_SCAN_ENABLE,
3130          OpCodeIndex::LE_SET_EXTENDED_SCAN_ENABLE},
3131         {OpCode::LE_EXTENDED_CREATE_CONNECTION,
3132          OpCodeIndex::LE_EXTENDED_CREATE_CONNECTION},
3133         {OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC,
3134          OpCodeIndex::LE_PERIODIC_ADVERTISING_CREATE_SYNC},
3135         {OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL,
3136          OpCodeIndex::LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL},
3137         {OpCode::LE_PERIODIC_ADVERTISING_TERMINATE_SYNC,
3138          OpCodeIndex::LE_PERIODIC_ADVERTISING_TERMINATE_SYNC},
3139         {OpCode::LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST,
3140          OpCodeIndex::LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST},
3141         {OpCode::LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST,
3142          OpCodeIndex::LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST},
3143         {OpCode::LE_CLEAR_PERIODIC_ADVERTISER_LIST,
3144          OpCodeIndex::LE_CLEAR_PERIODIC_ADVERTISER_LIST},
3145         {OpCode::LE_READ_PERIODIC_ADVERTISER_LIST_SIZE,
3146          OpCodeIndex::LE_READ_PERIODIC_ADVERTISER_LIST_SIZE},
3147         {OpCode::LE_READ_TRANSMIT_POWER, OpCodeIndex::LE_READ_TRANSMIT_POWER},
3148         {OpCode::LE_READ_RF_PATH_COMPENSATION_POWER,
3149          OpCodeIndex::LE_READ_RF_PATH_COMPENSATION_POWER},
3150         {OpCode::LE_WRITE_RF_PATH_COMPENSATION_POWER,
3151          OpCodeIndex::LE_WRITE_RF_PATH_COMPENSATION_POWER},
3152         {OpCode::LE_SET_PRIVACY_MODE, OpCodeIndex::LE_SET_PRIVACY_MODE},
3153         {OpCode::LE_RECEIVER_TEST_V3, OpCodeIndex::LE_RECEIVER_TEST_V3},
3154         {OpCode::LE_TRANSMITTER_TEST_V3, OpCodeIndex::LE_TRANSMITTER_TEST_V3},
3155         {OpCode::LE_SET_CONNECTIONLESS_CTE_TRANSMIT_PARAMETERS,
3156          OpCodeIndex::LE_SET_CONNECTIONLESS_CTE_TRANSMIT_PARAMETERS},
3157         {OpCode::LE_SET_CONNECTIONLESS_CTE_TRANSMIT_ENABLE,
3158          OpCodeIndex::LE_SET_CONNECTIONLESS_CTE_TRANSMIT_ENABLE},
3159         {OpCode::LE_SET_CONNECTIONLESS_IQ_SAMPLING_ENABLE,
3160          OpCodeIndex::LE_SET_CONNECTIONLESS_IQ_SAMPLING_ENABLE},
3161         {OpCode::LE_SET_CONNECTION_CTE_RECEIVE_PARAMETERS,
3162          OpCodeIndex::LE_SET_CONNECTION_CTE_RECEIVE_PARAMETERS},
3163         {OpCode::LE_SET_CONNECTION_CTE_TRANSMIT_PARAMETERS,
3164          OpCodeIndex::LE_SET_CONNECTION_CTE_TRANSMIT_PARAMETERS},
3165         {OpCode::LE_CONNECTION_CTE_REQUEST_ENABLE,
3166          OpCodeIndex::LE_CONNECTION_CTE_REQUEST_ENABLE},
3167         {OpCode::LE_CONNECTION_CTE_RESPONSE_ENABLE,
3168          OpCodeIndex::LE_CONNECTION_CTE_RESPONSE_ENABLE},
3169         {OpCode::LE_READ_ANTENNA_INFORMATION,
3170          OpCodeIndex::LE_READ_ANTENNA_INFORMATION},
3171         {OpCode::LE_SET_PERIODIC_ADVERTISING_RECEIVE_ENABLE,
3172          OpCodeIndex::LE_SET_PERIODIC_ADVERTISING_RECEIVE_ENABLE},
3173         {OpCode::LE_PERIODIC_ADVERTISING_SYNC_TRANSFER,
3174          OpCodeIndex::LE_PERIODIC_ADVERTISING_SYNC_TRANSFER},
3175         {OpCode::LE_PERIODIC_ADVERTISING_SET_INFO_TRANSFER,
3176          OpCodeIndex::LE_PERIODIC_ADVERTISING_SET_INFO_TRANSFER},
3177         {OpCode::LE_SET_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS,
3178          OpCodeIndex::LE_SET_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS},
3179         {OpCode::LE_SET_DEFAULT_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS,
3180          OpCodeIndex::
3181              LE_SET_DEFAULT_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS},
3182         {OpCode::LE_GENERATE_DHKEY_V2, OpCodeIndex::LE_GENERATE_DHKEY_V2},
3183         {OpCode::LE_MODIFY_SLEEP_CLOCK_ACCURACY,
3184          OpCodeIndex::LE_MODIFY_SLEEP_CLOCK_ACCURACY},
3185         {OpCode::LE_READ_BUFFER_SIZE_V2, OpCodeIndex::LE_READ_BUFFER_SIZE_V2},
3186         {OpCode::LE_READ_ISO_TX_SYNC, OpCodeIndex::LE_READ_ISO_TX_SYNC},
3187         {OpCode::LE_SET_CIG_PARAMETERS, OpCodeIndex::LE_SET_CIG_PARAMETERS},
3188         {OpCode::LE_SET_CIG_PARAMETERS_TEST,
3189          OpCodeIndex::LE_SET_CIG_PARAMETERS_TEST},
3190         {OpCode::LE_CREATE_CIS, OpCodeIndex::LE_CREATE_CIS},
3191         {OpCode::LE_REMOVE_CIG, OpCodeIndex::LE_REMOVE_CIG},
3192         {OpCode::LE_ACCEPT_CIS_REQUEST, OpCodeIndex::LE_ACCEPT_CIS_REQUEST},
3193         {OpCode::LE_REJECT_CIS_REQUEST, OpCodeIndex::LE_REJECT_CIS_REQUEST},
3194         {OpCode::LE_CREATE_BIG, OpCodeIndex::LE_CREATE_BIG},
3195         {OpCode::LE_CREATE_BIG_TEST, OpCodeIndex::LE_CREATE_BIG_TEST},
3196         {OpCode::LE_TERMINATE_BIG, OpCodeIndex::LE_TERMINATE_BIG},
3197         {OpCode::LE_BIG_CREATE_SYNC, OpCodeIndex::LE_BIG_CREATE_SYNC},
3198         {OpCode::LE_BIG_TERMINATE_SYNC, OpCodeIndex::LE_BIG_TERMINATE_SYNC},
3199         {OpCode::LE_REQUEST_PEER_SCA, OpCodeIndex::LE_REQUEST_PEER_SCA},
3200         {OpCode::LE_SETUP_ISO_DATA_PATH, OpCodeIndex::LE_SETUP_ISO_DATA_PATH},
3201         {OpCode::LE_REMOVE_ISO_DATA_PATH, OpCodeIndex::LE_REMOVE_ISO_DATA_PATH},
3202         {OpCode::LE_ISO_TRANSMIT_TEST, OpCodeIndex::LE_ISO_TRANSMIT_TEST},
3203         {OpCode::LE_ISO_RECEIVE_TEST, OpCodeIndex::LE_ISO_RECEIVE_TEST},
3204         {OpCode::LE_ISO_READ_TEST_COUNTERS,
3205          OpCodeIndex::LE_ISO_READ_TEST_COUNTERS},
3206         {OpCode::LE_ISO_TEST_END, OpCodeIndex::LE_ISO_TEST_END},
3207         {OpCode::LE_SET_HOST_FEATURE, OpCodeIndex::LE_SET_HOST_FEATURE},
3208         {OpCode::LE_READ_ISO_LINK_QUALITY,
3209          OpCodeIndex::LE_READ_ISO_LINK_QUALITY},
3210         {OpCode::LE_ENHANCED_READ_TRANSMIT_POWER_LEVEL,
3211          OpCodeIndex::LE_ENHANCED_READ_TRANSMIT_POWER_LEVEL},
3212         {OpCode::LE_READ_REMOTE_TRANSMIT_POWER_LEVEL,
3213          OpCodeIndex::LE_READ_REMOTE_TRANSMIT_POWER_LEVEL},
3214         {OpCode::LE_SET_PATH_LOSS_REPORTING_PARAMETERS,
3215          OpCodeIndex::LE_SET_PATH_LOSS_REPORTING_PARAMETERS},
3216         {OpCode::LE_SET_PATH_LOSS_REPORTING_ENABLE,
3217          OpCodeIndex::LE_SET_PATH_LOSS_REPORTING_ENABLE},
3218         {OpCode::LE_SET_TRANSMIT_POWER_REPORTING_ENABLE,
3219          OpCodeIndex::LE_SET_TRANSMIT_POWER_REPORTING_ENABLE},
3220         {OpCode::LE_TRANSMITTER_TEST_V4, OpCodeIndex::LE_TRANSMITTER_TEST_V4},
3221         {OpCode::LE_SET_DATA_RELATED_ADDRESS_CHANGES,
3222          OpCodeIndex::LE_SET_DATA_RELATED_ADDRESS_CHANGES},
3223         {OpCode::LE_SET_DEFAULT_SUBRATE, OpCodeIndex::LE_SET_DEFAULT_SUBRATE},
3224         {OpCode::LE_SUBRATE_REQUEST, OpCodeIndex::LE_SUBRATE_REQUEST},
3225     };
3226 
3227 const std::unordered_map<OpCode, DualModeController::CommandHandler>
3228     DualModeController::hci_command_handlers_{
3229         // LINK_CONTROL
3230         {OpCode::INQUIRY, &DualModeController::Inquiry},
3231         {OpCode::INQUIRY_CANCEL, &DualModeController::InquiryCancel},
3232         //{OpCode::PERIODIC_INQUIRY_MODE,
3233         //&DualModeController::PeriodicInquiryMode},
3234         //{OpCode::EXIT_PERIODIC_INQUIRY_MODE,
3235         //&DualModeController::ExitPeriodicInquiryMode},
3236         {OpCode::CREATE_CONNECTION, &DualModeController::CreateConnection},
3237         {OpCode::DISCONNECT, &DualModeController::Disconnect},
3238         {OpCode::ADD_SCO_CONNECTION, &DualModeController::AddScoConnection},
3239         {OpCode::CREATE_CONNECTION_CANCEL,
3240          &DualModeController::CreateConnectionCancel},
3241         {OpCode::ACCEPT_CONNECTION_REQUEST,
3242          &DualModeController::AcceptConnectionRequest},
3243         {OpCode::REJECT_CONNECTION_REQUEST,
3244          &DualModeController::RejectConnectionRequest},
3245         {OpCode::LINK_KEY_REQUEST_REPLY, &DualModeController::ForwardToLm},
3246         {OpCode::LINK_KEY_REQUEST_NEGATIVE_REPLY,
3247          &DualModeController::ForwardToLm},
3248         {OpCode::PIN_CODE_REQUEST_REPLY, &DualModeController::ForwardToLm},
3249         {OpCode::PIN_CODE_REQUEST_NEGATIVE_REPLY,
3250          &DualModeController::ForwardToLm},
3251         {OpCode::CHANGE_CONNECTION_PACKET_TYPE,
3252          &DualModeController::ChangeConnectionPacketType},
3253         {OpCode::AUTHENTICATION_REQUESTED, &DualModeController::ForwardToLm},
3254         {OpCode::SET_CONNECTION_ENCRYPTION, &DualModeController::ForwardToLm},
3255         {OpCode::CHANGE_CONNECTION_LINK_KEY,
3256          &DualModeController::ChangeConnectionLinkKey},
3257         {OpCode::CENTRAL_LINK_KEY, &DualModeController::CentralLinkKey},
3258         {OpCode::REMOTE_NAME_REQUEST, &DualModeController::RemoteNameRequest},
3259         //{OpCode::REMOTE_NAME_REQUEST_CANCEL,
3260         //&DualModeController::RemoteNameRequestCancel},
3261         {OpCode::READ_REMOTE_SUPPORTED_FEATURES,
3262          &DualModeController::ReadRemoteSupportedFeatures},
3263         {OpCode::READ_REMOTE_EXTENDED_FEATURES,
3264          &DualModeController::ReadRemoteExtendedFeatures},
3265         {OpCode::READ_REMOTE_VERSION_INFORMATION,
3266          &DualModeController::ReadRemoteVersionInformation},
3267         {OpCode::READ_CLOCK_OFFSET, &DualModeController::ReadClockOffset},
3268         //{OpCode::READ_LMP_HANDLE, &DualModeController::ReadLmpHandle},
3269         {OpCode::SETUP_SYNCHRONOUS_CONNECTION,
3270          &DualModeController::SetupSynchronousConnection},
3271         {OpCode::ACCEPT_SYNCHRONOUS_CONNECTION,
3272          &DualModeController::AcceptSynchronousConnection},
3273         {OpCode::REJECT_SYNCHRONOUS_CONNECTION,
3274          &DualModeController::RejectSynchronousConnection},
3275         {OpCode::IO_CAPABILITY_REQUEST_REPLY, &DualModeController::ForwardToLm},
3276         {OpCode::USER_CONFIRMATION_REQUEST_REPLY,
3277          &DualModeController::ForwardToLm},
3278         {OpCode::USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY,
3279          &DualModeController::ForwardToLm},
3280         {OpCode::USER_PASSKEY_REQUEST_REPLY, &DualModeController::ForwardToLm},
3281         {OpCode::USER_PASSKEY_REQUEST_NEGATIVE_REPLY,
3282          &DualModeController::ForwardToLm},
3283         {OpCode::REMOTE_OOB_DATA_REQUEST_REPLY,
3284          &DualModeController::ForwardToLm},
3285         {OpCode::REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY,
3286          &DualModeController::ForwardToLm},
3287         {OpCode::IO_CAPABILITY_REQUEST_NEGATIVE_REPLY,
3288          &DualModeController::ForwardToLm},
3289         {OpCode::ENHANCED_SETUP_SYNCHRONOUS_CONNECTION,
3290          &DualModeController::EnhancedSetupSynchronousConnection},
3291         {OpCode::ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION,
3292          &DualModeController::EnhancedAcceptSynchronousConnection},
3293         //{OpCode::TRUNCATED_PAGE, &DualModeController::TruncatedPage},
3294         //{OpCode::TRUNCATED_PAGE_CANCEL,
3295         //&DualModeController::TruncatedPageCancel},
3296         //{OpCode::SET_CONNECTIONLESS_PERIPHERAL_BROADCAST,
3297         //&DualModeController::SetConnectionlessPeripheralBroadcast},
3298         //{OpCode::SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVE,
3299         //&DualModeController::SetConnectionlessPeripheralBroadcastReceive},
3300         //{OpCode::START_SYNCHRONIZATION_TRAIN,
3301         //&DualModeController::StartSynchronizationTrain},
3302         //{OpCode::RECEIVE_SYNCHRONIZATION_TRAIN,
3303         //&DualModeController::ReceiveSynchronizationTrain},
3304         {OpCode::REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY,
3305          &DualModeController::ForwardToLm},
3306 
3307         // LINK_POLICY
3308         {OpCode::HOLD_MODE, &DualModeController::HoldMode},
3309         {OpCode::SNIFF_MODE, &DualModeController::SniffMode},
3310         {OpCode::EXIT_SNIFF_MODE, &DualModeController::ExitSniffMode},
3311         {OpCode::QOS_SETUP, &DualModeController::QosSetup},
3312         {OpCode::ROLE_DISCOVERY, &DualModeController::RoleDiscovery},
3313         {OpCode::SWITCH_ROLE, &DualModeController::SwitchRole},
3314         {OpCode::READ_LINK_POLICY_SETTINGS,
3315          &DualModeController::ReadLinkPolicySettings},
3316         {OpCode::WRITE_LINK_POLICY_SETTINGS,
3317          &DualModeController::WriteLinkPolicySettings},
3318         {OpCode::READ_DEFAULT_LINK_POLICY_SETTINGS,
3319          &DualModeController::ReadDefaultLinkPolicySettings},
3320         {OpCode::WRITE_DEFAULT_LINK_POLICY_SETTINGS,
3321          &DualModeController::WriteDefaultLinkPolicySettings},
3322         {OpCode::FLOW_SPECIFICATION, &DualModeController::FlowSpecification},
3323         {OpCode::SNIFF_SUBRATING, &DualModeController::SniffSubrating},
3324 
3325         // CONTROLLER_AND_BASEBAND
3326         {OpCode::SET_EVENT_MASK, &DualModeController::SetEventMask},
3327         {OpCode::RESET, &DualModeController::Reset},
3328         {OpCode::SET_EVENT_FILTER, &DualModeController::SetEventFilter},
3329         //{OpCode::FLUSH, &DualModeController::Flush},
3330         //{OpCode::READ_PIN_TYPE, &DualModeController::ReadPinType},
3331         //{OpCode::WRITE_PIN_TYPE, &DualModeController::WritePinType},
3332         //{OpCode::READ_STORED_LINK_KEY,
3333         //&DualModeController::ReadStoredLinkKey},
3334         //{OpCode::WRITE_STORED_LINK_KEY,
3335         //&DualModeController::WriteStoredLinkKey},
3336         {OpCode::DELETE_STORED_LINK_KEY,
3337          &DualModeController::DeleteStoredLinkKey},
3338         {OpCode::WRITE_LOCAL_NAME, &DualModeController::WriteLocalName},
3339         {OpCode::READ_LOCAL_NAME, &DualModeController::ReadLocalName},
3340         {OpCode::READ_CONNECTION_ACCEPT_TIMEOUT,
3341          &DualModeController::ReadConnectionAcceptTimeout},
3342         {OpCode::WRITE_CONNECTION_ACCEPT_TIMEOUT,
3343          &DualModeController::WriteConnectionAcceptTimeout},
3344         {OpCode::READ_PAGE_TIMEOUT, &DualModeController::ReadPageTimeout},
3345         {OpCode::WRITE_PAGE_TIMEOUT, &DualModeController::WritePageTimeout},
3346         {OpCode::READ_SCAN_ENABLE, &DualModeController::ReadScanEnable},
3347         {OpCode::WRITE_SCAN_ENABLE, &DualModeController::WriteScanEnable},
3348         {OpCode::READ_PAGE_SCAN_ACTIVITY,
3349          &DualModeController::ReadPageScanActivity},
3350         {OpCode::WRITE_PAGE_SCAN_ACTIVITY,
3351          &DualModeController::WritePageScanActivity},
3352         {OpCode::READ_INQUIRY_SCAN_ACTIVITY,
3353          &DualModeController::ReadInquiryScanActivity},
3354         {OpCode::WRITE_INQUIRY_SCAN_ACTIVITY,
3355          &DualModeController::WriteInquiryScanActivity},
3356         {OpCode::READ_AUTHENTICATION_ENABLE,
3357          &DualModeController::ReadAuthenticationEnable},
3358         {OpCode::WRITE_AUTHENTICATION_ENABLE,
3359          &DualModeController::WriteAuthenticationEnable},
3360         {OpCode::READ_CLASS_OF_DEVICE, &DualModeController::ReadClassOfDevice},
3361         {OpCode::WRITE_CLASS_OF_DEVICE,
3362          &DualModeController::WriteClassOfDevice},
3363         {OpCode::READ_VOICE_SETTING, &DualModeController::ReadVoiceSetting},
3364         {OpCode::WRITE_VOICE_SETTING, &DualModeController::WriteVoiceSetting},
3365         //{OpCode::READ_AUTOMATIC_FLUSH_TIMEOUT,
3366         //&DualModeController::ReadAutomaticFlushTimeout},
3367         //{OpCode::WRITE_AUTOMATIC_FLUSH_TIMEOUT,
3368         //&DualModeController::WriteAutomaticFlushTimeout},
3369         //{OpCode::READ_NUM_BROADCAST_RETRANSMITS,
3370         //&DualModeController::ReadNumBroadcastRetransmits},
3371         //{OpCode::WRITE_NUM_BROADCAST_RETRANSMITS,
3372         //&DualModeController::WriteNumBroadcastRetransmits},
3373         //{OpCode::READ_HOLD_MODE_ACTIVITY,
3374         //&DualModeController::ReadHoldModeActivity},
3375         //{OpCode::WRITE_HOLD_MODE_ACTIVITY,
3376         //&DualModeController::WriteHoldModeActivity},
3377         //{OpCode::READ_TRANSMIT_POWER_LEVEL,
3378         //&DualModeController::ReadTransmitPowerLevel},
3379         {OpCode::READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE,
3380          &DualModeController::ReadSynchronousFlowControlEnable},
3381         {OpCode::WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE,
3382          &DualModeController::WriteSynchronousFlowControlEnable},
3383         //{OpCode::SET_CONTROLLER_TO_HOST_FLOW_CONTROL,
3384         //&DualModeController::SetControllerToHostFlowControl},
3385         {OpCode::HOST_BUFFER_SIZE, &DualModeController::HostBufferSize},
3386         //{OpCode::HOST_NUMBER_OF_COMPLETED_PACKETS,
3387         //&DualModeController::HostNumberOfCompletedPackets},
3388         //{OpCode::READ_LINK_SUPERVISION_TIMEOUT,
3389         //&DualModeController::ReadLinkSupervisionTimeout},
3390         {OpCode::WRITE_LINK_SUPERVISION_TIMEOUT,
3391          &DualModeController::WriteLinkSupervisionTimeout},
3392         {OpCode::READ_NUMBER_OF_SUPPORTED_IAC,
3393          &DualModeController::ReadNumberOfSupportedIac},
3394         {OpCode::READ_CURRENT_IAC_LAP, &DualModeController::ReadCurrentIacLap},
3395         {OpCode::WRITE_CURRENT_IAC_LAP,
3396          &DualModeController::WriteCurrentIacLap},
3397         //{OpCode::SET_AFH_HOST_CHANNEL_CLASSIFICATION,
3398         //&DualModeController::SetAfhHostChannelClassification},
3399         {OpCode::READ_INQUIRY_SCAN_TYPE,
3400          &DualModeController::ReadInquiryScanType},
3401         {OpCode::WRITE_INQUIRY_SCAN_TYPE,
3402          &DualModeController::WriteInquiryScanType},
3403         {OpCode::READ_INQUIRY_MODE, &DualModeController::ReadInquiryMode},
3404         {OpCode::WRITE_INQUIRY_MODE, &DualModeController::WriteInquiryMode},
3405         {OpCode::READ_PAGE_SCAN_TYPE, &DualModeController::ReadPageScanType},
3406         {OpCode::WRITE_PAGE_SCAN_TYPE, &DualModeController::WritePageScanType},
3407         //{OpCode::READ_AFH_CHANNEL_ASSESSMENT_MODE,
3408         //&DualModeController::ReadAfhChannelAssessmentMode},
3409         //{OpCode::WRITE_AFH_CHANNEL_ASSESSMENT_MODE,
3410         //&DualModeController::WriteAfhChannelAssessmentMode},
3411         //{OpCode::READ_EXTENDED_INQUIRY_RESPONSE,
3412         //&DualModeController::ReadExtendedInquiryResponse},
3413         {OpCode::WRITE_EXTENDED_INQUIRY_RESPONSE,
3414          &DualModeController::WriteExtendedInquiryResponse},
3415         {OpCode::REFRESH_ENCRYPTION_KEY,
3416          &DualModeController::RefreshEncryptionKey},
3417         //{OpCode::READ_SIMPLE_PAIRING_MODE,
3418         //&DualModeController::ReadSimplePairingMode},
3419         {OpCode::WRITE_SIMPLE_PAIRING_MODE,
3420          &DualModeController::WriteSimplePairingMode},
3421         {OpCode::READ_LOCAL_OOB_DATA, &DualModeController::ReadLocalOobData},
3422         {OpCode::READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL,
3423          &DualModeController::ReadInquiryResponseTransmitPowerLevel},
3424         //{OpCode::WRITE_INQUIRY_TRANSMIT_POWER_LEVEL,
3425         //&DualModeController::WriteInquiryTransmitPowerLevel},
3426         //{OpCode::READ_DEFAULT_ERRONEOUS_DATA_REPORTING,
3427         //&DualModeController::ReadDefaultErroneousDataReporting},
3428         //{OpCode::WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING,
3429         //&DualModeController::WriteDefaultErroneousDataReporting},
3430         {OpCode::ENHANCED_FLUSH, &DualModeController::EnhancedFlush},
3431         {OpCode::SEND_KEYPRESS_NOTIFICATION, &DualModeController::ForwardToLm},
3432         {OpCode::SET_EVENT_MASK_PAGE_2, &DualModeController::SetEventMaskPage2},
3433         //{OpCode::READ_FLOW_CONTROL_MODE,
3434         //&DualModeController::ReadFlowControlMode},
3435         //{OpCode::WRITE_FLOW_CONTROL_MODE,
3436         //&DualModeController::WriteFlowControlMode},
3437         //{OpCode::READ_ENHANCED_TRANSMIT_POWER_LEVEL,
3438         //&DualModeController::ReadEnhancedTransmitPowerLevel},
3439         //{OpCode::READ_LE_HOST_SUPPORT,
3440         //&DualModeController::ReadLeHostSupport},
3441         {OpCode::WRITE_LE_HOST_SUPPORT,
3442          &DualModeController::WriteLeHostSupport},
3443         //{OpCode::SET_MWS_CHANNEL_PARAMETERS,
3444         //&DualModeController::SetMwsChannelParameters},
3445         //{OpCode::SET_EXTERNAL_FRAME_CONFIGURATION,
3446         //&DualModeController::SetExternalFrameConfiguration},
3447         //{OpCode::SET_MWS_SIGNALING, &DualModeController::SetMwsSignaling},
3448         //{OpCode::SET_MWS_TRANSPORT_LAYER,
3449         //&DualModeController::SetMwsTransportLayer},
3450         //{OpCode::SET_MWS_SCAN_FREQUENCY_TABLE,
3451         //&DualModeController::SetMwsScanFrequencyTable},
3452         //{OpCode::SET_MWS_PATTERN_CONFIGURATION,
3453         //&DualModeController::SetMwsPatternConfiguration},
3454         //{OpCode::SET_RESERVED_LT_ADDR,
3455         //&DualModeController::SetReservedLtAddr},
3456         //{OpCode::DELETE_RESERVED_LT_ADDR,
3457         //&DualModeController::DeleteReservedLtAddr},
3458         //{OpCode::SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_DATA,
3459         //&DualModeController::SetConnectionlessPeripheralBroadcastData},
3460         //{OpCode::READ_SYNCHRONIZATION_TRAIN_PARAMETERS,
3461         //&DualModeController::ReadSynchronizationTrainParameters},
3462         //{OpCode::WRITE_SYNCHRONIZATION_TRAIN_PARAMETERS,
3463         //&DualModeController::WriteSynchronizationTrainParameters},
3464         //{OpCode::READ_SECURE_CONNECTIONS_HOST_SUPPORT,
3465         //&DualModeController::ReadSecureConnectionsHostSupport},
3466         {OpCode::WRITE_SECURE_CONNECTIONS_HOST_SUPPORT,
3467          &DualModeController::WriteSecureConnectionsHostSupport},
3468         //{OpCode::READ_AUTHENTICATED_PAYLOAD_TIMEOUT,
3469         //&DualModeController::ReadAuthenticatedPayloadTimeout},
3470         //{OpCode::WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT,
3471         //&DualModeController::WriteAuthenticatedPayloadTimeout},
3472         {OpCode::READ_LOCAL_OOB_EXTENDED_DATA,
3473          &DualModeController::ReadLocalOobExtendedData},
3474         //{OpCode::READ_EXTENDED_PAGE_TIMEOUT,
3475         //&DualModeController::ReadExtendedPageTimeout},
3476         //{OpCode::WRITE_EXTENDED_PAGE_TIMEOUT,
3477         //&DualModeController::WriteExtendedPageTimeout},
3478         //{OpCode::READ_EXTENDED_INQUIRY_LENGTH,
3479         //&DualModeController::ReadExtendedInquiryLength},
3480         //{OpCode::WRITE_EXTENDED_INQUIRY_LENGTH,
3481         //&DualModeController::WriteExtendedInquiryLength},
3482         //{OpCode::SET_ECOSYSTEM_BASE_INTERVAL,
3483         //&DualModeController::SetEcosystemBaseInterval},
3484         //{OpCode::CONFIGURE_DATA_PATH, &DualModeController::ConfigureDataPath},
3485         //{OpCode::SET_MIN_ENCRYPTION_KEY_SIZE,
3486         //&DualModeController::SetMinEncryptionKeySize},
3487 
3488         // INFORMATIONAL_PARAMETERS
3489         {OpCode::READ_LOCAL_VERSION_INFORMATION,
3490          &DualModeController::ReadLocalVersionInformation},
3491         {OpCode::READ_LOCAL_SUPPORTED_COMMANDS,
3492          &DualModeController::ReadLocalSupportedCommands},
3493         {OpCode::READ_LOCAL_SUPPORTED_FEATURES,
3494          &DualModeController::ReadLocalSupportedFeatures},
3495         {OpCode::READ_LOCAL_EXTENDED_FEATURES,
3496          &DualModeController::ReadLocalExtendedFeatures},
3497         {OpCode::READ_BUFFER_SIZE, &DualModeController::ReadBufferSize},
3498         {OpCode::READ_BD_ADDR, &DualModeController::ReadBdAddr},
3499         //{OpCode::READ_DATA_BLOCK_SIZE,
3500         //&DualModeController::ReadDataBlockSize},
3501         {OpCode::READ_LOCAL_SUPPORTED_CODECS_V1,
3502          &DualModeController::ReadLocalSupportedCodecsV1},
3503         //{OpCode::READ_LOCAL_SIMPLE_PAIRING_OPTIONS,
3504         //&DualModeController::ReadLocalSimplePairingOptions},
3505         //{OpCode::READ_LOCAL_SUPPORTED_CODECS_V2,
3506         //&DualModeController::ReadLocalSupportedCodecsV2},
3507         //{OpCode::READ_LOCAL_SUPPORTED_CODEC_CAPABILITIES,
3508         //&DualModeController::ReadLocalSupportedCodecCapabilities},
3509         //{OpCode::READ_LOCAL_SUPPORTED_CONTROLLER_DELAY,
3510         //&DualModeController::ReadLocalSupportedControllerDelay},
3511 
3512         // STATUS_PARAMETERS
3513         //{OpCode::READ_FAILED_CONTACT_COUNTER,
3514         //&DualModeController::ReadFailedContactCounter},
3515         //{OpCode::RESET_FAILED_CONTACT_COUNTER,
3516         //&DualModeController::ResetFailedContactCounter},
3517         //{OpCode::READ_LINK_QUALITY, &DualModeController::ReadLinkQuality},
3518         {OpCode::READ_RSSI, &DualModeController::ReadRssi},
3519         //{OpCode::READ_AFH_CHANNEL_MAP,
3520         //&DualModeController::ReadAfhChannelMap},
3521         //{OpCode::READ_CLOCK, &DualModeController::ReadClock},
3522         {OpCode::READ_ENCRYPTION_KEY_SIZE,
3523          &DualModeController::ReadEncryptionKeySize},
3524         //{OpCode::GET_MWS_TRANSPORT_LAYER_CONFIGURATION,
3525         //&DualModeController::GetMwsTransportLayerConfiguration},
3526         //{OpCode::SET_TRIGGERED_CLOCK_CAPTURE,
3527         //&DualModeController::SetTriggeredClockCapture},
3528 
3529         // TESTING
3530         {OpCode::READ_LOOPBACK_MODE, &DualModeController::ReadLoopbackMode},
3531         {OpCode::WRITE_LOOPBACK_MODE, &DualModeController::WriteLoopbackMode},
3532         //{OpCode::ENABLE_DEVICE_UNDER_TEST_MODE,
3533         //&DualModeController::EnableDeviceUnderTestMode},
3534         //{OpCode::WRITE_SIMPLE_PAIRING_DEBUG_MODE,
3535         //&DualModeController::WriteSimplePairingDebugMode},
3536         //{OpCode::WRITE_SECURE_CONNECTIONS_TEST_MODE,
3537         //&DualModeController::WriteSecureConnectionsTestMode},
3538 
3539         // LE_CONTROLLER
3540         {OpCode::LE_SET_EVENT_MASK, &DualModeController::LeSetEventMask},
3541         {OpCode::LE_READ_BUFFER_SIZE_V1,
3542          &DualModeController::LeReadBufferSizeV1},
3543         {OpCode::LE_READ_LOCAL_SUPPORTED_FEATURES,
3544          &DualModeController::LeReadLocalSupportedFeatures},
3545         {OpCode::LE_SET_RANDOM_ADDRESS,
3546          &DualModeController::LeSetRandomAddress},
3547         {OpCode::LE_SET_ADVERTISING_PARAMETERS,
3548          &DualModeController::LeSetAdvertisingParameters},
3549         {OpCode::LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER,
3550          &DualModeController::LeReadAdvertisingPhysicalChannelTxPower},
3551         {OpCode::LE_SET_ADVERTISING_DATA,
3552          &DualModeController::LeSetAdvertisingData},
3553         {OpCode::LE_SET_SCAN_RESPONSE_DATA,
3554          &DualModeController::LeSetScanResponseData},
3555         {OpCode::LE_SET_ADVERTISING_ENABLE,
3556          &DualModeController::LeSetAdvertisingEnable},
3557         {OpCode::LE_SET_SCAN_PARAMETERS,
3558          &DualModeController::LeSetScanParameters},
3559         {OpCode::LE_SET_SCAN_ENABLE, &DualModeController::LeSetScanEnable},
3560         {OpCode::LE_CREATE_CONNECTION, &DualModeController::LeCreateConnection},
3561         {OpCode::LE_CREATE_CONNECTION_CANCEL,
3562          &DualModeController::LeCreateConnectionCancel},
3563         {OpCode::LE_READ_FILTER_ACCEPT_LIST_SIZE,
3564          &DualModeController::LeReadFilterAcceptListSize},
3565         {OpCode::LE_CLEAR_FILTER_ACCEPT_LIST,
3566          &DualModeController::LeClearFilterAcceptList},
3567         {OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST,
3568          &DualModeController::LeAddDeviceToFilterAcceptList},
3569         {OpCode::LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST,
3570          &DualModeController::LeRemoveDeviceFromFilterAcceptList},
3571         {OpCode::LE_CONNECTION_UPDATE, &DualModeController::LeConnectionUpdate},
3572         //{OpCode::LE_SET_HOST_CHANNEL_CLASSIFICATION,
3573         //&DualModeController::LeSetHostChannelClassification},
3574         //{OpCode::LE_READ_CHANNEL_MAP, &DualModeController::LeReadChannelMap},
3575         {OpCode::LE_READ_REMOTE_FEATURES,
3576          &DualModeController::LeReadRemoteFeatures},
3577         {OpCode::LE_ENCRYPT, &DualModeController::LeEncrypt},
3578         {OpCode::LE_RAND, &DualModeController::LeRand},
3579         {OpCode::LE_START_ENCRYPTION, &DualModeController::LeStartEncryption},
3580         {OpCode::LE_LONG_TERM_KEY_REQUEST_REPLY,
3581          &DualModeController::LeLongTermKeyRequestReply},
3582         {OpCode::LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY,
3583          &DualModeController::LeLongTermKeyRequestNegativeReply},
3584         {OpCode::LE_READ_SUPPORTED_STATES,
3585          &DualModeController::LeReadSupportedStates},
3586         //{OpCode::LE_RECEIVER_TEST_V1, &DualModeController::LeReceiverTestV1},
3587         //{OpCode::LE_TRANSMITTER_TEST_V1,
3588         //&DualModeController::LeTransmitterTestV1},
3589         //{OpCode::LE_TEST_END, &DualModeController::LeTestEnd},
3590         {OpCode::LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY,
3591          &DualModeController::LeRemoteConnectionParameterRequestReply},
3592         {OpCode::LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY,
3593          &DualModeController::LeRemoteConnectionParameterRequestNegativeReply},
3594         //{OpCode::LE_SET_DATA_LENGTH, &DualModeController::LeSetDataLength},
3595         {OpCode::LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH,
3596          &DualModeController::LeReadSuggestedDefaultDataLength},
3597         {OpCode::LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH,
3598          &DualModeController::LeWriteSuggestedDefaultDataLength},
3599         //{OpCode::LE_READ_LOCAL_P_256_PUBLIC_KEY,
3600         //&DualModeController::LeReadLocalP256PublicKey},
3601         //{OpCode::LE_GENERATE_DHKEY_V1,
3602         //&DualModeController::LeGenerateDhkeyV1},
3603         {OpCode::LE_ADD_DEVICE_TO_RESOLVING_LIST,
3604          &DualModeController::LeAddDeviceToResolvingList},
3605         {OpCode::LE_REMOVE_DEVICE_FROM_RESOLVING_LIST,
3606          &DualModeController::LeRemoveDeviceFromResolvingList},
3607         {OpCode::LE_CLEAR_RESOLVING_LIST,
3608          &DualModeController::LeClearResolvingList},
3609         {OpCode::LE_READ_RESOLVING_LIST_SIZE,
3610          &DualModeController::LeReadResolvingListSize},
3611         {OpCode::LE_READ_PEER_RESOLVABLE_ADDRESS,
3612          &DualModeController::LeReadPeerResolvableAddress},
3613         {OpCode::LE_READ_LOCAL_RESOLVABLE_ADDRESS,
3614          &DualModeController::LeReadLocalResolvableAddress},
3615         {OpCode::LE_SET_ADDRESS_RESOLUTION_ENABLE,
3616          &DualModeController::LeSetAddressResolutionEnable},
3617         {OpCode::LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT,
3618          &DualModeController::LeSetResolvablePrivateAddressTimeout},
3619         {OpCode::LE_READ_MAXIMUM_DATA_LENGTH,
3620          &DualModeController::LeReadMaximumDataLength},
3621         {OpCode::LE_READ_PHY, &DualModeController::LeReadPhy},
3622         {OpCode::LE_SET_DEFAULT_PHY, &DualModeController::LeSetDefaultPhy},
3623         {OpCode::LE_SET_PHY, &DualModeController::LeSetPhy},
3624         //{OpCode::LE_RECEIVER_TEST_V2, &DualModeController::LeReceiverTestV2},
3625         //{OpCode::LE_TRANSMITTER_TEST_V2,
3626         //&DualModeController::LeTransmitterTestV2},
3627         {OpCode::LE_SET_ADVERTISING_SET_RANDOM_ADDRESS,
3628          &DualModeController::LeSetAdvertisingSetRandomAddress},
3629         {OpCode::LE_SET_EXTENDED_ADVERTISING_PARAMETERS,
3630          &DualModeController::LeSetExtendedAdvertisingParameters},
3631         {OpCode::LE_SET_EXTENDED_ADVERTISING_DATA,
3632          &DualModeController::LeSetExtendedAdvertisingData},
3633         {OpCode::LE_SET_EXTENDED_SCAN_RESPONSE_DATA,
3634          &DualModeController::LeSetExtendedScanResponseData},
3635         {OpCode::LE_SET_EXTENDED_ADVERTISING_ENABLE,
3636          &DualModeController::LeSetExtendedAdvertisingEnable},
3637         {OpCode::LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH,
3638          &DualModeController::LeReadMaximumAdvertisingDataLength},
3639         {OpCode::LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS,
3640          &DualModeController::LeReadNumberOfSupportedAdvertisingSets},
3641         {OpCode::LE_REMOVE_ADVERTISING_SET,
3642          &DualModeController::LeRemoveAdvertisingSet},
3643         {OpCode::LE_CLEAR_ADVERTISING_SETS,
3644          &DualModeController::LeClearAdvertisingSets},
3645         {OpCode::LE_SET_PERIODIC_ADVERTISING_PARAMETERS,
3646          &DualModeController::LeSetPeriodicAdvertisingParameters},
3647         {OpCode::LE_SET_PERIODIC_ADVERTISING_DATA,
3648          &DualModeController::LeSetPeriodicAdvertisingData},
3649         {OpCode::LE_SET_PERIODIC_ADVERTISING_ENABLE,
3650          &DualModeController::LeSetPeriodicAdvertisingEnable},
3651         {OpCode::LE_SET_EXTENDED_SCAN_PARAMETERS,
3652          &DualModeController::LeSetExtendedScanParameters},
3653         {OpCode::LE_SET_EXTENDED_SCAN_ENABLE,
3654          &DualModeController::LeSetExtendedScanEnable},
3655         {OpCode::LE_EXTENDED_CREATE_CONNECTION,
3656          &DualModeController::LeExtendedCreateConnection},
3657         {OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC,
3658          &DualModeController::LePeriodicAdvertisingCreateSync},
3659         {OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL,
3660          &DualModeController::LePeriodicAdvertisingCreateSyncCancel},
3661         {OpCode::LE_PERIODIC_ADVERTISING_TERMINATE_SYNC,
3662          &DualModeController::LePeriodicAdvertisingTerminateSync},
3663         {OpCode::LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST,
3664          &DualModeController::LeAddDeviceToPeriodicAdvertiserList},
3665         {OpCode::LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST,
3666          &DualModeController::LeRemoveDeviceFromPeriodicAdvertiserList},
3667         {OpCode::LE_CLEAR_PERIODIC_ADVERTISER_LIST,
3668          &DualModeController::LeClearPeriodicAdvertiserList},
3669         {OpCode::LE_READ_PERIODIC_ADVERTISER_LIST_SIZE,
3670          &DualModeController::LeReadPeriodicAdvertiserListSize},
3671         //{OpCode::LE_READ_TRANSMIT_POWER,
3672         //&DualModeController::LeReadTransmitPower},
3673         //{OpCode::LE_READ_RF_PATH_COMPENSATION_POWER,
3674         //&DualModeController::LeReadRfPathCompensationPower},
3675         //{OpCode::LE_WRITE_RF_PATH_COMPENSATION_POWER,
3676         //&DualModeController::LeWriteRfPathCompensationPower},
3677         {OpCode::LE_SET_PRIVACY_MODE, &DualModeController::LeSetPrivacyMode},
3678         //{OpCode::LE_RECEIVER_TEST_V3, &DualModeController::LeReceiverTestV3},
3679         //{OpCode::LE_TRANSMITTER_TEST_V3,
3680         //&DualModeController::LeTransmitterTestV3},
3681         //{OpCode::LE_SET_CONNECTIONLESS_CTE_TRANSMIT_PARAMETERS,
3682         //&DualModeController::LeSetConnectionlessCteTransmitParameters},
3683         //{OpCode::LE_SET_CONNECTIONLESS_CTE_TRANSMIT_ENABLE,
3684         //&DualModeController::LeSetConnectionlessCteTransmitEnable},
3685         //{OpCode::LE_SET_CONNECTIONLESS_IQ_SAMPLING_ENABLE,
3686         //&DualModeController::LeSetConnectionlessIqSamplingEnable},
3687         //{OpCode::LE_SET_CONNECTION_CTE_RECEIVE_PARAMETERS,
3688         //&DualModeController::LeSetConnectionCteReceiveParameters},
3689         //{OpCode::LE_SET_CONNECTION_CTE_TRANSMIT_PARAMETERS,
3690         //&DualModeController::LeSetConnectionCteTransmitParameters},
3691         //{OpCode::LE_CONNECTION_CTE_REQUEST_ENABLE,
3692         //&DualModeController::LeConnectionCteRequestEnable},
3693         //{OpCode::LE_CONNECTION_CTE_RESPONSE_ENABLE,
3694         //&DualModeController::LeConnectionCteResponseEnable},
3695         //{OpCode::LE_READ_ANTENNA_INFORMATION,
3696         //&DualModeController::LeReadAntennaInformation},
3697         //{OpCode::LE_SET_PERIODIC_ADVERTISING_RECEIVE_ENABLE,
3698         //&DualModeController::LeSetPeriodicAdvertisingReceiveEnable},
3699         //{OpCode::LE_PERIODIC_ADVERTISING_SYNC_TRANSFER,
3700         //&DualModeController::LePeriodicAdvertisingSyncTransfer},
3701         //{OpCode::LE_PERIODIC_ADVERTISING_SET_INFO_TRANSFER,
3702         //&DualModeController::LePeriodicAdvertisingSetInfoTransfer},
3703         //{OpCode::LE_SET_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS,
3704         //&DualModeController::LeSetPeriodicAdvertisingSyncTransferParameters},
3705         //{OpCode::LE_SET_DEFAULT_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS,
3706         //&DualModeController::LeSetDefaultPeriodicAdvertisingSyncTransferParameters},
3707         //{OpCode::LE_GENERATE_DHKEY_V2,
3708         //&DualModeController::LeGenerateDhkeyV2},
3709         //{OpCode::LE_MODIFY_SLEEP_CLOCK_ACCURACY,
3710         //&DualModeController::LeModifySleepClockAccuracy},
3711         {OpCode::LE_READ_BUFFER_SIZE_V2,
3712          &DualModeController::LeReadBufferSizeV2},
3713         {OpCode::LE_READ_ISO_TX_SYNC, &DualModeController::LeReadIsoTxSync},
3714         {OpCode::LE_SET_CIG_PARAMETERS,
3715          &DualModeController::LeSetCigParameters},
3716         //{OpCode::LE_SET_CIG_PARAMETERS_TEST,
3717         //&DualModeController::LeSetCigParametersTest},
3718         {OpCode::LE_CREATE_CIS, &DualModeController::LeCreateCis},
3719         {OpCode::LE_REMOVE_CIG, &DualModeController::LeRemoveCig},
3720         {OpCode::LE_ACCEPT_CIS_REQUEST,
3721          &DualModeController::LeAcceptCisRequest},
3722         {OpCode::LE_REJECT_CIS_REQUEST,
3723          &DualModeController::LeRejectCisRequest},
3724         {OpCode::LE_CREATE_BIG, &DualModeController::LeCreateBig},
3725         //{OpCode::LE_CREATE_BIG_TEST, &DualModeController::LeCreateBigTest},
3726         {OpCode::LE_TERMINATE_BIG, &DualModeController::LeTerminateBig},
3727         {OpCode::LE_BIG_CREATE_SYNC, &DualModeController::LeBigCreateSync},
3728         {OpCode::LE_BIG_TERMINATE_SYNC,
3729          &DualModeController::LeBigTerminateSync},
3730         {OpCode::LE_REQUEST_PEER_SCA, &DualModeController::LeRequestPeerSca},
3731         {OpCode::LE_SETUP_ISO_DATA_PATH,
3732          &DualModeController::LeSetupIsoDataPath},
3733         {OpCode::LE_REMOVE_ISO_DATA_PATH,
3734          &DualModeController::LeRemoveIsoDataPath},
3735         //{OpCode::LE_ISO_TRANSMIT_TEST,
3736         //&DualModeController::LeIsoTransmitTest},
3737         //{OpCode::LE_ISO_RECEIVE_TEST, &DualModeController::LeIsoReceiveTest},
3738         //{OpCode::LE_ISO_READ_TEST_COUNTERS,
3739         //&DualModeController::LeIsoReadTestCounters},
3740         //{OpCode::LE_ISO_TEST_END, &DualModeController::LeIsoTestEnd},
3741         {OpCode::LE_SET_HOST_FEATURE, &DualModeController::LeSetHostFeature},
3742         //{OpCode::LE_READ_ISO_LINK_QUALITY,
3743         //&DualModeController::LeReadIsoLinkQuality},
3744         //{OpCode::LE_ENHANCED_READ_TRANSMIT_POWER_LEVEL,
3745         //&DualModeController::LeEnhancedReadTransmitPowerLevel},
3746         //{OpCode::LE_READ_REMOTE_TRANSMIT_POWER_LEVEL,
3747         //&DualModeController::LeReadRemoteTransmitPowerLevel},
3748         //{OpCode::LE_SET_PATH_LOSS_REPORTING_PARAMETERS,
3749         //&DualModeController::LeSetPathLossReportingParameters},
3750         //{OpCode::LE_SET_PATH_LOSS_REPORTING_ENABLE,
3751         //&DualModeController::LeSetPathLossReportingEnable},
3752         //{OpCode::LE_SET_TRANSMIT_POWER_REPORTING_ENABLE,
3753         //&DualModeController::LeSetTransmitPowerReportingEnable},
3754         //{OpCode::LE_TRANSMITTER_TEST_V4,
3755         //&DualModeController::LeTransmitterTestV4},
3756         //{OpCode::LE_SET_DATA_RELATED_ADDRESS_CHANGES,
3757         //&DualModeController::LeSetDataRelatedAddressChanges},
3758         //{OpCode::LE_SET_DEFAULT_SUBRATE,
3759         //&DualModeController::LeSetDefaultSubrate},
3760         //{OpCode::LE_SUBRATE_REQUEST, &DualModeController::LeSubrateRequest},
3761 
3762         // VENDOR
3763         {OpCode(CSR_VENDOR), &DualModeController::CsrVendorCommand},
3764         {OpCode::LE_MULTI_ADVT, &DualModeController::LeMultiAdv},
3765         {OpCode::LE_ADV_FILTER, &DualModeController::LeAdvertisingFilter},
3766         {OpCode::LE_EXTENDED_SCAN_PARAMS,
3767          &DualModeController::LeExtendedScanParams},
3768         {OpCode::LE_ENERGY_INFO, &DualModeController::LeEnergyInfo},
3769         {OpCode::LE_GET_VENDOR_CAPABILITIES,
3770          &DualModeController::LeGetVendorCapabilities}};
3771 
3772 }  // namespace rootcanal
3773