blob: 39e53732dda7df4a8a077b88558e32bf40c1e48b [file] [log] [blame]
Myles Watsone22dde22019-01-18 11:42:33 -08001/*
2 * Copyright 2017 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 "link_layer_controller.h"
18
Myles Watsone22dde22019-01-18 11:42:33 -080019#include "hci.h"
Chienyuan3d8a8032019-11-01 18:04:07 +080020#include "include/le_advertisement.h"
Myles Watson1a0a0da2019-10-17 11:36:33 -070021#include "os/log.h"
Chienyuandb55f312019-10-31 14:01:28 +080022#include "packet/raw_builder.h"
Myles Watsone22dde22019-01-18 11:42:33 -080023
24using std::vector;
25using namespace std::chrono;
26using namespace test_vendor_lib::packets;
27
28namespace test_vendor_lib {
29
Chienyuanc27da092019-11-20 19:29:43 +080030constexpr uint16_t kNumCommandPackets = 0x01;
31
Myles Watsone22dde22019-01-18 11:42:33 -080032// TODO: Model Rssi?
33static uint8_t GetRssi() {
34 static uint8_t rssi = 0;
35 rssi += 5;
36 if (rssi > 128) {
37 rssi = rssi % 7;
38 }
39 return -(rssi);
40}
41
Chienyuandb55f312019-10-31 14:01:28 +080042void LinkLayerController::SendLeLinkLayerPacket(
43 std::unique_ptr<model::packets::LinkLayerPacketBuilder> packet) {
44 std::shared_ptr<model::packets::LinkLayerPacketBuilder> shared_packet =
45 std::move(packet);
46 ScheduleTask(milliseconds(50), [this, shared_packet]() {
47 send_to_remote_(std::move(shared_packet), Phy::Type::LOW_ENERGY);
48 });
Myles Watsone22dde22019-01-18 11:42:33 -080049}
50
Chienyuandb55f312019-10-31 14:01:28 +080051void LinkLayerController::SendLinkLayerPacket(
52 std::unique_ptr<model::packets::LinkLayerPacketBuilder> packet) {
53 std::shared_ptr<model::packets::LinkLayerPacketBuilder> shared_packet =
54 std::move(packet);
55 ScheduleTask(milliseconds(50), [this, shared_packet]() {
56 send_to_remote_(std::move(shared_packet), Phy::Type::BR_EDR);
57 });
Myles Watsone22dde22019-01-18 11:42:33 -080058}
59
Chienyuan3d8a8032019-11-01 18:04:07 +080060bluetooth::hci::ErrorCode LinkLayerController::SendCommandToRemoteByAddress(
Chienyuan676cefe2019-11-22 16:46:24 +080061 bluetooth::hci::OpCode opcode, bluetooth::packet::PacketView<true> args,
Myles Watsone066df42019-11-13 14:39:18 -080062 const Address& remote) {
63 Address local_address = properties_.GetAddress();
64
65 switch (opcode) {
66 case (bluetooth::hci::OpCode::REMOTE_NAME_REQUEST):
67 // LMP features get requested with remote name requests.
68 SendLinkLayerPacket(model::packets::ReadRemoteLmpFeaturesBuilder::Create(
69 local_address, remote));
70 SendLinkLayerPacket(model::packets::RemoteNameRequestBuilder::Create(
71 local_address, remote));
72 break;
73 case (bluetooth::hci::OpCode::READ_REMOTE_SUPPORTED_FEATURES):
74 SendLinkLayerPacket(
75 model::packets::ReadRemoteSupportedFeaturesBuilder::Create(
76 local_address, remote));
77 break;
78 case (bluetooth::hci::OpCode::READ_REMOTE_EXTENDED_FEATURES): {
79 uint8_t page_number =
80 (args.begin() + 2).extract<uint8_t>(); // skip the handle
81 SendLinkLayerPacket(
82 model::packets::ReadRemoteExtendedFeaturesBuilder::Create(
83 local_address, remote, page_number));
84 } break;
85 case (bluetooth::hci::OpCode::READ_REMOTE_VERSION_INFORMATION):
86 SendLinkLayerPacket(
87 model::packets::ReadRemoteVersionInformationBuilder::Create(
88 local_address, remote));
89 break;
90 case (bluetooth::hci::OpCode::READ_CLOCK_OFFSET):
91 SendLinkLayerPacket(model::packets::ReadClockOffsetBuilder::Create(
92 local_address, remote));
93 break;
94 default:
95 LOG_INFO("Dropping unhandled command 0x%04x",
96 static_cast<uint16_t>(opcode));
97 return bluetooth::hci::ErrorCode::UNKNOWN_HCI_COMMAND;
Myles Watsone22dde22019-01-18 11:42:33 -080098 }
Chienyuandb55f312019-10-31 14:01:28 +080099
Chienyuan3d8a8032019-11-01 18:04:07 +0800100 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -0800101}
102
Chienyuan3d8a8032019-11-01 18:04:07 +0800103bluetooth::hci::ErrorCode LinkLayerController::SendCommandToRemoteByHandle(
Chienyuan676cefe2019-11-22 16:46:24 +0800104 bluetooth::hci::OpCode opcode, bluetooth::packet::PacketView<true> args,
105 uint16_t handle) {
Myles Watsone22dde22019-01-18 11:42:33 -0800106 // TODO: Handle LE connections
Myles Watson96723532019-09-02 14:52:46 -0700107 if (!connections_.HasHandle(handle)) {
Chienyuan3d8a8032019-11-01 18:04:07 +0800108 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Myles Watsone22dde22019-01-18 11:42:33 -0800109 }
Myles Watsone066df42019-11-13 14:39:18 -0800110 return SendCommandToRemoteByAddress(opcode, args,
111 connections_.GetAddress(handle));
Myles Watsone22dde22019-01-18 11:42:33 -0800112}
113
Chienyuan85db6ee2019-11-21 22:07:09 +0800114hci::Status LinkLayerController::SendAclToRemote(
115 bluetooth::hci::AclPacketView acl_packet) {
Myles Watsone22dde22019-01-18 11:42:33 -0800116 uint16_t handle = acl_packet.GetHandle();
Myles Watson96723532019-09-02 14:52:46 -0700117 if (!connections_.HasHandle(handle)) {
Myles Watsone22dde22019-01-18 11:42:33 -0800118 return hci::Status::UNKNOWN_CONNECTION;
119 }
120
Myles Watson96723532019-09-02 14:52:46 -0700121 Address my_address = properties_.GetAddress();
122 Address destination = connections_.GetAddress(handle);
123 if (connections_.GetOwnAddressType(handle) != 0) { // If it's not public, it must be LE
124 my_address = properties_.GetLeAddress();
125 }
Myles Watsone22dde22019-01-18 11:42:33 -0800126
Myles Watson1a0a0da2019-10-17 11:36:33 -0700127 LOG_INFO("%s(%s): handle 0x%x size %d", __func__, properties_.GetAddress().ToString().c_str(), handle,
Myles Watsone22dde22019-01-18 11:42:33 -0800128 static_cast<int>(acl_packet.size()));
129
Myles Watson8fe710e2019-09-05 09:01:00 -0700130 ScheduleTask(milliseconds(5), [this, handle]() {
Chienyuanc27da092019-11-20 19:29:43 +0800131 std::vector<bluetooth::hci::CompletedPackets> completed_packets;
132 bluetooth::hci::CompletedPackets cp;
133 cp.connection_handle_ = handle;
134 cp.host_num_of_completed_packets_ = kNumCommandPackets;
135 completed_packets.push_back(cp);
136 auto packet = bluetooth::hci::NumberOfCompletedPacketsBuilder::Create(
137 completed_packets);
Chienyuan3d8a8032019-11-01 18:04:07 +0800138 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800139 });
Chienyuandb55f312019-10-31 14:01:28 +0800140
141 auto acl_payload = acl_packet.GetPayload();
142
143 std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
144 std::make_unique<bluetooth::packet::RawBuilder>();
145 std::vector<uint8_t> payload_bytes(acl_payload.begin(), acl_payload.end());
146
147 uint16_t first_two_bytes =
148 static_cast<uint16_t>(acl_packet.GetHandle()) +
Chienyuan85db6ee2019-11-21 22:07:09 +0800149 (static_cast<uint16_t>(acl_packet.GetPacketBoundaryFlag()) << 12) +
150 (static_cast<uint16_t>(acl_packet.GetBroadcastFlag()) << 14);
Chienyuandb55f312019-10-31 14:01:28 +0800151 raw_builder_ptr->AddOctets2(first_two_bytes);
152 raw_builder_ptr->AddOctets2(static_cast<uint16_t>(payload_bytes.size()));
153 raw_builder_ptr->AddOctets(payload_bytes);
154
155 auto acl = model::packets::AclPacketBuilder::Create(
156 my_address, destination, std::move(raw_builder_ptr));
157
158 SendLinkLayerPacket(std::move(acl));
Myles Watsone22dde22019-01-18 11:42:33 -0800159 return hci::Status::SUCCESS;
160}
161
Chienyuandb55f312019-10-31 14:01:28 +0800162void LinkLayerController::IncomingPacket(
163 model::packets::LinkLayerPacketView incoming) {
164 ASSERT(incoming.IsValid());
165
Myles Watsone22dde22019-01-18 11:42:33 -0800166 // TODO: Resolvable private addresses?
167 if (incoming.GetDestinationAddress() != properties_.GetAddress() &&
168 incoming.GetDestinationAddress() != properties_.GetLeAddress() &&
169 incoming.GetDestinationAddress() != Address::kEmpty) {
170 // Drop packets not addressed to me
171 return;
172 }
173
174 switch (incoming.GetType()) {
Chienyuandb55f312019-10-31 14:01:28 +0800175 case model::packets::PacketType::ACL:
Myles Watsone22dde22019-01-18 11:42:33 -0800176 IncomingAclPacket(incoming);
177 break;
Chienyuandb55f312019-10-31 14:01:28 +0800178 case model::packets::PacketType::DISCONNECT:
Myles Watsone22dde22019-01-18 11:42:33 -0800179 IncomingDisconnectPacket(incoming);
180 break;
Chienyuandb55f312019-10-31 14:01:28 +0800181 case model::packets::PacketType::ENCRYPT_CONNECTION:
Myles Watsone22dde22019-01-18 11:42:33 -0800182 IncomingEncryptConnection(incoming);
183 break;
Chienyuandb55f312019-10-31 14:01:28 +0800184 case model::packets::PacketType::ENCRYPT_CONNECTION_RESPONSE:
Myles Watsone22dde22019-01-18 11:42:33 -0800185 IncomingEncryptConnectionResponse(incoming);
186 break;
Chienyuandb55f312019-10-31 14:01:28 +0800187 case model::packets::PacketType::INQUIRY:
Myles Watsone22dde22019-01-18 11:42:33 -0800188 if (inquiry_scans_enabled_) {
189 IncomingInquiryPacket(incoming);
190 }
191 break;
Chienyuandb55f312019-10-31 14:01:28 +0800192 case model::packets::PacketType::INQUIRY_RESPONSE:
Myles Watsone22dde22019-01-18 11:42:33 -0800193 IncomingInquiryResponsePacket(incoming);
194 break;
Chienyuandb55f312019-10-31 14:01:28 +0800195 case model::packets::PacketType::IO_CAPABILITY_REQUEST:
Myles Watsone22dde22019-01-18 11:42:33 -0800196 IncomingIoCapabilityRequestPacket(incoming);
197 break;
Myles Watsone066df42019-11-13 14:39:18 -0800198 case model::packets::PacketType::IO_CAPABILITY_RESPONSE:
199 IncomingIoCapabilityResponsePacket(incoming);
200 break;
Chienyuandb55f312019-10-31 14:01:28 +0800201 case model::packets::PacketType::IO_CAPABILITY_NEGATIVE_RESPONSE:
Myles Watsone22dde22019-01-18 11:42:33 -0800202 IncomingIoCapabilityNegativeResponsePacket(incoming);
203 break;
Chienyuandb55f312019-10-31 14:01:28 +0800204 case model::packets::PacketType::LE_ADVERTISEMENT:
Myles Watsone22dde22019-01-18 11:42:33 -0800205 if (le_scan_enable_ || le_connect_) {
206 IncomingLeAdvertisementPacket(incoming);
207 }
208 break;
Chienyuandb55f312019-10-31 14:01:28 +0800209 case model::packets::PacketType::LE_CONNECT:
Myles Watson96723532019-09-02 14:52:46 -0700210 IncomingLeConnectPacket(incoming);
211 break;
Chienyuandb55f312019-10-31 14:01:28 +0800212 case model::packets::PacketType::LE_CONNECT_COMPLETE:
Myles Watson96723532019-09-02 14:52:46 -0700213 IncomingLeConnectCompletePacket(incoming);
214 break;
Chienyuandb55f312019-10-31 14:01:28 +0800215 case model::packets::PacketType::LE_SCAN:
Myles Watsone22dde22019-01-18 11:42:33 -0800216 // TODO: Check Advertising flags and see if we are scannable.
217 IncomingLeScanPacket(incoming);
218 break;
Chienyuandb55f312019-10-31 14:01:28 +0800219 case model::packets::PacketType::LE_SCAN_RESPONSE:
Myles Watsone22dde22019-01-18 11:42:33 -0800220 if (le_scan_enable_ && le_scan_type_ == 1) {
221 IncomingLeScanResponsePacket(incoming);
222 }
223 break;
Chienyuandb55f312019-10-31 14:01:28 +0800224 case model::packets::PacketType::PAGE:
Myles Watsone22dde22019-01-18 11:42:33 -0800225 if (page_scans_enabled_) {
226 IncomingPagePacket(incoming);
227 }
228 break;
Chienyuandb55f312019-10-31 14:01:28 +0800229 case model::packets::PacketType::PAGE_RESPONSE:
Chienyuan Huang85471e42019-11-06 12:52:58 +0000230 IncomingPageResponsePacket(incoming);
231 break;
Chienyuandb55f312019-10-31 14:01:28 +0800232 case model::packets::PacketType::PAGE_REJECT:
233 IncomingPageRejectPacket(incoming);
234 break;
Myles Watsone066df42019-11-13 14:39:18 -0800235 case (model::packets::PacketType::REMOTE_NAME_REQUEST):
236 IncomingRemoteNameRequest(incoming);
237 break;
238 case (model::packets::PacketType::REMOTE_NAME_REQUEST_RESPONSE):
239 IncomingRemoteNameRequestResponse(incoming);
240 break;
241 case (model::packets::PacketType::READ_REMOTE_SUPPORTED_FEATURES):
242 IncomingReadRemoteSupportedFeatures(incoming);
243 break;
244 case (model::packets::PacketType::READ_REMOTE_SUPPORTED_FEATURES_RESPONSE):
245 IncomingReadRemoteSupportedFeaturesResponse(incoming);
246 break;
247 case (model::packets::PacketType::READ_REMOTE_LMP_FEATURES):
248 IncomingReadRemoteLmpFeatures(incoming);
249 break;
250 case (model::packets::PacketType::READ_REMOTE_LMP_FEATURES_RESPONSE):
251 IncomingReadRemoteLmpFeaturesResponse(incoming);
252 break;
253 case (model::packets::PacketType::READ_REMOTE_EXTENDED_FEATURES):
254 IncomingReadRemoteExtendedFeatures(incoming);
255 break;
256 case (model::packets::PacketType::READ_REMOTE_EXTENDED_FEATURES_RESPONSE):
257 IncomingReadRemoteExtendedFeaturesResponse(incoming);
258 break;
259 case (model::packets::PacketType::READ_REMOTE_VERSION_INFORMATION):
260 IncomingReadRemoteVersion(incoming);
261 break;
262 case (model::packets::PacketType::READ_REMOTE_VERSION_INFORMATION_RESPONSE):
263 IncomingReadRemoteVersionResponse(incoming);
264 break;
265 case (model::packets::PacketType::READ_CLOCK_OFFSET):
266 IncomingReadClockOffset(incoming);
267 break;
268 case (model::packets::PacketType::READ_CLOCK_OFFSET_RESPONSE):
269 IncomingReadClockOffsetResponse(incoming);
Myles Watsone22dde22019-01-18 11:42:33 -0800270 break;
271 default:
Myles Watsone066df42019-11-13 14:39:18 -0800272 LOG_WARN("Dropping unhandled packet of type %s",
273 model::packets::PacketTypeText(incoming.GetType()).c_str());
Myles Watsone22dde22019-01-18 11:42:33 -0800274 }
275}
276
Chienyuandb55f312019-10-31 14:01:28 +0800277void LinkLayerController::IncomingAclPacket(
278 model::packets::LinkLayerPacketView incoming) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700279 LOG_INFO("Acl Packet %s -> %s", incoming.GetSourceAddress().ToString().c_str(),
Myles Watsone22dde22019-01-18 11:42:33 -0800280 incoming.GetDestinationAddress().ToString().c_str());
Chienyuandb55f312019-10-31 14:01:28 +0800281
282 auto acl = model::packets::AclPacketView::Create(incoming);
283 ASSERT(acl.IsValid());
284 auto payload = acl.GetPayload();
285 std::shared_ptr<std::vector<uint8_t>> payload_bytes =
286 std::make_shared<std::vector<uint8_t>>(payload.begin(), payload.end());
287
Chienyuan85db6ee2019-11-21 22:07:09 +0800288 bluetooth::hci::PacketView<bluetooth::hci::kLittleEndian> raw_packet(
289 payload_bytes);
290 auto acl_view = bluetooth::hci::AclPacketView::Create(raw_packet);
291 ASSERT(acl_view.IsValid());
292
Myles Watson1a0a0da2019-10-17 11:36:33 -0700293 LOG_INFO("%s: remote handle 0x%x size %d", __func__, acl_view.GetHandle(), static_cast<int>(acl_view.size()));
Myles Watson96723532019-09-02 14:52:46 -0700294 uint16_t local_handle = connections_.GetHandle(incoming.GetSourceAddress());
Myles Watson1a0a0da2019-10-17 11:36:33 -0700295 LOG_INFO("%s: local handle 0x%x", __func__, local_handle);
Myles Watsone22dde22019-01-18 11:42:33 -0800296
Chienyuan85db6ee2019-11-21 22:07:09 +0800297 std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
298 std::make_unique<bluetooth::packet::RawBuilder>();
299 std::vector<uint8_t> payload_data(acl_view.GetPayload().begin(),
300 acl_view.GetPayload().end());
301 raw_builder_ptr->AddOctets(payload_data);
302
303 auto acl_packet = bluetooth::hci::AclPacketBuilder::Create(
304 local_handle, acl_view.GetPacketBoundaryFlag(),
305 acl_view.GetBroadcastFlag(), std::move(raw_builder_ptr));
306
307 send_acl_(std::move(acl_packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800308}
309
Myles Watsone066df42019-11-13 14:39:18 -0800310void LinkLayerController::IncomingRemoteNameRequest(
311 model::packets::LinkLayerPacketView packet) {
312 auto view = model::packets::RemoteNameRequestView::Create(packet);
313 ASSERT(view.IsValid());
Chienyuandb55f312019-10-31 14:01:28 +0800314
Myles Watsone066df42019-11-13 14:39:18 -0800315 SendLinkLayerPacket(model::packets::RemoteNameRequestResponseBuilder::Create(
316 packet.GetDestinationAddress(), packet.GetSourceAddress(),
317 properties_.GetName()));
318}
Myles Watsone22dde22019-01-18 11:42:33 -0800319
Myles Watsone066df42019-11-13 14:39:18 -0800320void LinkLayerController::IncomingRemoteNameRequestResponse(
321 model::packets::LinkLayerPacketView packet) {
322 auto view = model::packets::RemoteNameRequestResponseView::Create(packet);
323 ASSERT(view.IsValid());
324
325 send_event_(bluetooth::hci::RemoteNameRequestCompleteBuilder::Create(
326 bluetooth::hci::ErrorCode::SUCCESS, packet.GetSourceAddress(),
327 view.GetName()));
328}
329
330void LinkLayerController::IncomingReadRemoteLmpFeatures(
331 model::packets::LinkLayerPacketView packet) {
332 SendLinkLayerPacket(
333 model::packets::ReadRemoteLmpFeaturesResponseBuilder::Create(
334 packet.GetDestinationAddress(), packet.GetSourceAddress(),
335 properties_.GetExtendedFeatures(1)));
336}
337
338void LinkLayerController::IncomingReadRemoteLmpFeaturesResponse(
339 model::packets::LinkLayerPacketView packet) {
340 auto view = model::packets::ReadRemoteLmpFeaturesResponseView::Create(packet);
341 ASSERT(view.IsValid());
342 send_event_(
343 bluetooth::hci::RemoteHostSupportedFeaturesNotificationBuilder::Create(
344 packet.GetSourceAddress(), view.GetFeatures()));
345}
346
347void LinkLayerController::IncomingReadRemoteSupportedFeatures(
348 model::packets::LinkLayerPacketView packet) {
349 SendLinkLayerPacket(
350 model::packets::ReadRemoteSupportedFeaturesResponseBuilder::Create(
351 packet.GetDestinationAddress(), packet.GetSourceAddress(),
352 properties_.GetSupportedFeatures()));
353}
354
355void LinkLayerController::IncomingReadRemoteSupportedFeaturesResponse(
356 model::packets::LinkLayerPacketView packet) {
357 auto view =
358 model::packets::ReadRemoteSupportedFeaturesResponseView::Create(packet);
359 ASSERT(view.IsValid());
360 Address source = packet.GetSourceAddress();
361 if (connections_.IsDeviceConnected(source)) {
362 uint16_t handle = connections_.GetHandle(source);
363 send_event_(
364 bluetooth::hci::ReadRemoteSupportedFeaturesCompleteBuilder::Create(
365 bluetooth::hci::ErrorCode::SUCCESS, handle, view.GetFeatures()));
366 } else {
367 LOG_INFO("Discarding response from a disconnected device %s",
368 source.ToString().c_str());
Myles Watsone22dde22019-01-18 11:42:33 -0800369 }
Myles Watsone066df42019-11-13 14:39:18 -0800370}
Chienyuandb55f312019-10-31 14:01:28 +0800371
Myles Watsone066df42019-11-13 14:39:18 -0800372void LinkLayerController::IncomingReadRemoteExtendedFeatures(
373 model::packets::LinkLayerPacketView packet) {
374 auto view = model::packets::ReadRemoteExtendedFeaturesView::Create(packet);
375 ASSERT(view.IsValid());
376 uint8_t page_number = view.GetPageNumber();
377 uint8_t error_code = static_cast<uint8_t>(bluetooth::hci::ErrorCode::SUCCESS);
378 if (page_number > properties_.GetExtendedFeaturesMaximumPageNumber()) {
379 error_code = static_cast<uint8_t>(
380 bluetooth::hci::ErrorCode::INVALID_LMP_OR_LL_PARAMETERS);
Chienyuandb55f312019-10-31 14:01:28 +0800381 }
Myles Watsone066df42019-11-13 14:39:18 -0800382 SendLinkLayerPacket(
383 model::packets::ReadRemoteExtendedFeaturesResponseBuilder::Create(
384 packet.GetDestinationAddress(), packet.GetSourceAddress(), error_code,
385 page_number, properties_.GetExtendedFeaturesMaximumPageNumber(),
386 properties_.GetExtendedFeatures(view.GetPageNumber())));
387}
Chienyuandb55f312019-10-31 14:01:28 +0800388
Myles Watsone066df42019-11-13 14:39:18 -0800389void LinkLayerController::IncomingReadRemoteExtendedFeaturesResponse(
390 model::packets::LinkLayerPacketView packet) {
391 auto view =
392 model::packets::ReadRemoteExtendedFeaturesResponseView::Create(packet);
393 ASSERT(view.IsValid());
394 Address source = packet.GetSourceAddress();
395 if (connections_.IsDeviceConnected(source)) {
396 uint16_t handle = connections_.GetHandle(packet.GetSourceAddress());
397 send_event_(
398 bluetooth::hci::ReadRemoteExtendedFeaturesCompleteBuilder::Create(
399 static_cast<bluetooth::hci::ErrorCode>(view.GetStatus()), handle,
400 view.GetPageNumber(), view.GetMaxPageNumber(), view.GetFeatures()));
401 } else {
402 LOG_INFO("Discarding response from a disconnected device %s",
403 source.ToString().c_str());
404 }
405}
Chienyuandb55f312019-10-31 14:01:28 +0800406
Myles Watsone066df42019-11-13 14:39:18 -0800407void LinkLayerController::IncomingReadRemoteVersion(
408 model::packets::LinkLayerPacketView packet) {
409 SendLinkLayerPacket(
410 model::packets::ReadRemoteSupportedFeaturesResponseBuilder::Create(
411 packet.GetDestinationAddress(), packet.GetSourceAddress(),
412 properties_.GetSupportedFeatures()));
413}
414
415void LinkLayerController::IncomingReadRemoteVersionResponse(
416 model::packets::LinkLayerPacketView packet) {
417 auto view =
418 model::packets::ReadRemoteVersionInformationResponseView::Create(packet);
419 ASSERT(view.IsValid());
420 Address source = packet.GetSourceAddress();
421 if (connections_.IsDeviceConnected(source)) {
422 uint16_t handle = connections_.GetHandle(packet.GetSourceAddress());
423 send_event_(
424 bluetooth::hci::ReadRemoteVersionInformationCompleteBuilder::Create(
425 bluetooth::hci::ErrorCode::SUCCESS, handle, view.GetLmpVersion(),
426 view.GetManufacturerName(), view.GetLmpSubversion()));
427 } else {
428 LOG_INFO("Discarding response from a disconnected device %s",
429 source.ToString().c_str());
430 }
431}
432
433void LinkLayerController::IncomingReadClockOffset(
434 model::packets::LinkLayerPacketView packet) {
435 SendLinkLayerPacket(model::packets::ReadClockOffsetResponseBuilder::Create(
436 packet.GetDestinationAddress(), packet.GetSourceAddress(),
437 properties_.GetClockOffset()));
438}
439
440void LinkLayerController::IncomingReadClockOffsetResponse(
441 model::packets::LinkLayerPacketView packet) {
442 auto view = model::packets::ReadClockOffsetResponseView::Create(packet);
443 ASSERT(view.IsValid());
444 Address source = packet.GetSourceAddress();
445 if (connections_.IsDeviceConnected(source)) {
446 uint16_t handle = connections_.GetHandle(packet.GetSourceAddress());
447 send_event_(bluetooth::hci::ReadClockOffsetCompleteBuilder::Create(
448 bluetooth::hci::ErrorCode::SUCCESS, handle, view.GetOffset()));
449 } else {
450 LOG_INFO("Discarding response from a disconnected device %s",
451 source.ToString().c_str());
452 }
Myles Watsone22dde22019-01-18 11:42:33 -0800453}
454
Chienyuandb55f312019-10-31 14:01:28 +0800455void LinkLayerController::IncomingDisconnectPacket(
456 model::packets::LinkLayerPacketView incoming) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700457 LOG_INFO("Disconnect Packet");
Chienyuandb55f312019-10-31 14:01:28 +0800458 auto disconnect = model::packets::DisconnectView::Create(incoming);
459 ASSERT(disconnect.IsValid());
460
Myles Watsone22dde22019-01-18 11:42:33 -0800461 Address peer = incoming.GetSourceAddress();
Myles Watson96723532019-09-02 14:52:46 -0700462 uint16_t handle = connections_.GetHandle(peer);
Myles Watsone22dde22019-01-18 11:42:33 -0800463 if (handle == acl::kReservedHandle) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700464 LOG_INFO("%s: Unknown connection @%s", __func__, peer.ToString().c_str());
Myles Watsone22dde22019-01-18 11:42:33 -0800465 return;
466 }
Myles Watson1a0a0da2019-10-17 11:36:33 -0700467 ASSERT_LOG(connections_.Disconnect(handle), "GetHandle() returned invalid handle %hx", handle);
Myles Watsone22dde22019-01-18 11:42:33 -0800468
469 uint8_t reason = disconnect.GetReason();
Myles Watson8fe710e2019-09-05 09:01:00 -0700470 ScheduleTask(milliseconds(20), [this, handle, reason]() { DisconnectCleanup(handle, reason); });
Myles Watsone22dde22019-01-18 11:42:33 -0800471}
472
Chienyuandb55f312019-10-31 14:01:28 +0800473void LinkLayerController::IncomingEncryptConnection(
474 model::packets::LinkLayerPacketView incoming) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700475 LOG_INFO("%s", __func__);
Chienyuandb55f312019-10-31 14:01:28 +0800476
Myles Watsone22dde22019-01-18 11:42:33 -0800477 // TODO: Check keys
478 Address peer = incoming.GetSourceAddress();
Myles Watson96723532019-09-02 14:52:46 -0700479 uint16_t handle = connections_.GetHandle(peer);
Myles Watsone22dde22019-01-18 11:42:33 -0800480 if (handle == acl::kReservedHandle) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700481 LOG_INFO("%s: Unknown connection @%s", __func__, peer.ToString().c_str());
Myles Watsone22dde22019-01-18 11:42:33 -0800482 return;
483 }
Myles Watsone066df42019-11-13 14:39:18 -0800484 send_event_(bluetooth::hci::EncryptionChangeBuilder::Create(
Chienyuan3d8a8032019-11-01 18:04:07 +0800485 bluetooth::hci::ErrorCode::SUCCESS, handle,
Myles Watsone066df42019-11-13 14:39:18 -0800486 bluetooth::hci::EncryptionEnabled::ON));
487
488 uint16_t count = security_manager_.ReadKey(peer);
489 if (count == 0) {
490 LOG_ERROR("NO KEY HERE for %s", peer.ToString().c_str());
491 return;
492 }
493 auto array = security_manager_.GetKey(peer);
494 std::vector<uint8_t> key_vec{array.begin(), array.end()};
Chienyuandb55f312019-10-31 14:01:28 +0800495 auto response = model::packets::EncryptConnectionResponseBuilder::Create(
Myles Watsone066df42019-11-13 14:39:18 -0800496 properties_.GetAddress(), peer, key_vec);
Chienyuandb55f312019-10-31 14:01:28 +0800497 SendLinkLayerPacket(std::move(response));
Myles Watsone22dde22019-01-18 11:42:33 -0800498}
499
Chienyuandb55f312019-10-31 14:01:28 +0800500void LinkLayerController::IncomingEncryptConnectionResponse(
501 model::packets::LinkLayerPacketView incoming) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700502 LOG_INFO("%s", __func__);
Myles Watsone22dde22019-01-18 11:42:33 -0800503 // TODO: Check keys
Myles Watson96723532019-09-02 14:52:46 -0700504 uint16_t handle = connections_.GetHandle(incoming.GetSourceAddress());
Myles Watsone22dde22019-01-18 11:42:33 -0800505 if (handle == acl::kReservedHandle) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700506 LOG_INFO("%s: Unknown connection @%s", __func__, incoming.GetSourceAddress().ToString().c_str());
Myles Watsone22dde22019-01-18 11:42:33 -0800507 return;
508 }
Chienyuan3d8a8032019-11-01 18:04:07 +0800509 auto packet = bluetooth::hci::EncryptionChangeBuilder::Create(
510 bluetooth::hci::ErrorCode::SUCCESS, handle,
511 bluetooth::hci::EncryptionEnabled::ON);
512 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800513}
514
Chienyuandb55f312019-10-31 14:01:28 +0800515void LinkLayerController::IncomingInquiryPacket(
516 model::packets::LinkLayerPacketView incoming) {
517 auto inquiry = model::packets::InquiryView::Create(incoming);
518 ASSERT(inquiry.IsValid());
Myles Watsone22dde22019-01-18 11:42:33 -0800519
Chienyuandb55f312019-10-31 14:01:28 +0800520 Address peer = incoming.GetSourceAddress();
Myles Watsone22dde22019-01-18 11:42:33 -0800521
Chienyuandb55f312019-10-31 14:01:28 +0800522 switch (inquiry.GetInquiryType()) {
523 case (model::packets::InquiryType::STANDARD): {
524 auto inquiry_response = model::packets::InquiryResponseBuilder::Create(
525 properties_.GetAddress(), peer,
526 properties_.GetPageScanRepetitionMode(),
527 properties_.GetClassOfDevice(), properties_.GetClockOffset());
528 SendLinkLayerPacket(std::move(inquiry_response));
529 } break;
530 case (model::packets::InquiryType::RSSI): {
531 auto inquiry_response =
532 model::packets::InquiryResponseWithRssiBuilder::Create(
533 properties_.GetAddress(), peer,
534 properties_.GetPageScanRepetitionMode(),
535 properties_.GetClassOfDevice(), properties_.GetClockOffset(),
536 GetRssi());
537 SendLinkLayerPacket(std::move(inquiry_response));
538 } break;
539 case (model::packets::InquiryType::EXTENDED): {
540 auto inquiry_response =
541 model::packets::ExtendedInquiryResponseBuilder::Create(
542 properties_.GetAddress(), peer,
543 properties_.GetPageScanRepetitionMode(),
544 properties_.GetClassOfDevice(), properties_.GetClockOffset(),
545 GetRssi(), properties_.GetExtendedInquiryData());
546 SendLinkLayerPacket(std::move(inquiry_response));
547
548 } break;
Myles Watsone22dde22019-01-18 11:42:33 -0800549 default:
Myles Watson1a0a0da2019-10-17 11:36:33 -0700550 LOG_WARN("Unhandled Incoming Inquiry of type %d", static_cast<int>(inquiry.GetType()));
Myles Watsone22dde22019-01-18 11:42:33 -0800551 return;
552 }
Chienyuandb55f312019-10-31 14:01:28 +0800553 // TODO: Send an Inquiry Response Notification Event 7.7.74
Myles Watsone22dde22019-01-18 11:42:33 -0800554}
555
Chienyuandb55f312019-10-31 14:01:28 +0800556void LinkLayerController::IncomingInquiryResponsePacket(
557 model::packets::LinkLayerPacketView incoming) {
558 auto basic_inquiry_response =
559 model::packets::BasicInquiryResponseView::Create(incoming);
560 ASSERT(basic_inquiry_response.IsValid());
Myles Watsone22dde22019-01-18 11:42:33 -0800561 std::vector<uint8_t> eir;
562
Chienyuandb55f312019-10-31 14:01:28 +0800563 switch (basic_inquiry_response.GetInquiryType()) {
564 case (model::packets::InquiryType::STANDARD): {
Myles Watsone22dde22019-01-18 11:42:33 -0800565 // TODO: Support multiple inquiries in the same packet.
Chienyuandb55f312019-10-31 14:01:28 +0800566 auto inquiry_response =
567 model::packets::InquiryResponseView::Create(basic_inquiry_response);
568 ASSERT(inquiry_response.IsValid());
Chienyuan3d8a8032019-11-01 18:04:07 +0800569
570 auto page_scan_repetition_mode =
571 (bluetooth::hci::PageScanRepetitionMode)
572 inquiry_response.GetPageScanRepetitionMode();
573
574 auto packet = bluetooth::hci::InquiryResultBuilder::Create(
575 0x01, inquiry_response.GetSourceAddress(), page_scan_repetition_mode,
Chienyuandb55f312019-10-31 14:01:28 +0800576 inquiry_response.GetClassOfDevice(),
577 inquiry_response.GetClockOffset());
Chienyuan3d8a8032019-11-01 18:04:07 +0800578
579 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800580 } break;
581
Chienyuandb55f312019-10-31 14:01:28 +0800582 case (model::packets::InquiryType::RSSI): {
Chienyuandb55f312019-10-31 14:01:28 +0800583 auto inquiry_response =
584 model::packets::InquiryResponseWithRssiView::Create(
585 basic_inquiry_response);
586 ASSERT(inquiry_response.IsValid());
Chienyuan3d8a8032019-11-01 18:04:07 +0800587
588 auto page_scan_repetition_mode =
589 (bluetooth::hci::PageScanRepetitionMode)
590 inquiry_response.GetPageScanRepetitionMode();
591
592 auto packet = bluetooth::hci::InquiryResultWithRssiBuilder::Create(
593 0x01, inquiry_response.GetSourceAddress(), page_scan_repetition_mode,
594 inquiry_response.GetClassOfDevice(),
595 inquiry_response.GetClockOffset(), inquiry_response.GetRssi());
596 send_event_(std::move(packet));
Chienyuandb55f312019-10-31 14:01:28 +0800597 } break;
Myles Watsone22dde22019-01-18 11:42:33 -0800598
Chienyuandb55f312019-10-31 14:01:28 +0800599 case (model::packets::InquiryType::EXTENDED): {
Chienyuandb55f312019-10-31 14:01:28 +0800600 auto inquiry_response =
601 model::packets::ExtendedInquiryResponseView::Create(
602 basic_inquiry_response);
603 ASSERT(inquiry_response.IsValid());
Chienyuan3d8a8032019-11-01 18:04:07 +0800604
605 std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
606 std::make_unique<bluetooth::packet::RawBuilder>();
Chienyuanc27da092019-11-20 19:29:43 +0800607 raw_builder_ptr->AddOctets1(kNumCommandPackets);
Chienyuan3d8a8032019-11-01 18:04:07 +0800608 raw_builder_ptr->AddAddress(inquiry_response.GetSourceAddress());
609 raw_builder_ptr->AddOctets1(inquiry_response.GetPageScanRepetitionMode());
610 raw_builder_ptr->AddOctets1(0x00); // _reserved_
611 auto class_of_device = inquiry_response.GetClassOfDevice();
612 for (unsigned int i = 0; i < class_of_device.kLength; i++) {
613 raw_builder_ptr->AddOctets1(class_of_device.cod[i]);
614 }
615 raw_builder_ptr->AddOctets2(inquiry_response.GetClockOffset());
616 raw_builder_ptr->AddOctets1(inquiry_response.GetRssi());
617 raw_builder_ptr->AddOctets(inquiry_response.GetExtendedData());
618
619 auto packet = bluetooth::hci::EventPacketBuilder::Create(
620 bluetooth::hci::EventCode::EXTENDED_INQUIRY_RESULT,
621 std::move(raw_builder_ptr));
622 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800623 } break;
624 default:
Chienyuandb55f312019-10-31 14:01:28 +0800625 LOG_WARN("Unhandled Incoming Inquiry Response of type %d",
626 static_cast<int>(basic_inquiry_response.GetInquiryType()));
Myles Watsone22dde22019-01-18 11:42:33 -0800627 }
628}
629
Chienyuandb55f312019-10-31 14:01:28 +0800630void LinkLayerController::IncomingIoCapabilityRequestPacket(
631 model::packets::LinkLayerPacketView incoming) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700632 LOG_DEBUG("%s", __func__);
Myles Watsone22dde22019-01-18 11:42:33 -0800633 if (!simple_pairing_mode_enabled_) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700634 LOG_WARN("%s: Only simple pairing mode is implemented", __func__);
Myles Watsone22dde22019-01-18 11:42:33 -0800635 return;
636 }
Chienyuan Huang85471e42019-11-06 12:52:58 +0000637
Chienyuandb55f312019-10-31 14:01:28 +0800638 auto request = model::packets::IoCapabilityRequestView::Create(incoming);
639 ASSERT(request.IsValid());
640
641 Address peer = incoming.GetSourceAddress();
Myles Watsone22dde22019-01-18 11:42:33 -0800642 uint8_t io_capability = request.GetIoCapability();
643 uint8_t oob_data_present = request.GetOobDataPresent();
644 uint8_t authentication_requirements = request.GetAuthenticationRequirements();
645
Myles Watson96723532019-09-02 14:52:46 -0700646 uint16_t handle = connections_.GetHandle(peer);
Myles Watsone22dde22019-01-18 11:42:33 -0800647 if (handle == acl::kReservedHandle) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700648 LOG_INFO("%s: Device not connected %s", __func__, peer.ToString().c_str());
Myles Watsone22dde22019-01-18 11:42:33 -0800649 return;
650 }
651
652 security_manager_.AuthenticationRequest(peer, handle);
653
654 security_manager_.SetPeerIoCapability(peer, io_capability, oob_data_present, authentication_requirements);
655
Chienyuan3d8a8032019-11-01 18:04:07 +0800656 auto packet = bluetooth::hci::IoCapabilityResponseBuilder::Create(
657 peer, static_cast<bluetooth::hci::IoCapability>(io_capability),
658 static_cast<bluetooth::hci::OobDataPresent>(oob_data_present),
659 static_cast<bluetooth::hci::AuthenticationRequirements>(
660 authentication_requirements));
661 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800662
663 StartSimplePairing(peer);
664}
665
Chienyuandb55f312019-10-31 14:01:28 +0800666void LinkLayerController::IncomingIoCapabilityResponsePacket(
667 model::packets::LinkLayerPacketView incoming) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700668 LOG_DEBUG("%s", __func__);
Chienyuandb55f312019-10-31 14:01:28 +0800669
670 auto response = model::packets::IoCapabilityResponseView::Create(incoming);
671 ASSERT(response.IsValid());
672
Myles Watsone22dde22019-01-18 11:42:33 -0800673 Address peer = incoming.GetSourceAddress();
674 uint8_t io_capability = response.GetIoCapability();
675 uint8_t oob_data_present = response.GetOobDataPresent();
676 uint8_t authentication_requirements = response.GetAuthenticationRequirements();
677
Chienyuandb55f312019-10-31 14:01:28 +0800678 security_manager_.SetPeerIoCapability(peer, io_capability, oob_data_present,
679 authentication_requirements);
Myles Watsone22dde22019-01-18 11:42:33 -0800680
Chienyuan3d8a8032019-11-01 18:04:07 +0800681 auto packet = bluetooth::hci::IoCapabilityResponseBuilder::Create(
682 peer, static_cast<bluetooth::hci::IoCapability>(io_capability),
683 static_cast<bluetooth::hci::OobDataPresent>(oob_data_present),
684 static_cast<bluetooth::hci::AuthenticationRequirements>(
685 authentication_requirements));
686 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800687
688 PairingType pairing_type = security_manager_.GetSimplePairingType();
689 if (pairing_type != PairingType::INVALID) {
Chienyuandb55f312019-10-31 14:01:28 +0800690 ScheduleTask(milliseconds(5), [this, peer, pairing_type]() {
691 AuthenticateRemoteStage1(peer, pairing_type);
692 });
Myles Watsone22dde22019-01-18 11:42:33 -0800693 } else {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700694 LOG_INFO("%s: Security Manager returned INVALID", __func__);
Myles Watsone22dde22019-01-18 11:42:33 -0800695 }
696}
697
Chienyuandb55f312019-10-31 14:01:28 +0800698void LinkLayerController::IncomingIoCapabilityNegativeResponsePacket(
699 model::packets::LinkLayerPacketView incoming) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700700 LOG_DEBUG("%s", __func__);
Myles Watsone22dde22019-01-18 11:42:33 -0800701 Address peer = incoming.GetSourceAddress();
702
Myles Watson1a0a0da2019-10-17 11:36:33 -0700703 ASSERT(security_manager_.GetAuthenticationAddress() == peer);
Myles Watsone22dde22019-01-18 11:42:33 -0800704
705 security_manager_.InvalidateIoCapabilities();
706}
707
Chienyuandb55f312019-10-31 14:01:28 +0800708void LinkLayerController::IncomingLeAdvertisementPacket(
709 model::packets::LinkLayerPacketView incoming) {
Myles Watsone22dde22019-01-18 11:42:33 -0800710 // TODO: Handle multiple advertisements per packet.
711
Myles Watson96723532019-09-02 14:52:46 -0700712 Address address = incoming.GetSourceAddress();
Chienyuandb55f312019-10-31 14:01:28 +0800713 auto advertisement = model::packets::LeAdvertisementView::Create(incoming);
714 ASSERT(advertisement.IsValid());
715 auto adv_type = static_cast<LeAdvertisement::AdvertisementType>(
716 advertisement.GetAdvertisementType());
717 auto address_type =
718 static_cast<LeAdvertisement::AddressType>(advertisement.GetAddressType());
Myles Watsone22dde22019-01-18 11:42:33 -0800719
720 if (le_scan_enable_) {
Chienyuandb55f312019-10-31 14:01:28 +0800721 vector<uint8_t> ad = advertisement.GetData();
722
Chienyuan3d8a8032019-11-01 18:04:07 +0800723 std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
724 std::make_unique<bluetooth::packet::RawBuilder>();
725 raw_builder_ptr->AddOctets1(
726 static_cast<uint8_t>(bluetooth::hci::SubeventCode::ADVERTISING_REPORT));
727 raw_builder_ptr->AddOctets1(0x01); // num reports
728 raw_builder_ptr->AddOctets1(static_cast<uint8_t>(adv_type));
729 raw_builder_ptr->AddOctets1(static_cast<uint8_t>(address_type));
730 raw_builder_ptr->AddAddress(address);
731 raw_builder_ptr->AddOctets1(ad.size());
732 raw_builder_ptr->AddOctets(ad);
733 raw_builder_ptr->AddOctets1(GetRssi());
734 auto packet = bluetooth::hci::EventPacketBuilder::Create(
735 bluetooth::hci::EventCode::LE_META_EVENT, std::move(raw_builder_ptr));
736 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800737 }
738
Myles Watsone22dde22019-01-18 11:42:33 -0800739 // Active scanning
740 if (le_scan_enable_ && le_scan_type_ == 1) {
Chienyuandb55f312019-10-31 14:01:28 +0800741 auto to_send = model::packets::LeScanBuilder::Create(
742 properties_.GetLeAddress(), address);
743 SendLeLinkLayerPacket(std::move(to_send));
Myles Watsone22dde22019-01-18 11:42:33 -0800744 }
Myles Watson96723532019-09-02 14:52:46 -0700745
746 // Connect
747 if ((le_connect_ && le_peer_address_ == address && le_peer_address_type_ == static_cast<uint8_t>(address_type) &&
748 (adv_type == LeAdvertisement::AdvertisementType::ADV_IND ||
749 adv_type == LeAdvertisement::AdvertisementType::ADV_DIRECT_IND)) ||
750 (LeWhiteListContainsDevice(address, static_cast<uint8_t>(address_type)))) {
751 if (!connections_.CreatePendingLeConnection(incoming.GetSourceAddress(), static_cast<uint8_t>(address_type))) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700752 LOG_WARN("%s: CreatePendingLeConnection failed for connection to %s (type %hhx)", __func__,
Myles Watson96723532019-09-02 14:52:46 -0700753 incoming.GetSourceAddress().ToString().c_str(), address_type);
754 }
Myles Watson1a0a0da2019-10-17 11:36:33 -0700755 LOG_INFO("%s: connecting to %s (type %hhx)", __func__, incoming.GetSourceAddress().ToString().c_str(),
Myles Watson96723532019-09-02 14:52:46 -0700756 address_type);
757 le_connect_ = false;
758 le_scan_enable_ = false;
759
Chienyuandb55f312019-10-31 14:01:28 +0800760 auto to_send = model::packets::LeConnectBuilder::Create(
761 properties_.GetLeAddress(), incoming.GetSourceAddress(),
762 le_connection_interval_min_, le_connection_interval_max_,
763 le_connection_latency_, le_connection_supervision_timeout_,
764 static_cast<uint8_t>(le_address_type_));
765
766 SendLeLinkLayerPacket(std::move(to_send));
Myles Watson96723532019-09-02 14:52:46 -0700767 }
768}
769
770void LinkLayerController::HandleLeConnection(Address address, uint8_t address_type, uint8_t own_address_type,
771 uint8_t role, uint16_t connection_interval, uint16_t connection_latency,
772 uint16_t supervision_timeout) {
773 // TODO: Choose between LeConnectionComplete and LeEnhancedConnectionComplete
774 uint16_t handle = connections_.CreateLeConnection(address, address_type, own_address_type);
775 if (handle == acl::kReservedHandle) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700776 LOG_WARN("%s: No pending connection for connection from %s (type %hhx)", __func__, address.ToString().c_str(),
777 address_type);
Myles Watson96723532019-09-02 14:52:46 -0700778 return;
779 }
Chienyuan3d8a8032019-11-01 18:04:07 +0800780 auto packet = bluetooth::hci::LeConnectionCompleteBuilder::Create(
781 bluetooth::hci::ErrorCode::SUCCESS, handle,
782 static_cast<bluetooth::hci::Role>(role),
783 static_cast<bluetooth::hci::AddressType>(address_type), address,
784 connection_interval, connection_latency, supervision_timeout,
785 static_cast<bluetooth::hci::MasterClockAccuracy>(0x00));
786 send_event_(std::move(packet));
Myles Watson96723532019-09-02 14:52:46 -0700787}
788
Chienyuandb55f312019-10-31 14:01:28 +0800789void LinkLayerController::IncomingLeConnectPacket(
790 model::packets::LinkLayerPacketView incoming) {
791 auto connect = model::packets::LeConnectView::Create(incoming);
792 ASSERT(connect.IsValid());
Myles Watson96723532019-09-02 14:52:46 -0700793 uint16_t connection_interval = (connect.GetLeConnectionIntervalMax() + connect.GetLeConnectionIntervalMin()) / 2;
794 if (!connections_.CreatePendingLeConnection(incoming.GetSourceAddress(),
795 static_cast<uint8_t>(connect.GetAddressType()))) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700796 LOG_WARN("%s: CreatePendingLeConnection failed for connection from %s (type %hhx)", __func__,
Myles Watson96723532019-09-02 14:52:46 -0700797 incoming.GetSourceAddress().ToString().c_str(), connect.GetAddressType());
798 return;
799 }
800 HandleLeConnection(incoming.GetSourceAddress(), static_cast<uint8_t>(connect.GetAddressType()),
801 static_cast<uint8_t>(properties_.GetLeAdvertisingOwnAddressType()),
802 static_cast<uint8_t>(hci::Role::SLAVE), connection_interval, connect.GetLeConnectionLatency(),
803 connect.GetLeConnectionSupervisionTimeout());
Chienyuandb55f312019-10-31 14:01:28 +0800804
805 auto to_send = model::packets::LeConnectCompleteBuilder::Create(
806 incoming.GetDestinationAddress(), incoming.GetSourceAddress(),
807 connection_interval, connect.GetLeConnectionLatency(),
808 connect.GetLeConnectionSupervisionTimeout(),
809 properties_.GetLeAdvertisingOwnAddressType());
810 SendLeLinkLayerPacket(std::move(to_send));
Myles Watson96723532019-09-02 14:52:46 -0700811}
812
Chienyuandb55f312019-10-31 14:01:28 +0800813void LinkLayerController::IncomingLeConnectCompletePacket(
814 model::packets::LinkLayerPacketView incoming) {
815 auto complete = model::packets::LeConnectCompleteView::Create(incoming);
816 ASSERT(complete.IsValid());
Myles Watson96723532019-09-02 14:52:46 -0700817 HandleLeConnection(incoming.GetSourceAddress(), static_cast<uint8_t>(complete.GetAddressType()),
818 static_cast<uint8_t>(le_address_type_), static_cast<uint8_t>(hci::Role::MASTER),
819 complete.GetLeConnectionInterval(), complete.GetLeConnectionLatency(),
820 complete.GetLeConnectionSupervisionTimeout());
Myles Watsone22dde22019-01-18 11:42:33 -0800821}
822
Chienyuandb55f312019-10-31 14:01:28 +0800823void LinkLayerController::IncomingLeScanPacket(
824 model::packets::LinkLayerPacketView incoming) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700825 LOG_INFO("LE Scan Packet");
Chienyuandb55f312019-10-31 14:01:28 +0800826
827 auto to_send = model::packets::LeScanResponseBuilder::Create(
828 properties_.GetLeAddress(), incoming.GetSourceAddress(),
829 static_cast<model::packets::AddressType>(properties_.GetLeAddressType()),
830 static_cast<model::packets::AdvertisementType>(
831 properties_.GetLeAdvertisementType()),
Myles Watsone22dde22019-01-18 11:42:33 -0800832 properties_.GetLeScanResponse());
Chienyuandb55f312019-10-31 14:01:28 +0800833
834 SendLeLinkLayerPacket(std::move(to_send));
Myles Watsone22dde22019-01-18 11:42:33 -0800835}
836
Chienyuandb55f312019-10-31 14:01:28 +0800837void LinkLayerController::IncomingLeScanResponsePacket(
838 model::packets::LinkLayerPacketView incoming) {
839 auto scan_response = model::packets::LeScanResponseView::Create(incoming);
840 ASSERT(scan_response.IsValid());
841 vector<uint8_t> ad = scan_response.GetData();
842 auto adv_type = static_cast<LeAdvertisement::AdvertisementType>(
843 scan_response.GetAdvertisementType());
844 auto address_type =
845 static_cast<LeAdvertisement::AddressType>(scan_response.GetAddressType());
Myles Watsone22dde22019-01-18 11:42:33 -0800846
Chienyuan3d8a8032019-11-01 18:04:07 +0800847 std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
848 std::make_unique<bluetooth::packet::RawBuilder>();
849 raw_builder_ptr->AddOctets1(
850 static_cast<uint8_t>(bluetooth::hci::SubeventCode::ADVERTISING_REPORT));
851 raw_builder_ptr->AddOctets1(0x01); // num reports
852 raw_builder_ptr->AddOctets1(static_cast<uint8_t>(adv_type));
853 raw_builder_ptr->AddOctets1(static_cast<uint8_t>(address_type));
854 raw_builder_ptr->AddAddress(incoming.GetSourceAddress());
855 raw_builder_ptr->AddOctets1(ad.size());
856 raw_builder_ptr->AddOctets(ad);
857 raw_builder_ptr->AddOctets1(GetRssi());
858 auto packet = bluetooth::hci::EventPacketBuilder::Create(
859 bluetooth::hci::EventCode::LE_META_EVENT, std::move(raw_builder_ptr));
860 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800861}
862
Chienyuandb55f312019-10-31 14:01:28 +0800863void LinkLayerController::IncomingPagePacket(
864 model::packets::LinkLayerPacketView incoming) {
865 auto page = model::packets::PageView::Create(incoming);
866 ASSERT(page.IsValid());
Myles Watson1a0a0da2019-10-17 11:36:33 -0700867 LOG_INFO("%s from %s", __func__, incoming.GetSourceAddress().ToString().c_str());
Myles Watsone22dde22019-01-18 11:42:33 -0800868
Myles Watsone066df42019-11-13 14:39:18 -0800869 if (!connections_.CreatePendingConnection(
870 incoming.GetSourceAddress(), properties_.GetAuthenticationEnable())) {
Myles Watsone22dde22019-01-18 11:42:33 -0800871 // Send a response to indicate that we're busy, or drop the packet?
Myles Watson1a0a0da2019-10-17 11:36:33 -0700872 LOG_WARN("%s: Failed to create a pending connection for %s", __func__,
Myles Watson96723532019-09-02 14:52:46 -0700873 incoming.GetSourceAddress().ToString().c_str());
Myles Watsone22dde22019-01-18 11:42:33 -0800874 }
875
Chienyuan3d8a8032019-11-01 18:04:07 +0800876 bluetooth::hci::Address source_address;
877 bluetooth::hci::Address::FromString(page.GetSourceAddress().ToString(),
878 source_address);
879
880 auto packet = bluetooth::hci::ConnectionRequestBuilder::Create(
881 source_address, page.GetClassOfDevice(),
882 bluetooth::hci::ConnectionRequestLinkType::ACL);
883
884 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800885}
886
Chienyuandb55f312019-10-31 14:01:28 +0800887void LinkLayerController::IncomingPageRejectPacket(
888 model::packets::LinkLayerPacketView incoming) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700889 LOG_INFO("%s: %s", __func__, incoming.GetSourceAddress().ToString().c_str());
Chienyuandb55f312019-10-31 14:01:28 +0800890 auto reject = model::packets::PageRejectView::Create(incoming);
891 ASSERT(reject.IsValid());
Myles Watson1a0a0da2019-10-17 11:36:33 -0700892 LOG_INFO("%s: Sending CreateConnectionComplete", __func__);
Chienyuan3d8a8032019-11-01 18:04:07 +0800893 auto packet = bluetooth::hci::ConnectionCompleteBuilder::Create(
894 static_cast<bluetooth::hci::ErrorCode>(reject.GetReason()), 0x0eff,
895 incoming.GetSourceAddress(), bluetooth::hci::LinkType::ACL,
896 bluetooth::hci::Enable::DISABLED);
897 send_event_(std::move(packet));
Hansong Zhang4cb1cf52019-07-08 15:32:26 -0700898}
899
Chienyuandb55f312019-10-31 14:01:28 +0800900void LinkLayerController::IncomingPageResponsePacket(
901 model::packets::LinkLayerPacketView incoming) {
Myles Watsone066df42019-11-13 14:39:18 -0800902 Address peer = incoming.GetSourceAddress();
903 LOG_INFO("%s: %s", __func__, peer.ToString().c_str());
904 bool awaiting_authentication = connections_.AuthenticatePendingConnection();
905 uint16_t handle = connections_.CreateConnection(peer);
Myles Watsone22dde22019-01-18 11:42:33 -0800906 if (handle == acl::kReservedHandle) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700907 LOG_WARN("%s: No free handles", __func__);
Myles Watsone22dde22019-01-18 11:42:33 -0800908 return;
909 }
Chienyuan3d8a8032019-11-01 18:04:07 +0800910 auto packet = bluetooth::hci::ConnectionCompleteBuilder::Create(
911 bluetooth::hci::ErrorCode::SUCCESS, handle, incoming.GetSourceAddress(),
912 bluetooth::hci::LinkType::ACL, bluetooth::hci::Enable::DISABLED);
913 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800914
Myles Watsone066df42019-11-13 14:39:18 -0800915 if (awaiting_authentication) {
916 ScheduleTask(milliseconds(5), [this, peer, handle]() {
917 HandleAuthenticationRequest(peer, handle);
918 });
Myles Watsone22dde22019-01-18 11:42:33 -0800919 }
920}
921
922void LinkLayerController::TimerTick() {
923 if (inquiry_state_ == Inquiry::InquiryState::INQUIRY) Inquiry();
924 if (inquiry_state_ == Inquiry::InquiryState::INQUIRY) PageScan();
Myles Watson99aea892019-09-02 15:54:08 -0700925 LeAdvertising();
Myles Watsone22dde22019-01-18 11:42:33 -0800926 Connections();
927}
928
Myles Watson99aea892019-09-02 15:54:08 -0700929void LinkLayerController::LeAdvertising() {
930 if (!le_advertising_enable_) {
931 return;
932 }
933 steady_clock::time_point now = steady_clock::now();
934 if (duration_cast<milliseconds>(now - last_le_advertisement_) < milliseconds(200)) {
935 return;
936 }
Chienyuan1290e962019-11-07 17:37:26 +0800937 last_le_advertisement_ = now;
Myles Watson99aea892019-09-02 15:54:08 -0700938
Chienyuandb55f312019-10-31 14:01:28 +0800939 auto own_address_type = static_cast<model::packets::AddressType>(
940 properties_.GetLeAdvertisingOwnAddressType());
Myles Watson96723532019-09-02 14:52:46 -0700941 Address advertising_address = Address::kEmpty;
Chienyuandb55f312019-10-31 14:01:28 +0800942 if (own_address_type == model::packets::AddressType::PUBLIC) {
Myles Watson96723532019-09-02 14:52:46 -0700943 advertising_address = properties_.GetAddress();
Chienyuandb55f312019-10-31 14:01:28 +0800944 } else if (own_address_type == model::packets::AddressType::RANDOM) {
Myles Watson96723532019-09-02 14:52:46 -0700945 advertising_address = properties_.GetLeAddress();
Myles Watson99aea892019-09-02 15:54:08 -0700946 }
Myles Watson1a0a0da2019-10-17 11:36:33 -0700947 ASSERT(advertising_address != Address::kEmpty);
Chienyuandb55f312019-10-31 14:01:28 +0800948 auto to_send = model::packets::LeAdvertisementBuilder::Create(
949 advertising_address, Address::kEmpty, own_address_type,
950 static_cast<model::packets::AdvertisementType>(own_address_type),
951 properties_.GetLeAdvertisement());
952 SendLeLinkLayerPacket(std::move(to_send));
Myles Watson99aea892019-09-02 15:54:08 -0700953}
954
Myles Watsone22dde22019-01-18 11:42:33 -0800955void LinkLayerController::Connections() {
956 // TODO: Keep connections alive?
957}
958
959void LinkLayerController::RegisterEventChannel(
Chienyuan3d8a8032019-11-01 18:04:07 +0800960 const std::function<
961 void(std::shared_ptr<bluetooth::hci::EventPacketBuilder>)>& callback) {
Myles Watsone22dde22019-01-18 11:42:33 -0800962 send_event_ = callback;
963}
964
965void LinkLayerController::RegisterAclChannel(
Chienyuan85db6ee2019-11-21 22:07:09 +0800966 const std::function<
967 void(std::shared_ptr<bluetooth::hci::AclPacketBuilder>)>& callback) {
Myles Watsone22dde22019-01-18 11:42:33 -0800968 send_acl_ = callback;
969}
970
971void LinkLayerController::RegisterScoChannel(
972 const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& callback) {
973 send_sco_ = callback;
974}
975
Jakub Pawlowskide6c0132019-11-12 16:14:32 +0100976void LinkLayerController::RegisterIsoChannel(
977 const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>&
978 callback) {
979 send_iso_ = callback;
980}
981
Myles Watsone22dde22019-01-18 11:42:33 -0800982void LinkLayerController::RegisterRemoteChannel(
Chienyuandb55f312019-10-31 14:01:28 +0800983 const std::function<void(
984 std::shared_ptr<model::packets::LinkLayerPacketBuilder>, Phy::Type)>&
985 callback) {
Myles Watsone22dde22019-01-18 11:42:33 -0800986 send_to_remote_ = callback;
987}
988
989void LinkLayerController::RegisterTaskScheduler(
990 std::function<AsyncTaskId(milliseconds, const TaskCallback&)> event_scheduler) {
991 schedule_task_ = event_scheduler;
992}
993
Myles Watson8fe710e2019-09-05 09:01:00 -0700994AsyncTaskId LinkLayerController::ScheduleTask(milliseconds delay_ms, const TaskCallback& callback) {
995 if (schedule_task_) {
996 return schedule_task_(delay_ms, callback);
997 } else {
998 callback();
999 return 0;
1000 }
1001}
1002
Myles Watsone22dde22019-01-18 11:42:33 -08001003void LinkLayerController::RegisterPeriodicTaskScheduler(
1004 std::function<AsyncTaskId(milliseconds, milliseconds, const TaskCallback&)> periodic_event_scheduler) {
1005 schedule_periodic_task_ = periodic_event_scheduler;
1006}
1007
Myles Watson8fe710e2019-09-05 09:01:00 -07001008void LinkLayerController::CancelScheduledTask(AsyncTaskId task_id) {
1009 if (schedule_task_ && cancel_task_) {
1010 cancel_task_(task_id);
1011 }
1012}
1013
Myles Watsone22dde22019-01-18 11:42:33 -08001014void LinkLayerController::RegisterTaskCancel(std::function<void(AsyncTaskId)> task_cancel) {
1015 cancel_task_ = task_cancel;
1016}
1017
1018void LinkLayerController::AddControllerEvent(milliseconds delay, const TaskCallback& task) {
Myles Watson8fe710e2019-09-05 09:01:00 -07001019 controller_events_.push_back(ScheduleTask(delay, task));
Myles Watsone22dde22019-01-18 11:42:33 -08001020}
1021
1022void LinkLayerController::WriteSimplePairingMode(bool enabled) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001023 ASSERT_LOG(enabled, "The spec says don't disable this!");
Myles Watsone22dde22019-01-18 11:42:33 -08001024 simple_pairing_mode_enabled_ = enabled;
1025}
1026
1027void LinkLayerController::StartSimplePairing(const Address& address) {
1028 // IO Capability Exchange (See the Diagram in the Spec)
Chienyuan3d8a8032019-11-01 18:04:07 +08001029 auto packet = bluetooth::hci::IoCapabilityRequestBuilder::Create(address);
1030 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001031
1032 // Get a Key, then authenticate
1033 // PublicKeyExchange(address);
1034 // AuthenticateRemoteStage1(address);
1035 // AuthenticateRemoteStage2(address);
1036}
1037
1038void LinkLayerController::AuthenticateRemoteStage1(const Address& peer, PairingType pairing_type) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001039 ASSERT(security_manager_.GetAuthenticationAddress() == peer);
Myles Watsone22dde22019-01-18 11:42:33 -08001040 // TODO: Public key exchange first?
1041 switch (pairing_type) {
Myles Watsone066df42019-11-13 14:39:18 -08001042 case PairingType::AUTO_CONFIRMATION:
1043 send_event_(
1044 bluetooth::hci::UserConfirmationRequestBuilder::Create(peer, 123456));
1045 break;
Myles Watsone22dde22019-01-18 11:42:33 -08001046 case PairingType::CONFIRM_Y_N:
Myles Watsone066df42019-11-13 14:39:18 -08001047 send_event_(
1048 bluetooth::hci::UserConfirmationRequestBuilder::Create(peer, 123456));
Myles Watsone22dde22019-01-18 11:42:33 -08001049 break;
1050 case PairingType::DISPLAY_PIN:
Myles Watsone066df42019-11-13 14:39:18 -08001051 send_event_(
1052 bluetooth::hci::UserConfirmationRequestBuilder::Create(peer, 123456));
Myles Watsone22dde22019-01-18 11:42:33 -08001053 break;
1054 case PairingType::DISPLAY_AND_CONFIRM:
Myles Watsone066df42019-11-13 14:39:18 -08001055 send_event_(
1056 bluetooth::hci::UserConfirmationRequestBuilder::Create(peer, 123456));
Myles Watsone22dde22019-01-18 11:42:33 -08001057 break;
1058 case PairingType::INPUT_PIN:
Myles Watsone066df42019-11-13 14:39:18 -08001059 send_event_(bluetooth::hci::UserPasskeyRequestBuilder::Create(peer));
Myles Watsone22dde22019-01-18 11:42:33 -08001060 break;
1061 default:
Myles Watson1a0a0da2019-10-17 11:36:33 -07001062 LOG_ALWAYS_FATAL("Invalid PairingType %d", static_cast<int>(pairing_type));
Myles Watsone22dde22019-01-18 11:42:33 -08001063 }
1064}
1065
1066void LinkLayerController::AuthenticateRemoteStage2(const Address& peer) {
1067 uint16_t handle = security_manager_.GetAuthenticationHandle();
Myles Watson1a0a0da2019-10-17 11:36:33 -07001068 ASSERT(security_manager_.GetAuthenticationAddress() == peer);
Myles Watsone22dde22019-01-18 11:42:33 -08001069 // Check key in security_manager_ ?
Chienyuan3d8a8032019-11-01 18:04:07 +08001070 auto packet = bluetooth::hci::AuthenticationCompleteBuilder::Create(
1071 bluetooth::hci::ErrorCode::SUCCESS, handle);
1072 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001073}
1074
Chienyuan3d8a8032019-11-01 18:04:07 +08001075bluetooth::hci::ErrorCode LinkLayerController::LinkKeyRequestReply(
Myles Watsone066df42019-11-13 14:39:18 -08001076 const Address& peer, const std::array<uint8_t, 16>& key) {
1077 security_manager_.WriteKey(peer, key);
Myles Watsone22dde22019-01-18 11:42:33 -08001078 security_manager_.AuthenticationRequestFinished();
1079
Myles Watson8fe710e2019-09-05 09:01:00 -07001080 ScheduleTask(milliseconds(5), [this, peer]() { AuthenticateRemoteStage2(peer); });
Myles Watsone22dde22019-01-18 11:42:33 -08001081
Chienyuan3d8a8032019-11-01 18:04:07 +08001082 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001083}
1084
Chienyuan3d8a8032019-11-01 18:04:07 +08001085bluetooth::hci::ErrorCode LinkLayerController::LinkKeyRequestNegativeReply(
1086 const Address& address) {
Myles Watsone22dde22019-01-18 11:42:33 -08001087 security_manager_.DeleteKey(address);
1088 // Simple pairing to get a key
Myles Watson96723532019-09-02 14:52:46 -07001089 uint16_t handle = connections_.GetHandle(address);
Myles Watsone22dde22019-01-18 11:42:33 -08001090 if (handle == acl::kReservedHandle) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001091 LOG_INFO("%s: Device not connected %s", __func__, address.ToString().c_str());
Chienyuan3d8a8032019-11-01 18:04:07 +08001092 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Myles Watsone22dde22019-01-18 11:42:33 -08001093 }
1094
1095 security_manager_.AuthenticationRequest(address, handle);
1096
Myles Watson8fe710e2019-09-05 09:01:00 -07001097 ScheduleTask(milliseconds(5), [this, address]() { StartSimplePairing(address); });
Chienyuan3d8a8032019-11-01 18:04:07 +08001098 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001099}
1100
Chienyuan3d8a8032019-11-01 18:04:07 +08001101bluetooth::hci::ErrorCode LinkLayerController::IoCapabilityRequestReply(
1102 const Address& peer, uint8_t io_capability, uint8_t oob_data_present_flag,
1103 uint8_t authentication_requirements) {
Myles Watsone22dde22019-01-18 11:42:33 -08001104 security_manager_.SetLocalIoCapability(peer, io_capability, oob_data_present_flag, authentication_requirements);
1105
1106 PairingType pairing_type = security_manager_.GetSimplePairingType();
Chienyuandb55f312019-10-31 14:01:28 +08001107
Myles Watsone22dde22019-01-18 11:42:33 -08001108 if (pairing_type != PairingType::INVALID) {
Myles Watsone066df42019-11-13 14:39:18 -08001109 ScheduleTask(milliseconds(5), [this, peer, pairing_type]() {
1110 AuthenticateRemoteStage1(peer, pairing_type);
1111 });
1112 SendLinkLayerPacket(model::packets::IoCapabilityResponseBuilder::Create(
Chienyuandb55f312019-10-31 14:01:28 +08001113 properties_.GetAddress(), peer, io_capability, oob_data_present_flag,
Myles Watsone066df42019-11-13 14:39:18 -08001114 authentication_requirements));
Myles Watsone22dde22019-01-18 11:42:33 -08001115 } else {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001116 LOG_INFO("%s: Requesting remote capability", __func__);
Chienyuandb55f312019-10-31 14:01:28 +08001117
Myles Watsone066df42019-11-13 14:39:18 -08001118 SendLinkLayerPacket(model::packets::IoCapabilityRequestBuilder::Create(
Chienyuandb55f312019-10-31 14:01:28 +08001119 properties_.GetAddress(), peer, io_capability, oob_data_present_flag,
Myles Watsone066df42019-11-13 14:39:18 -08001120 authentication_requirements));
Myles Watsone22dde22019-01-18 11:42:33 -08001121 }
1122
Chienyuan3d8a8032019-11-01 18:04:07 +08001123 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001124}
1125
Chienyuan3d8a8032019-11-01 18:04:07 +08001126bluetooth::hci::ErrorCode LinkLayerController::IoCapabilityRequestNegativeReply(
1127 const Address& peer, hci::Status reason) {
Myles Watsone22dde22019-01-18 11:42:33 -08001128 if (security_manager_.GetAuthenticationAddress() != peer) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001129 return bluetooth::hci::ErrorCode::AUTHENTICATION_FAILURE;
Myles Watsone22dde22019-01-18 11:42:33 -08001130 }
1131
1132 security_manager_.InvalidateIoCapabilities();
1133
Chienyuandb55f312019-10-31 14:01:28 +08001134 auto packet = model::packets::IoCapabilityNegativeResponseBuilder::Create(
1135 properties_.GetAddress(), peer, static_cast<uint8_t>(reason));
1136 SendLinkLayerPacket(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001137
Chienyuan3d8a8032019-11-01 18:04:07 +08001138 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001139}
1140
Chienyuan3d8a8032019-11-01 18:04:07 +08001141bluetooth::hci::ErrorCode LinkLayerController::UserConfirmationRequestReply(
1142 const Address& peer) {
Myles Watsone22dde22019-01-18 11:42:33 -08001143 if (security_manager_.GetAuthenticationAddress() != peer) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001144 return bluetooth::hci::ErrorCode::AUTHENTICATION_FAILURE;
Myles Watsone22dde22019-01-18 11:42:33 -08001145 }
1146 // TODO: Key could be calculated here.
Myles Watsone066df42019-11-13 14:39:18 -08001147 std::array<uint8_t, 16> key_vec{1, 2, 3, 4, 5, 6, 7, 8,
1148 9, 10, 11, 12, 13, 14, 15, 16};
Myles Watsone22dde22019-01-18 11:42:33 -08001149 security_manager_.WriteKey(peer, key_vec);
1150
1151 security_manager_.AuthenticationRequestFinished();
1152
Myles Watsone066df42019-11-13 14:39:18 -08001153 ScheduleTask(milliseconds(5), [this, peer, key_vec]() {
1154 send_event_(bluetooth::hci::LinkKeyNotificationBuilder::Create(
1155 peer, key_vec, bluetooth::hci::KeyType::AUTHENTICATED_P256));
1156 });
1157
1158 ScheduleTask(milliseconds(15),
1159 [this, peer]() { AuthenticateRemoteStage2(peer); });
Chienyuan3d8a8032019-11-01 18:04:07 +08001160 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001161}
1162
Chienyuan3d8a8032019-11-01 18:04:07 +08001163bluetooth::hci::ErrorCode
1164LinkLayerController::UserConfirmationRequestNegativeReply(const Address& peer) {
Myles Watsone22dde22019-01-18 11:42:33 -08001165 if (security_manager_.GetAuthenticationAddress() != peer) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001166 return bluetooth::hci::ErrorCode::AUTHENTICATION_FAILURE;
Myles Watsone22dde22019-01-18 11:42:33 -08001167 }
Chienyuan3d8a8032019-11-01 18:04:07 +08001168 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001169}
1170
Chienyuan3d8a8032019-11-01 18:04:07 +08001171bluetooth::hci::ErrorCode LinkLayerController::UserPasskeyRequestReply(
1172 const Address& peer, uint32_t numeric_value) {
Myles Watsone22dde22019-01-18 11:42:33 -08001173 if (security_manager_.GetAuthenticationAddress() != peer) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001174 return bluetooth::hci::ErrorCode::AUTHENTICATION_FAILURE;
Myles Watsone22dde22019-01-18 11:42:33 -08001175 }
Myles Watson1a0a0da2019-10-17 11:36:33 -07001176 LOG_INFO("TODO:Do something with the passkey %06d", numeric_value);
Chienyuan3d8a8032019-11-01 18:04:07 +08001177 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001178}
1179
Chienyuan3d8a8032019-11-01 18:04:07 +08001180bluetooth::hci::ErrorCode LinkLayerController::UserPasskeyRequestNegativeReply(
1181 const Address& peer) {
Myles Watsone22dde22019-01-18 11:42:33 -08001182 if (security_manager_.GetAuthenticationAddress() != peer) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001183 return bluetooth::hci::ErrorCode::AUTHENTICATION_FAILURE;
Myles Watsone22dde22019-01-18 11:42:33 -08001184 }
Chienyuan3d8a8032019-11-01 18:04:07 +08001185 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001186}
1187
Chienyuan3d8a8032019-11-01 18:04:07 +08001188bluetooth::hci::ErrorCode LinkLayerController::RemoteOobDataRequestReply(
1189 const Address& peer, const std::vector<uint8_t>& c,
1190 const std::vector<uint8_t>& r) {
Myles Watsone22dde22019-01-18 11:42:33 -08001191 if (security_manager_.GetAuthenticationAddress() != peer) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001192 return bluetooth::hci::ErrorCode::AUTHENTICATION_FAILURE;
Myles Watsone22dde22019-01-18 11:42:33 -08001193 }
Myles Watson1a0a0da2019-10-17 11:36:33 -07001194 LOG_INFO("TODO:Do something with the OOB data c=%d r=%d", c[0], r[0]);
Chienyuan3d8a8032019-11-01 18:04:07 +08001195 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001196}
1197
Chienyuan3d8a8032019-11-01 18:04:07 +08001198bluetooth::hci::ErrorCode
1199LinkLayerController::RemoteOobDataRequestNegativeReply(const Address& peer) {
Myles Watsone22dde22019-01-18 11:42:33 -08001200 if (security_manager_.GetAuthenticationAddress() != peer) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001201 return bluetooth::hci::ErrorCode::AUTHENTICATION_FAILURE;
Myles Watsone22dde22019-01-18 11:42:33 -08001202 }
Chienyuan3d8a8032019-11-01 18:04:07 +08001203 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001204}
1205
1206void LinkLayerController::HandleAuthenticationRequest(const Address& address, uint16_t handle) {
1207 if (simple_pairing_mode_enabled_ == true) {
1208 security_manager_.AuthenticationRequest(address, handle);
Chienyuan3d8a8032019-11-01 18:04:07 +08001209 auto packet = bluetooth::hci::LinkKeyRequestBuilder::Create(address);
1210 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001211 } else { // Should never happen for our phones
1212 // Check for a key, try to authenticate, ask for a PIN.
Chienyuan3d8a8032019-11-01 18:04:07 +08001213 auto packet = bluetooth::hci::AuthenticationCompleteBuilder::Create(
1214 bluetooth::hci::ErrorCode::AUTHENTICATION_FAILURE, handle);
1215 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001216 }
1217}
1218
Chienyuan3d8a8032019-11-01 18:04:07 +08001219bluetooth::hci::ErrorCode LinkLayerController::AuthenticationRequested(
1220 uint16_t handle) {
Myles Watson96723532019-09-02 14:52:46 -07001221 if (!connections_.HasHandle(handle)) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001222 LOG_INFO("Authentication Requested for unknown handle %04x", handle);
Chienyuan3d8a8032019-11-01 18:04:07 +08001223 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Myles Watsone22dde22019-01-18 11:42:33 -08001224 }
1225
Myles Watson96723532019-09-02 14:52:46 -07001226 Address remote = connections_.GetAddress(handle);
Myles Watsone22dde22019-01-18 11:42:33 -08001227
Myles Watson8fe710e2019-09-05 09:01:00 -07001228 ScheduleTask(milliseconds(5), [this, remote, handle]() { HandleAuthenticationRequest(remote, handle); });
Myles Watsone22dde22019-01-18 11:42:33 -08001229
Chienyuan3d8a8032019-11-01 18:04:07 +08001230 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001231}
1232
1233void LinkLayerController::HandleSetConnectionEncryption(const Address& peer, uint16_t handle,
1234 uint8_t encryption_enable) {
1235 // TODO: Block ACL traffic or at least guard against it
1236
Myles Watson96723532019-09-02 14:52:46 -07001237 if (connections_.IsEncrypted(handle) && encryption_enable) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001238 auto packet = bluetooth::hci::EncryptionChangeBuilder::Create(
1239 bluetooth::hci::ErrorCode::SUCCESS, handle,
1240 static_cast<bluetooth::hci::EncryptionEnabled>(encryption_enable));
1241 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001242 return;
1243 }
1244
Myles Watsone066df42019-11-13 14:39:18 -08001245 uint16_t count = security_manager_.ReadKey(peer);
1246 if (count == 0) {
1247 LOG_ERROR("NO KEY HERE for %s", peer.ToString().c_str());
1248 return;
1249 }
1250 auto array = security_manager_.GetKey(peer);
1251 std::vector<uint8_t> key_vec{array.begin(), array.end()};
Chienyuandb55f312019-10-31 14:01:28 +08001252 auto packet = model::packets::EncryptConnectionBuilder::Create(
Myles Watsone066df42019-11-13 14:39:18 -08001253 properties_.GetAddress(), peer, key_vec);
Chienyuandb55f312019-10-31 14:01:28 +08001254 SendLinkLayerPacket(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001255}
1256
Chienyuan3d8a8032019-11-01 18:04:07 +08001257bluetooth::hci::ErrorCode LinkLayerController::SetConnectionEncryption(
1258 uint16_t handle, uint8_t encryption_enable) {
Myles Watson96723532019-09-02 14:52:46 -07001259 if (!connections_.HasHandle(handle)) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001260 LOG_INFO("Set Connection Encryption for unknown handle %04x", handle);
Chienyuan3d8a8032019-11-01 18:04:07 +08001261 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Myles Watsone22dde22019-01-18 11:42:33 -08001262 }
1263
Myles Watson96723532019-09-02 14:52:46 -07001264 if (connections_.IsEncrypted(handle) && !encryption_enable) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001265 return bluetooth::hci::ErrorCode::ENCRYPTION_MODE_NOT_ACCEPTABLE;
Myles Watsone22dde22019-01-18 11:42:33 -08001266 }
Myles Watson96723532019-09-02 14:52:46 -07001267 Address remote = connections_.GetAddress(handle);
Myles Watsone22dde22019-01-18 11:42:33 -08001268
Chienyuanad340b02019-09-25 19:23:21 +08001269 if (security_manager_.ReadKey(remote) == 0) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001270 return bluetooth::hci::ErrorCode::PIN_OR_KEY_MISSING;
Chienyuanad340b02019-09-25 19:23:21 +08001271 }
1272
Myles Watson8fe710e2019-09-05 09:01:00 -07001273 ScheduleTask(milliseconds(5), [this, remote, handle, encryption_enable]() {
Myles Watsone22dde22019-01-18 11:42:33 -08001274 HandleSetConnectionEncryption(remote, handle, encryption_enable);
1275 });
Chienyuan3d8a8032019-11-01 18:04:07 +08001276 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001277}
1278
Chienyuan3d8a8032019-11-01 18:04:07 +08001279bluetooth::hci::ErrorCode LinkLayerController::AcceptConnectionRequest(
1280 const Address& addr, bool try_role_switch) {
Myles Watson96723532019-09-02 14:52:46 -07001281 if (!connections_.HasPendingConnection(addr)) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001282 LOG_INFO("%s: No pending connection for %s", __func__, addr.ToString().c_str());
Chienyuan3d8a8032019-11-01 18:04:07 +08001283 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Myles Watsone22dde22019-01-18 11:42:33 -08001284 }
1285
Myles Watson1a0a0da2019-10-17 11:36:33 -07001286 LOG_INFO("%s: Accept in 200ms", __func__);
Myles Watson8fe710e2019-09-05 09:01:00 -07001287 ScheduleTask(milliseconds(200), [this, addr, try_role_switch]() {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001288 LOG_INFO("%s: Accepted", __func__);
Myles Watsone22dde22019-01-18 11:42:33 -08001289 MakeSlaveConnection(addr, try_role_switch);
1290 });
1291
Chienyuan3d8a8032019-11-01 18:04:07 +08001292 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001293}
1294
1295void LinkLayerController::MakeSlaveConnection(const Address& addr, bool try_role_switch) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001296 LOG_INFO("%s sending page response to %s", __func__, addr.ToString().c_str());
Chienyuandb55f312019-10-31 14:01:28 +08001297 auto to_send = model::packets::PageResponseBuilder::Create(
1298 properties_.GetAddress(), addr, try_role_switch);
1299 SendLinkLayerPacket(std::move(to_send));
Myles Watsone22dde22019-01-18 11:42:33 -08001300
Myles Watson96723532019-09-02 14:52:46 -07001301 uint16_t handle = connections_.CreateConnection(addr);
Myles Watsone22dde22019-01-18 11:42:33 -08001302 if (handle == acl::kReservedHandle) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001303 LOG_INFO("%s CreateConnection failed", __func__);
Myles Watsone22dde22019-01-18 11:42:33 -08001304 return;
1305 }
Myles Watson1a0a0da2019-10-17 11:36:33 -07001306 LOG_INFO("%s CreateConnection returned handle 0x%x", __func__, handle);
Chienyuan3d8a8032019-11-01 18:04:07 +08001307 auto packet = bluetooth::hci::ConnectionCompleteBuilder::Create(
1308 bluetooth::hci::ErrorCode::SUCCESS, handle, addr,
1309 bluetooth::hci::LinkType::ACL, bluetooth::hci::Enable::DISABLED);
1310 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001311}
1312
Chienyuan3d8a8032019-11-01 18:04:07 +08001313bluetooth::hci::ErrorCode LinkLayerController::RejectConnectionRequest(
1314 const Address& addr, uint8_t reason) {
Myles Watson96723532019-09-02 14:52:46 -07001315 if (!connections_.HasPendingConnection(addr)) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001316 LOG_INFO("%s: No pending connection for %s", __func__, addr.ToString().c_str());
Chienyuan3d8a8032019-11-01 18:04:07 +08001317 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Myles Watsone22dde22019-01-18 11:42:33 -08001318 }
1319
Myles Watsone066df42019-11-13 14:39:18 -08001320 ScheduleTask(milliseconds(200),
1321 [this, addr, reason]() { RejectSlaveConnection(addr, reason); });
Myles Watsone22dde22019-01-18 11:42:33 -08001322
Chienyuan3d8a8032019-11-01 18:04:07 +08001323 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001324}
1325
1326void LinkLayerController::RejectSlaveConnection(const Address& addr, uint8_t reason) {
Chienyuandb55f312019-10-31 14:01:28 +08001327 auto to_send = model::packets::PageRejectBuilder::Create(
1328 properties_.GetAddress(), addr, reason);
Myles Watsone066df42019-11-13 14:39:18 -08001329 LOG_INFO("%s sending page reject to %s (reason 0x%02hhx)", __func__,
1330 addr.ToString().c_str(), reason);
Chienyuandb55f312019-10-31 14:01:28 +08001331 SendLinkLayerPacket(std::move(to_send));
Hansong Zhang4cb1cf52019-07-08 15:32:26 -07001332
Chienyuan3d8a8032019-11-01 18:04:07 +08001333 auto packet = bluetooth::hci::ConnectionCompleteBuilder::Create(
1334 static_cast<bluetooth::hci::ErrorCode>(reason), 0xeff, addr,
1335 bluetooth::hci::LinkType::ACL, bluetooth::hci::Enable::DISABLED);
1336 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001337}
1338
Chienyuan3d8a8032019-11-01 18:04:07 +08001339bluetooth::hci::ErrorCode LinkLayerController::CreateConnection(
1340 const Address& addr, uint16_t, uint8_t, uint16_t,
1341 uint8_t allow_role_switch) {
Myles Watsone066df42019-11-13 14:39:18 -08001342 if (!connections_.CreatePendingConnection(
1343 addr, properties_.GetAuthenticationEnable() == 1)) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001344 return bluetooth::hci::ErrorCode::CONTROLLER_BUSY;
Myles Watsone22dde22019-01-18 11:42:33 -08001345 }
Chienyuandb55f312019-10-31 14:01:28 +08001346 auto page = model::packets::PageBuilder::Create(
1347 properties_.GetAddress(), addr, properties_.GetClassOfDevice(),
1348 allow_role_switch);
1349 SendLinkLayerPacket(std::move(page));
Myles Watsone22dde22019-01-18 11:42:33 -08001350
Chienyuan3d8a8032019-11-01 18:04:07 +08001351 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001352}
1353
Chienyuan3d8a8032019-11-01 18:04:07 +08001354bluetooth::hci::ErrorCode LinkLayerController::CreateConnectionCancel(
1355 const Address& addr) {
Myles Watson96723532019-09-02 14:52:46 -07001356 if (!connections_.CancelPendingConnection(addr)) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001357 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Myles Watsone22dde22019-01-18 11:42:33 -08001358 }
Chienyuan3d8a8032019-11-01 18:04:07 +08001359 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001360}
1361
Chienyuan3d8a8032019-11-01 18:04:07 +08001362bluetooth::hci::ErrorCode LinkLayerController::Disconnect(uint16_t handle,
1363 uint8_t reason) {
Myles Watsone22dde22019-01-18 11:42:33 -08001364 // TODO: Handle LE
Myles Watson96723532019-09-02 14:52:46 -07001365 if (!connections_.HasHandle(handle)) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001366 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Myles Watsone22dde22019-01-18 11:42:33 -08001367 }
1368
Myles Watson96723532019-09-02 14:52:46 -07001369 const Address& remote = connections_.GetAddress(handle);
Chienyuandb55f312019-10-31 14:01:28 +08001370 auto packet = model::packets::DisconnectBuilder::Create(
1371 properties_.GetAddress(), remote, reason);
1372 SendLinkLayerPacket(std::move(packet));
Myles Watson1a0a0da2019-10-17 11:36:33 -07001373 ASSERT_LOG(connections_.Disconnect(handle), "Disconnecting %hx", handle);
Myles Watsone22dde22019-01-18 11:42:33 -08001374
Myles Watson8fe710e2019-09-05 09:01:00 -07001375 ScheduleTask(milliseconds(20), [this, handle]() {
Myles Watsone22dde22019-01-18 11:42:33 -08001376 DisconnectCleanup(handle, static_cast<uint8_t>(hci::Status::CONNECTION_TERMINATED_BY_LOCAL_HOST));
1377 });
1378
Chienyuan3d8a8032019-11-01 18:04:07 +08001379 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001380}
1381
1382void LinkLayerController::DisconnectCleanup(uint16_t handle, uint8_t reason) {
1383 // TODO: Clean up other connection state.
Chienyuan3d8a8032019-11-01 18:04:07 +08001384 auto packet = bluetooth::hci::DisconnectionCompleteBuilder::Create(
1385 bluetooth::hci::ErrorCode::SUCCESS, handle,
1386 static_cast<bluetooth::hci::ErrorCode>(reason));
1387 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001388}
1389
Chienyuan3d8a8032019-11-01 18:04:07 +08001390bluetooth::hci::ErrorCode LinkLayerController::ChangeConnectionPacketType(
1391 uint16_t handle, uint16_t types) {
Myles Watson96723532019-09-02 14:52:46 -07001392 if (!connections_.HasHandle(handle)) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001393 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Myles Watsone22dde22019-01-18 11:42:33 -08001394 }
Chienyuan3d8a8032019-11-01 18:04:07 +08001395 auto packet = bluetooth::hci::ConnectionPacketTypeChangedBuilder::Create(
1396 bluetooth::hci::ErrorCode::SUCCESS, handle, types);
1397 std::shared_ptr<bluetooth::hci::ConnectionPacketTypeChangedBuilder>
1398 shared_packet = std::move(packet);
1399 ScheduleTask(milliseconds(20), [this, shared_packet]() {
1400 send_event_(std::move(shared_packet));
1401 });
Myles Watsone22dde22019-01-18 11:42:33 -08001402
Chienyuan3d8a8032019-11-01 18:04:07 +08001403 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001404}
1405
Chienyuan3d8a8032019-11-01 18:04:07 +08001406bluetooth::hci::ErrorCode LinkLayerController::ChangeConnectionLinkKey(
1407 uint16_t handle) {
Chienyuanad340b02019-09-25 19:23:21 +08001408 if (!connections_.HasHandle(handle)) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001409 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Chienyuanad340b02019-09-25 19:23:21 +08001410 }
1411
1412 // TODO: implement real logic
Chienyuan3d8a8032019-11-01 18:04:07 +08001413 return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
Chienyuanad340b02019-09-25 19:23:21 +08001414}
1415
Chienyuan3d8a8032019-11-01 18:04:07 +08001416bluetooth::hci::ErrorCode LinkLayerController::MasterLinkKey(
1417 uint8_t /* key_flag */) {
Chienyuan9145e7a2019-10-02 15:18:55 +08001418 // TODO: implement real logic
Chienyuan3d8a8032019-11-01 18:04:07 +08001419 return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
Chienyuan9145e7a2019-10-02 15:18:55 +08001420}
1421
Chienyuan3d8a8032019-11-01 18:04:07 +08001422bluetooth::hci::ErrorCode LinkLayerController::HoldMode(
1423 uint16_t handle, uint16_t hold_mode_max_interval,
1424 uint16_t hold_mode_min_interval) {
Chienyuanad340b02019-09-25 19:23:21 +08001425 if (!connections_.HasHandle(handle)) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001426 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Chienyuanad340b02019-09-25 19:23:21 +08001427 }
1428
1429 if (hold_mode_max_interval < hold_mode_min_interval) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001430 return bluetooth::hci::ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
Chienyuanad340b02019-09-25 19:23:21 +08001431 }
1432
1433 // TODO: implement real logic
Chienyuan3d8a8032019-11-01 18:04:07 +08001434 return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
Chienyuanad340b02019-09-25 19:23:21 +08001435}
1436
Chienyuan3d8a8032019-11-01 18:04:07 +08001437bluetooth::hci::ErrorCode LinkLayerController::SniffMode(
1438 uint16_t handle, uint16_t sniff_max_interval, uint16_t sniff_min_interval,
1439 uint16_t sniff_attempt, uint16_t sniff_timeout) {
Chienyuanad340b02019-09-25 19:23:21 +08001440 if (!connections_.HasHandle(handle)) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001441 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Chienyuanad340b02019-09-25 19:23:21 +08001442 }
1443
Myles Watson1a0a0da2019-10-17 11:36:33 -07001444 if (sniff_max_interval < sniff_min_interval || sniff_attempt < 0x0001 || sniff_attempt > 0x7FFF ||
1445 sniff_timeout > 0x7FFF) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001446 return bluetooth::hci::ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
Chienyuanad340b02019-09-25 19:23:21 +08001447 }
1448
1449 // TODO: implement real logic
Chienyuan3d8a8032019-11-01 18:04:07 +08001450 return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
Chienyuanad340b02019-09-25 19:23:21 +08001451}
1452
Chienyuan3d8a8032019-11-01 18:04:07 +08001453bluetooth::hci::ErrorCode LinkLayerController::ExitSniffMode(uint16_t handle) {
Chienyuanad340b02019-09-25 19:23:21 +08001454 if (!connections_.HasHandle(handle)) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001455 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Chienyuanad340b02019-09-25 19:23:21 +08001456 }
1457
1458 // TODO: implement real logic
Chienyuan3d8a8032019-11-01 18:04:07 +08001459 return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
Chienyuanad340b02019-09-25 19:23:21 +08001460}
1461
Chienyuan3d8a8032019-11-01 18:04:07 +08001462bluetooth::hci::ErrorCode LinkLayerController::QosSetup(
1463 uint16_t handle, uint8_t service_type, uint32_t /* token_rate */,
1464 uint32_t /* peak_bandwidth */, uint32_t /* latency */,
1465 uint32_t /* delay_variation */) {
Chienyuanad340b02019-09-25 19:23:21 +08001466 if (!connections_.HasHandle(handle)) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001467 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Chienyuanad340b02019-09-25 19:23:21 +08001468 }
1469
1470 if (service_type > 0x02) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001471 return bluetooth::hci::ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
Chienyuanad340b02019-09-25 19:23:21 +08001472 }
1473
1474 // TODO: implement real logic
Chienyuan3d8a8032019-11-01 18:04:07 +08001475 return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
Chienyuanad340b02019-09-25 19:23:21 +08001476}
1477
Chienyuan3d8a8032019-11-01 18:04:07 +08001478bluetooth::hci::ErrorCode LinkLayerController::SwitchRole(Address /* bd_addr */,
1479 uint8_t /* role */) {
Chienyuan9145e7a2019-10-02 15:18:55 +08001480 // TODO: implement real logic
Chienyuan3d8a8032019-11-01 18:04:07 +08001481 return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
Chienyuan9145e7a2019-10-02 15:18:55 +08001482}
1483
Chienyuan3d8a8032019-11-01 18:04:07 +08001484bluetooth::hci::ErrorCode LinkLayerController::WriteLinkPolicySettings(
1485 uint16_t handle, uint16_t) {
Myles Watson96723532019-09-02 14:52:46 -07001486 if (!connections_.HasHandle(handle)) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001487 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Myles Watsone22dde22019-01-18 11:42:33 -08001488 }
Chienyuan3d8a8032019-11-01 18:04:07 +08001489 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001490}
1491
Chienyuan3d8a8032019-11-01 18:04:07 +08001492bluetooth::hci::ErrorCode LinkLayerController::FlowSpecification(
1493 uint16_t handle, uint8_t flow_direction, uint8_t service_type,
1494 uint32_t /* token_rate */, uint32_t /* token_bucket_size */,
1495 uint32_t /* peak_bandwidth */, uint32_t /* access_latency */) {
Chienyuanad340b02019-09-25 19:23:21 +08001496 if (!connections_.HasHandle(handle)) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001497 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Chienyuanad340b02019-09-25 19:23:21 +08001498 }
1499
1500 if (flow_direction > 0x01 || service_type > 0x02) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001501 return bluetooth::hci::ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
Chienyuanad340b02019-09-25 19:23:21 +08001502 }
1503
1504 // TODO: implement real logic
Chienyuan3d8a8032019-11-01 18:04:07 +08001505 return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
Chienyuanad340b02019-09-25 19:23:21 +08001506}
1507
Chienyuan3d8a8032019-11-01 18:04:07 +08001508bluetooth::hci::ErrorCode LinkLayerController::WriteLinkSupervisionTimeout(
1509 uint16_t handle, uint16_t) {
Myles Watson96723532019-09-02 14:52:46 -07001510 if (!connections_.HasHandle(handle)) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001511 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Myles Watsone22dde22019-01-18 11:42:33 -08001512 }
Chienyuan3d8a8032019-11-01 18:04:07 +08001513 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001514}
1515
1516void LinkLayerController::LeWhiteListClear() {
1517 le_white_list_.clear();
1518}
1519
Calvin Huangee1980c2019-11-01 16:35:55 -07001520void LinkLayerController::LeResolvingListClear() { le_resolving_list_.clear(); }
1521
Myles Watsone22dde22019-01-18 11:42:33 -08001522void LinkLayerController::LeWhiteListAddDevice(Address addr, uint8_t addr_type) {
1523 std::tuple<Address, uint8_t> new_tuple = std::make_tuple(addr, addr_type);
1524 for (auto dev : le_white_list_) {
1525 if (dev == new_tuple) {
1526 return;
1527 }
1528 }
1529 le_white_list_.emplace_back(new_tuple);
1530}
1531
Calvin Huangee1980c2019-11-01 16:35:55 -07001532void LinkLayerController::LeResolvingListAddDevice(
1533 Address addr, uint8_t addr_type, std::array<uint8_t, kIrk_size> peerIrk,
1534 std::array<uint8_t, kIrk_size> localIrk) {
1535 std::tuple<Address, uint8_t, std::array<uint8_t, kIrk_size>,
1536 std::array<uint8_t, kIrk_size>>
1537 new_tuple = std::make_tuple(addr, addr_type, peerIrk, localIrk);
1538 for (size_t i = 0; i < le_white_list_.size(); i++) {
1539 auto curr = le_white_list_[i];
1540 if (std::get<0>(curr) == addr && std::get<1>(curr) == addr_type) {
1541 le_resolving_list_[i] = new_tuple;
1542 return;
1543 }
1544 }
1545 le_resolving_list_.emplace_back(new_tuple);
1546}
1547
1548void LinkLayerController::LeSetPrivacyMode(uint8_t address_type, Address addr,
1549 uint8_t mode) {
1550 // set mode for addr
1551 LOG_INFO("address type = %d ", address_type);
1552 LOG_INFO("address = %s ", addr.ToString().c_str());
1553 LOG_INFO("mode = %d ", mode);
1554}
1555
Myles Watsone22dde22019-01-18 11:42:33 -08001556void LinkLayerController::LeWhiteListRemoveDevice(Address addr, uint8_t addr_type) {
1557 // TODO: Add checks to see if advertising, scanning, or a connection request
1558 // with the white list is ongoing.
1559 std::tuple<Address, uint8_t> erase_tuple = std::make_tuple(addr, addr_type);
1560 for (size_t i = 0; i < le_white_list_.size(); i++) {
1561 if (le_white_list_[i] == erase_tuple) {
1562 le_white_list_.erase(le_white_list_.begin() + i);
1563 }
1564 }
1565}
1566
Calvin Huangee1980c2019-11-01 16:35:55 -07001567void LinkLayerController::LeResolvingListRemoveDevice(Address addr,
1568 uint8_t addr_type) {
1569 // TODO: Add checks to see if advertising, scanning, or a connection request
1570 // with the white list is ongoing.
1571 for (size_t i = 0; i < le_white_list_.size(); i++) {
1572 auto curr = le_white_list_[i];
1573 if (std::get<0>(curr) == addr && std::get<1>(curr) == addr_type) {
1574 le_resolving_list_.erase(le_resolving_list_.begin() + i);
1575 }
1576 }
1577}
1578
Myles Watsone22dde22019-01-18 11:42:33 -08001579bool LinkLayerController::LeWhiteListContainsDevice(Address addr, uint8_t addr_type) {
1580 std::tuple<Address, uint8_t> sought_tuple = std::make_tuple(addr, addr_type);
1581 for (size_t i = 0; i < le_white_list_.size(); i++) {
1582 if (le_white_list_[i] == sought_tuple) {
1583 return true;
1584 }
1585 }
1586 return false;
1587}
1588
Calvin Huangee1980c2019-11-01 16:35:55 -07001589bool LinkLayerController::LeResolvingListContainsDevice(Address addr,
1590 uint8_t addr_type) {
1591 for (size_t i = 0; i < le_white_list_.size(); i++) {
1592 auto curr = le_white_list_[i];
1593 if (std::get<0>(curr) == addr && std::get<1>(curr) == addr_type) {
1594 return true;
1595 }
1596 }
1597 return false;
1598}
1599
Myles Watsone22dde22019-01-18 11:42:33 -08001600bool LinkLayerController::LeWhiteListFull() {
1601 return le_white_list_.size() >= properties_.GetLeWhiteListSize();
1602}
1603
Calvin Huangee1980c2019-11-01 16:35:55 -07001604bool LinkLayerController::LeResolvingListFull() {
1605 return le_resolving_list_.size() >= properties_.GetLeResolvingListSize();
1606}
1607
Myles Watsone22dde22019-01-18 11:42:33 -08001608void LinkLayerController::Reset() {
1609 inquiry_state_ = Inquiry::InquiryState::STANDBY;
1610 last_inquiry_ = steady_clock::now();
1611 le_scan_enable_ = 0;
Myles Watson96723532019-09-02 14:52:46 -07001612 le_advertising_enable_ = 0;
Myles Watsone22dde22019-01-18 11:42:33 -08001613 le_connect_ = 0;
1614}
1615
1616void LinkLayerController::PageScan() {}
1617
1618void LinkLayerController::StartInquiry(milliseconds timeout) {
Myles Watson8fe710e2019-09-05 09:01:00 -07001619 ScheduleTask(milliseconds(timeout), [this]() { LinkLayerController::InquiryTimeout(); });
Myles Watsone22dde22019-01-18 11:42:33 -08001620 inquiry_state_ = Inquiry::InquiryState::INQUIRY;
Myles Watsone22dde22019-01-18 11:42:33 -08001621}
1622
1623void LinkLayerController::InquiryCancel() {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001624 ASSERT(inquiry_state_ == Inquiry::InquiryState::INQUIRY);
Myles Watsone22dde22019-01-18 11:42:33 -08001625 inquiry_state_ = Inquiry::InquiryState::STANDBY;
1626}
1627
1628void LinkLayerController::InquiryTimeout() {
1629 if (inquiry_state_ == Inquiry::InquiryState::INQUIRY) {
1630 inquiry_state_ = Inquiry::InquiryState::STANDBY;
Chienyuan3d8a8032019-11-01 18:04:07 +08001631 auto packet = bluetooth::hci::InquiryCompleteBuilder::Create(
1632 bluetooth::hci::ErrorCode::SUCCESS);
1633 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001634 }
1635}
1636
1637void LinkLayerController::SetInquiryMode(uint8_t mode) {
Chienyuandb55f312019-10-31 14:01:28 +08001638 inquiry_mode_ = static_cast<model::packets::InquiryType>(mode);
Myles Watsone22dde22019-01-18 11:42:33 -08001639}
1640
1641void LinkLayerController::SetInquiryLAP(uint64_t lap) {
1642 inquiry_lap_ = lap;
1643}
1644
1645void LinkLayerController::SetInquiryMaxResponses(uint8_t max) {
1646 inquiry_max_responses_ = max;
1647}
1648
1649void LinkLayerController::Inquiry() {
1650 steady_clock::time_point now = steady_clock::now();
1651 if (duration_cast<milliseconds>(now - last_inquiry_) < milliseconds(2000)) {
1652 return;
1653 }
Chienyuandb55f312019-10-31 14:01:28 +08001654
1655 auto packet = model::packets::InquiryBuilder::Create(
1656 properties_.GetAddress(), Address::kEmpty, inquiry_mode_);
1657 SendLinkLayerPacket(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001658 last_inquiry_ = now;
1659}
1660
1661void LinkLayerController::SetInquiryScanEnable(bool enable) {
1662 inquiry_scans_enabled_ = enable;
1663}
1664
1665void LinkLayerController::SetPageScanEnable(bool enable) {
1666 page_scans_enabled_ = enable;
1667}
1668
Myles Watsone22dde22019-01-18 11:42:33 -08001669} // namespace test_vendor_lib