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