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