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