blob: a272f84ae563b4ead20febc56ab216b51e624fcf [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"
Myles Watsone22dde22019-01-18 11:42:33 -080022#include "packets/hci/acl_packet_builder.h"
23#include "packets/hci/command_packet_view.h"
Myles Watsone22dde22019-01-18 11:42:33 -080024#include "packets/hci/sco_packet_builder.h"
Chienyuan3d8a8032019-11-01 18:04:07 +080025#include "packets/raw_builder.h"
Chienyuandb55f312019-10-31 14:01:28 +080026
27#include "packet/raw_builder.h"
Myles Watsone22dde22019-01-18 11:42:33 -080028
29using std::vector;
30using namespace std::chrono;
31using namespace test_vendor_lib::packets;
32
33namespace test_vendor_lib {
34
35// TODO: Model Rssi?
36static uint8_t GetRssi() {
37 static uint8_t rssi = 0;
38 rssi += 5;
39 if (rssi > 128) {
40 rssi = rssi % 7;
41 }
42 return -(rssi);
43}
44
Chienyuandb55f312019-10-31 14:01:28 +080045void LinkLayerController::SendLeLinkLayerPacket(
46 std::unique_ptr<model::packets::LinkLayerPacketBuilder> packet) {
47 std::shared_ptr<model::packets::LinkLayerPacketBuilder> shared_packet =
48 std::move(packet);
49 ScheduleTask(milliseconds(50), [this, shared_packet]() {
50 send_to_remote_(std::move(shared_packet), Phy::Type::LOW_ENERGY);
51 });
Myles Watsone22dde22019-01-18 11:42:33 -080052}
53
Chienyuandb55f312019-10-31 14:01:28 +080054void LinkLayerController::SendLinkLayerPacket(
55 std::unique_ptr<model::packets::LinkLayerPacketBuilder> packet) {
56 std::shared_ptr<model::packets::LinkLayerPacketBuilder> shared_packet =
57 std::move(packet);
58 ScheduleTask(milliseconds(50), [this, shared_packet]() {
59 send_to_remote_(std::move(shared_packet), Phy::Type::BR_EDR);
60 });
Myles Watsone22dde22019-01-18 11:42:33 -080061}
62
Chienyuan3d8a8032019-11-01 18:04:07 +080063bluetooth::hci::ErrorCode LinkLayerController::SendCommandToRemoteByAddress(
64 bluetooth::hci::OpCode opcode, PacketView<true> args, const Address& remote,
65 bool use_public_address) {
Myles Watsone22dde22019-01-18 11:42:33 -080066 Address local_address;
67 if (use_public_address) {
68 local_address = properties_.GetAddress();
69 } else {
70 local_address = properties_.GetLeAddress();
71 }
Chienyuandb55f312019-10-31 14:01:28 +080072
73 std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
74 std::make_unique<bluetooth::packet::RawBuilder>();
75 std::vector<uint8_t> payload_bytes(args.begin(), args.end());
76 raw_builder_ptr->AddOctets2(static_cast<uint16_t>(opcode));
77 raw_builder_ptr->AddOctets(payload_bytes);
78
79 auto command = model::packets::CommandBuilder::Create(
80 local_address, remote, std::move(raw_builder_ptr));
81
Myles Watsone22dde22019-01-18 11:42:33 -080082 SendLinkLayerPacket(std::move(command));
Chienyuan3d8a8032019-11-01 18:04:07 +080083 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -080084}
85
Chienyuan3d8a8032019-11-01 18:04:07 +080086bluetooth::hci::ErrorCode LinkLayerController::SendCommandToRemoteByHandle(
87 bluetooth::hci::OpCode opcode, PacketView<true> args, uint16_t handle) {
Myles Watsone22dde22019-01-18 11:42:33 -080088 // TODO: Handle LE connections
89 bool use_public_address = true;
Myles Watson96723532019-09-02 14:52:46 -070090 if (!connections_.HasHandle(handle)) {
Chienyuan3d8a8032019-11-01 18:04:07 +080091 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Myles Watsone22dde22019-01-18 11:42:33 -080092 }
Myles Watson96723532019-09-02 14:52:46 -070093 return SendCommandToRemoteByAddress(opcode, args, connections_.GetAddress(handle), use_public_address);
Myles Watsone22dde22019-01-18 11:42:33 -080094}
95
96hci::Status LinkLayerController::SendAclToRemote(AclPacketView acl_packet) {
Myles Watsone22dde22019-01-18 11:42:33 -080097 uint16_t handle = acl_packet.GetHandle();
Myles Watson96723532019-09-02 14:52:46 -070098 if (!connections_.HasHandle(handle)) {
Myles Watsone22dde22019-01-18 11:42:33 -080099 return hci::Status::UNKNOWN_CONNECTION;
100 }
101
Myles Watson96723532019-09-02 14:52:46 -0700102 Address my_address = properties_.GetAddress();
103 Address destination = connections_.GetAddress(handle);
104 if (connections_.GetOwnAddressType(handle) != 0) { // If it's not public, it must be LE
105 my_address = properties_.GetLeAddress();
106 }
Myles Watsone22dde22019-01-18 11:42:33 -0800107
Myles Watson1a0a0da2019-10-17 11:36:33 -0700108 LOG_INFO("%s(%s): handle 0x%x size %d", __func__, properties_.GetAddress().ToString().c_str(), handle,
Myles Watsone22dde22019-01-18 11:42:33 -0800109 static_cast<int>(acl_packet.size()));
110
Myles Watson8fe710e2019-09-05 09:01:00 -0700111 ScheduleTask(milliseconds(5), [this, handle]() {
Chienyuan3d8a8032019-11-01 18:04:07 +0800112 std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
113 std::make_unique<bluetooth::packet::RawBuilder>();
114 raw_builder_ptr->AddOctets1(0x01);
115 raw_builder_ptr->AddOctets2(handle);
116 raw_builder_ptr->AddOctets2(0x01);
117
118 auto packet = bluetooth::hci::EventPacketBuilder::Create(
119 bluetooth::hci::EventCode::NUMBER_OF_COMPLETED_PACKETS,
120 std::move(raw_builder_ptr));
121 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800122 });
Chienyuandb55f312019-10-31 14:01:28 +0800123
124 auto acl_payload = acl_packet.GetPayload();
125
126 std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
127 std::make_unique<bluetooth::packet::RawBuilder>();
128 std::vector<uint8_t> payload_bytes(acl_payload.begin(), acl_payload.end());
129
130 uint16_t first_two_bytes =
131 static_cast<uint16_t>(acl_packet.GetHandle()) +
132 (static_cast<uint16_t>(acl_packet.GetPacketBoundaryFlags()) << 12) +
133 (static_cast<uint16_t>(acl_packet.GetBroadcastFlags()) << 14);
134 raw_builder_ptr->AddOctets2(first_two_bytes);
135 raw_builder_ptr->AddOctets2(static_cast<uint16_t>(payload_bytes.size()));
136 raw_builder_ptr->AddOctets(payload_bytes);
137
138 auto acl = model::packets::AclPacketBuilder::Create(
139 my_address, destination, std::move(raw_builder_ptr));
140
141 SendLinkLayerPacket(std::move(acl));
Myles Watsone22dde22019-01-18 11:42:33 -0800142 return hci::Status::SUCCESS;
143}
144
Chienyuandb55f312019-10-31 14:01:28 +0800145void LinkLayerController::IncomingPacket(
146 model::packets::LinkLayerPacketView incoming) {
147 ASSERT(incoming.IsValid());
148
Myles Watsone22dde22019-01-18 11:42:33 -0800149 // TODO: Resolvable private addresses?
150 if (incoming.GetDestinationAddress() != properties_.GetAddress() &&
151 incoming.GetDestinationAddress() != properties_.GetLeAddress() &&
152 incoming.GetDestinationAddress() != Address::kEmpty) {
153 // Drop packets not addressed to me
154 return;
155 }
156
157 switch (incoming.GetType()) {
Chienyuandb55f312019-10-31 14:01:28 +0800158 case model::packets::PacketType::ACL:
Myles Watsone22dde22019-01-18 11:42:33 -0800159 IncomingAclPacket(incoming);
160 break;
Chienyuandb55f312019-10-31 14:01:28 +0800161 case model::packets::PacketType::COMMAND:
Myles Watsone22dde22019-01-18 11:42:33 -0800162 IncomingCommandPacket(incoming);
163 break;
Chienyuandb55f312019-10-31 14:01:28 +0800164 case model::packets::PacketType::DISCONNECT:
Myles Watsone22dde22019-01-18 11:42:33 -0800165 IncomingDisconnectPacket(incoming);
166 break;
Chienyuandb55f312019-10-31 14:01:28 +0800167 case model::packets::PacketType::ENCRYPT_CONNECTION:
Myles Watsone22dde22019-01-18 11:42:33 -0800168 IncomingEncryptConnection(incoming);
169 break;
Chienyuandb55f312019-10-31 14:01:28 +0800170 case model::packets::PacketType::ENCRYPT_CONNECTION_RESPONSE:
Myles Watsone22dde22019-01-18 11:42:33 -0800171 IncomingEncryptConnectionResponse(incoming);
172 break;
Chienyuandb55f312019-10-31 14:01:28 +0800173 case model::packets::PacketType::INQUIRY:
Myles Watsone22dde22019-01-18 11:42:33 -0800174 if (inquiry_scans_enabled_) {
175 IncomingInquiryPacket(incoming);
176 }
177 break;
Chienyuandb55f312019-10-31 14:01:28 +0800178 case model::packets::PacketType::INQUIRY_RESPONSE:
Myles Watsone22dde22019-01-18 11:42:33 -0800179 IncomingInquiryResponsePacket(incoming);
180 break;
Chienyuandb55f312019-10-31 14:01:28 +0800181 case model::packets::PacketType::IO_CAPABILITY_REQUEST:
Myles Watsone22dde22019-01-18 11:42:33 -0800182 IncomingIoCapabilityRequestPacket(incoming);
183 break;
Chienyuandb55f312019-10-31 14:01:28 +0800184 case model::packets::PacketType::IO_CAPABILITY_NEGATIVE_RESPONSE:
Myles Watsone22dde22019-01-18 11:42:33 -0800185 IncomingIoCapabilityNegativeResponsePacket(incoming);
186 break;
Chienyuandb55f312019-10-31 14:01:28 +0800187 case model::packets::PacketType::LE_ADVERTISEMENT:
Myles Watsone22dde22019-01-18 11:42:33 -0800188 if (le_scan_enable_ || le_connect_) {
189 IncomingLeAdvertisementPacket(incoming);
190 }
191 break;
Chienyuandb55f312019-10-31 14:01:28 +0800192 case model::packets::PacketType::LE_CONNECT:
Myles Watson96723532019-09-02 14:52:46 -0700193 IncomingLeConnectPacket(incoming);
194 break;
Chienyuandb55f312019-10-31 14:01:28 +0800195 case model::packets::PacketType::LE_CONNECT_COMPLETE:
Myles Watson96723532019-09-02 14:52:46 -0700196 IncomingLeConnectCompletePacket(incoming);
197 break;
Chienyuandb55f312019-10-31 14:01:28 +0800198 case model::packets::PacketType::LE_SCAN:
Myles Watsone22dde22019-01-18 11:42:33 -0800199 // TODO: Check Advertising flags and see if we are scannable.
200 IncomingLeScanPacket(incoming);
201 break;
Chienyuandb55f312019-10-31 14:01:28 +0800202 case model::packets::PacketType::LE_SCAN_RESPONSE:
Myles Watsone22dde22019-01-18 11:42:33 -0800203 if (le_scan_enable_ && le_scan_type_ == 1) {
204 IncomingLeScanResponsePacket(incoming);
205 }
206 break;
Chienyuandb55f312019-10-31 14:01:28 +0800207 case model::packets::PacketType::PAGE:
Myles Watsone22dde22019-01-18 11:42:33 -0800208 if (page_scans_enabled_) {
209 IncomingPagePacket(incoming);
210 }
211 break;
Chienyuandb55f312019-10-31 14:01:28 +0800212 case model::packets::PacketType::PAGE_RESPONSE:
Chienyuan Huang85471e42019-11-06 12:52:58 +0000213 IncomingPageResponsePacket(incoming);
214 break;
Chienyuandb55f312019-10-31 14:01:28 +0800215 case model::packets::PacketType::PAGE_REJECT:
216 IncomingPageRejectPacket(incoming);
217 break;
218 case model::packets::PacketType::RESPONSE:
Myles Watsone22dde22019-01-18 11:42:33 -0800219 IncomingResponsePacket(incoming);
220 break;
221 default:
Myles Watson1a0a0da2019-10-17 11:36:33 -0700222 LOG_WARN("Dropping unhandled packet of type %d", static_cast<int32_t>(incoming.GetType()));
Myles Watsone22dde22019-01-18 11:42:33 -0800223 }
224}
225
Chienyuandb55f312019-10-31 14:01:28 +0800226void LinkLayerController::IncomingAclPacket(
227 model::packets::LinkLayerPacketView incoming) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700228 LOG_INFO("Acl Packet %s -> %s", incoming.GetSourceAddress().ToString().c_str(),
Myles Watsone22dde22019-01-18 11:42:33 -0800229 incoming.GetDestinationAddress().ToString().c_str());
Chienyuandb55f312019-10-31 14:01:28 +0800230
231 auto acl = model::packets::AclPacketView::Create(incoming);
232 ASSERT(acl.IsValid());
233 auto payload = acl.GetPayload();
234 std::shared_ptr<std::vector<uint8_t>> payload_bytes =
235 std::make_shared<std::vector<uint8_t>>(payload.begin(), payload.end());
236
237 AclPacketView acl_view = AclPacketView::Create(payload_bytes);
Myles Watson1a0a0da2019-10-17 11:36:33 -0700238 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 -0700239 uint16_t local_handle = connections_.GetHandle(incoming.GetSourceAddress());
Myles Watson1a0a0da2019-10-17 11:36:33 -0700240 LOG_INFO("%s: local handle 0x%x", __func__, local_handle);
Myles Watsone22dde22019-01-18 11:42:33 -0800241
242 acl::PacketBoundaryFlagsType boundary_flags = acl_view.GetPacketBoundaryFlags();
243 acl::BroadcastFlagsType broadcast_flags = acl_view.GetBroadcastFlags();
Chienyuandb55f312019-10-31 14:01:28 +0800244 std::unique_ptr<RawBuilder> builder = std::make_unique<RawBuilder>();
245 std::vector<uint8_t> raw_data(acl_view.GetPayload().begin(),
246 acl_view.GetPayload().end());
247 builder->AddOctets(raw_data);
Myles Watson96723532019-09-02 14:52:46 -0700248 send_acl_(AclPacketBuilder::Create(local_handle, boundary_flags, broadcast_flags, std::move(builder))->ToVector());
Myles Watsone22dde22019-01-18 11:42:33 -0800249}
250
Chienyuandb55f312019-10-31 14:01:28 +0800251void LinkLayerController::IncomingCommandPacket(
252 model::packets::LinkLayerPacketView incoming) {
Myles Watsone22dde22019-01-18 11:42:33 -0800253 // TODO: Check the destination address to see if this packet is for me.
Chienyuandb55f312019-10-31 14:01:28 +0800254 auto command = model::packets::CommandView::Create(incoming);
255 ASSERT(command.IsValid());
256
257 auto args = command.GetPayload().begin();
Myles Watsone22dde22019-01-18 11:42:33 -0800258 std::vector<uint64_t> response_data;
Chienyuandb55f312019-10-31 14:01:28 +0800259 hci::OpCode opcode = static_cast<hci::OpCode>(args.extract<uint16_t>());
Chienyuan3d8a8032019-11-01 18:04:07 +0800260 std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
261 std::make_unique<bluetooth::packet::RawBuilder>();
Myles Watsone22dde22019-01-18 11:42:33 -0800262
263 switch (opcode) {
264 case (hci::OpCode::REMOTE_NAME_REQUEST): {
265 std::vector<uint8_t> name = properties_.GetName();
Myles Watson1a0a0da2019-10-17 11:36:33 -0700266 LOG_INFO("Remote Name (Local Name) %d", static_cast<int>(name.size()));
Chienyuan3d8a8032019-11-01 18:04:07 +0800267 raw_builder_ptr->AddOctets1(
268 static_cast<uint8_t>(bluetooth::hci::ErrorCode::SUCCESS));
269 raw_builder_ptr->AddOctets8(name.size());
270 raw_builder_ptr->AddOctets(name);
Myles Watsone22dde22019-01-18 11:42:33 -0800271 } break;
272 case (hci::OpCode::READ_REMOTE_SUPPORTED_FEATURES):
Myles Watson1a0a0da2019-10-17 11:36:33 -0700273 LOG_INFO("(%s) Remote Supported Features Requested by: %s %x",
Myles Watsone22dde22019-01-18 11:42:33 -0800274 incoming.GetDestinationAddress().ToString().c_str(), incoming.GetSourceAddress().ToString().c_str(),
275 static_cast<int>(properties_.GetSupportedFeatures()));
Chienyuan3d8a8032019-11-01 18:04:07 +0800276 raw_builder_ptr->AddOctets1(
277 static_cast<uint8_t>(bluetooth::hci::ErrorCode::SUCCESS));
278 raw_builder_ptr->AddOctets8(properties_.GetSupportedFeatures());
Myles Watsone22dde22019-01-18 11:42:33 -0800279 break;
280 case (hci::OpCode::READ_REMOTE_EXTENDED_FEATURES): {
281 uint8_t page_number = (args + 2).extract<uint8_t>(); // skip the handle
Myles Watson1a0a0da2019-10-17 11:36:33 -0700282 LOG_INFO("(%s) Remote Extended Features %d Requested by: %s", incoming.GetDestinationAddress().ToString().c_str(),
283 page_number, incoming.GetSourceAddress().ToString().c_str());
Myles Watsone22dde22019-01-18 11:42:33 -0800284 uint8_t max_page_number = properties_.GetExtendedFeaturesMaximumPageNumber();
285 if (page_number > max_page_number) {
Chienyuan3d8a8032019-11-01 18:04:07 +0800286 raw_builder_ptr->AddOctets1(static_cast<uint8_t>(
287 bluetooth::hci::ErrorCode::INVALID_HCI_COMMAND_PARAMETERS));
288 raw_builder_ptr->AddOctets1(page_number);
289 raw_builder_ptr->AddOctets1(max_page_number);
290 raw_builder_ptr->AddOctets8(0);
Myles Watsone22dde22019-01-18 11:42:33 -0800291 } else {
Chienyuan3d8a8032019-11-01 18:04:07 +0800292 raw_builder_ptr->AddOctets1(
293 static_cast<uint8_t>(bluetooth::hci::ErrorCode::SUCCESS));
294 raw_builder_ptr->AddOctets1(page_number);
295 raw_builder_ptr->AddOctets1(max_page_number);
296 raw_builder_ptr->AddOctets8(
297 properties_.GetExtendedFeatures(page_number));
Myles Watsone22dde22019-01-18 11:42:33 -0800298 }
299 } break;
300 case (hci::OpCode::READ_REMOTE_VERSION_INFORMATION):
Chienyuan3d8a8032019-11-01 18:04:07 +0800301 raw_builder_ptr->AddOctets1(
302 static_cast<uint8_t>(bluetooth::hci::ErrorCode::SUCCESS));
303 raw_builder_ptr->AddOctets1(properties_.GetLmpPalVersion());
304 raw_builder_ptr->AddOctets2(properties_.GetManufacturerName());
305 raw_builder_ptr->AddOctets2(properties_.GetLmpPalSubversion());
Myles Watsone22dde22019-01-18 11:42:33 -0800306 break;
307 case (hci::OpCode::READ_CLOCK_OFFSET):
Chienyuan3d8a8032019-11-01 18:04:07 +0800308 raw_builder_ptr->AddOctets1(
309 static_cast<uint8_t>(bluetooth::hci::ErrorCode::SUCCESS));
310 raw_builder_ptr->AddOctets2(properties_.GetClockOffset());
Myles Watsone22dde22019-01-18 11:42:33 -0800311 break;
312 default:
Myles Watson1a0a0da2019-10-17 11:36:33 -0700313 LOG_INFO("Dropping unhandled command 0x%04x", static_cast<uint16_t>(opcode));
Myles Watsone22dde22019-01-18 11:42:33 -0800314 return;
315 }
Chienyuandb55f312019-10-31 14:01:28 +0800316
Chienyuandb55f312019-10-31 14:01:28 +0800317 for (uint64_t data : response_data) {
318 raw_builder_ptr->AddOctets8(data);
319 }
320
321 auto response = model::packets::ResponseBuilder::Create(
322 properties_.GetAddress(), incoming.GetSourceAddress(),
323 static_cast<uint16_t>(opcode), std::move(raw_builder_ptr));
324
325 SendLinkLayerPacket(std::move(response));
Myles Watsone22dde22019-01-18 11:42:33 -0800326}
327
Chienyuandb55f312019-10-31 14:01:28 +0800328void LinkLayerController::IncomingDisconnectPacket(
329 model::packets::LinkLayerPacketView incoming) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700330 LOG_INFO("Disconnect Packet");
Chienyuandb55f312019-10-31 14:01:28 +0800331 auto disconnect = model::packets::DisconnectView::Create(incoming);
332 ASSERT(disconnect.IsValid());
333
Myles Watsone22dde22019-01-18 11:42:33 -0800334 Address peer = incoming.GetSourceAddress();
Myles Watson96723532019-09-02 14:52:46 -0700335 uint16_t handle = connections_.GetHandle(peer);
Myles Watsone22dde22019-01-18 11:42:33 -0800336 if (handle == acl::kReservedHandle) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700337 LOG_INFO("%s: Unknown connection @%s", __func__, peer.ToString().c_str());
Myles Watsone22dde22019-01-18 11:42:33 -0800338 return;
339 }
Myles Watson1a0a0da2019-10-17 11:36:33 -0700340 ASSERT_LOG(connections_.Disconnect(handle), "GetHandle() returned invalid handle %hx", handle);
Myles Watsone22dde22019-01-18 11:42:33 -0800341
342 uint8_t reason = disconnect.GetReason();
Myles Watson8fe710e2019-09-05 09:01:00 -0700343 ScheduleTask(milliseconds(20), [this, handle, reason]() { DisconnectCleanup(handle, reason); });
Myles Watsone22dde22019-01-18 11:42:33 -0800344}
345
Chienyuandb55f312019-10-31 14:01:28 +0800346void LinkLayerController::IncomingEncryptConnection(
347 model::packets::LinkLayerPacketView incoming) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700348 LOG_INFO("%s", __func__);
Chienyuandb55f312019-10-31 14:01:28 +0800349
Myles Watsone22dde22019-01-18 11:42:33 -0800350 // TODO: Check keys
351 Address peer = incoming.GetSourceAddress();
Myles Watson96723532019-09-02 14:52:46 -0700352 uint16_t handle = connections_.GetHandle(peer);
Myles Watsone22dde22019-01-18 11:42:33 -0800353 if (handle == acl::kReservedHandle) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700354 LOG_INFO("%s: Unknown connection @%s", __func__, peer.ToString().c_str());
Myles Watsone22dde22019-01-18 11:42:33 -0800355 return;
356 }
Chienyuan3d8a8032019-11-01 18:04:07 +0800357 auto packet = bluetooth::hci::EncryptionChangeBuilder::Create(
358 bluetooth::hci::ErrorCode::SUCCESS, handle,
359 bluetooth::hci::EncryptionEnabled::ON);
360 send_event_(std::move(packet));
Chienyuandb55f312019-10-31 14:01:28 +0800361 auto response = model::packets::EncryptConnectionResponseBuilder::Create(
362 properties_.GetAddress(), peer, security_manager_.GetKey(peer));
363 SendLinkLayerPacket(std::move(response));
Myles Watsone22dde22019-01-18 11:42:33 -0800364}
365
Chienyuandb55f312019-10-31 14:01:28 +0800366void LinkLayerController::IncomingEncryptConnectionResponse(
367 model::packets::LinkLayerPacketView incoming) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700368 LOG_INFO("%s", __func__);
Myles Watsone22dde22019-01-18 11:42:33 -0800369 // TODO: Check keys
Myles Watson96723532019-09-02 14:52:46 -0700370 uint16_t handle = connections_.GetHandle(incoming.GetSourceAddress());
Myles Watsone22dde22019-01-18 11:42:33 -0800371 if (handle == acl::kReservedHandle) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700372 LOG_INFO("%s: Unknown connection @%s", __func__, incoming.GetSourceAddress().ToString().c_str());
Myles Watsone22dde22019-01-18 11:42:33 -0800373 return;
374 }
Chienyuan3d8a8032019-11-01 18:04:07 +0800375 auto packet = bluetooth::hci::EncryptionChangeBuilder::Create(
376 bluetooth::hci::ErrorCode::SUCCESS, handle,
377 bluetooth::hci::EncryptionEnabled::ON);
378 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800379}
380
Chienyuandb55f312019-10-31 14:01:28 +0800381void LinkLayerController::IncomingInquiryPacket(
382 model::packets::LinkLayerPacketView incoming) {
383 auto inquiry = model::packets::InquiryView::Create(incoming);
384 ASSERT(inquiry.IsValid());
Myles Watsone22dde22019-01-18 11:42:33 -0800385
Chienyuandb55f312019-10-31 14:01:28 +0800386 Address peer = incoming.GetSourceAddress();
Myles Watsone22dde22019-01-18 11:42:33 -0800387
Chienyuandb55f312019-10-31 14:01:28 +0800388 switch (inquiry.GetInquiryType()) {
389 case (model::packets::InquiryType::STANDARD): {
390 auto inquiry_response = model::packets::InquiryResponseBuilder::Create(
391 properties_.GetAddress(), peer,
392 properties_.GetPageScanRepetitionMode(),
393 properties_.GetClassOfDevice(), properties_.GetClockOffset());
394 SendLinkLayerPacket(std::move(inquiry_response));
395 } break;
396 case (model::packets::InquiryType::RSSI): {
397 auto inquiry_response =
398 model::packets::InquiryResponseWithRssiBuilder::Create(
399 properties_.GetAddress(), peer,
400 properties_.GetPageScanRepetitionMode(),
401 properties_.GetClassOfDevice(), properties_.GetClockOffset(),
402 GetRssi());
403 SendLinkLayerPacket(std::move(inquiry_response));
404 } break;
405 case (model::packets::InquiryType::EXTENDED): {
406 auto inquiry_response =
407 model::packets::ExtendedInquiryResponseBuilder::Create(
408 properties_.GetAddress(), peer,
409 properties_.GetPageScanRepetitionMode(),
410 properties_.GetClassOfDevice(), properties_.GetClockOffset(),
411 GetRssi(), properties_.GetExtendedInquiryData());
412 SendLinkLayerPacket(std::move(inquiry_response));
413
414 } break;
Myles Watsone22dde22019-01-18 11:42:33 -0800415 default:
Myles Watson1a0a0da2019-10-17 11:36:33 -0700416 LOG_WARN("Unhandled Incoming Inquiry of type %d", static_cast<int>(inquiry.GetType()));
Myles Watsone22dde22019-01-18 11:42:33 -0800417 return;
418 }
Chienyuandb55f312019-10-31 14:01:28 +0800419 // TODO: Send an Inquiry Response Notification Event 7.7.74
Myles Watsone22dde22019-01-18 11:42:33 -0800420}
421
Chienyuandb55f312019-10-31 14:01:28 +0800422void LinkLayerController::IncomingInquiryResponsePacket(
423 model::packets::LinkLayerPacketView incoming) {
424 auto basic_inquiry_response =
425 model::packets::BasicInquiryResponseView::Create(incoming);
426 ASSERT(basic_inquiry_response.IsValid());
Myles Watsone22dde22019-01-18 11:42:33 -0800427 std::vector<uint8_t> eir;
428
Chienyuandb55f312019-10-31 14:01:28 +0800429 switch (basic_inquiry_response.GetInquiryType()) {
430 case (model::packets::InquiryType::STANDARD): {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700431 LOG_WARN("Incoming Standard Inquiry Response");
Myles Watsone22dde22019-01-18 11:42:33 -0800432 // TODO: Support multiple inquiries in the same packet.
Chienyuandb55f312019-10-31 14:01:28 +0800433 auto inquiry_response =
434 model::packets::InquiryResponseView::Create(basic_inquiry_response);
435 ASSERT(inquiry_response.IsValid());
Chienyuan3d8a8032019-11-01 18:04:07 +0800436
437 auto page_scan_repetition_mode =
438 (bluetooth::hci::PageScanRepetitionMode)
439 inquiry_response.GetPageScanRepetitionMode();
440
441 auto packet = bluetooth::hci::InquiryResultBuilder::Create(
442 0x01, inquiry_response.GetSourceAddress(), page_scan_repetition_mode,
Chienyuandb55f312019-10-31 14:01:28 +0800443 inquiry_response.GetClassOfDevice(),
444 inquiry_response.GetClockOffset());
Chienyuan3d8a8032019-11-01 18:04:07 +0800445
446 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800447 } break;
448
Chienyuandb55f312019-10-31 14:01:28 +0800449 case (model::packets::InquiryType::RSSI): {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700450 LOG_WARN("Incoming RSSI Inquiry Response");
Chienyuandb55f312019-10-31 14:01:28 +0800451 auto inquiry_response =
452 model::packets::InquiryResponseWithRssiView::Create(
453 basic_inquiry_response);
454 ASSERT(inquiry_response.IsValid());
Chienyuan3d8a8032019-11-01 18:04:07 +0800455
456 auto page_scan_repetition_mode =
457 (bluetooth::hci::PageScanRepetitionMode)
458 inquiry_response.GetPageScanRepetitionMode();
459
460 auto packet = bluetooth::hci::InquiryResultWithRssiBuilder::Create(
461 0x01, inquiry_response.GetSourceAddress(), page_scan_repetition_mode,
462 inquiry_response.GetClassOfDevice(),
463 inquiry_response.GetClockOffset(), inquiry_response.GetRssi());
464 send_event_(std::move(packet));
Chienyuandb55f312019-10-31 14:01:28 +0800465 } break;
Myles Watsone22dde22019-01-18 11:42:33 -0800466
Chienyuandb55f312019-10-31 14:01:28 +0800467 case (model::packets::InquiryType::EXTENDED): {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700468 LOG_WARN("Incoming Extended Inquiry Response");
Chienyuandb55f312019-10-31 14:01:28 +0800469 auto inquiry_response =
470 model::packets::ExtendedInquiryResponseView::Create(
471 basic_inquiry_response);
472 ASSERT(inquiry_response.IsValid());
Chienyuan3d8a8032019-11-01 18:04:07 +0800473
474 std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
475 std::make_unique<bluetooth::packet::RawBuilder>();
476 raw_builder_ptr->AddOctets1(0x01); // num_responses
477 raw_builder_ptr->AddAddress(inquiry_response.GetSourceAddress());
478 raw_builder_ptr->AddOctets1(inquiry_response.GetPageScanRepetitionMode());
479 raw_builder_ptr->AddOctets1(0x00); // _reserved_
480 auto class_of_device = inquiry_response.GetClassOfDevice();
481 for (unsigned int i = 0; i < class_of_device.kLength; i++) {
482 raw_builder_ptr->AddOctets1(class_of_device.cod[i]);
483 }
484 raw_builder_ptr->AddOctets2(inquiry_response.GetClockOffset());
485 raw_builder_ptr->AddOctets1(inquiry_response.GetRssi());
486 raw_builder_ptr->AddOctets(inquiry_response.GetExtendedData());
487
488 auto packet = bluetooth::hci::EventPacketBuilder::Create(
489 bluetooth::hci::EventCode::EXTENDED_INQUIRY_RESULT,
490 std::move(raw_builder_ptr));
491 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800492 } break;
493 default:
Chienyuandb55f312019-10-31 14:01:28 +0800494 LOG_WARN("Unhandled Incoming Inquiry Response of type %d",
495 static_cast<int>(basic_inquiry_response.GetInquiryType()));
Myles Watsone22dde22019-01-18 11:42:33 -0800496 }
497}
498
Chienyuandb55f312019-10-31 14:01:28 +0800499void LinkLayerController::IncomingIoCapabilityRequestPacket(
500 model::packets::LinkLayerPacketView incoming) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700501 LOG_DEBUG("%s", __func__);
Myles Watsone22dde22019-01-18 11:42:33 -0800502 if (!simple_pairing_mode_enabled_) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700503 LOG_WARN("%s: Only simple pairing mode is implemented", __func__);
Myles Watsone22dde22019-01-18 11:42:33 -0800504 return;
505 }
Chienyuan Huang85471e42019-11-06 12:52:58 +0000506
Chienyuandb55f312019-10-31 14:01:28 +0800507 auto request = model::packets::IoCapabilityRequestView::Create(incoming);
508 ASSERT(request.IsValid());
509
510 Address peer = incoming.GetSourceAddress();
Myles Watsone22dde22019-01-18 11:42:33 -0800511 uint8_t io_capability = request.GetIoCapability();
512 uint8_t oob_data_present = request.GetOobDataPresent();
513 uint8_t authentication_requirements = request.GetAuthenticationRequirements();
514
Myles Watson96723532019-09-02 14:52:46 -0700515 uint16_t handle = connections_.GetHandle(peer);
Myles Watsone22dde22019-01-18 11:42:33 -0800516 if (handle == acl::kReservedHandle) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700517 LOG_INFO("%s: Device not connected %s", __func__, peer.ToString().c_str());
Myles Watsone22dde22019-01-18 11:42:33 -0800518 return;
519 }
520
521 security_manager_.AuthenticationRequest(peer, handle);
522
523 security_manager_.SetPeerIoCapability(peer, io_capability, oob_data_present, authentication_requirements);
524
Chienyuan3d8a8032019-11-01 18:04:07 +0800525 auto packet = bluetooth::hci::IoCapabilityResponseBuilder::Create(
526 peer, static_cast<bluetooth::hci::IoCapability>(io_capability),
527 static_cast<bluetooth::hci::OobDataPresent>(oob_data_present),
528 static_cast<bluetooth::hci::AuthenticationRequirements>(
529 authentication_requirements));
530 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800531
532 StartSimplePairing(peer);
533}
534
Chienyuandb55f312019-10-31 14:01:28 +0800535void LinkLayerController::IncomingIoCapabilityResponsePacket(
536 model::packets::LinkLayerPacketView incoming) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700537 LOG_DEBUG("%s", __func__);
Chienyuandb55f312019-10-31 14:01:28 +0800538
539 auto response = model::packets::IoCapabilityResponseView::Create(incoming);
540 ASSERT(response.IsValid());
541
Myles Watsone22dde22019-01-18 11:42:33 -0800542 Address peer = incoming.GetSourceAddress();
543 uint8_t io_capability = response.GetIoCapability();
544 uint8_t oob_data_present = response.GetOobDataPresent();
545 uint8_t authentication_requirements = response.GetAuthenticationRequirements();
546
Chienyuandb55f312019-10-31 14:01:28 +0800547 security_manager_.SetPeerIoCapability(peer, io_capability, oob_data_present,
548 authentication_requirements);
Myles Watsone22dde22019-01-18 11:42:33 -0800549
Chienyuan3d8a8032019-11-01 18:04:07 +0800550 auto packet = bluetooth::hci::IoCapabilityResponseBuilder::Create(
551 peer, static_cast<bluetooth::hci::IoCapability>(io_capability),
552 static_cast<bluetooth::hci::OobDataPresent>(oob_data_present),
553 static_cast<bluetooth::hci::AuthenticationRequirements>(
554 authentication_requirements));
555 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800556
557 PairingType pairing_type = security_manager_.GetSimplePairingType();
558 if (pairing_type != PairingType::INVALID) {
Chienyuandb55f312019-10-31 14:01:28 +0800559 ScheduleTask(milliseconds(5), [this, peer, pairing_type]() {
560 AuthenticateRemoteStage1(peer, pairing_type);
561 });
Myles Watsone22dde22019-01-18 11:42:33 -0800562 } else {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700563 LOG_INFO("%s: Security Manager returned INVALID", __func__);
Myles Watsone22dde22019-01-18 11:42:33 -0800564 }
565}
566
Chienyuandb55f312019-10-31 14:01:28 +0800567void LinkLayerController::IncomingIoCapabilityNegativeResponsePacket(
568 model::packets::LinkLayerPacketView incoming) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700569 LOG_DEBUG("%s", __func__);
Myles Watsone22dde22019-01-18 11:42:33 -0800570 Address peer = incoming.GetSourceAddress();
571
Myles Watson1a0a0da2019-10-17 11:36:33 -0700572 ASSERT(security_manager_.GetAuthenticationAddress() == peer);
Myles Watsone22dde22019-01-18 11:42:33 -0800573
574 security_manager_.InvalidateIoCapabilities();
575}
576
Chienyuandb55f312019-10-31 14:01:28 +0800577void LinkLayerController::IncomingLeAdvertisementPacket(
578 model::packets::LinkLayerPacketView incoming) {
Myles Watsone22dde22019-01-18 11:42:33 -0800579 // TODO: Handle multiple advertisements per packet.
580
Myles Watson96723532019-09-02 14:52:46 -0700581 Address address = incoming.GetSourceAddress();
Chienyuandb55f312019-10-31 14:01:28 +0800582 auto advertisement = model::packets::LeAdvertisementView::Create(incoming);
583 ASSERT(advertisement.IsValid());
584 auto adv_type = static_cast<LeAdvertisement::AdvertisementType>(
585 advertisement.GetAdvertisementType());
586 auto address_type =
587 static_cast<LeAdvertisement::AddressType>(advertisement.GetAddressType());
Myles Watsone22dde22019-01-18 11:42:33 -0800588
589 if (le_scan_enable_) {
Chienyuandb55f312019-10-31 14:01:28 +0800590 vector<uint8_t> ad = advertisement.GetData();
591
Chienyuan3d8a8032019-11-01 18:04:07 +0800592 std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
593 std::make_unique<bluetooth::packet::RawBuilder>();
594 raw_builder_ptr->AddOctets1(
595 static_cast<uint8_t>(bluetooth::hci::SubeventCode::ADVERTISING_REPORT));
596 raw_builder_ptr->AddOctets1(0x01); // num reports
597 raw_builder_ptr->AddOctets1(static_cast<uint8_t>(adv_type));
598 raw_builder_ptr->AddOctets1(static_cast<uint8_t>(address_type));
599 raw_builder_ptr->AddAddress(address);
600 raw_builder_ptr->AddOctets1(ad.size());
601 raw_builder_ptr->AddOctets(ad);
602 raw_builder_ptr->AddOctets1(GetRssi());
603 auto packet = bluetooth::hci::EventPacketBuilder::Create(
604 bluetooth::hci::EventCode::LE_META_EVENT, std::move(raw_builder_ptr));
605 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800606 }
607
Myles Watsone22dde22019-01-18 11:42:33 -0800608 // Active scanning
609 if (le_scan_enable_ && le_scan_type_ == 1) {
Chienyuandb55f312019-10-31 14:01:28 +0800610 auto to_send = model::packets::LeScanBuilder::Create(
611 properties_.GetLeAddress(), address);
612 SendLeLinkLayerPacket(std::move(to_send));
Myles Watsone22dde22019-01-18 11:42:33 -0800613 }
Myles Watson96723532019-09-02 14:52:46 -0700614
615 // Connect
616 if ((le_connect_ && le_peer_address_ == address && le_peer_address_type_ == static_cast<uint8_t>(address_type) &&
617 (adv_type == LeAdvertisement::AdvertisementType::ADV_IND ||
618 adv_type == LeAdvertisement::AdvertisementType::ADV_DIRECT_IND)) ||
619 (LeWhiteListContainsDevice(address, static_cast<uint8_t>(address_type)))) {
620 if (!connections_.CreatePendingLeConnection(incoming.GetSourceAddress(), static_cast<uint8_t>(address_type))) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700621 LOG_WARN("%s: CreatePendingLeConnection failed for connection to %s (type %hhx)", __func__,
Myles Watson96723532019-09-02 14:52:46 -0700622 incoming.GetSourceAddress().ToString().c_str(), address_type);
623 }
Myles Watson1a0a0da2019-10-17 11:36:33 -0700624 LOG_INFO("%s: connecting to %s (type %hhx)", __func__, incoming.GetSourceAddress().ToString().c_str(),
Myles Watson96723532019-09-02 14:52:46 -0700625 address_type);
626 le_connect_ = false;
627 le_scan_enable_ = false;
628
Chienyuandb55f312019-10-31 14:01:28 +0800629 auto to_send = model::packets::LeConnectBuilder::Create(
630 properties_.GetLeAddress(), incoming.GetSourceAddress(),
631 le_connection_interval_min_, le_connection_interval_max_,
632 le_connection_latency_, le_connection_supervision_timeout_,
633 static_cast<uint8_t>(le_address_type_));
634
635 SendLeLinkLayerPacket(std::move(to_send));
Myles Watson96723532019-09-02 14:52:46 -0700636 }
637}
638
639void LinkLayerController::HandleLeConnection(Address address, uint8_t address_type, uint8_t own_address_type,
640 uint8_t role, uint16_t connection_interval, uint16_t connection_latency,
641 uint16_t supervision_timeout) {
642 // TODO: Choose between LeConnectionComplete and LeEnhancedConnectionComplete
643 uint16_t handle = connections_.CreateLeConnection(address, address_type, own_address_type);
644 if (handle == acl::kReservedHandle) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700645 LOG_WARN("%s: No pending connection for connection from %s (type %hhx)", __func__, address.ToString().c_str(),
646 address_type);
Myles Watson96723532019-09-02 14:52:46 -0700647 return;
648 }
Chienyuan3d8a8032019-11-01 18:04:07 +0800649 auto packet = bluetooth::hci::LeConnectionCompleteBuilder::Create(
650 bluetooth::hci::ErrorCode::SUCCESS, handle,
651 static_cast<bluetooth::hci::Role>(role),
652 static_cast<bluetooth::hci::AddressType>(address_type), address,
653 connection_interval, connection_latency, supervision_timeout,
654 static_cast<bluetooth::hci::MasterClockAccuracy>(0x00));
655 send_event_(std::move(packet));
Myles Watson96723532019-09-02 14:52:46 -0700656}
657
Chienyuandb55f312019-10-31 14:01:28 +0800658void LinkLayerController::IncomingLeConnectPacket(
659 model::packets::LinkLayerPacketView incoming) {
660 auto connect = model::packets::LeConnectView::Create(incoming);
661 ASSERT(connect.IsValid());
Myles Watson96723532019-09-02 14:52:46 -0700662 uint16_t connection_interval = (connect.GetLeConnectionIntervalMax() + connect.GetLeConnectionIntervalMin()) / 2;
663 if (!connections_.CreatePendingLeConnection(incoming.GetSourceAddress(),
664 static_cast<uint8_t>(connect.GetAddressType()))) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700665 LOG_WARN("%s: CreatePendingLeConnection failed for connection from %s (type %hhx)", __func__,
Myles Watson96723532019-09-02 14:52:46 -0700666 incoming.GetSourceAddress().ToString().c_str(), connect.GetAddressType());
667 return;
668 }
669 HandleLeConnection(incoming.GetSourceAddress(), static_cast<uint8_t>(connect.GetAddressType()),
670 static_cast<uint8_t>(properties_.GetLeAdvertisingOwnAddressType()),
671 static_cast<uint8_t>(hci::Role::SLAVE), connection_interval, connect.GetLeConnectionLatency(),
672 connect.GetLeConnectionSupervisionTimeout());
Chienyuandb55f312019-10-31 14:01:28 +0800673
674 auto to_send = model::packets::LeConnectCompleteBuilder::Create(
675 incoming.GetDestinationAddress(), incoming.GetSourceAddress(),
676 connection_interval, connect.GetLeConnectionLatency(),
677 connect.GetLeConnectionSupervisionTimeout(),
678 properties_.GetLeAdvertisingOwnAddressType());
679 SendLeLinkLayerPacket(std::move(to_send));
Myles Watson96723532019-09-02 14:52:46 -0700680}
681
Chienyuandb55f312019-10-31 14:01:28 +0800682void LinkLayerController::IncomingLeConnectCompletePacket(
683 model::packets::LinkLayerPacketView incoming) {
684 auto complete = model::packets::LeConnectCompleteView::Create(incoming);
685 ASSERT(complete.IsValid());
Myles Watson96723532019-09-02 14:52:46 -0700686 HandleLeConnection(incoming.GetSourceAddress(), static_cast<uint8_t>(complete.GetAddressType()),
687 static_cast<uint8_t>(le_address_type_), static_cast<uint8_t>(hci::Role::MASTER),
688 complete.GetLeConnectionInterval(), complete.GetLeConnectionLatency(),
689 complete.GetLeConnectionSupervisionTimeout());
Myles Watsone22dde22019-01-18 11:42:33 -0800690}
691
Chienyuandb55f312019-10-31 14:01:28 +0800692void LinkLayerController::IncomingLeScanPacket(
693 model::packets::LinkLayerPacketView incoming) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700694 LOG_INFO("LE Scan Packet");
Chienyuandb55f312019-10-31 14:01:28 +0800695
696 auto to_send = model::packets::LeScanResponseBuilder::Create(
697 properties_.GetLeAddress(), incoming.GetSourceAddress(),
698 static_cast<model::packets::AddressType>(properties_.GetLeAddressType()),
699 static_cast<model::packets::AdvertisementType>(
700 properties_.GetLeAdvertisementType()),
Myles Watsone22dde22019-01-18 11:42:33 -0800701 properties_.GetLeScanResponse());
Chienyuandb55f312019-10-31 14:01:28 +0800702
703 SendLeLinkLayerPacket(std::move(to_send));
Myles Watsone22dde22019-01-18 11:42:33 -0800704}
705
Chienyuandb55f312019-10-31 14:01:28 +0800706void LinkLayerController::IncomingLeScanResponsePacket(
707 model::packets::LinkLayerPacketView incoming) {
708 auto scan_response = model::packets::LeScanResponseView::Create(incoming);
709 ASSERT(scan_response.IsValid());
710 vector<uint8_t> ad = scan_response.GetData();
711 auto adv_type = static_cast<LeAdvertisement::AdvertisementType>(
712 scan_response.GetAdvertisementType());
713 auto address_type =
714 static_cast<LeAdvertisement::AddressType>(scan_response.GetAddressType());
Myles Watsone22dde22019-01-18 11:42:33 -0800715
Chienyuan3d8a8032019-11-01 18:04:07 +0800716 std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
717 std::make_unique<bluetooth::packet::RawBuilder>();
718 raw_builder_ptr->AddOctets1(
719 static_cast<uint8_t>(bluetooth::hci::SubeventCode::ADVERTISING_REPORT));
720 raw_builder_ptr->AddOctets1(0x01); // num reports
721 raw_builder_ptr->AddOctets1(static_cast<uint8_t>(adv_type));
722 raw_builder_ptr->AddOctets1(static_cast<uint8_t>(address_type));
723 raw_builder_ptr->AddAddress(incoming.GetSourceAddress());
724 raw_builder_ptr->AddOctets1(ad.size());
725 raw_builder_ptr->AddOctets(ad);
726 raw_builder_ptr->AddOctets1(GetRssi());
727 auto packet = bluetooth::hci::EventPacketBuilder::Create(
728 bluetooth::hci::EventCode::LE_META_EVENT, std::move(raw_builder_ptr));
729 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800730}
731
Chienyuandb55f312019-10-31 14:01:28 +0800732void LinkLayerController::IncomingPagePacket(
733 model::packets::LinkLayerPacketView incoming) {
734 auto page = model::packets::PageView::Create(incoming);
735 ASSERT(page.IsValid());
Myles Watson1a0a0da2019-10-17 11:36:33 -0700736 LOG_INFO("%s from %s", __func__, incoming.GetSourceAddress().ToString().c_str());
Myles Watsone22dde22019-01-18 11:42:33 -0800737
Myles Watson96723532019-09-02 14:52:46 -0700738 if (!connections_.CreatePendingConnection(incoming.GetSourceAddress())) {
Myles Watsone22dde22019-01-18 11:42:33 -0800739 // Send a response to indicate that we're busy, or drop the packet?
Myles Watson1a0a0da2019-10-17 11:36:33 -0700740 LOG_WARN("%s: Failed to create a pending connection for %s", __func__,
Myles Watson96723532019-09-02 14:52:46 -0700741 incoming.GetSourceAddress().ToString().c_str());
Myles Watsone22dde22019-01-18 11:42:33 -0800742 }
743
Chienyuan3d8a8032019-11-01 18:04:07 +0800744 bluetooth::hci::Address source_address;
745 bluetooth::hci::Address::FromString(page.GetSourceAddress().ToString(),
746 source_address);
747
748 auto packet = bluetooth::hci::ConnectionRequestBuilder::Create(
749 source_address, page.GetClassOfDevice(),
750 bluetooth::hci::ConnectionRequestLinkType::ACL);
751
752 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800753}
754
Chienyuandb55f312019-10-31 14:01:28 +0800755void LinkLayerController::IncomingPageRejectPacket(
756 model::packets::LinkLayerPacketView incoming) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700757 LOG_INFO("%s: %s", __func__, incoming.GetSourceAddress().ToString().c_str());
Chienyuandb55f312019-10-31 14:01:28 +0800758 auto reject = model::packets::PageRejectView::Create(incoming);
759 ASSERT(reject.IsValid());
Myles Watson1a0a0da2019-10-17 11:36:33 -0700760 LOG_INFO("%s: Sending CreateConnectionComplete", __func__);
Chienyuan3d8a8032019-11-01 18:04:07 +0800761 auto packet = bluetooth::hci::ConnectionCompleteBuilder::Create(
762 static_cast<bluetooth::hci::ErrorCode>(reject.GetReason()), 0x0eff,
763 incoming.GetSourceAddress(), bluetooth::hci::LinkType::ACL,
764 bluetooth::hci::Enable::DISABLED);
765 send_event_(std::move(packet));
Hansong Zhang4cb1cf52019-07-08 15:32:26 -0700766}
767
Chienyuandb55f312019-10-31 14:01:28 +0800768void LinkLayerController::IncomingPageResponsePacket(
769 model::packets::LinkLayerPacketView incoming) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700770 LOG_INFO("%s: %s", __func__, incoming.GetSourceAddress().ToString().c_str());
Myles Watson96723532019-09-02 14:52:46 -0700771 uint16_t handle = connections_.CreateConnection(incoming.GetSourceAddress());
Myles Watsone22dde22019-01-18 11:42:33 -0800772 if (handle == acl::kReservedHandle) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700773 LOG_WARN("%s: No free handles", __func__);
Myles Watsone22dde22019-01-18 11:42:33 -0800774 return;
775 }
Chienyuan3d8a8032019-11-01 18:04:07 +0800776 auto packet = bluetooth::hci::ConnectionCompleteBuilder::Create(
777 bluetooth::hci::ErrorCode::SUCCESS, handle, incoming.GetSourceAddress(),
778 bluetooth::hci::LinkType::ACL, bluetooth::hci::Enable::DISABLED);
779 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800780}
781
Chienyuandb55f312019-10-31 14:01:28 +0800782void LinkLayerController::IncomingResponsePacket(
783 model::packets::LinkLayerPacketView incoming) {
784 auto response = model::packets::ResponseView::Create(incoming);
785 ASSERT(response.IsValid());
Myles Watsone22dde22019-01-18 11:42:33 -0800786
787 // TODO: Check to see if I'm expecting this response.
788
789 hci::OpCode opcode = static_cast<hci::OpCode>(response.GetOpcode());
Chienyuandb55f312019-10-31 14:01:28 +0800790 auto args = response.GetPayload().begin();
Chienyuan3d8a8032019-11-01 18:04:07 +0800791 auto status = static_cast<bluetooth::hci::ErrorCode>(args.extract<uint8_t>());
Myles Watsone22dde22019-01-18 11:42:33 -0800792
Myles Watson96723532019-09-02 14:52:46 -0700793 uint16_t handle = connections_.GetHandle(incoming.GetSourceAddress());
Myles Watsone22dde22019-01-18 11:42:33 -0800794
795 switch (opcode) {
796 case (hci::OpCode::REMOTE_NAME_REQUEST): {
Chienyuan3d8a8032019-11-01 18:04:07 +0800797 std::array<uint8_t, 248> remote_name;
798 remote_name.fill(0x00);
799 uint64_t len = args.extract<uint64_t>();
800 if (len > 247) {
801 len = 247; // one byte for NULL octet (0x00)
Myles Watsone22dde22019-01-18 11:42:33 -0800802 }
Chienyuan3d8a8032019-11-01 18:04:07 +0800803 for (uint64_t i = 0; i < len; i++) {
804 remote_name[i] = args.extract<uint8_t>();
805 }
806 auto packet = bluetooth::hci::RemoteNameRequestCompleteBuilder::Create(
807 status, incoming.GetSourceAddress(), remote_name);
808 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800809 } break;
810 case (hci::OpCode::READ_REMOTE_SUPPORTED_FEATURES): {
Chienyuan3d8a8032019-11-01 18:04:07 +0800811 auto packet =
812 bluetooth::hci::ReadRemoteSupportedFeaturesCompleteBuilder::Create(
813 status, handle, args.extract<uint64_t>());
814 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800815 } break;
816 case (hci::OpCode::READ_REMOTE_EXTENDED_FEATURES): {
Chienyuan3d8a8032019-11-01 18:04:07 +0800817 if (status == bluetooth::hci::ErrorCode::SUCCESS) {
818 auto packet =
819 bluetooth::hci::ReadRemoteExtendedFeaturesCompleteBuilder::Create(
820 status, handle, args.extract<uint8_t>(),
821 args.extract<uint8_t>(), args.extract<uint64_t>());
822 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800823 } else {
Chienyuan3d8a8032019-11-01 18:04:07 +0800824 auto packet =
825 bluetooth::hci::ReadRemoteExtendedFeaturesCompleteBuilder::Create(
826 status, handle, 0, 0, 0);
827 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800828 }
829 } break;
830 case (hci::OpCode::READ_REMOTE_VERSION_INFORMATION): {
Chienyuan3d8a8032019-11-01 18:04:07 +0800831 auto packet =
832 bluetooth::hci::ReadRemoteVersionInformationCompleteBuilder::Create(
833 status, handle, args.extract<uint8_t>(), args.extract<uint16_t>(),
834 args.extract<uint16_t>());
835 send_event_(std::move(packet));
Myles Watson1a0a0da2019-10-17 11:36:33 -0700836 LOG_INFO("Read remote version handle 0x%04x", handle);
Myles Watsone22dde22019-01-18 11:42:33 -0800837 } break;
838 case (hci::OpCode::READ_CLOCK_OFFSET): {
Chienyuan3d8a8032019-11-01 18:04:07 +0800839 auto packet = bluetooth::hci::ReadClockOffsetCompleteBuilder::Create(
840 status, handle, args.extract<uint16_t>());
841 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800842 } break;
843 default:
Myles Watson1a0a0da2019-10-17 11:36:33 -0700844 LOG_INFO("Unhandled response to command 0x%04x", static_cast<uint16_t>(opcode));
Myles Watsone22dde22019-01-18 11:42:33 -0800845 }
846}
847
848void LinkLayerController::TimerTick() {
849 if (inquiry_state_ == Inquiry::InquiryState::INQUIRY) Inquiry();
850 if (inquiry_state_ == Inquiry::InquiryState::INQUIRY) PageScan();
Myles Watson99aea892019-09-02 15:54:08 -0700851 LeAdvertising();
Myles Watsone22dde22019-01-18 11:42:33 -0800852 Connections();
853}
854
Myles Watson99aea892019-09-02 15:54:08 -0700855void LinkLayerController::LeAdvertising() {
856 if (!le_advertising_enable_) {
857 return;
858 }
859 steady_clock::time_point now = steady_clock::now();
860 if (duration_cast<milliseconds>(now - last_le_advertisement_) < milliseconds(200)) {
861 return;
862 }
Chienyuan1290e962019-11-07 17:37:26 +0800863 last_le_advertisement_ = now;
Myles Watson99aea892019-09-02 15:54:08 -0700864
Chienyuandb55f312019-10-31 14:01:28 +0800865 auto own_address_type = static_cast<model::packets::AddressType>(
866 properties_.GetLeAdvertisingOwnAddressType());
Myles Watson96723532019-09-02 14:52:46 -0700867 Address advertising_address = Address::kEmpty;
Chienyuandb55f312019-10-31 14:01:28 +0800868 if (own_address_type == model::packets::AddressType::PUBLIC) {
Myles Watson96723532019-09-02 14:52:46 -0700869 advertising_address = properties_.GetAddress();
Chienyuandb55f312019-10-31 14:01:28 +0800870 } else if (own_address_type == model::packets::AddressType::RANDOM) {
Myles Watson96723532019-09-02 14:52:46 -0700871 advertising_address = properties_.GetLeAddress();
Myles Watson99aea892019-09-02 15:54:08 -0700872 }
Myles Watson1a0a0da2019-10-17 11:36:33 -0700873 ASSERT(advertising_address != Address::kEmpty);
Chienyuandb55f312019-10-31 14:01:28 +0800874 auto to_send = model::packets::LeAdvertisementBuilder::Create(
875 advertising_address, Address::kEmpty, own_address_type,
876 static_cast<model::packets::AdvertisementType>(own_address_type),
877 properties_.GetLeAdvertisement());
878 SendLeLinkLayerPacket(std::move(to_send));
Myles Watson99aea892019-09-02 15:54:08 -0700879}
880
Myles Watsone22dde22019-01-18 11:42:33 -0800881void LinkLayerController::Connections() {
882 // TODO: Keep connections alive?
883}
884
885void LinkLayerController::RegisterEventChannel(
Chienyuan3d8a8032019-11-01 18:04:07 +0800886 const std::function<
887 void(std::shared_ptr<bluetooth::hci::EventPacketBuilder>)>& callback) {
Myles Watsone22dde22019-01-18 11:42:33 -0800888 send_event_ = callback;
889}
890
891void LinkLayerController::RegisterAclChannel(
892 const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& callback) {
893 send_acl_ = callback;
894}
895
896void LinkLayerController::RegisterScoChannel(
897 const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& callback) {
898 send_sco_ = callback;
899}
900
Jakub Pawlowskide6c0132019-11-12 16:14:32 +0100901void LinkLayerController::RegisterIsoChannel(
902 const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>&
903 callback) {
904 send_iso_ = callback;
905}
906
Myles Watsone22dde22019-01-18 11:42:33 -0800907void LinkLayerController::RegisterRemoteChannel(
Chienyuandb55f312019-10-31 14:01:28 +0800908 const std::function<void(
909 std::shared_ptr<model::packets::LinkLayerPacketBuilder>, Phy::Type)>&
910 callback) {
Myles Watsone22dde22019-01-18 11:42:33 -0800911 send_to_remote_ = callback;
912}
913
914void LinkLayerController::RegisterTaskScheduler(
915 std::function<AsyncTaskId(milliseconds, const TaskCallback&)> event_scheduler) {
916 schedule_task_ = event_scheduler;
917}
918
Myles Watson8fe710e2019-09-05 09:01:00 -0700919AsyncTaskId LinkLayerController::ScheduleTask(milliseconds delay_ms, const TaskCallback& callback) {
920 if (schedule_task_) {
921 return schedule_task_(delay_ms, callback);
922 } else {
923 callback();
924 return 0;
925 }
926}
927
Myles Watsone22dde22019-01-18 11:42:33 -0800928void LinkLayerController::RegisterPeriodicTaskScheduler(
929 std::function<AsyncTaskId(milliseconds, milliseconds, const TaskCallback&)> periodic_event_scheduler) {
930 schedule_periodic_task_ = periodic_event_scheduler;
931}
932
Myles Watson8fe710e2019-09-05 09:01:00 -0700933void LinkLayerController::CancelScheduledTask(AsyncTaskId task_id) {
934 if (schedule_task_ && cancel_task_) {
935 cancel_task_(task_id);
936 }
937}
938
Myles Watsone22dde22019-01-18 11:42:33 -0800939void LinkLayerController::RegisterTaskCancel(std::function<void(AsyncTaskId)> task_cancel) {
940 cancel_task_ = task_cancel;
941}
942
943void LinkLayerController::AddControllerEvent(milliseconds delay, const TaskCallback& task) {
Myles Watson8fe710e2019-09-05 09:01:00 -0700944 controller_events_.push_back(ScheduleTask(delay, task));
Myles Watsone22dde22019-01-18 11:42:33 -0800945}
946
947void LinkLayerController::WriteSimplePairingMode(bool enabled) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700948 ASSERT_LOG(enabled, "The spec says don't disable this!");
Myles Watsone22dde22019-01-18 11:42:33 -0800949 simple_pairing_mode_enabled_ = enabled;
950}
951
952void LinkLayerController::StartSimplePairing(const Address& address) {
953 // IO Capability Exchange (See the Diagram in the Spec)
Chienyuan3d8a8032019-11-01 18:04:07 +0800954 auto packet = bluetooth::hci::IoCapabilityRequestBuilder::Create(address);
955 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800956
957 // Get a Key, then authenticate
958 // PublicKeyExchange(address);
959 // AuthenticateRemoteStage1(address);
960 // AuthenticateRemoteStage2(address);
961}
962
963void LinkLayerController::AuthenticateRemoteStage1(const Address& peer, PairingType pairing_type) {
Myles Watson1a0a0da2019-10-17 11:36:33 -0700964 ASSERT(security_manager_.GetAuthenticationAddress() == peer);
Myles Watsone22dde22019-01-18 11:42:33 -0800965 // TODO: Public key exchange first?
966 switch (pairing_type) {
Chienyuan3d8a8032019-11-01 18:04:07 +0800967 case PairingType::AUTO_CONFIRMATION: {
968 auto packet =
969 bluetooth::hci::UserConfirmationRequestBuilder::Create(peer, 123456);
970 send_event_(std::move(packet));
971 } break;
Myles Watsone22dde22019-01-18 11:42:33 -0800972 case PairingType::CONFIRM_Y_N:
Myles Watson1a0a0da2019-10-17 11:36:33 -0700973 LOG_ALWAYS_FATAL("Unimplemented PairingType %d", static_cast<int>(pairing_type));
Myles Watsone22dde22019-01-18 11:42:33 -0800974 break;
975 case PairingType::DISPLAY_PIN:
Myles Watson1a0a0da2019-10-17 11:36:33 -0700976 LOG_ALWAYS_FATAL("Unimplemented PairingType %d", static_cast<int>(pairing_type));
Myles Watsone22dde22019-01-18 11:42:33 -0800977 break;
978 case PairingType::DISPLAY_AND_CONFIRM:
Myles Watson1a0a0da2019-10-17 11:36:33 -0700979 LOG_ALWAYS_FATAL("Unimplemented PairingType %d", static_cast<int>(pairing_type));
Myles Watsone22dde22019-01-18 11:42:33 -0800980 break;
981 case PairingType::INPUT_PIN:
Myles Watson1a0a0da2019-10-17 11:36:33 -0700982 LOG_ALWAYS_FATAL("Unimplemented PairingType %d", static_cast<int>(pairing_type));
Myles Watsone22dde22019-01-18 11:42:33 -0800983 break;
984 case PairingType::INVALID:
Myles Watson1a0a0da2019-10-17 11:36:33 -0700985 LOG_ALWAYS_FATAL("Unimplemented PairingType %d", static_cast<int>(pairing_type));
Myles Watsone22dde22019-01-18 11:42:33 -0800986 break;
987 default:
Myles Watson1a0a0da2019-10-17 11:36:33 -0700988 LOG_ALWAYS_FATAL("Invalid PairingType %d", static_cast<int>(pairing_type));
Myles Watsone22dde22019-01-18 11:42:33 -0800989 }
990}
991
992void LinkLayerController::AuthenticateRemoteStage2(const Address& peer) {
993 uint16_t handle = security_manager_.GetAuthenticationHandle();
Myles Watson1a0a0da2019-10-17 11:36:33 -0700994 ASSERT(security_manager_.GetAuthenticationAddress() == peer);
Myles Watsone22dde22019-01-18 11:42:33 -0800995 // Check key in security_manager_ ?
Chienyuan3d8a8032019-11-01 18:04:07 +0800996 auto packet = bluetooth::hci::AuthenticationCompleteBuilder::Create(
997 bluetooth::hci::ErrorCode::SUCCESS, handle);
998 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -0800999}
1000
Chienyuan3d8a8032019-11-01 18:04:07 +08001001bluetooth::hci::ErrorCode LinkLayerController::LinkKeyRequestReply(
1002 const Address& peer, PacketView<true> key) {
Myles Watsone22dde22019-01-18 11:42:33 -08001003 std::vector<uint8_t> key_vec(key.begin(), key.end());
1004 security_manager_.WriteKey(peer, key_vec);
1005 security_manager_.AuthenticationRequestFinished();
1006
Myles Watson8fe710e2019-09-05 09:01:00 -07001007 ScheduleTask(milliseconds(5), [this, peer]() { AuthenticateRemoteStage2(peer); });
Myles Watsone22dde22019-01-18 11:42:33 -08001008
Chienyuan3d8a8032019-11-01 18:04:07 +08001009 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001010}
1011
Chienyuan3d8a8032019-11-01 18:04:07 +08001012bluetooth::hci::ErrorCode LinkLayerController::LinkKeyRequestNegativeReply(
1013 const Address& address) {
Myles Watsone22dde22019-01-18 11:42:33 -08001014 security_manager_.DeleteKey(address);
1015 // Simple pairing to get a key
Myles Watson96723532019-09-02 14:52:46 -07001016 uint16_t handle = connections_.GetHandle(address);
Myles Watsone22dde22019-01-18 11:42:33 -08001017 if (handle == acl::kReservedHandle) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001018 LOG_INFO("%s: Device not connected %s", __func__, address.ToString().c_str());
Chienyuan3d8a8032019-11-01 18:04:07 +08001019 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Myles Watsone22dde22019-01-18 11:42:33 -08001020 }
1021
1022 security_manager_.AuthenticationRequest(address, handle);
1023
Myles Watson8fe710e2019-09-05 09:01:00 -07001024 ScheduleTask(milliseconds(5), [this, address]() { StartSimplePairing(address); });
Chienyuan3d8a8032019-11-01 18:04:07 +08001025 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001026}
1027
Chienyuan3d8a8032019-11-01 18:04:07 +08001028bluetooth::hci::ErrorCode LinkLayerController::IoCapabilityRequestReply(
1029 const Address& peer, uint8_t io_capability, uint8_t oob_data_present_flag,
1030 uint8_t authentication_requirements) {
Myles Watsone22dde22019-01-18 11:42:33 -08001031 security_manager_.SetLocalIoCapability(peer, io_capability, oob_data_present_flag, authentication_requirements);
1032
1033 PairingType pairing_type = security_manager_.GetSimplePairingType();
Chienyuandb55f312019-10-31 14:01:28 +08001034
Myles Watsone22dde22019-01-18 11:42:33 -08001035 if (pairing_type != PairingType::INVALID) {
Myles Watson8fe710e2019-09-05 09:01:00 -07001036 ScheduleTask(milliseconds(5), [this, peer, pairing_type]() { AuthenticateRemoteStage1(peer, pairing_type); });
Chienyuandb55f312019-10-31 14:01:28 +08001037 auto packet = model::packets::IoCapabilityResponseBuilder::Create(
1038 properties_.GetAddress(), peer, io_capability, oob_data_present_flag,
1039 authentication_requirements);
1040 SendLinkLayerPacket(std::move(packet));
1041
Myles Watsone22dde22019-01-18 11:42:33 -08001042 } else {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001043 LOG_INFO("%s: Requesting remote capability", __func__);
Chienyuandb55f312019-10-31 14:01:28 +08001044
1045 auto packet = model::packets::IoCapabilityRequestBuilder::Create(
1046 properties_.GetAddress(), peer, io_capability, oob_data_present_flag,
1047 authentication_requirements);
1048 SendLinkLayerPacket(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001049 }
1050
Chienyuan3d8a8032019-11-01 18:04:07 +08001051 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001052}
1053
Chienyuan3d8a8032019-11-01 18:04:07 +08001054bluetooth::hci::ErrorCode LinkLayerController::IoCapabilityRequestNegativeReply(
1055 const Address& peer, hci::Status reason) {
Myles Watsone22dde22019-01-18 11:42:33 -08001056 if (security_manager_.GetAuthenticationAddress() != peer) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001057 return bluetooth::hci::ErrorCode::AUTHENTICATION_FAILURE;
Myles Watsone22dde22019-01-18 11:42:33 -08001058 }
1059
1060 security_manager_.InvalidateIoCapabilities();
1061
Chienyuandb55f312019-10-31 14:01:28 +08001062 auto packet = model::packets::IoCapabilityNegativeResponseBuilder::Create(
1063 properties_.GetAddress(), peer, static_cast<uint8_t>(reason));
1064 SendLinkLayerPacket(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001065
Chienyuan3d8a8032019-11-01 18:04:07 +08001066 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001067}
1068
Chienyuan3d8a8032019-11-01 18:04:07 +08001069bluetooth::hci::ErrorCode LinkLayerController::UserConfirmationRequestReply(
1070 const Address& peer) {
Myles Watsone22dde22019-01-18 11:42:33 -08001071 if (security_manager_.GetAuthenticationAddress() != peer) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001072 return bluetooth::hci::ErrorCode::AUTHENTICATION_FAILURE;
Myles Watsone22dde22019-01-18 11:42:33 -08001073 }
1074 // TODO: Key could be calculated here.
1075 std::vector<uint8_t> key_vec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
1076 security_manager_.WriteKey(peer, key_vec);
1077
1078 security_manager_.AuthenticationRequestFinished();
1079
Myles Watson8fe710e2019-09-05 09:01:00 -07001080 ScheduleTask(milliseconds(5), [this, peer]() { AuthenticateRemoteStage2(peer); });
Chienyuan3d8a8032019-11-01 18:04:07 +08001081 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001082}
1083
Chienyuan3d8a8032019-11-01 18:04:07 +08001084bluetooth::hci::ErrorCode
1085LinkLayerController::UserConfirmationRequestNegativeReply(const Address& peer) {
Myles Watsone22dde22019-01-18 11:42:33 -08001086 if (security_manager_.GetAuthenticationAddress() != peer) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001087 return bluetooth::hci::ErrorCode::AUTHENTICATION_FAILURE;
Myles Watsone22dde22019-01-18 11:42:33 -08001088 }
Chienyuan3d8a8032019-11-01 18:04:07 +08001089 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001090}
1091
Chienyuan3d8a8032019-11-01 18:04:07 +08001092bluetooth::hci::ErrorCode LinkLayerController::UserPasskeyRequestReply(
1093 const Address& peer, uint32_t numeric_value) {
Myles Watsone22dde22019-01-18 11:42:33 -08001094 if (security_manager_.GetAuthenticationAddress() != peer) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001095 return bluetooth::hci::ErrorCode::AUTHENTICATION_FAILURE;
Myles Watsone22dde22019-01-18 11:42:33 -08001096 }
Myles Watson1a0a0da2019-10-17 11:36:33 -07001097 LOG_INFO("TODO:Do something with the passkey %06d", numeric_value);
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::UserPasskeyRequestNegativeReply(
1102 const Address& peer) {
Myles Watsone22dde22019-01-18 11:42:33 -08001103 if (security_manager_.GetAuthenticationAddress() != peer) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001104 return bluetooth::hci::ErrorCode::AUTHENTICATION_FAILURE;
Myles Watsone22dde22019-01-18 11:42:33 -08001105 }
Chienyuan3d8a8032019-11-01 18:04:07 +08001106 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001107}
1108
Chienyuan3d8a8032019-11-01 18:04:07 +08001109bluetooth::hci::ErrorCode LinkLayerController::RemoteOobDataRequestReply(
1110 const Address& peer, const std::vector<uint8_t>& c,
1111 const std::vector<uint8_t>& r) {
Myles Watsone22dde22019-01-18 11:42:33 -08001112 if (security_manager_.GetAuthenticationAddress() != peer) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001113 return bluetooth::hci::ErrorCode::AUTHENTICATION_FAILURE;
Myles Watsone22dde22019-01-18 11:42:33 -08001114 }
Myles Watson1a0a0da2019-10-17 11:36:33 -07001115 LOG_INFO("TODO:Do something with the OOB data c=%d r=%d", c[0], r[0]);
Chienyuan3d8a8032019-11-01 18:04:07 +08001116 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001117}
1118
Chienyuan3d8a8032019-11-01 18:04:07 +08001119bluetooth::hci::ErrorCode
1120LinkLayerController::RemoteOobDataRequestNegativeReply(const Address& peer) {
Myles Watsone22dde22019-01-18 11:42:33 -08001121 if (security_manager_.GetAuthenticationAddress() != peer) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001122 return bluetooth::hci::ErrorCode::AUTHENTICATION_FAILURE;
Myles Watsone22dde22019-01-18 11:42:33 -08001123 }
Chienyuan3d8a8032019-11-01 18:04:07 +08001124 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001125}
1126
1127void LinkLayerController::HandleAuthenticationRequest(const Address& address, uint16_t handle) {
1128 if (simple_pairing_mode_enabled_ == true) {
1129 security_manager_.AuthenticationRequest(address, handle);
Chienyuan3d8a8032019-11-01 18:04:07 +08001130 auto packet = bluetooth::hci::LinkKeyRequestBuilder::Create(address);
1131 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001132 } else { // Should never happen for our phones
1133 // Check for a key, try to authenticate, ask for a PIN.
Chienyuan3d8a8032019-11-01 18:04:07 +08001134 auto packet = bluetooth::hci::AuthenticationCompleteBuilder::Create(
1135 bluetooth::hci::ErrorCode::AUTHENTICATION_FAILURE, handle);
1136 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001137 }
1138}
1139
Chienyuan3d8a8032019-11-01 18:04:07 +08001140bluetooth::hci::ErrorCode LinkLayerController::AuthenticationRequested(
1141 uint16_t handle) {
Myles Watson96723532019-09-02 14:52:46 -07001142 if (!connections_.HasHandle(handle)) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001143 LOG_INFO("Authentication Requested for unknown handle %04x", handle);
Chienyuan3d8a8032019-11-01 18:04:07 +08001144 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Myles Watsone22dde22019-01-18 11:42:33 -08001145 }
1146
Myles Watson96723532019-09-02 14:52:46 -07001147 Address remote = connections_.GetAddress(handle);
Myles Watsone22dde22019-01-18 11:42:33 -08001148
Myles Watson8fe710e2019-09-05 09:01:00 -07001149 ScheduleTask(milliseconds(5), [this, remote, handle]() { HandleAuthenticationRequest(remote, handle); });
Myles Watsone22dde22019-01-18 11:42:33 -08001150
Chienyuan3d8a8032019-11-01 18:04:07 +08001151 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001152}
1153
1154void LinkLayerController::HandleSetConnectionEncryption(const Address& peer, uint16_t handle,
1155 uint8_t encryption_enable) {
1156 // TODO: Block ACL traffic or at least guard against it
1157
Myles Watson96723532019-09-02 14:52:46 -07001158 if (connections_.IsEncrypted(handle) && encryption_enable) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001159 auto packet = bluetooth::hci::EncryptionChangeBuilder::Create(
1160 bluetooth::hci::ErrorCode::SUCCESS, handle,
1161 static_cast<bluetooth::hci::EncryptionEnabled>(encryption_enable));
1162 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001163 return;
1164 }
1165
Chienyuandb55f312019-10-31 14:01:28 +08001166 auto packet = model::packets::EncryptConnectionBuilder::Create(
1167 properties_.GetAddress(), peer, security_manager_.GetKey(peer));
1168 SendLinkLayerPacket(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001169}
1170
Chienyuan3d8a8032019-11-01 18:04:07 +08001171bluetooth::hci::ErrorCode LinkLayerController::SetConnectionEncryption(
1172 uint16_t handle, uint8_t encryption_enable) {
Myles Watson96723532019-09-02 14:52:46 -07001173 if (!connections_.HasHandle(handle)) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001174 LOG_INFO("Set Connection Encryption for unknown handle %04x", handle);
Chienyuan3d8a8032019-11-01 18:04:07 +08001175 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Myles Watsone22dde22019-01-18 11:42:33 -08001176 }
1177
Myles Watson96723532019-09-02 14:52:46 -07001178 if (connections_.IsEncrypted(handle) && !encryption_enable) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001179 return bluetooth::hci::ErrorCode::ENCRYPTION_MODE_NOT_ACCEPTABLE;
Myles Watsone22dde22019-01-18 11:42:33 -08001180 }
Myles Watson96723532019-09-02 14:52:46 -07001181 Address remote = connections_.GetAddress(handle);
Myles Watsone22dde22019-01-18 11:42:33 -08001182
Chienyuanad340b02019-09-25 19:23:21 +08001183 if (security_manager_.ReadKey(remote) == 0) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001184 return bluetooth::hci::ErrorCode::PIN_OR_KEY_MISSING;
Chienyuanad340b02019-09-25 19:23:21 +08001185 }
1186
Myles Watson8fe710e2019-09-05 09:01:00 -07001187 ScheduleTask(milliseconds(5), [this, remote, handle, encryption_enable]() {
Myles Watsone22dde22019-01-18 11:42:33 -08001188 HandleSetConnectionEncryption(remote, handle, encryption_enable);
1189 });
Chienyuan3d8a8032019-11-01 18:04:07 +08001190 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001191}
1192
Chienyuan3d8a8032019-11-01 18:04:07 +08001193bluetooth::hci::ErrorCode LinkLayerController::AcceptConnectionRequest(
1194 const Address& addr, bool try_role_switch) {
Myles Watson96723532019-09-02 14:52:46 -07001195 if (!connections_.HasPendingConnection(addr)) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001196 LOG_INFO("%s: No pending connection for %s", __func__, addr.ToString().c_str());
Chienyuan3d8a8032019-11-01 18:04:07 +08001197 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Myles Watsone22dde22019-01-18 11:42:33 -08001198 }
1199
Myles Watson1a0a0da2019-10-17 11:36:33 -07001200 LOG_INFO("%s: Accept in 200ms", __func__);
Myles Watson8fe710e2019-09-05 09:01:00 -07001201 ScheduleTask(milliseconds(200), [this, addr, try_role_switch]() {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001202 LOG_INFO("%s: Accepted", __func__);
Myles Watsone22dde22019-01-18 11:42:33 -08001203 MakeSlaveConnection(addr, try_role_switch);
1204 });
1205
Chienyuan3d8a8032019-11-01 18:04:07 +08001206 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001207}
1208
1209void LinkLayerController::MakeSlaveConnection(const Address& addr, bool try_role_switch) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001210 LOG_INFO("%s sending page response to %s", __func__, addr.ToString().c_str());
Chienyuandb55f312019-10-31 14:01:28 +08001211 auto to_send = model::packets::PageResponseBuilder::Create(
1212 properties_.GetAddress(), addr, try_role_switch);
1213 SendLinkLayerPacket(std::move(to_send));
Myles Watsone22dde22019-01-18 11:42:33 -08001214
Myles Watson96723532019-09-02 14:52:46 -07001215 uint16_t handle = connections_.CreateConnection(addr);
Myles Watsone22dde22019-01-18 11:42:33 -08001216 if (handle == acl::kReservedHandle) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001217 LOG_INFO("%s CreateConnection failed", __func__);
Myles Watsone22dde22019-01-18 11:42:33 -08001218 return;
1219 }
Myles Watson1a0a0da2019-10-17 11:36:33 -07001220 LOG_INFO("%s CreateConnection returned handle 0x%x", __func__, handle);
Chienyuan3d8a8032019-11-01 18:04:07 +08001221 auto packet = bluetooth::hci::ConnectionCompleteBuilder::Create(
1222 bluetooth::hci::ErrorCode::SUCCESS, handle, addr,
1223 bluetooth::hci::LinkType::ACL, bluetooth::hci::Enable::DISABLED);
1224 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001225}
1226
Chienyuan3d8a8032019-11-01 18:04:07 +08001227bluetooth::hci::ErrorCode LinkLayerController::RejectConnectionRequest(
1228 const Address& addr, uint8_t reason) {
Myles Watson96723532019-09-02 14:52:46 -07001229 if (!connections_.HasPendingConnection(addr)) {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001230 LOG_INFO("%s: No pending connection for %s", __func__, addr.ToString().c_str());
Chienyuan3d8a8032019-11-01 18:04:07 +08001231 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Myles Watsone22dde22019-01-18 11:42:33 -08001232 }
1233
Myles Watson1a0a0da2019-10-17 11:36:33 -07001234 LOG_INFO("%s: Reject in 200ms", __func__);
Myles Watson8fe710e2019-09-05 09:01:00 -07001235 ScheduleTask(milliseconds(200), [this, addr, reason]() {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001236 LOG_INFO("%s: Reject", __func__);
Myles Watsone22dde22019-01-18 11:42:33 -08001237 RejectSlaveConnection(addr, reason);
1238 });
1239
Chienyuan3d8a8032019-11-01 18:04:07 +08001240 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001241}
1242
1243void LinkLayerController::RejectSlaveConnection(const Address& addr, uint8_t reason) {
Chienyuandb55f312019-10-31 14:01:28 +08001244 auto to_send = model::packets::PageRejectBuilder::Create(
1245 properties_.GetAddress(), addr, reason);
Myles Watson1a0a0da2019-10-17 11:36:33 -07001246 LOG_INFO("%s sending page reject to %s", __func__, addr.ToString().c_str());
Chienyuandb55f312019-10-31 14:01:28 +08001247 SendLinkLayerPacket(std::move(to_send));
Hansong Zhang4cb1cf52019-07-08 15:32:26 -07001248
Myles Watson1a0a0da2019-10-17 11:36:33 -07001249 ASSERT(reason >= 0x0d && reason <= 0x0f);
Chienyuan3d8a8032019-11-01 18:04:07 +08001250 auto packet = bluetooth::hci::ConnectionCompleteBuilder::Create(
1251 static_cast<bluetooth::hci::ErrorCode>(reason), 0xeff, addr,
1252 bluetooth::hci::LinkType::ACL, bluetooth::hci::Enable::DISABLED);
1253 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001254}
1255
Chienyuan3d8a8032019-11-01 18:04:07 +08001256bluetooth::hci::ErrorCode LinkLayerController::CreateConnection(
1257 const Address& addr, uint16_t, uint8_t, uint16_t,
1258 uint8_t allow_role_switch) {
Myles Watson96723532019-09-02 14:52:46 -07001259 if (!connections_.CreatePendingConnection(addr)) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001260 return bluetooth::hci::ErrorCode::CONTROLLER_BUSY;
Myles Watsone22dde22019-01-18 11:42:33 -08001261 }
1262
Chienyuandb55f312019-10-31 14:01:28 +08001263 auto page = model::packets::PageBuilder::Create(
1264 properties_.GetAddress(), addr, properties_.GetClassOfDevice(),
1265 allow_role_switch);
1266 SendLinkLayerPacket(std::move(page));
Myles Watsone22dde22019-01-18 11:42:33 -08001267
Chienyuan3d8a8032019-11-01 18:04:07 +08001268 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001269}
1270
Chienyuan3d8a8032019-11-01 18:04:07 +08001271bluetooth::hci::ErrorCode LinkLayerController::CreateConnectionCancel(
1272 const Address& addr) {
Myles Watson96723532019-09-02 14:52:46 -07001273 if (!connections_.CancelPendingConnection(addr)) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001274 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Myles Watsone22dde22019-01-18 11:42:33 -08001275 }
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::Disconnect(uint16_t handle,
1280 uint8_t reason) {
Myles Watsone22dde22019-01-18 11:42:33 -08001281 // TODO: Handle LE
Myles Watson96723532019-09-02 14:52:46 -07001282 if (!connections_.HasHandle(handle)) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001283 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Myles Watsone22dde22019-01-18 11:42:33 -08001284 }
1285
Myles Watson96723532019-09-02 14:52:46 -07001286 const Address& remote = connections_.GetAddress(handle);
Chienyuandb55f312019-10-31 14:01:28 +08001287 auto packet = model::packets::DisconnectBuilder::Create(
1288 properties_.GetAddress(), remote, reason);
1289 SendLinkLayerPacket(std::move(packet));
Myles Watson1a0a0da2019-10-17 11:36:33 -07001290 ASSERT_LOG(connections_.Disconnect(handle), "Disconnecting %hx", handle);
Myles Watsone22dde22019-01-18 11:42:33 -08001291
Myles Watson8fe710e2019-09-05 09:01:00 -07001292 ScheduleTask(milliseconds(20), [this, handle]() {
Myles Watsone22dde22019-01-18 11:42:33 -08001293 DisconnectCleanup(handle, static_cast<uint8_t>(hci::Status::CONNECTION_TERMINATED_BY_LOCAL_HOST));
1294 });
1295
Chienyuan3d8a8032019-11-01 18:04:07 +08001296 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001297}
1298
1299void LinkLayerController::DisconnectCleanup(uint16_t handle, uint8_t reason) {
1300 // TODO: Clean up other connection state.
Chienyuan3d8a8032019-11-01 18:04:07 +08001301 auto packet = bluetooth::hci::DisconnectionCompleteBuilder::Create(
1302 bluetooth::hci::ErrorCode::SUCCESS, handle,
1303 static_cast<bluetooth::hci::ErrorCode>(reason));
1304 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001305}
1306
Chienyuan3d8a8032019-11-01 18:04:07 +08001307bluetooth::hci::ErrorCode LinkLayerController::ChangeConnectionPacketType(
1308 uint16_t handle, uint16_t types) {
Myles Watson96723532019-09-02 14:52:46 -07001309 if (!connections_.HasHandle(handle)) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001310 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Myles Watsone22dde22019-01-18 11:42:33 -08001311 }
Chienyuan3d8a8032019-11-01 18:04:07 +08001312 auto packet = bluetooth::hci::ConnectionPacketTypeChangedBuilder::Create(
1313 bluetooth::hci::ErrorCode::SUCCESS, handle, types);
1314 std::shared_ptr<bluetooth::hci::ConnectionPacketTypeChangedBuilder>
1315 shared_packet = std::move(packet);
1316 ScheduleTask(milliseconds(20), [this, shared_packet]() {
1317 send_event_(std::move(shared_packet));
1318 });
Myles Watsone22dde22019-01-18 11:42:33 -08001319
Chienyuan3d8a8032019-11-01 18:04:07 +08001320 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001321}
1322
Chienyuan3d8a8032019-11-01 18:04:07 +08001323bluetooth::hci::ErrorCode LinkLayerController::ChangeConnectionLinkKey(
1324 uint16_t handle) {
Chienyuanad340b02019-09-25 19:23:21 +08001325 if (!connections_.HasHandle(handle)) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001326 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Chienyuanad340b02019-09-25 19:23:21 +08001327 }
1328
1329 // TODO: implement real logic
Chienyuan3d8a8032019-11-01 18:04:07 +08001330 return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
Chienyuanad340b02019-09-25 19:23:21 +08001331}
1332
Chienyuan3d8a8032019-11-01 18:04:07 +08001333bluetooth::hci::ErrorCode LinkLayerController::MasterLinkKey(
1334 uint8_t /* key_flag */) {
Chienyuan9145e7a2019-10-02 15:18:55 +08001335 // TODO: implement real logic
Chienyuan3d8a8032019-11-01 18:04:07 +08001336 return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
Chienyuan9145e7a2019-10-02 15:18:55 +08001337}
1338
Chienyuan3d8a8032019-11-01 18:04:07 +08001339bluetooth::hci::ErrorCode LinkLayerController::HoldMode(
1340 uint16_t handle, uint16_t hold_mode_max_interval,
1341 uint16_t hold_mode_min_interval) {
Chienyuanad340b02019-09-25 19:23:21 +08001342 if (!connections_.HasHandle(handle)) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001343 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Chienyuanad340b02019-09-25 19:23:21 +08001344 }
1345
1346 if (hold_mode_max_interval < hold_mode_min_interval) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001347 return bluetooth::hci::ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
Chienyuanad340b02019-09-25 19:23:21 +08001348 }
1349
1350 // TODO: implement real logic
Chienyuan3d8a8032019-11-01 18:04:07 +08001351 return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
Chienyuanad340b02019-09-25 19:23:21 +08001352}
1353
Chienyuan3d8a8032019-11-01 18:04:07 +08001354bluetooth::hci::ErrorCode LinkLayerController::SniffMode(
1355 uint16_t handle, uint16_t sniff_max_interval, uint16_t sniff_min_interval,
1356 uint16_t sniff_attempt, uint16_t sniff_timeout) {
Chienyuanad340b02019-09-25 19:23:21 +08001357 if (!connections_.HasHandle(handle)) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001358 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Chienyuanad340b02019-09-25 19:23:21 +08001359 }
1360
Myles Watson1a0a0da2019-10-17 11:36:33 -07001361 if (sniff_max_interval < sniff_min_interval || sniff_attempt < 0x0001 || sniff_attempt > 0x7FFF ||
1362 sniff_timeout > 0x7FFF) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001363 return bluetooth::hci::ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
Chienyuanad340b02019-09-25 19:23:21 +08001364 }
1365
1366 // TODO: implement real logic
Chienyuan3d8a8032019-11-01 18:04:07 +08001367 return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
Chienyuanad340b02019-09-25 19:23:21 +08001368}
1369
Chienyuan3d8a8032019-11-01 18:04:07 +08001370bluetooth::hci::ErrorCode LinkLayerController::ExitSniffMode(uint16_t handle) {
Chienyuanad340b02019-09-25 19:23:21 +08001371 if (!connections_.HasHandle(handle)) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001372 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Chienyuanad340b02019-09-25 19:23:21 +08001373 }
1374
1375 // TODO: implement real logic
Chienyuan3d8a8032019-11-01 18:04:07 +08001376 return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
Chienyuanad340b02019-09-25 19:23:21 +08001377}
1378
Chienyuan3d8a8032019-11-01 18:04:07 +08001379bluetooth::hci::ErrorCode LinkLayerController::QosSetup(
1380 uint16_t handle, uint8_t service_type, uint32_t /* token_rate */,
1381 uint32_t /* peak_bandwidth */, uint32_t /* latency */,
1382 uint32_t /* delay_variation */) {
Chienyuanad340b02019-09-25 19:23:21 +08001383 if (!connections_.HasHandle(handle)) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001384 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Chienyuanad340b02019-09-25 19:23:21 +08001385 }
1386
1387 if (service_type > 0x02) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001388 return bluetooth::hci::ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
Chienyuanad340b02019-09-25 19:23:21 +08001389 }
1390
1391 // TODO: implement real logic
Chienyuan3d8a8032019-11-01 18:04:07 +08001392 return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
Chienyuanad340b02019-09-25 19:23:21 +08001393}
1394
Chienyuan3d8a8032019-11-01 18:04:07 +08001395bluetooth::hci::ErrorCode LinkLayerController::SwitchRole(Address /* bd_addr */,
1396 uint8_t /* role */) {
Chienyuan9145e7a2019-10-02 15:18:55 +08001397 // TODO: implement real logic
Chienyuan3d8a8032019-11-01 18:04:07 +08001398 return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
Chienyuan9145e7a2019-10-02 15:18:55 +08001399}
1400
Chienyuan3d8a8032019-11-01 18:04:07 +08001401bluetooth::hci::ErrorCode LinkLayerController::WriteLinkPolicySettings(
1402 uint16_t handle, uint16_t) {
Myles Watson96723532019-09-02 14:52:46 -07001403 if (!connections_.HasHandle(handle)) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001404 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Myles Watsone22dde22019-01-18 11:42:33 -08001405 }
Chienyuan3d8a8032019-11-01 18:04:07 +08001406 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001407}
1408
Chienyuan3d8a8032019-11-01 18:04:07 +08001409bluetooth::hci::ErrorCode LinkLayerController::FlowSpecification(
1410 uint16_t handle, uint8_t flow_direction, uint8_t service_type,
1411 uint32_t /* token_rate */, uint32_t /* token_bucket_size */,
1412 uint32_t /* peak_bandwidth */, uint32_t /* access_latency */) {
Chienyuanad340b02019-09-25 19:23:21 +08001413 if (!connections_.HasHandle(handle)) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001414 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Chienyuanad340b02019-09-25 19:23:21 +08001415 }
1416
1417 if (flow_direction > 0x01 || service_type > 0x02) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001418 return bluetooth::hci::ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
Chienyuanad340b02019-09-25 19:23:21 +08001419 }
1420
1421 // TODO: implement real logic
Chienyuan3d8a8032019-11-01 18:04:07 +08001422 return bluetooth::hci::ErrorCode::COMMAND_DISALLOWED;
Chienyuanad340b02019-09-25 19:23:21 +08001423}
1424
Chienyuan3d8a8032019-11-01 18:04:07 +08001425bluetooth::hci::ErrorCode LinkLayerController::WriteLinkSupervisionTimeout(
1426 uint16_t handle, uint16_t) {
Myles Watson96723532019-09-02 14:52:46 -07001427 if (!connections_.HasHandle(handle)) {
Chienyuan3d8a8032019-11-01 18:04:07 +08001428 return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
Myles Watsone22dde22019-01-18 11:42:33 -08001429 }
Chienyuan3d8a8032019-11-01 18:04:07 +08001430 return bluetooth::hci::ErrorCode::SUCCESS;
Myles Watsone22dde22019-01-18 11:42:33 -08001431}
1432
1433void LinkLayerController::LeWhiteListClear() {
1434 le_white_list_.clear();
1435}
1436
Calvin Huangee1980c2019-11-01 16:35:55 -07001437void LinkLayerController::LeResolvingListClear() { le_resolving_list_.clear(); }
1438
Myles Watsone22dde22019-01-18 11:42:33 -08001439void LinkLayerController::LeWhiteListAddDevice(Address addr, uint8_t addr_type) {
1440 std::tuple<Address, uint8_t> new_tuple = std::make_tuple(addr, addr_type);
1441 for (auto dev : le_white_list_) {
1442 if (dev == new_tuple) {
1443 return;
1444 }
1445 }
1446 le_white_list_.emplace_back(new_tuple);
1447}
1448
Calvin Huangee1980c2019-11-01 16:35:55 -07001449void LinkLayerController::LeResolvingListAddDevice(
1450 Address addr, uint8_t addr_type, std::array<uint8_t, kIrk_size> peerIrk,
1451 std::array<uint8_t, kIrk_size> localIrk) {
1452 std::tuple<Address, uint8_t, std::array<uint8_t, kIrk_size>,
1453 std::array<uint8_t, kIrk_size>>
1454 new_tuple = std::make_tuple(addr, addr_type, peerIrk, localIrk);
1455 for (size_t i = 0; i < le_white_list_.size(); i++) {
1456 auto curr = le_white_list_[i];
1457 if (std::get<0>(curr) == addr && std::get<1>(curr) == addr_type) {
1458 le_resolving_list_[i] = new_tuple;
1459 return;
1460 }
1461 }
1462 le_resolving_list_.emplace_back(new_tuple);
1463}
1464
1465void LinkLayerController::LeSetPrivacyMode(uint8_t address_type, Address addr,
1466 uint8_t mode) {
1467 // set mode for addr
1468 LOG_INFO("address type = %d ", address_type);
1469 LOG_INFO("address = %s ", addr.ToString().c_str());
1470 LOG_INFO("mode = %d ", mode);
1471}
1472
Myles Watsone22dde22019-01-18 11:42:33 -08001473void LinkLayerController::LeWhiteListRemoveDevice(Address addr, uint8_t addr_type) {
1474 // TODO: Add checks to see if advertising, scanning, or a connection request
1475 // with the white list is ongoing.
1476 std::tuple<Address, uint8_t> erase_tuple = std::make_tuple(addr, addr_type);
1477 for (size_t i = 0; i < le_white_list_.size(); i++) {
1478 if (le_white_list_[i] == erase_tuple) {
1479 le_white_list_.erase(le_white_list_.begin() + i);
1480 }
1481 }
1482}
1483
Calvin Huangee1980c2019-11-01 16:35:55 -07001484void LinkLayerController::LeResolvingListRemoveDevice(Address addr,
1485 uint8_t addr_type) {
1486 // TODO: Add checks to see if advertising, scanning, or a connection request
1487 // with the white list is ongoing.
1488 for (size_t i = 0; i < le_white_list_.size(); i++) {
1489 auto curr = le_white_list_[i];
1490 if (std::get<0>(curr) == addr && std::get<1>(curr) == addr_type) {
1491 le_resolving_list_.erase(le_resolving_list_.begin() + i);
1492 }
1493 }
1494}
1495
Myles Watsone22dde22019-01-18 11:42:33 -08001496bool LinkLayerController::LeWhiteListContainsDevice(Address addr, uint8_t addr_type) {
1497 std::tuple<Address, uint8_t> sought_tuple = std::make_tuple(addr, addr_type);
1498 for (size_t i = 0; i < le_white_list_.size(); i++) {
1499 if (le_white_list_[i] == sought_tuple) {
1500 return true;
1501 }
1502 }
1503 return false;
1504}
1505
Calvin Huangee1980c2019-11-01 16:35:55 -07001506bool LinkLayerController::LeResolvingListContainsDevice(Address addr,
1507 uint8_t addr_type) {
1508 for (size_t i = 0; i < le_white_list_.size(); i++) {
1509 auto curr = le_white_list_[i];
1510 if (std::get<0>(curr) == addr && std::get<1>(curr) == addr_type) {
1511 return true;
1512 }
1513 }
1514 return false;
1515}
1516
Myles Watsone22dde22019-01-18 11:42:33 -08001517bool LinkLayerController::LeWhiteListFull() {
1518 return le_white_list_.size() >= properties_.GetLeWhiteListSize();
1519}
1520
Calvin Huangee1980c2019-11-01 16:35:55 -07001521bool LinkLayerController::LeResolvingListFull() {
1522 return le_resolving_list_.size() >= properties_.GetLeResolvingListSize();
1523}
1524
Myles Watsone22dde22019-01-18 11:42:33 -08001525void LinkLayerController::Reset() {
1526 inquiry_state_ = Inquiry::InquiryState::STANDBY;
1527 last_inquiry_ = steady_clock::now();
1528 le_scan_enable_ = 0;
Myles Watson96723532019-09-02 14:52:46 -07001529 le_advertising_enable_ = 0;
Myles Watsone22dde22019-01-18 11:42:33 -08001530 le_connect_ = 0;
1531}
1532
1533void LinkLayerController::PageScan() {}
1534
1535void LinkLayerController::StartInquiry(milliseconds timeout) {
Myles Watson8fe710e2019-09-05 09:01:00 -07001536 ScheduleTask(milliseconds(timeout), [this]() { LinkLayerController::InquiryTimeout(); });
Myles Watsone22dde22019-01-18 11:42:33 -08001537 inquiry_state_ = Inquiry::InquiryState::INQUIRY;
Myles Watson1a0a0da2019-10-17 11:36:33 -07001538 LOG_INFO("InquiryState = %d ", static_cast<int>(inquiry_state_));
Myles Watsone22dde22019-01-18 11:42:33 -08001539}
1540
1541void LinkLayerController::InquiryCancel() {
Myles Watson1a0a0da2019-10-17 11:36:33 -07001542 ASSERT(inquiry_state_ == Inquiry::InquiryState::INQUIRY);
Myles Watsone22dde22019-01-18 11:42:33 -08001543 inquiry_state_ = Inquiry::InquiryState::STANDBY;
1544}
1545
1546void LinkLayerController::InquiryTimeout() {
1547 if (inquiry_state_ == Inquiry::InquiryState::INQUIRY) {
1548 inquiry_state_ = Inquiry::InquiryState::STANDBY;
Chienyuan3d8a8032019-11-01 18:04:07 +08001549 auto packet = bluetooth::hci::InquiryCompleteBuilder::Create(
1550 bluetooth::hci::ErrorCode::SUCCESS);
1551 send_event_(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001552 }
1553}
1554
1555void LinkLayerController::SetInquiryMode(uint8_t mode) {
Chienyuandb55f312019-10-31 14:01:28 +08001556 inquiry_mode_ = static_cast<model::packets::InquiryType>(mode);
Myles Watsone22dde22019-01-18 11:42:33 -08001557}
1558
1559void LinkLayerController::SetInquiryLAP(uint64_t lap) {
1560 inquiry_lap_ = lap;
1561}
1562
1563void LinkLayerController::SetInquiryMaxResponses(uint8_t max) {
1564 inquiry_max_responses_ = max;
1565}
1566
1567void LinkLayerController::Inquiry() {
1568 steady_clock::time_point now = steady_clock::now();
1569 if (duration_cast<milliseconds>(now - last_inquiry_) < milliseconds(2000)) {
1570 return;
1571 }
Myles Watson1a0a0da2019-10-17 11:36:33 -07001572 LOG_INFO("Inquiry ");
Chienyuandb55f312019-10-31 14:01:28 +08001573
1574 auto packet = model::packets::InquiryBuilder::Create(
1575 properties_.GetAddress(), Address::kEmpty, inquiry_mode_);
1576 SendLinkLayerPacket(std::move(packet));
Myles Watsone22dde22019-01-18 11:42:33 -08001577 last_inquiry_ = now;
1578}
1579
1580void LinkLayerController::SetInquiryScanEnable(bool enable) {
1581 inquiry_scans_enabled_ = enable;
1582}
1583
1584void LinkLayerController::SetPageScanEnable(bool enable) {
1585 page_scans_enabled_ = enable;
1586}
1587
Myles Watsone22dde22019-01-18 11:42:33 -08001588} // namespace test_vendor_lib