blob: 587536a27e853a54355ad90c29affe045bf3eda8 [file] [log] [blame]
Myles Watsone22dde22019-01-18 11:42:33 -08001/*
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
Myles Watsone22dde22019-01-18 11:42:33 -080017#include "dual_mode_controller.h"
18
19#include <memory>
20
21#include <base/files/file_util.h>
22#include <base/json/json_reader.h>
Myles Watsone22dde22019-01-18 11:42:33 -080023#include <base/values.h>
24
Myles Watson1a0a0da2019-10-17 11:36:33 -070025#include "os/log.h"
Chienyuan3d8a8032019-11-01 18:04:07 +080026#include "packet/raw_builder.h"
Myles Watsone22dde22019-01-18 11:42:33 -080027
28#include "hci.h"
29#include "packets/hci/acl_packet_view.h"
30#include "packets/hci/command_packet_view.h"
Myles Watsone22dde22019-01-18 11:42:33 -080031#include "packets/hci/sco_packet_view.h"
32
33using std::vector;
34using test_vendor_lib::hci::EventCode;
35using test_vendor_lib::hci::OpCode;
36
37namespace {
38
39size_t LastNonZero(test_vendor_lib::packets::PacketView<true> view) {
40 for (size_t i = view.size() - 1; i > 0; i--) {
41 if (view[i] != 0) {
42 return i;
43 }
44 }
45 return 0;
46}
47
48} // namespace
49
50namespace test_vendor_lib {
51constexpr char DualModeController::kControllerPropertiesFile[];
52constexpr uint16_t DualModeController::kSecurityManagerNumKeys;
Chienyuanc27da092019-11-20 19:29:43 +080053constexpr uint16_t kNumCommandPackets = 0x01;
Myles Watsone22dde22019-01-18 11:42:33 -080054
55// Device methods.
56void DualModeController::Initialize(const std::vector<std::string>& args) {
57 if (args.size() < 2) return;
58
59 Address addr;
Hansong Zhang106fc602019-06-19 16:53:15 -070060 if (Address::FromString(args[1], addr)) {
61 properties_.SetAddress(addr);
62 } else {
Myles Watson1a0a0da2019-10-17 11:36:33 -070063 LOG_ALWAYS_FATAL("Invalid address: %s", args[1].c_str());
Hansong Zhang106fc602019-06-19 16:53:15 -070064 }
Myles Watsone22dde22019-01-18 11:42:33 -080065};
66
67std::string DualModeController::GetTypeString() const {
68 return "Simulated Bluetooth Controller";
69}
70
Chienyuandb55f312019-10-31 14:01:28 +080071void DualModeController::IncomingPacket(
72 model::packets::LinkLayerPacketView incoming) {
Myles Watsone22dde22019-01-18 11:42:33 -080073 link_layer_controller_.IncomingPacket(incoming);
74}
75
76void DualModeController::TimerTick() {
77 link_layer_controller_.TimerTick();
78}
79
Myles Watsone22dde22019-01-18 11:42:33 -080080void DualModeController::SendCommandCompleteUnknownOpCodeEvent(uint16_t command_opcode) const {
Chienyuan3d8a8032019-11-01 18:04:07 +080081 std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
82 std::make_unique<bluetooth::packet::RawBuilder>();
Chienyuanc27da092019-11-20 19:29:43 +080083 raw_builder_ptr->AddOctets1(kNumCommandPackets);
Chienyuan3d8a8032019-11-01 18:04:07 +080084 raw_builder_ptr->AddOctets2(command_opcode);
85 raw_builder_ptr->AddOctets1(
86 static_cast<uint8_t>(bluetooth::hci::ErrorCode::UNKNOWN_HCI_COMMAND));
87
88 auto packet = bluetooth::hci::EventPacketBuilder::Create(
89 bluetooth::hci::EventCode::COMMAND_COMPLETE, std::move(raw_builder_ptr));
90 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -080091}
92
Myles Watsone22dde22019-01-18 11:42:33 -080093DualModeController::DualModeController(const std::string& properties_filename, uint16_t num_keys)
94 : Device(properties_filename), security_manager_(num_keys) {
95 loopback_mode_ = hci::LoopbackMode::NO;
96
97 Address public_address;
Myles Watson1a0a0da2019-10-17 11:36:33 -070098 ASSERT(Address::FromString("3C:5A:B4:04:05:06", public_address));
Myles Watsone22dde22019-01-18 11:42:33 -080099 properties_.SetAddress(public_address);
100
101 link_layer_controller_.RegisterRemoteChannel(
Chienyuandb55f312019-10-31 14:01:28 +0800102 [this](std::shared_ptr<model::packets::LinkLayerPacketBuilder> packet,
103 Phy::Type phy_type) {
Myles Watsone22dde22019-01-18 11:42:33 -0800104 DualModeController::SendLinkLayerPacket(packet, phy_type);
105 });
106
107#define SET_HANDLER(opcode, method) \
108 active_hci_commands_[static_cast<uint16_t>(opcode)] = [this](packets::PacketView<true> param) { method(param); };
109 SET_HANDLER(OpCode::RESET, HciReset);
110 SET_HANDLER(OpCode::READ_BUFFER_SIZE, HciReadBufferSize);
111 SET_HANDLER(OpCode::HOST_BUFFER_SIZE, HciHostBufferSize);
112 SET_HANDLER(OpCode::SNIFF_SUBRATING, HciSniffSubrating);
Calvin Huang63a08962019-10-31 19:12:25 -0700113 SET_HANDLER(OpCode::READ_ENCRYPTION_KEY_SIZE, HciReadEncryptionKeySize);
Myles Watsone22dde22019-01-18 11:42:33 -0800114 SET_HANDLER(OpCode::READ_LOCAL_VERSION_INFORMATION, HciReadLocalVersionInformation);
115 SET_HANDLER(OpCode::READ_BD_ADDR, HciReadBdAddr);
116 SET_HANDLER(OpCode::READ_LOCAL_SUPPORTED_COMMANDS, HciReadLocalSupportedCommands);
Myles Watson1a0a0da2019-10-17 11:36:33 -0700117 SET_HANDLER(OpCode::READ_LOCAL_SUPPORTED_FEATURES, HciReadLocalSupportedFeatures);
Myles Watsone22dde22019-01-18 11:42:33 -0800118 SET_HANDLER(OpCode::READ_LOCAL_SUPPORTED_CODECS, HciReadLocalSupportedCodecs);
119 SET_HANDLER(OpCode::READ_LOCAL_EXTENDED_FEATURES, HciReadLocalExtendedFeatures);
120 SET_HANDLER(OpCode::READ_REMOTE_EXTENDED_FEATURES, HciReadRemoteExtendedFeatures);
Chienyuan9145e7a2019-10-02 15:18:55 +0800121 SET_HANDLER(OpCode::SWITCH_ROLE, HciSwitchRole);
Myles Watsone22dde22019-01-18 11:42:33 -0800122 SET_HANDLER(OpCode::READ_REMOTE_SUPPORTED_FEATURES, HciReadRemoteSupportedFeatures);
123 SET_HANDLER(OpCode::READ_CLOCK_OFFSET, HciReadClockOffset);
124 SET_HANDLER(OpCode::IO_CAPABILITY_REQUEST_REPLY, HciIoCapabilityRequestReply);
125 SET_HANDLER(OpCode::USER_CONFIRMATION_REQUEST_REPLY, HciUserConfirmationRequestReply);
126 SET_HANDLER(OpCode::USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY, HciUserConfirmationRequestNegativeReply);
127 SET_HANDLER(OpCode::IO_CAPABILITY_REQUEST_NEGATIVE_REPLY, HciIoCapabilityRequestNegativeReply);
128 SET_HANDLER(OpCode::WRITE_SIMPLE_PAIRING_MODE, HciWriteSimplePairingMode);
129 SET_HANDLER(OpCode::WRITE_LE_HOST_SUPPORT, HciWriteLeHostSupport);
Calvin Huang63a08962019-10-31 19:12:25 -0700130 SET_HANDLER(OpCode::WRITE_SECURE_CONNECTIONS_HOST_SUPPORT,
Chienyuanc27da092019-11-20 19:29:43 +0800131 HciWriteSecureConnectionsHostSupport);
Myles Watsone22dde22019-01-18 11:42:33 -0800132 SET_HANDLER(OpCode::SET_EVENT_MASK, HciSetEventMask);
133 SET_HANDLER(OpCode::WRITE_INQUIRY_MODE, HciWriteInquiryMode);
134 SET_HANDLER(OpCode::WRITE_PAGE_SCAN_TYPE, HciWritePageScanType);
135 SET_HANDLER(OpCode::WRITE_INQUIRY_SCAN_TYPE, HciWriteInquiryScanType);
136 SET_HANDLER(OpCode::AUTHENTICATION_REQUESTED, HciAuthenticationRequested);
137 SET_HANDLER(OpCode::SET_CONNECTION_ENCRYPTION, HciSetConnectionEncryption);
Chienyuanad340b02019-09-25 19:23:21 +0800138 SET_HANDLER(OpCode::CHANGE_CONNECTION_LINK_KEY, HciChangeConnectionLinkKey);
Chienyuan9145e7a2019-10-02 15:18:55 +0800139 SET_HANDLER(OpCode::MASTER_LINK_KEY, HciMasterLinkKey);
Myles Watsone22dde22019-01-18 11:42:33 -0800140 SET_HANDLER(OpCode::WRITE_AUTHENTICATION_ENABLE, HciWriteAuthenticationEnable);
141 SET_HANDLER(OpCode::READ_AUTHENTICATION_ENABLE, HciReadAuthenticationEnable);
142 SET_HANDLER(OpCode::WRITE_CLASS_OF_DEVICE, HciWriteClassOfDevice);
143 SET_HANDLER(OpCode::WRITE_PAGE_TIMEOUT, HciWritePageTimeout);
144 SET_HANDLER(OpCode::WRITE_LINK_SUPERVISION_TIMEOUT, HciWriteLinkSupervisionTimeout);
Chienyuanad340b02019-09-25 19:23:21 +0800145 SET_HANDLER(OpCode::HOLD_MODE, HciHoldMode);
146 SET_HANDLER(OpCode::SNIFF_MODE, HciSniffMode);
147 SET_HANDLER(OpCode::EXIT_SNIFF_MODE, HciExitSniffMode);
148 SET_HANDLER(OpCode::QOS_SETUP, HciQosSetup);
Myles Watsone22dde22019-01-18 11:42:33 -0800149 SET_HANDLER(OpCode::WRITE_DEFAULT_LINK_POLICY_SETTINGS, HciWriteDefaultLinkPolicySettings);
Chienyuanad340b02019-09-25 19:23:21 +0800150 SET_HANDLER(OpCode::FLOW_SPECIFICATION, HciFlowSpecification);
Myles Watsone22dde22019-01-18 11:42:33 -0800151 SET_HANDLER(OpCode::WRITE_LINK_POLICY_SETTINGS, HciWriteLinkPolicySettings);
152 SET_HANDLER(OpCode::CHANGE_CONNECTION_PACKET_TYPE, HciChangeConnectionPacketType);
153 SET_HANDLER(OpCode::WRITE_LOCAL_NAME, HciWriteLocalName);
154 SET_HANDLER(OpCode::READ_LOCAL_NAME, HciReadLocalName);
155 SET_HANDLER(OpCode::WRITE_EXTENDED_INQUIRY_RESPONSE, HciWriteExtendedInquiryResponse);
Myles Watsonb293d732019-08-19 12:35:36 -0700156 SET_HANDLER(OpCode::REFRESH_ENCRYPTION_KEY, HciRefreshEncryptionKey);
Myles Watsone22dde22019-01-18 11:42:33 -0800157 SET_HANDLER(OpCode::WRITE_VOICE_SETTING, HciWriteVoiceSetting);
158 SET_HANDLER(OpCode::WRITE_CURRENT_IAC_LAP, HciWriteCurrentIacLap);
159 SET_HANDLER(OpCode::WRITE_INQUIRY_SCAN_ACTIVITY, HciWriteInquiryScanActivity);
160 SET_HANDLER(OpCode::WRITE_SCAN_ENABLE, HciWriteScanEnable);
161 SET_HANDLER(OpCode::SET_EVENT_FILTER, HciSetEventFilter);
162 SET_HANDLER(OpCode::INQUIRY, HciInquiry);
163 SET_HANDLER(OpCode::INQUIRY_CANCEL, HciInquiryCancel);
164 SET_HANDLER(OpCode::ACCEPT_CONNECTION_REQUEST, HciAcceptConnectionRequest);
165 SET_HANDLER(OpCode::REJECT_CONNECTION_REQUEST, HciRejectConnectionRequest);
166 SET_HANDLER(OpCode::LINK_KEY_REQUEST_REPLY, HciLinkKeyRequestReply);
167 SET_HANDLER(OpCode::LINK_KEY_REQUEST_NEGATIVE_REPLY, HciLinkKeyRequestNegativeReply);
168 SET_HANDLER(OpCode::DELETE_STORED_LINK_KEY, HciDeleteStoredLinkKey);
169 SET_HANDLER(OpCode::REMOTE_NAME_REQUEST, HciRemoteNameRequest);
170 SET_HANDLER(OpCode::LE_SET_EVENT_MASK, HciLeSetEventMask);
171 SET_HANDLER(OpCode::LE_READ_BUFFER_SIZE, HciLeReadBufferSize);
172 SET_HANDLER(OpCode::LE_READ_LOCAL_SUPPORTED_FEATURES, HciLeReadLocalSupportedFeatures);
173 SET_HANDLER(OpCode::LE_SET_RANDOM_ADDRESS, HciLeSetRandomAddress);
Myles Watsone22dde22019-01-18 11:42:33 -0800174 SET_HANDLER(OpCode::LE_SET_ADVERTISING_PARAMETERS, HciLeSetAdvertisingParameters);
Myles Watson99aea892019-09-02 15:54:08 -0700175 SET_HANDLER(OpCode::LE_SET_ADVERTISING_DATA, HciLeSetAdvertisingData);
176 SET_HANDLER(OpCode::LE_SET_SCAN_RESPONSE_DATA, HciLeSetScanResponseData);
177 SET_HANDLER(OpCode::LE_SET_ADVERTISING_ENABLE, HciLeSetAdvertisingEnable);
Myles Watsone22dde22019-01-18 11:42:33 -0800178 SET_HANDLER(OpCode::LE_SET_SCAN_PARAMETERS, HciLeSetScanParameters);
179 SET_HANDLER(OpCode::LE_SET_SCAN_ENABLE, HciLeSetScanEnable);
180 SET_HANDLER(OpCode::LE_CREATE_CONNECTION, HciLeCreateConnection);
181 SET_HANDLER(OpCode::CREATE_CONNECTION, HciCreateConnection);
182 SET_HANDLER(OpCode::DISCONNECT, HciDisconnect);
183 SET_HANDLER(OpCode::LE_CREATE_CONNECTION_CANCEL, HciLeConnectionCancel);
184 SET_HANDLER(OpCode::LE_READ_WHITE_LIST_SIZE, HciLeReadWhiteListSize);
185 SET_HANDLER(OpCode::LE_CLEAR_WHITE_LIST, HciLeClearWhiteList);
186 SET_HANDLER(OpCode::LE_ADD_DEVICE_TO_WHITE_LIST, HciLeAddDeviceToWhiteList);
187 SET_HANDLER(OpCode::LE_REMOVE_DEVICE_FROM_WHITE_LIST, HciLeRemoveDeviceFromWhiteList);
188 SET_HANDLER(OpCode::LE_RAND, HciLeRand);
189 SET_HANDLER(OpCode::LE_READ_SUPPORTED_STATES, HciLeReadSupportedStates);
190 SET_HANDLER(OpCode::LE_GET_VENDOR_CAPABILITIES, HciLeVendorCap);
191 SET_HANDLER(OpCode::LE_MULTI_ADVT, HciLeVendorMultiAdv);
192 SET_HANDLER(OpCode::LE_ADV_FILTER, HciLeAdvertisingFilter);
193 SET_HANDLER(OpCode::LE_ENERGY_INFO, HciLeEnergyInfo);
194 SET_HANDLER(OpCode::LE_EXTENDED_SCAN_PARAMS, HciLeExtendedScanParams);
195 SET_HANDLER(OpCode::LE_READ_REMOTE_FEATURES, HciLeReadRemoteFeatures);
196 SET_HANDLER(OpCode::READ_REMOTE_VERSION_INFORMATION, HciReadRemoteVersionInformation);
197 SET_HANDLER(OpCode::LE_CONNECTION_UPDATE, HciLeConnectionUpdate);
198 SET_HANDLER(OpCode::LE_START_ENCRYPTION, HciLeStartEncryption);
Calvin Huangee1980c2019-11-01 16:35:55 -0700199 SET_HANDLER(OpCode::LE_ADD_DEVICE_TO_RESOLVING_LIST,
200 HciLeAddDeviceToResolvingList);
201 SET_HANDLER(OpCode::LE_REMOVE_DEVICE_FROM_RESOLVING_LIST,
202 HciLeRemoveDeviceFromResolvingList);
203 SET_HANDLER(OpCode::LE_CLEAR_RESOLVING_LIST, HciLeClearResolvingList);
204 SET_HANDLER(OpCode::LE_SET_PRIVACY_MODE, HciLeSetPrivacyMode);
Myles Watsone22dde22019-01-18 11:42:33 -0800205 // Testing Commands
206 SET_HANDLER(OpCode::READ_LOOPBACK_MODE, HciReadLoopbackMode);
207 SET_HANDLER(OpCode::WRITE_LOOPBACK_MODE, HciWriteLoopbackMode);
208#undef SET_HANDLER
209}
210
211void DualModeController::HciSniffSubrating(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700212 ASSERT_LOG(args.size() == 8, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -0800213
214 uint16_t handle = args.begin().extract<uint16_t>();
215
Chienyuan3d8a8032019-11-01 18:04:07 +0800216 auto packet = bluetooth::hci::SniffSubratingCompleteBuilder::Create(
Chienyuanc27da092019-11-20 19:29:43 +0800217 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, handle);
Chienyuan3d8a8032019-11-01 18:04:07 +0800218 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800219}
220
221void DualModeController::RegisterTaskScheduler(
222 std::function<AsyncTaskId(std::chrono::milliseconds, const TaskCallback&)> oneshot_scheduler) {
223 link_layer_controller_.RegisterTaskScheduler(oneshot_scheduler);
224}
225
226void DualModeController::RegisterPeriodicTaskScheduler(
227 std::function<AsyncTaskId(std::chrono::milliseconds, std::chrono::milliseconds, const TaskCallback&)>
228 periodic_scheduler) {
229 link_layer_controller_.RegisterPeriodicTaskScheduler(periodic_scheduler);
230}
231
232void DualModeController::RegisterTaskCancel(std::function<void(AsyncTaskId)> task_cancel) {
233 link_layer_controller_.RegisterTaskCancel(task_cancel);
234}
235
236void DualModeController::HandleAcl(std::shared_ptr<std::vector<uint8_t>> packet) {
237 auto acl_packet = packets::AclPacketView::Create(packet);
238 if (loopback_mode_ == hci::LoopbackMode::LOCAL) {
239 uint16_t handle = acl_packet.GetHandle();
Chienyuan3d8a8032019-11-01 18:04:07 +0800240
Chienyuanc27da092019-11-20 19:29:43 +0800241 std::vector<bluetooth::hci::CompletedPackets> completed_packets;
242 bluetooth::hci::CompletedPackets cp;
243 cp.connection_handle_ = handle;
244 cp.host_num_of_completed_packets_ = kNumCommandPackets;
245 completed_packets.push_back(cp);
246 auto packet = bluetooth::hci::NumberOfCompletedPacketsBuilder::Create(
247 completed_packets);
Chienyuan3d8a8032019-11-01 18:04:07 +0800248 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800249 return;
250 }
251
252 link_layer_controller_.SendAclToRemote(acl_packet);
253}
254
255void DualModeController::HandleSco(std::shared_ptr<std::vector<uint8_t>> packet) {
256 auto sco_packet = packets::ScoPacketView::Create(packet);
257 if (loopback_mode_ == hci::LoopbackMode::LOCAL) {
258 uint16_t handle = sco_packet.GetHandle();
259 send_sco_(packet);
Chienyuanc27da092019-11-20 19:29:43 +0800260 std::vector<bluetooth::hci::CompletedPackets> completed_packets;
261 bluetooth::hci::CompletedPackets cp;
262 cp.connection_handle_ = handle;
263 cp.host_num_of_completed_packets_ = kNumCommandPackets;
264 completed_packets.push_back(cp);
265 auto packet = bluetooth::hci::NumberOfCompletedPacketsBuilder::Create(
266 completed_packets);
Chienyuan3d8a8032019-11-01 18:04:07 +0800267 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800268 return;
269 }
270}
271
272void DualModeController::HandleCommand(std::shared_ptr<std::vector<uint8_t>> packet) {
273 auto command_packet = packets::CommandPacketView::Create(packet);
274 uint16_t opcode = command_packet.GetOpcode();
275 hci::OpCode op = static_cast<hci::OpCode>(opcode);
276
277 if (loopback_mode_ == hci::LoopbackMode::LOCAL &&
278 // Loopback exceptions.
279 op != OpCode::RESET && op != OpCode::SET_CONTROLLER_TO_HOST_FLOW_CONTROL && op != OpCode::HOST_BUFFER_SIZE &&
280 op != OpCode::HOST_NUM_COMPLETED_PACKETS && op != OpCode::READ_BUFFER_SIZE && op != OpCode::READ_LOOPBACK_MODE &&
281 op != OpCode::WRITE_LOOPBACK_MODE) {
Chienyuan3d8a8032019-11-01 18:04:07 +0800282 std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
283 std::make_unique<bluetooth::packet::RawBuilder>();
284 raw_builder_ptr->AddOctets(*packet);
285 auto packet = bluetooth::hci::LoopbackCommandBuilder::Create(
286 std::move(raw_builder_ptr));
287 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800288 } else if (active_hci_commands_.count(opcode) > 0) {
289 active_hci_commands_[opcode](command_packet.GetPayload());
290 } else {
291 SendCommandCompleteUnknownOpCodeEvent(opcode);
Chienyuan3d8a8032019-11-01 18:04:07 +0800292 LOG_INFO("Unknown command, opcode: 0x%04X, OGF: 0x%04X, OCF: 0x%04X",
293 opcode, (opcode & 0xFC00) >> 10, opcode & 0x03FF);
Myles Watsone22dde22019-01-18 11:42:33 -0800294 }
295}
296
297void DualModeController::RegisterEventChannel(
298 const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& callback) {
Chienyuan3d8a8032019-11-01 18:04:07 +0800299 send_event_ =
300 [callback](std::shared_ptr<bluetooth::hci::EventPacketBuilder> event) {
301 auto bytes = std::make_shared<std::vector<uint8_t>>();
302 bluetooth::packet::BitInserter bit_inserter(*bytes);
303 bytes->reserve(event->size());
304 event->Serialize(bit_inserter);
305 callback(std::move(bytes));
306 };
307 link_layer_controller_.RegisterEventChannel(send_event_);
Myles Watsone22dde22019-01-18 11:42:33 -0800308}
309
310void DualModeController::RegisterAclChannel(
311 const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& callback) {
312 link_layer_controller_.RegisterAclChannel(callback);
313 send_acl_ = callback;
314}
315
316void DualModeController::RegisterScoChannel(
317 const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& callback) {
318 link_layer_controller_.RegisterScoChannel(callback);
319 send_sco_ = callback;
320}
321
322void DualModeController::HciReset(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700323 ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -0800324 link_layer_controller_.Reset();
Hansong Zhang843271b2019-04-30 10:51:27 -0700325 if (loopback_mode_ == hci::LoopbackMode::LOCAL) {
326 loopback_mode_ = hci::LoopbackMode::NO;
327 }
Myles Watsone22dde22019-01-18 11:42:33 -0800328
Chienyuanc27da092019-11-20 19:29:43 +0800329 auto packet = bluetooth::hci::ResetCompleteBuilder::Create(
330 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
331 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800332}
333
334void DualModeController::HciReadBufferSize(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700335 ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -0800336
Chienyuan3d8a8032019-11-01 18:04:07 +0800337 auto packet = bluetooth::hci::ReadBufferSizeCompleteBuilder::Create(
Chienyuanc27da092019-11-20 19:29:43 +0800338 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
Chienyuan3d8a8032019-11-01 18:04:07 +0800339 properties_.GetAclDataPacketSize(),
340 properties_.GetSynchronousDataPacketSize(),
341 properties_.GetTotalNumAclDataPackets(),
342 properties_.GetTotalNumSynchronousDataPackets());
343 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800344}
345
Calvin Huang63a08962019-10-31 19:12:25 -0700346void DualModeController::HciReadEncryptionKeySize(
347 packets::PacketView<true> args) {
348 ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
349
350 uint16_t handle = args.begin().extract<uint16_t>();
351
Chienyuan3d8a8032019-11-01 18:04:07 +0800352 auto packet = bluetooth::hci::ReadEncryptionKeySizeCompleteBuilder::Create(
Chienyuanc27da092019-11-20 19:29:43 +0800353 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, handle,
Chienyuan3d8a8032019-11-01 18:04:07 +0800354 properties_.GetEncryptionKeySize());
355 send_event_(std::move(packet));
Calvin Huang63a08962019-10-31 19:12:25 -0700356}
357
Myles Watsone22dde22019-01-18 11:42:33 -0800358void DualModeController::HciHostBufferSize(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700359 ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
Chienyuanc27da092019-11-20 19:29:43 +0800360 auto packet = bluetooth::hci::HostBufferSizeCompleteBuilder::Create(
361 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
362 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800363}
364
365void DualModeController::HciReadLocalVersionInformation(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700366 ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
Chienyuan3d8a8032019-11-01 18:04:07 +0800367
Chienyuanc27da092019-11-20 19:29:43 +0800368 bluetooth::hci::LocalVersionInformation local_version_information;
369 local_version_information.hci_version_ =
370 static_cast<bluetooth::hci::HciVersion>(properties_.GetVersion());
371 local_version_information.hci_revision_ = properties_.GetRevision();
372 local_version_information.lmp_version_ =
373 static_cast<bluetooth::hci::LmpVersion>(properties_.GetLmpPalVersion());
374 local_version_information.manufacturer_name_ =
375 properties_.GetManufacturerName();
376 local_version_information.lmp_subversion_ = properties_.GetLmpPalSubversion();
377 auto packet =
378 bluetooth::hci::ReadLocalVersionInformationCompleteBuilder::Create(
379 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
380 local_version_information);
Chienyuan3d8a8032019-11-01 18:04:07 +0800381 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800382}
383
384void DualModeController::HciReadRemoteVersionInformation(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700385 ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -0800386
387 uint16_t handle = args.begin().extract<uint16_t>();
388
Chienyuan3d8a8032019-11-01 18:04:07 +0800389 auto status = link_layer_controller_.SendCommandToRemoteByHandle(
390 bluetooth::hci::OpCode::READ_REMOTE_VERSION_INFORMATION, args, handle);
Myles Watsone22dde22019-01-18 11:42:33 -0800391
Chienyuanc27da092019-11-20 19:29:43 +0800392 auto packet =
393 bluetooth::hci::ReadRemoteVersionInformationStatusBuilder::Create(
394 status, kNumCommandPackets);
395 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800396}
397
398void DualModeController::HciReadBdAddr(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700399 ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
Chienyuan3d8a8032019-11-01 18:04:07 +0800400 auto packet = bluetooth::hci::ReadBdAddrCompleteBuilder::Create(
Chienyuanc27da092019-11-20 19:29:43 +0800401 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
402 properties_.GetAddress());
Chienyuan3d8a8032019-11-01 18:04:07 +0800403 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800404}
405
406void DualModeController::HciReadLocalSupportedCommands(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700407 ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
Chienyuan3d8a8032019-11-01 18:04:07 +0800408
409 std::array<uint8_t, 64> supported_commands;
410 supported_commands.fill(0x00);
411 size_t len = properties_.GetSupportedCommands().size();
412 if (len > 64) {
413 len = 64;
414 }
415 std::copy_n(properties_.GetSupportedCommands().begin(), len,
416 supported_commands.begin());
417
418 auto packet =
419 bluetooth::hci::ReadLocalSupportedCommandsCompleteBuilder::Create(
Chienyuanc27da092019-11-20 19:29:43 +0800420 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
421 supported_commands);
Chienyuan3d8a8032019-11-01 18:04:07 +0800422 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800423}
424
Myles Watson1a0a0da2019-10-17 11:36:33 -0700425void DualModeController::HciReadLocalSupportedFeatures(packets::PacketView<true> args) {
426 ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
Chienyuan3d8a8032019-11-01 18:04:07 +0800427 auto packet =
428 bluetooth::hci::ReadLocalSupportedFeaturesCompleteBuilder::Create(
Chienyuanc27da092019-11-20 19:29:43 +0800429 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
Chienyuan3d8a8032019-11-01 18:04:07 +0800430 properties_.GetSupportedFeatures());
431 send_event_(std::move(packet));
Myles Watson14d56862019-08-19 13:03:46 -0700432}
433
Myles Watsone22dde22019-01-18 11:42:33 -0800434void DualModeController::HciReadLocalSupportedCodecs(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700435 ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
Chienyuan3d8a8032019-11-01 18:04:07 +0800436 auto packet = bluetooth::hci::ReadLocalSupportedCodecsCompleteBuilder::Create(
Chienyuanc27da092019-11-20 19:29:43 +0800437 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
Chienyuan3d8a8032019-11-01 18:04:07 +0800438 properties_.GetSupportedCodecs(), properties_.GetVendorSpecificCodecs());
439 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800440}
441
442void DualModeController::HciReadLocalExtendedFeatures(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700443 ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -0800444 uint8_t page_number = args.begin().extract<uint8_t>();
Chienyuan3d8a8032019-11-01 18:04:07 +0800445
446 auto pakcet =
447 bluetooth::hci::ReadLocalExtendedFeaturesCompleteBuilder::Create(
Chienyuanc27da092019-11-20 19:29:43 +0800448 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, page_number,
Chienyuan3d8a8032019-11-01 18:04:07 +0800449 properties_.GetExtendedFeaturesMaximumPageNumber(),
450 properties_.GetExtendedFeatures(page_number));
451 send_event_(std::move(pakcet));
Myles Watsone22dde22019-01-18 11:42:33 -0800452}
453
454void DualModeController::HciReadRemoteExtendedFeatures(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700455 ASSERT_LOG(args.size() == 3, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -0800456
457 uint16_t handle = args.begin().extract<uint16_t>();
458
Chienyuan3d8a8032019-11-01 18:04:07 +0800459 auto status = link_layer_controller_.SendCommandToRemoteByHandle(
460 bluetooth::hci::OpCode::READ_REMOTE_EXTENDED_FEATURES, args, handle);
Myles Watsone22dde22019-01-18 11:42:33 -0800461
Chienyuanc27da092019-11-20 19:29:43 +0800462 auto packet = bluetooth::hci::ReadRemoteExtendedFeaturesStatusBuilder::Create(
463 status, kNumCommandPackets);
464 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800465}
466
Chienyuan9145e7a2019-10-02 15:18:55 +0800467void DualModeController::HciSwitchRole(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700468 ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
Chienyuan9145e7a2019-10-02 15:18:55 +0800469
470 Address address = args.begin().extract<Address>();
471 uint8_t role = args.begin().extract<uint8_t>();
472
Chienyuan3d8a8032019-11-01 18:04:07 +0800473 auto status = link_layer_controller_.SwitchRole(address, role);
Chienyuan9145e7a2019-10-02 15:18:55 +0800474
Chienyuanc27da092019-11-20 19:29:43 +0800475 auto packet = bluetooth::hci::SwitchRoleStatusBuilder::Create(
476 status, kNumCommandPackets);
477 send_event_(std::move(packet));
Chienyuan9145e7a2019-10-02 15:18:55 +0800478}
479
Myles Watsone22dde22019-01-18 11:42:33 -0800480void DualModeController::HciReadRemoteSupportedFeatures(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700481 ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -0800482
483 uint16_t handle = args.begin().extract<uint16_t>();
484
Chienyuan3d8a8032019-11-01 18:04:07 +0800485 auto status = link_layer_controller_.SendCommandToRemoteByHandle(
486 bluetooth::hci::OpCode::READ_REMOTE_SUPPORTED_FEATURES, args, handle);
Myles Watsone22dde22019-01-18 11:42:33 -0800487
Chienyuanc27da092019-11-20 19:29:43 +0800488 auto packet =
489 bluetooth::hci::ReadRemoteSupportedFeaturesStatusBuilder::Create(
490 status, kNumCommandPackets);
491 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800492}
493
494void DualModeController::HciReadClockOffset(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700495 ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -0800496
497 uint16_t handle = args.begin().extract<uint16_t>();
498
Chienyuan3d8a8032019-11-01 18:04:07 +0800499 auto status = link_layer_controller_.SendCommandToRemoteByHandle(
500 bluetooth::hci::OpCode::READ_CLOCK_OFFSET, args, handle);
Myles Watsone22dde22019-01-18 11:42:33 -0800501
Chienyuanc27da092019-11-20 19:29:43 +0800502 auto packet = bluetooth::hci::ReadClockOffsetStatusBuilder::Create(
503 status, kNumCommandPackets);
504 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800505}
506
507void DualModeController::HciIoCapabilityRequestReply(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700508 ASSERT_LOG(args.size() == 9, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -0800509
510 auto args_itr = args.begin();
511 Address peer = args_itr.extract<Address>();
512 uint8_t io_capability = args_itr.extract<uint8_t>();
513 uint8_t oob_data_present_flag = args_itr.extract<uint8_t>();
514 uint8_t authentication_requirements = args_itr.extract<uint8_t>();
515
Chienyuan3d8a8032019-11-01 18:04:07 +0800516 auto status = link_layer_controller_.IoCapabilityRequestReply(
517 peer, io_capability, oob_data_present_flag, authentication_requirements);
518 auto packet = bluetooth::hci::IoCapabilityRequestReplyCompleteBuilder::Create(
Chienyuanc27da092019-11-20 19:29:43 +0800519 kNumCommandPackets, status, peer);
Myles Watsone22dde22019-01-18 11:42:33 -0800520
Chienyuan3d8a8032019-11-01 18:04:07 +0800521 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800522}
523
524void DualModeController::HciUserConfirmationRequestReply(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700525 ASSERT_LOG(args.size() == 6, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -0800526
527 Address peer = args.begin().extract<Address>();
528
Chienyuan3d8a8032019-11-01 18:04:07 +0800529 auto status = link_layer_controller_.UserConfirmationRequestReply(peer);
530 auto packet =
531 bluetooth::hci::UserConfirmationRequestReplyCompleteBuilder::Create(
Chienyuanc27da092019-11-20 19:29:43 +0800532 kNumCommandPackets, status, peer);
Myles Watsone22dde22019-01-18 11:42:33 -0800533
Chienyuan3d8a8032019-11-01 18:04:07 +0800534 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800535}
536
537void DualModeController::HciUserConfirmationRequestNegativeReply(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700538 ASSERT_LOG(args.size() == 6, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -0800539
540 Address peer = args.begin().extract<Address>();
541
Chienyuan3d8a8032019-11-01 18:04:07 +0800542 auto status =
543 link_layer_controller_.UserConfirmationRequestNegativeReply(peer);
544 auto packet =
545 bluetooth::hci::UserConfirmationRequestNegativeReplyCompleteBuilder::
Chienyuanc27da092019-11-20 19:29:43 +0800546 Create(kNumCommandPackets, status, peer);
Myles Watsone22dde22019-01-18 11:42:33 -0800547
Chienyuan3d8a8032019-11-01 18:04:07 +0800548 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800549}
550
551void DualModeController::HciUserPasskeyRequestReply(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700552 ASSERT_LOG(args.size() == 10, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -0800553
554 auto args_itr = args.begin();
555 Address peer = args_itr.extract<Address>();
556 uint32_t numeric_value = args_itr.extract<uint32_t>();
557
Chienyuan3d8a8032019-11-01 18:04:07 +0800558 auto status =
559 link_layer_controller_.UserPasskeyRequestReply(peer, numeric_value);
560 auto packet = bluetooth::hci::UserPasskeyRequestReplyCompleteBuilder::Create(
Chienyuanc27da092019-11-20 19:29:43 +0800561 kNumCommandPackets, status, peer);
Myles Watsone22dde22019-01-18 11:42:33 -0800562
Chienyuan3d8a8032019-11-01 18:04:07 +0800563 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800564}
565
566void DualModeController::HciUserPasskeyRequestNegativeReply(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700567 ASSERT_LOG(args.size() == 6, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -0800568
569 Address peer = args.begin().extract<Address>();
570
Chienyuan3d8a8032019-11-01 18:04:07 +0800571 auto status = link_layer_controller_.UserPasskeyRequestNegativeReply(peer);
572 auto packet =
573 bluetooth::hci::UserPasskeyRequestNegativeReplyCompleteBuilder::Create(
Chienyuanc27da092019-11-20 19:29:43 +0800574 kNumCommandPackets, status, peer);
Myles Watsone22dde22019-01-18 11:42:33 -0800575
Chienyuan3d8a8032019-11-01 18:04:07 +0800576 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800577}
578
579void DualModeController::HciRemoteOobDataRequestReply(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700580 ASSERT_LOG(args.size() == 38, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -0800581
582 auto args_itr = args.begin();
583 Address peer = args_itr.extract<Address>();
584 std::vector<uint8_t> c;
585 std::vector<uint8_t> r;
586 for (size_t i = 0; i < 16; i++) {
587 c.push_back(args_itr.extract<uint8_t>());
588 }
589 for (size_t i = 0; i < 16; i++) {
590 r.push_back(args_itr.extract<uint8_t>());
591 }
Chienyuan3d8a8032019-11-01 18:04:07 +0800592 auto status = link_layer_controller_.RemoteOobDataRequestReply(peer, c, r);
593 auto packet =
594 bluetooth::hci::RemoteOobDataRequestReplyCompleteBuilder::Create(
Chienyuanc27da092019-11-20 19:29:43 +0800595 kNumCommandPackets, status, peer);
Myles Watsone22dde22019-01-18 11:42:33 -0800596
Chienyuan3d8a8032019-11-01 18:04:07 +0800597 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800598}
599
600void DualModeController::HciRemoteOobDataRequestNegativeReply(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700601 ASSERT_LOG(args.size() == 6, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -0800602
603 Address peer = args.begin().extract<Address>();
604
Chienyuan3d8a8032019-11-01 18:04:07 +0800605 auto status = link_layer_controller_.RemoteOobDataRequestNegativeReply(peer);
606 auto packet =
607 bluetooth::hci::RemoteOobDataRequestNegativeReplyCompleteBuilder::Create(
Chienyuanc27da092019-11-20 19:29:43 +0800608 kNumCommandPackets, status, peer);
Myles Watsone22dde22019-01-18 11:42:33 -0800609
Chienyuan3d8a8032019-11-01 18:04:07 +0800610 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800611}
612
613void DualModeController::HciIoCapabilityRequestNegativeReply(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700614 ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -0800615
616 auto args_itr = args.begin();
617 Address peer = args_itr.extract<Address>();
618 hci::Status reason = args_itr.extract<hci::Status>();
619
Chienyuan3d8a8032019-11-01 18:04:07 +0800620 auto status =
621 link_layer_controller_.IoCapabilityRequestNegativeReply(peer, reason);
622 auto packet =
623 bluetooth::hci::IoCapabilityRequestNegativeReplyCompleteBuilder::Create(
Chienyuanc27da092019-11-20 19:29:43 +0800624 kNumCommandPackets, status, peer);
Myles Watsone22dde22019-01-18 11:42:33 -0800625
Chienyuan3d8a8032019-11-01 18:04:07 +0800626 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800627}
628
629void DualModeController::HciWriteSimplePairingMode(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700630 ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
631 ASSERT(args[0] == 1 || args[0] == 0);
Myles Watsone22dde22019-01-18 11:42:33 -0800632 link_layer_controller_.WriteSimplePairingMode(args[0] == 1);
Chienyuanc27da092019-11-20 19:29:43 +0800633 auto packet = bluetooth::hci::WriteSimplePairingModeCompleteBuilder::Create(
634 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
635 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800636}
637
638void DualModeController::HciChangeConnectionPacketType(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700639 ASSERT_LOG(args.size() == 4, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -0800640 auto args_itr = args.begin();
641 uint16_t handle = args_itr.extract<uint16_t>();
642 uint16_t packet_type = args_itr.extract<uint16_t>();
643
Chienyuan3d8a8032019-11-01 18:04:07 +0800644 auto status =
645 link_layer_controller_.ChangeConnectionPacketType(handle, packet_type);
Myles Watsone22dde22019-01-18 11:42:33 -0800646
Chienyuanc27da092019-11-20 19:29:43 +0800647 auto packet = bluetooth::hci::ChangeConnectionPacketTypeStatusBuilder::Create(
648 status, kNumCommandPackets);
649 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800650}
651
652void DualModeController::HciWriteLeHostSupport(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700653 ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
Chienyuanc27da092019-11-20 19:29:43 +0800654 auto packet = bluetooth::hci::WriteLeHostSupportCompleteBuilder::Create(
655 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
656 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800657}
658
Chienyuanc27da092019-11-20 19:29:43 +0800659void DualModeController::HciWriteSecureConnectionsHostSupport(
Calvin Huang63a08962019-10-31 19:12:25 -0700660 packets::PacketView<true> args) {
661 ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
Myles Watson171ccb22019-11-13 09:37:29 -0800662 properties_.SetExtendedFeatures(properties_.GetExtendedFeatures(1) | 0x8, 1);
Chienyuanc27da092019-11-20 19:29:43 +0800663 auto packet =
664 bluetooth::hci::WriteSecureConnectionsHostSupportCompleteBuilder::Create(
665 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
666 send_event_(std::move(packet));
Calvin Huang63a08962019-10-31 19:12:25 -0700667}
668
Myles Watsone22dde22019-01-18 11:42:33 -0800669void DualModeController::HciSetEventMask(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700670 ASSERT_LOG(args.size() == 8, "%s size=%zu", __func__, args.size());
Chienyuanc27da092019-11-20 19:29:43 +0800671 auto packet = bluetooth::hci::SetEventMaskCompleteBuilder::Create(
672 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
673 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800674}
675
676void DualModeController::HciWriteInquiryMode(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700677 ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -0800678 link_layer_controller_.SetInquiryMode(args[0]);
Chienyuanc27da092019-11-20 19:29:43 +0800679 auto packet = bluetooth::hci::WriteInquiryModeCompleteBuilder::Create(
680 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
681 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800682}
683
684void DualModeController::HciWritePageScanType(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700685 ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
Chienyuanc27da092019-11-20 19:29:43 +0800686 auto packet = bluetooth::hci::WritePageScanTypeCompleteBuilder::Create(
687 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
688 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800689}
690
691void DualModeController::HciWriteInquiryScanType(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700692 ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
Chienyuanc27da092019-11-20 19:29:43 +0800693 auto packet = bluetooth::hci::WriteInquiryScanTypeCompleteBuilder::Create(
694 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
695 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800696}
697
698void DualModeController::HciAuthenticationRequested(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700699 ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -0800700 uint16_t handle = args.begin().extract<uint16_t>();
Chienyuan3d8a8032019-11-01 18:04:07 +0800701 auto status = link_layer_controller_.AuthenticationRequested(handle);
Myles Watsone22dde22019-01-18 11:42:33 -0800702
Chienyuanc27da092019-11-20 19:29:43 +0800703 auto packet = bluetooth::hci::AuthenticationRequestedStatusBuilder::Create(
704 status, kNumCommandPackets);
705 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800706}
707
708void DualModeController::HciSetConnectionEncryption(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700709 ASSERT_LOG(args.size() == 3, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -0800710 auto args_itr = args.begin();
711 uint16_t handle = args_itr.extract<uint16_t>();
712 uint8_t encryption_enable = args_itr.extract<uint8_t>();
Chienyuan3d8a8032019-11-01 18:04:07 +0800713 auto status =
714 link_layer_controller_.SetConnectionEncryption(handle, encryption_enable);
Myles Watsone22dde22019-01-18 11:42:33 -0800715
Chienyuanc27da092019-11-20 19:29:43 +0800716 auto packet = bluetooth::hci::SetConnectionEncryptionStatusBuilder::Create(
717 status, kNumCommandPackets);
718 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800719}
720
Myles Watson1a0a0da2019-10-17 11:36:33 -0700721void DualModeController::HciChangeConnectionLinkKey(packets::PacketView<true> args) {
722 ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
Chienyuanad340b02019-09-25 19:23:21 +0800723 auto args_itr = args.begin();
724 uint16_t handle = args_itr.extract<uint16_t>();
725
Chienyuan3d8a8032019-11-01 18:04:07 +0800726 auto status = link_layer_controller_.ChangeConnectionLinkKey(handle);
Chienyuanad340b02019-09-25 19:23:21 +0800727
Chienyuanc27da092019-11-20 19:29:43 +0800728 auto packet = bluetooth::hci::ChangeConnectionLinkKeyStatusBuilder::Create(
729 status, kNumCommandPackets);
730 send_event_(std::move(packet));
Chienyuanad340b02019-09-25 19:23:21 +0800731}
732
Chienyuan9145e7a2019-10-02 15:18:55 +0800733void DualModeController::HciMasterLinkKey(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700734 ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
Chienyuan9145e7a2019-10-02 15:18:55 +0800735 auto args_itr = args.begin();
736 uint8_t key_flag = args_itr.extract<uint8_t>();
737
Chienyuan3d8a8032019-11-01 18:04:07 +0800738 auto status = link_layer_controller_.MasterLinkKey(key_flag);
Chienyuan9145e7a2019-10-02 15:18:55 +0800739
Chienyuanc27da092019-11-20 19:29:43 +0800740 auto packet = bluetooth::hci::MasterLinkKeyStatusBuilder::Create(
741 status, kNumCommandPackets);
742 send_event_(std::move(packet));
Chienyuan9145e7a2019-10-02 15:18:55 +0800743}
744
Myles Watsone22dde22019-01-18 11:42:33 -0800745void DualModeController::HciWriteAuthenticationEnable(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700746 ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -0800747 properties_.SetAuthenticationEnable(args[0]);
Chienyuanc27da092019-11-20 19:29:43 +0800748 auto packet =
749 bluetooth::hci::WriteAuthenticationEnableCompleteBuilder::Create(
750 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
751 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800752}
753
754void DualModeController::HciReadAuthenticationEnable(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700755 ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
Chienyuan3d8a8032019-11-01 18:04:07 +0800756 auto packet = bluetooth::hci::ReadAuthenticationEnableCompleteBuilder::Create(
Chienyuanc27da092019-11-20 19:29:43 +0800757 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
Chienyuan3d8a8032019-11-01 18:04:07 +0800758 static_cast<bluetooth::hci::AuthenticationEnable>(
759 properties_.GetAuthenticationEnable()));
760 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800761}
762
763void DualModeController::HciWriteClassOfDevice(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700764 ASSERT_LOG(args.size() == 3, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -0800765 properties_.SetClassOfDevice(args[0], args[1], args[2]);
Chienyuanc27da092019-11-20 19:29:43 +0800766 auto packet = bluetooth::hci::WriteClassOfDeviceCompleteBuilder::Create(
767 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
768 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800769}
770
771void DualModeController::HciWritePageTimeout(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700772 ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
Chienyuanc27da092019-11-20 19:29:43 +0800773 auto packet = bluetooth::hci::WritePageTimeoutCompleteBuilder::Create(
774 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
775 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800776}
777
Chienyuanad340b02019-09-25 19:23:21 +0800778void DualModeController::HciHoldMode(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700779 ASSERT_LOG(args.size() == 6, "%s size=%zu", __func__, args.size());
Chienyuanad340b02019-09-25 19:23:21 +0800780 auto args_itr = args.begin();
781 uint16_t handle = args_itr.extract<uint16_t>();
782 uint16_t hold_mode_max_interval = args_itr.extract<uint16_t>();
783 uint16_t hold_mode_min_interval = args_itr.extract<uint16_t>();
784
Chienyuan3d8a8032019-11-01 18:04:07 +0800785 auto status = link_layer_controller_.HoldMode(handle, hold_mode_max_interval,
786 hold_mode_min_interval);
Chienyuanad340b02019-09-25 19:23:21 +0800787
Chienyuanc27da092019-11-20 19:29:43 +0800788 auto packet =
789 bluetooth::hci::HoldModeStatusBuilder::Create(status, kNumCommandPackets);
790 send_event_(std::move(packet));
Chienyuanad340b02019-09-25 19:23:21 +0800791}
792
793void DualModeController::HciSniffMode(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700794 ASSERT_LOG(args.size() == 10, "%s size=%zu", __func__, args.size());
Chienyuanad340b02019-09-25 19:23:21 +0800795 auto args_itr = args.begin();
796 uint16_t handle = args_itr.extract<uint16_t>();
797 uint16_t sniff_max_interval = args_itr.extract<uint16_t>();
798 uint16_t sniff_min_interval = args_itr.extract<uint16_t>();
799 uint16_t sniff_attempt = args_itr.extract<uint16_t>();
800 uint16_t sniff_timeout = args_itr.extract<uint16_t>();
801
Chienyuan3d8a8032019-11-01 18:04:07 +0800802 auto status = link_layer_controller_.SniffMode(handle, sniff_max_interval,
803 sniff_min_interval,
804 sniff_attempt, sniff_timeout);
Chienyuanad340b02019-09-25 19:23:21 +0800805
Chienyuanc27da092019-11-20 19:29:43 +0800806 auto packet = bluetooth::hci::SniffModeStatusBuilder::Create(
807 status, kNumCommandPackets);
808 send_event_(std::move(packet));
Chienyuanad340b02019-09-25 19:23:21 +0800809}
810
811void DualModeController::HciExitSniffMode(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700812 ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
Chienyuanad340b02019-09-25 19:23:21 +0800813 auto args_itr = args.begin();
814 uint16_t handle = args_itr.extract<uint16_t>();
815
Chienyuan3d8a8032019-11-01 18:04:07 +0800816 auto status = link_layer_controller_.ExitSniffMode(handle);
Chienyuanad340b02019-09-25 19:23:21 +0800817
Chienyuanc27da092019-11-20 19:29:43 +0800818 auto packet = bluetooth::hci::ExitSniffModeStatusBuilder::Create(
819 status, kNumCommandPackets);
820 send_event_(std::move(packet));
Chienyuanad340b02019-09-25 19:23:21 +0800821}
822
823void DualModeController::HciQosSetup(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700824 ASSERT_LOG(args.size() == 20, "%s size=%zu", __func__, args.size());
Chienyuanad340b02019-09-25 19:23:21 +0800825 auto args_itr = args.begin();
826 uint16_t handle = args_itr.extract<uint16_t>();
827 args_itr.extract<uint8_t>(); // unused
828 uint8_t service_type = args_itr.extract<uint8_t>();
829 uint32_t token_rate = args_itr.extract<uint32_t>();
830 uint32_t peak_bandwidth = args_itr.extract<uint32_t>();
831 uint32_t latency = args_itr.extract<uint32_t>();
832 uint32_t delay_variation = args_itr.extract<uint32_t>();
833
Chienyuan3d8a8032019-11-01 18:04:07 +0800834 auto status =
835 link_layer_controller_.QosSetup(handle, service_type, token_rate,
836 peak_bandwidth, latency, delay_variation);
Chienyuanad340b02019-09-25 19:23:21 +0800837
Chienyuanc27da092019-11-20 19:29:43 +0800838 auto packet =
839 bluetooth::hci::QosSetupStatusBuilder::Create(status, kNumCommandPackets);
840 send_event_(std::move(packet));
Chienyuanad340b02019-09-25 19:23:21 +0800841}
842
Myles Watsone22dde22019-01-18 11:42:33 -0800843void DualModeController::HciWriteDefaultLinkPolicySettings(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700844 ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
Chienyuanc27da092019-11-20 19:29:43 +0800845 auto packet =
846 bluetooth::hci::WriteDefaultLinkPolicySettingsCompleteBuilder::Create(
847 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
848 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800849}
850
Chienyuanad340b02019-09-25 19:23:21 +0800851void DualModeController::HciFlowSpecification(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700852 ASSERT_LOG(args.size() == 21, "%s size=%zu", __func__, args.size());
Chienyuanad340b02019-09-25 19:23:21 +0800853 auto args_itr = args.begin();
854 uint16_t handle = args_itr.extract<uint16_t>();
855 args_itr.extract<uint8_t>(); // unused
856 uint8_t flow_direction = args_itr.extract<uint8_t>();
857 uint8_t service_type = args_itr.extract<uint8_t>();
858 uint32_t token_rate = args_itr.extract<uint32_t>();
859 uint32_t token_bucket_size = args_itr.extract<uint32_t>();
860 uint32_t peak_bandwidth = args_itr.extract<uint32_t>();
861 uint32_t access_latency = args_itr.extract<uint32_t>();
862
Chienyuan3d8a8032019-11-01 18:04:07 +0800863 auto status = link_layer_controller_.FlowSpecification(
864 handle, flow_direction, service_type, token_rate, token_bucket_size,
865 peak_bandwidth, access_latency);
Chienyuanad340b02019-09-25 19:23:21 +0800866
Chienyuanc27da092019-11-20 19:29:43 +0800867 auto packet = bluetooth::hci::FlowSpecificationStatusBuilder::Create(
868 status, kNumCommandPackets);
869 send_event_(std::move(packet));
Chienyuanad340b02019-09-25 19:23:21 +0800870}
871
Myles Watsone22dde22019-01-18 11:42:33 -0800872void DualModeController::HciWriteLinkPolicySettings(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700873 ASSERT_LOG(args.size() == 4, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -0800874
875 auto args_itr = args.begin();
876 uint16_t handle = args_itr.extract<uint16_t>();
877 uint16_t settings = args_itr.extract<uint16_t>();
878
Chienyuan3d8a8032019-11-01 18:04:07 +0800879 auto status =
880 link_layer_controller_.WriteLinkPolicySettings(handle, settings);
Myles Watsone22dde22019-01-18 11:42:33 -0800881
Chienyuan3d8a8032019-11-01 18:04:07 +0800882 auto packet = bluetooth::hci::WriteLinkPolicySettingsCompleteBuilder::Create(
Chienyuanc27da092019-11-20 19:29:43 +0800883 kNumCommandPackets, status, handle);
Chienyuan3d8a8032019-11-01 18:04:07 +0800884 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800885}
886
887void DualModeController::HciWriteLinkSupervisionTimeout(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700888 ASSERT_LOG(args.size() == 4, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -0800889
890 auto args_itr = args.begin();
891 uint16_t handle = args_itr.extract<uint16_t>();
892 uint16_t timeout = args_itr.extract<uint16_t>();
893
Chienyuan3d8a8032019-11-01 18:04:07 +0800894 auto status =
895 link_layer_controller_.WriteLinkSupervisionTimeout(handle, timeout);
896 auto packet =
897 bluetooth::hci::WriteLinkSupervisionTimeoutCompleteBuilder::Create(
Chienyuanc27da092019-11-20 19:29:43 +0800898 kNumCommandPackets, status, handle);
Chienyuan3d8a8032019-11-01 18:04:07 +0800899 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800900}
901
902void DualModeController::HciReadLocalName(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700903 ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
Chienyuan3d8a8032019-11-01 18:04:07 +0800904
905 std::array<uint8_t, 248> local_name;
906 local_name.fill(0x00);
907 size_t len = properties_.GetName().size();
908 if (len > 247) {
909 len = 247; // one byte for NULL octet (0x00)
910 }
911 std::copy_n(properties_.GetName().begin(), len, local_name.begin());
912
913 auto packet = bluetooth::hci::ReadLocalNameCompleteBuilder::Create(
Chienyuanc27da092019-11-20 19:29:43 +0800914 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, local_name);
Chienyuan3d8a8032019-11-01 18:04:07 +0800915 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800916}
917
918void DualModeController::HciWriteLocalName(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700919 ASSERT_LOG(args.size() == 248, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -0800920 std::vector<uint8_t> clipped(args.begin(), args.begin() + LastNonZero(args) + 1);
921 properties_.SetName(clipped);
Chienyuanc27da092019-11-20 19:29:43 +0800922 auto packet = bluetooth::hci::WriteLocalNameCompleteBuilder::Create(
923 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
924 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800925}
926
927void DualModeController::HciWriteExtendedInquiryResponse(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700928 ASSERT_LOG(args.size() == 241, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -0800929 // Strip FEC byte and trailing zeros
930 std::vector<uint8_t> clipped(args.begin() + 1, args.begin() + LastNonZero(args) + 1);
931 properties_.SetExtendedInquiryData(clipped);
Myles Watson1a0a0da2019-10-17 11:36:33 -0700932 LOG_WARN("Write EIR Inquiry - Size = %d (%d)", static_cast<int>(properties_.GetExtendedInquiryData().size()),
Myles Watsone22dde22019-01-18 11:42:33 -0800933 static_cast<int>(clipped.size()));
Chienyuanc27da092019-11-20 19:29:43 +0800934 auto packet =
935 bluetooth::hci::WriteExtendedInquiryResponseCompleteBuilder::Create(
936 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
937 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800938}
939
Myles Watson1a0a0da2019-10-17 11:36:33 -0700940void DualModeController::HciRefreshEncryptionKey(packets::PacketView<true> args) {
941 ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
Myles Watsonb293d732019-08-19 12:35:36 -0700942 auto args_itr = args.begin();
943 uint16_t handle = args_itr.extract<uint16_t>();
Chienyuanc27da092019-11-20 19:29:43 +0800944 auto status_packet =
945 bluetooth::hci::RefreshEncryptionKeyStatusBuilder::Create(
946 bluetooth::hci::ErrorCode::SUCCESS, kNumCommandPackets);
947 send_event_(std::move(status_packet));
Myles Watsonb293d732019-08-19 12:35:36 -0700948 // TODO: Support this in the link layer
Chienyuanc27da092019-11-20 19:29:43 +0800949 auto complete_packet =
950 bluetooth::hci::EncryptionKeyRefreshCompleteBuilder::Create(
951 bluetooth::hci::ErrorCode::SUCCESS, handle);
952 send_event_(std::move(complete_packet));
Myles Watsonb293d732019-08-19 12:35:36 -0700953}
954
Myles Watsone22dde22019-01-18 11:42:33 -0800955void DualModeController::HciWriteVoiceSetting(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700956 ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
Chienyuanc27da092019-11-20 19:29:43 +0800957 auto packet = bluetooth::hci::WriteVoiceSettingCompleteBuilder::Create(
958 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
959 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800960}
961
962void DualModeController::HciWriteCurrentIacLap(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700963 ASSERT(args.size() > 0);
964 ASSERT(args.size() == 1 + (3 * args[0])); // count + 3-byte IACs
Chienyuanc27da092019-11-20 19:29:43 +0800965 auto packet = bluetooth::hci::WriteCurrentIacLapCompleteBuilder::Create(
966 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
967 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800968}
969
970void DualModeController::HciWriteInquiryScanActivity(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700971 ASSERT_LOG(args.size() == 4, "%s size=%zu", __func__, args.size());
Chienyuanc27da092019-11-20 19:29:43 +0800972 auto packet = bluetooth::hci::WriteInquiryScanActivityCompleteBuilder::Create(
973 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
974 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800975}
976
977void DualModeController::HciWriteScanEnable(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700978 ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -0800979 link_layer_controller_.SetInquiryScanEnable(args[0] & 0x1);
980 link_layer_controller_.SetPageScanEnable(args[0] & 0x2);
Chienyuanc27da092019-11-20 19:29:43 +0800981 auto packet = bluetooth::hci::WriteScanEnableCompleteBuilder::Create(
982 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
983 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800984}
985
986void DualModeController::HciSetEventFilter(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700987 ASSERT(args.size() > 0);
Chienyuanc27da092019-11-20 19:29:43 +0800988 auto packet = bluetooth::hci::SetEventFilterCompleteBuilder::Create(
989 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
990 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800991}
992
993void DualModeController::HciInquiry(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700994 ASSERT_LOG(args.size() == 5, "%s size=%zu", __func__, args.size());
995 link_layer_controller_.SetInquiryLAP(args[0] | (args[1], 8) | (args[2], 16));
Myles Watsone22dde22019-01-18 11:42:33 -0800996 link_layer_controller_.SetInquiryMaxResponses(args[4]);
997 link_layer_controller_.StartInquiry(std::chrono::milliseconds(args[3] * 1280));
998
Chienyuanc27da092019-11-20 19:29:43 +0800999 auto packet = bluetooth::hci::InquiryStatusBuilder::Create(
1000 bluetooth::hci::ErrorCode::SUCCESS, kNumCommandPackets);
1001 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001002}
1003
1004void DualModeController::HciInquiryCancel(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001005 ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -08001006 link_layer_controller_.InquiryCancel();
Chienyuanc27da092019-11-20 19:29:43 +08001007 auto packet = bluetooth::hci::InquiryCancelCompleteBuilder::Create(
1008 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
1009 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001010}
1011
1012void DualModeController::HciAcceptConnectionRequest(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001013 ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -08001014 Address addr = args.begin().extract<Address>();
1015 bool try_role_switch = args[6] == 0;
Chienyuan3d8a8032019-11-01 18:04:07 +08001016 auto status =
1017 link_layer_controller_.AcceptConnectionRequest(addr, try_role_switch);
Chienyuanc27da092019-11-20 19:29:43 +08001018 auto packet = bluetooth::hci::AcceptConnectionRequestStatusBuilder::Create(
1019 status, kNumCommandPackets);
1020 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001021}
1022
1023void DualModeController::HciRejectConnectionRequest(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001024 ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -08001025 auto args_itr = args.begin();
1026 Address addr = args_itr.extract<Address>();
1027 uint8_t reason = args_itr.extract<uint8_t>();
Chienyuan3d8a8032019-11-01 18:04:07 +08001028 auto status = link_layer_controller_.RejectConnectionRequest(addr, reason);
Chienyuanc27da092019-11-20 19:29:43 +08001029 auto packet = bluetooth::hci::RejectConnectionRequestStatusBuilder::Create(
1030 status, kNumCommandPackets);
1031 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001032}
1033
1034void DualModeController::HciLinkKeyRequestReply(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001035 ASSERT_LOG(args.size() == 22, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -08001036 Address addr = args.begin().extract<Address>();
1037 packets::PacketView<true> key = args.SubViewLittleEndian(6, 22);
Chienyuan3d8a8032019-11-01 18:04:07 +08001038 auto status = link_layer_controller_.LinkKeyRequestReply(addr, key);
Chienyuanc27da092019-11-20 19:29:43 +08001039 auto packet = bluetooth::hci::LinkKeyRequestReplyCompleteBuilder::Create(
1040 kNumCommandPackets, status);
Chienyuan3d8a8032019-11-01 18:04:07 +08001041 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001042}
1043
1044void DualModeController::HciLinkKeyRequestNegativeReply(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001045 ASSERT_LOG(args.size() == 6, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -08001046 Address addr = args.begin().extract<Address>();
Chienyuan3d8a8032019-11-01 18:04:07 +08001047 auto status = link_layer_controller_.LinkKeyRequestNegativeReply(addr);
1048 auto packet =
1049 bluetooth::hci::LinkKeyRequestNegativeReplyCompleteBuilder::Create(
Chienyuanc27da092019-11-20 19:29:43 +08001050 kNumCommandPackets, status, addr);
Chienyuan3d8a8032019-11-01 18:04:07 +08001051 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001052}
1053
1054void DualModeController::HciDeleteStoredLinkKey(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001055 ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -08001056
1057 uint16_t deleted_keys = 0;
1058
1059 if (args[6] == 0) {
1060 Address addr = args.begin().extract<Address>();
1061 deleted_keys = security_manager_.DeleteKey(addr);
1062 }
1063
1064 if (args[6] == 1) {
1065 security_manager_.DeleteAllKeys();
1066 }
1067
Chienyuan3d8a8032019-11-01 18:04:07 +08001068 auto packet = bluetooth::hci::DeleteStoredLinkKeyCompleteBuilder::Create(
Chienyuanc27da092019-11-20 19:29:43 +08001069 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, deleted_keys);
Chienyuan3d8a8032019-11-01 18:04:07 +08001070
1071 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001072}
1073
1074void DualModeController::HciRemoteNameRequest(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001075 ASSERT_LOG(args.size() == 10, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -08001076
1077 Address remote_addr = args.begin().extract<Address>();
1078
Chienyuan3d8a8032019-11-01 18:04:07 +08001079 auto status = link_layer_controller_.SendCommandToRemoteByAddress(
1080 bluetooth::hci::OpCode::REMOTE_NAME_REQUEST, args, remote_addr, false);
Myles Watsone22dde22019-01-18 11:42:33 -08001081
Chienyuanc27da092019-11-20 19:29:43 +08001082 auto packet = bluetooth::hci::RemoteNameRequestStatusBuilder::Create(
1083 status, kNumCommandPackets);
1084 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001085}
1086
1087void DualModeController::HciLeSetEventMask(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001088 ASSERT_LOG(args.size() == 8, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -08001089 /*
1090 uint64_t mask = args.begin().extract<uint64_t>();
1091 link_layer_controller_.SetLeEventMask(mask);
1092 */
Chienyuanc27da092019-11-20 19:29:43 +08001093 auto packet = bluetooth::hci::LeSetEventMaskCompleteBuilder::Create(
1094 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
1095 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001096}
1097
1098void DualModeController::HciLeReadBufferSize(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001099 ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
Chienyuan3d8a8032019-11-01 18:04:07 +08001100
Chienyuanc27da092019-11-20 19:29:43 +08001101 bluetooth::hci::LeBufferSize le_buffer_size;
1102 le_buffer_size.le_data_packet_length_ = properties_.GetLeDataPacketLength();
1103 le_buffer_size.total_num_le_packets_ = properties_.GetTotalNumLeDataPackets();
Chienyuan3d8a8032019-11-01 18:04:07 +08001104
Chienyuanc27da092019-11-20 19:29:43 +08001105 auto packet = bluetooth::hci::LeReadBufferSizeCompleteBuilder::Create(
1106 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, le_buffer_size);
Chienyuan3d8a8032019-11-01 18:04:07 +08001107 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001108}
1109
1110void DualModeController::HciLeReadLocalSupportedFeatures(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001111 ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
Chienyuan3d8a8032019-11-01 18:04:07 +08001112 auto packet =
1113 bluetooth::hci::LeReadLocalSupportedFeaturesCompleteBuilder::Create(
Chienyuanc27da092019-11-20 19:29:43 +08001114 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
Chienyuan3d8a8032019-11-01 18:04:07 +08001115 properties_.GetLeSupportedFeatures());
1116 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001117}
1118
1119void DualModeController::HciLeSetRandomAddress(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001120 ASSERT_LOG(args.size() == 6, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -08001121 properties_.SetLeAddress(args.begin().extract<Address>());
Chienyuanc27da092019-11-20 19:29:43 +08001122 auto packet = bluetooth::hci::LeSetRandomAddressCompleteBuilder::Create(
1123 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
1124 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001125}
1126
1127void DualModeController::HciLeSetAdvertisingParameters(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001128 ASSERT_LOG(args.size() == 15, "%s size=%zu", __func__, args.size());
Myles Watson99aea892019-09-02 15:54:08 -07001129 auto args_itr = args.begin();
1130 properties_.SetLeAdvertisingParameters(
1131 args_itr.extract<uint16_t>() /* AdverisingIntervalMin */,
1132 args_itr.extract<uint16_t>() /* AdverisingIntervalMax */, args_itr.extract<uint8_t>() /* AdverisingType */,
1133 args_itr.extract<uint8_t>() /* OwnAddressType */, args_itr.extract<uint8_t>() /* PeerAddressType */,
1134 args_itr.extract<Address>() /* PeerAddress */, args_itr.extract<uint8_t>() /* AdvertisingChannelMap */,
1135 args_itr.extract<uint8_t>() /* AdvertisingFilterPolicy */
1136 );
Myles Watsone22dde22019-01-18 11:42:33 -08001137
Chienyuanc27da092019-11-20 19:29:43 +08001138 auto packet =
1139 bluetooth::hci::LeSetAdvertisingParametersCompleteBuilder::Create(
1140 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
1141 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001142}
1143
1144void DualModeController::HciLeSetAdvertisingData(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001145 ASSERT_LOG(args.size() == 32, "%s size=%zu", __func__, args.size());
Myles Watson99aea892019-09-02 15:54:08 -07001146 properties_.SetLeAdvertisement(std::vector<uint8_t>(args.begin() + 1, args.end()));
Chienyuanc27da092019-11-20 19:29:43 +08001147 auto packet = bluetooth::hci::LeSetAdvertisingDataCompleteBuilder::Create(
1148 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
1149 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001150}
1151
Myles Watson99aea892019-09-02 15:54:08 -07001152void DualModeController::HciLeSetScanResponseData(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001153 ASSERT_LOG(args.size() == 32, "%s size=%zu", __func__, args.size());
Myles Watson99aea892019-09-02 15:54:08 -07001154 properties_.SetLeScanResponse(std::vector<uint8_t>(args.begin() + 1, args.end()));
Chienyuanc27da092019-11-20 19:29:43 +08001155 auto packet = bluetooth::hci::LeSetScanResponseDataCompleteBuilder::Create(
1156 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
1157 send_event_(std::move(packet));
Myles Watson99aea892019-09-02 15:54:08 -07001158}
1159
1160void DualModeController::HciLeSetAdvertisingEnable(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001161 ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
Chienyuan3d8a8032019-11-01 18:04:07 +08001162 auto status = link_layer_controller_.SetLeAdvertisingEnable(
1163 args.begin().extract<uint8_t>());
Chienyuanc27da092019-11-20 19:29:43 +08001164 auto packet = bluetooth::hci::LeSetAdvertisingEnableCompleteBuilder::Create(
1165 kNumCommandPackets, status);
1166 send_event_(std::move(packet));
Myles Watson99aea892019-09-02 15:54:08 -07001167}
1168
Myles Watsone22dde22019-01-18 11:42:33 -08001169void DualModeController::HciLeSetScanParameters(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001170 ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -08001171 link_layer_controller_.SetLeScanType(args[0]);
Myles Watson1a0a0da2019-10-17 11:36:33 -07001172 link_layer_controller_.SetLeScanInterval(args[1] | (args[2], 8));
1173 link_layer_controller_.SetLeScanWindow(args[3] | (args[4], 8));
Myles Watsone22dde22019-01-18 11:42:33 -08001174 link_layer_controller_.SetLeAddressType(args[5]);
1175 link_layer_controller_.SetLeScanFilterPolicy(args[6]);
Chienyuanc27da092019-11-20 19:29:43 +08001176 auto packet = bluetooth::hci::LeSetScanParametersCompleteBuilder::Create(
1177 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
1178 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001179}
1180
1181void DualModeController::HciLeSetScanEnable(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001182 ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
1183 LOG_INFO("SetScanEnable: %d %d", args[0], args[1]);
Myles Watsone22dde22019-01-18 11:42:33 -08001184 link_layer_controller_.SetLeScanEnable(args[0]);
1185 link_layer_controller_.SetLeFilterDuplicates(args[1]);
Chienyuanc27da092019-11-20 19:29:43 +08001186 auto packet = bluetooth::hci::LeSetScanEnableCompleteBuilder::Create(
1187 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
1188 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001189}
1190
1191void DualModeController::HciLeCreateConnection(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001192 ASSERT_LOG(args.size() == 25, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -08001193 auto args_itr = args.begin();
1194 link_layer_controller_.SetLeScanInterval(args_itr.extract<uint16_t>());
1195 link_layer_controller_.SetLeScanWindow(args_itr.extract<uint16_t>());
1196 uint8_t initiator_filter_policy = args_itr.extract<uint8_t>();
1197 link_layer_controller_.SetLeInitiatorFilterPolicy(initiator_filter_policy);
1198
1199 if (initiator_filter_policy == 0) { // White list not used
1200 uint8_t peer_address_type = args_itr.extract<uint8_t>();
1201 Address peer_address = args_itr.extract<Address>();
1202 link_layer_controller_.SetLePeerAddressType(peer_address_type);
1203 link_layer_controller_.SetLePeerAddress(peer_address);
1204 }
1205 link_layer_controller_.SetLeAddressType(args_itr.extract<uint8_t>());
1206 link_layer_controller_.SetLeConnectionIntervalMin(args_itr.extract<uint16_t>());
1207 link_layer_controller_.SetLeConnectionIntervalMax(args_itr.extract<uint16_t>());
1208 link_layer_controller_.SetLeConnectionLatency(args_itr.extract<uint16_t>());
1209 link_layer_controller_.SetLeSupervisionTimeout(args_itr.extract<uint16_t>());
1210 link_layer_controller_.SetLeMinimumCeLength(args_itr.extract<uint16_t>());
1211 link_layer_controller_.SetLeMaximumCeLength(args_itr.extract<uint16_t>());
1212
Chienyuan3d8a8032019-11-01 18:04:07 +08001213 auto status = link_layer_controller_.SetLeConnect(true);
Myles Watsone22dde22019-01-18 11:42:33 -08001214
Chienyuanc27da092019-11-20 19:29:43 +08001215 auto packet = bluetooth::hci::LeCreateConnectionStatusBuilder::Create(
1216 status, kNumCommandPackets);
1217 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001218}
1219
1220void DualModeController::HciLeConnectionUpdate(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001221 ASSERT_LOG(args.size() == 14, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -08001222
Chienyuanc27da092019-11-20 19:29:43 +08001223 auto status_packet = bluetooth::hci::LeConnectionUpdateStatusBuilder::Create(
Chienyuan3d8a8032019-11-01 18:04:07 +08001224 bluetooth::hci::ErrorCode::CONNECTION_REJECTED_UNACCEPTABLE_BD_ADDR,
Chienyuanc27da092019-11-20 19:29:43 +08001225 kNumCommandPackets);
1226 send_event_(std::move(status_packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001227
Chienyuanc27da092019-11-20 19:29:43 +08001228 auto complete_packet =
1229 bluetooth::hci::LeConnectionUpdateCompleteBuilder::Create(
1230 bluetooth::hci::ErrorCode::SUCCESS, 0x0002, 0x0006, 0x0000, 0x01f4);
1231 send_event_(std::move(complete_packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001232}
1233
1234void DualModeController::HciCreateConnection(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001235 ASSERT_LOG(args.size() == 13, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -08001236
1237 auto args_itr = args.begin();
1238 Address address = args_itr.extract<Address>();
1239 uint16_t packet_type = args_itr.extract<uint16_t>();
1240 uint8_t page_scan_mode = args_itr.extract<uint8_t>();
1241 uint16_t clock_offset = args_itr.extract<uint16_t>();
1242 uint8_t allow_role_switch = args_itr.extract<uint8_t>();
1243
Chienyuan3d8a8032019-11-01 18:04:07 +08001244 auto status = link_layer_controller_.CreateConnection(
1245 address, packet_type, page_scan_mode, clock_offset, allow_role_switch);
Myles Watsone22dde22019-01-18 11:42:33 -08001246
Chienyuanc27da092019-11-20 19:29:43 +08001247 auto packet = bluetooth::hci::CreateConnectionStatusBuilder::Create(
1248 status, kNumCommandPackets);
1249 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001250}
1251
1252void DualModeController::HciDisconnect(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001253 ASSERT_LOG(args.size() == 3, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -08001254
1255 auto args_itr = args.begin();
1256 uint16_t handle = args_itr.extract<uint16_t>();
1257 uint8_t reason = args_itr.extract<uint8_t>();
1258
Chienyuan3d8a8032019-11-01 18:04:07 +08001259 auto status = link_layer_controller_.Disconnect(handle, reason);
Myles Watsone22dde22019-01-18 11:42:33 -08001260
Chienyuanc27da092019-11-20 19:29:43 +08001261 auto packet = bluetooth::hci::DisconnectStatusBuilder::Create(
1262 status, kNumCommandPackets);
1263 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001264}
1265
1266void DualModeController::HciLeConnectionCancel(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001267 ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -08001268 link_layer_controller_.SetLeConnect(false);
Chienyuanc27da092019-11-20 19:29:43 +08001269 auto packet = bluetooth::hci::LeCreateConnectionCancelStatusBuilder::Create(
1270 bluetooth::hci::ErrorCode::SUCCESS, kNumCommandPackets);
1271 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001272 /* For testing Jakub's patch: Figure out a neat way to call this without
1273 recompiling. I'm thinking about a bad device. */
1274 /*
1275 SendCommandCompleteOnlyStatus(OpCode::LE_CREATE_CONNECTION_CANCEL,
Chienyuan3d8a8032019-11-01 18:04:07 +08001276 bluetooth::hci::ErrorCode::COMMAND_DISALLOWED);
Myles Watsone22dde22019-01-18 11:42:33 -08001277 */
1278}
1279
1280void DualModeController::HciLeReadWhiteListSize(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001281 ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
Chienyuan3d8a8032019-11-01 18:04:07 +08001282 auto packet = bluetooth::hci::LeReadWhiteListSizeCompleteBuilder::Create(
Chienyuanc27da092019-11-20 19:29:43 +08001283 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
Chienyuan3d8a8032019-11-01 18:04:07 +08001284 properties_.GetLeWhiteListSize());
1285 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001286}
1287
1288void DualModeController::HciLeClearWhiteList(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001289 ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -08001290 link_layer_controller_.LeWhiteListClear();
Chienyuanc27da092019-11-20 19:29:43 +08001291 auto packet = bluetooth::hci::LeClearWhiteListCompleteBuilder::Create(
1292 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
1293 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001294}
1295
1296void DualModeController::HciLeAddDeviceToWhiteList(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001297 ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -08001298
1299 if (link_layer_controller_.LeWhiteListFull()) {
Chienyuanc27da092019-11-20 19:29:43 +08001300 auto packet = bluetooth::hci::LeAddDeviceToWhiteListCompleteBuilder::Create(
1301 kNumCommandPackets,
Chienyuan3d8a8032019-11-01 18:04:07 +08001302 bluetooth::hci::ErrorCode::MEMORY_CAPACITY_EXCEEDED);
Chienyuanc27da092019-11-20 19:29:43 +08001303 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001304 return;
1305 }
1306 auto args_itr = args.begin();
1307 uint8_t addr_type = args_itr.extract<uint8_t>();
1308 Address address = args_itr.extract<Address>();
1309 link_layer_controller_.LeWhiteListAddDevice(address, addr_type);
Chienyuanc27da092019-11-20 19:29:43 +08001310 auto packet = bluetooth::hci::LeAddDeviceToWhiteListCompleteBuilder::Create(
1311 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
1312 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001313}
1314
1315void DualModeController::HciLeRemoveDeviceFromWhiteList(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001316 ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -08001317
1318 auto args_itr = args.begin();
1319 uint8_t addr_type = args_itr.extract<uint8_t>();
1320 Address address = args_itr.extract<Address>();
1321 link_layer_controller_.LeWhiteListRemoveDevice(address, addr_type);
Chienyuanc27da092019-11-20 19:29:43 +08001322 auto packet =
1323 bluetooth::hci::LeRemoveDeviceFromWhiteListCompleteBuilder::Create(
1324 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
1325 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001326}
1327
Calvin Huangee1980c2019-11-01 16:35:55 -07001328void DualModeController::HciLeClearResolvingList(
1329 packets::PacketView<true> args) {
1330 ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
1331 link_layer_controller_.LeResolvingListClear();
Chienyuanc27da092019-11-20 19:29:43 +08001332 auto packet = bluetooth::hci::LeClearResolvingListCompleteBuilder::Create(
1333 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
1334 send_event_(std::move(packet));
Calvin Huangee1980c2019-11-01 16:35:55 -07001335}
1336
1337void DualModeController::HciLeAddDeviceToResolvingList(
1338 packets::PacketView<true> args) {
1339 ASSERT_LOG(args.size() == 39, "%s size=%zu", __func__, args.size());
1340
1341 if (link_layer_controller_.LeResolvingListFull()) {
Chienyuanc27da092019-11-20 19:29:43 +08001342 auto packet =
1343 bluetooth::hci::LeAddDeviceToResolvingListCompleteBuilder::Create(
1344 kNumCommandPackets,
1345 bluetooth::hci::ErrorCode::MEMORY_CAPACITY_EXCEEDED);
1346 send_event_(std::move(packet));
Calvin Huangee1980c2019-11-01 16:35:55 -07001347 return;
1348 }
1349 auto args_itr = args.begin();
1350 uint8_t addr_type = args_itr.extract<uint8_t>();
1351 Address address = args_itr.extract<Address>();
1352 std::array<uint8_t, LinkLayerController::kIrk_size> peerIrk;
1353 std::array<uint8_t, LinkLayerController::kIrk_size> localIrk;
1354 for (size_t irk_ind = 0; irk_ind < LinkLayerController::kIrk_size;
1355 irk_ind++) {
1356 peerIrk[irk_ind] = args_itr.extract<uint8_t>();
1357 }
1358
1359 for (size_t irk_ind = 0; irk_ind < LinkLayerController::kIrk_size;
1360 irk_ind++) {
1361 localIrk[irk_ind] = args_itr.extract<uint8_t>();
1362 }
1363
1364 link_layer_controller_.LeResolvingListAddDevice(address, addr_type, peerIrk,
1365 localIrk);
Chienyuanc27da092019-11-20 19:29:43 +08001366 auto packet =
1367 bluetooth::hci::LeAddDeviceToResolvingListCompleteBuilder::Create(
1368 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
1369 send_event_(std::move(packet));
Calvin Huangee1980c2019-11-01 16:35:55 -07001370}
1371
1372void DualModeController::HciLeRemoveDeviceFromResolvingList(
1373 packets::PacketView<true> args) {
1374 ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
1375
1376 auto args_itr = args.begin();
1377 uint8_t addr_type = args_itr.extract<uint8_t>();
1378 Address address = args_itr.extract<Address>();
1379 link_layer_controller_.LeResolvingListRemoveDevice(address, addr_type);
Chienyuanc27da092019-11-20 19:29:43 +08001380 auto packet =
1381 bluetooth::hci::LeRemoveDeviceFromResolvingListCompleteBuilder::Create(
1382 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
1383 send_event_(std::move(packet));
Calvin Huangee1980c2019-11-01 16:35:55 -07001384}
1385
1386void DualModeController::HciLeSetPrivacyMode(packets::PacketView<true> args) {
1387 ASSERT_LOG(args.size() == 8, "%s size=%zu", __func__, args.size());
1388
1389 auto args_itr = args.begin();
1390 uint8_t peer_identity_address_type = args_itr.extract<uint8_t>();
1391 Address peer_identity_address = args_itr.extract<Address>();
1392 uint8_t privacy_mode = args_itr.extract<uint8_t>();
1393
1394 if (link_layer_controller_.LeResolvingListContainsDevice(
1395 peer_identity_address, peer_identity_address_type)) {
1396 link_layer_controller_.LeSetPrivacyMode(
1397 peer_identity_address_type, peer_identity_address, privacy_mode);
1398 }
1399
Chienyuanc27da092019-11-20 19:29:43 +08001400 auto packet = bluetooth::hci::LeSetPrivacyModeCompleteBuilder::Create(
1401 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
1402 send_event_(std::move(packet));
Calvin Huangee1980c2019-11-01 16:35:55 -07001403}
1404
Myles Watsone22dde22019-01-18 11:42:33 -08001405void DualModeController::HciLeReadRemoteFeatures(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001406 ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -08001407
1408 uint16_t handle = args.begin().extract<uint16_t>();
1409
Chienyuan3d8a8032019-11-01 18:04:07 +08001410 auto status = link_layer_controller_.SendCommandToRemoteByHandle(
1411 bluetooth::hci::OpCode::LE_READ_REMOTE_FEATURES, args, handle);
Myles Watsone22dde22019-01-18 11:42:33 -08001412
Chienyuanc27da092019-11-20 19:29:43 +08001413 auto packet = bluetooth::hci::LeConnectionUpdateStatusBuilder::Create(
1414 status, kNumCommandPackets);
1415 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001416}
1417
1418void DualModeController::HciLeRand(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001419 ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -08001420 uint64_t random_val = 0;
1421 for (size_t rand_bytes = 0; rand_bytes < sizeof(uint64_t); rand_bytes += sizeof(RAND_MAX)) {
1422 random_val = (random_val << (8 * sizeof(RAND_MAX))) | random();
1423 }
Chienyuan3d8a8032019-11-01 18:04:07 +08001424
1425 auto packet = bluetooth::hci::LeRandCompleteBuilder::Create(
Chienyuanc27da092019-11-20 19:29:43 +08001426 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, random_val);
Chienyuan3d8a8032019-11-01 18:04:07 +08001427 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001428}
1429
1430void DualModeController::HciLeReadSupportedStates(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001431 ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
Chienyuan3d8a8032019-11-01 18:04:07 +08001432 auto packet = bluetooth::hci::LeReadSupportedStatesCompleteBuilder::Create(
Chienyuanc27da092019-11-20 19:29:43 +08001433 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
Chienyuan3d8a8032019-11-01 18:04:07 +08001434 properties_.GetLeSupportedStates());
1435 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001436}
1437
1438void DualModeController::HciLeVendorCap(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001439 ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -08001440 vector<uint8_t> caps = properties_.GetLeVendorCap();
1441 if (caps.size() == 0) {
Chienyuanc27da092019-11-20 19:29:43 +08001442 SendCommandCompleteUnknownOpCodeEvent(static_cast<uint16_t>(
1443 bluetooth::hci::OpCode::LE_GET_VENDOR_CAPABILITIES));
Myles Watsone22dde22019-01-18 11:42:33 -08001444 return;
1445 }
1446
Chienyuan3d8a8032019-11-01 18:04:07 +08001447 std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
1448 std::make_unique<bluetooth::packet::RawBuilder>();
1449 raw_builder_ptr->AddOctets1(
1450 static_cast<uint8_t>(bluetooth::hci::ErrorCode::SUCCESS));
1451 raw_builder_ptr->AddOctets(properties_.GetLeVendorCap());
1452
1453 auto packet = bluetooth::hci::CommandCompleteBuilder::Create(
Chienyuanc27da092019-11-20 19:29:43 +08001454 kNumCommandPackets, bluetooth::hci::OpCode::LE_GET_VENDOR_CAPABILITIES,
Chienyuan3d8a8032019-11-01 18:04:07 +08001455 std::move(raw_builder_ptr));
1456 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001457}
1458
1459void DualModeController::HciLeVendorMultiAdv(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001460 ASSERT(args.size() > 0);
Chienyuanc27da092019-11-20 19:29:43 +08001461 SendCommandCompleteUnknownOpCodeEvent(
1462 static_cast<uint16_t>(bluetooth::hci::OpCode::LE_MULTI_ADVT));
Myles Watsone22dde22019-01-18 11:42:33 -08001463}
1464
1465void DualModeController::HciLeAdvertisingFilter(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001466 ASSERT(args.size() > 0);
Chienyuanc27da092019-11-20 19:29:43 +08001467 SendCommandCompleteUnknownOpCodeEvent(
1468 static_cast<uint16_t>(bluetooth::hci::OpCode::LE_ADV_FILTER));
Myles Watsone22dde22019-01-18 11:42:33 -08001469}
1470
1471void DualModeController::HciLeEnergyInfo(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001472 ASSERT(args.size() > 0);
Chienyuanc27da092019-11-20 19:29:43 +08001473 SendCommandCompleteUnknownOpCodeEvent(
1474 static_cast<uint16_t>(bluetooth::hci::OpCode::LE_ENERGY_INFO));
Myles Watsone22dde22019-01-18 11:42:33 -08001475}
1476
1477void DualModeController::HciLeExtendedScanParams(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001478 ASSERT(args.size() > 0);
Chienyuanc27da092019-11-20 19:29:43 +08001479 SendCommandCompleteUnknownOpCodeEvent(
1480 static_cast<uint16_t>(bluetooth::hci::OpCode::LE_EXTENDED_SCAN_PARAMS));
Myles Watsone22dde22019-01-18 11:42:33 -08001481}
1482
1483void DualModeController::HciLeStartEncryption(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001484 ASSERT_LOG(args.size() == 28, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -08001485
1486 auto args_itr = args.begin();
1487 uint16_t handle = args_itr.extract<uint16_t>();
1488 // uint64_t random_number = args_itr.extract<uint64_t>();
1489 // uint16_t encrypted_diversifier = args_itr.extract<uint16_t>();
1490 // std::vector<uint8_t> long_term_key;
1491 // for (size_t i = 0; i < 16; i++) {
1492 // long_term_key.push_back(args_itr.extract<uint18_t>();
1493 // }
Chienyuanc27da092019-11-20 19:29:43 +08001494 auto status_packet = bluetooth::hci::LeStartEncryptionStatusBuilder::Create(
1495 bluetooth::hci::ErrorCode::SUCCESS, kNumCommandPackets);
1496 send_event_(std::move(status_packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001497
Chienyuanc27da092019-11-20 19:29:43 +08001498 auto complete_packet = bluetooth::hci::EncryptionChangeBuilder::Create(
Chienyuan3d8a8032019-11-01 18:04:07 +08001499 bluetooth::hci::ErrorCode::SUCCESS, handle,
1500 bluetooth::hci::EncryptionEnabled::OFF);
Chienyuanc27da092019-11-20 19:29:43 +08001501 send_event_(std::move(complete_packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001502#if 0
1503
1504 std::shared_ptr<packets::AclPacketBuilder> encryption_information =
1505 std::make_shared<packets::AclPacketBuilder>(
1506 0x0002, Acl::FIRST_AUTOMATICALLY_FLUSHABLE, Acl::POINT_TO_POINT,
1507 std::vector<uint8_t>({}));
1508
1509 encryption_information->AddPayloadOctets2(0x0011);
1510 encryption_information->AddPayloadOctets2(0x0006);
1511 encryption_information->AddPayloadOctets1(0x06);
1512 encryption_information->AddPayloadOctets8(0x0706050403020100);
1513 encryption_information->AddPayloadOctets8(0x0F0E0D0C0B0A0908);
1514
1515 send_acl_(encryption_information);
1516
1517 encryption_information = std::make_shared<packets::AclPacketBuilder>(
1518 0x0002, Acl::FIRST_AUTOMATICALLY_FLUSHABLE, Acl::POINT_TO_POINT,
1519 std::vector<uint8_t>({}));
1520
1521 encryption_information->AddPayloadOctets2(0x000B);
1522 encryption_information->AddPayloadOctets2(0x0006);
1523 encryption_information->AddPayloadOctets1(0x07);
1524 encryption_information->AddPayloadOctets2(0xBEEF);
1525 encryption_information->AddPayloadOctets8(0x0706050403020100);
1526
1527 send_acl_(encryption_information);
1528
1529 encryption_information = std::make_shared<packets::AclPacketBuilder>(
1530 0x0002, Acl::FIRST_AUTOMATICALLY_FLUSHABLE, Acl::POINT_TO_POINT,
1531 std::vector<uint8_t>({}));
1532
1533 encryption_information->AddPayloadOctets2(0x0011);
1534 encryption_information->AddPayloadOctets2(0x0006);
1535 encryption_information->AddPayloadOctets1(0x08);
1536 encryption_information->AddPayloadOctets8(0x0F0E0D0C0B0A0908);
1537 encryption_information->AddPayloadOctets8(0x0706050403020100);
1538
1539 send_acl_(encryption_information);
1540
1541 encryption_information = std::make_shared<packets::AclPacketBuilder>(
1542 0x0002, Acl::FIRST_AUTOMATICALLY_FLUSHABLE, Acl::POINT_TO_POINT,
1543 std::vector<uint8_t>({}));
1544
1545 encryption_information->AddPayloadOctets2(0x0008);
1546 encryption_information->AddPayloadOctets2(0x0006);
1547 encryption_information->AddPayloadOctets1(0x09);
1548 encryption_information->AddPayloadOctets1(0x01);
1549 encryption_information->AddPayloadOctets6(0xDEADBEEFF00D);
1550 send_acl_(encryption_information);
1551 // send_event_(packets::EventPacketBuilder::CreateLeStartEncryption()->ToVector());
1552
1553#endif
1554}
1555
1556void DualModeController::HciReadLoopbackMode(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001557 ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
Chienyuan3d8a8032019-11-01 18:04:07 +08001558 auto packet = bluetooth::hci::ReadLoopbackModeCompleteBuilder::Create(
Chienyuanc27da092019-11-20 19:29:43 +08001559 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
Chienyuan3d8a8032019-11-01 18:04:07 +08001560 static_cast<bluetooth::hci::LoopbackMode>(loopback_mode_));
1561 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001562}
1563
1564void DualModeController::HciWriteLoopbackMode(packets::PacketView<true> args) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001565 ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
Myles Watsone22dde22019-01-18 11:42:33 -08001566 loopback_mode_ = static_cast<hci::LoopbackMode>(args[0]);
1567 // ACL channel
1568 uint16_t acl_handle = 0x123;
Chienyuan3d8a8032019-11-01 18:04:07 +08001569 auto packet_acl = bluetooth::hci::ConnectionCompleteBuilder::Create(
1570 bluetooth::hci::ErrorCode::SUCCESS, acl_handle, properties_.GetAddress(),
1571 bluetooth::hci::LinkType::ACL, bluetooth::hci::Enable::DISABLED);
1572 send_event_(std::move(packet_acl));
Myles Watsone22dde22019-01-18 11:42:33 -08001573 // SCO channel
1574 uint16_t sco_handle = 0x345;
Chienyuan3d8a8032019-11-01 18:04:07 +08001575 auto packet_sco = bluetooth::hci::ConnectionCompleteBuilder::Create(
1576 bluetooth::hci::ErrorCode::SUCCESS, sco_handle, properties_.GetAddress(),
1577 bluetooth::hci::LinkType::SCO, bluetooth::hci::Enable::DISABLED);
1578 send_event_(std::move(packet_sco));
Chienyuanc27da092019-11-20 19:29:43 +08001579 auto packet = bluetooth::hci::WriteLoopbackModeCompleteBuilder::Create(
1580 kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
1581 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001582}
1583
Myles Watson205c32e2019-11-12 13:16:32 -08001584void DualModeController::SetAddress(Address address) {
1585 properties_.SetAddress(address);
1586}
1587
Myles Watsone22dde22019-01-18 11:42:33 -08001588} // namespace test_vendor_lib