1 /*
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
17 #include "model/controller/link_layer_controller.h"
18
19 #include <packet_runtime.h>
20
21 #include <algorithm>
22 #include <array>
23 #include <chrono>
24 #include <cstddef>
25 #include <cstdint>
26 #include <cstdlib>
27 #include <functional>
28 #include <memory>
29 #include <optional>
30 #include <utility>
31 #include <vector>
32
33 #include "crypto/crypto.h"
34 #include "hci/address.h"
35 #include "hci/address_with_type.h"
36 #include "log.h"
37 #include "model/controller/acl_connection.h"
38 #include "model/controller/acl_connection_handler.h"
39 #include "model/controller/controller_properties.h"
40 #include "model/controller/le_advertiser.h"
41 #include "model/controller/sco_connection.h"
42 #include "packets/hci_packets.h"
43 #include "packets/link_layer_packets.h"
44 #include "phy.h"
45 #include "rust/include/rootcanal_rs.h"
46
47 using namespace std::chrono;
48 using bluetooth::hci::Address;
49 using bluetooth::hci::AddressType;
50 using bluetooth::hci::AddressWithType;
51 using bluetooth::hci::LLFeaturesBits;
52 using bluetooth::hci::SubeventCode;
53
54 using namespace model::packets;
55 using namespace std::literals;
56
57 using TaskId = rootcanal::LinkLayerController::TaskId;
58
59 namespace rootcanal {
60
61 constexpr milliseconds kScanRequestTimeout(200);
62 constexpr milliseconds kNoDelayMs(0);
63 constexpr milliseconds kPageInterval(1000);
64
GetAddress() const65 const Address& LinkLayerController::GetAddress() const { return address_; }
66
PeerDeviceAddress(Address address,PeerAddressType peer_address_type)67 AddressWithType PeerDeviceAddress(Address address, PeerAddressType peer_address_type) {
68 switch (peer_address_type) {
69 case PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS:
70 return AddressWithType(address, AddressType::PUBLIC_DEVICE_ADDRESS);
71 case PeerAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS:
72 return AddressWithType(address, AddressType::RANDOM_DEVICE_ADDRESS);
73 }
74 }
75
PeerIdentityAddress(Address address,PeerAddressType peer_address_type)76 AddressWithType PeerIdentityAddress(Address address, PeerAddressType peer_address_type) {
77 switch (peer_address_type) {
78 case PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS:
79 return AddressWithType(address, AddressType::PUBLIC_IDENTITY_ADDRESS);
80 case PeerAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS:
81 return AddressWithType(address, AddressType::RANDOM_IDENTITY_ADDRESS);
82 }
83 }
84
IsEventUnmasked(EventCode event) const85 bool LinkLayerController::IsEventUnmasked(EventCode event) const {
86 uint8_t evt = static_cast<uint8_t>(event);
87
88 if (evt <= 64) {
89 uint64_t bit = UINT64_C(1) << (evt - 1);
90 return (event_mask_ & bit) != 0;
91 } else {
92 evt -= 64;
93 uint64_t bit = UINT64_C(1) << (evt - 1);
94 return (event_mask_page_2_ & bit) != 0;
95 }
96 }
97
IsLeEventUnmasked(SubeventCode subevent) const98 bool LinkLayerController::IsLeEventUnmasked(SubeventCode subevent) const {
99 uint64_t bit = UINT64_C(1) << (static_cast<uint8_t>(subevent) - 1);
100 return IsEventUnmasked(EventCode::LE_META_EVENT) && (le_event_mask_ & bit) != 0;
101 }
102
FilterAcceptListBusy()103 bool LinkLayerController::FilterAcceptListBusy() {
104 // Filter Accept List cannot be modified when
105 // • any advertising filter policy uses the Filter Accept List and
106 // advertising is enabled,
107 if (legacy_advertiser_.IsEnabled() &&
108 legacy_advertiser_.advertising_filter_policy !=
109 bluetooth::hci::AdvertisingFilterPolicy::ALL_DEVICES) {
110 return true;
111 }
112
113 for (auto const& [_, advertiser] : extended_advertisers_) {
114 if (advertiser.IsEnabled() && advertiser.advertising_filter_policy !=
115 bluetooth::hci::AdvertisingFilterPolicy::ALL_DEVICES) {
116 return true;
117 }
118 }
119
120 // • the scanning filter policy uses the Filter Accept List and scanning
121 // is enabled,
122 if (scanner_.IsEnabled() &&
123 (scanner_.scan_filter_policy ==
124 bluetooth::hci::LeScanningFilterPolicy::FILTER_ACCEPT_LIST_ONLY ||
125 scanner_.scan_filter_policy == bluetooth::hci::LeScanningFilterPolicy::
126 FILTER_ACCEPT_LIST_AND_INITIATORS_IDENTITY)) {
127 return true;
128 }
129
130 // • the initiator filter policy uses the Filter Accept List and an
131 // HCI_LE_Create_Connection or HCI_LE_Extended_Create_Connection
132 // command is pending.
133 if (initiator_.IsEnabled() &&
134 initiator_.initiator_filter_policy ==
135 bluetooth::hci::InitiatorFilterPolicy::USE_FILTER_ACCEPT_LIST_WITH_PEER_ADDRESS) {
136 return true;
137 }
138
139 return false;
140 }
141
LeFilterAcceptListContainsDevice(FilterAcceptListAddressType address_type,Address address)142 bool LinkLayerController::LeFilterAcceptListContainsDevice(FilterAcceptListAddressType address_type,
143 Address address) {
144 for (auto const& entry : le_filter_accept_list_) {
145 if (entry.address_type == address_type &&
146 (address_type == FilterAcceptListAddressType::ANONYMOUS_ADVERTISERS ||
147 entry.address == address)) {
148 return true;
149 }
150 }
151
152 return false;
153 }
154
LePeriodicAdvertiserListContainsDevice(bluetooth::hci::AdvertiserAddressType advertiser_address_type,Address advertiser_address,uint8_t advertising_sid)155 bool LinkLayerController::LePeriodicAdvertiserListContainsDevice(
156 bluetooth::hci::AdvertiserAddressType advertiser_address_type, Address advertiser_address,
157 uint8_t advertising_sid) {
158 for (auto const& entry : le_periodic_advertiser_list_) {
159 if (entry.advertiser_address_type == advertiser_address_type &&
160 entry.advertiser_address == advertiser_address &&
161 entry.advertising_sid == advertising_sid) {
162 return true;
163 }
164 }
165
166 return false;
167 }
168
LeFilterAcceptListContainsDevice(AddressWithType address)169 bool LinkLayerController::LeFilterAcceptListContainsDevice(AddressWithType address) {
170 FilterAcceptListAddressType address_type;
171 switch (address.GetAddressType()) {
172 case AddressType::PUBLIC_DEVICE_ADDRESS:
173 case AddressType::PUBLIC_IDENTITY_ADDRESS:
174 address_type = FilterAcceptListAddressType::PUBLIC;
175 break;
176 case AddressType::RANDOM_DEVICE_ADDRESS:
177 case AddressType::RANDOM_IDENTITY_ADDRESS:
178 address_type = FilterAcceptListAddressType::RANDOM;
179 break;
180 }
181
182 return LeFilterAcceptListContainsDevice(address_type, address.GetAddress());
183 }
184
ResolvingListBusy()185 bool LinkLayerController::ResolvingListBusy() {
186 // The resolving list cannot be modified when
187 // • Advertising (other than periodic advertising) is enabled,
188 if (legacy_advertiser_.IsEnabled()) {
189 return true;
190 }
191
192 for (auto const& [_, advertiser] : extended_advertisers_) {
193 if (advertiser.IsEnabled()) {
194 return true;
195 }
196 }
197
198 // • Scanning is enabled,
199 if (scanner_.IsEnabled()) {
200 return true;
201 }
202
203 // • an HCI_LE_Create_Connection, HCI_LE_Extended_Create_Connection, or
204 // HCI_LE_Periodic_Advertising_Create_Sync command is pending.
205 if (initiator_.IsEnabled()) {
206 return true;
207 }
208
209 return false;
210 }
211
ResolvePrivateAddress(AddressWithType address)212 std::optional<AddressWithType> LinkLayerController::ResolvePrivateAddress(AddressWithType address) {
213 if (!address.IsRpa()) {
214 return address;
215 }
216
217 if (!le_resolving_list_enabled_) {
218 return {};
219 }
220
221 for (auto& entry : le_resolving_list_) {
222 if (address.IsRpaThatMatchesIrk(entry.peer_irk)) {
223 // Update the peer resolvable address used for the peer
224 // with the returned identity address.
225 entry.peer_resolvable_address = address.GetAddress();
226
227 return PeerDeviceAddress(entry.peer_identity_address, entry.peer_identity_address_type);
228 }
229 }
230
231 return {};
232 }
233
ResolveTargetA(AddressWithType target_a,AddressWithType adv_a)234 bool LinkLayerController::ResolveTargetA(AddressWithType target_a, AddressWithType adv_a) {
235 if (!le_resolving_list_enabled_) {
236 return false;
237 }
238
239 for (auto const& entry : le_resolving_list_) {
240 if (adv_a == PeerDeviceAddress(entry.peer_identity_address, entry.peer_identity_address_type) &&
241 target_a.IsRpaThatMatchesIrk(entry.local_irk)) {
242 return true;
243 }
244 }
245
246 return false;
247 }
248
ValidateTargetA(AddressWithType target_a,AddressWithType adv_a)249 bool LinkLayerController::ValidateTargetA(AddressWithType target_a, AddressWithType adv_a) {
250 if (IsLocalPublicOrRandomAddress(target_a)) {
251 return true;
252 }
253 if (target_a.IsRpa()) {
254 return ResolveTargetA(target_a, adv_a);
255 }
256 return false;
257 }
258
GenerateResolvablePrivateAddress(AddressWithType address,IrkSelection irk)259 std::optional<AddressWithType> LinkLayerController::GenerateResolvablePrivateAddress(
260 AddressWithType address, IrkSelection irk) {
261 for (auto& entry : le_resolving_list_) {
262 if (address.GetAddress() == entry.peer_identity_address &&
263 address.ToPeerAddressType() == entry.peer_identity_address_type) {
264 std::array<uint8_t, LinkLayerController::kIrkSize> const& used_irk =
265 irk == IrkSelection::Local ? entry.local_irk : entry.peer_irk;
266 Address local_resolvable_address = generate_rpa(used_irk);
267
268 // Update the local resolvable address used for the peer
269 // with the returned identity address.
270 if (irk == IrkSelection::Local) {
271 entry.local_resolvable_address = local_resolvable_address;
272 }
273
274 return AddressWithType{local_resolvable_address, AddressType::RANDOM_DEVICE_ADDRESS};
275 }
276 }
277
278 return {};
279 }
280
281 // =============================================================================
282 // BR/EDR Commands
283 // =============================================================================
284
285 // HCI Read Rssi command (Vol 4, Part E § 7.5.4).
ReadRssi(uint16_t connection_handle,int8_t * rssi)286 ErrorCode LinkLayerController::ReadRssi(uint16_t connection_handle, int8_t* rssi) {
287 // Not documented: If the connection handle is not found, the Controller
288 // shall return the error code Unknown Connection Identifier (0x02).
289 if (!connections_.HasHandle(connection_handle)) {
290 INFO(id_, "unknown connection identifier");
291 return ErrorCode::UNKNOWN_CONNECTION;
292 }
293
294 *rssi = connections_.GetRssi(connection_handle);
295 return ErrorCode::SUCCESS;
296 }
297
298 // =============================================================================
299 // General LE Commands
300 // =============================================================================
301
302 // HCI LE Set Random Address command (Vol 4, Part E § 7.8.4).
LeSetRandomAddress(Address random_address)303 ErrorCode LinkLayerController::LeSetRandomAddress(Address random_address) {
304 // If the Host issues this command when any of advertising (created using
305 // legacy advertising commands), scanning, or initiating are enabled,
306 // the Controller shall return the error code Command Disallowed (0x0C).
307 if (legacy_advertiser_.IsEnabled() || scanner_.IsEnabled() || initiator_.IsEnabled()) {
308 INFO(id_, "advertising, scanning or initiating are currently active");
309 return ErrorCode::COMMAND_DISALLOWED;
310 }
311
312 if (random_address == Address::kEmpty) {
313 INFO(id_, "the random address may not be set to 00:00:00:00:00:00");
314 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
315 }
316
317 random_address_ = random_address;
318 return ErrorCode::SUCCESS;
319 }
320
321 // HCI LE Set Host Feature command (Vol 4, Part E § 7.8.45).
LeSetResolvablePrivateAddressTimeout(uint16_t rpa_timeout)322 ErrorCode LinkLayerController::LeSetResolvablePrivateAddressTimeout(uint16_t rpa_timeout) {
323 // Note: no documented status code for this case.
324 if (rpa_timeout < 0x1 || rpa_timeout > 0x0e10) {
325 INFO(id_,
326 "rpa_timeout (0x{:04x}) is outside the range of supported values "
327 " 0x1 - 0x0e10",
328 rpa_timeout);
329 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
330 }
331
332 resolvable_private_address_timeout_ = seconds(rpa_timeout);
333 return ErrorCode::SUCCESS;
334 }
335
336 // HCI LE Read Phy command (Vol 4, Part E § 7.8.47).
LeReadPhy(uint16_t connection_handle,bluetooth::hci::PhyType * tx_phy,bluetooth::hci::PhyType * rx_phy)337 ErrorCode LinkLayerController::LeReadPhy(uint16_t connection_handle,
338 bluetooth::hci::PhyType* tx_phy,
339 bluetooth::hci::PhyType* rx_phy) {
340 // Note: no documented status code for this case.
341 if (!connections_.HasHandle(connection_handle) ||
342 connections_.GetPhyType(connection_handle) != Phy::Type::LOW_ENERGY) {
343 INFO(id_, "unknown or invalid connection handle");
344 return ErrorCode::UNKNOWN_CONNECTION;
345 }
346
347 AclConnection const& connection = connections_.GetAclConnection(connection_handle);
348 *tx_phy = connection.GetTxPhy();
349 *rx_phy = connection.GetRxPhy();
350 return ErrorCode::SUCCESS;
351 }
352
353 // HCI LE Set Default Phy command (Vol 4, Part E § 7.8.48).
LeSetDefaultPhy(bool all_phys_no_transmit_preference,bool all_phys_no_receive_preference,uint8_t tx_phys,uint8_t rx_phys)354 ErrorCode LinkLayerController::LeSetDefaultPhy(bool all_phys_no_transmit_preference,
355 bool all_phys_no_receive_preference, uint8_t tx_phys,
356 uint8_t rx_phys) {
357 uint8_t supported_phys = properties_.LeSupportedPhys();
358
359 // If the All_PHYs parameter specifies that the Host has no preference,
360 // the TX_PHYs parameter shall be ignored; otherwise at least one bit shall
361 // be set to 1.
362 if (all_phys_no_transmit_preference) {
363 tx_phys = supported_phys;
364 }
365 if (tx_phys == 0) {
366 INFO(id_, "TX_Phys does not configure any bit");
367 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
368 }
369
370 // If the All_PHYs parameter specifies that the Host has no preference,
371 // the RX_PHYs parameter shall be ignored; otherwise at least one bit shall
372 // be set to 1.
373 if (all_phys_no_receive_preference) {
374 rx_phys = supported_phys;
375 }
376 if (rx_phys == 0) {
377 INFO(id_, "RX_Phys does not configure any bit");
378 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
379 }
380
381 // If the Host sets, in the TX_PHYs or RX_PHYs parameter, a bit for a PHY that
382 // the Controller does not support, including a bit that is reserved for
383 // future use, the Controller shall return the error code Unsupported Feature
384 // or Parameter Value (0x11).
385 if ((tx_phys & ~supported_phys) != 0) {
386 INFO(id_, "TX_PhyS {:x} configures unsupported or reserved bits", tx_phys);
387 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
388 }
389 if ((rx_phys & ~supported_phys) != 0) {
390 INFO(id_, "RX_PhyS {:x} configures unsupported or reserved bits", rx_phys);
391 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
392 }
393
394 default_tx_phys_ = tx_phys;
395 default_rx_phys_ = rx_phys;
396 return ErrorCode::SUCCESS;
397 }
398
399 // HCI LE Set Phy command (Vol 4, Part E § 7.8.49).
LeSetPhy(uint16_t connection_handle,bool all_phys_no_transmit_preference,bool all_phys_no_receive_preference,uint8_t tx_phys,uint8_t rx_phys,bluetooth::hci::PhyOptions)400 ErrorCode LinkLayerController::LeSetPhy(uint16_t connection_handle,
401 bool all_phys_no_transmit_preference,
402 bool all_phys_no_receive_preference, uint8_t tx_phys,
403 uint8_t rx_phys,
404 bluetooth::hci::PhyOptions /*phy_options*/) {
405 uint8_t supported_phys = properties_.LeSupportedPhys();
406
407 // Note: no documented status code for this case.
408 if (!connections_.HasHandle(connection_handle) ||
409 connections_.GetPhyType(connection_handle) != Phy::Type::LOW_ENERGY) {
410 INFO(id_, "unknown or invalid connection handle");
411 return ErrorCode::UNKNOWN_CONNECTION;
412 }
413
414 // If the All_PHYs parameter specifies that the Host has no preference,
415 // the TX_PHYs parameter shall be ignored; otherwise at least one bit shall
416 // be set to 1.
417 if (all_phys_no_transmit_preference) {
418 tx_phys = supported_phys;
419 }
420 if (tx_phys == 0) {
421 INFO(id_, "TX_Phys does not configure any bit");
422 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
423 }
424
425 // If the All_PHYs parameter specifies that the Host has no preference,
426 // the RX_PHYs parameter shall be ignored; otherwise at least one bit shall
427 // be set to 1.
428 if (all_phys_no_receive_preference) {
429 rx_phys = supported_phys;
430 }
431 if (rx_phys == 0) {
432 INFO(id_, "RX_Phys does not configure any bit");
433 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
434 }
435
436 // If the Host sets, in the TX_PHYs or RX_PHYs parameter, a bit for a PHY that
437 // the Controller does not support, including a bit that is reserved for
438 // future use, the Controller shall return the error code Unsupported Feature
439 // or Parameter Value (0x11).
440 if ((tx_phys & ~supported_phys) != 0) {
441 INFO(id_, "TX_PhyS ({:x}) configures unsupported or reserved bits", tx_phys);
442 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
443 }
444 if ((rx_phys & ~supported_phys) != 0) {
445 INFO(id_, "RX_PhyS ({:x}) configures unsupported or reserved bits", rx_phys);
446 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
447 }
448
449 // The HCI_LE_PHY_Update_Complete event shall be generated either when one
450 // or both PHY changes or when the Controller determines that neither PHY
451 // will change immediately.
452 SendLeLinkLayerPacket(model::packets::LlPhyReqBuilder::Create(
453 connections_.GetOwnAddress(connection_handle).GetAddress(),
454 connections_.GetAddress(connection_handle).GetAddress(), tx_phys, rx_phys));
455
456 connections_.GetAclConnection(connection_handle).InitiatePhyUpdate();
457 requested_tx_phys_ = tx_phys;
458 requested_rx_phys_ = rx_phys;
459 return ErrorCode::SUCCESS;
460 }
461
462 // Helper to pick one phy in enabled phys.
select_phy(uint8_t phys,bluetooth::hci::PhyType current)463 static bluetooth::hci::PhyType select_phy(uint8_t phys, bluetooth::hci::PhyType current) {
464 return (phys & 0x4) ? bluetooth::hci::PhyType::LE_CODED
465 : (phys & 0x2) ? bluetooth::hci::PhyType::LE_2M
466 : (phys & 0x1) ? bluetooth::hci::PhyType::LE_1M
467 : current;
468 }
469
470 // Helper to generate the LL_PHY_UPDATE_IND mask for the selected phy.
471 // The mask is non zero only if the phy has changed.
indicate_phy(bluetooth::hci::PhyType selected,bluetooth::hci::PhyType current)472 static uint8_t indicate_phy(bluetooth::hci::PhyType selected, bluetooth::hci::PhyType current) {
473 return selected == current ? 0x0
474 : selected == bluetooth::hci::PhyType::LE_CODED ? 0x4
475 : selected == bluetooth::hci::PhyType::LE_2M ? 0x2
476 : 0x1;
477 }
478
IncomingLlPhyReq(model::packets::LinkLayerPacketView incoming)479 void LinkLayerController::IncomingLlPhyReq(model::packets::LinkLayerPacketView incoming) {
480 auto phy_req = model::packets::LlPhyReqView::Create(incoming);
481 ASSERT(phy_req.IsValid());
482 uint16_t connection_handle = connections_.GetHandleOnlyAddress(incoming.GetSourceAddress());
483
484 if (connection_handle == kReservedHandle) {
485 INFO(id_, "@{}: Unknown connection @{}", incoming.GetDestinationAddress(),
486 incoming.GetSourceAddress());
487 return;
488 }
489
490 AclConnection& connection = connections_.GetAclConnection(connection_handle);
491
492 if (connection.GetRole() == bluetooth::hci::Role::PERIPHERAL) {
493 // Peripheral receives the request: respond with local phy preferences
494 // in LL_PHY_RSP pdu.
495 SendLeLinkLayerPacket(model::packets::LlPhyRspBuilder::Create(
496 incoming.GetDestinationAddress(), incoming.GetSourceAddress(), default_tx_phys_,
497 default_rx_phys_));
498 } else {
499 // Central receives the request: respond with LL_PHY_UPDATE_IND and
500 // the selected phys.
501
502 // Intersect phy preferences with local preferences.
503 uint8_t tx_phys = phy_req.GetRxPhys() & default_tx_phys_;
504 uint8_t rx_phys = phy_req.GetTxPhys() & default_rx_phys_;
505
506 // Select valid TX and RX phys from preferences.
507 bluetooth::hci::PhyType phy_c_to_p = select_phy(tx_phys, connection.GetTxPhy());
508 bluetooth::hci::PhyType phy_p_to_c = select_phy(rx_phys, connection.GetRxPhy());
509
510 // Send LL_PHY_UPDATE_IND to notify selected phys.
511 //
512 // PHY_C_TO_P shall be set to indicate the PHY that shall be used for
513 // packets sent from the Central to the Peripheral. These fields each
514 // consist of 8 bits. If a PHY is changing, the bit corresponding to the new
515 // PHY shall be set to 1 and the remaining bits to 0; if a PHY is remaining
516 // unchanged, then the corresponding field shall be set to the value 0.
517 SendLeLinkLayerPacket(model::packets::LlPhyUpdateIndBuilder::Create(
518 incoming.GetDestinationAddress(), incoming.GetSourceAddress(),
519 indicate_phy(phy_c_to_p, connection.GetTxPhy()),
520 indicate_phy(phy_p_to_c, connection.GetRxPhy()), 0));
521
522 // Notify the host when the phy selection has changed
523 // (responder in this case).
524 if ((phy_c_to_p != connection.GetTxPhy() || phy_p_to_c != connection.GetRxPhy()) &&
525 IsLeEventUnmasked(SubeventCode::LE_PHY_UPDATE_COMPLETE)) {
526 send_event_(bluetooth::hci::LePhyUpdateCompleteBuilder::Create(
527 ErrorCode::SUCCESS, connection_handle, phy_c_to_p, phy_p_to_c));
528 }
529
530 // Update local state.
531 connection.SetTxPhy(phy_c_to_p);
532 connection.SetRxPhy(phy_p_to_c);
533 }
534 }
535
IncomingLlPhyRsp(model::packets::LinkLayerPacketView incoming)536 void LinkLayerController::IncomingLlPhyRsp(model::packets::LinkLayerPacketView incoming) {
537 auto phy_rsp = model::packets::LlPhyRspView::Create(incoming);
538 ASSERT(phy_rsp.IsValid());
539 uint16_t connection_handle = connections_.GetHandleOnlyAddress(incoming.GetSourceAddress());
540
541 if (connection_handle == kReservedHandle) {
542 INFO(id_, "@{}: Unknown connection @{}", incoming.GetDestinationAddress(),
543 incoming.GetSourceAddress());
544 return;
545 }
546
547 AclConnection& connection = connections_.GetAclConnection(connection_handle);
548 ASSERT(connection.GetRole() == bluetooth::hci::Role::CENTRAL);
549
550 // Intersect phy preferences with local preferences.
551 uint8_t tx_phys = phy_rsp.GetRxPhys() & requested_tx_phys_;
552 uint8_t rx_phys = phy_rsp.GetTxPhys() & requested_rx_phys_;
553
554 // Select valid TX and RX phys from preferences.
555 bluetooth::hci::PhyType phy_c_to_p = select_phy(tx_phys, connection.GetTxPhy());
556 bluetooth::hci::PhyType phy_p_to_c = select_phy(rx_phys, connection.GetRxPhy());
557
558 // Send LL_PHY_UPDATE_IND to notify selected phys.
559 //
560 // PHY_C_TO_P shall be set to indicate the PHY that shall be used for
561 // packets sent from the Central to the Peripheral. These fields each
562 // consist of 8 bits. If a PHY is changing, the bit corresponding to the new
563 // PHY shall be set to 1 and the remaining bits to 0; if a PHY is remaining
564 // unchanged, then the corresponding field shall be set to the value 0.
565 SendLeLinkLayerPacket(model::packets::LlPhyUpdateIndBuilder::Create(
566 incoming.GetDestinationAddress(), incoming.GetSourceAddress(),
567 indicate_phy(phy_c_to_p, connection.GetTxPhy()),
568 indicate_phy(phy_p_to_c, connection.GetRxPhy()), 0));
569
570 // Always notify the host, even if the phy selection has not changed
571 // (initiator in this case).
572 if (IsLeEventUnmasked(SubeventCode::LE_PHY_UPDATE_COMPLETE)) {
573 send_event_(bluetooth::hci::LePhyUpdateCompleteBuilder::Create(
574 ErrorCode::SUCCESS, connection_handle, phy_c_to_p, phy_p_to_c));
575 }
576
577 // Update local state.
578 connection.PhyUpdateComplete();
579 connection.SetTxPhy(phy_c_to_p);
580 connection.SetRxPhy(phy_p_to_c);
581 }
582
IncomingLlPhyUpdateInd(model::packets::LinkLayerPacketView incoming)583 void LinkLayerController::IncomingLlPhyUpdateInd(model::packets::LinkLayerPacketView incoming) {
584 auto phy_update_ind = model::packets::LlPhyUpdateIndView::Create(incoming);
585 ASSERT(phy_update_ind.IsValid());
586 uint16_t connection_handle = connections_.GetHandleOnlyAddress(incoming.GetSourceAddress());
587
588 if (connection_handle == kReservedHandle) {
589 INFO(id_, "@{}: Unknown connection @{}", incoming.GetDestinationAddress(),
590 incoming.GetSourceAddress());
591 return;
592 }
593
594 AclConnection& connection = connections_.GetAclConnection(connection_handle);
595 ASSERT(connection.GetRole() == bluetooth::hci::Role::PERIPHERAL);
596
597 bluetooth::hci::PhyType tx_phy = select_phy(phy_update_ind.GetPhyPToC(), connection.GetTxPhy());
598 bluetooth::hci::PhyType rx_phy = select_phy(phy_update_ind.GetPhyCToP(), connection.GetRxPhy());
599
600 // Update local state, and notify the host.
601 // The notification is sent only when the local host is initiator
602 // of the Phy update procedure or the phy selection has changed.
603 if (IsLeEventUnmasked(SubeventCode::LE_PHY_UPDATE_COMPLETE) &&
604 (tx_phy != connection.GetTxPhy() || rx_phy != connection.GetRxPhy() ||
605 connection.InitiatedPhyUpdate())) {
606 send_event_(bluetooth::hci::LePhyUpdateCompleteBuilder::Create(
607 ErrorCode::SUCCESS, connection_handle, tx_phy, rx_phy));
608 }
609
610 connection.PhyUpdateComplete();
611 connection.SetTxPhy(tx_phy);
612 connection.SetRxPhy(rx_phy);
613 }
614
615 // HCI LE Set Host Feature command (Vol 4, Part E § 7.8.115).
LeSetHostFeature(uint8_t bit_number,uint8_t bit_value)616 ErrorCode LinkLayerController::LeSetHostFeature(uint8_t bit_number, uint8_t bit_value) {
617 if (bit_number >= 64 || bit_value > 1) {
618 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
619 }
620
621 // If Bit_Value is set to 0x01 and Bit_Number specifies a feature bit that
622 // requires support of a feature that the Controller does not support,
623 // the Controller shall return the error code Unsupported Feature or
624 // Parameter Value (0x11).
625 // TODO
626
627 // If the Host issues this command while the Controller has a connection to
628 // another device, the Controller shall return the error code
629 // Command Disallowed (0x0C).
630 if (HasAclConnection()) {
631 return ErrorCode::COMMAND_DISALLOWED;
632 }
633
634 uint64_t bit_mask = UINT64_C(1) << bit_number;
635 if (bit_mask ==
636 static_cast<uint64_t>(LLFeaturesBits::CONNECTED_ISOCHRONOUS_STREAM_HOST_SUPPORT)) {
637 connected_isochronous_stream_host_support_ = bit_value != 0;
638 } else if (bit_mask == static_cast<uint64_t>(LLFeaturesBits::CONNECTION_SUBRATING_HOST_SUPPORT)) {
639 connection_subrating_host_support_ = bit_value != 0;
640 }
641 // If Bit_Number specifies a feature bit that is not controlled by the Host,
642 // the Controller shall return the error code Unsupported Feature or
643 // Parameter Value (0x11).
644 else {
645 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
646 }
647
648 if (bit_value != 0) {
649 le_host_supported_features_ |= bit_mask;
650 } else {
651 le_host_supported_features_ &= ~bit_mask;
652 }
653
654 return ErrorCode::SUCCESS;
655 }
656
657 // =============================================================================
658 // LE Resolving List
659 // =============================================================================
660
661 // HCI command LE_Add_Device_To_Resolving_List (Vol 4, Part E § 7.8.38).
LeAddDeviceToResolvingList(PeerAddressType peer_identity_address_type,Address peer_identity_address,std::array<uint8_t,kIrkSize> peer_irk,std::array<uint8_t,kIrkSize> local_irk)662 ErrorCode LinkLayerController::LeAddDeviceToResolvingList(
663 PeerAddressType peer_identity_address_type, Address peer_identity_address,
664 std::array<uint8_t, kIrkSize> peer_irk, std::array<uint8_t, kIrkSize> local_irk) {
665 // This command shall not be used when address resolution is enabled in the
666 // Controller and:
667 // • Advertising (other than periodic advertising) is enabled,
668 // • Scanning is enabled, or
669 // • an HCI_LE_Create_Connection, HCI_LE_Extended_Create_Connection, or
670 // HCI_LE_Periodic_Advertising_Create_Sync command is pending.
671 if (le_resolving_list_enabled_ && ResolvingListBusy()) {
672 INFO(id_,
673 "device is currently advertising, scanning, or establishing an"
674 " LE connection");
675 return ErrorCode::COMMAND_DISALLOWED;
676 }
677
678 // When a Controller cannot add a device to the list because there is no space
679 // available, it shall return the error code Memory Capacity Exceeded (0x07).
680 if (le_resolving_list_.size() >= properties_.le_resolving_list_size) {
681 INFO(id_, "resolving list is full");
682 return ErrorCode::MEMORY_CAPACITY_EXCEEDED;
683 }
684
685 // If there is an existing entry in the resolving list with the same
686 // Peer_Identity_Address and Peer_Identity_Address_Type, or with the same
687 // Peer_IRK, the Controller should return the error code Invalid HCI Command
688 // Parameters (0x12).
689 for (auto const& entry : le_resolving_list_) {
690 if ((entry.peer_identity_address_type == peer_identity_address_type &&
691 entry.peer_identity_address == peer_identity_address) ||
692 (entry.peer_irk == peer_irk && !irk_is_zero(peer_irk))) {
693 INFO(id_, "device is already present in the resolving list");
694 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
695 }
696 }
697
698 le_resolving_list_.emplace_back(ResolvingListEntry{peer_identity_address_type,
699 peer_identity_address,
700 peer_irk,
701 local_irk,
702 PrivacyMode::NETWORK,
703 {},
704 {}});
705 return ErrorCode::SUCCESS;
706 }
707
708 // HCI command LE_Remove_Device_From_Resolving_List (Vol 4, Part E § 7.8.39).
LeRemoveDeviceFromResolvingList(PeerAddressType peer_identity_address_type,Address peer_identity_address)709 ErrorCode LinkLayerController::LeRemoveDeviceFromResolvingList(
710 PeerAddressType peer_identity_address_type, Address peer_identity_address) {
711 // This command shall not be used when address resolution is enabled in the
712 // Controller and:
713 // • Advertising (other than periodic advertising) is enabled,
714 // • Scanning is enabled, or
715 // • an HCI_LE_Create_Connection, HCI_LE_Extended_Create_Connection, or
716 // HCI_LE_Periodic_Advertising_Create_Sync command is pending.
717 if (le_resolving_list_enabled_ && ResolvingListBusy()) {
718 INFO(id_,
719 "device is currently advertising, scanning, or establishing an"
720 " LE connection");
721 return ErrorCode::COMMAND_DISALLOWED;
722 }
723
724 for (auto it = le_resolving_list_.begin(); it != le_resolving_list_.end(); it++) {
725 if (it->peer_identity_address_type == peer_identity_address_type &&
726 it->peer_identity_address == peer_identity_address) {
727 le_resolving_list_.erase(it);
728 return ErrorCode::SUCCESS;
729 }
730 }
731
732 // When a Controller cannot remove a device from the resolving list because
733 // it is not found, it shall return the error code
734 // Unknown Connection Identifier (0x02).
735 INFO(id_, "peer address not found in the resolving list");
736 return ErrorCode::UNKNOWN_CONNECTION;
737 }
738
739 // HCI command LE_Clear_Resolving_List (Vol 4, Part E § 7.8.40).
LeClearResolvingList()740 ErrorCode LinkLayerController::LeClearResolvingList() {
741 // This command shall not be used when address resolution is enabled in the
742 // Controller and:
743 // • Advertising (other than periodic advertising) is enabled,
744 // • Scanning is enabled, or
745 // • an HCI_LE_Create_Connection, HCI_LE_Extended_Create_Connection, or
746 // HCI_LE_Periodic_Advertising_Create_Sync command is pending.
747 if (le_resolving_list_enabled_ && ResolvingListBusy()) {
748 INFO(id_,
749 "device is currently advertising, scanning,"
750 " or establishing an LE connection");
751 return ErrorCode::COMMAND_DISALLOWED;
752 }
753
754 le_resolving_list_.clear();
755 return ErrorCode::SUCCESS;
756 }
757
758 // HCI command LE_Read_Peer_Resolvable_Address (Vol 4, Part E § 7.8.42).
LeReadPeerResolvableAddress(PeerAddressType peer_identity_address_type,Address peer_identity_address,Address * peer_resolvable_address)759 ErrorCode LinkLayerController::LeReadPeerResolvableAddress(
760 PeerAddressType peer_identity_address_type, Address peer_identity_address,
761 Address* peer_resolvable_address) {
762 for (auto const& entry : le_resolving_list_) {
763 if (entry.peer_identity_address_type == peer_identity_address_type &&
764 entry.peer_identity_address == peer_identity_address &&
765 entry.peer_resolvable_address.has_value()) {
766 *peer_resolvable_address = entry.peer_resolvable_address.value();
767 return ErrorCode::SUCCESS;
768 }
769 }
770
771 // When a Controller cannot find a Resolvable Private Address associated with
772 // the Peer Identity Address, or if the Peer Identity Address cannot be found
773 // in the resolving list, it shall return the error code
774 // Unknown Connection Identifier (0x02).
775 INFO(id_,
776 "peer identity address {}[{}] not found in the resolving list,"
777 " or peer resolvable address unavailable",
778 peer_identity_address, PeerAddressTypeText(peer_identity_address_type));
779 return ErrorCode::UNKNOWN_CONNECTION;
780 }
781
782 // HCI command LE_Read_Local_Resolvable_Address (Vol 4, Part E § 7.8.43).
LeReadLocalResolvableAddress(PeerAddressType peer_identity_address_type,Address peer_identity_address,Address * local_resolvable_address)783 ErrorCode LinkLayerController::LeReadLocalResolvableAddress(
784 PeerAddressType peer_identity_address_type, Address peer_identity_address,
785 Address* local_resolvable_address) {
786 for (auto const& entry : le_resolving_list_) {
787 if (entry.peer_identity_address_type == peer_identity_address_type &&
788 entry.peer_identity_address == peer_identity_address &&
789 entry.local_resolvable_address.has_value()) {
790 *local_resolvable_address = entry.local_resolvable_address.value();
791 return ErrorCode::SUCCESS;
792 }
793 }
794
795 // When a Controller cannot find a Resolvable Private Address associated with
796 // the Peer Identity Address, or if the Peer Identity Address cannot be found
797 // in the resolving list, it shall return the error code
798 // Unknown Connection Identifier (0x02).
799 INFO(id_,
800 "peer identity address {}[{}] not found in the resolving list,"
801 " or peer resolvable address unavailable",
802 peer_identity_address, PeerAddressTypeText(peer_identity_address_type));
803 return ErrorCode::UNKNOWN_CONNECTION;
804 }
805
806 // HCI command LE_Set_Address_Resolution_Enable (Vol 4, Part E § 7.8.44).
LeSetAddressResolutionEnable(bool enable)807 ErrorCode LinkLayerController::LeSetAddressResolutionEnable(bool enable) {
808 // This command shall not be used when:
809 // • Advertising (other than periodic advertising) is enabled,
810 // • Scanning is enabled, or
811 // • an HCI_LE_Create_Connection, HCI_LE_Extended_Create_Connection, or
812 // HCI_LE_Periodic_Advertising_Create_Sync command is pending.
813 if (ResolvingListBusy()) {
814 INFO(id_,
815 "device is currently advertising, scanning,"
816 " or establishing an LE connection");
817 return ErrorCode::COMMAND_DISALLOWED;
818 }
819
820 le_resolving_list_enabled_ = enable;
821 return ErrorCode::SUCCESS;
822 }
823
824 // HCI command LE_Set_Privacy_Mode (Vol 4, Part E § 7.8.77).
LeSetPrivacyMode(PeerAddressType peer_identity_address_type,Address peer_identity_address,bluetooth::hci::PrivacyMode privacy_mode)825 ErrorCode LinkLayerController::LeSetPrivacyMode(PeerAddressType peer_identity_address_type,
826 Address peer_identity_address,
827 bluetooth::hci::PrivacyMode privacy_mode) {
828 // This command shall not be used when address resolution is enabled in the
829 // Controller and:
830 // • Advertising (other than periodic advertising) is enabled,
831 // • Scanning is enabled, or
832 // • an HCI_LE_Create_Connection, HCI_LE_Extended_Create_Connection, or
833 // HCI_LE_Periodic_Advertising_Create_Sync command is pending.
834 if (le_resolving_list_enabled_ && ResolvingListBusy()) {
835 INFO(id_,
836 "device is currently advertising, scanning,"
837 " or establishing an LE connection");
838 return ErrorCode::COMMAND_DISALLOWED;
839 }
840
841 for (auto& entry : le_resolving_list_) {
842 if (entry.peer_identity_address_type == peer_identity_address_type &&
843 entry.peer_identity_address == peer_identity_address) {
844 entry.privacy_mode = privacy_mode;
845 return ErrorCode::SUCCESS;
846 }
847 }
848
849 // If the device is not on the resolving list, the Controller shall return
850 // the error code Unknown Connection Identifier (0x02).
851 INFO(id_, "peer address not found in the resolving list");
852 return ErrorCode::UNKNOWN_CONNECTION;
853 }
854
855 // =============================================================================
856 // LE Filter Accept List
857 // =============================================================================
858
859 // HCI command LE_Clear_Filter_Accept_List (Vol 4, Part E § 7.8.15).
LeClearFilterAcceptList()860 ErrorCode LinkLayerController::LeClearFilterAcceptList() {
861 // This command shall not be used when:
862 // • any advertising filter policy uses the Filter Accept List and
863 // advertising is enabled,
864 // • the scanning filter policy uses the Filter Accept List and scanning
865 // is enabled, or
866 // • the initiator filter policy uses the Filter Accept List and an
867 // HCI_LE_Create_Connection or HCI_LE_Extended_Create_Connection
868 // command is pending.
869 if (FilterAcceptListBusy()) {
870 INFO(id_,
871 "device is currently advertising, scanning,"
872 " or establishing an LE connection using the filter accept list");
873 return ErrorCode::COMMAND_DISALLOWED;
874 }
875
876 le_filter_accept_list_.clear();
877 return ErrorCode::SUCCESS;
878 }
879
880 // HCI command LE_Add_Device_To_Filter_Accept_List (Vol 4, Part E § 7.8.16).
LeAddDeviceToFilterAcceptList(FilterAcceptListAddressType address_type,Address address)881 ErrorCode LinkLayerController::LeAddDeviceToFilterAcceptList(
882 FilterAcceptListAddressType address_type, Address address) {
883 // This command shall not be used when:
884 // • any advertising filter policy uses the Filter Accept List and
885 // advertising is enabled,
886 // • the scanning filter policy uses the Filter Accept List and scanning
887 // is enabled, or
888 // • the initiator filter policy uses the Filter Accept List and an
889 // HCI_LE_Create_Connection or HCI_LE_Extended_Create_Connection
890 // command is pending.
891 if (FilterAcceptListBusy()) {
892 INFO(id_,
893 "device is currently advertising, scanning,"
894 " or establishing an LE connection using the filter accept list");
895 return ErrorCode::COMMAND_DISALLOWED;
896 }
897
898 // When a Controller cannot add a device to the Filter Accept List
899 // because there is no space available, it shall return the error code
900 // Memory Capacity Exceeded (0x07).
901 if (le_filter_accept_list_.size() >= properties_.le_filter_accept_list_size) {
902 INFO(id_, "filter accept list is full");
903 return ErrorCode::MEMORY_CAPACITY_EXCEEDED;
904 }
905
906 le_filter_accept_list_.emplace_back(FilterAcceptListEntry{address_type, address});
907 return ErrorCode::SUCCESS;
908 }
909
910 // HCI command LE_Remove_Device_From_Filter_Accept_List (Vol 4, Part E
911 // § 7.8.17).
LeRemoveDeviceFromFilterAcceptList(FilterAcceptListAddressType address_type,Address address)912 ErrorCode LinkLayerController::LeRemoveDeviceFromFilterAcceptList(
913 FilterAcceptListAddressType address_type, Address address) {
914 // This command shall not be used when:
915 // • any advertising filter policy uses the Filter Accept List and
916 // advertising is enabled,
917 // • the scanning filter policy uses the Filter Accept List and scanning
918 // is enabled, or
919 // • the initiator filter policy uses the Filter Accept List and an
920 // HCI_LE_Create_Connection or HCI_LE_Extended_Create_Connection
921 // command is pending.
922 if (FilterAcceptListBusy()) {
923 INFO(id_,
924 "device is currently advertising, scanning,"
925 " or establishing an LE connection using the filter accept list");
926 return ErrorCode::COMMAND_DISALLOWED;
927 }
928
929 for (auto it = le_filter_accept_list_.begin(); it != le_filter_accept_list_.end(); it++) {
930 // Address shall be ignored when Address_Type is set to 0xFF.
931 if (it->address_type == address_type &&
932 (address_type == FilterAcceptListAddressType::ANONYMOUS_ADVERTISERS ||
933 it->address == address)) {
934 le_filter_accept_list_.erase(it);
935 return ErrorCode::SUCCESS;
936 }
937 }
938
939 // Note: this case is not documented.
940 INFO(id_, "address not found in the filter accept list");
941 return ErrorCode::SUCCESS;
942 }
943
944 // =============================================================================
945 // LE Periodic Advertiser List
946 // =============================================================================
947
948 // HCI LE Add Device To Periodic Advertiser List command (Vol 4, Part E
949 // § 7.8.70).
LeAddDeviceToPeriodicAdvertiserList(bluetooth::hci::AdvertiserAddressType advertiser_address_type,Address advertiser_address,uint8_t advertising_sid)950 ErrorCode LinkLayerController::LeAddDeviceToPeriodicAdvertiserList(
951 bluetooth::hci::AdvertiserAddressType advertiser_address_type, Address advertiser_address,
952 uint8_t advertising_sid) {
953 // If the Host issues this command when an HCI_LE_Periodic_Advertising_-
954 // Create_Sync command is pending, the Controller shall return the error code
955 // Command Disallowed (0x0C).
956 if (synchronizing_.has_value()) {
957 INFO(id_, "LE Periodic Advertising Create Sync command is currently pending");
958 return ErrorCode::COMMAND_DISALLOWED;
959 }
960
961 // When a Controller cannot add an entry to the Periodic Advertiser list
962 // because the list is full, the Controller shall return the error code Memory
963 // Capacity Exceeded (0x07).
964 if (le_periodic_advertiser_list_.size() >= properties_.le_periodic_advertiser_list_size) {
965 INFO(id_, "periodic advertiser list is full");
966 return ErrorCode::MEMORY_CAPACITY_EXCEEDED;
967 }
968
969 // If the entry is already on the list, the Controller shall
970 // return the error code Invalid HCI Command Parameters (0x12).
971 for (auto& entry : le_periodic_advertiser_list_) {
972 if (entry.advertiser_address_type == advertiser_address_type &&
973 entry.advertiser_address == advertiser_address &&
974 entry.advertising_sid == advertising_sid) {
975 INFO(id_, "entry is already found in the periodic advertiser list");
976 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
977 }
978 }
979
980 le_periodic_advertiser_list_.emplace_back(PeriodicAdvertiserListEntry{
981 advertiser_address_type, advertiser_address, advertising_sid});
982 return ErrorCode::SUCCESS;
983 }
984
985 // HCI LE Remove Device From Periodic Advertiser List command
986 // (Vol 4, Part E § 7.8.71).
LeRemoveDeviceFromPeriodicAdvertiserList(bluetooth::hci::AdvertiserAddressType advertiser_address_type,Address advertiser_address,uint8_t advertising_sid)987 ErrorCode LinkLayerController::LeRemoveDeviceFromPeriodicAdvertiserList(
988 bluetooth::hci::AdvertiserAddressType advertiser_address_type, Address advertiser_address,
989 uint8_t advertising_sid) {
990 // If this command is used when an HCI_LE_Periodic_Advertising_Create_Sync
991 // command is pending, the Controller shall return the error code Command
992 // Disallowed (0x0C).
993 if (synchronizing_.has_value()) {
994 INFO(id_, "LE Periodic Advertising Create Sync command is currently pending");
995 return ErrorCode::COMMAND_DISALLOWED;
996 }
997
998 for (auto it = le_periodic_advertiser_list_.begin(); it != le_periodic_advertiser_list_.end();
999 it++) {
1000 if (it->advertiser_address_type == advertiser_address_type &&
1001 it->advertiser_address == advertiser_address && it->advertising_sid == advertising_sid) {
1002 le_periodic_advertiser_list_.erase(it);
1003 return ErrorCode::SUCCESS;
1004 }
1005 }
1006
1007 // When a Controller cannot remove an entry from the Periodic Advertiser list
1008 // because it is not found, the Controller shall return the error code Unknown
1009 // Advertising Identifier (0x42).
1010 INFO(id_, "entry not found in the periodic advertiser list");
1011 return ErrorCode::UNKNOWN_ADVERTISING_IDENTIFIER;
1012 }
1013
1014 // HCI LE Clear Periodic Advertiser List command (Vol 4, Part E § 7.8.72).
LeClearPeriodicAdvertiserList()1015 ErrorCode LinkLayerController::LeClearPeriodicAdvertiserList() {
1016 // If this command is used when an HCI_LE_Periodic_Advertising_Create_Sync
1017 // command is pending, the Controller shall return the error code Command
1018 // Disallowed (0x0C).
1019 if (synchronizing_.has_value()) {
1020 INFO(id_, "LE Periodic Advertising Create Sync command is currently pending");
1021 return ErrorCode::COMMAND_DISALLOWED;
1022 }
1023
1024 le_periodic_advertiser_list_.clear();
1025 return ErrorCode::SUCCESS;
1026 }
1027
1028 // =============================================================================
1029 // LE Periodic Sync
1030 // =============================================================================
1031
1032 // HCI LE Periodic Advertising Create Sync command (Vol 4, Part E § 7.8.67).
LePeriodicAdvertisingCreateSync(bluetooth::hci::PeriodicAdvertisingOptions options,uint8_t advertising_sid,bluetooth::hci::AdvertiserAddressType advertiser_address_type,Address advertiser_address,uint16_t,uint16_t sync_timeout,uint8_t sync_cte_type)1033 ErrorCode LinkLayerController::LePeriodicAdvertisingCreateSync(
1034 bluetooth::hci::PeriodicAdvertisingOptions options, uint8_t advertising_sid,
1035 bluetooth::hci::AdvertiserAddressType advertiser_address_type, Address advertiser_address,
1036 uint16_t /*skip*/, uint16_t sync_timeout, uint8_t sync_cte_type) {
1037 // If the Host issues this command when another HCI_LE_Periodic_Advertising_-
1038 // Create_Sync command is pending, the Controller shall return the error code
1039 // Command Disallowed (0x0C).
1040 if (synchronizing_.has_value()) {
1041 INFO(id_, "LE Periodic Advertising Create Sync command is currently pending");
1042 return ErrorCode::COMMAND_DISALLOWED;
1043 }
1044
1045 // If the Host sets all the non-reserved bits of the Sync_CTE_Type parameter
1046 // to 1, the Controller shall return the error code Command Disallowed (0x0C).
1047 uint8_t sync_cte_type_mask = 0x1f;
1048 if ((sync_cte_type & sync_cte_type_mask) == sync_cte_type_mask) {
1049 INFO(id_, "Sync_CTE_Type is configured to ignore all types of advertisement");
1050 return ErrorCode::COMMAND_DISALLOWED;
1051 }
1052
1053 // If the Host issues this command with bit 0 of Options not set and with
1054 // Advertising_SID, Advertiser_Address_Type, and Advertiser_Address the same
1055 // as those of a periodic advertising train that the Controller is already
1056 // synchronized to, the Controller shall return the error code
1057 // Connection Already Exists (0x0B).
1058 bool has_synchronized_train = false;
1059 for (auto& [_, sync] : synchronized_) {
1060 has_synchronized_train |= sync.advertiser_address_type == advertiser_address_type &&
1061 sync.advertiser_address == advertiser_address &&
1062 sync.advertising_sid == advertising_sid;
1063 }
1064 if (!options.use_periodic_advertiser_list_ && has_synchronized_train) {
1065 INFO(id_,
1066 "the controller is already synchronized on the periodic advertising"
1067 " train from {}[{}] - SID=0x{:x}",
1068 advertiser_address, bluetooth::hci::AdvertiserAddressTypeText(advertiser_address_type),
1069 advertising_sid);
1070 return ErrorCode::CONNECTION_ALREADY_EXISTS;
1071 }
1072
1073 // If the Host issues this command and the Controller has insufficient
1074 // resources to handle any more periodic advertising trains, the Controller
1075 // shall return the error code Memory Capacity Exceeded (0x07)
1076 // TODO emulate LE state limits.
1077
1078 // If bit 1 of Options is set to 0, bit 2 is set to 1, and the Controller does
1079 // not support the Periodic Advertising ADI Support feature, then the
1080 // Controller shall return an error which should use the error code
1081 // Unsupported Feature or Parameter Value (0x11).
1082 if (!options.disable_reporting_ && options.enable_duplicate_filtering_ &&
1083 !properties_.SupportsLLFeature(LLFeaturesBits::PERIODIC_ADVERTISING_ADI_SUPPORT)) {
1084 INFO(id_,
1085 "reporting and duplicate filtering are enabled in the options,"
1086 " but the controller does not support the Periodic Advertising ADI"
1087 " Support feature");
1088 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1089 }
1090
1091 // If bit 1 of the Options parameter is set to 1 and the Controller does not
1092 // support the HCI_LE_Set_Periodic_Advertising_Receive_Enable command, the
1093 // Controller shall return the error code Connection Failed to be Established
1094 // / Synchronization Timeout (0x3E).
1095 if (options.disable_reporting_ &&
1096 !properties_.SupportsCommand(
1097 bluetooth::hci::OpCodeIndex::LE_SET_PERIODIC_ADVERTISING_RECEIVE_ENABLE)) {
1098 INFO(id_,
1099 "reporting is disabled in the options, but the controller does not"
1100 " support the HCI_LE_Set_Periodic_Advertising_Receive_Enable command");
1101 return ErrorCode::CONNECTION_FAILED_ESTABLISHMENT;
1102 }
1103
1104 synchronizing_ = Synchronizing{
1105 .options = options,
1106 .advertiser_address_type = advertiser_address_type,
1107 .advertiser_address = advertiser_address,
1108 .advertising_sid = advertising_sid,
1109 .sync_timeout = 10ms * sync_timeout,
1110 };
1111 return ErrorCode::SUCCESS;
1112 }
1113
1114 // HCI LE Periodic Advertising Create Sync Cancel command (Vol 4, Part E
1115 // § 7.8.68).
LePeriodicAdvertisingCreateSyncCancel()1116 ErrorCode LinkLayerController::LePeriodicAdvertisingCreateSyncCancel() {
1117 // If the Host issues this command while no HCI_LE_Periodic_Advertising_-
1118 // Create_Sync command is pending, the Controller shall return the error code
1119 // Command Disallowed (0x0C).
1120 if (!synchronizing_.has_value()) {
1121 INFO(id_, "no LE Periodic Advertising Create Sync command is pending");
1122 return ErrorCode::COMMAND_DISALLOWED;
1123 }
1124
1125 // After the HCI_Command_Complete is sent and if the cancellation was
1126 // successful, the Controller sends an HCI_LE_Periodic_Advertising_Sync_-
1127 // Established event to the Host with the error code Operation Cancelled
1128 // by Host (0x44).
1129 if (IsLeEventUnmasked(SubeventCode::LE_PERIODIC_ADVERTISING_SYNC_ESTABLISHED_V1)) {
1130 ScheduleTask(0ms, [this] {
1131 send_event_(bluetooth::hci::LePeriodicAdvertisingSyncEstablishedV1Builder::Create(
1132 ErrorCode::OPERATION_CANCELLED_BY_HOST, 0, 0, AddressType::PUBLIC_DEVICE_ADDRESS,
1133 Address::kEmpty, bluetooth::hci::SecondaryPhyType::NO_PACKETS, 0,
1134 bluetooth::hci::ClockAccuracy::PPM_500));
1135 });
1136 }
1137
1138 synchronizing_ = {};
1139 return ErrorCode::SUCCESS;
1140 }
1141
1142 // HCI LE Periodic Advertising Terminate Sync command (Vol 4, Part E
1143 // § 7.8.69).
LePeriodicAdvertisingTerminateSync(uint16_t sync_handle)1144 ErrorCode LinkLayerController::LePeriodicAdvertisingTerminateSync(uint16_t sync_handle) {
1145 // If the periodic advertising train corresponding to the Sync_Handle
1146 // parameter does not exist, then the Controller shall return the error
1147 // code Unknown Advertising Identifier (0x42).
1148 if (synchronized_.count(sync_handle) == 0) {
1149 INFO(id_, "the Sync_Handle 0x{:x} does not exist", sync_handle);
1150 return ErrorCode::UNKNOWN_ADVERTISING_IDENTIFIER;
1151 }
1152
1153 synchronized_.erase(sync_handle);
1154 return ErrorCode::SUCCESS;
1155 }
1156
1157 // =============================================================================
1158 // LE Legacy Scanning
1159 // =============================================================================
1160
1161 // HCI command LE_Set_Scan_Parameters (Vol 4, Part E § 7.8.10).
LeSetScanParameters(bluetooth::hci::LeScanType scan_type,uint16_t scan_interval,uint16_t scan_window,bluetooth::hci::OwnAddressType own_address_type,bluetooth::hci::LeScanningFilterPolicy scanning_filter_policy)1162 ErrorCode LinkLayerController::LeSetScanParameters(
1163 bluetooth::hci::LeScanType scan_type, uint16_t scan_interval, uint16_t scan_window,
1164 bluetooth::hci::OwnAddressType own_address_type,
1165 bluetooth::hci::LeScanningFilterPolicy scanning_filter_policy) {
1166 // Legacy advertising commands are disallowed when extended advertising
1167 // commands were used since the last reset.
1168 if (!SelectLegacyAdvertising()) {
1169 INFO(id_,
1170 "legacy advertising command rejected because extended advertising"
1171 " is being used");
1172 return ErrorCode::COMMAND_DISALLOWED;
1173 }
1174
1175 // The Host shall not issue this command when scanning is enabled in the
1176 // Controller; if it is the Command Disallowed error code shall be used.
1177 if (scanner_.IsEnabled()) {
1178 INFO(id_, "scanning is currently enabled");
1179 return ErrorCode::COMMAND_DISALLOWED;
1180 }
1181
1182 // Note: no explicit error code stated for invalid interval and window
1183 // values but assuming Unsupported Feature or Parameter Value (0x11)
1184 // error code based on similar advertising command.
1185 if (scan_interval < 0x4 || scan_interval > 0x4000 || scan_window < 0x4 || scan_window > 0x4000) {
1186 INFO(id_,
1187 "le_scan_interval (0x{:04x}) and/or"
1188 " le_scan_window (0x{:04x}) are outside the range"
1189 " of supported values (0x0004 - 0x4000)",
1190 scan_interval, scan_window);
1191 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1192 }
1193
1194 // The LE_Scan_Window parameter shall always be set to a value smaller
1195 // or equal to the value set for the LE_Scan_Interval parameter.
1196 if (scan_window > scan_interval) {
1197 INFO(id_, "le_scan_window (0x{:04x}) is larger than le_scan_interval (0x{:04x})", scan_window,
1198 scan_interval);
1199 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1200 }
1201
1202 scanner_.le_1m_phy.enabled = true;
1203 scanner_.le_coded_phy.enabled = false;
1204 scanner_.le_1m_phy.scan_type = scan_type;
1205 scanner_.le_1m_phy.scan_interval = scan_interval;
1206 scanner_.le_1m_phy.scan_window = scan_window;
1207 scanner_.own_address_type = own_address_type;
1208 scanner_.scan_filter_policy = scanning_filter_policy;
1209 return ErrorCode::SUCCESS;
1210 }
1211
1212 // HCI command LE_Set_Scan_Enable (Vol 4, Part E § 7.8.11).
LeSetScanEnable(bool enable,bool filter_duplicates)1213 ErrorCode LinkLayerController::LeSetScanEnable(bool enable, bool filter_duplicates) {
1214 // Legacy advertising commands are disallowed when extended advertising
1215 // commands were used since the last reset.
1216 if (!SelectLegacyAdvertising()) {
1217 INFO(id_,
1218 "legacy advertising command rejected because extended advertising"
1219 " is being used");
1220 return ErrorCode::COMMAND_DISALLOWED;
1221 }
1222
1223 if (!enable) {
1224 scanner_.scan_enable = false;
1225 scanner_.pending_scan_request = {};
1226 scanner_.pending_scan_request_timeout = {};
1227 scanner_.history.clear();
1228 return ErrorCode::SUCCESS;
1229 }
1230
1231 // TODO: additional checks would apply in the case of a LE only Controller
1232 // with no configured public device address.
1233
1234 // If LE_Scan_Enable is set to 0x01, the scanning parameters' Own_Address_Type
1235 // parameter is set to 0x01 or 0x03, and the random address for the device
1236 // has not been initialized using the HCI_LE_Set_Random_Address command,
1237 // the Controller shall return the error code
1238 // Invalid HCI Command Parameters (0x12).
1239 if ((scanner_.own_address_type == bluetooth::hci::OwnAddressType::RANDOM_DEVICE_ADDRESS ||
1240 scanner_.own_address_type == bluetooth::hci::OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS) &&
1241 random_address_ == Address::kEmpty) {
1242 INFO(id_,
1243 "own_address_type is Random_Device_Address or"
1244 " Resolvable_or_Random_Address but the Random_Address"
1245 " has not been initialized");
1246 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1247 }
1248
1249 scanner_.scan_enable = true;
1250 scanner_.history.clear();
1251 scanner_.timeout = {};
1252 scanner_.periodical_timeout = {};
1253 scanner_.pending_scan_request = {};
1254 scanner_.pending_scan_request_timeout = {};
1255 scanner_.filter_duplicates = filter_duplicates ? bluetooth::hci::FilterDuplicates::ENABLED
1256 : bluetooth::hci::FilterDuplicates::DISABLED;
1257 return ErrorCode::SUCCESS;
1258 }
1259
1260 // =============================================================================
1261 // LE Extended Scanning
1262 // =============================================================================
1263
1264 // HCI command LE_Set_Extended_Scan_Parameters (Vol 4, Part E § 7.8.64).
LeSetExtendedScanParameters(bluetooth::hci::OwnAddressType own_address_type,bluetooth::hci::LeScanningFilterPolicy scanning_filter_policy,uint8_t scanning_phys,std::vector<bluetooth::hci::ScanningPhyParameters> scanning_phy_parameters)1265 ErrorCode LinkLayerController::LeSetExtendedScanParameters(
1266 bluetooth::hci::OwnAddressType own_address_type,
1267 bluetooth::hci::LeScanningFilterPolicy scanning_filter_policy, uint8_t scanning_phys,
1268 std::vector<bluetooth::hci::ScanningPhyParameters> scanning_phy_parameters) {
1269 uint8_t supported_phys = properties_.LeSupportedPhys();
1270
1271 // Extended advertising commands are disallowed when legacy advertising
1272 // commands were used since the last reset.
1273 if (!SelectExtendedAdvertising()) {
1274 INFO(id_,
1275 "extended advertising command rejected because legacy advertising"
1276 " is being used");
1277 return ErrorCode::COMMAND_DISALLOWED;
1278 }
1279
1280 // If the Host issues this command when scanning is enabled in the Controller,
1281 // the Controller shall return the error code Command Disallowed (0x0C).
1282 if (scanner_.IsEnabled()) {
1283 INFO(id_, "scanning is currently enabled");
1284 return ErrorCode::COMMAND_DISALLOWED;
1285 }
1286
1287 // If the Host specifies a PHY that is not supported by the Controller,
1288 // including a bit that is reserved for future use, it should return the
1289 // error code Unsupported Feature or Parameter Value (0x11).
1290 if ((scanning_phys & ~supported_phys) != 0) {
1291 INFO(id_,
1292 "scanning_phys ({:02x}) enables PHYs that are not supported by"
1293 " the controller",
1294 scanning_phys);
1295 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1296 }
1297
1298 // TODO(c++20) std::popcount
1299 if (__builtin_popcount(scanning_phys) != int(scanning_phy_parameters.size())) {
1300 INFO(id_,
1301 "scanning_phy_parameters ({})"
1302 " does not match scanning_phys ({:02x})",
1303 scanning_phy_parameters.size(), scanning_phys);
1304 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1305 }
1306
1307 // Note: no explicit error code stated for empty scanning_phys
1308 // but assuming Unsupported Feature or Parameter Value (0x11)
1309 // error code based on HCI Extended LE Create Connecton command.
1310 if (scanning_phys == 0) {
1311 INFO(id_, "scanning_phys is empty");
1312 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1313 }
1314
1315 for (auto const& parameter : scanning_phy_parameters) {
1316 // If the requested scan cannot be supported by the implementation,
1317 // the Controller shall return the error code
1318 // Invalid HCI Command Parameters (0x12).
1319 if (parameter.le_scan_interval_ < 0x4 || parameter.le_scan_window_ < 0x4) {
1320 INFO(id_,
1321 "le_scan_interval (0x{:04x}) and/or"
1322 " le_scan_window (0x{:04x}) are outside the range"
1323 " of supported values (0x0004 - 0xffff)",
1324 parameter.le_scan_interval_, parameter.le_scan_window_);
1325 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1326 }
1327
1328 if (parameter.le_scan_window_ > parameter.le_scan_interval_) {
1329 INFO(id_,
1330 "le_scan_window (0x{:04x}) is larger than le_scan_interval "
1331 "(0x{:04x})",
1332 parameter.le_scan_window_, parameter.le_scan_interval_);
1333 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1334 }
1335 }
1336
1337 scanner_.own_address_type = own_address_type;
1338 scanner_.scan_filter_policy = scanning_filter_policy;
1339 scanner_.le_1m_phy.enabled = false;
1340 scanner_.le_coded_phy.enabled = false;
1341 int offset = 0;
1342
1343 if (scanning_phys & 0x1) {
1344 scanner_.le_1m_phy = Scanner::PhyParameters{
1345 .enabled = true,
1346 .scan_type = scanning_phy_parameters[offset].le_scan_type_,
1347 .scan_interval = scanning_phy_parameters[offset].le_scan_interval_,
1348 .scan_window = scanning_phy_parameters[offset].le_scan_window_,
1349 };
1350 offset++;
1351 }
1352
1353 if (scanning_phys & 0x4) {
1354 scanner_.le_coded_phy = Scanner::PhyParameters{
1355 .enabled = true,
1356 .scan_type = scanning_phy_parameters[offset].le_scan_type_,
1357 .scan_interval = scanning_phy_parameters[offset].le_scan_interval_,
1358 .scan_window = scanning_phy_parameters[offset].le_scan_window_,
1359 };
1360 offset++;
1361 }
1362
1363 return ErrorCode::SUCCESS;
1364 }
1365
1366 // HCI command LE_Set_Extended_Scan_Enable (Vol 4, Part E § 7.8.65).
LeSetExtendedScanEnable(bool enable,bluetooth::hci::FilterDuplicates filter_duplicates,uint16_t duration,uint16_t period)1367 ErrorCode LinkLayerController::LeSetExtendedScanEnable(
1368 bool enable, bluetooth::hci::FilterDuplicates filter_duplicates, uint16_t duration,
1369 uint16_t period) {
1370 // Extended advertising commands are disallowed when legacy advertising
1371 // commands were used since the last reset.
1372 if (!SelectExtendedAdvertising()) {
1373 INFO(id_,
1374 "extended advertising command rejected because legacy advertising"
1375 " is being used");
1376 return ErrorCode::COMMAND_DISALLOWED;
1377 }
1378
1379 if (!enable) {
1380 scanner_.scan_enable = false;
1381 scanner_.pending_scan_request = {};
1382 scanner_.pending_scan_request_timeout = {};
1383 scanner_.history.clear();
1384 return ErrorCode::SUCCESS;
1385 }
1386
1387 // The Period parameter shall be ignored when the Duration parameter is zero.
1388 if (duration == 0) {
1389 period = 0;
1390 }
1391
1392 // If Filter_Duplicates is set to 0x02 and either Period or Duration to zero,
1393 // the Controller shall return the error code
1394 // Invalid HCI Command Parameters (0x12).
1395 if (filter_duplicates == bluetooth::hci::FilterDuplicates::RESET_EACH_PERIOD &&
1396 (period == 0 || duration == 0)) {
1397 INFO(id_,
1398 "filter_duplicates is Reset_Each_Period but either"
1399 " the period or duration is 0");
1400 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1401 }
1402
1403 auto duration_ms = std::chrono::milliseconds(10 * duration);
1404 auto period_ms = std::chrono::milliseconds(1280 * period);
1405
1406 // If both the Duration and Period parameters are non-zero and the Duration is
1407 // greater than or equal to the Period, the Controller shall return the
1408 // error code Invalid HCI Command Parameters (0x12).
1409 if (period != 0 && duration != 0 && duration_ms >= period_ms) {
1410 INFO(id_, "the period is greater than or equal to the duration");
1411 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1412 }
1413
1414 // TODO: additional checks would apply in the case of a LE only Controller
1415 // with no configured public device address.
1416
1417 // If LE_Scan_Enable is set to 0x01, the scanning parameters' Own_Address_Type
1418 // parameter is set to 0x01 or 0x03, and the random address for the device
1419 // has not been initialized using the HCI_LE_Set_Random_Address command,
1420 // the Controller shall return the error code
1421 // Invalid HCI Command Parameters (0x12).
1422 if ((scanner_.own_address_type == bluetooth::hci::OwnAddressType::RANDOM_DEVICE_ADDRESS ||
1423 scanner_.own_address_type == bluetooth::hci::OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS) &&
1424 random_address_ == Address::kEmpty) {
1425 INFO(id_,
1426 "own_address_type is Random_Device_Address or"
1427 " Resolvable_or_Random_Address but the Random_Address"
1428 " has not been initialized");
1429 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1430 }
1431
1432 scanner_.scan_enable = true;
1433 scanner_.history.clear();
1434 scanner_.timeout = {};
1435 scanner_.periodical_timeout = {};
1436 scanner_.pending_scan_request = {};
1437 scanner_.pending_scan_request_timeout = {};
1438 scanner_.filter_duplicates = filter_duplicates;
1439 scanner_.duration = duration_ms;
1440 scanner_.period = period_ms;
1441
1442 auto now = std::chrono::steady_clock::now();
1443
1444 // At the end of a single scan (Duration non-zero but Period zero), an
1445 // HCI_LE_Scan_Timeout event shall be generated.
1446 if (duration != 0) {
1447 scanner_.timeout = now + scanner_.duration;
1448 }
1449 if (period != 0) {
1450 scanner_.periodical_timeout = now + scanner_.period;
1451 }
1452
1453 return ErrorCode::SUCCESS;
1454 }
1455
1456 // =============================================================================
1457 // LE Legacy Connection
1458 // =============================================================================
1459
1460 // HCI LE Create Connection command (Vol 4, Part E § 7.8.12).
LeCreateConnection(uint16_t scan_interval,uint16_t scan_window,bluetooth::hci::InitiatorFilterPolicy initiator_filter_policy,AddressWithType peer_address,bluetooth::hci::OwnAddressType own_address_type,uint16_t connection_interval_min,uint16_t connection_interval_max,uint16_t max_latency,uint16_t supervision_timeout,uint16_t min_ce_length,uint16_t max_ce_length)1461 ErrorCode LinkLayerController::LeCreateConnection(
1462 uint16_t scan_interval, uint16_t scan_window,
1463 bluetooth::hci::InitiatorFilterPolicy initiator_filter_policy, AddressWithType peer_address,
1464 bluetooth::hci::OwnAddressType own_address_type, uint16_t connection_interval_min,
1465 uint16_t connection_interval_max, uint16_t max_latency, uint16_t supervision_timeout,
1466 uint16_t min_ce_length, uint16_t max_ce_length) {
1467 // Legacy advertising commands are disallowed when extended advertising
1468 // commands were used since the last reset.
1469 if (!SelectLegacyAdvertising()) {
1470 INFO(id_,
1471 "legacy advertising command rejected because extended advertising"
1472 " is being used");
1473 return ErrorCode::COMMAND_DISALLOWED;
1474 }
1475
1476 // If the Host issues this command when another HCI_LE_Create_Connection
1477 // command is pending in the Controller, the Controller shall return the
1478 // error code Command Disallowed (0x0C).
1479 if (initiator_.IsEnabled()) {
1480 INFO(id_, "initiator is currently enabled");
1481 return ErrorCode::COMMAND_DISALLOWED;
1482 }
1483
1484 // Note: no explicit error code stated for invalid interval and window
1485 // values but assuming Unsupported Feature or Parameter Value (0x11)
1486 // error code based on similar advertising command.
1487 if (scan_interval < 0x4 || scan_interval > 0x4000 || scan_window < 0x4 || scan_window > 0x4000) {
1488 INFO(id_,
1489 "scan_interval (0x{:04x}) and/or "
1490 "scan_window (0x{:04x}) are outside the range"
1491 " of supported values (0x4 - 0x4000)",
1492 scan_interval, scan_window);
1493 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1494 }
1495
1496 // The LE_Scan_Window parameter shall be set to a value smaller or equal to
1497 // the value set for the LE_Scan_Interval parameter.
1498 if (scan_interval < scan_window) {
1499 INFO(id_, "scan_window (0x{:04x}) is larger than scan_interval (0x{:04x})", scan_window,
1500 scan_interval);
1501 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1502 }
1503
1504 // Note: no explicit error code stated for invalid connection interval
1505 // values but assuming Unsupported Feature or Parameter Value (0x11)
1506 // error code based on similar advertising command.
1507 if (connection_interval_min < 0x6 || connection_interval_min > 0x0c80 ||
1508 connection_interval_max < 0x6 || connection_interval_max > 0x0c80) {
1509 INFO(id_,
1510 "connection_interval_min (0x{:04x}) and/or "
1511 "connection_interval_max (0x{:04x}) are outside the range"
1512 " of supported values (0x6 - 0x0c80)",
1513 connection_interval_min, connection_interval_max);
1514 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1515 }
1516
1517 // The Connection_Interval_Min parameter shall not be greater than the
1518 // Connection_Interval_Max parameter.
1519 if (connection_interval_max < connection_interval_min) {
1520 INFO(id_,
1521 "connection_interval_min (0x{:04x}) is larger than"
1522 " connection_interval_max (0x{:04x})",
1523 connection_interval_min, connection_interval_max);
1524 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1525 }
1526
1527 // Note: no explicit error code stated for invalid max_latency
1528 // values but assuming Unsupported Feature or Parameter Value (0x11)
1529 // error code based on similar advertising command.
1530 if (max_latency > 0x01f3) {
1531 INFO(id_,
1532 "max_latency (0x{:04x}) is outside the range"
1533 " of supported values (0x0 - 0x01f3)",
1534 max_latency);
1535 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1536 }
1537
1538 // Note: no explicit error code stated for invalid supervision timeout
1539 // values but assuming Unsupported Feature or Parameter Value (0x11)
1540 // error code based on similar advertising command.
1541 if (supervision_timeout < 0xa || supervision_timeout > 0x0c80) {
1542 INFO(id_,
1543 "supervision_timeout (0x{:04x}) is outside the range"
1544 " of supported values (0xa - 0x0c80)",
1545 supervision_timeout);
1546 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1547 }
1548
1549 // The Supervision_Timeout in milliseconds shall be larger than
1550 // (1 + Max_Latency) * Connection_Interval_Max * 2, where
1551 // Connection_Interval_Max is given in milliseconds.
1552 milliseconds min_supervision_timeout =
1553 duration_cast<milliseconds>((1 + max_latency) * slots(2 * connection_interval_max) * 2);
1554 if (supervision_timeout * 10ms < min_supervision_timeout) {
1555 INFO(id_,
1556 "supervision_timeout ({} ms) is smaller that the minimal supervision "
1557 "timeout allowed by connection_interval_max and max_latency ({} ms)",
1558 supervision_timeout * 10, static_cast<unsigned>(min_supervision_timeout / 1ms));
1559 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1560 }
1561
1562 // TODO: additional checks would apply in the case of a LE only Controller
1563 // with no configured public device address.
1564
1565 // If the Own_Address_Type parameter is set to 0x01 and the random
1566 // address for the device has not been initialized using the
1567 // HCI_LE_Set_Random_Address command, the Controller shall return the
1568 // error code Invalid HCI Command Parameters (0x12).
1569 if (own_address_type == OwnAddressType::RANDOM_DEVICE_ADDRESS &&
1570 random_address_ == Address::kEmpty) {
1571 INFO(id_,
1572 "own_address_type is Random_Device_Address but the Random_Address"
1573 " has not been initialized");
1574 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1575 }
1576
1577 // If the Own_Address_Type parameter is set to 0x03, the
1578 // Initiator_Filter_Policy parameter is set to 0x00, the controller's
1579 // resolving list did not contain matching entry, and the random address for
1580 // the device has not been initialized using the HCI_LE_Set_Random_Address
1581 // command, the Controller shall return the error code
1582 // Invalid HCI Command Parameters (0x12).
1583 if (own_address_type == OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS &&
1584 initiator_filter_policy == InitiatorFilterPolicy::USE_PEER_ADDRESS &&
1585 !GenerateResolvablePrivateAddress(peer_address, IrkSelection::Local) &&
1586 random_address_ == Address::kEmpty) {
1587 INFO(id_,
1588 "own_address_type is Resolvable_Or_Random_Address but the"
1589 " Resolving_List does not contain a matching entry and the"
1590 " Random_Address is not initialized");
1591 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1592 }
1593
1594 initiator_.connect_enable = true;
1595 initiator_.initiator_filter_policy = initiator_filter_policy;
1596 initiator_.peer_address = peer_address;
1597 initiator_.own_address_type = own_address_type;
1598 initiator_.le_1m_phy.enabled = true;
1599 initiator_.le_1m_phy.scan_interval = scan_interval;
1600 initiator_.le_1m_phy.scan_window = scan_window;
1601 initiator_.le_1m_phy.connection_interval_min = connection_interval_min;
1602 initiator_.le_1m_phy.connection_interval_max = connection_interval_max;
1603 initiator_.le_1m_phy.max_latency = max_latency;
1604 initiator_.le_1m_phy.supervision_timeout = supervision_timeout;
1605 initiator_.le_1m_phy.min_ce_length = min_ce_length;
1606 initiator_.le_1m_phy.max_ce_length = max_ce_length;
1607 initiator_.le_2m_phy.enabled = false;
1608 initiator_.le_coded_phy.enabled = false;
1609 initiator_.pending_connect_request = {};
1610 return ErrorCode::SUCCESS;
1611 }
1612
1613 // HCI LE Create Connection Cancel command (Vol 4, Part E § 7.8.12).
LeCreateConnectionCancel()1614 ErrorCode LinkLayerController::LeCreateConnectionCancel() {
1615 // If no HCI_LE_Create_Connection or HCI_LE_Extended_Create_Connection
1616 // command is pending, then the Controller shall return the error code
1617 // Command Disallowed (0x0C).
1618 if (!initiator_.IsEnabled()) {
1619 INFO(id_, "initiator is currently disabled");
1620 return ErrorCode::COMMAND_DISALLOWED;
1621 }
1622
1623 // If the cancellation was successful then, after the HCI_Command_Complete
1624 // event for the HCI_LE_Create_Connection_Cancel command, either an LE
1625 // Connection Complete or an HCI_LE_Enhanced_Connection_Complete event
1626 // shall be generated. In either case, the event shall be sent with the error
1627 // code Unknown Connection Identifier (0x02).
1628 if (IsLeEventUnmasked(SubeventCode::LE_ENHANCED_CONNECTION_COMPLETE_V1)) {
1629 ScheduleTask(0ms, [this] {
1630 send_event_(bluetooth::hci::LeEnhancedConnectionCompleteV1Builder::Create(
1631 ErrorCode::UNKNOWN_CONNECTION, 0, Role::CENTRAL, AddressType::PUBLIC_DEVICE_ADDRESS,
1632 Address(), Address(), Address(), 0, 0, 0, bluetooth::hci::ClockAccuracy::PPM_500));
1633 });
1634 } else if (IsLeEventUnmasked(SubeventCode::LE_CONNECTION_COMPLETE)) {
1635 ScheduleTask(0ms, [this] {
1636 send_event_(bluetooth::hci::LeConnectionCompleteBuilder::Create(
1637 ErrorCode::UNKNOWN_CONNECTION, 0, Role::CENTRAL, AddressType::PUBLIC_DEVICE_ADDRESS,
1638 Address(), 0, 0, 0, bluetooth::hci::ClockAccuracy::PPM_500));
1639 });
1640 }
1641
1642 initiator_.Disable();
1643 return ErrorCode::SUCCESS;
1644 }
1645
1646 // =============================================================================
1647 // LE Extended Connection
1648 // =============================================================================
1649
1650 // HCI LE Extended Create Connection command (Vol 4, Part E § 7.8.66).
LeExtendedCreateConnection(bluetooth::hci::InitiatorFilterPolicy initiator_filter_policy,bluetooth::hci::OwnAddressType own_address_type,AddressWithType peer_address,uint8_t initiating_phys,std::vector<bluetooth::hci::InitiatingPhyParameters> initiating_phy_parameters)1651 ErrorCode LinkLayerController::LeExtendedCreateConnection(
1652 bluetooth::hci::InitiatorFilterPolicy initiator_filter_policy,
1653 bluetooth::hci::OwnAddressType own_address_type, AddressWithType peer_address,
1654 uint8_t initiating_phys,
1655 std::vector<bluetooth::hci::InitiatingPhyParameters> initiating_phy_parameters) {
1656 // Extended advertising commands are disallowed when legacy advertising
1657 // commands were used since the last reset.
1658 if (!SelectExtendedAdvertising()) {
1659 INFO(id_,
1660 "extended advertising command rejected because legacy advertising"
1661 " is being used");
1662 return ErrorCode::COMMAND_DISALLOWED;
1663 }
1664
1665 // If the Host issues this command when another
1666 // HCI_LE_Extended_Create_Connection command is pending in the Controller,
1667 // the Controller shall return the error code Command Disallowed (0x0C).
1668 if (initiator_.IsEnabled()) {
1669 INFO(id_, "initiator is currently enabled");
1670 return ErrorCode::COMMAND_DISALLOWED;
1671 }
1672
1673 // If the Host specifies a PHY that is not supported by the Controller,
1674 // including a bit that is reserved for future use, the latter should return
1675 // the error code Unsupported Feature or Parameter Value (0x11).
1676 if ((initiating_phys & 0xf8) != 0) {
1677 INFO(id_,
1678 "initiating_phys ({:02x}) enables PHYs that are not supported by"
1679 " the controller",
1680 initiating_phys);
1681 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1682 }
1683
1684 // TODO(c++20) std::popcount
1685 if (__builtin_popcount(initiating_phys) != int(initiating_phy_parameters.size())) {
1686 INFO(id_,
1687 "initiating_phy_parameters ({})"
1688 " does not match initiating_phys ({:02x})",
1689 initiating_phy_parameters.size(), initiating_phys);
1690 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1691 }
1692
1693 // If the Initiating_PHYs parameter does not have at least one bit set for a
1694 // PHY allowed for scanning on the primary advertising physical channel, the
1695 // Controller shall return the error code
1696 // Invalid HCI Command Parameters (0x12).
1697 if (initiating_phys == 0) {
1698 INFO(id_, "initiating_phys is empty");
1699 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1700 }
1701
1702 for (auto const& parameter : initiating_phy_parameters) {
1703 // Note: no explicit error code stated for invalid interval and window
1704 // values but assuming Unsupported Feature or Parameter Value (0x11)
1705 // error code based on similar advertising command.
1706 if (parameter.scan_interval_ < 0x4 || parameter.scan_interval_ > 0x4000 ||
1707 parameter.scan_window_ < 0x4 || parameter.scan_window_ > 0x4000) {
1708 INFO(id_,
1709 "scan_interval (0x{:04x}) and/or "
1710 "scan_window (0x{:04x}) are outside the range"
1711 " of supported values (0x4 - 0x4000)",
1712 parameter.scan_interval_, parameter.scan_window_);
1713 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1714 }
1715
1716 // The LE_Scan_Window parameter shall be set to a value smaller or equal to
1717 // the value set for the LE_Scan_Interval parameter.
1718 if (parameter.scan_interval_ < parameter.scan_window_) {
1719 INFO(id_, "scan_window (0x{:04x}) is larger than scan_interval (0x{:04x})",
1720 parameter.scan_window_, parameter.scan_interval_);
1721 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1722 }
1723
1724 // Note: no explicit error code stated for invalid connection interval
1725 // values but assuming Unsupported Feature or Parameter Value (0x11)
1726 // error code based on similar advertising command.
1727 if (parameter.connection_interval_min_ < 0x6 || parameter.connection_interval_min_ > 0x0c80 ||
1728 parameter.connection_interval_max_ < 0x6 || parameter.connection_interval_max_ > 0x0c80) {
1729 INFO(id_,
1730 "connection_interval_min (0x{:04x}) and/or "
1731 "connection_interval_max (0x{:04x}) are outside the range"
1732 " of supported values (0x6 - 0x0c80)",
1733 parameter.connection_interval_min_, parameter.connection_interval_max_);
1734 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1735 }
1736
1737 // The Connection_Interval_Min parameter shall not be greater than the
1738 // Connection_Interval_Max parameter.
1739 if (parameter.connection_interval_max_ < parameter.connection_interval_min_) {
1740 INFO(id_,
1741 "connection_interval_min (0x{:04x}) is larger than"
1742 " connection_interval_max (0x{:04x})",
1743 parameter.connection_interval_min_, parameter.connection_interval_max_);
1744 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1745 }
1746
1747 // Note: no explicit error code stated for invalid max_latency
1748 // values but assuming Unsupported Feature or Parameter Value (0x11)
1749 // error code based on similar advertising command.
1750 if (parameter.max_latency_ > 0x01f3) {
1751 INFO(id_,
1752 "max_latency (0x{:04x}) is outside the range"
1753 " of supported values (0x0 - 0x01f3)",
1754 parameter.max_latency_);
1755 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1756 }
1757
1758 // Note: no explicit error code stated for invalid supervision timeout
1759 // values but assuming Unsupported Feature or Parameter Value (0x11)
1760 // error code based on similar advertising command.
1761 if (parameter.supervision_timeout_ < 0xa || parameter.supervision_timeout_ > 0x0c80) {
1762 INFO(id_,
1763 "supervision_timeout (0x{:04x}) is outside the range"
1764 " of supported values (0xa - 0x0c80)",
1765 parameter.supervision_timeout_);
1766 return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
1767 }
1768
1769 // The Supervision_Timeout in milliseconds shall be larger than
1770 // (1 + Max_Latency) * Connection_Interval_Max * 2, where
1771 // Connection_Interval_Max is given in milliseconds.
1772 milliseconds min_supervision_timeout = duration_cast<milliseconds>(
1773 (1 + parameter.max_latency_) * slots(2 * parameter.connection_interval_max_) * 2);
1774 if (parameter.supervision_timeout_ * 10ms < min_supervision_timeout) {
1775 INFO(id_,
1776 "supervision_timeout ({} ms) is smaller that the minimal supervision "
1777 "timeout allowed by connection_interval_max and max_latency ({} ms)",
1778 parameter.supervision_timeout_ * 10,
1779 static_cast<unsigned>(min_supervision_timeout / 1ms));
1780 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1781 }
1782 }
1783
1784 // TODO: additional checks would apply in the case of a LE only Controller
1785 // with no configured public device address.
1786
1787 // If the Own_Address_Type parameter is set to 0x01 and the random
1788 // address for the device has not been initialized using the
1789 // HCI_LE_Set_Random_Address command, the Controller shall return the
1790 // error code Invalid HCI Command Parameters (0x12).
1791 if (own_address_type == OwnAddressType::RANDOM_DEVICE_ADDRESS &&
1792 random_address_ == Address::kEmpty) {
1793 INFO(id_,
1794 "own_address_type is Random_Device_Address but the Random_Address"
1795 " has not been initialized");
1796 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1797 }
1798
1799 // If the Own_Address_Type parameter is set to 0x03, the
1800 // Initiator_Filter_Policy parameter is set to 0x00, the controller's
1801 // resolving list did not contain matching entry, and the random address for
1802 // the device has not been initialized using the HCI_LE_Set_Random_Address
1803 // command, the Controller shall return the error code
1804 // Invalid HCI Command Parameters (0x12).
1805 if (own_address_type == OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS &&
1806 initiator_filter_policy == InitiatorFilterPolicy::USE_PEER_ADDRESS &&
1807 !GenerateResolvablePrivateAddress(peer_address, IrkSelection::Local) &&
1808 random_address_ == Address::kEmpty) {
1809 INFO(id_,
1810 "own_address_type is Resolvable_Or_Random_Address but the"
1811 " Resolving_List does not contain a matching entry and the"
1812 " Random_Address is not initialized");
1813 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
1814 }
1815
1816 initiator_.connect_enable = true;
1817 initiator_.initiator_filter_policy = initiator_filter_policy;
1818 initiator_.peer_address = peer_address;
1819 initiator_.own_address_type = own_address_type;
1820 initiator_.pending_connect_request = {};
1821
1822 initiator_.le_1m_phy.enabled = false;
1823 initiator_.le_2m_phy.enabled = false;
1824 initiator_.le_coded_phy.enabled = false;
1825 int offset = 0;
1826
1827 if (initiating_phys & 0x1) {
1828 initiator_.le_1m_phy = Initiator::PhyParameters{
1829 .enabled = true,
1830 .scan_interval = initiating_phy_parameters[offset].scan_interval_,
1831 .scan_window = initiating_phy_parameters[offset].scan_window_,
1832 .connection_interval_min = initiating_phy_parameters[offset].connection_interval_min_,
1833 .connection_interval_max = initiating_phy_parameters[offset].connection_interval_max_,
1834 .max_latency = initiating_phy_parameters[offset].max_latency_,
1835 .supervision_timeout = initiating_phy_parameters[offset].supervision_timeout_,
1836 .min_ce_length = initiating_phy_parameters[offset].min_ce_length_,
1837 .max_ce_length = initiating_phy_parameters[offset].max_ce_length_,
1838 };
1839 offset++;
1840 }
1841
1842 if (initiating_phys & 0x2) {
1843 initiator_.le_2m_phy = Initiator::PhyParameters{
1844 .enabled = true,
1845 .scan_interval = initiating_phy_parameters[offset].scan_interval_,
1846 .scan_window = initiating_phy_parameters[offset].scan_window_,
1847 .connection_interval_min = initiating_phy_parameters[offset].connection_interval_min_,
1848 .connection_interval_max = initiating_phy_parameters[offset].connection_interval_max_,
1849 .max_latency = initiating_phy_parameters[offset].max_latency_,
1850 .supervision_timeout = initiating_phy_parameters[offset].supervision_timeout_,
1851 .min_ce_length = initiating_phy_parameters[offset].min_ce_length_,
1852 .max_ce_length = initiating_phy_parameters[offset].max_ce_length_,
1853 };
1854 offset++;
1855 }
1856
1857 if (initiating_phys & 0x4) {
1858 initiator_.le_coded_phy = Initiator::PhyParameters{
1859 .enabled = true,
1860 .scan_interval = initiating_phy_parameters[offset].scan_interval_,
1861 .scan_window = initiating_phy_parameters[offset].scan_window_,
1862 .connection_interval_min = initiating_phy_parameters[offset].connection_interval_min_,
1863 .connection_interval_max = initiating_phy_parameters[offset].connection_interval_max_,
1864 .max_latency = initiating_phy_parameters[offset].max_latency_,
1865 .supervision_timeout = initiating_phy_parameters[offset].supervision_timeout_,
1866 .min_ce_length = initiating_phy_parameters[offset].min_ce_length_,
1867 .max_ce_length = initiating_phy_parameters[offset].max_ce_length_,
1868 };
1869 offset++;
1870 }
1871
1872 return ErrorCode::SUCCESS;
1873 }
1874
SetSecureSimplePairingSupport(bool enable)1875 void LinkLayerController::SetSecureSimplePairingSupport(bool enable) {
1876 uint64_t bit = 0x1;
1877 secure_simple_pairing_host_support_ = enable;
1878 if (enable) {
1879 host_supported_features_ |= bit;
1880 } else {
1881 host_supported_features_ &= ~bit;
1882 }
1883 }
1884
SetLeHostSupport(bool enable)1885 void LinkLayerController::SetLeHostSupport(bool enable) {
1886 // TODO: Vol 2, Part C § 3.5 Feature requirements.
1887 // (65) LE Supported (Host) implies
1888 // (38) LE Supported (Controller)
1889 uint64_t bit = 0x2;
1890 le_host_support_ = enable;
1891 if (enable) {
1892 host_supported_features_ |= bit;
1893 } else {
1894 host_supported_features_ &= ~bit;
1895 }
1896 }
1897
SetSecureConnectionsSupport(bool enable)1898 void LinkLayerController::SetSecureConnectionsSupport(bool enable) {
1899 // TODO: Vol 2, Part C § 3.5 Feature requirements.
1900 // (67) Secure Connections (Host Support) implies
1901 // (64) Secure Simple Pairing (Host Support) and
1902 // (136) Secure Connections (Controller Support)
1903 uint64_t bit = 0x8;
1904 secure_connections_host_support_ = enable;
1905 if (enable) {
1906 host_supported_features_ |= bit;
1907 } else {
1908 host_supported_features_ &= ~bit;
1909 }
1910 }
1911
SetLocalName(std::array<uint8_t,kLocalNameSize> const & local_name)1912 void LinkLayerController::SetLocalName(std::array<uint8_t, kLocalNameSize> const& local_name) {
1913 std::copy(local_name.begin(), local_name.end(), local_name_.begin());
1914 }
1915
SetLocalName(std::vector<uint8_t> const & local_name)1916 void LinkLayerController::SetLocalName(std::vector<uint8_t> const& local_name) {
1917 ASSERT(local_name.size() <= local_name_.size());
1918 local_name_.fill(0);
1919 std::copy(local_name.begin(), local_name.end(), local_name_.begin());
1920 }
1921
SetExtendedInquiryResponse(std::array<uint8_t,240> const & extended_inquiry_response)1922 void LinkLayerController::SetExtendedInquiryResponse(
1923 std::array<uint8_t, 240> const& extended_inquiry_response) {
1924 extended_inquiry_response_ = extended_inquiry_response;
1925 }
1926
SetExtendedInquiryResponse(std::vector<uint8_t> const & extended_inquiry_response)1927 void LinkLayerController::SetExtendedInquiryResponse(
1928 std::vector<uint8_t> const& extended_inquiry_response) {
1929 ASSERT(extended_inquiry_response.size() <= extended_inquiry_response_.size());
1930 extended_inquiry_response_.fill(0);
1931 std::copy(extended_inquiry_response.begin(), extended_inquiry_response.end(),
1932 extended_inquiry_response_.begin());
1933 }
1934
LinkLayerController(const Address & address,const ControllerProperties & properties,uint32_t id)1935 LinkLayerController::LinkLayerController(const Address& address,
1936 const ControllerProperties& properties, uint32_t id)
1937 : id_(id),
1938 address_(address),
1939 properties_(properties),
1940 lm_(nullptr, link_manager_destroy),
1941 ll_(nullptr, link_layer_destroy) {
1942 if (properties_.quirks.has_default_random_address) {
1943 WARNING(id_, "Configuring a default random address for this controller");
1944 random_address_ = Address{0xba, 0xdb, 0xad, 0xba, 0xdb, 0xad};
1945 }
1946
1947 controller_ops_ = {
1948 .user_pointer = this,
1949 .get_handle =
1950 [](void* user, const uint8_t(*address)[6]) {
1951 auto controller = static_cast<LinkLayerController*>(user);
1952
1953 return controller->connections_.GetHandleOnlyAddress(Address(*address));
1954 },
1955
1956 .get_address =
1957 [](void* user, uint16_t handle, uint8_t(*result)[6]) {
1958 auto controller = static_cast<LinkLayerController*>(user);
1959
1960 auto address_opt = controller->connections_.GetAddressSafe(handle);
1961 Address address = address_opt.has_value() ? address_opt.value().GetAddress()
1962 : Address::kEmpty;
1963 std::copy(address.data(), address.data() + 6,
1964 reinterpret_cast<uint8_t*>(result));
1965 },
1966
1967 .get_extended_features =
1968 [](void* user, uint8_t features_page) {
1969 auto controller = static_cast<LinkLayerController*>(user);
1970 return controller->GetLmpFeatures(features_page);
1971 },
1972
1973 .get_le_features =
1974 [](void* user) {
1975 auto controller = static_cast<LinkLayerController*>(user);
1976 return controller->GetLeSupportedFeatures();
1977 },
1978
1979 .get_le_event_mask =
1980 [](void* user) {
1981 auto controller = static_cast<LinkLayerController*>(user);
1982 return controller->le_event_mask_;
1983 },
1984
1985 .send_hci_event =
1986 [](void* user, const uint8_t* data, uintptr_t len) {
1987 auto controller = static_cast<LinkLayerController*>(user);
1988
1989 auto event_code = static_cast<EventCode>(data[0]);
1990 controller->send_event_(bluetooth::hci::EventBuilder::Create(
1991 event_code, std::vector(data + 2, data + len)));
1992 },
1993
1994 .send_lmp_packet =
1995 [](void* user, const uint8_t(*to)[6], const uint8_t* data, uintptr_t len) {
1996 auto controller = static_cast<LinkLayerController*>(user);
1997
1998 Address source = controller->GetAddress();
1999 Address dest(*to);
2000
2001 controller->SendLinkLayerPacket(model::packets::LmpBuilder::Create(
2002 source, dest, std::vector(data, data + len)));
2003 },
2004
2005 .send_llcp_packet =
2006 [](void* user, uint16_t acl_connection_handle, const uint8_t* data,
2007 uintptr_t len) {
2008 auto controller = static_cast<LinkLayerController*>(user);
2009
2010 if (!controller->connections_.HasHandle(acl_connection_handle)) {
2011 ERROR("Dropping LLCP packet sent for unknown connection handle "
2012 "0x{:x}",
2013 acl_connection_handle);
2014 return;
2015 }
2016
2017 AclConnection const& connection =
2018 controller->connections_.GetAclConnection(acl_connection_handle);
2019 Address source = connection.GetOwnAddress().GetAddress();
2020 Address destination = connection.GetAddress().GetAddress();
2021
2022 controller->SendLinkLayerPacket(model::packets::LlcpBuilder::Create(
2023 source, destination, std::vector(data, data + len)));
2024 }};
2025
2026 lm_.reset(link_manager_create(controller_ops_));
2027 ll_.reset(link_layer_create(controller_ops_));
2028 }
2029
~LinkLayerController()2030 LinkLayerController::~LinkLayerController() {}
2031
SendLeLinkLayerPacket(std::unique_ptr<model::packets::LinkLayerPacketBuilder> packet,int8_t tx_power)2032 void LinkLayerController::SendLeLinkLayerPacket(
2033 std::unique_ptr<model::packets::LinkLayerPacketBuilder> packet, int8_t tx_power) {
2034 std::shared_ptr<model::packets::LinkLayerPacketBuilder> shared_packet = std::move(packet);
2035 ScheduleTask(kNoDelayMs, [this, shared_packet, tx_power]() {
2036 send_to_remote_(shared_packet, Phy::Type::LOW_ENERGY, tx_power);
2037 });
2038 }
2039
SendLinkLayerPacket(std::unique_ptr<model::packets::LinkLayerPacketBuilder> packet,int8_t tx_power)2040 void LinkLayerController::SendLinkLayerPacket(
2041 std::unique_ptr<model::packets::LinkLayerPacketBuilder> packet, int8_t tx_power) {
2042 std::shared_ptr<model::packets::LinkLayerPacketBuilder> shared_packet = std::move(packet);
2043 ScheduleTask(kNoDelayMs, [this, shared_packet, tx_power]() {
2044 send_to_remote_(shared_packet, Phy::Type::BR_EDR, tx_power);
2045 });
2046 }
2047
SendLeCommandToRemoteByAddress(OpCode opcode,const Address & own_address,const Address & peer_address)2048 ErrorCode LinkLayerController::SendLeCommandToRemoteByAddress(OpCode opcode,
2049 const Address& own_address,
2050 const Address& peer_address) {
2051 switch (opcode) {
2052 case (OpCode::LE_READ_REMOTE_FEATURES_PAGE_0):
2053 SendLeLinkLayerPacket(
2054 model::packets::LeReadRemoteFeaturesBuilder::Create(own_address, peer_address));
2055 break;
2056 default:
2057 INFO(id_, "Dropping unhandled command 0x{:04x}", static_cast<uint16_t>(opcode));
2058 return ErrorCode::UNKNOWN_HCI_COMMAND;
2059 }
2060
2061 return ErrorCode::SUCCESS;
2062 }
2063
SendCommandToRemoteByAddress(OpCode opcode,pdl::packet::slice args,const Address & own_address,const Address & peer_address)2064 ErrorCode LinkLayerController::SendCommandToRemoteByAddress(OpCode opcode, pdl::packet::slice args,
2065 const Address& own_address,
2066 const Address& peer_address) {
2067 switch (opcode) {
2068 case (OpCode::REMOTE_NAME_REQUEST):
2069 // LMP features get requested with remote name requests.
2070 SendLinkLayerPacket(
2071 model::packets::ReadRemoteLmpFeaturesBuilder::Create(own_address, peer_address));
2072 SendLinkLayerPacket(
2073 model::packets::RemoteNameRequestBuilder::Create(own_address, peer_address));
2074 break;
2075 case (OpCode::READ_REMOTE_SUPPORTED_FEATURES):
2076 SendLinkLayerPacket(model::packets::ReadRemoteSupportedFeaturesBuilder::Create(own_address,
2077 peer_address));
2078 break;
2079 case (OpCode::READ_REMOTE_EXTENDED_FEATURES): {
2080 pdl::packet::slice page_number_slice = args.subrange(5, 1);
2081 uint8_t page_number = page_number_slice.read_le<uint8_t>();
2082 SendLinkLayerPacket(model::packets::ReadRemoteExtendedFeaturesBuilder::Create(
2083 own_address, peer_address, page_number));
2084 } break;
2085 case (OpCode::READ_REMOTE_VERSION_INFORMATION):
2086 SendLinkLayerPacket(model::packets::ReadRemoteVersionInformationBuilder::Create(
2087 own_address, peer_address));
2088 break;
2089 case (OpCode::READ_CLOCK_OFFSET):
2090 SendLinkLayerPacket(
2091 model::packets::ReadClockOffsetBuilder::Create(own_address, peer_address));
2092 break;
2093 default:
2094 INFO(id_, "Dropping unhandled command 0x{:04x}", static_cast<uint16_t>(opcode));
2095 return ErrorCode::UNKNOWN_HCI_COMMAND;
2096 }
2097
2098 return ErrorCode::SUCCESS;
2099 }
2100
SendCommandToRemoteByHandle(OpCode opcode,pdl::packet::slice args,uint16_t handle)2101 ErrorCode LinkLayerController::SendCommandToRemoteByHandle(OpCode opcode, pdl::packet::slice args,
2102 uint16_t handle) {
2103 if (!connections_.HasHandle(handle)) {
2104 return ErrorCode::UNKNOWN_CONNECTION;
2105 }
2106
2107 switch (opcode) {
2108 case (OpCode::LE_READ_REMOTE_FEATURES_PAGE_0):
2109 return SendLeCommandToRemoteByAddress(opcode, connections_.GetOwnAddress(handle).GetAddress(),
2110 connections_.GetAddress(handle).GetAddress());
2111 default:
2112 return SendCommandToRemoteByAddress(opcode, args,
2113 connections_.GetOwnAddress(handle).GetAddress(),
2114 connections_.GetAddress(handle).GetAddress());
2115 }
2116 }
2117
SendAclToRemote(bluetooth::hci::AclView acl_packet)2118 ErrorCode LinkLayerController::SendAclToRemote(bluetooth::hci::AclView acl_packet) {
2119 uint16_t handle = acl_packet.GetHandle();
2120 if (!connections_.HasHandle(handle)) {
2121 return ErrorCode::UNKNOWN_CONNECTION;
2122 }
2123
2124 AddressWithType my_address = connections_.GetOwnAddress(handle);
2125 AddressWithType destination = connections_.GetAddress(handle);
2126 Phy::Type phy = connections_.GetPhyType(handle);
2127
2128 auto acl_packet_payload = acl_packet.GetPayload();
2129 auto acl = model::packets::AclBuilder::Create(
2130 my_address.GetAddress(), destination.GetAddress(),
2131 static_cast<uint8_t>(acl_packet.GetPacketBoundaryFlag()),
2132 static_cast<uint8_t>(acl_packet.GetBroadcastFlag()),
2133 std::vector(acl_packet_payload.begin(), acl_packet_payload.end()));
2134
2135 switch (phy) {
2136 case Phy::Type::BR_EDR:
2137 SendLinkLayerPacket(std::move(acl));
2138 break;
2139 case Phy::Type::LOW_ENERGY:
2140 SendLeLinkLayerPacket(std::move(acl));
2141 break;
2142 }
2143
2144 ScheduleTask(kNoDelayMs, [this, handle]() {
2145 send_event_(bluetooth::hci::NumberOfCompletedPacketsBuilder::Create(
2146 {bluetooth::hci::CompletedPackets(handle, 1)}));
2147 });
2148 return ErrorCode::SUCCESS;
2149 }
2150
SendScoToRemote(bluetooth::hci::ScoView sco_packet)2151 ErrorCode LinkLayerController::SendScoToRemote(bluetooth::hci::ScoView sco_packet) {
2152 uint16_t handle = sco_packet.GetHandle();
2153 if (!connections_.HasScoHandle(handle)) {
2154 return ErrorCode::UNKNOWN_CONNECTION;
2155 }
2156
2157 // TODO: SCO flow control
2158 Address source = GetAddress();
2159 Address destination = connections_.GetScoAddress(handle);
2160
2161 auto sco_data = sco_packet.GetData();
2162 std::vector<uint8_t> sco_data_bytes(sco_data.begin(), sco_data.end());
2163
2164 SendLinkLayerPacket(
2165 model::packets::ScoBuilder::Create(source, destination, std::move(sco_data_bytes)));
2166 return ErrorCode::SUCCESS;
2167 }
2168
IncomingPacket(model::packets::LinkLayerPacketView incoming,int8_t rssi)2169 void LinkLayerController::IncomingPacket(model::packets::LinkLayerPacketView incoming,
2170 int8_t rssi) {
2171 ASSERT(incoming.IsValid());
2172 auto destination_address = incoming.GetDestinationAddress();
2173
2174 // Match broadcasts
2175 bool address_matches = (destination_address == Address::kEmpty);
2176
2177 // Address match is performed in specific handlers for these PDU types.
2178 switch (incoming.GetType()) {
2179 case model::packets::PacketType::LE_SCAN:
2180 case model::packets::PacketType::LE_SCAN_RESPONSE:
2181 case model::packets::PacketType::LE_LEGACY_ADVERTISING_PDU:
2182 case model::packets::PacketType::LE_EXTENDED_ADVERTISING_PDU:
2183 case model::packets::PacketType::LE_CONNECT:
2184 address_matches = true;
2185 break;
2186 default:
2187 break;
2188 }
2189
2190 // Check public address
2191 if (destination_address == address_ || destination_address == random_address_) {
2192 address_matches = true;
2193 }
2194
2195 // Check current connection address
2196 if (destination_address == initiator_.initiating_address) {
2197 address_matches = true;
2198 }
2199
2200 // Check connection addresses
2201 auto source_address = incoming.GetSourceAddress();
2202 auto handle = connections_.GetHandleOnlyAddress(source_address);
2203 if (handle != kReservedHandle) {
2204 if (connections_.GetOwnAddress(handle).GetAddress() == destination_address) {
2205 address_matches = true;
2206
2207 // Update link timeout for valid ACL connections
2208 connections_.ResetLinkTimer(handle);
2209 }
2210 }
2211
2212 // Drop packets not addressed to me
2213 if (!address_matches) {
2214 INFO(id_, "{} | Dropping packet not addressed to me {}->{} (type 0x{:x})", address_,
2215 source_address, destination_address, static_cast<int>(incoming.GetType()));
2216 return;
2217 }
2218
2219 switch (incoming.GetType()) {
2220 case model::packets::PacketType::ACL:
2221 IncomingAclPacket(incoming, rssi);
2222 break;
2223 case model::packets::PacketType::SCO:
2224 IncomingScoPacket(incoming);
2225 break;
2226 case model::packets::PacketType::LE_CONNECTED_ISOCHRONOUS_PDU:
2227 IncomingLeConnectedIsochronousPdu(incoming);
2228 break;
2229 case model::packets::PacketType::DISCONNECT:
2230 IncomingDisconnectPacket(incoming);
2231 break;
2232 case model::packets::PacketType::LMP:
2233 IncomingLmpPacket(incoming);
2234 break;
2235 case model::packets::PacketType::LLCP:
2236 IncomingLlcpPacket(incoming);
2237 break;
2238 case model::packets::PacketType::INQUIRY:
2239 if (inquiry_scan_enable_) {
2240 IncomingInquiryPacket(incoming, rssi);
2241 }
2242 break;
2243 case model::packets::PacketType::INQUIRY_RESPONSE:
2244 IncomingInquiryResponsePacket(incoming);
2245 break;
2246 case model::packets::PacketType::LE_LEGACY_ADVERTISING_PDU:
2247 IncomingLeLegacyAdvertisingPdu(incoming, rssi);
2248 return;
2249 case model::packets::PacketType::LE_EXTENDED_ADVERTISING_PDU:
2250 IncomingLeExtendedAdvertisingPdu(incoming, rssi);
2251 return;
2252 case model::packets::PacketType::LE_PERIODIC_ADVERTISING_PDU:
2253 IncomingLePeriodicAdvertisingPdu(incoming, rssi);
2254 return;
2255 case model::packets::PacketType::LE_CONNECT:
2256 IncomingLeConnectPacket(incoming);
2257 break;
2258 case model::packets::PacketType::LE_CONNECT_COMPLETE:
2259 IncomingLeConnectCompletePacket(incoming);
2260 break;
2261 case model::packets::PacketType::LE_CONNECTION_PARAMETER_REQUEST:
2262 IncomingLeConnectionParameterRequest(incoming);
2263 break;
2264 case model::packets::PacketType::LE_CONNECTION_PARAMETER_UPDATE:
2265 IncomingLeConnectionParameterUpdate(incoming);
2266 break;
2267 case model::packets::PacketType::LE_ENCRYPT_CONNECTION:
2268 IncomingLeEncryptConnection(incoming);
2269 break;
2270 case model::packets::PacketType::LE_ENCRYPT_CONNECTION_RESPONSE:
2271 IncomingLeEncryptConnectionResponse(incoming);
2272 break;
2273 case (model::packets::PacketType::LE_READ_REMOTE_FEATURES):
2274 IncomingLeReadRemoteFeatures(incoming);
2275 break;
2276 case (model::packets::PacketType::LE_READ_REMOTE_FEATURES_RESPONSE):
2277 IncomingLeReadRemoteFeaturesResponse(incoming);
2278 break;
2279 case model::packets::PacketType::LE_SCAN:
2280 IncomingLeScanPacket(incoming);
2281 break;
2282 case model::packets::PacketType::LE_SCAN_RESPONSE:
2283 IncomingLeScanResponsePacket(incoming, rssi);
2284 break;
2285 case model::packets::PacketType::PAGE:
2286 if (page_scan_enable_) {
2287 IncomingPagePacket(incoming);
2288 }
2289 break;
2290 case model::packets::PacketType::PAGE_RESPONSE:
2291 IncomingPageResponsePacket(incoming);
2292 break;
2293 case model::packets::PacketType::PAGE_REJECT:
2294 IncomingPageRejectPacket(incoming);
2295 break;
2296 case (model::packets::PacketType::REMOTE_NAME_REQUEST):
2297 IncomingRemoteNameRequest(incoming);
2298 break;
2299 case (model::packets::PacketType::REMOTE_NAME_REQUEST_RESPONSE):
2300 IncomingRemoteNameRequestResponse(incoming);
2301 break;
2302 case (model::packets::PacketType::READ_REMOTE_SUPPORTED_FEATURES):
2303 IncomingReadRemoteSupportedFeatures(incoming);
2304 break;
2305 case (model::packets::PacketType::READ_REMOTE_SUPPORTED_FEATURES_RESPONSE):
2306 IncomingReadRemoteSupportedFeaturesResponse(incoming);
2307 break;
2308 case (model::packets::PacketType::READ_REMOTE_LMP_FEATURES):
2309 IncomingReadRemoteLmpFeatures(incoming);
2310 break;
2311 case (model::packets::PacketType::READ_REMOTE_LMP_FEATURES_RESPONSE):
2312 IncomingReadRemoteLmpFeaturesResponse(incoming);
2313 break;
2314 case (model::packets::PacketType::READ_REMOTE_EXTENDED_FEATURES):
2315 IncomingReadRemoteExtendedFeatures(incoming);
2316 break;
2317 case (model::packets::PacketType::READ_REMOTE_EXTENDED_FEATURES_RESPONSE):
2318 IncomingReadRemoteExtendedFeaturesResponse(incoming);
2319 break;
2320 case (model::packets::PacketType::READ_REMOTE_VERSION_INFORMATION):
2321 IncomingReadRemoteVersion(incoming);
2322 break;
2323 case (model::packets::PacketType::READ_REMOTE_VERSION_INFORMATION_RESPONSE):
2324 IncomingReadRemoteVersionResponse(incoming);
2325 break;
2326 case (model::packets::PacketType::READ_CLOCK_OFFSET):
2327 IncomingReadClockOffset(incoming);
2328 break;
2329 case (model::packets::PacketType::READ_CLOCK_OFFSET_RESPONSE):
2330 IncomingReadClockOffsetResponse(incoming);
2331 break;
2332 case model::packets::PacketType::SCO_CONNECTION_REQUEST:
2333 IncomingScoConnectionRequest(incoming);
2334 break;
2335 case model::packets::PacketType::SCO_CONNECTION_RESPONSE:
2336 IncomingScoConnectionResponse(incoming);
2337 break;
2338 case model::packets::PacketType::SCO_DISCONNECT:
2339 IncomingScoDisconnect(incoming);
2340 break;
2341 case model::packets::PacketType::PING_REQUEST:
2342 IncomingPingRequest(incoming);
2343 break;
2344 case model::packets::PacketType::PING_RESPONSE:
2345 // ping responses require no action
2346 break;
2347 case model::packets::PacketType::ROLE_SWITCH_REQUEST:
2348 IncomingRoleSwitchRequest(incoming);
2349 break;
2350 case model::packets::PacketType::ROLE_SWITCH_RESPONSE:
2351 IncomingRoleSwitchResponse(incoming);
2352 break;
2353 case model::packets::PacketType::LL_PHY_REQ:
2354 IncomingLlPhyReq(incoming);
2355 break;
2356 case model::packets::PacketType::LL_PHY_RSP:
2357 IncomingLlPhyRsp(incoming);
2358 break;
2359 case model::packets::PacketType::LL_PHY_UPDATE_IND:
2360 IncomingLlPhyUpdateInd(incoming);
2361 break;
2362 default:
2363 WARNING(id_, "Dropping unhandled packet of type {}",
2364 model::packets::PacketTypeText(incoming.GetType()));
2365 }
2366 }
2367
IncomingAclPacket(model::packets::LinkLayerPacketView incoming,int8_t rssi)2368 void LinkLayerController::IncomingAclPacket(model::packets::LinkLayerPacketView incoming,
2369 int8_t rssi) {
2370 auto acl = model::packets::AclView::Create(incoming);
2371 ASSERT(acl.IsValid());
2372
2373 auto acl_data = acl.GetData();
2374 auto packet_boundary_flag = bluetooth::hci::PacketBoundaryFlag(acl.GetPacketBoundaryFlag());
2375 auto broadcast_flag = bluetooth::hci::BroadcastFlag(acl.GetBroadcastFlag());
2376
2377 if (packet_boundary_flag ==
2378 bluetooth::hci::PacketBoundaryFlag::FIRST_NON_AUTOMATICALLY_FLUSHABLE) {
2379 packet_boundary_flag = bluetooth::hci::PacketBoundaryFlag::FIRST_AUTOMATICALLY_FLUSHABLE;
2380 }
2381
2382 INFO(id_, "Acl Packet [{}] {} -> {}", acl_data.size(), incoming.GetSourceAddress(),
2383 incoming.GetDestinationAddress());
2384
2385 uint16_t connection_handle = connections_.GetHandleOnlyAddress(incoming.GetSourceAddress());
2386 if (connection_handle == kReservedHandle) {
2387 INFO(id_, "Dropping packet since connection does not exist");
2388 return;
2389 }
2390
2391 // Update the RSSI for the local ACL connection.
2392 connections_.SetRssi(connection_handle, rssi);
2393
2394 // Send the packet to the host segmented according to the
2395 // controller ACL data packet length.
2396 size_t acl_buffer_size = properties_.acl_data_packet_length;
2397 size_t offset = 0;
2398
2399 while (offset < acl_data.size()) {
2400 size_t fragment_size = std::min(acl_buffer_size, acl_data.size() - offset);
2401 std::vector<uint8_t> fragment(acl_data.begin() + offset,
2402 acl_data.begin() + offset + fragment_size);
2403
2404 auto acl_packet = bluetooth::hci::AclBuilder::Create(connection_handle, packet_boundary_flag,
2405 broadcast_flag, std::move(fragment));
2406
2407 send_acl_(std::move(acl_packet));
2408
2409 packet_boundary_flag = bluetooth::hci::PacketBoundaryFlag::CONTINUING_FRAGMENT;
2410 offset += fragment_size;
2411 }
2412 }
2413
IncomingScoPacket(model::packets::LinkLayerPacketView incoming)2414 void LinkLayerController::IncomingScoPacket(model::packets::LinkLayerPacketView incoming) {
2415 Address source = incoming.GetSourceAddress();
2416 uint16_t sco_handle = connections_.GetScoHandle(source);
2417 if (!connections_.HasScoHandle(sco_handle)) {
2418 INFO(id_, "Spurious SCO packet from {}", source);
2419 return;
2420 }
2421
2422 auto sco = model::packets::ScoView::Create(incoming);
2423 ASSERT(sco.IsValid());
2424 auto sco_data = sco.GetPayload();
2425 std::vector<uint8_t> sco_data_bytes(sco_data.begin(), sco_data.end());
2426
2427 INFO(id_, "Sco Packet [{}] {} -> {}", static_cast<int>(sco_data_bytes.size()),
2428 incoming.GetSourceAddress(), incoming.GetDestinationAddress());
2429
2430 send_sco_(bluetooth::hci::ScoBuilder::Create(
2431 sco_handle, bluetooth::hci::PacketStatusFlag::CORRECTLY_RECEIVED, sco_data_bytes));
2432 }
2433
IncomingRemoteNameRequest(model::packets::LinkLayerPacketView incoming)2434 void LinkLayerController::IncomingRemoteNameRequest(model::packets::LinkLayerPacketView incoming) {
2435 auto view = model::packets::RemoteNameRequestView::Create(incoming);
2436 ASSERT(view.IsValid());
2437
2438 SendLinkLayerPacket(model::packets::RemoteNameRequestResponseBuilder::Create(
2439 incoming.GetDestinationAddress(), incoming.GetSourceAddress(), local_name_));
2440 }
2441
IncomingRemoteNameRequestResponse(model::packets::LinkLayerPacketView incoming)2442 void LinkLayerController::IncomingRemoteNameRequestResponse(
2443 model::packets::LinkLayerPacketView incoming) {
2444 auto view = model::packets::RemoteNameRequestResponseView::Create(incoming);
2445 ASSERT(view.IsValid());
2446
2447 if (IsEventUnmasked(EventCode::REMOTE_NAME_REQUEST_COMPLETE)) {
2448 send_event_(bluetooth::hci::RemoteNameRequestCompleteBuilder::Create(
2449 ErrorCode::SUCCESS, incoming.GetSourceAddress(), view.GetName()));
2450 }
2451 }
2452
IncomingReadRemoteLmpFeatures(model::packets::LinkLayerPacketView incoming)2453 void LinkLayerController::IncomingReadRemoteLmpFeatures(
2454 model::packets::LinkLayerPacketView incoming) {
2455 SendLinkLayerPacket(model::packets::ReadRemoteLmpFeaturesResponseBuilder::Create(
2456 incoming.GetDestinationAddress(), incoming.GetSourceAddress(), host_supported_features_));
2457 }
2458
IncomingReadRemoteLmpFeaturesResponse(model::packets::LinkLayerPacketView incoming)2459 void LinkLayerController::IncomingReadRemoteLmpFeaturesResponse(
2460 model::packets::LinkLayerPacketView incoming) {
2461 auto view = model::packets::ReadRemoteLmpFeaturesResponseView::Create(incoming);
2462 ASSERT(view.IsValid());
2463 if (IsEventUnmasked(EventCode::REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION)) {
2464 send_event_(bluetooth::hci::RemoteHostSupportedFeaturesNotificationBuilder::Create(
2465 incoming.GetSourceAddress(), view.GetFeatures()));
2466 }
2467 }
2468
IncomingReadRemoteSupportedFeatures(model::packets::LinkLayerPacketView incoming)2469 void LinkLayerController::IncomingReadRemoteSupportedFeatures(
2470 model::packets::LinkLayerPacketView incoming) {
2471 SendLinkLayerPacket(model::packets::ReadRemoteSupportedFeaturesResponseBuilder::Create(
2472 incoming.GetDestinationAddress(), incoming.GetSourceAddress(),
2473 properties_.lmp_features[0]));
2474 }
2475
IncomingReadRemoteSupportedFeaturesResponse(model::packets::LinkLayerPacketView incoming)2476 void LinkLayerController::IncomingReadRemoteSupportedFeaturesResponse(
2477 model::packets::LinkLayerPacketView incoming) {
2478 auto view = model::packets::ReadRemoteSupportedFeaturesResponseView::Create(incoming);
2479 ASSERT(view.IsValid());
2480 Address source = incoming.GetSourceAddress();
2481 uint16_t handle = connections_.GetHandleOnlyAddress(source);
2482 if (handle == kReservedHandle) {
2483 INFO(id_, "Discarding response from a disconnected device {}", source);
2484 return;
2485 }
2486 if (IsEventUnmasked(EventCode::READ_REMOTE_SUPPORTED_FEATURES_COMPLETE)) {
2487 send_event_(bluetooth::hci::ReadRemoteSupportedFeaturesCompleteBuilder::Create(
2488 ErrorCode::SUCCESS, handle, view.GetFeatures()));
2489 }
2490 }
2491
IncomingReadRemoteExtendedFeatures(model::packets::LinkLayerPacketView incoming)2492 void LinkLayerController::IncomingReadRemoteExtendedFeatures(
2493 model::packets::LinkLayerPacketView incoming) {
2494 auto view = model::packets::ReadRemoteExtendedFeaturesView::Create(incoming);
2495 ASSERT(view.IsValid());
2496 uint8_t page_number = view.GetPageNumber();
2497 uint8_t error_code = static_cast<uint8_t>(ErrorCode::SUCCESS);
2498 if (page_number >= properties_.lmp_features.size()) {
2499 error_code = static_cast<uint8_t>(ErrorCode::INVALID_LMP_OR_LL_PARAMETERS);
2500 }
2501 SendLinkLayerPacket(model::packets::ReadRemoteExtendedFeaturesResponseBuilder::Create(
2502 incoming.GetDestinationAddress(), incoming.GetSourceAddress(), error_code, page_number,
2503 GetMaxLmpFeaturesPageNumber(), GetLmpFeatures(page_number)));
2504 }
2505
IncomingReadRemoteExtendedFeaturesResponse(model::packets::LinkLayerPacketView incoming)2506 void LinkLayerController::IncomingReadRemoteExtendedFeaturesResponse(
2507 model::packets::LinkLayerPacketView incoming) {
2508 auto view = model::packets::ReadRemoteExtendedFeaturesResponseView::Create(incoming);
2509 ASSERT(view.IsValid());
2510 Address source = incoming.GetSourceAddress();
2511 uint16_t handle = connections_.GetHandleOnlyAddress(source);
2512 if (handle == kReservedHandle) {
2513 INFO(id_, "Discarding response from a disconnected device {}", source);
2514 return;
2515 }
2516 if (IsEventUnmasked(EventCode::READ_REMOTE_EXTENDED_FEATURES_COMPLETE)) {
2517 send_event_(bluetooth::hci::ReadRemoteExtendedFeaturesCompleteBuilder::Create(
2518 static_cast<ErrorCode>(view.GetStatus()), handle, view.GetPageNumber(),
2519 view.GetMaxPageNumber(), view.GetFeatures()));
2520 }
2521 }
2522
IncomingReadRemoteVersion(model::packets::LinkLayerPacketView incoming)2523 void LinkLayerController::IncomingReadRemoteVersion(model::packets::LinkLayerPacketView incoming) {
2524 SendLinkLayerPacket(model::packets::ReadRemoteVersionInformationResponseBuilder::Create(
2525 incoming.GetDestinationAddress(), incoming.GetSourceAddress(),
2526 static_cast<uint8_t>(properties_.lmp_version),
2527 static_cast<uint16_t>(properties_.lmp_subversion), properties_.company_identifier));
2528 }
2529
IncomingReadRemoteVersionResponse(model::packets::LinkLayerPacketView incoming)2530 void LinkLayerController::IncomingReadRemoteVersionResponse(
2531 model::packets::LinkLayerPacketView incoming) {
2532 auto view = model::packets::ReadRemoteVersionInformationResponseView::Create(incoming);
2533 ASSERT(view.IsValid());
2534 Address source = incoming.GetSourceAddress();
2535 uint16_t handle = connections_.GetHandleOnlyAddress(source);
2536 if (handle == kReservedHandle) {
2537 INFO(id_, "Discarding response from a disconnected device {}", source);
2538 return;
2539 }
2540 if (IsEventUnmasked(EventCode::READ_REMOTE_VERSION_INFORMATION_COMPLETE)) {
2541 send_event_(bluetooth::hci::ReadRemoteVersionInformationCompleteBuilder::Create(
2542 ErrorCode::SUCCESS, handle, view.GetLmpVersion(), view.GetManufacturerName(),
2543 view.GetLmpSubversion()));
2544 }
2545 }
2546
IncomingReadClockOffset(model::packets::LinkLayerPacketView incoming)2547 void LinkLayerController::IncomingReadClockOffset(model::packets::LinkLayerPacketView incoming) {
2548 SendLinkLayerPacket(model::packets::ReadClockOffsetResponseBuilder::Create(
2549 incoming.GetDestinationAddress(), incoming.GetSourceAddress(), GetClockOffset()));
2550 }
2551
IncomingReadClockOffsetResponse(model::packets::LinkLayerPacketView incoming)2552 void LinkLayerController::IncomingReadClockOffsetResponse(
2553 model::packets::LinkLayerPacketView incoming) {
2554 auto view = model::packets::ReadClockOffsetResponseView::Create(incoming);
2555 ASSERT(view.IsValid());
2556 Address source = incoming.GetSourceAddress();
2557 uint16_t handle = connections_.GetHandleOnlyAddress(source);
2558 if (handle == kReservedHandle) {
2559 INFO(id_, "Discarding response from a disconnected device {}", source);
2560 return;
2561 }
2562 if (IsEventUnmasked(EventCode::READ_CLOCK_OFFSET_COMPLETE)) {
2563 send_event_(bluetooth::hci::ReadClockOffsetCompleteBuilder::Create(ErrorCode::SUCCESS, handle,
2564 view.GetOffset()));
2565 }
2566 }
2567
IncomingDisconnectPacket(model::packets::LinkLayerPacketView incoming)2568 void LinkLayerController::IncomingDisconnectPacket(model::packets::LinkLayerPacketView incoming) {
2569 INFO(id_, "Disconnect Packet");
2570 auto disconnect = model::packets::DisconnectView::Create(incoming);
2571 ASSERT(disconnect.IsValid());
2572
2573 Address peer = incoming.GetSourceAddress();
2574 uint16_t handle = connections_.GetHandleOnlyAddress(peer);
2575 if (handle == kReservedHandle) {
2576 INFO(id_, "Discarding disconnect from a disconnected device {}", peer);
2577 return;
2578 }
2579 auto is_br_edr = connections_.GetPhyType(handle) == Phy::Type::BR_EDR;
2580 ASSERT_LOG(
2581 connections_.Disconnect(handle, [this](TaskId task_id) { CancelScheduledTask(task_id); }),
2582 "GetHandle() returned invalid handle 0x{:x}", handle);
2583
2584 uint8_t reason = disconnect.GetReason();
2585 SendDisconnectionCompleteEvent(handle, ErrorCode(reason));
2586 if (is_br_edr) {
2587 ASSERT(link_manager_remove_link(lm_.get(), reinterpret_cast<uint8_t(*)[6]>(peer.data())));
2588 } else {
2589 ASSERT(link_layer_remove_link(ll_.get(), handle));
2590 }
2591 }
2592
IncomingInquiryPacket(model::packets::LinkLayerPacketView incoming,uint8_t rssi)2593 void LinkLayerController::IncomingInquiryPacket(model::packets::LinkLayerPacketView incoming,
2594 uint8_t rssi) {
2595 auto inquiry = model::packets::InquiryView::Create(incoming);
2596 ASSERT(inquiry.IsValid());
2597
2598 Address peer = incoming.GetSourceAddress();
2599 uint8_t lap = inquiry.GetLap();
2600
2601 // Filter out inquiry packets with IAC not present in the
2602 // list Current_IAC_LAP.
2603 if (std::none_of(current_iac_lap_list_.cbegin(), current_iac_lap_list_.cend(),
2604 [lap](auto iac_lap) { return iac_lap.lap_ == lap; })) {
2605 return;
2606 }
2607
2608 switch (inquiry.GetInquiryType()) {
2609 case (model::packets::InquiryType::STANDARD): {
2610 SendLinkLayerPacket(model::packets::InquiryResponseBuilder::Create(
2611 GetAddress(), peer, static_cast<uint8_t>(GetPageScanRepetitionMode()),
2612 class_of_device_, GetClockOffset()));
2613 } break;
2614 case (model::packets::InquiryType::RSSI): {
2615 SendLinkLayerPacket(model::packets::InquiryResponseWithRssiBuilder::Create(
2616 GetAddress(), peer, static_cast<uint8_t>(GetPageScanRepetitionMode()),
2617 class_of_device_, GetClockOffset(), rssi));
2618 } break;
2619 case (model::packets::InquiryType::EXTENDED): {
2620 SendLinkLayerPacket(model::packets::ExtendedInquiryResponseBuilder::Create(
2621 GetAddress(), peer, static_cast<uint8_t>(GetPageScanRepetitionMode()),
2622 class_of_device_, GetClockOffset(), rssi, extended_inquiry_response_));
2623 } break;
2624 default:
2625 WARNING(id_, "Unhandled Incoming Inquiry of type {}", static_cast<int>(inquiry.GetType()));
2626 return;
2627 }
2628 // TODO: Send an Inquiry Response Notification Event 7.7.74
2629 }
2630
IncomingInquiryResponsePacket(model::packets::LinkLayerPacketView incoming)2631 void LinkLayerController::IncomingInquiryResponsePacket(
2632 model::packets::LinkLayerPacketView incoming) {
2633 auto basic_inquiry_response = model::packets::BasicInquiryResponseView::Create(incoming);
2634 ASSERT(basic_inquiry_response.IsValid());
2635 std::vector<uint8_t> eir;
2636
2637 switch (basic_inquiry_response.GetInquiryType()) {
2638 case (model::packets::InquiryType::STANDARD): {
2639 // TODO: Support multiple inquiries in the same packet.
2640 auto inquiry_response = model::packets::InquiryResponseView::Create(basic_inquiry_response);
2641 ASSERT(inquiry_response.IsValid());
2642
2643 auto page_scan_repetition_mode =
2644 (bluetooth::hci::PageScanRepetitionMode)inquiry_response.GetPageScanRepetitionMode();
2645
2646 std::vector<bluetooth::hci::InquiryResponse> responses;
2647 responses.emplace_back();
2648 responses.back().bd_addr_ = inquiry_response.GetSourceAddress();
2649 responses.back().page_scan_repetition_mode_ = page_scan_repetition_mode;
2650 responses.back().class_of_device_ = inquiry_response.GetClassOfDevice();
2651 responses.back().clock_offset_ = inquiry_response.GetClockOffset();
2652 if (IsEventUnmasked(EventCode::INQUIRY_RESULT)) {
2653 send_event_(bluetooth::hci::InquiryResultBuilder::Create(responses));
2654 }
2655 } break;
2656
2657 case (model::packets::InquiryType::RSSI): {
2658 auto inquiry_response =
2659 model::packets::InquiryResponseWithRssiView::Create(basic_inquiry_response);
2660 ASSERT(inquiry_response.IsValid());
2661
2662 auto page_scan_repetition_mode =
2663 (bluetooth::hci::PageScanRepetitionMode)inquiry_response.GetPageScanRepetitionMode();
2664
2665 std::vector<bluetooth::hci::InquiryResponseWithRssi> responses;
2666 responses.emplace_back();
2667 responses.back().address_ = inquiry_response.GetSourceAddress();
2668 responses.back().page_scan_repetition_mode_ = page_scan_repetition_mode;
2669 responses.back().class_of_device_ = inquiry_response.GetClassOfDevice();
2670 responses.back().clock_offset_ = inquiry_response.GetClockOffset();
2671 responses.back().rssi_ = inquiry_response.GetRssi();
2672 if (IsEventUnmasked(EventCode::INQUIRY_RESULT_WITH_RSSI)) {
2673 send_event_(bluetooth::hci::InquiryResultWithRssiBuilder::Create(responses));
2674 }
2675 } break;
2676
2677 case (model::packets::InquiryType::EXTENDED): {
2678 auto inquiry_response =
2679 model::packets::ExtendedInquiryResponseView::Create(basic_inquiry_response);
2680 ASSERT(inquiry_response.IsValid());
2681
2682 send_event_(bluetooth::hci::ExtendedInquiryResultBuilder::Create(
2683 inquiry_response.GetSourceAddress(),
2684 static_cast<bluetooth::hci::PageScanRepetitionMode>(
2685 inquiry_response.GetPageScanRepetitionMode()),
2686 inquiry_response.GetClassOfDevice(), inquiry_response.GetClockOffset(),
2687 inquiry_response.GetRssi(), inquiry_response.GetExtendedInquiryResponse()));
2688 } break;
2689
2690 default:
2691 WARNING(id_, "Unhandled Incoming Inquiry Response of type {}",
2692 static_cast<int>(basic_inquiry_response.GetInquiryType()));
2693 }
2694 }
2695
generate_rpa(std::array<uint8_t,LinkLayerController::kIrkSize> irk)2696 Address LinkLayerController::generate_rpa(std::array<uint8_t, LinkLayerController::kIrkSize> irk) {
2697 // most significant bit, bit7, bit6 is 01 to be resolvable random
2698 // Bits of the random part of prand shall not be all 1 or all 0
2699 std::array<uint8_t, 3> prand;
2700 prand[0] = std::rand();
2701 prand[1] = std::rand();
2702 prand[2] = std::rand();
2703
2704 constexpr uint8_t BLE_RESOLVE_ADDR_MSB = 0x40;
2705 prand[2] &= ~0xC0; // BLE Address mask
2706 if ((prand[0] == 0x00 && prand[1] == 0x00 && prand[2] == 0x00) ||
2707 (prand[0] == 0xFF && prand[1] == 0xFF && prand[2] == 0x3F)) {
2708 prand[0] = (uint8_t)(std::rand() % 0xFE + 1);
2709 }
2710 prand[2] |= BLE_RESOLVE_ADDR_MSB;
2711
2712 Address rpa;
2713 rpa.address[3] = prand[0];
2714 rpa.address[4] = prand[1];
2715 rpa.address[5] = prand[2];
2716
2717 /* encrypt with IRK */
2718 rootcanal::crypto::Octet16 p = rootcanal::crypto::aes_128(irk, prand.data(), 3);
2719
2720 /* set hash to be LSB of rpAddress */
2721 rpa.address[0] = p[0];
2722 rpa.address[1] = p[1];
2723 rpa.address[2] = p[2];
2724 INFO("RPA {}", rpa);
2725 return rpa;
2726 }
2727
irk_is_zero(std::array<uint8_t,LinkLayerController::kIrkSize> irk)2728 bool LinkLayerController::irk_is_zero(std::array<uint8_t, LinkLayerController::kIrkSize> irk) {
2729 return std::all_of(irk.begin(), irk.end(), [](uint8_t b) { return b == 0; });
2730 }
2731
2732 // Handle legacy advertising PDUs while in the Scanning state.
ScanIncomingLeLegacyAdvertisingPdu(model::packets::LeLegacyAdvertisingPduView & pdu,uint8_t rssi)2733 void LinkLayerController::ScanIncomingLeLegacyAdvertisingPdu(
2734 model::packets::LeLegacyAdvertisingPduView& pdu, uint8_t rssi) {
2735 if (!scanner_.IsEnabled()) {
2736 return;
2737 }
2738
2739 auto advertising_type = pdu.GetAdvertisingType();
2740 std::vector<uint8_t> advertising_data = pdu.GetAdvertisingData();
2741
2742 AddressWithType advertising_address{pdu.GetSourceAddress(),
2743 static_cast<AddressType>(pdu.GetAdvertisingAddressType())};
2744
2745 AddressWithType target_address{pdu.GetDestinationAddress(),
2746 static_cast<AddressType>(pdu.GetTargetAddressType())};
2747
2748 bool scannable_advertising =
2749 advertising_type == model::packets::LegacyAdvertisingType::ADV_IND ||
2750 advertising_type == model::packets::LegacyAdvertisingType::ADV_SCAN_IND;
2751
2752 bool directed_advertising =
2753 advertising_type == model::packets::LegacyAdvertisingType::ADV_DIRECT_IND;
2754
2755 bool connectable_advertising =
2756 advertising_type == model::packets::LegacyAdvertisingType::ADV_IND ||
2757 advertising_type == model::packets::LegacyAdvertisingType::ADV_DIRECT_IND;
2758
2759 // TODO: check originating PHY, compare against active scanning PHYs
2760 // (scanner_.le_1m_phy or scanner_.le_coded_phy).
2761
2762 // When a scanner receives an advertising packet that contains a resolvable
2763 // private address for the advertiser’s device address (AdvA field) and
2764 // address resolution is enabled, the Link Layer shall resolve the private
2765 // address. The scanner’s filter policy shall then determine if the scanner
2766 // responds with a scan request.
2767 AddressWithType resolved_advertising_address =
2768 ResolvePrivateAddress(advertising_address).value_or(advertising_address);
2769
2770 if (resolved_advertising_address != advertising_address) {
2771 DEBUG(id_, "Resolved the advertising address {} to {}", advertising_address,
2772 resolved_advertising_address);
2773 }
2774
2775 // Vol 6, Part B § 4.3.3 Scanner filter policy
2776 switch (scanner_.scan_filter_policy) {
2777 case bluetooth::hci::LeScanningFilterPolicy::ACCEPT_ALL:
2778 case bluetooth::hci::LeScanningFilterPolicy::CHECK_INITIATORS_IDENTITY:
2779 break;
2780 case bluetooth::hci::LeScanningFilterPolicy::FILTER_ACCEPT_LIST_ONLY:
2781 case bluetooth::hci::LeScanningFilterPolicy::FILTER_ACCEPT_LIST_AND_INITIATORS_IDENTITY:
2782 if (!LeFilterAcceptListContainsDevice(resolved_advertising_address)) {
2783 DEBUG(id_,
2784 "Legacy advertising ignored by scanner because the advertising "
2785 "address {} is not in the filter accept list",
2786 resolved_advertising_address);
2787 return;
2788 }
2789 break;
2790 }
2791
2792 // When LE_Set_Scan_Enable is used:
2793 //
2794 // When the Scanning_Filter_Policy is set to 0x02 or 0x03 (see Section 7.8.10)
2795 // and a directed advertisement was received where the advertiser used a
2796 // resolvable private address which the Controller is unable to resolve, an
2797 // HCI_LE_Directed_Advertising_Report event shall be generated instead of an
2798 // HCI_LE_Advertising_Report event.
2799 bool should_send_directed_advertising_report = false;
2800
2801 if (directed_advertising) {
2802 switch (scanner_.scan_filter_policy) {
2803 // In both basic scanner filter policy modes, a directed advertising PDU
2804 // shall be ignored unless either:
2805 // • the TargetA field is identical to the scanner's device address, or
2806 // • the TargetA field is a resolvable private address, address
2807 // resolution is enabled, and the address is resolved successfully
2808 case bluetooth::hci::LeScanningFilterPolicy::ACCEPT_ALL:
2809 case bluetooth::hci::LeScanningFilterPolicy::FILTER_ACCEPT_LIST_ONLY:
2810 if (!ValidateTargetA(target_address, resolved_advertising_address)) {
2811 DEBUG(id_,
2812 "Legacy advertising ignored by scanner because the directed "
2813 "address {} does not match the current device or cannot be "
2814 "resolved",
2815 target_address);
2816 return;
2817 }
2818 break;
2819 // These are identical to the basic modes except
2820 // that a directed advertising PDU shall be ignored unless either:
2821 // • the TargetA field is identical to the scanner's device address, or
2822 // • the TargetA field is a resolvable private address.
2823 case bluetooth::hci::LeScanningFilterPolicy::CHECK_INITIATORS_IDENTITY:
2824 case bluetooth::hci::LeScanningFilterPolicy::FILTER_ACCEPT_LIST_AND_INITIATORS_IDENTITY:
2825 if (!IsLocalPublicOrRandomAddress(target_address) && !target_address.IsRpa()) {
2826 DEBUG(id_,
2827 "Legacy advertising ignored by scanner because the directed "
2828 "address {} does not match the current device or is not a "
2829 "resovable private address",
2830 target_address);
2831 return;
2832 }
2833 should_send_directed_advertising_report =
2834 target_address.IsRpa() &&
2835 !ResolveTargetA(target_address, resolved_advertising_address);
2836 break;
2837 }
2838 }
2839
2840 bool should_send_advertising_report = true;
2841 if (scanner_.filter_duplicates != bluetooth::hci::FilterDuplicates::DISABLED) {
2842 if (scanner_.IsPacketInHistory(pdu.bytes())) {
2843 should_send_advertising_report = false;
2844 } else {
2845 scanner_.AddPacketToHistory(pdu.bytes());
2846 }
2847 }
2848
2849 // Legacy scanning, directed advertising.
2850 if (LegacyAdvertising() && should_send_advertising_report &&
2851 should_send_directed_advertising_report &&
2852 IsLeEventUnmasked(SubeventCode::LE_DIRECTED_ADVERTISING_REPORT)) {
2853 bluetooth::hci::LeDirectedAdvertisingResponse response;
2854 response.event_type_ = bluetooth::hci::DirectAdvertisingEventType::ADV_DIRECT_IND;
2855 response.address_type_ = static_cast<bluetooth::hci::DirectAdvertisingAddressType>(
2856 resolved_advertising_address.GetAddressType());
2857 response.address_ = resolved_advertising_address.GetAddress();
2858 response.direct_address_type_ = bluetooth::hci::DirectAddressType::RANDOM_DEVICE_ADDRESS;
2859 response.direct_address_ = target_address.GetAddress();
2860 response.rssi_ = rssi;
2861
2862 send_event_(bluetooth::hci::LeDirectedAdvertisingReportBuilder::Create({response}));
2863 }
2864
2865 // Legacy scanning, un-directed advertising.
2866 if (LegacyAdvertising() && should_send_advertising_report &&
2867 !should_send_directed_advertising_report &&
2868 IsLeEventUnmasked(SubeventCode::LE_ADVERTISING_REPORT)) {
2869 bluetooth::hci::LeAdvertisingResponse response;
2870 response.address_type_ = resolved_advertising_address.GetAddressType();
2871 response.address_ = resolved_advertising_address.GetAddress();
2872 response.advertising_data_ = advertising_data;
2873 response.rssi_ = rssi;
2874
2875 switch (advertising_type) {
2876 case model::packets::LegacyAdvertisingType::ADV_IND:
2877 response.event_type_ = bluetooth::hci::AdvertisingEventType::ADV_IND;
2878 break;
2879 case model::packets::LegacyAdvertisingType::ADV_DIRECT_IND:
2880 response.event_type_ = bluetooth::hci::AdvertisingEventType::ADV_DIRECT_IND;
2881 break;
2882 case model::packets::LegacyAdvertisingType::ADV_SCAN_IND:
2883 response.event_type_ = bluetooth::hci::AdvertisingEventType::ADV_SCAN_IND;
2884 break;
2885 case model::packets::LegacyAdvertisingType::ADV_NONCONN_IND:
2886 response.event_type_ = bluetooth::hci::AdvertisingEventType::ADV_NONCONN_IND;
2887 break;
2888 }
2889
2890 send_event_(bluetooth::hci::LeAdvertisingReportBuilder::Create({response}));
2891 }
2892
2893 // Extended scanning.
2894 if (ExtendedAdvertising() && should_send_advertising_report &&
2895 IsLeEventUnmasked(SubeventCode::LE_EXTENDED_ADVERTISING_REPORT)) {
2896 bluetooth::hci::LeExtendedAdvertisingResponse response;
2897 response.connectable_ = connectable_advertising;
2898 response.scannable_ = scannable_advertising;
2899 response.directed_ = directed_advertising;
2900 response.scan_response_ = false;
2901 response.legacy_ = true;
2902 response.data_status_ = bluetooth::hci::DataStatus::COMPLETE;
2903 response.address_type_ = static_cast<bluetooth::hci::DirectAdvertisingAddressType>(
2904 resolved_advertising_address.GetAddressType());
2905 response.address_ = resolved_advertising_address.GetAddress();
2906 response.primary_phy_ = bluetooth::hci::PrimaryPhyType::LE_1M;
2907 response.secondary_phy_ = bluetooth::hci::SecondaryPhyType::NO_PACKETS;
2908 response.advertising_sid_ = 0xff; // ADI not provided.
2909 response.tx_power_ = 0x7f; // TX power information not available.
2910 response.rssi_ = rssi;
2911 response.periodic_advertising_interval_ = 0; // No periodic advertising.
2912 if (directed_advertising) {
2913 response.direct_address_type_ =
2914 bluetooth::hci::DirectAdvertisingAddressType(target_address.GetAddressType());
2915 response.direct_address_ = target_address.GetAddress();
2916 } else {
2917 response.direct_address_type_ =
2918 bluetooth::hci::DirectAdvertisingAddressType::NO_ADDRESS_PROVIDED;
2919 response.direct_address_ = Address::kEmpty;
2920 }
2921 response.advertising_data_ = advertising_data;
2922
2923 send_event_(bluetooth::hci::LeExtendedAdvertisingReportBuilder::Create({response}));
2924 }
2925
2926 // Did the user enable Active scanning ?
2927 bool active_scanning = (scanner_.le_1m_phy.enabled &&
2928 scanner_.le_1m_phy.scan_type == bluetooth::hci::LeScanType::ACTIVE) ||
2929 (scanner_.le_coded_phy.enabled &&
2930 scanner_.le_coded_phy.scan_type == bluetooth::hci::LeScanType::ACTIVE);
2931
2932 // Active scanning.
2933 // Note: only send SCAN requests in response to scannable advertising
2934 // events (ADV_IND, ADV_SCAN_IND).
2935 if (!scannable_advertising) {
2936 DEBUG(id_,
2937 "Not sending LE Scan request to advertising address {} because "
2938 "it is not scannable",
2939 advertising_address);
2940 } else if (!active_scanning) {
2941 DEBUG(id_,
2942 "Not sending LE Scan request to advertising address {} because "
2943 "the scanner is passive",
2944 advertising_address);
2945 } else if (scanner_.pending_scan_request) {
2946 DEBUG(id_,
2947 "Not sending LE Scan request to advertising address {} because "
2948 "an LE Scan request is already pending",
2949 advertising_address);
2950 } else if (!should_send_advertising_report) {
2951 DEBUG(id_,
2952 "Not sending LE Scan request to advertising address {} because "
2953 "the advertising message was filtered",
2954 advertising_address);
2955 } else {
2956 // TODO: apply privacy mode in resolving list.
2957 // Scan requests with public or random device addresses must be ignored
2958 // when the peer has network privacy mode.
2959
2960 AddressWithType public_address{address_, AddressType::PUBLIC_DEVICE_ADDRESS};
2961 AddressWithType random_address{random_address_, AddressType::RANDOM_DEVICE_ADDRESS};
2962 std::optional<AddressWithType> resolvable_scanning_address =
2963 GenerateResolvablePrivateAddress(resolved_advertising_address, IrkSelection::Local);
2964
2965 // The ScanA field of the scanning PDU is generated using the
2966 // Resolving List’s Local IRK value and the Resolvable Private Address
2967 // Generation procedure (see Section 1.3.2.2), or the address is provided
2968 // by the Host.
2969 AddressWithType scanning_address;
2970 switch (scanner_.own_address_type) {
2971 case bluetooth::hci::OwnAddressType::PUBLIC_DEVICE_ADDRESS:
2972 scanning_address = public_address;
2973 break;
2974 case bluetooth::hci::OwnAddressType::RANDOM_DEVICE_ADDRESS:
2975 // The random address is checked in Le_Set_Scan_Enable or
2976 // Le_Set_Extended_Scan_Enable.
2977 ASSERT(random_address_ != Address::kEmpty);
2978 scanning_address = random_address;
2979 break;
2980 case bluetooth::hci::OwnAddressType::RESOLVABLE_OR_PUBLIC_ADDRESS:
2981 scanning_address = resolvable_scanning_address.value_or(public_address);
2982 break;
2983 case bluetooth::hci::OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS:
2984 // The random address is checked in Le_Set_Scan_Enable or
2985 // Le_Set_Extended_Scan_Enable.
2986 ASSERT(random_address_ != Address::kEmpty);
2987 scanning_address = resolvable_scanning_address.value_or(random_address);
2988 break;
2989 }
2990
2991 // Save the original advertising type to report if the advertising
2992 // is connectable in the scan response report.
2993 scanner_.connectable_scan_response = connectable_advertising;
2994 scanner_.extended_scan_response = false;
2995 scanner_.primary_scan_response_phy = model::packets::PhyType::LE_1M;
2996 scanner_.secondary_scan_response_phy = model::packets::PhyType::NO_PACKETS;
2997 scanner_.pending_scan_request = advertising_address;
2998 scanner_.pending_scan_request_timeout = std::chrono::steady_clock::now() + kScanRequestTimeout;
2999
3000 INFO(id_,
3001 "Sending LE Scan request to advertising address {} with scanning "
3002 "address {}",
3003 advertising_address, scanning_address);
3004
3005 // The advertiser’s device address (AdvA field) in the scan request PDU
3006 // shall be the same as the advertiser’s device address (AdvA field)
3007 // received in the advertising PDU to which the scanner is responding.
3008 SendLeLinkLayerPacket(model::packets::LeScanBuilder::Create(
3009 scanning_address.GetAddress(), advertising_address.GetAddress(),
3010 static_cast<model::packets::AddressType>(scanning_address.GetAddressType()),
3011 static_cast<model::packets::AddressType>(advertising_address.GetAddressType())));
3012 }
3013 }
3014
ConnectIncomingLeLegacyAdvertisingPdu(model::packets::LeLegacyAdvertisingPduView & pdu)3015 void LinkLayerController::ConnectIncomingLeLegacyAdvertisingPdu(
3016 model::packets::LeLegacyAdvertisingPduView& pdu) {
3017 if (!initiator_.IsEnabled()) {
3018 return;
3019 }
3020
3021 auto advertising_type = pdu.GetAdvertisingType();
3022 bool connectable_advertising =
3023 advertising_type == model::packets::LegacyAdvertisingType::ADV_IND ||
3024 advertising_type == model::packets::LegacyAdvertisingType::ADV_DIRECT_IND;
3025 bool directed_advertising =
3026 advertising_type == model::packets::LegacyAdvertisingType::ADV_DIRECT_IND;
3027
3028 // Connection.
3029 // Note: only send CONNECT requests in response to connectable advertising
3030 // events (ADV_IND, ADV_DIRECT_IND).
3031 if (!connectable_advertising) {
3032 DEBUG(id_,
3033 "Legacy advertising ignored by initiator because it is not "
3034 "connectable");
3035 return;
3036 }
3037 if (initiator_.pending_connect_request) {
3038 DEBUG(id_,
3039 "Legacy advertising ignored because an LE Connect request is already "
3040 "pending");
3041 return;
3042 }
3043
3044 AddressWithType advertising_address{pdu.GetSourceAddress(),
3045 static_cast<AddressType>(pdu.GetAdvertisingAddressType())};
3046
3047 AddressWithType target_address{pdu.GetDestinationAddress(),
3048 static_cast<AddressType>(pdu.GetTargetAddressType())};
3049
3050 AddressWithType resolved_advertising_address =
3051 ResolvePrivateAddress(advertising_address).value_or(advertising_address);
3052
3053 // Vol 6, Part B § 4.3.5 Initiator filter policy.
3054 switch (initiator_.initiator_filter_policy) {
3055 case bluetooth::hci::InitiatorFilterPolicy::USE_PEER_ADDRESS:
3056 if (resolved_advertising_address != initiator_.peer_address) {
3057 DEBUG(id_,
3058 "Legacy advertising ignored by initiator because the "
3059 "advertising address {} does not match the peer address {}",
3060 resolved_advertising_address, initiator_.peer_address);
3061 return;
3062 }
3063 break;
3064 case bluetooth::hci::InitiatorFilterPolicy::USE_FILTER_ACCEPT_LIST_WITH_PEER_ADDRESS:
3065 if (!LeFilterAcceptListContainsDevice(resolved_advertising_address)) {
3066 DEBUG(id_,
3067 "Legacy advertising ignored by initiator because the "
3068 "advertising address {} is not in the filter accept list",
3069 resolved_advertising_address);
3070 return;
3071 }
3072 break;
3073 case bluetooth::hci::InitiatorFilterPolicy::USE_DECISION_PDUS:
3074 case bluetooth::hci::InitiatorFilterPolicy::USE_FILTER_ACCEPT_LIST_WITH_DECISION_PDUS:
3075 DEBUG(id_,
3076 "Legacy advertising ignored by initiated because the "
3077 "initiator filter policy is unsupported");
3078 return;
3079 }
3080
3081 // When an initiator receives a directed connectable advertising event that
3082 // contains a resolvable private address for the target’s address
3083 // (TargetA field) and address resolution is enabled, the Link Layer shall
3084 // resolve the private address using the resolving list’s Local IRK values.
3085 // An initiator that has been instructed by the Host to use Resolvable Private
3086 // Addresses shall not respond to directed connectable advertising events that
3087 // contain Public or Static addresses for the target’s address (TargetA
3088 // field).
3089 if (directed_advertising) {
3090 if (!ValidateTargetA(target_address, resolved_advertising_address)) {
3091 DEBUG(id_,
3092 "Directed legacy advertising ignored by initiator because the "
3093 "target address {} does not match the current device addresses",
3094 target_address);
3095 return;
3096 }
3097 if (!target_address.IsRpa() &&
3098 (initiator_.own_address_type == OwnAddressType::RESOLVABLE_OR_PUBLIC_ADDRESS ||
3099 initiator_.own_address_type == OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS)) {
3100 DEBUG(id_,
3101 "Directed legacy advertising ignored by initiator because the "
3102 "target address {} is static or public and the initiator is "
3103 "configured to use resolvable addresses",
3104 target_address);
3105 return;
3106 }
3107 }
3108
3109 AddressWithType public_address{address_, AddressType::PUBLIC_DEVICE_ADDRESS};
3110 AddressWithType random_address{random_address_, AddressType::RANDOM_DEVICE_ADDRESS};
3111 std::optional<AddressWithType> resolvable_initiating_address =
3112 GenerateResolvablePrivateAddress(resolved_advertising_address, IrkSelection::Local);
3113
3114 // The Link Layer shall use resolvable private addresses for the initiator’s
3115 // device address (InitA field) when initiating connection establishment with
3116 // an associated device that exists in the Resolving List.
3117 AddressWithType initiating_address;
3118 switch (initiator_.own_address_type) {
3119 case bluetooth::hci::OwnAddressType::PUBLIC_DEVICE_ADDRESS:
3120 initiating_address = public_address;
3121 break;
3122 case bluetooth::hci::OwnAddressType::RANDOM_DEVICE_ADDRESS:
3123 // The random address is checked in Le_Create_Connection or
3124 // Le_Extended_Create_Connection.
3125 ASSERT(random_address_ != Address::kEmpty);
3126 initiating_address = random_address;
3127 break;
3128 case bluetooth::hci::OwnAddressType::RESOLVABLE_OR_PUBLIC_ADDRESS:
3129 initiating_address = resolvable_initiating_address.value_or(public_address);
3130 break;
3131 case bluetooth::hci::OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS:
3132 // The random address is checked in Le_Create_Connection or
3133 // Le_Extended_Create_Connection.
3134 ASSERT(random_address_ != Address::kEmpty);
3135 initiating_address = resolvable_initiating_address.value_or(random_address);
3136 break;
3137 }
3138
3139 if (!connections_.CreatePendingLeConnection(advertising_address,
3140 resolved_advertising_address != advertising_address
3141 ? resolved_advertising_address
3142 : AddressWithType{},
3143 initiating_address)) {
3144 WARNING(id_, "CreatePendingLeConnection failed for connection to {}", advertising_address);
3145 }
3146
3147 initiator_.pending_connect_request = advertising_address;
3148 initiator_.initiating_address = initiating_address.GetAddress();
3149
3150 INFO(id_, "Sending LE Connect request to {} with initiating address {}",
3151 resolved_advertising_address, initiating_address);
3152
3153 // The advertiser’s device address (AdvA field) in the initiating PDU
3154 // shall be the same as the advertiser’s device address (AdvA field)
3155 // received in the advertising event PDU to which the initiator is
3156 // responding.
3157 SendLeLinkLayerPacket(model::packets::LeConnectBuilder::Create(
3158 initiating_address.GetAddress(), advertising_address.GetAddress(),
3159 static_cast<model::packets::AddressType>(initiating_address.GetAddressType()),
3160 static_cast<model::packets::AddressType>(advertising_address.GetAddressType()),
3161 // The connection is created with the highest allowed
3162 // value for the connection interval and the latency.
3163 initiator_.le_1m_phy.connection_interval_max, initiator_.le_1m_phy.max_latency,
3164 initiator_.le_1m_phy.supervision_timeout));
3165 }
3166
IncomingLeLegacyAdvertisingPdu(model::packets::LinkLayerPacketView incoming,uint8_t rssi)3167 void LinkLayerController::IncomingLeLegacyAdvertisingPdu(
3168 model::packets::LinkLayerPacketView incoming, uint8_t rssi) {
3169 auto pdu = model::packets::LeLegacyAdvertisingPduView::Create(incoming);
3170 ASSERT(pdu.IsValid());
3171
3172 ScanIncomingLeLegacyAdvertisingPdu(pdu, rssi);
3173 ConnectIncomingLeLegacyAdvertisingPdu(pdu);
3174 }
3175
3176 // Handle legacy advertising PDUs while in the Scanning state.
ScanIncomingLeExtendedAdvertisingPdu(model::packets::LeExtendedAdvertisingPduView & pdu,uint8_t rssi)3177 void LinkLayerController::ScanIncomingLeExtendedAdvertisingPdu(
3178 model::packets::LeExtendedAdvertisingPduView& pdu, uint8_t rssi) {
3179 if (!scanner_.IsEnabled()) {
3180 return;
3181 }
3182 if (!ExtendedAdvertising()) {
3183 DEBUG(id_, "Extended advertising ignored because the scanner is legacy");
3184 return;
3185 }
3186
3187 std::vector<uint8_t> advertising_data = pdu.GetAdvertisingData();
3188 AddressWithType advertising_address{pdu.GetSourceAddress(),
3189 static_cast<AddressType>(pdu.GetAdvertisingAddressType())};
3190
3191 AddressWithType target_address{pdu.GetDestinationAddress(),
3192 static_cast<AddressType>(pdu.GetTargetAddressType())};
3193
3194 bool scannable_advertising = pdu.GetScannable();
3195 bool connectable_advertising = pdu.GetConnectable();
3196 bool directed_advertising = pdu.GetDirected();
3197 auto primary_phy = pdu.GetPrimaryPhy();
3198 auto secondary_phy = pdu.GetSecondaryPhy();
3199
3200 // Check originating primary PHY, compare against active scanning PHYs.
3201 if ((primary_phy == model::packets::PhyType::LE_1M && !scanner_.le_1m_phy.enabled) ||
3202 (primary_phy == model::packets::PhyType::LE_CODED_S8 && !scanner_.le_coded_phy.enabled)) {
3203 DEBUG(id_,
3204 "Extended adverising ignored because the scanner is not scanning on "
3205 "the primary phy type {}",
3206 model::packets::PhyTypeText(primary_phy));
3207 return;
3208 }
3209
3210 // Check originating sceondary PHY, compare against local
3211 // supported features. The primary PHY is validated by the command
3212 // LE Set Extended Scan Parameters.
3213 if ((secondary_phy == model::packets::PhyType::LE_2M &&
3214 !properties_.SupportsLLFeature(bluetooth::hci::LLFeaturesBits::LE_2M_PHY)) ||
3215 (secondary_phy == model::packets::PhyType::LE_CODED_S8 &&
3216 !properties_.SupportsLLFeature(bluetooth::hci::LLFeaturesBits::LE_CODED_PHY)) ||
3217 (secondary_phy == model::packets::PhyType::LE_CODED_S2 &&
3218 !properties_.SupportsLLFeature(bluetooth::hci::LLFeaturesBits::LE_CODED_PHY))) {
3219 DEBUG(id_,
3220 "Extended adverising ignored because the scanner does not support "
3221 "the secondary phy type {}",
3222 model::packets::PhyTypeText(secondary_phy));
3223 return;
3224 }
3225
3226 // When a scanner receives an advertising packet that contains a resolvable
3227 // private address for the advertiser’s device address (AdvA field) and
3228 // address resolution is enabled, the Link Layer shall resolve the private
3229 // address. The scanner’s filter policy shall then determine if the scanner
3230 // responds with a scan request.
3231 AddressWithType resolved_advertising_address =
3232 ResolvePrivateAddress(advertising_address).value_or(advertising_address);
3233
3234 if (resolved_advertising_address != advertising_address) {
3235 DEBUG(id_, "Resolved the advertising address {} to {}", advertising_address,
3236 bluetooth::hci::AddressTypeText(advertising_address.GetAddressType()),
3237 resolved_advertising_address,
3238 bluetooth::hci::AddressTypeText(resolved_advertising_address.GetAddressType()));
3239 }
3240
3241 // Vol 6, Part B § 4.3.3 Scanner filter policy
3242 switch (scanner_.scan_filter_policy) {
3243 case bluetooth::hci::LeScanningFilterPolicy::ACCEPT_ALL:
3244 case bluetooth::hci::LeScanningFilterPolicy::CHECK_INITIATORS_IDENTITY:
3245 break;
3246 case bluetooth::hci::LeScanningFilterPolicy::FILTER_ACCEPT_LIST_ONLY:
3247 case bluetooth::hci::LeScanningFilterPolicy::FILTER_ACCEPT_LIST_AND_INITIATORS_IDENTITY:
3248 if (!LeFilterAcceptListContainsDevice(resolved_advertising_address)) {
3249 DEBUG(id_,
3250 "Extended advertising ignored by scanner because the advertising "
3251 "address {} is not in the filter accept list",
3252 resolved_advertising_address);
3253 return;
3254 }
3255 break;
3256 }
3257
3258 if (directed_advertising) {
3259 switch (scanner_.scan_filter_policy) {
3260 // In both basic scanner filter policy modes, a directed advertising PDU
3261 // shall be ignored unless either:
3262 // • the TargetA field is identical to the scanner's device address, or
3263 // • the TargetA field is a resolvable private address, address
3264 // resolution is enabled, and the address is resolved successfully
3265 case bluetooth::hci::LeScanningFilterPolicy::ACCEPT_ALL:
3266 case bluetooth::hci::LeScanningFilterPolicy::FILTER_ACCEPT_LIST_ONLY:
3267 if (!ValidateTargetA(target_address, resolved_advertising_address)) {
3268 DEBUG(id_,
3269 "Extended advertising ignored by scanner because the directed "
3270 "address {} does not match the current device or cannot be "
3271 "resolved",
3272 target_address);
3273 return;
3274 }
3275 break;
3276 // These are identical to the basic modes except
3277 // that a directed advertising PDU shall be ignored unless either:
3278 // • the TargetA field is identical to the scanner's device address, or
3279 // • the TargetA field is a resolvable private address.
3280 case bluetooth::hci::LeScanningFilterPolicy::CHECK_INITIATORS_IDENTITY:
3281 case bluetooth::hci::LeScanningFilterPolicy::FILTER_ACCEPT_LIST_AND_INITIATORS_IDENTITY:
3282 if (!IsLocalPublicOrRandomAddress(target_address) && !target_address.IsRpa()) {
3283 DEBUG(id_,
3284 "Extended advertising ignored by scanner because the directed "
3285 "address {} does not match the current device or is not a "
3286 "resovable private address",
3287 target_address);
3288 return;
3289 }
3290 break;
3291 }
3292 }
3293
3294 bool should_send_advertising_report = true;
3295 if (scanner_.filter_duplicates != bluetooth::hci::FilterDuplicates::DISABLED) {
3296 if (scanner_.IsPacketInHistory(pdu.bytes())) {
3297 should_send_advertising_report = false;
3298 } else {
3299 scanner_.AddPacketToHistory(pdu.bytes());
3300 }
3301 }
3302
3303 if (should_send_advertising_report &&
3304 IsLeEventUnmasked(SubeventCode::LE_EXTENDED_ADVERTISING_REPORT)) {
3305 bluetooth::hci::LeExtendedAdvertisingResponse response;
3306 response.connectable_ = connectable_advertising;
3307 response.scannable_ = scannable_advertising;
3308 response.directed_ = directed_advertising;
3309 response.scan_response_ = false;
3310 response.legacy_ = false;
3311 response.data_status_ = bluetooth::hci::DataStatus::COMPLETE;
3312 response.address_type_ = static_cast<bluetooth::hci::DirectAdvertisingAddressType>(
3313 resolved_advertising_address.GetAddressType());
3314 response.address_ = resolved_advertising_address.GetAddress();
3315 response.primary_phy_ = static_cast<bluetooth::hci::PrimaryPhyType>(primary_phy);
3316 response.secondary_phy_ = static_cast<bluetooth::hci::SecondaryPhyType>(secondary_phy);
3317 response.advertising_sid_ = pdu.GetSid();
3318 response.tx_power_ = pdu.GetTxPower();
3319 response.rssi_ = rssi;
3320 response.periodic_advertising_interval_ = pdu.GetPeriodicAdvertisingInterval();
3321 if (directed_advertising) {
3322 response.direct_address_type_ =
3323 bluetooth::hci::DirectAdvertisingAddressType(target_address.GetAddressType());
3324 response.direct_address_ = target_address.GetAddress();
3325 } else {
3326 response.direct_address_type_ =
3327 bluetooth::hci::DirectAdvertisingAddressType::NO_ADDRESS_PROVIDED;
3328 response.direct_address_ = Address::kEmpty;
3329 }
3330 response.advertising_data_ = advertising_data;
3331
3332 // Each extended advertising report can only pass 229 bytes of
3333 // advertising data (255 - size of report fields).
3334 // RootCanal must fragment the report as necessary.
3335 const size_t max_fragment_size = 229;
3336 size_t offset = 0;
3337 do {
3338 size_t remaining_size = advertising_data.size() - offset;
3339 size_t fragment_size = std::min(max_fragment_size, remaining_size);
3340 response.data_status_ = remaining_size <= max_fragment_size
3341 ? bluetooth::hci::DataStatus::COMPLETE
3342 : bluetooth::hci::DataStatus::CONTINUING;
3343 response.advertising_data_ = std::vector(advertising_data.begin() + offset,
3344 advertising_data.begin() + offset + fragment_size);
3345 offset += fragment_size;
3346 send_event_(bluetooth::hci::LeExtendedAdvertisingReportBuilder::Create({response}));
3347 } while (offset < advertising_data.size());
3348 }
3349
3350 // Did the user enable Active scanning ?
3351 bool active_scanning = (scanner_.le_1m_phy.enabled &&
3352 scanner_.le_1m_phy.scan_type == bluetooth::hci::LeScanType::ACTIVE) ||
3353 (scanner_.le_coded_phy.enabled &&
3354 scanner_.le_coded_phy.scan_type == bluetooth::hci::LeScanType::ACTIVE);
3355
3356 // Active scanning.
3357 // Note: only send SCAN requests in response to scannable advertising
3358 // events (ADV_IND, ADV_SCAN_IND).
3359 if (!scannable_advertising) {
3360 DEBUG(id_,
3361 "Not sending LE Scan request to advertising address {} because "
3362 "it is not scannable",
3363 advertising_address);
3364 } else if (!active_scanning) {
3365 DEBUG(id_,
3366 "Not sending LE Scan request to advertising address {} because "
3367 "the scanner is passive",
3368 advertising_address);
3369 } else if (scanner_.pending_scan_request) {
3370 DEBUG(id_,
3371 "Not sending LE Scan request to advertising address {} because "
3372 "an LE Scan request is already pending",
3373 advertising_address);
3374 } else if (!should_send_advertising_report) {
3375 DEBUG(id_,
3376 "Not sending LE Scan request to advertising address {} because "
3377 "the advertising message was filtered",
3378 advertising_address);
3379 } else {
3380 // TODO: apply privacy mode in resolving list.
3381 // Scan requests with public or random device addresses must be ignored
3382 // when the peer has network privacy mode.
3383
3384 AddressWithType public_address{address_, AddressType::PUBLIC_DEVICE_ADDRESS};
3385 AddressWithType random_address{random_address_, AddressType::RANDOM_DEVICE_ADDRESS};
3386 std::optional<AddressWithType> resolvable_address =
3387 GenerateResolvablePrivateAddress(resolved_advertising_address, IrkSelection::Local);
3388
3389 // The ScanA field of the scanning PDU is generated using the
3390 // Resolving List’s Local IRK value and the Resolvable Private Address
3391 // Generation procedure (see Section 1.3.2.2), or the address is provided
3392 // by the Host.
3393 AddressWithType scanning_address;
3394 std::optional<AddressWithType> resolvable_scanning_address;
3395 switch (scanner_.own_address_type) {
3396 case bluetooth::hci::OwnAddressType::PUBLIC_DEVICE_ADDRESS:
3397 scanning_address = public_address;
3398 break;
3399 case bluetooth::hci::OwnAddressType::RANDOM_DEVICE_ADDRESS:
3400 // The random address is checked in Le_Set_Scan_Enable or
3401 // Le_Set_Extended_Scan_Enable.
3402 ASSERT(random_address_ != Address::kEmpty);
3403 scanning_address = random_address;
3404 break;
3405 case bluetooth::hci::OwnAddressType::RESOLVABLE_OR_PUBLIC_ADDRESS:
3406 scanning_address = resolvable_address.value_or(public_address);
3407 break;
3408 case bluetooth::hci::OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS:
3409 // The random address is checked in Le_Set_Scan_Enable or
3410 // Le_Set_Extended_Scan_Enable.
3411 ASSERT(random_address_ != Address::kEmpty);
3412 scanning_address = resolvable_address.value_or(random_address);
3413 break;
3414 }
3415
3416 // Save the original advertising type to report if the advertising
3417 // is connectable in the scan response report.
3418 scanner_.connectable_scan_response = connectable_advertising;
3419 scanner_.extended_scan_response = true;
3420 scanner_.primary_scan_response_phy = primary_phy;
3421 scanner_.secondary_scan_response_phy = secondary_phy;
3422 scanner_.pending_scan_request = advertising_address;
3423
3424 INFO(id_,
3425 "Sending LE Scan request to advertising address {} with scanning "
3426 "address {}",
3427 advertising_address, scanning_address);
3428
3429 // The advertiser’s device address (AdvA field) in the scan request PDU
3430 // shall be the same as the advertiser’s device address (AdvA field)
3431 // received in the advertising PDU to which the scanner is responding.
3432 SendLeLinkLayerPacket(model::packets::LeScanBuilder::Create(
3433 scanning_address.GetAddress(), advertising_address.GetAddress(),
3434 static_cast<model::packets::AddressType>(scanning_address.GetAddressType()),
3435 static_cast<model::packets::AddressType>(advertising_address.GetAddressType())));
3436 }
3437 }
3438
ConnectIncomingLeExtendedAdvertisingPdu(model::packets::LeExtendedAdvertisingPduView & pdu)3439 void LinkLayerController::ConnectIncomingLeExtendedAdvertisingPdu(
3440 model::packets::LeExtendedAdvertisingPduView& pdu) {
3441 if (!initiator_.IsEnabled()) {
3442 return;
3443 }
3444 if (!ExtendedAdvertising()) {
3445 DEBUG(id_, "Extended advertising ignored because the initiator is legacy");
3446 return;
3447 }
3448
3449 // Connection.
3450 // Note: only send CONNECT requests in response to connectable advertising
3451 // events (ADV_IND, ADV_DIRECT_IND).
3452 if (!pdu.GetConnectable()) {
3453 DEBUG(id_,
3454 "Extended advertising ignored by initiator because it is not "
3455 "connectable");
3456 return;
3457 }
3458 if (initiator_.pending_connect_request) {
3459 DEBUG(id_,
3460 "Extended advertising ignored because an LE Connect request is already "
3461 "pending");
3462 return;
3463 }
3464
3465 AddressWithType advertising_address{pdu.GetSourceAddress(),
3466 static_cast<AddressType>(pdu.GetAdvertisingAddressType())};
3467
3468 AddressWithType target_address{pdu.GetDestinationAddress(),
3469 static_cast<AddressType>(pdu.GetTargetAddressType())};
3470
3471 AddressWithType resolved_advertising_address =
3472 ResolvePrivateAddress(advertising_address).value_or(advertising_address);
3473
3474 // Vol 6, Part B § 4.3.5 Initiator filter policy.
3475 switch (initiator_.initiator_filter_policy) {
3476 case bluetooth::hci::InitiatorFilterPolicy::USE_PEER_ADDRESS:
3477 if (resolved_advertising_address != initiator_.peer_address) {
3478 DEBUG(id_,
3479 "Extended advertising ignored by initiator because the "
3480 "advertising address {} does not match the peer address {}",
3481 resolved_advertising_address, initiator_.peer_address);
3482 return;
3483 }
3484 break;
3485 case bluetooth::hci::InitiatorFilterPolicy::USE_FILTER_ACCEPT_LIST_WITH_PEER_ADDRESS:
3486 if (!LeFilterAcceptListContainsDevice(resolved_advertising_address)) {
3487 DEBUG(id_,
3488 "Extended advertising ignored by initiator because the "
3489 "advertising address {} is not in the filter accept list",
3490 resolved_advertising_address);
3491 return;
3492 }
3493 break;
3494 case bluetooth::hci::InitiatorFilterPolicy::USE_DECISION_PDUS:
3495 case bluetooth::hci::InitiatorFilterPolicy::USE_FILTER_ACCEPT_LIST_WITH_DECISION_PDUS:
3496 DEBUG(id_,
3497 "Extended advertising ignored by initiator because the "
3498 "initiator filter policy is not supported");
3499 return;
3500 }
3501
3502 // When an initiator receives a directed connectable advertising event that
3503 // contains a resolvable private address for the target’s address
3504 // (TargetA field) and address resolution is enabled, the Link Layer shall
3505 // resolve the private address using the resolving list’s Local IRK values.
3506 // An initiator that has been instructed by the Host to use Resolvable Private
3507 // Addresses shall not respond to directed connectable advertising events that
3508 // contain Public or Static addresses for the target’s address (TargetA
3509 // field).
3510 if (pdu.GetDirected()) {
3511 if (!ValidateTargetA(target_address, resolved_advertising_address)) {
3512 DEBUG(id_,
3513 "Directed extended advertising ignored by initiator because the "
3514 "target address {} does not match the current device addresses",
3515 target_address);
3516 return;
3517 }
3518 if (!target_address.IsRpa() &&
3519 (initiator_.own_address_type == OwnAddressType::RESOLVABLE_OR_PUBLIC_ADDRESS ||
3520 initiator_.own_address_type == OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS)) {
3521 DEBUG(id_,
3522 "Directed extended advertising ignored by initiator because the "
3523 "target address {} is static or public and the initiator is "
3524 "configured to use resolvable addresses",
3525 target_address);
3526 return;
3527 }
3528 }
3529
3530 AddressWithType public_address{address_, AddressType::PUBLIC_DEVICE_ADDRESS};
3531 AddressWithType random_address{random_address_, AddressType::RANDOM_DEVICE_ADDRESS};
3532 std::optional<AddressWithType> resolvable_initiating_address =
3533 GenerateResolvablePrivateAddress(resolved_advertising_address, IrkSelection::Local);
3534
3535 // The Link Layer shall use resolvable private addresses for the initiator’s
3536 // device address (InitA field) when initiating connection establishment with
3537 // an associated device that exists in the Resolving List.
3538 AddressWithType initiating_address;
3539 switch (initiator_.own_address_type) {
3540 case bluetooth::hci::OwnAddressType::PUBLIC_DEVICE_ADDRESS:
3541 initiating_address = public_address;
3542 break;
3543 case bluetooth::hci::OwnAddressType::RANDOM_DEVICE_ADDRESS:
3544 // The random address is checked in Le_Create_Connection or
3545 // Le_Extended_Create_Connection.
3546 ASSERT(random_address_ != Address::kEmpty);
3547 initiating_address = random_address;
3548 break;
3549 case bluetooth::hci::OwnAddressType::RESOLVABLE_OR_PUBLIC_ADDRESS:
3550 initiating_address = resolvable_initiating_address.value_or(public_address);
3551 break;
3552 case bluetooth::hci::OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS:
3553 // The random address is checked in Le_Create_Connection or
3554 // Le_Extended_Create_Connection.
3555 ASSERT(random_address_ != Address::kEmpty);
3556 initiating_address = resolvable_initiating_address.value_or(random_address);
3557 break;
3558 }
3559
3560 if (!connections_.CreatePendingLeConnection(advertising_address,
3561 resolved_advertising_address != advertising_address
3562 ? resolved_advertising_address
3563 : AddressWithType{},
3564 initiating_address)) {
3565 WARNING(id_, "CreatePendingLeConnection failed for connection to {}", advertising_address);
3566 }
3567
3568 initiator_.pending_connect_request = advertising_address;
3569 initiator_.initiating_address = initiating_address.GetAddress();
3570
3571 INFO(id_, "Sending LE Connect request to {} with initiating address {}",
3572 resolved_advertising_address, initiating_address);
3573
3574 // The advertiser’s device address (AdvA field) in the initiating PDU
3575 // shall be the same as the advertiser’s device address (AdvA field)
3576 // received in the advertising event PDU to which the initiator is
3577 // responding.
3578 SendLeLinkLayerPacket(model::packets::LeConnectBuilder::Create(
3579 initiating_address.GetAddress(), advertising_address.GetAddress(),
3580 static_cast<model::packets::AddressType>(initiating_address.GetAddressType()),
3581 static_cast<model::packets::AddressType>(advertising_address.GetAddressType()),
3582 // The connection is created with the highest allowed value
3583 // for the connection interval and the latency.
3584 initiator_.le_1m_phy.connection_interval_max, initiator_.le_1m_phy.max_latency,
3585 initiator_.le_1m_phy.supervision_timeout));
3586 }
3587
IncomingLeExtendedAdvertisingPdu(model::packets::LinkLayerPacketView incoming,uint8_t rssi)3588 void LinkLayerController::IncomingLeExtendedAdvertisingPdu(
3589 model::packets::LinkLayerPacketView incoming, uint8_t rssi) {
3590 auto pdu = model::packets::LeExtendedAdvertisingPduView::Create(incoming);
3591 ASSERT(pdu.IsValid());
3592
3593 ScanIncomingLeExtendedAdvertisingPdu(pdu, rssi);
3594 ConnectIncomingLeExtendedAdvertisingPdu(pdu);
3595 }
3596
IncomingLePeriodicAdvertisingPdu(model::packets::LinkLayerPacketView incoming,uint8_t rssi)3597 void LinkLayerController::IncomingLePeriodicAdvertisingPdu(
3598 model::packets::LinkLayerPacketView incoming, uint8_t rssi) {
3599 auto pdu = model::packets::LePeriodicAdvertisingPduView::Create(incoming);
3600 ASSERT(pdu.IsValid());
3601
3602 // Synchronization with periodic advertising only occurs while extended
3603 // scanning is enabled.
3604 if (!scanner_.IsEnabled()) {
3605 return;
3606 }
3607 if (!ExtendedAdvertising()) {
3608 DEBUG(id_, "Extended advertising ignored because the scanner is legacy");
3609 return;
3610 }
3611
3612 AddressWithType advertiser_address{pdu.GetSourceAddress(),
3613 static_cast<AddressType>(pdu.GetAdvertisingAddressType())};
3614 uint8_t advertising_sid = pdu.GetSid();
3615
3616 // When a scanner receives an advertising packet that contains a resolvable
3617 // private address for the advertiser's device address (AdvA field) and
3618 // address resolution is enabled, the Link Layer shall resolve the private
3619 // address. The scanner's periodic sync establishment filter policy shall
3620 // determine if the scanner processes the advertising packet.
3621 AddressWithType resolved_advertiser_address =
3622 ResolvePrivateAddress(advertiser_address).value_or(advertiser_address);
3623
3624 bluetooth::hci::AdvertiserAddressType advertiser_address_type;
3625 switch (resolved_advertiser_address.GetAddressType()) {
3626 case AddressType::PUBLIC_DEVICE_ADDRESS:
3627 case AddressType::PUBLIC_IDENTITY_ADDRESS:
3628 default:
3629 advertiser_address_type =
3630 bluetooth::hci::AdvertiserAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS;
3631 break;
3632 case AddressType::RANDOM_DEVICE_ADDRESS:
3633 case AddressType::RANDOM_IDENTITY_ADDRESS:
3634 advertiser_address_type =
3635 bluetooth::hci::AdvertiserAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS;
3636 break;
3637 }
3638
3639 // Check if the periodic advertising PDU matches a pending
3640 // LE Periodic Advertising Create Sync command.
3641 // The direct parameters or the periodic advertiser list are used
3642 // depending on the synchronizing options.
3643 bool matches_synchronizing = false;
3644 if (synchronizing_.has_value()) {
3645 matches_synchronizing =
3646 synchronizing_->options.use_periodic_advertiser_list_
3647 ? LePeriodicAdvertiserListContainsDevice(
3648 advertiser_address_type, resolved_advertiser_address.GetAddress(),
3649 advertising_sid)
3650 : synchronizing_->advertiser_address_type == advertiser_address_type &&
3651 synchronizing_->advertiser_address ==
3652 resolved_advertiser_address.GetAddress() &&
3653 synchronizing_->advertising_sid == advertising_sid;
3654 }
3655
3656 // If the periodic advertising event matches the synchronizing state,
3657 // create the synchronized train and report to the Host.
3658 if (matches_synchronizing) {
3659 INFO(id_, "Established Sync with advertiser {}[{}] - SID 0x{:x}", advertiser_address,
3660 bluetooth::hci::AdvertiserAddressTypeText(advertiser_address_type), advertising_sid);
3661 // Use the first unused Sync_Handle.
3662 // Note: sync handles are allocated from a different number space
3663 // compared to connection handles.
3664 uint16_t sync_handle = 0;
3665 for (; synchronized_.count(sync_handle) != 0; sync_handle++) {
3666 }
3667
3668 // Notify of the new Synchronized train.
3669 if (IsLeEventUnmasked(SubeventCode::LE_PERIODIC_ADVERTISING_SYNC_ESTABLISHED_V1)) {
3670 send_event_(bluetooth::hci::LePeriodicAdvertisingSyncEstablishedV1Builder::Create(
3671 ErrorCode::SUCCESS, sync_handle, advertising_sid,
3672 resolved_advertiser_address.GetAddressType(),
3673 resolved_advertiser_address.GetAddress(), bluetooth::hci::SecondaryPhyType::LE_1M,
3674 pdu.GetAdvertisingInterval(), bluetooth::hci::ClockAccuracy::PPM_500));
3675 }
3676
3677 // Update the synchronization state.
3678 synchronized_.insert(
3679 {sync_handle,
3680 Synchronized{
3681 .advertiser_address_type = advertiser_address_type,
3682 .advertiser_address = resolved_advertiser_address.GetAddress(),
3683 .advertising_sid = advertising_sid,
3684 .sync_handle = sync_handle,
3685 .sync_timeout = synchronizing_->sync_timeout,
3686 .timeout = std::chrono::steady_clock::now() + synchronizing_->sync_timeout,
3687 }});
3688
3689 // Quit synchronizing state.
3690 synchronizing_ = {};
3691
3692 // Create Sync ensure that they are no other established syncs that
3693 // already match the advertiser address and advertising SID;
3694 // no need to check again.
3695 return;
3696 }
3697
3698 // Check if the periodic advertising PDU matches any of the established
3699 // syncs.
3700 for (auto& [_, sync] : synchronized_) {
3701 if (sync.advertiser_address_type != advertiser_address_type ||
3702 sync.advertiser_address != resolved_advertiser_address.GetAddress() ||
3703 sync.advertising_sid != advertising_sid) {
3704 continue;
3705 }
3706
3707 // Send a Periodic Advertising event for the matching Sync,
3708 // and refresh the timeout for sync termination. The periodic
3709 // advertising event might need to be fragmented to fit the maximum
3710 // size of an HCI event.
3711 if (IsLeEventUnmasked(SubeventCode::LE_PERIODIC_ADVERTISING_REPORT_V1)) {
3712 // Each extended advertising report can only pass 229 bytes of
3713 // advertising data (255 - 8 = size of report fields).
3714 std::vector<uint8_t> advertising_data = pdu.GetAdvertisingData();
3715 const size_t max_fragment_size = 247;
3716 size_t offset = 0;
3717 do {
3718 size_t remaining_size = advertising_data.size() - offset;
3719 size_t fragment_size = std::min(max_fragment_size, remaining_size);
3720
3721 bluetooth::hci::DataStatus data_status = remaining_size <= max_fragment_size
3722 ? bluetooth::hci::DataStatus::COMPLETE
3723 : bluetooth::hci::DataStatus::CONTINUING;
3724 std::vector<uint8_t> fragment_data(advertising_data.begin() + offset,
3725 advertising_data.begin() + offset + fragment_size);
3726 offset += fragment_size;
3727 send_event_(bluetooth::hci::LePeriodicAdvertisingReportV1Builder::Create(
3728 sync.sync_handle, pdu.GetTxPower(), rssi,
3729 bluetooth::hci::CteType::NO_CONSTANT_TONE_EXTENSION, data_status, fragment_data));
3730 } while (offset < advertising_data.size());
3731 }
3732
3733 // Refresh the timeout for the sync disconnection.
3734 sync.timeout = std::chrono::steady_clock::now() + sync.sync_timeout;
3735 }
3736 }
3737
IncomingScoConnectionRequest(model::packets::LinkLayerPacketView incoming)3738 void LinkLayerController::IncomingScoConnectionRequest(
3739 model::packets::LinkLayerPacketView incoming) {
3740 Address address = incoming.GetSourceAddress();
3741 auto request = model::packets::ScoConnectionRequestView::Create(incoming);
3742 ASSERT(request.IsValid());
3743
3744 INFO(id_, "Received eSCO connection request from {}", address);
3745
3746 // Automatically reject if connection request was already sent
3747 // from the current device.
3748 if (connections_.HasPendingScoConnection(address)) {
3749 INFO(id_,
3750 "Rejecting eSCO connection request from {}, "
3751 "an eSCO connection already exist with this device",
3752 address);
3753
3754 SendLinkLayerPacket(model::packets::ScoConnectionResponseBuilder::Create(
3755 GetAddress(), address, (uint8_t)ErrorCode::SYNCHRONOUS_CONNECTION_LIMIT_EXCEEDED, 0, 0,
3756 0, 0, 0, 0));
3757 return;
3758 }
3759
3760 // Create local connection context.
3761 ScoConnectionParameters connection_parameters = {
3762 request.GetTransmitBandwidth(), request.GetReceiveBandwidth(),
3763 request.GetMaxLatency(), request.GetVoiceSetting(),
3764 request.GetRetransmissionEffort(), request.GetPacketType()};
3765
3766 bool extended = connection_parameters.IsExtended();
3767 connections_.CreateScoConnection(address, connection_parameters,
3768 extended ? ScoState::SCO_STATE_SENT_ESCO_CONNECTION_REQUEST
3769 : ScoState::SCO_STATE_SENT_SCO_CONNECTION_REQUEST,
3770 ScoDatapath::NORMAL);
3771
3772 // Send connection request event and wait for Accept or Reject command.
3773 send_event_(bluetooth::hci::ConnectionRequestBuilder::Create(
3774 address, request.GetClassOfDevice(),
3775 extended ? bluetooth::hci::ConnectionRequestLinkType::ESCO
3776 : bluetooth::hci::ConnectionRequestLinkType::SCO));
3777 }
3778
IncomingScoConnectionResponse(model::packets::LinkLayerPacketView incoming)3779 void LinkLayerController::IncomingScoConnectionResponse(
3780 model::packets::LinkLayerPacketView incoming) {
3781 Address address = incoming.GetSourceAddress();
3782 auto response = model::packets::ScoConnectionResponseView::Create(incoming);
3783 ASSERT(response.IsValid());
3784 auto status = ErrorCode(response.GetStatus());
3785 bool is_legacy = connections_.IsLegacyScoConnection(address);
3786
3787 INFO(id_, "Received eSCO connection response with status 0x{:02x} from {}",
3788 static_cast<unsigned>(status), incoming.GetSourceAddress());
3789
3790 if (status == ErrorCode::SUCCESS) {
3791 bool extended = response.GetExtended();
3792 ScoLinkParameters link_parameters = {
3793 response.GetTransmissionInterval(),
3794 response.GetRetransmissionWindow(),
3795 response.GetRxPacketLength(),
3796 response.GetTxPacketLength(),
3797 response.GetAirMode(),
3798 extended,
3799 };
3800
3801 connections_.AcceptPendingScoConnection(address, link_parameters, [this, address] {
3802 return LinkLayerController::StartScoStream(address);
3803 });
3804
3805 if (is_legacy) {
3806 send_event_(bluetooth::hci::ConnectionCompleteBuilder::Create(
3807 ErrorCode::SUCCESS, connections_.GetScoHandle(address), address,
3808 bluetooth::hci::LinkType::SCO, bluetooth::hci::Enable::DISABLED));
3809 } else {
3810 send_event_(bluetooth::hci::SynchronousConnectionCompleteBuilder::Create(
3811 ErrorCode::SUCCESS, connections_.GetScoHandle(address), address,
3812 extended ? bluetooth::hci::ScoLinkType::ESCO : bluetooth::hci::ScoLinkType::SCO,
3813 extended ? response.GetTransmissionInterval() : 0,
3814 extended ? response.GetRetransmissionWindow() : 0,
3815 extended ? response.GetRxPacketLength() : 0,
3816 extended ? response.GetTxPacketLength() : 0,
3817 bluetooth::hci::ScoAirMode(response.GetAirMode())));
3818 }
3819 } else {
3820 connections_.CancelPendingScoConnection(address);
3821 if (is_legacy) {
3822 send_event_(bluetooth::hci::ConnectionCompleteBuilder::Create(
3823 status, 0, address, bluetooth::hci::LinkType::SCO, bluetooth::hci::Enable::DISABLED));
3824 } else {
3825 ScoConnectionParameters connection_parameters =
3826 connections_.GetScoConnectionParameters(address);
3827 send_event_(bluetooth::hci::SynchronousConnectionCompleteBuilder::Create(
3828 status, 0, address,
3829 connection_parameters.IsExtended() ? bluetooth::hci::ScoLinkType::ESCO
3830 : bluetooth::hci::ScoLinkType::SCO,
3831 0, 0, 0, 0, bluetooth::hci::ScoAirMode::TRANSPARENT));
3832 }
3833 }
3834 }
3835
IncomingScoDisconnect(model::packets::LinkLayerPacketView incoming)3836 void LinkLayerController::IncomingScoDisconnect(model::packets::LinkLayerPacketView incoming) {
3837 Address address = incoming.GetSourceAddress();
3838 auto request = model::packets::ScoDisconnectView::Create(incoming);
3839 ASSERT(request.IsValid());
3840 auto reason = request.GetReason();
3841 uint16_t handle = connections_.GetScoHandle(address);
3842
3843 INFO(id_,
3844 "Received eSCO disconnection request with"
3845 " reason 0x{:02x} from {}",
3846 static_cast<unsigned>(reason), incoming.GetSourceAddress());
3847
3848 if (handle != kReservedHandle) {
3849 connections_.Disconnect(handle, [this](TaskId task_id) { CancelScheduledTask(task_id); });
3850 SendDisconnectionCompleteEvent(handle, ErrorCode(reason));
3851 }
3852 }
3853
IncomingLmpPacket(model::packets::LinkLayerPacketView incoming)3854 void LinkLayerController::IncomingLmpPacket(model::packets::LinkLayerPacketView incoming) {
3855 Address address = incoming.GetSourceAddress();
3856 auto request = model::packets::LmpView::Create(incoming);
3857 ASSERT(request.IsValid());
3858 auto payload = request.GetPayload();
3859 auto packet = std::vector(payload.begin(), payload.end());
3860
3861 ASSERT(link_manager_ingest_lmp(lm_.get(), reinterpret_cast<uint8_t(*)[6]>(address.data()),
3862 packet.data(), packet.size()));
3863 }
3864
IncomingLlcpPacket(model::packets::LinkLayerPacketView incoming)3865 void LinkLayerController::IncomingLlcpPacket(model::packets::LinkLayerPacketView incoming) {
3866 Address address = incoming.GetSourceAddress();
3867 auto request = model::packets::LlcpView::Create(incoming);
3868 ASSERT(request.IsValid());
3869 auto payload = request.GetPayload();
3870 auto packet = std::vector(payload.begin(), payload.end());
3871 uint16_t acl_connection_handle = connections_.GetHandleOnlyAddress(address);
3872
3873 if (acl_connection_handle == kReservedHandle) {
3874 INFO(id_, "Dropping LLCP packet since connection does not exist");
3875 return;
3876 }
3877
3878 ASSERT(link_layer_ingest_llcp(ll_.get(), acl_connection_handle, packet.data(), packet.size()));
3879 }
3880
IncomingLeConnectedIsochronousPdu(LinkLayerPacketView incoming)3881 void LinkLayerController::IncomingLeConnectedIsochronousPdu(LinkLayerPacketView incoming) {
3882 auto pdu = model::packets::LeConnectedIsochronousPduView::Create(incoming);
3883 ASSERT(pdu.IsValid());
3884 auto data = pdu.GetData();
3885 auto packet = std::vector(data.begin(), data.end());
3886 uint8_t cig_id = pdu.GetCigId();
3887 uint8_t cis_id = pdu.GetCisId();
3888 uint16_t cis_connection_handle = 0;
3889 uint16_t iso_sdu_length = packet.size();
3890
3891 if (!link_layer_get_cis_connection_handle(ll_.get(), cig_id, cis_id, &cis_connection_handle)) {
3892 INFO(id_, "Dropping CIS pdu received on disconnected CIS cig_id={}, cis_id={}", cig_id, cis_id);
3893 return;
3894 }
3895
3896 // Fragment the ISO SDU if larger than the maximum payload size (4095).
3897 constexpr size_t kMaxPayloadSize = 4095 - 4; // remove sequence_number and
3898 // iso_sdu_length
3899 size_t remaining_size = packet.size();
3900 size_t offset = 0;
3901 auto packet_boundary_flag = remaining_size <= kMaxPayloadSize
3902 ? bluetooth::hci::IsoPacketBoundaryFlag::COMPLETE_SDU
3903 : bluetooth::hci::IsoPacketBoundaryFlag::FIRST_FRAGMENT;
3904
3905 do {
3906 size_t fragment_size = std::min(kMaxPayloadSize, remaining_size);
3907 std::vector<uint8_t> fragment(packet.data() + offset, packet.data() + offset + fragment_size);
3908
3909 send_iso_(bluetooth::hci::IsoWithoutTimestampBuilder::Create(
3910 cis_connection_handle, packet_boundary_flag, pdu.GetSequenceNumber(), iso_sdu_length,
3911 bluetooth::hci::IsoPacketStatusFlag::VALID, std::move(fragment)));
3912
3913 remaining_size -= fragment_size;
3914 offset += fragment_size;
3915 packet_boundary_flag = remaining_size <= kMaxPayloadSize
3916 ? bluetooth::hci::IsoPacketBoundaryFlag::LAST_FRAGMENT
3917 : bluetooth::hci::IsoPacketBoundaryFlag::CONTINUATION_FRAGMENT;
3918 } while (remaining_size > 0);
3919 }
3920
HandleIso(bluetooth::hci::IsoView iso)3921 void LinkLayerController::HandleIso(bluetooth::hci::IsoView iso) {
3922 uint16_t cis_connection_handle = iso.GetConnectionHandle();
3923 auto pb_flag = iso.GetPbFlag();
3924 auto ts_flag = iso.GetTsFlag();
3925 auto iso_data_load = iso.GetPayload();
3926
3927 // In the Host to Controller direction, ISO_Data_Load_Length
3928 // shall be less than or equal to the size of the buffer supported by the
3929 // Controller (which is returned using the ISO_Data_Packet_Length return
3930 // parameter of the LE Read Buffer Size command).
3931 if (iso_data_load.size() > properties_.iso_data_packet_length) {
3932 FATAL(id_,
3933 "Received ISO HCI packet with ISO_Data_Load_Length ({}) larger than"
3934 " the controller buffer size ISO_Data_Packet_Length ({})",
3935 iso_data_load.size(), properties_.iso_data_packet_length);
3936 }
3937
3938 // The TS_Flag bit shall only be set if the PB_Flag field equals 0b00 or 0b10.
3939 if (ts_flag == bluetooth::hci::TimeStampFlag::PRESENT &&
3940 (pb_flag == bluetooth::hci::IsoPacketBoundaryFlag::CONTINUATION_FRAGMENT ||
3941 pb_flag == bluetooth::hci::IsoPacketBoundaryFlag::LAST_FRAGMENT)) {
3942 FATAL(id_,
3943 "Received ISO HCI packet with TS_Flag set, but no ISO Header is "
3944 "expected");
3945 }
3946
3947 uint8_t cig_id = 0;
3948 uint8_t cis_id = 0;
3949 uint16_t acl_connection_handle = kReservedHandle;
3950 uint16_t packet_sequence_number = 0;
3951 uint16_t max_sdu_length = 0;
3952
3953 if (!link_layer_get_cis_information(ll_.get(), cis_connection_handle, &acl_connection_handle,
3954 &cig_id, &cis_id, &max_sdu_length)) {
3955 INFO(id_, "Ignoring CIS pdu received on disconnected CIS handle={}", cis_connection_handle);
3956 return;
3957 }
3958
3959 if (pb_flag == bluetooth::hci::IsoPacketBoundaryFlag::FIRST_FRAGMENT ||
3960 pb_flag == bluetooth::hci::IsoPacketBoundaryFlag::COMPLETE_SDU) {
3961 iso_sdu_.clear();
3962 }
3963
3964 switch (ts_flag) {
3965 case bluetooth::hci::TimeStampFlag::PRESENT: {
3966 auto iso_with_timestamp = bluetooth::hci::IsoWithTimestampView::Create(iso);
3967 ASSERT(iso_with_timestamp.IsValid());
3968 auto iso_payload = iso_with_timestamp.GetPayload();
3969 iso_sdu_.insert(iso_sdu_.end(), iso_payload.begin(), iso_payload.end());
3970 packet_sequence_number = iso_with_timestamp.GetPacketSequenceNumber();
3971 break;
3972 }
3973 default:
3974 case bluetooth::hci::TimeStampFlag::NOT_PRESENT: {
3975 auto iso_without_timestamp = bluetooth::hci::IsoWithoutTimestampView::Create(iso);
3976 ASSERT(iso_without_timestamp.IsValid());
3977 auto iso_payload = iso_without_timestamp.GetPayload();
3978 iso_sdu_.insert(iso_sdu_.end(), iso_payload.begin(), iso_payload.end());
3979 packet_sequence_number = iso_without_timestamp.GetPacketSequenceNumber();
3980 break;
3981 }
3982 }
3983
3984 if (pb_flag == bluetooth::hci::IsoPacketBoundaryFlag::LAST_FRAGMENT ||
3985 pb_flag == bluetooth::hci::IsoPacketBoundaryFlag::COMPLETE_SDU) {
3986 // Validate that the Host stack is not sending ISO SDUs that are larger
3987 // that what was configured for the CIS.
3988 if (iso_sdu_.size() > max_sdu_length) {
3989 WARNING(id_,
3990 "attempted to send an SDU of length {} that exceeds the configure "
3991 "Max_SDU_Length ({})",
3992 iso_sdu_.size(), max_sdu_length);
3993 return;
3994 }
3995
3996 SendLeLinkLayerPacket(model::packets::LeConnectedIsochronousPduBuilder::Create(
3997 address_, connections_.GetAddress(acl_connection_handle).GetAddress(), cig_id, cis_id,
3998 packet_sequence_number, std::move(iso_sdu_)));
3999 }
4000 }
4001
HandleLeConnection(AddressWithType address,AddressWithType own_address,bluetooth::hci::Role role,uint16_t connection_interval,uint16_t connection_latency,uint16_t supervision_timeout,bool send_le_channel_selection_algorithm_event)4002 uint16_t LinkLayerController::HandleLeConnection(
4003 AddressWithType address, AddressWithType own_address, bluetooth::hci::Role role,
4004 uint16_t connection_interval, uint16_t connection_latency, uint16_t supervision_timeout,
4005 bool send_le_channel_selection_algorithm_event) {
4006 // Note: the HCI_LE_Connection_Complete event is not sent if the
4007 // HCI_LE_Enhanced_Connection_Complete event (see Section 7.7.65.10) is
4008 // unmasked.
4009
4010 uint16_t handle = connections_.CreateLeConnection(address, own_address, role);
4011 if (handle == kReservedHandle) {
4012 WARNING(id_, "No pending connection for connection from {}", address);
4013 return kReservedHandle;
4014 }
4015
4016 if (IsLeEventUnmasked(SubeventCode::LE_ENHANCED_CONNECTION_COMPLETE_V1)) {
4017 AddressWithType peer_resolved_address = connections_.GetResolvedAddress(handle);
4018 Address peer_resolvable_private_address;
4019 Address connection_address = address.GetAddress();
4020 AddressType peer_address_type = address.GetAddressType();
4021 if (peer_resolved_address != AddressWithType()) {
4022 peer_resolvable_private_address = address.GetAddress();
4023 peer_address_type = peer_resolved_address.GetAddressType();
4024 connection_address = peer_resolved_address.GetAddress();
4025 }
4026 Address local_resolved_address = own_address.GetAddress();
4027 if (local_resolved_address == GetAddress() || local_resolved_address == random_address_) {
4028 local_resolved_address = Address::kEmpty;
4029 }
4030
4031 send_event_(bluetooth::hci::LeEnhancedConnectionCompleteV1Builder::Create(
4032 ErrorCode::SUCCESS, handle, role, peer_address_type, connection_address,
4033 local_resolved_address, peer_resolvable_private_address, connection_interval,
4034 connection_latency, supervision_timeout,
4035 static_cast<bluetooth::hci::ClockAccuracy>(0x00)));
4036 } else if (IsLeEventUnmasked(SubeventCode::LE_CONNECTION_COMPLETE)) {
4037 send_event_(bluetooth::hci::LeConnectionCompleteBuilder::Create(
4038 ErrorCode::SUCCESS, handle, role, address.GetAddressType(), address.GetAddress(),
4039 connection_interval, connection_latency, supervision_timeout,
4040 static_cast<bluetooth::hci::ClockAccuracy>(0x00)));
4041 }
4042
4043 // Update the link layer with the new link.
4044 ASSERT(link_layer_add_link(ll_.get(), handle,
4045 reinterpret_cast<const uint8_t(*)[6]>(address.GetAddress().data()),
4046 static_cast<uint8_t>(role)));
4047
4048 // Note: the HCI_LE_Connection_Complete event is immediately followed by
4049 // an HCI_LE_Channel_Selection_Algorithm event if the connection is created
4050 // using the LE_Extended_Create_Connection command (see Section 7.7.8.66).
4051 if (send_le_channel_selection_algorithm_event &&
4052 IsLeEventUnmasked(SubeventCode::LE_CHANNEL_SELECTION_ALGORITHM)) {
4053 // The selection channel algorithm probably will have no impact
4054 // on emulation.
4055 send_event_(bluetooth::hci::LeChannelSelectionAlgorithmBuilder::Create(
4056 handle, bluetooth::hci::ChannelSelectionAlgorithm::ALGORITHM_1));
4057 }
4058
4059 if (own_address.GetAddress() == initiator_.initiating_address) {
4060 initiator_.initiating_address = Address::kEmpty;
4061 }
4062 return handle;
4063 }
4064
4065 // Handle CONNECT_IND PDUs for the legacy advertiser.
ProcessIncomingLegacyConnectRequest(model::packets::LeConnectView const & connect_ind)4066 bool LinkLayerController::ProcessIncomingLegacyConnectRequest(
4067 model::packets::LeConnectView const& connect_ind) {
4068 if (!legacy_advertiser_.IsEnabled()) {
4069 return false;
4070 }
4071 if (!legacy_advertiser_.IsConnectable()) {
4072 DEBUG(id_,
4073 "LE Connect request ignored by legacy advertiser because it is not "
4074 "connectable");
4075 return false;
4076 }
4077
4078 AddressWithType advertising_address{
4079 connect_ind.GetDestinationAddress(),
4080 static_cast<AddressType>(connect_ind.GetAdvertisingAddressType()),
4081 };
4082
4083 AddressWithType initiating_address{
4084 connect_ind.GetSourceAddress(),
4085 static_cast<AddressType>(connect_ind.GetInitiatingAddressType()),
4086 };
4087
4088 if (legacy_advertiser_.GetAdvertisingAddress() != advertising_address) {
4089 DEBUG(id_,
4090 "LE Connect request ignored by legacy advertiser because the "
4091 "advertising address {} does not match {}",
4092 advertising_address, legacy_advertiser_.GetAdvertisingAddress());
4093 return false;
4094 }
4095
4096 // When an advertiser receives a connection request that contains a resolvable
4097 // private address for the initiator’s address (InitA field) and address
4098 // resolution is enabled, the Link Layer shall resolve the private address.
4099 // The advertising filter policy shall then determine if the
4100 // advertiser establishes a connection.
4101 AddressWithType resolved_initiating_address =
4102 ResolvePrivateAddress(initiating_address).value_or(initiating_address);
4103
4104 if (resolved_initiating_address != initiating_address) {
4105 DEBUG(id_, "Resolved the initiating address {} to {}", initiating_address,
4106 resolved_initiating_address);
4107 }
4108
4109 // When the Link Layer is [...] connectable directed advertising events the
4110 // advertising filter policy shall be ignored.
4111 if (legacy_advertiser_.IsDirected()) {
4112 if (resolved_initiating_address !=
4113 PeerDeviceAddress(legacy_advertiser_.peer_address, legacy_advertiser_.peer_address_type)) {
4114 DEBUG(id_,
4115 "LE Connect request ignored by legacy advertiser because the "
4116 "initiating address {} does not match the target address {}[{}]",
4117 resolved_initiating_address, legacy_advertiser_.peer_address,
4118 PeerAddressTypeText(legacy_advertiser_.peer_address_type));
4119 return false;
4120 }
4121 } else {
4122 // Check if initiator address is in the filter accept list
4123 // for this advertiser.
4124 switch (legacy_advertiser_.advertising_filter_policy) {
4125 case bluetooth::hci::AdvertisingFilterPolicy::ALL_DEVICES:
4126 case bluetooth::hci::AdvertisingFilterPolicy::LISTED_SCAN:
4127 break;
4128 case bluetooth::hci::AdvertisingFilterPolicy::LISTED_CONNECT:
4129 case bluetooth::hci::AdvertisingFilterPolicy::LISTED_SCAN_AND_CONNECT:
4130 if (!LeFilterAcceptListContainsDevice(resolved_initiating_address)) {
4131 DEBUG(id_,
4132 "LE Connect request ignored by legacy advertiser because the "
4133 "initiating address {} is not in the filter accept list",
4134 resolved_initiating_address);
4135 return false;
4136 }
4137 break;
4138 }
4139 }
4140
4141 INFO(id_,
4142 "Accepting LE Connect request to legacy advertiser from initiating "
4143 "address {}",
4144 resolved_initiating_address);
4145
4146 if (!connections_.CreatePendingLeConnection(initiating_address,
4147 resolved_initiating_address != initiating_address
4148 ? resolved_initiating_address
4149 : AddressWithType{},
4150 advertising_address)) {
4151 WARNING(id_, "CreatePendingLeConnection failed for connection from {}",
4152 initiating_address.GetAddress());
4153 return false;
4154 }
4155
4156 (void)HandleLeConnection(initiating_address, advertising_address,
4157 bluetooth::hci::Role::PERIPHERAL, connect_ind.GetConnInterval(),
4158 connect_ind.GetConnPeripheralLatency(),
4159 connect_ind.GetConnSupervisionTimeout(), false);
4160
4161 SendLeLinkLayerPacket(model::packets::LeConnectCompleteBuilder::Create(
4162 advertising_address.GetAddress(), initiating_address.GetAddress(),
4163 static_cast<model::packets::AddressType>(initiating_address.GetAddressType()),
4164 static_cast<model::packets::AddressType>(advertising_address.GetAddressType()),
4165 connect_ind.GetConnInterval(), connect_ind.GetConnPeripheralLatency(),
4166 connect_ind.GetConnSupervisionTimeout()));
4167
4168 legacy_advertiser_.Disable();
4169 return true;
4170 }
4171
4172 // Handle CONNECT_IND PDUs for the selected extended advertiser.
ProcessIncomingExtendedConnectRequest(ExtendedAdvertiser & advertiser,model::packets::LeConnectView const & connect_ind)4173 bool LinkLayerController::ProcessIncomingExtendedConnectRequest(
4174 ExtendedAdvertiser& advertiser, model::packets::LeConnectView const& connect_ind) {
4175 if (!advertiser.IsEnabled()) {
4176 return false;
4177 }
4178 if (!advertiser.IsConnectable()) {
4179 DEBUG(id_,
4180 "LE Connect request ignored by extended advertiser {} because it is "
4181 "not connectable",
4182 advertiser.advertising_handle);
4183 return false;
4184 }
4185
4186 AddressWithType advertising_address{
4187 connect_ind.GetDestinationAddress(),
4188 static_cast<AddressType>(connect_ind.GetAdvertisingAddressType()),
4189 };
4190
4191 AddressWithType initiating_address{
4192 connect_ind.GetSourceAddress(),
4193 static_cast<AddressType>(connect_ind.GetInitiatingAddressType()),
4194 };
4195
4196 if (advertiser.GetAdvertisingAddress() != advertising_address) {
4197 DEBUG(id_,
4198 "LE Connect request ignored by extended advertiser {} because the "
4199 "advertising address {} does not match {}",
4200 advertiser.advertising_handle, advertising_address, advertiser.GetAdvertisingAddress());
4201 return false;
4202 }
4203
4204 // When an advertiser receives a connection request that contains a resolvable
4205 // private address for the initiator’s address (InitA field) and address
4206 // resolution is enabled, the Link Layer shall resolve the private address.
4207 // The advertising filter policy shall then determine if the
4208 // advertiser establishes a connection.
4209 AddressWithType resolved_initiating_address =
4210 ResolvePrivateAddress(initiating_address).value_or(initiating_address);
4211
4212 if (resolved_initiating_address != initiating_address) {
4213 DEBUG(id_, "Resolved the initiating address {} to {}", initiating_address,
4214 resolved_initiating_address);
4215 }
4216
4217 // When the Link Layer is [...] connectable directed advertising events the
4218 // advertising filter policy shall be ignored.
4219 if (advertiser.IsDirected()) {
4220 if (resolved_initiating_address !=
4221 PeerDeviceAddress(advertiser.peer_address, advertiser.peer_address_type)) {
4222 DEBUG(id_,
4223 "LE Connect request ignored by extended advertiser {} because the "
4224 "initiating address {} does not match the target address {}[{}]",
4225 advertiser.advertising_handle, resolved_initiating_address, advertiser.peer_address,
4226 PeerAddressTypeText(advertiser.peer_address_type));
4227 return false;
4228 }
4229 } else {
4230 // Check if initiator address is in the filter accept list
4231 // for this advertiser.
4232 switch (advertiser.advertising_filter_policy) {
4233 case bluetooth::hci::AdvertisingFilterPolicy::ALL_DEVICES:
4234 case bluetooth::hci::AdvertisingFilterPolicy::LISTED_SCAN:
4235 break;
4236 case bluetooth::hci::AdvertisingFilterPolicy::LISTED_CONNECT:
4237 case bluetooth::hci::AdvertisingFilterPolicy::LISTED_SCAN_AND_CONNECT:
4238 if (!LeFilterAcceptListContainsDevice(resolved_initiating_address)) {
4239 DEBUG(id_,
4240 "LE Connect request ignored by extended advertiser {} because "
4241 "the initiating address {} is not in the filter accept list",
4242 advertiser.advertising_handle, resolved_initiating_address);
4243 return false;
4244 }
4245 break;
4246 }
4247 }
4248
4249 INFO(id_,
4250 "Accepting LE Connect request to extended advertiser {} from initiating "
4251 "address {}",
4252 advertiser.advertising_handle, resolved_initiating_address);
4253
4254 if (!connections_.CreatePendingLeConnection(initiating_address,
4255 resolved_initiating_address != initiating_address
4256 ? resolved_initiating_address
4257 : AddressWithType{},
4258 advertising_address)) {
4259 WARNING(id_, "CreatePendingLeConnection failed for connection from {}",
4260 initiating_address.GetAddress());
4261 return false;
4262 }
4263
4264 advertiser.Disable();
4265
4266 uint16_t connection_handle = HandleLeConnection(
4267 initiating_address, advertising_address, bluetooth::hci::Role::PERIPHERAL,
4268 connect_ind.GetConnInterval(), connect_ind.GetConnPeripheralLatency(),
4269 connect_ind.GetConnSupervisionTimeout(), false);
4270
4271 SendLeLinkLayerPacket(model::packets::LeConnectCompleteBuilder::Create(
4272 advertising_address.GetAddress(), initiating_address.GetAddress(),
4273 static_cast<model::packets::AddressType>(initiating_address.GetAddressType()),
4274 static_cast<model::packets::AddressType>(advertising_address.GetAddressType()),
4275 connect_ind.GetConnInterval(), connect_ind.GetConnPeripheralLatency(),
4276 connect_ind.GetConnSupervisionTimeout()));
4277
4278 // If the advertising set is connectable and a connection gets created, an
4279 // HCI_LE_Connection_Complete or HCI_LE_Enhanced_Connection_Complete
4280 // event shall be generated followed by an HCI_LE_Advertising_Set_Terminated
4281 // event with the Status parameter set to 0x00. The Controller should not send
4282 // any other events in between these two events
4283
4284 if (IsLeEventUnmasked(SubeventCode::LE_ADVERTISING_SET_TERMINATED)) {
4285 send_event_(bluetooth::hci::LeAdvertisingSetTerminatedBuilder::Create(
4286 ErrorCode::SUCCESS, advertiser.advertising_handle, connection_handle,
4287 advertiser.num_completed_extended_advertising_events));
4288 }
4289
4290 return true;
4291 }
4292
IncomingLeConnectPacket(model::packets::LinkLayerPacketView incoming)4293 void LinkLayerController::IncomingLeConnectPacket(model::packets::LinkLayerPacketView incoming) {
4294 model::packets::LeConnectView connect = model::packets::LeConnectView::Create(incoming);
4295 ASSERT(connect.IsValid());
4296
4297 if (ProcessIncomingLegacyConnectRequest(connect)) {
4298 return;
4299 }
4300
4301 for (auto& [_, advertiser] : extended_advertisers_) {
4302 if (ProcessIncomingExtendedConnectRequest(advertiser, connect)) {
4303 return;
4304 }
4305 }
4306 }
4307
IncomingLeConnectCompletePacket(model::packets::LinkLayerPacketView incoming)4308 void LinkLayerController::IncomingLeConnectCompletePacket(
4309 model::packets::LinkLayerPacketView incoming) {
4310 auto complete = model::packets::LeConnectCompleteView::Create(incoming);
4311 ASSERT(complete.IsValid());
4312
4313 AddressWithType advertising_address{
4314 incoming.GetSourceAddress(),
4315 static_cast<bluetooth::hci::AddressType>(complete.GetAdvertisingAddressType())};
4316
4317 INFO(id_, "Received LE Connect complete response with advertising address {}",
4318 advertising_address);
4319
4320 HandleLeConnection(advertising_address,
4321 AddressWithType(incoming.GetDestinationAddress(),
4322 static_cast<bluetooth::hci::AddressType>(
4323 complete.GetInitiatingAddressType())),
4324 bluetooth::hci::Role::CENTRAL, complete.GetConnInterval(),
4325 complete.GetConnPeripheralLatency(), complete.GetConnSupervisionTimeout(),
4326 ExtendedAdvertising());
4327
4328 initiator_.pending_connect_request = {};
4329 initiator_.Disable();
4330 }
4331
IncomingLeConnectionParameterRequest(model::packets::LinkLayerPacketView incoming)4332 void LinkLayerController::IncomingLeConnectionParameterRequest(
4333 model::packets::LinkLayerPacketView incoming) {
4334 auto request = model::packets::LeConnectionParameterRequestView::Create(incoming);
4335 ASSERT(request.IsValid());
4336 Address peer = incoming.GetSourceAddress();
4337 uint16_t handle = connections_.GetHandleOnlyAddress(peer);
4338 if (handle == kReservedHandle) {
4339 INFO(id_, "@{}: Unknown connection @{}", incoming.GetDestinationAddress(), peer);
4340 return;
4341 }
4342
4343 if (IsLeEventUnmasked(SubeventCode::LE_REMOTE_CONNECTION_PARAMETER_REQUEST)) {
4344 send_event_(bluetooth::hci::LeRemoteConnectionParameterRequestBuilder::Create(
4345 handle, request.GetIntervalMin(), request.GetIntervalMax(), request.GetLatency(),
4346 request.GetTimeout()));
4347 } else {
4348 // If the request is being indicated to the Host and the event to the Host
4349 // is masked, then the Link Layer shall issue an LL_REJECT_EXT_IND PDU with
4350 // the ErrorCode set to Unsupported Remote Feature (0x1A).
4351 SendLeLinkLayerPacket(model::packets::LeConnectionParameterUpdateBuilder::Create(
4352 request.GetDestinationAddress(), request.GetSourceAddress(),
4353 static_cast<uint8_t>(ErrorCode::UNSUPPORTED_REMOTE_OR_LMP_FEATURE), 0, 0, 0));
4354 }
4355 }
4356
IncomingLeConnectionParameterUpdate(model::packets::LinkLayerPacketView incoming)4357 void LinkLayerController::IncomingLeConnectionParameterUpdate(
4358 model::packets::LinkLayerPacketView incoming) {
4359 auto update = model::packets::LeConnectionParameterUpdateView::Create(incoming);
4360 ASSERT(update.IsValid());
4361 Address peer = incoming.GetSourceAddress();
4362 uint16_t handle = connections_.GetHandleOnlyAddress(peer);
4363 if (handle == kReservedHandle) {
4364 INFO(id_, "@{}: Unknown connection @{}", incoming.GetDestinationAddress(), peer);
4365 return;
4366 }
4367 if (IsLeEventUnmasked(SubeventCode::LE_CONNECTION_UPDATE_COMPLETE)) {
4368 send_event_(bluetooth::hci::LeConnectionUpdateCompleteBuilder::Create(
4369 static_cast<ErrorCode>(update.GetStatus()), handle, update.GetInterval(),
4370 update.GetLatency(), update.GetTimeout()));
4371 }
4372 }
4373
IncomingLeEncryptConnection(model::packets::LinkLayerPacketView incoming)4374 void LinkLayerController::IncomingLeEncryptConnection(
4375 model::packets::LinkLayerPacketView incoming) {
4376 INFO(id_, "IncomingLeEncryptConnection");
4377
4378 Address peer = incoming.GetSourceAddress();
4379 uint16_t handle = connections_.GetHandleOnlyAddress(peer);
4380 if (handle == kReservedHandle) {
4381 INFO(id_, "@{}: Unknown connection @{}", incoming.GetDestinationAddress(), peer);
4382 return;
4383 }
4384 auto le_encrypt = model::packets::LeEncryptConnectionView::Create(incoming);
4385 ASSERT(le_encrypt.IsValid());
4386
4387 // TODO: Save keys to check
4388
4389 if (IsEventUnmasked(EventCode::LE_META_EVENT)) {
4390 send_event_(bluetooth::hci::LeLongTermKeyRequestBuilder::Create(handle, le_encrypt.GetRand(),
4391 le_encrypt.GetEdiv()));
4392 }
4393 }
4394
IncomingLeEncryptConnectionResponse(model::packets::LinkLayerPacketView incoming)4395 void LinkLayerController::IncomingLeEncryptConnectionResponse(
4396 model::packets::LinkLayerPacketView incoming) {
4397 INFO(id_, "IncomingLeEncryptConnectionResponse");
4398 // TODO: Check keys
4399 uint16_t handle = connections_.GetHandleOnlyAddress(incoming.GetSourceAddress());
4400 if (handle == kReservedHandle) {
4401 INFO(id_, "@{}: Unknown connection @{}", incoming.GetDestinationAddress(),
4402 incoming.GetSourceAddress());
4403 return;
4404 }
4405 ErrorCode status = ErrorCode::SUCCESS;
4406 auto response = model::packets::LeEncryptConnectionResponseView::Create(incoming);
4407 ASSERT(response.IsValid());
4408
4409 bool success = true;
4410 // Zero LTK is a rejection
4411 if (response.GetLtk() == std::array<uint8_t, 16>{0}) {
4412 status = ErrorCode::AUTHENTICATION_FAILURE;
4413 success = false;
4414 }
4415
4416 if (connections_.IsEncrypted(handle)) {
4417 if (IsEventUnmasked(EventCode::ENCRYPTION_KEY_REFRESH_COMPLETE)) {
4418 send_event_(bluetooth::hci::EncryptionKeyRefreshCompleteBuilder::Create(status, handle));
4419 }
4420 } else if (success) {
4421 connections_.Encrypt(handle);
4422 if (IsEventUnmasked(EventCode::ENCRYPTION_CHANGE)) {
4423 send_event_(bluetooth::hci::EncryptionChangeBuilder::Create(
4424 status, handle, bluetooth::hci::EncryptionEnabled::ON));
4425 }
4426 } else {
4427 if (IsEventUnmasked(EventCode::ENCRYPTION_CHANGE)) {
4428 send_event_(bluetooth::hci::EncryptionChangeBuilder::Create(
4429 status, handle, bluetooth::hci::EncryptionEnabled::OFF));
4430 }
4431 }
4432 }
4433
IncomingLeReadRemoteFeatures(model::packets::LinkLayerPacketView incoming)4434 void LinkLayerController::IncomingLeReadRemoteFeatures(
4435 model::packets::LinkLayerPacketView incoming) {
4436 uint16_t handle = connections_.GetHandleOnlyAddress(incoming.GetSourceAddress());
4437 ErrorCode status = ErrorCode::SUCCESS;
4438 if (handle == kReservedHandle) {
4439 WARNING(id_, "@{}: Unknown connection @{}", incoming.GetDestinationAddress(),
4440 incoming.GetSourceAddress());
4441 }
4442 SendLeLinkLayerPacket(model::packets::LeReadRemoteFeaturesResponseBuilder::Create(
4443 incoming.GetDestinationAddress(), incoming.GetSourceAddress(), GetLeSupportedFeatures(),
4444 static_cast<uint8_t>(status)));
4445 }
4446
IncomingLeReadRemoteFeaturesResponse(model::packets::LinkLayerPacketView incoming)4447 void LinkLayerController::IncomingLeReadRemoteFeaturesResponse(
4448 model::packets::LinkLayerPacketView incoming) {
4449 uint16_t handle = connections_.GetHandleOnlyAddress(incoming.GetSourceAddress());
4450 ErrorCode status = ErrorCode::SUCCESS;
4451 auto response = model::packets::LeReadRemoteFeaturesResponseView::Create(incoming);
4452 ASSERT(response.IsValid());
4453 if (handle == kReservedHandle) {
4454 INFO(id_, "@{}: Unknown connection @{}", incoming.GetDestinationAddress(),
4455 incoming.GetSourceAddress());
4456 status = ErrorCode::UNKNOWN_CONNECTION;
4457 } else {
4458 status = static_cast<ErrorCode>(response.GetStatus());
4459 }
4460 if (IsEventUnmasked(EventCode::LE_META_EVENT)) {
4461 send_event_(bluetooth::hci::LeReadRemoteFeaturesPage0CompleteBuilder::Create(
4462 status, handle, response.GetFeatures()));
4463 }
4464 }
4465
ProcessIncomingLegacyScanRequest(AddressWithType scanning_address,AddressWithType resolved_scanning_address,AddressWithType advertising_address)4466 void LinkLayerController::ProcessIncomingLegacyScanRequest(
4467 AddressWithType scanning_address, AddressWithType resolved_scanning_address,
4468 AddressWithType advertising_address) {
4469 // Check if the advertising addresses matches the legacy
4470 // advertising address.
4471 if (!legacy_advertiser_.IsEnabled()) {
4472 return;
4473 }
4474 if (!legacy_advertiser_.IsScannable()) {
4475 DEBUG(id_,
4476 "LE Scan request ignored by legacy advertiser because it is not "
4477 "scannable");
4478 return;
4479 }
4480
4481 if (advertising_address != legacy_advertiser_.advertising_address) {
4482 DEBUG(id_,
4483 "LE Scan request ignored by legacy advertiser because the advertising "
4484 "address {} does not match {}",
4485 advertising_address, legacy_advertiser_.GetAdvertisingAddress());
4486 return;
4487 }
4488
4489 // Check if scanner address is in the filter accept list
4490 // for this advertiser.
4491 switch (legacy_advertiser_.advertising_filter_policy) {
4492 case bluetooth::hci::AdvertisingFilterPolicy::ALL_DEVICES:
4493 case bluetooth::hci::AdvertisingFilterPolicy::LISTED_CONNECT:
4494 break;
4495 case bluetooth::hci::AdvertisingFilterPolicy::LISTED_SCAN:
4496 case bluetooth::hci::AdvertisingFilterPolicy::LISTED_SCAN_AND_CONNECT:
4497 if (!LeFilterAcceptListContainsDevice(resolved_scanning_address)) {
4498 DEBUG(id_,
4499 "LE Scan request ignored by legacy advertiser because the scanning "
4500 "address {} is not in the filter accept list",
4501 resolved_scanning_address);
4502 return;
4503 }
4504 break;
4505 }
4506
4507 INFO(id_,
4508 "Accepting LE Scan request to legacy advertiser from scanning address "
4509 "{}",
4510 resolved_scanning_address);
4511
4512 // Generate the SCAN_RSP packet.
4513 // Note: If the advertiser processes the scan request, the advertiser’s
4514 // device address (AdvA field) in the SCAN_RSP PDU shall be the same as
4515 // the advertiser’s device address (AdvA field) in the SCAN_REQ PDU to
4516 // which it is responding.
4517 SendLeLinkLayerPacket(
4518 model::packets::LeScanResponseBuilder::Create(
4519 advertising_address.GetAddress(), scanning_address.GetAddress(),
4520 static_cast<model::packets::AddressType>(advertising_address.GetAddressType()),
4521 legacy_advertiser_.scan_response_data),
4522 properties_.le_advertising_physical_channel_tx_power);
4523 }
4524
ProcessIncomingExtendedScanRequest(ExtendedAdvertiser const & advertiser,AddressWithType scanning_address,AddressWithType resolved_scanning_address,AddressWithType advertising_address)4525 void LinkLayerController::ProcessIncomingExtendedScanRequest(
4526 ExtendedAdvertiser const& advertiser, AddressWithType scanning_address,
4527 AddressWithType resolved_scanning_address, AddressWithType advertising_address) {
4528 // Check if the advertising addresses matches the legacy
4529 // advertising address.
4530 if (!advertiser.IsEnabled()) {
4531 return;
4532 }
4533 if (!advertiser.IsScannable()) {
4534 DEBUG(id_,
4535 "LE Scan request ignored by extended advertiser {} because it is not "
4536 "scannable",
4537 advertiser.advertising_handle);
4538 return;
4539 }
4540
4541 if (advertising_address != advertiser.advertising_address) {
4542 DEBUG(id_,
4543 "LE Scan request ignored by extended advertiser {} because the "
4544 "advertising address {} does not match {}",
4545 advertiser.advertising_handle, advertising_address, advertiser.GetAdvertisingAddress());
4546 return;
4547 }
4548
4549 // Check if scanner address is in the filter accept list
4550 // for this advertiser.
4551 switch (advertiser.advertising_filter_policy) {
4552 case bluetooth::hci::AdvertisingFilterPolicy::ALL_DEVICES:
4553 case bluetooth::hci::AdvertisingFilterPolicy::LISTED_CONNECT:
4554 break;
4555 case bluetooth::hci::AdvertisingFilterPolicy::LISTED_SCAN:
4556 case bluetooth::hci::AdvertisingFilterPolicy::LISTED_SCAN_AND_CONNECT:
4557 if (!LeFilterAcceptListContainsDevice(resolved_scanning_address)) {
4558 DEBUG(id_,
4559 "LE Scan request ignored by extended advertiser {} because the "
4560 "scanning address {} is not in the filter accept list",
4561 advertiser.advertising_handle, resolved_scanning_address);
4562 return;
4563 }
4564 break;
4565 }
4566
4567 // Check if the scanner address is the target address in the case of
4568 // scannable directed event types.
4569 if (advertiser.IsDirected() && advertiser.target_address != resolved_scanning_address) {
4570 DEBUG(id_,
4571 "LE Scan request ignored by extended advertiser {} because the "
4572 "scanning address {} does not match the target address {}",
4573 advertiser.advertising_handle, resolved_scanning_address, advertiser.GetTargetAddress());
4574 return;
4575 }
4576
4577 INFO(id_,
4578 "Accepting LE Scan request to extended advertiser {} from scanning "
4579 "address {}",
4580 advertiser.advertising_handle, resolved_scanning_address);
4581
4582 // Generate the SCAN_RSP packet.
4583 // Note: If the advertiser processes the scan request, the advertiser’s
4584 // device address (AdvA field) in the SCAN_RSP PDU shall be the same as
4585 // the advertiser’s device address (AdvA field) in the SCAN_REQ PDU to
4586 // which it is responding.
4587 SendLeLinkLayerPacket(
4588 model::packets::LeScanResponseBuilder::Create(
4589 advertising_address.GetAddress(), scanning_address.GetAddress(),
4590 static_cast<model::packets::AddressType>(advertising_address.GetAddressType()),
4591 advertiser.scan_response_data),
4592 advertiser.advertising_tx_power);
4593 }
4594
IncomingLeScanPacket(model::packets::LinkLayerPacketView incoming)4595 void LinkLayerController::IncomingLeScanPacket(model::packets::LinkLayerPacketView incoming) {
4596 auto scan_request = model::packets::LeScanView::Create(incoming);
4597 ASSERT(scan_request.IsValid());
4598
4599 AddressWithType scanning_address{scan_request.GetSourceAddress(),
4600 static_cast<AddressType>(scan_request.GetScanningAddressType())};
4601
4602 AddressWithType advertising_address{
4603 scan_request.GetDestinationAddress(),
4604 static_cast<AddressType>(scan_request.GetAdvertisingAddressType())};
4605
4606 // Note: Vol 6, Part B § 6.2 Privacy in the Advertising State.
4607 //
4608 // When an advertiser receives a scan request that contains a resolvable
4609 // private address for the scanner’s device address (ScanA field) and
4610 // address resolution is enabled, the Link Layer shall resolve the private
4611 // address. The advertising filter policy shall then determine if
4612 // the advertiser processes the scan request.
4613 AddressWithType resolved_scanning_address =
4614 ResolvePrivateAddress(scanning_address).value_or(scanning_address);
4615
4616 if (resolved_scanning_address != scanning_address) {
4617 DEBUG(id_, "Resolved the scanning address {} to {}", scanning_address,
4618 resolved_scanning_address);
4619 }
4620
4621 ProcessIncomingLegacyScanRequest(scanning_address, resolved_scanning_address,
4622 advertising_address);
4623 for (auto& [_, advertiser] : extended_advertisers_) {
4624 ProcessIncomingExtendedScanRequest(advertiser, scanning_address, resolved_scanning_address,
4625 advertising_address);
4626 }
4627 }
4628
IncomingLeScanResponsePacket(model::packets::LinkLayerPacketView incoming,uint8_t rssi)4629 void LinkLayerController::IncomingLeScanResponsePacket(model::packets::LinkLayerPacketView incoming,
4630 uint8_t rssi) {
4631 auto scan_response = model::packets::LeScanResponseView::Create(incoming);
4632 ASSERT(scan_response.IsValid());
4633
4634 if (!scanner_.IsEnabled()) {
4635 return;
4636 }
4637
4638 if (!scanner_.pending_scan_request) {
4639 DEBUG(id_,
4640 "LE Scan response ignored by scanner because no request is currently "
4641 "pending");
4642 return;
4643 }
4644
4645 AddressWithType advertising_address{
4646 scan_response.GetSourceAddress(),
4647 static_cast<AddressType>(scan_response.GetAdvertisingAddressType())};
4648
4649 // If the advertiser processes the scan request, the advertiser’s device
4650 // address (AdvA field) in the scan response PDU shall be the same as the
4651 // advertiser’s device address (AdvA field) in the scan request PDU to which
4652 // it is responding.
4653 if (advertising_address != scanner_.pending_scan_request) {
4654 DEBUG(id_,
4655 "LE Scan response ignored by scanner because the advertising address "
4656 "{} does not match the pending request {}",
4657 advertising_address, scanner_.pending_scan_request.value());
4658 return;
4659 }
4660
4661 AddressWithType resolved_advertising_address =
4662 ResolvePrivateAddress(advertising_address).value_or(advertising_address);
4663
4664 if (advertising_address != resolved_advertising_address) {
4665 DEBUG(id_, "Resolved the advertising address {} to {}", advertising_address,
4666 resolved_advertising_address);
4667 }
4668
4669 INFO(id_, "Accepting LE Scan response from advertising address {}", resolved_advertising_address);
4670
4671 scanner_.pending_scan_request = {};
4672
4673 bool should_send_advertising_report = true;
4674 if (scanner_.filter_duplicates != bluetooth::hci::FilterDuplicates::DISABLED) {
4675 if (scanner_.IsPacketInHistory(incoming.bytes())) {
4676 should_send_advertising_report = false;
4677 } else {
4678 scanner_.AddPacketToHistory(incoming.bytes());
4679 }
4680 }
4681
4682 if (LegacyAdvertising() && should_send_advertising_report &&
4683 IsLeEventUnmasked(SubeventCode::LE_ADVERTISING_REPORT)) {
4684 bluetooth::hci::LeAdvertisingResponse response;
4685 response.event_type_ = bluetooth::hci::AdvertisingEventType::SCAN_RESPONSE;
4686 response.address_ = resolved_advertising_address.GetAddress();
4687 response.address_type_ = resolved_advertising_address.GetAddressType();
4688 response.advertising_data_ = scan_response.GetScanResponseData();
4689 response.rssi_ = rssi;
4690 send_event_(bluetooth::hci::LeAdvertisingReportBuilder::Create({response}));
4691 }
4692
4693 if (ExtendedAdvertising() && should_send_advertising_report &&
4694 IsLeEventUnmasked(SubeventCode::LE_EXTENDED_ADVERTISING_REPORT)) {
4695 bluetooth::hci::LeExtendedAdvertisingResponse response;
4696 response.address_ = resolved_advertising_address.GetAddress();
4697 response.address_type_ = static_cast<bluetooth::hci::DirectAdvertisingAddressType>(
4698 resolved_advertising_address.GetAddressType());
4699 response.connectable_ = scanner_.connectable_scan_response;
4700 response.scannable_ = true;
4701 response.legacy_ = !scanner_.extended_scan_response;
4702 response.scan_response_ = true;
4703 response.primary_phy_ =
4704 static_cast<bluetooth::hci::PrimaryPhyType>(scanner_.primary_scan_response_phy);
4705 response.secondary_phy_ =
4706 static_cast<bluetooth::hci::SecondaryPhyType>(scanner_.secondary_scan_response_phy);
4707 // TODO: SID should be set in scan response PDU
4708 response.advertising_sid_ = 0xFF;
4709 response.tx_power_ = 0x7F;
4710 response.rssi_ = rssi;
4711 response.direct_address_type_ =
4712 bluetooth::hci::DirectAdvertisingAddressType::NO_ADDRESS_PROVIDED;
4713
4714 // Each extended advertising report can only pass 229 bytes of
4715 // advertising data (255 - size of report fields).
4716 // RootCanal must fragment the report as necessary.
4717 const size_t max_fragment_size = 229;
4718 size_t offset = 0;
4719 std::vector<uint8_t> advertising_data = scan_response.GetScanResponseData();
4720
4721 do {
4722 size_t remaining_size = advertising_data.size() - offset;
4723 size_t fragment_size = std::min(max_fragment_size, remaining_size);
4724 response.data_status_ = remaining_size <= max_fragment_size
4725 ? bluetooth::hci::DataStatus::COMPLETE
4726 : bluetooth::hci::DataStatus::CONTINUING;
4727 response.advertising_data_ = std::vector(advertising_data.begin() + offset,
4728 advertising_data.begin() + offset + fragment_size);
4729 offset += fragment_size;
4730 send_event_(bluetooth::hci::LeExtendedAdvertisingReportBuilder::Create({response}));
4731 } while (offset < advertising_data.size());
4732 }
4733 }
4734
LeScanning()4735 void LinkLayerController::LeScanning() {
4736 if (!scanner_.IsEnabled()) {
4737 return;
4738 }
4739
4740 std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
4741
4742 // Extended Scanning Timeout
4743
4744 // Generate HCI Connection Complete or Enhanced HCI Connection Complete
4745 // events with Advertising Timeout error code when the advertising
4746 // type is ADV_DIRECT_IND and the connection failed to be established.
4747
4748 if (scanner_.timeout.has_value() && !scanner_.periodical_timeout.has_value() &&
4749 now >= scanner_.timeout.value()) {
4750 // At the end of a single scan (Duration non-zero but Period zero),
4751 // an HCI_LE_Scan_Timeout event shall be generated.
4752 INFO(id_, "Extended Scan Timeout");
4753 scanner_.scan_enable = false;
4754 scanner_.pending_scan_request = {};
4755 scanner_.history.clear();
4756 if (IsLeEventUnmasked(SubeventCode::LE_SCAN_TIMEOUT)) {
4757 send_event_(bluetooth::hci::LeScanTimeoutBuilder::Create());
4758 }
4759 }
4760
4761 // End of duration with scan enabled
4762 if (scanner_.timeout.has_value() && scanner_.periodical_timeout.has_value() &&
4763 now >= scanner_.timeout.value()) {
4764 scanner_.timeout = {};
4765 }
4766
4767 // End of period
4768 if (!scanner_.timeout.has_value() && scanner_.periodical_timeout.has_value() &&
4769 now >= scanner_.periodical_timeout.value()) {
4770 if (scanner_.filter_duplicates == FilterDuplicates::RESET_EACH_PERIOD) {
4771 scanner_.history.clear();
4772 }
4773 scanner_.timeout = now + scanner_.duration;
4774 scanner_.periodical_timeout = now + scanner_.period;
4775 }
4776
4777 // Pending scan timeout.
4778 // Cancel the pending scan request. This may condition may be triggered
4779 // when the advertiser is stopped before sending the scan request.
4780 if (scanner_.pending_scan_request_timeout.has_value() &&
4781 now >= scanner_.pending_scan_request_timeout.value()) {
4782 scanner_.pending_scan_request = {};
4783 scanner_.pending_scan_request_timeout = {};
4784 }
4785 }
4786
LeSynchronization()4787 void LinkLayerController::LeSynchronization() {
4788 std::vector<uint16_t> removed_sync_handles;
4789 for (auto& [_, sync] : synchronized_) {
4790 if (sync.timeout > std::chrono::steady_clock::now()) {
4791 INFO(id_, "Periodic advertising sync with handle 0x{:x} lost", sync.sync_handle);
4792 removed_sync_handles.push_back(sync.sync_handle);
4793 }
4794 if (IsLeEventUnmasked(SubeventCode::LE_PERIODIC_ADVERTISING_SYNC_LOST)) {
4795 send_event_(bluetooth::hci::LePeriodicAdvertisingSyncLostBuilder::Create(sync.sync_handle));
4796 }
4797 }
4798
4799 for (auto sync_handle : removed_sync_handles) {
4800 synchronized_.erase(sync_handle);
4801 }
4802 }
4803
IncomingPagePacket(model::packets::LinkLayerPacketView incoming)4804 void LinkLayerController::IncomingPagePacket(model::packets::LinkLayerPacketView incoming) {
4805 auto bd_addr = incoming.GetSourceAddress();
4806 auto page = model::packets::PageView::Create(incoming);
4807 ASSERT(page.IsValid());
4808
4809 // [HCI] 7.3.3 Set Event Filter command
4810 // If the Auto_Accept_Flag is off and the Host has masked the
4811 // HCI_Connection_Request event, the Controller shall reject the
4812 // connection attempt.
4813 if (!IsEventUnmasked(EventCode::CONNECTION_REQUEST)) {
4814 INFO(id_,
4815 "rejecting connection request from {} because the HCI_Connection_Request"
4816 " event is masked by the Host",
4817 bd_addr);
4818 SendLinkLayerPacket(model::packets::PageRejectBuilder::Create(
4819 GetAddress(), bd_addr, static_cast<uint8_t>(ErrorCode::CONNECTION_TIMEOUT)));
4820 return;
4821 }
4822
4823 // Cannot establish two BR-EDR connections with the same peer.
4824 if (connections_.GetAclConnectionHandle(bd_addr).has_value()) {
4825 return;
4826 }
4827
4828 bool allow_role_switch = page.GetAllowRoleSwitch();
4829 if (!connections_.CreatePendingConnection(
4830 bd_addr, authentication_enable_ == AuthenticationEnable::REQUIRED,
4831 allow_role_switch)) {
4832 // Will be triggered when multiple hosts are paging simultaneously;
4833 // only one connection will be accepted.
4834 WARNING(id_, "Failed to create a pending connection for {}", bd_addr);
4835 return;
4836 }
4837
4838 send_event_(bluetooth::hci::ConnectionRequestBuilder::Create(
4839 bd_addr, page.GetClassOfDevice(), bluetooth::hci::ConnectionRequestLinkType::ACL));
4840 }
4841
IncomingPageRejectPacket(model::packets::LinkLayerPacketView incoming)4842 void LinkLayerController::IncomingPageRejectPacket(model::packets::LinkLayerPacketView incoming) {
4843 auto bd_addr = incoming.GetSourceAddress();
4844 auto reject = model::packets::PageRejectView::Create(incoming);
4845 ASSERT(reject.IsValid());
4846
4847 if (!page_.has_value() || page_->bd_addr != bd_addr) {
4848 INFO(id_,
4849 "ignoring Page Reject packet received when not in Page state,"
4850 " or paging to a different address");
4851 return;
4852 }
4853
4854 INFO(id_, "Received Page Reject packet from {}", bd_addr);
4855 page_ = {};
4856
4857 if (IsEventUnmasked(EventCode::CONNECTION_COMPLETE)) {
4858 send_event_(bluetooth::hci::ConnectionCompleteBuilder::Create(
4859 static_cast<ErrorCode>(reject.GetReason()), 0, bd_addr, bluetooth::hci::LinkType::ACL,
4860 bluetooth::hci::Enable::DISABLED));
4861 }
4862 }
4863
IncomingPageResponsePacket(model::packets::LinkLayerPacketView incoming)4864 void LinkLayerController::IncomingPageResponsePacket(model::packets::LinkLayerPacketView incoming) {
4865 auto bd_addr = incoming.GetSourceAddress();
4866 auto response = model::packets::PageResponseView::Create(incoming);
4867 ASSERT(response.IsValid());
4868
4869 if (!page_.has_value() || page_->bd_addr != bd_addr) {
4870 INFO(id_,
4871 "ignoring Page Response packet received when not in Page state,"
4872 " or paging to a different address");
4873 return;
4874 }
4875
4876 INFO(id_, "Received Page Response packet from {}", bd_addr);
4877
4878 uint16_t connection_handle = connections_.CreateConnection(bd_addr, GetAddress(), false);
4879 ASSERT(connection_handle != kReservedHandle);
4880
4881 bluetooth::hci::Role role = page_->allow_role_switch && response.GetTryRoleSwitch()
4882 ? bluetooth::hci::Role::PERIPHERAL
4883 : bluetooth::hci::Role::CENTRAL;
4884
4885 AclConnection& connection = connections_.GetAclConnection(connection_handle);
4886 CheckExpiringConnection(connection_handle);
4887 connection.SetLinkPolicySettings(default_link_policy_settings_);
4888 connection.SetRole(role);
4889 page_ = {};
4890
4891 ASSERT(link_manager_add_link(lm_.get(), reinterpret_cast<const uint8_t(*)[6]>(bd_addr.data())));
4892
4893 // Role change event before connection complete generates an HCI Role Change
4894 // event on the initiator side if accepted; the event is sent before the
4895 // HCI Connection Complete event.
4896 if (role == bluetooth::hci::Role::PERIPHERAL && IsEventUnmasked(EventCode::ROLE_CHANGE)) {
4897 send_event_(bluetooth::hci::RoleChangeBuilder::Create(ErrorCode::SUCCESS, bd_addr, role));
4898 }
4899
4900 if (IsEventUnmasked(EventCode::CONNECTION_COMPLETE)) {
4901 send_event_(bluetooth::hci::ConnectionCompleteBuilder::Create(
4902 ErrorCode::SUCCESS, connection_handle, bd_addr, bluetooth::hci::LinkType::ACL,
4903 bluetooth::hci::Enable::DISABLED));
4904 }
4905 }
4906
Tick()4907 void LinkLayerController::Tick() {
4908 RunPendingTasks();
4909 Paging();
4910
4911 if (inquiry_timer_task_id_ != kInvalidTaskId) {
4912 Inquiry();
4913 }
4914 LeAdvertising();
4915 LeScanning();
4916 link_manager_tick(lm_.get());
4917 }
4918
Close()4919 void LinkLayerController::Close() {
4920 for (auto handle : connections_.GetAclHandles()) {
4921 Disconnect(handle, ErrorCode::REMOTE_DEVICE_TERMINATED_CONNECTION_POWER_OFF,
4922 ErrorCode::REMOTE_DEVICE_TERMINATED_CONNECTION_POWER_OFF);
4923 }
4924 }
4925
RegisterEventChannel(const std::function<void (std::shared_ptr<bluetooth::hci::EventBuilder>)> & send_event)4926 void LinkLayerController::RegisterEventChannel(
4927 const std::function<void(std::shared_ptr<bluetooth::hci::EventBuilder>)>& send_event) {
4928 send_event_ = send_event;
4929 }
4930
RegisterAclChannel(const std::function<void (std::shared_ptr<bluetooth::hci::AclBuilder>)> & send_acl)4931 void LinkLayerController::RegisterAclChannel(
4932 const std::function<void(std::shared_ptr<bluetooth::hci::AclBuilder>)>& send_acl) {
4933 send_acl_ = send_acl;
4934 }
4935
RegisterScoChannel(const std::function<void (std::shared_ptr<bluetooth::hci::ScoBuilder>)> & send_sco)4936 void LinkLayerController::RegisterScoChannel(
4937 const std::function<void(std::shared_ptr<bluetooth::hci::ScoBuilder>)>& send_sco) {
4938 send_sco_ = send_sco;
4939 }
4940
RegisterIsoChannel(const std::function<void (std::shared_ptr<bluetooth::hci::IsoBuilder>)> & send_iso)4941 void LinkLayerController::RegisterIsoChannel(
4942 const std::function<void(std::shared_ptr<bluetooth::hci::IsoBuilder>)>& send_iso) {
4943 send_iso_ = send_iso;
4944 }
4945
RegisterRemoteChannel(const std::function<void (std::shared_ptr<model::packets::LinkLayerPacketBuilder>,Phy::Type,int8_t)> & send_to_remote)4946 void LinkLayerController::RegisterRemoteChannel(
4947 const std::function<void(std::shared_ptr<model::packets::LinkLayerPacketBuilder>, Phy::Type,
4948 int8_t)>& send_to_remote) {
4949 send_to_remote_ = send_to_remote;
4950 }
4951
ForwardToLm(bluetooth::hci::CommandView command)4952 void LinkLayerController::ForwardToLm(bluetooth::hci::CommandView command) {
4953 auto packet = command.bytes().bytes();
4954 ASSERT(link_manager_ingest_hci(lm_.get(), packet.data(), packet.size()));
4955 }
4956
ForwardToLl(bluetooth::hci::CommandView command)4957 void LinkLayerController::ForwardToLl(bluetooth::hci::CommandView command) {
4958 auto packet = command.bytes().bytes();
4959 ASSERT(link_layer_ingest_hci(ll_.get(), packet.data(), packet.size()));
4960 }
4961
ReadCurrentIacLap() const4962 std::vector<bluetooth::hci::Lap> const& LinkLayerController::ReadCurrentIacLap() const {
4963 return current_iac_lap_list_;
4964 }
4965
WriteCurrentIacLap(std::vector<bluetooth::hci::Lap> iac_lap)4966 void LinkLayerController::WriteCurrentIacLap(std::vector<bluetooth::hci::Lap> iac_lap) {
4967 current_iac_lap_list_.swap(iac_lap);
4968
4969 // If Num_Current_IAC is greater than Num_Supported_IAC then only the first
4970 // Num_Supported_IAC shall be stored in the Controller
4971 if (current_iac_lap_list_.size() > properties_.num_supported_iac) {
4972 current_iac_lap_list_.resize(properties_.num_supported_iac);
4973 }
4974 }
4975
AcceptConnectionRequest(const Address & bd_addr,bool try_role_switch)4976 ErrorCode LinkLayerController::AcceptConnectionRequest(const Address& bd_addr,
4977 bool try_role_switch) {
4978 if (connections_.HasPendingConnection(bd_addr)) {
4979 INFO(id_, "Accepting connection request from {}", bd_addr);
4980 ScheduleTask(kNoDelayMs, [this, bd_addr, try_role_switch]() {
4981 INFO(id_, "Accepted connection from {}", bd_addr);
4982 MakePeripheralConnection(bd_addr, try_role_switch);
4983 });
4984
4985 return ErrorCode::SUCCESS;
4986 }
4987
4988 // The HCI command Accept Connection may be used to accept incoming SCO
4989 // connection requests.
4990 if (connections_.HasPendingScoConnection(bd_addr)) {
4991 ErrorCode status = ErrorCode::SUCCESS;
4992 uint16_t sco_handle = 0;
4993 ScoLinkParameters link_parameters = {};
4994 ScoConnectionParameters connection_parameters =
4995 connections_.GetScoConnectionParameters(bd_addr);
4996
4997 if (!connections_.AcceptPendingScoConnection(bd_addr, connection_parameters, [this, bd_addr] {
4998 return LinkLayerController::StartScoStream(bd_addr);
4999 })) {
5000 connections_.CancelPendingScoConnection(bd_addr);
5001 status = ErrorCode::SCO_INTERVAL_REJECTED; // TODO: proper status code
5002 } else {
5003 sco_handle = connections_.GetScoHandle(bd_addr);
5004 link_parameters = connections_.GetScoLinkParameters(bd_addr);
5005 }
5006
5007 // Send eSCO connection response to peer.
5008 SendLinkLayerPacket(model::packets::ScoConnectionResponseBuilder::Create(
5009 GetAddress(), bd_addr, (uint8_t)status, link_parameters.transmission_interval,
5010 link_parameters.retransmission_window, link_parameters.rx_packet_length,
5011 link_parameters.tx_packet_length, link_parameters.air_mode, link_parameters.extended));
5012
5013 // Schedule HCI Connection Complete event.
5014 if (IsEventUnmasked(EventCode::CONNECTION_COMPLETE)) {
5015 ScheduleTask(kNoDelayMs, [this, status, sco_handle, bd_addr]() {
5016 send_event_(bluetooth::hci::ConnectionCompleteBuilder::Create(
5017 ErrorCode(status), sco_handle, bd_addr, bluetooth::hci::LinkType::SCO,
5018 bluetooth::hci::Enable::DISABLED));
5019 });
5020 }
5021
5022 return ErrorCode::SUCCESS;
5023 }
5024
5025 INFO(id_, "No pending connection for {}", bd_addr);
5026 return ErrorCode::UNKNOWN_CONNECTION;
5027 }
5028
MakePeripheralConnection(const Address & bd_addr,bool try_role_switch)5029 void LinkLayerController::MakePeripheralConnection(const Address& bd_addr, bool try_role_switch) {
5030 uint16_t connection_handle = connections_.CreateConnection(bd_addr, GetAddress());
5031 if (connection_handle == kReservedHandle) {
5032 INFO(id_, "CreateConnection failed");
5033 return;
5034 }
5035
5036 bluetooth::hci::Role role =
5037 try_role_switch && connections_.IsRoleSwitchAllowedForPendingConnection()
5038 ? bluetooth::hci::Role::CENTRAL
5039 : bluetooth::hci::Role::PERIPHERAL;
5040
5041 AclConnection& connection = connections_.GetAclConnection(connection_handle);
5042 CheckExpiringConnection(connection_handle);
5043 connection.SetLinkPolicySettings(default_link_policy_settings_);
5044 connection.SetRole(role);
5045
5046 ASSERT(link_manager_add_link(lm_.get(), reinterpret_cast<const uint8_t(*)[6]>(bd_addr.data())));
5047
5048 // Role change event before connection complete generates an HCI Role Change
5049 // event on the acceptor side if accepted; the event is sent before the
5050 // HCI Connection Complete event.
5051 if (role == bluetooth::hci::Role::CENTRAL && IsEventUnmasked(EventCode::ROLE_CHANGE)) {
5052 INFO(id_, "Role at connection setup accepted");
5053 send_event_(bluetooth::hci::RoleChangeBuilder::Create(ErrorCode::SUCCESS, bd_addr, role));
5054 }
5055
5056 if (IsEventUnmasked(EventCode::CONNECTION_COMPLETE)) {
5057 send_event_(bluetooth::hci::ConnectionCompleteBuilder::Create(
5058 ErrorCode::SUCCESS, connection_handle, bd_addr, bluetooth::hci::LinkType::ACL,
5059 bluetooth::hci::Enable::DISABLED));
5060 }
5061
5062 // If the current Host was initiating a connection to the same bd_addr,
5063 // send a connection complete event for the pending Create Connection
5064 // command and cancel the paging.
5065 if (page_.has_value() && page_->bd_addr == bd_addr) {
5066 // TODO: the core specification is very unclear as to what behavior
5067 // is expected when two connections are established simultaneously.
5068 // This implementation considers that a unique HCI Connection Complete
5069 // event is expected for both the HCI Create Connection and HCI Accept
5070 // Connection Request commands.
5071 page_ = {};
5072 }
5073
5074 INFO(id_, "Sending page response to {}", bd_addr.ToString());
5075 SendLinkLayerPacket(
5076 model::packets::PageResponseBuilder::Create(GetAddress(), bd_addr, try_role_switch));
5077 }
5078
RejectConnectionRequest(const Address & addr,uint8_t reason)5079 ErrorCode LinkLayerController::RejectConnectionRequest(const Address& addr, uint8_t reason) {
5080 if (!connections_.HasPendingConnection(addr)) {
5081 INFO(id_, "No pending connection for {}", addr);
5082 return ErrorCode::UNKNOWN_CONNECTION;
5083 }
5084
5085 ScheduleTask(kNoDelayMs, [this, addr, reason]() { RejectPeripheralConnection(addr, reason); });
5086
5087 return ErrorCode::SUCCESS;
5088 }
5089
RejectPeripheralConnection(const Address & addr,uint8_t reason)5090 void LinkLayerController::RejectPeripheralConnection(const Address& addr, uint8_t reason) {
5091 INFO(id_, "Sending page reject to {} (reason 0x{:02x})", addr, reason);
5092 SendLinkLayerPacket(model::packets::PageRejectBuilder::Create(GetAddress(), addr, reason));
5093
5094 if (IsEventUnmasked(EventCode::CONNECTION_COMPLETE)) {
5095 send_event_(bluetooth::hci::ConnectionCompleteBuilder::Create(
5096 static_cast<ErrorCode>(reason), 0xeff, addr, bluetooth::hci::LinkType::ACL,
5097 bluetooth::hci::Enable::DISABLED));
5098 }
5099 }
5100
CreateConnection(const Address & bd_addr,uint16_t,uint8_t,uint16_t,uint8_t allow_role_switch)5101 ErrorCode LinkLayerController::CreateConnection(const Address& bd_addr, uint16_t /* packet_type */,
5102 uint8_t /* page_scan_mode */,
5103 uint16_t /* clock_offset */,
5104 uint8_t allow_role_switch) {
5105 // RootCanal only accepts one pending outgoing connection at any time.
5106 if (page_.has_value()) {
5107 INFO(id_, "Create Connection command is already pending");
5108 return ErrorCode::COMMAND_DISALLOWED;
5109 }
5110
5111 // Reject the command if a connection or pending connection already exists
5112 // for the selected peer address.
5113 if (connections_.HasPendingConnection(bd_addr) ||
5114 connections_.GetAclConnectionHandle(bd_addr).has_value()) {
5115 INFO(id_, "Connection with {} already exists", bd_addr.ToString());
5116 return ErrorCode::CONNECTION_ALREADY_EXISTS;
5117 }
5118
5119 auto now = std::chrono::steady_clock::now();
5120 page_ = Page{
5121 .bd_addr = bd_addr,
5122 .allow_role_switch = allow_role_switch,
5123 .next_page_event = now + kPageInterval,
5124 .page_timeout = now + slots(page_timeout_),
5125 };
5126
5127 return ErrorCode::SUCCESS;
5128 }
5129
CreateConnectionCancel(const Address & bd_addr)5130 ErrorCode LinkLayerController::CreateConnectionCancel(const Address& bd_addr) {
5131 // If the HCI_Create_Connection_Cancel command is sent to the Controller
5132 // without a preceding HCI_Create_Connection command to the same device,
5133 // the BR/EDR Controller shall return an HCI_Command_Complete event with
5134 // the error code Unknown Connection Identifier (0x02)
5135 if (!page_.has_value() || page_->bd_addr != bd_addr) {
5136 INFO(id_, "no pending connection to {}", bd_addr.ToString());
5137 return ErrorCode::UNKNOWN_CONNECTION;
5138 }
5139
5140 // The HCI_Connection_Complete event for the corresponding HCI_Create_-
5141 // Connection command shall always be sent. The HCI_Connection_Complete
5142 // event shall be sent after the HCI_Command_Complete event for the
5143 // HCI_Create_Connection_Cancel command. If the cancellation was successful,
5144 // the HCI_Connection_Complete event will be generated with the error code
5145 // Unknown Connection Identifier (0x02).
5146 if (IsEventUnmasked(EventCode::CONNECTION_COMPLETE)) {
5147 ScheduleTask(kNoDelayMs, [this, bd_addr]() {
5148 send_event_(bluetooth::hci::ConnectionCompleteBuilder::Create(
5149 ErrorCode::UNKNOWN_CONNECTION, 0, bd_addr, bluetooth::hci::LinkType::ACL,
5150 bluetooth::hci::Enable::DISABLED));
5151 });
5152 }
5153
5154 page_ = {};
5155 return ErrorCode::SUCCESS;
5156 }
5157
SendDisconnectionCompleteEvent(uint16_t handle,ErrorCode reason)5158 void LinkLayerController::SendDisconnectionCompleteEvent(uint16_t handle, ErrorCode reason) {
5159 if (IsEventUnmasked(EventCode::DISCONNECTION_COMPLETE)) {
5160 ScheduleTask(kNoDelayMs, [this, handle, reason]() {
5161 send_event_(bluetooth::hci::DisconnectionCompleteBuilder::Create(ErrorCode::SUCCESS, handle,
5162 reason));
5163 });
5164 }
5165 }
5166
Disconnect(uint16_t handle,ErrorCode host_reason,ErrorCode controller_reason)5167 ErrorCode LinkLayerController::Disconnect(uint16_t handle, ErrorCode host_reason,
5168 ErrorCode controller_reason) {
5169 if (connections_.HasScoHandle(handle)) {
5170 const Address remote = connections_.GetScoAddress(handle);
5171 INFO(id_, "Disconnecting eSCO connection with {}", remote);
5172
5173 SendLinkLayerPacket(model::packets::ScoDisconnectBuilder::Create(
5174 GetAddress(), remote, static_cast<uint8_t>(host_reason)));
5175
5176 connections_.Disconnect(handle, [this](TaskId task_id) { CancelScheduledTask(task_id); });
5177 SendDisconnectionCompleteEvent(handle, controller_reason);
5178 return ErrorCode::SUCCESS;
5179 }
5180
5181 if (!connections_.HasHandle(handle)) {
5182 return ErrorCode::UNKNOWN_CONNECTION;
5183 }
5184
5185 const AddressWithType remote = connections_.GetAddress(handle);
5186 auto is_br_edr = connections_.GetPhyType(handle) == Phy::Type::BR_EDR;
5187
5188 if (is_br_edr) {
5189 INFO(id_, "Disconnecting ACL connection with {}", remote);
5190
5191 uint16_t sco_handle = connections_.GetScoHandle(remote.GetAddress());
5192 if (sco_handle != kReservedHandle) {
5193 SendLinkLayerPacket(model::packets::ScoDisconnectBuilder::Create(
5194 GetAddress(), remote.GetAddress(), static_cast<uint8_t>(host_reason)));
5195
5196 connections_.Disconnect(sco_handle, [this](TaskId task_id) { CancelScheduledTask(task_id); });
5197 SendDisconnectionCompleteEvent(sco_handle, controller_reason);
5198 }
5199
5200 SendLinkLayerPacket(model::packets::DisconnectBuilder::Create(
5201 GetAddress(), remote.GetAddress(), static_cast<uint8_t>(host_reason)));
5202 } else {
5203 INFO(id_, "Disconnecting LE connection with {}", remote);
5204
5205 SendLeLinkLayerPacket(model::packets::DisconnectBuilder::Create(
5206 connections_.GetOwnAddress(handle).GetAddress(), remote.GetAddress(),
5207 static_cast<uint8_t>(host_reason)));
5208 }
5209
5210 connections_.Disconnect(handle, [this](TaskId task_id) { CancelScheduledTask(task_id); });
5211 SendDisconnectionCompleteEvent(handle, controller_reason);
5212 if (is_br_edr) {
5213 ASSERT(link_manager_remove_link(lm_.get(),
5214 reinterpret_cast<uint8_t(*)[6]>(remote.GetAddress().data())));
5215 } else {
5216 ASSERT(link_layer_remove_link(ll_.get(), handle));
5217 }
5218 return ErrorCode::SUCCESS;
5219 }
5220
ChangeConnectionPacketType(uint16_t handle,uint16_t types)5221 ErrorCode LinkLayerController::ChangeConnectionPacketType(uint16_t handle, uint16_t types) {
5222 if (!connections_.HasHandle(handle)) {
5223 return ErrorCode::UNKNOWN_CONNECTION;
5224 }
5225
5226 ScheduleTask(kNoDelayMs, [this, handle, types]() {
5227 if (IsEventUnmasked(EventCode::CONNECTION_PACKET_TYPE_CHANGED)) {
5228 send_event_(bluetooth::hci::ConnectionPacketTypeChangedBuilder::Create(ErrorCode::SUCCESS,
5229 handle, types));
5230 }
5231 });
5232
5233 return ErrorCode::SUCCESS;
5234 }
5235
5236 // NOLINTNEXTLINE(readability-convert-member-functions-to-static)
ChangeConnectionLinkKey(uint16_t handle)5237 ErrorCode LinkLayerController::ChangeConnectionLinkKey(uint16_t handle) {
5238 if (!connections_.HasHandle(handle)) {
5239 return ErrorCode::UNKNOWN_CONNECTION;
5240 }
5241
5242 // TODO: implement real logic
5243 return ErrorCode::COMMAND_DISALLOWED;
5244 }
5245
5246 // NOLINTNEXTLINE(readability-convert-member-functions-to-static)
CentralLinkKey(uint8_t)5247 ErrorCode LinkLayerController::CentralLinkKey(uint8_t /* key_flag */) {
5248 // TODO: implement real logic
5249 return ErrorCode::COMMAND_DISALLOWED;
5250 }
5251
HoldMode(uint16_t handle,uint16_t hold_mode_max_interval,uint16_t hold_mode_min_interval)5252 ErrorCode LinkLayerController::HoldMode(uint16_t handle, uint16_t hold_mode_max_interval,
5253 uint16_t hold_mode_min_interval) {
5254 if (!connections_.HasHandle(handle)) {
5255 return ErrorCode::UNKNOWN_CONNECTION;
5256 }
5257
5258 if (hold_mode_max_interval < hold_mode_min_interval) {
5259 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
5260 }
5261
5262 // TODO: implement real logic
5263 return ErrorCode::COMMAND_DISALLOWED;
5264 }
5265
SniffMode(uint16_t handle,uint16_t sniff_max_interval,uint16_t sniff_min_interval,uint16_t sniff_attempt,uint16_t sniff_timeout)5266 ErrorCode LinkLayerController::SniffMode(uint16_t handle, uint16_t sniff_max_interval,
5267 uint16_t sniff_min_interval, uint16_t sniff_attempt,
5268 uint16_t sniff_timeout) {
5269 if (!connections_.HasHandle(handle)) {
5270 return ErrorCode::UNKNOWN_CONNECTION;
5271 }
5272
5273 if (sniff_max_interval < sniff_min_interval || sniff_attempt < 0x0001 || sniff_attempt > 0x7FFF ||
5274 sniff_timeout > 0x7FFF) {
5275 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
5276 }
5277
5278 // TODO: implement real logic
5279 return ErrorCode::COMMAND_DISALLOWED;
5280 }
5281
ExitSniffMode(uint16_t handle)5282 ErrorCode LinkLayerController::ExitSniffMode(uint16_t handle) {
5283 if (!connections_.HasHandle(handle)) {
5284 return ErrorCode::UNKNOWN_CONNECTION;
5285 }
5286
5287 // TODO: implement real logic
5288 return ErrorCode::COMMAND_DISALLOWED;
5289 }
5290
QosSetup(uint16_t handle,uint8_t service_type,uint32_t,uint32_t,uint32_t,uint32_t)5291 ErrorCode LinkLayerController::QosSetup(uint16_t handle, uint8_t service_type,
5292 uint32_t /* token_rate */, uint32_t /* peak_bandwidth */,
5293 uint32_t /* latency */, uint32_t /* delay_variation */) {
5294 if (!connections_.HasHandle(handle)) {
5295 return ErrorCode::UNKNOWN_CONNECTION;
5296 }
5297
5298 if (service_type > 0x02) {
5299 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
5300 }
5301
5302 // TODO: implement real logic
5303 return ErrorCode::COMMAND_DISALLOWED;
5304 }
5305
RoleDiscovery(uint16_t handle,bluetooth::hci::Role * role)5306 ErrorCode LinkLayerController::RoleDiscovery(uint16_t handle, bluetooth::hci::Role* role) {
5307 if (!connections_.HasHandle(handle)) {
5308 return ErrorCode::UNKNOWN_CONNECTION;
5309 }
5310
5311 *role = connections_.GetAclRole(handle);
5312 return ErrorCode::SUCCESS;
5313 }
5314
SwitchRole(Address bd_addr,bluetooth::hci::Role role)5315 ErrorCode LinkLayerController::SwitchRole(Address bd_addr, bluetooth::hci::Role role) {
5316 // The BD_ADDR command parameter indicates for which connection
5317 // the role switch is to be performed and shall specify a BR/EDR Controller
5318 // for which a connection already exists.
5319 uint16_t connection_handle = connections_.GetHandleOnlyAddress(bd_addr);
5320 if (connection_handle == kReservedHandle) {
5321 INFO(id_, "unknown connection address {}", bd_addr);
5322 return ErrorCode::UNKNOWN_CONNECTION;
5323 }
5324
5325 AclConnection& connection = connections_.GetAclConnection(connection_handle);
5326
5327 // If there is an (e)SCO connection between the local device and the device
5328 // identified by the BD_ADDR parameter, an attempt to perform a role switch
5329 // shall be rejected by the local device.
5330 if (connections_.GetScoHandle(bd_addr) != kReservedHandle) {
5331 INFO(id_,
5332 "role switch rejected because an Sco link is opened with"
5333 " the target device");
5334 return ErrorCode::COMMAND_DISALLOWED;
5335 }
5336
5337 // If the connection between the local device and the device identified by the
5338 // BD_ADDR parameter is placed in Sniff mode, an attempt to perform a role
5339 // switch shall be rejected by the local device.
5340 if (connection.GetMode() == AclConnectionState::kSniffMode) {
5341 INFO(id_, "role switch rejected because the acl connection is in sniff mode");
5342 return ErrorCode::COMMAND_DISALLOWED;
5343 }
5344
5345 if (role != connection.GetRole()) {
5346 SendLinkLayerPacket(model::packets::RoleSwitchRequestBuilder::Create(GetAddress(), bd_addr));
5347 } else if (IsEventUnmasked(EventCode::ROLE_CHANGE)) {
5348 // Note: the status is Success only if the role change procedure was
5349 // actually performed, otherwise the status is >0.
5350 ScheduleTask(kNoDelayMs, [this, bd_addr, role]() {
5351 send_event_(bluetooth::hci::RoleChangeBuilder::Create(ErrorCode::ROLE_SWITCH_FAILED, bd_addr,
5352 role));
5353 });
5354 }
5355
5356 return ErrorCode::SUCCESS;
5357 }
5358
IncomingRoleSwitchRequest(model::packets::LinkLayerPacketView incoming)5359 void LinkLayerController::IncomingRoleSwitchRequest(model::packets::LinkLayerPacketView incoming) {
5360 auto bd_addr = incoming.GetSourceAddress();
5361 auto connection_handle = connections_.GetHandleOnlyAddress(bd_addr);
5362 auto switch_req = model::packets::RoleSwitchRequestView::Create(incoming);
5363 ASSERT(switch_req.IsValid());
5364
5365 if (connection_handle == kReservedHandle) {
5366 INFO(id_, "ignoring Switch Request received on unknown connection");
5367 return;
5368 }
5369
5370 AclConnection& connection = connections_.GetAclConnection(connection_handle);
5371
5372 if (!connection.IsRoleSwitchEnabled()) {
5373 INFO(id_, "role switch disabled by local link policy settings");
5374 SendLinkLayerPacket(model::packets::RoleSwitchResponseBuilder::Create(
5375 GetAddress(), bd_addr, static_cast<uint8_t>(ErrorCode::ROLE_CHANGE_NOT_ALLOWED)));
5376 } else {
5377 INFO(id_, "role switch request accepted by local device");
5378 SendLinkLayerPacket(model::packets::RoleSwitchResponseBuilder::Create(
5379 GetAddress(), bd_addr, static_cast<uint8_t>(ErrorCode::SUCCESS)));
5380
5381 bluetooth::hci::Role new_role = connection.GetRole() == bluetooth::hci::Role::CENTRAL
5382 ? bluetooth::hci::Role::PERIPHERAL
5383 : bluetooth::hci::Role::CENTRAL;
5384
5385 connection.SetRole(new_role);
5386
5387 if (IsEventUnmasked(EventCode::ROLE_CHANGE)) {
5388 ScheduleTask(kNoDelayMs, [this, bd_addr, new_role]() {
5389 send_event_(
5390 bluetooth::hci::RoleChangeBuilder::Create(ErrorCode::SUCCESS, bd_addr, new_role));
5391 });
5392 }
5393 }
5394 }
5395
IncomingRoleSwitchResponse(model::packets::LinkLayerPacketView incoming)5396 void LinkLayerController::IncomingRoleSwitchResponse(model::packets::LinkLayerPacketView incoming) {
5397 auto bd_addr = incoming.GetSourceAddress();
5398 auto connection_handle = connections_.GetHandleOnlyAddress(bd_addr);
5399 auto switch_rsp = model::packets::RoleSwitchResponseView::Create(incoming);
5400 ASSERT(switch_rsp.IsValid());
5401
5402 if (connection_handle == kReservedHandle) {
5403 INFO(id_, "ignoring Switch Response received on unknown connection");
5404 return;
5405 }
5406
5407 AclConnection& connection = connections_.GetAclConnection(connection_handle);
5408 ErrorCode status = ErrorCode(switch_rsp.GetStatus());
5409 bluetooth::hci::Role new_role = status != ErrorCode::SUCCESS ? connection.GetRole()
5410 : connection.GetRole() == bluetooth::hci::Role::CENTRAL
5411 ? bluetooth::hci::Role::PERIPHERAL
5412 : bluetooth::hci::Role::CENTRAL;
5413
5414 connection.SetRole(new_role);
5415
5416 if (IsEventUnmasked(EventCode::ROLE_CHANGE)) {
5417 ScheduleTask(kNoDelayMs, [this, status, bd_addr, new_role]() {
5418 send_event_(bluetooth::hci::RoleChangeBuilder::Create(status, bd_addr, new_role));
5419 });
5420 }
5421 }
5422
ReadLinkPolicySettings(uint16_t handle,uint16_t * settings)5423 ErrorCode LinkLayerController::ReadLinkPolicySettings(uint16_t handle, uint16_t* settings) {
5424 if (!connections_.HasHandle(handle)) {
5425 return ErrorCode::UNKNOWN_CONNECTION;
5426 }
5427
5428 *settings = connections_.GetAclLinkPolicySettings(handle);
5429 return ErrorCode::SUCCESS;
5430 }
5431
WriteLinkPolicySettings(uint16_t handle,uint16_t settings)5432 ErrorCode LinkLayerController::WriteLinkPolicySettings(uint16_t handle, uint16_t settings) {
5433 if (!connections_.HasHandle(handle)) {
5434 return ErrorCode::UNKNOWN_CONNECTION;
5435 }
5436 if (settings > 7 /* Sniff + Hold + Role switch */) {
5437 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
5438 }
5439 connections_.SetAclLinkPolicySettings(handle, settings);
5440 return ErrorCode::SUCCESS;
5441 }
5442
WriteDefaultLinkPolicySettings(uint16_t settings)5443 ErrorCode LinkLayerController::WriteDefaultLinkPolicySettings(uint16_t settings) {
5444 if (settings > 7 /* Sniff + Hold + Role switch */) {
5445 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
5446 }
5447
5448 default_link_policy_settings_ = settings;
5449 return ErrorCode::SUCCESS;
5450 }
5451
ReadDefaultLinkPolicySettings() const5452 uint16_t LinkLayerController::ReadDefaultLinkPolicySettings() const {
5453 return default_link_policy_settings_;
5454 }
5455
ReadLocalOobData()5456 void LinkLayerController::ReadLocalOobData() {
5457 std::array<uint8_t, 16> c_array({'c', ' ', 'a', 'r', 'r', 'a', 'y', ' ', '0', '0', '0', '0', '0',
5458 '0', static_cast<uint8_t>((oob_id_ % 0x10000) >> 8),
5459 static_cast<uint8_t>(oob_id_ % 0x100)});
5460
5461 std::array<uint8_t, 16> r_array({'r', ' ', 'a', 'r', 'r', 'a', 'y', ' ', '0', '0', '0', '0', '0',
5462 '0', static_cast<uint8_t>((oob_id_ % 0x10000) >> 8),
5463 static_cast<uint8_t>(oob_id_ % 0x100)});
5464
5465 send_event_(bluetooth::hci::ReadLocalOobDataCompleteBuilder::Create(1, ErrorCode::SUCCESS,
5466 c_array, r_array));
5467 oob_id_ += 1;
5468 }
5469
ReadLocalOobExtendedData()5470 void LinkLayerController::ReadLocalOobExtendedData() {
5471 std::array<uint8_t, 16> c_192_array({'c', ' ', 'a', 'r', 'r', 'a', 'y', ' ', '1', '9', '2', '0',
5472 '0', '0', static_cast<uint8_t>((oob_id_ % 0x10000) >> 8),
5473 static_cast<uint8_t>(oob_id_ % 0x100)});
5474
5475 std::array<uint8_t, 16> r_192_array({'r', ' ', 'a', 'r', 'r', 'a', 'y', ' ', '1', '9', '2', '0',
5476 '0', '0', static_cast<uint8_t>((oob_id_ % 0x10000) >> 8),
5477 static_cast<uint8_t>(oob_id_ % 0x100)});
5478
5479 std::array<uint8_t, 16> c_256_array({'c', ' ', 'a', 'r', 'r', 'a', 'y', ' ', '2', '5', '6', '0',
5480 '0', '0', static_cast<uint8_t>((oob_id_ % 0x10000) >> 8),
5481 static_cast<uint8_t>(oob_id_ % 0x100)});
5482
5483 std::array<uint8_t, 16> r_256_array({'r', ' ', 'a', 'r', 'r', 'a', 'y', ' ', '2', '5', '6', '0',
5484 '0', '0', static_cast<uint8_t>((oob_id_ % 0x10000) >> 8),
5485 static_cast<uint8_t>(oob_id_ % 0x100)});
5486
5487 send_event_(bluetooth::hci::ReadLocalOobExtendedDataCompleteBuilder::Create(
5488 1, ErrorCode::SUCCESS, c_192_array, r_192_array, c_256_array, r_256_array));
5489 oob_id_ += 1;
5490 }
5491
FlowSpecification(uint16_t handle,uint8_t flow_direction,uint8_t service_type,uint32_t,uint32_t,uint32_t,uint32_t)5492 ErrorCode LinkLayerController::FlowSpecification(uint16_t handle, uint8_t flow_direction,
5493 uint8_t service_type, uint32_t /* token_rate */,
5494 uint32_t /* token_bucket_size */,
5495 uint32_t /* peak_bandwidth */,
5496 uint32_t /* access_latency */) {
5497 if (!connections_.HasHandle(handle)) {
5498 return ErrorCode::UNKNOWN_CONNECTION;
5499 }
5500
5501 if (flow_direction > 0x01 || service_type > 0x02) {
5502 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
5503 }
5504
5505 // TODO: implement real logic
5506 return ErrorCode::COMMAND_DISALLOWED;
5507 }
5508
WriteLinkSupervisionTimeout(uint16_t handle,uint16_t)5509 ErrorCode LinkLayerController::WriteLinkSupervisionTimeout(uint16_t handle,
5510 uint16_t /* timeout */) {
5511 if (!connections_.HasHandle(handle)) {
5512 return ErrorCode::UNKNOWN_CONNECTION;
5513 }
5514 return ErrorCode::SUCCESS;
5515 }
5516
LeConnectionUpdateComplete(uint16_t handle,uint16_t interval_min,uint16_t interval_max,uint16_t latency,uint16_t supervision_timeout)5517 void LinkLayerController::LeConnectionUpdateComplete(uint16_t handle, uint16_t interval_min,
5518 uint16_t interval_max, uint16_t latency,
5519 uint16_t supervision_timeout) {
5520 ErrorCode status = ErrorCode::SUCCESS;
5521 if (!connections_.HasHandle(handle)) {
5522 status = ErrorCode::UNKNOWN_CONNECTION;
5523 }
5524
5525 if (interval_min < 6 || interval_max > 0xC80 || interval_min > interval_max ||
5526 interval_max < interval_min || latency > 0x1F3 || supervision_timeout < 0xA ||
5527 supervision_timeout > 0xC80 ||
5528 // The Supervision_Timeout in milliseconds (*10) shall be larger than (1 +
5529 // Connection_Latency) * Connection_Interval_Max (* 5/4) * 2
5530 supervision_timeout <= ((((1 + latency) * interval_max * 10) / 4) / 10)) {
5531 status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
5532 }
5533 uint16_t interval = (interval_min + interval_max) / 2;
5534
5535 SendLeLinkLayerPacket(LeConnectionParameterUpdateBuilder::Create(
5536 connections_.GetOwnAddress(handle).GetAddress(),
5537 connections_.GetAddress(handle).GetAddress(), static_cast<uint8_t>(ErrorCode::SUCCESS),
5538 interval, latency, supervision_timeout));
5539
5540 if (IsLeEventUnmasked(SubeventCode::LE_CONNECTION_UPDATE_COMPLETE)) {
5541 send_event_(bluetooth::hci::LeConnectionUpdateCompleteBuilder::Create(
5542 status, handle, interval, latency, supervision_timeout));
5543 }
5544 }
5545
LeConnectionUpdate(uint16_t handle,uint16_t interval_min,uint16_t interval_max,uint16_t latency,uint16_t supervision_timeout)5546 ErrorCode LinkLayerController::LeConnectionUpdate(uint16_t handle, uint16_t interval_min,
5547 uint16_t interval_max, uint16_t latency,
5548 uint16_t supervision_timeout) {
5549 if (!connections_.HasHandle(handle)) {
5550 return ErrorCode::UNKNOWN_CONNECTION;
5551 }
5552
5553 bluetooth::hci::Role role = connections_.GetAclRole(handle);
5554
5555 if (role == bluetooth::hci::Role::CENTRAL) {
5556 // As Central, it is allowed to directly send
5557 // LL_CONNECTION_PARAM_UPDATE_IND to update the parameters.
5558 SendLeLinkLayerPacket(LeConnectionParameterUpdateBuilder::Create(
5559 connections_.GetOwnAddress(handle).GetAddress(),
5560 connections_.GetAddress(handle).GetAddress(), static_cast<uint8_t>(ErrorCode::SUCCESS),
5561 interval_max, latency, supervision_timeout));
5562
5563 if (IsLeEventUnmasked(SubeventCode::LE_CONNECTION_UPDATE_COMPLETE)) {
5564 send_event_(bluetooth::hci::LeConnectionUpdateCompleteBuilder::Create(
5565 ErrorCode::SUCCESS, handle, interval_max, latency, supervision_timeout));
5566 }
5567 } else {
5568 // Send LL_CONNECTION_PARAM_REQ and wait for LL_CONNECTION_PARAM_RSP
5569 // in return.
5570 SendLeLinkLayerPacket(LeConnectionParameterRequestBuilder::Create(
5571 connections_.GetOwnAddress(handle).GetAddress(),
5572 connections_.GetAddress(handle).GetAddress(), interval_min, interval_max, latency,
5573 supervision_timeout));
5574 }
5575
5576 return ErrorCode::SUCCESS;
5577 }
5578
LeRemoteConnectionParameterRequestReply(uint16_t connection_handle,uint16_t interval_min,uint16_t interval_max,uint16_t timeout,uint16_t latency,uint16_t minimum_ce_length,uint16_t maximum_ce_length)5579 ErrorCode LinkLayerController::LeRemoteConnectionParameterRequestReply(
5580 uint16_t connection_handle, uint16_t interval_min, uint16_t interval_max, uint16_t timeout,
5581 uint16_t latency, uint16_t minimum_ce_length, uint16_t maximum_ce_length) {
5582 if (!connections_.HasHandle(connection_handle)) {
5583 return ErrorCode::UNKNOWN_CONNECTION;
5584 }
5585
5586 if ((interval_min > interval_max) || (minimum_ce_length > maximum_ce_length)) {
5587 return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
5588 }
5589
5590 ScheduleTask(kNoDelayMs, [this, connection_handle, interval_min, interval_max, latency,
5591 timeout]() {
5592 LeConnectionUpdateComplete(connection_handle, interval_min, interval_max, latency, timeout);
5593 });
5594 return ErrorCode::SUCCESS;
5595 }
5596
LeRemoteConnectionParameterRequestNegativeReply(uint16_t connection_handle,bluetooth::hci::ErrorCode reason)5597 ErrorCode LinkLayerController::LeRemoteConnectionParameterRequestNegativeReply(
5598 uint16_t connection_handle, bluetooth::hci::ErrorCode reason) {
5599 if (!connections_.HasHandle(connection_handle)) {
5600 return ErrorCode::UNKNOWN_CONNECTION;
5601 }
5602
5603 uint16_t interval = 0;
5604 uint16_t latency = 0;
5605 uint16_t timeout = 0;
5606 SendLeLinkLayerPacket(LeConnectionParameterUpdateBuilder::Create(
5607 connections_.GetOwnAddress(connection_handle).GetAddress(),
5608 connections_.GetAddress(connection_handle).GetAddress(), static_cast<uint8_t>(reason),
5609 interval, latency, timeout));
5610 return ErrorCode::SUCCESS;
5611 }
5612
HasAclConnection()5613 bool LinkLayerController::HasAclConnection() { return !connections_.GetAclHandles().empty(); }
5614
HasAclConnection(uint16_t connection_handle)5615 bool LinkLayerController::HasAclConnection(uint16_t connection_handle) {
5616 return connections_.HasHandle(connection_handle);
5617 }
5618
HandleLeEnableEncryption(uint16_t handle,std::array<uint8_t,8> rand,uint16_t ediv,std::array<uint8_t,kLtkSize> ltk)5619 void LinkLayerController::HandleLeEnableEncryption(uint16_t handle, std::array<uint8_t, 8> rand,
5620 uint16_t ediv,
5621 std::array<uint8_t, kLtkSize> ltk) {
5622 // TODO: Check keys
5623 // TODO: Block ACL traffic or at least guard against it
5624 if (!connections_.HasHandle(handle)) {
5625 return;
5626 }
5627 SendLeLinkLayerPacket(model::packets::LeEncryptConnectionBuilder::Create(
5628 connections_.GetOwnAddress(handle).GetAddress(),
5629 connections_.GetAddress(handle).GetAddress(), rand, ediv, ltk));
5630 }
5631
LeEnableEncryption(uint16_t handle,std::array<uint8_t,8> rand,uint16_t ediv,std::array<uint8_t,kLtkSize> ltk)5632 ErrorCode LinkLayerController::LeEnableEncryption(uint16_t handle, std::array<uint8_t, 8> rand,
5633 uint16_t ediv,
5634 std::array<uint8_t, kLtkSize> ltk) {
5635 if (!connections_.HasHandle(handle)) {
5636 INFO(id_, "Unknown handle 0x{:04x}", handle);
5637 return ErrorCode::UNKNOWN_CONNECTION;
5638 }
5639
5640 ScheduleTask(kNoDelayMs, [this, handle, rand, ediv, ltk]() {
5641 HandleLeEnableEncryption(handle, rand, ediv, ltk);
5642 });
5643 return ErrorCode::SUCCESS;
5644 }
5645
LeLongTermKeyRequestReply(uint16_t handle,std::array<uint8_t,kLtkSize> ltk)5646 ErrorCode LinkLayerController::LeLongTermKeyRequestReply(uint16_t handle,
5647 std::array<uint8_t, kLtkSize> ltk) {
5648 if (!connections_.HasHandle(handle)) {
5649 INFO(id_, "Unknown handle {:04x}", handle);
5650 return ErrorCode::UNKNOWN_CONNECTION;
5651 }
5652
5653 // TODO: Check keys
5654 if (connections_.IsEncrypted(handle)) {
5655 if (IsEventUnmasked(EventCode::ENCRYPTION_KEY_REFRESH_COMPLETE)) {
5656 send_event_(bluetooth::hci::EncryptionKeyRefreshCompleteBuilder::Create(ErrorCode::SUCCESS,
5657 handle));
5658 }
5659 } else {
5660 connections_.Encrypt(handle);
5661 if (IsEventUnmasked(EventCode::ENCRYPTION_CHANGE_V2)) {
5662 send_event_(bluetooth::hci::EncryptionChangeV2Builder::Create(
5663 ErrorCode::SUCCESS, handle, bluetooth::hci::EncryptionEnabled::ON,
5664 0x10 /* key_size */));
5665 } else if (IsEventUnmasked(EventCode::ENCRYPTION_CHANGE)) {
5666 send_event_(bluetooth::hci::EncryptionChangeBuilder::Create(
5667 ErrorCode::SUCCESS, handle, bluetooth::hci::EncryptionEnabled::ON));
5668 }
5669 }
5670 SendLeLinkLayerPacket(model::packets::LeEncryptConnectionResponseBuilder::Create(
5671 connections_.GetOwnAddress(handle).GetAddress(),
5672 connections_.GetAddress(handle).GetAddress(), std::array<uint8_t, 8>(), uint16_t(), ltk));
5673
5674 return ErrorCode::SUCCESS;
5675 }
5676
LeLongTermKeyRequestNegativeReply(uint16_t handle)5677 ErrorCode LinkLayerController::LeLongTermKeyRequestNegativeReply(uint16_t handle) {
5678 if (!connections_.HasHandle(handle)) {
5679 INFO(id_, "Unknown handle {:04x}", handle);
5680 return ErrorCode::UNKNOWN_CONNECTION;
5681 }
5682
5683 SendLeLinkLayerPacket(model::packets::LeEncryptConnectionResponseBuilder::Create(
5684 connections_.GetOwnAddress(handle).GetAddress(),
5685 connections_.GetAddress(handle).GetAddress(), std::array<uint8_t, 8>(), uint16_t(),
5686 std::array<uint8_t, 16>()));
5687 return ErrorCode::SUCCESS;
5688 }
5689
Reset()5690 void LinkLayerController::Reset() {
5691 host_supported_features_ = 0;
5692 le_host_support_ = false;
5693 secure_simple_pairing_host_support_ = false;
5694 secure_connections_host_support_ = false;
5695 le_host_supported_features_ = 0;
5696 connected_isochronous_stream_host_support_ = false;
5697 connection_subrating_host_support_ = false;
5698 random_address_ = Address::kEmpty;
5699 page_scan_enable_ = false;
5700 inquiry_scan_enable_ = false;
5701 inquiry_scan_interval_ = 0x1000;
5702 inquiry_scan_window_ = 0x0012;
5703 page_timeout_ = 0x2000;
5704 connection_accept_timeout_ = 0x1FA0;
5705 page_scan_interval_ = 0x0800;
5706 page_scan_window_ = 0x0012;
5707 voice_setting_ = 0x0060;
5708 authentication_enable_ = AuthenticationEnable::NOT_REQUIRED;
5709 default_link_policy_settings_ = 0x0000;
5710 sco_flow_control_enable_ = false;
5711 local_name_.fill(0);
5712 extended_inquiry_response_.fill(0);
5713 class_of_device_ = 0;
5714 min_encryption_key_size_ = 16;
5715 event_mask_ = 0x00001fffffffffff;
5716 event_mask_page_2_ = 0x0;
5717 le_event_mask_ = 0x01f;
5718 le_suggested_max_tx_octets_ = 0x001b;
5719 le_suggested_max_tx_time_ = 0x0148;
5720 resolvable_private_address_timeout_ = std::chrono::seconds(0x0384);
5721 page_scan_repetition_mode_ = PageScanRepetitionMode::R0;
5722 connections_ = AclConnectionHandler();
5723 oob_id_ = 1;
5724 key_id_ = 1;
5725 le_periodic_advertiser_list_.clear();
5726 le_filter_accept_list_.clear();
5727 le_resolving_list_.clear();
5728 le_resolving_list_enabled_ = false;
5729 legacy_advertising_in_use_ = false;
5730 extended_advertising_in_use_ = false;
5731 legacy_advertiser_ = LegacyAdvertiser{};
5732 extended_advertisers_.clear();
5733 scanner_ = Scanner{};
5734 apcf_scanner_ = ApcfScanner{};
5735 initiator_ = Initiator{};
5736 synchronizing_ = {};
5737 synchronized_ = {};
5738 last_inquiry_ = steady_clock::now();
5739 inquiry_mode_ = InquiryType::STANDARD;
5740 inquiry_lap_ = 0;
5741 inquiry_max_responses_ = 0;
5742 default_tx_phys_ = properties_.LeSupportedPhys();
5743 default_rx_phys_ = properties_.LeSupportedPhys();
5744
5745 bluetooth::hci::Lap general_iac;
5746 general_iac.lap_ = 0x33; // 0x9E8B33
5747 current_iac_lap_list_.clear();
5748 current_iac_lap_list_.emplace_back(general_iac);
5749
5750 page_ = {};
5751
5752 if (inquiry_timer_task_id_ != kInvalidTaskId) {
5753 CancelScheduledTask(inquiry_timer_task_id_);
5754 inquiry_timer_task_id_ = kInvalidTaskId;
5755 }
5756
5757 lm_.reset(link_manager_create(controller_ops_));
5758 ll_.reset(link_layer_create(controller_ops_));
5759 }
5760
5761 /// Drive the logic for the Page controller substate.
Paging()5762 void LinkLayerController::Paging() {
5763 auto now = std::chrono::steady_clock::now();
5764
5765 if (page_.has_value() && now >= page_->page_timeout) {
5766 INFO("page timeout triggered for connection with {}", page_->bd_addr.ToString());
5767
5768 send_event_(bluetooth::hci::ConnectionCompleteBuilder::Create(
5769 ErrorCode::PAGE_TIMEOUT, 0, page_->bd_addr, bluetooth::hci::LinkType::ACL,
5770 bluetooth::hci::Enable::DISABLED));
5771
5772 page_ = {};
5773 return;
5774 }
5775
5776 // Send a Page packet to the peer when a paging interval has passed.
5777 // Paging is suppressed while a pending connection with the same peer is
5778 // being established (i.e. two hosts initiated a connection simultaneously).
5779 if (page_.has_value() && now >= page_->next_page_event &&
5780 !connections_.HasPendingConnection(page_->bd_addr)) {
5781 SendLinkLayerPacket(model::packets::PageBuilder::Create(
5782 GetAddress(), page_->bd_addr, class_of_device_, page_->allow_role_switch));
5783 page_->next_page_event = now + kPageInterval;
5784 }
5785 }
5786
StartInquiry(milliseconds timeout)5787 void LinkLayerController::StartInquiry(milliseconds timeout) {
5788 inquiry_timer_task_id_ =
5789 ScheduleTask(milliseconds(timeout), [this]() { LinkLayerController::InquiryTimeout(); });
5790 }
5791
InquiryCancel()5792 void LinkLayerController::InquiryCancel() {
5793 ASSERT(inquiry_timer_task_id_ != kInvalidTaskId);
5794 CancelScheduledTask(inquiry_timer_task_id_);
5795 inquiry_timer_task_id_ = kInvalidTaskId;
5796 }
5797
InquiryTimeout()5798 void LinkLayerController::InquiryTimeout() {
5799 if (inquiry_timer_task_id_ != kInvalidTaskId) {
5800 inquiry_timer_task_id_ = kInvalidTaskId;
5801 if (IsEventUnmasked(EventCode::INQUIRY_COMPLETE)) {
5802 send_event_(bluetooth::hci::InquiryCompleteBuilder::Create(ErrorCode::SUCCESS));
5803 }
5804 }
5805 }
5806
SetInquiryMode(uint8_t mode)5807 void LinkLayerController::SetInquiryMode(uint8_t mode) {
5808 inquiry_mode_ = static_cast<model::packets::InquiryType>(mode);
5809 }
5810
SetInquiryLAP(uint64_t lap)5811 void LinkLayerController::SetInquiryLAP(uint64_t lap) { inquiry_lap_ = lap; }
5812
SetInquiryMaxResponses(uint8_t max)5813 void LinkLayerController::SetInquiryMaxResponses(uint8_t max) { inquiry_max_responses_ = max; }
5814
Inquiry()5815 void LinkLayerController::Inquiry() {
5816 steady_clock::time_point now = steady_clock::now();
5817 if (duration_cast<milliseconds>(now - last_inquiry_) < milliseconds(2000)) {
5818 return;
5819 }
5820
5821 SendLinkLayerPacket(model::packets::InquiryBuilder::Create(GetAddress(), Address::kEmpty,
5822 inquiry_mode_, inquiry_lap_));
5823 last_inquiry_ = now;
5824 }
5825
SetInquiryScanEnable(bool enable)5826 void LinkLayerController::SetInquiryScanEnable(bool enable) { inquiry_scan_enable_ = enable; }
5827
SetPageScanEnable(bool enable)5828 void LinkLayerController::SetPageScanEnable(bool enable) { page_scan_enable_ = enable; }
5829
SetPageTimeout(uint16_t page_timeout)5830 void LinkLayerController::SetPageTimeout(uint16_t page_timeout) { page_timeout_ = page_timeout; }
5831
AddScoConnection(uint16_t connection_handle,uint16_t packet_type,ScoDatapath datapath)5832 ErrorCode LinkLayerController::AddScoConnection(uint16_t connection_handle, uint16_t packet_type,
5833 ScoDatapath datapath) {
5834 if (!connections_.HasHandle(connection_handle)) {
5835 return ErrorCode::UNKNOWN_CONNECTION;
5836 }
5837
5838 Address bd_addr = connections_.GetAddress(connection_handle).GetAddress();
5839 if (connections_.HasPendingScoConnection(bd_addr)) {
5840 return ErrorCode::COMMAND_DISALLOWED;
5841 }
5842
5843 INFO(id_, "Creating SCO connection with {}", bd_addr);
5844
5845 // Save connection parameters.
5846 ScoConnectionParameters connection_parameters = {
5847 8000,
5848 8000,
5849 0xffff,
5850 0x60 /* 16bit CVSD */,
5851 (uint8_t)bluetooth::hci::RetransmissionEffort::NO_RETRANSMISSION,
5852 (uint16_t)((uint16_t)((packet_type >> 5) & 0x7U) |
5853 (uint16_t)bluetooth::hci::SynchronousPacketTypeBits::NO_2_EV3_ALLOWED |
5854 (uint16_t)bluetooth::hci::SynchronousPacketTypeBits::NO_3_EV3_ALLOWED |
5855 (uint16_t)bluetooth::hci::SynchronousPacketTypeBits::NO_2_EV5_ALLOWED |
5856 (uint16_t)bluetooth::hci::SynchronousPacketTypeBits::NO_3_EV5_ALLOWED)};
5857 connections_.CreateScoConnection(connections_.GetAddress(connection_handle).GetAddress(),
5858 connection_parameters, SCO_STATE_PENDING, datapath, true);
5859
5860 // Send SCO connection request to peer.
5861 SendLinkLayerPacket(model::packets::ScoConnectionRequestBuilder::Create(
5862 GetAddress(), bd_addr, connection_parameters.transmit_bandwidth,
5863 connection_parameters.receive_bandwidth, connection_parameters.max_latency,
5864 connection_parameters.voice_setting, connection_parameters.retransmission_effort,
5865 connection_parameters.packet_type, class_of_device_));
5866 return ErrorCode::SUCCESS;
5867 }
5868
SetupSynchronousConnection(uint16_t connection_handle,uint32_t transmit_bandwidth,uint32_t receive_bandwidth,uint16_t max_latency,uint16_t voice_setting,uint8_t retransmission_effort,uint16_t packet_types,ScoDatapath datapath)5869 ErrorCode LinkLayerController::SetupSynchronousConnection(
5870 uint16_t connection_handle, uint32_t transmit_bandwidth, uint32_t receive_bandwidth,
5871 uint16_t max_latency, uint16_t voice_setting, uint8_t retransmission_effort,
5872 uint16_t packet_types, ScoDatapath datapath) {
5873 if (!connections_.HasHandle(connection_handle)) {
5874 return ErrorCode::UNKNOWN_CONNECTION;
5875 }
5876
5877 Address bd_addr = connections_.GetAddress(connection_handle).GetAddress();
5878 if (connections_.HasPendingScoConnection(bd_addr)) {
5879 // This command may be used to modify an exising eSCO link.
5880 // Skip for now. TODO: should return an event
5881 // HCI_Synchronous_Connection_Changed on both sides.
5882 return ErrorCode::COMMAND_DISALLOWED;
5883 }
5884
5885 INFO(id_, "Creating eSCO connection with {}", bd_addr);
5886
5887 // Save connection parameters.
5888 ScoConnectionParameters connection_parameters = {transmit_bandwidth, receive_bandwidth,
5889 max_latency, voice_setting,
5890 retransmission_effort, packet_types};
5891 connections_.CreateScoConnection(connections_.GetAddress(connection_handle).GetAddress(),
5892 connection_parameters, SCO_STATE_PENDING, datapath);
5893
5894 // Send eSCO connection request to peer.
5895 SendLinkLayerPacket(model::packets::ScoConnectionRequestBuilder::Create(
5896 GetAddress(), bd_addr, transmit_bandwidth, receive_bandwidth, max_latency, voice_setting,
5897 retransmission_effort, packet_types, class_of_device_));
5898 return ErrorCode::SUCCESS;
5899 }
5900
AcceptSynchronousConnection(Address bd_addr,uint32_t transmit_bandwidth,uint32_t receive_bandwidth,uint16_t max_latency,uint16_t voice_setting,uint8_t retransmission_effort,uint16_t packet_types)5901 ErrorCode LinkLayerController::AcceptSynchronousConnection(
5902 Address bd_addr, uint32_t transmit_bandwidth, uint32_t receive_bandwidth,
5903 uint16_t max_latency, uint16_t voice_setting, uint8_t retransmission_effort,
5904 uint16_t packet_types) {
5905 INFO(id_, "Accepting eSCO connection request from {}", bd_addr);
5906
5907 if (!connections_.HasPendingScoConnection(bd_addr)) {
5908 INFO(id_, "No pending eSCO connection for {}", bd_addr);
5909 return ErrorCode::COMMAND_DISALLOWED;
5910 }
5911
5912 ErrorCode status = ErrorCode::SUCCESS;
5913 uint16_t sco_handle = 0;
5914 ScoLinkParameters link_parameters = {};
5915 ScoConnectionParameters connection_parameters = {transmit_bandwidth, receive_bandwidth,
5916 max_latency, voice_setting,
5917 retransmission_effort, packet_types};
5918
5919 if (!connections_.AcceptPendingScoConnection(bd_addr, connection_parameters, [this, bd_addr] {
5920 return LinkLayerController::StartScoStream(bd_addr);
5921 })) {
5922 connections_.CancelPendingScoConnection(bd_addr);
5923 status = ErrorCode::STATUS_UNKNOWN; // TODO: proper status code
5924 } else {
5925 sco_handle = connections_.GetScoHandle(bd_addr);
5926 link_parameters = connections_.GetScoLinkParameters(bd_addr);
5927 }
5928
5929 // Send eSCO connection response to peer.
5930 SendLinkLayerPacket(model::packets::ScoConnectionResponseBuilder::Create(
5931 GetAddress(), bd_addr, (uint8_t)status, link_parameters.transmission_interval,
5932 link_parameters.retransmission_window, link_parameters.rx_packet_length,
5933 link_parameters.tx_packet_length, link_parameters.air_mode, link_parameters.extended));
5934
5935 // Schedule HCI Synchronous Connection Complete event.
5936 ScheduleTask(kNoDelayMs, [this, status, sco_handle, bd_addr, link_parameters]() {
5937 send_event_(bluetooth::hci::SynchronousConnectionCompleteBuilder::Create(
5938 ErrorCode(status), sco_handle, bd_addr,
5939 link_parameters.extended ? bluetooth::hci::ScoLinkType::ESCO
5940 : bluetooth::hci::ScoLinkType::SCO,
5941 link_parameters.extended ? link_parameters.transmission_interval : 0,
5942 link_parameters.extended ? link_parameters.retransmission_window : 0,
5943 link_parameters.extended ? link_parameters.rx_packet_length : 0,
5944 link_parameters.extended ? link_parameters.tx_packet_length : 0,
5945 bluetooth::hci::ScoAirMode(link_parameters.air_mode)));
5946 });
5947
5948 return ErrorCode::SUCCESS;
5949 }
5950
RejectSynchronousConnection(Address bd_addr,uint16_t reason)5951 ErrorCode LinkLayerController::RejectSynchronousConnection(Address bd_addr, uint16_t reason) {
5952 INFO(id_, "Rejecting eSCO connection request from {}", bd_addr);
5953
5954 if (reason == (uint8_t)ErrorCode::SUCCESS) {
5955 reason = (uint8_t)ErrorCode::REMOTE_USER_TERMINATED_CONNECTION;
5956 }
5957 if (!connections_.HasPendingScoConnection(bd_addr)) {
5958 return ErrorCode::COMMAND_DISALLOWED;
5959 }
5960
5961 connections_.CancelPendingScoConnection(bd_addr);
5962
5963 // Send eSCO connection response to peer.
5964 SendLinkLayerPacket(model::packets::ScoConnectionResponseBuilder::Create(
5965 GetAddress(), bd_addr, reason, 0, 0, 0, 0, 0, 0));
5966
5967 // Schedule HCI Synchronous Connection Complete event.
5968 ScheduleTask(kNoDelayMs, [this, reason, bd_addr]() {
5969 send_event_(bluetooth::hci::SynchronousConnectionCompleteBuilder::Create(
5970 ErrorCode(reason), 0, bd_addr, bluetooth::hci::ScoLinkType::ESCO, 0, 0, 0, 0,
5971 bluetooth::hci::ScoAirMode::TRANSPARENT));
5972 });
5973
5974 return ErrorCode::SUCCESS;
5975 }
5976
CheckExpiringConnection(uint16_t handle)5977 void LinkLayerController::CheckExpiringConnection(uint16_t handle) {
5978 if (!connections_.HasHandle(handle)) {
5979 return;
5980 }
5981
5982 if (connections_.HasLinkExpired(handle)) {
5983 Disconnect(handle, ErrorCode::CONNECTION_TIMEOUT, ErrorCode::CONNECTION_TIMEOUT);
5984 return;
5985 }
5986
5987 if (connections_.IsLinkNearExpiring(handle)) {
5988 AddressWithType my_address = connections_.GetOwnAddress(handle);
5989 AddressWithType destination = connections_.GetAddress(handle);
5990 SendLinkLayerPacket(model::packets::PingRequestBuilder::Create(my_address.GetAddress(),
5991 destination.GetAddress()));
5992 ScheduleTask(
5993 std::chrono::duration_cast<milliseconds>(connections_.TimeUntilLinkExpired(handle)),
5994 [this, handle] { CheckExpiringConnection(handle); });
5995 return;
5996 }
5997
5998 ScheduleTask(
5999 std::chrono::duration_cast<milliseconds>(connections_.TimeUntilLinkNearExpiring(handle)),
6000 [this, handle] { CheckExpiringConnection(handle); });
6001 }
6002
IncomingPingRequest(model::packets::LinkLayerPacketView incoming)6003 void LinkLayerController::IncomingPingRequest(model::packets::LinkLayerPacketView incoming) {
6004 auto view = model::packets::PingRequestView::Create(incoming);
6005 ASSERT(view.IsValid());
6006 SendLinkLayerPacket(model::packets::PingResponseBuilder::Create(incoming.GetDestinationAddress(),
6007 incoming.GetSourceAddress()));
6008 }
6009
StartScoStream(Address address)6010 TaskId LinkLayerController::StartScoStream(Address address) {
6011 auto sco_builder =
6012 bluetooth::hci::ScoBuilder::Create(connections_.GetScoHandle(address),
6013 PacketStatusFlag::CORRECTLY_RECEIVED, {0, 0, 0, 0, 0});
6014
6015 auto sco_bytes = sco_builder->SerializeToBytes();
6016 auto sco_view = bluetooth::hci::ScoView::Create(
6017 pdl::packet::slice(std::make_shared<std::vector<uint8_t>>(std::move(sco_bytes))));
6018 ASSERT(sco_view.IsValid());
6019
6020 return SchedulePeriodicTask(0ms, 20ms, [this, address, sco_view]() {
6021 INFO(id_, "SCO sending...");
6022 SendScoToRemote(sco_view);
6023 });
6024 }
6025
NextTaskId()6026 TaskId LinkLayerController::NextTaskId() {
6027 TaskId task_id = task_counter_++;
6028 while (task_id == kInvalidTaskId ||
6029 std::any_of(task_queue_.begin(), task_queue_.end(),
6030 [=](Task const& task) { return task.task_id == task_id; })) {
6031 task_id = task_counter_++;
6032 }
6033 return task_id;
6034 }
6035
ScheduleTask(std::chrono::milliseconds delay,TaskCallback task_callback)6036 TaskId LinkLayerController::ScheduleTask(std::chrono::milliseconds delay,
6037 TaskCallback task_callback) {
6038 TaskId task_id = NextTaskId();
6039 task_queue_.emplace(std::chrono::steady_clock::now() + delay, std::move(task_callback), task_id);
6040 return task_id;
6041 }
6042
SchedulePeriodicTask(std::chrono::milliseconds delay,std::chrono::milliseconds period,TaskCallback task_callback)6043 TaskId LinkLayerController::SchedulePeriodicTask(std::chrono::milliseconds delay,
6044 std::chrono::milliseconds period,
6045 TaskCallback task_callback) {
6046 TaskId task_id = NextTaskId();
6047 task_queue_.emplace(std::chrono::steady_clock::now() + delay, period, std::move(task_callback),
6048 task_id);
6049 return task_id;
6050 }
6051
CancelScheduledTask(TaskId task_id)6052 void LinkLayerController::CancelScheduledTask(TaskId task_id) {
6053 auto it = task_queue_.cbegin();
6054 for (; it != task_queue_.cend(); it++) {
6055 if (it->task_id == task_id) {
6056 task_queue_.erase(it);
6057 return;
6058 }
6059 }
6060 }
6061
RunPendingTasks()6062 void LinkLayerController::RunPendingTasks() {
6063 std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
6064 while (!task_queue_.empty()) {
6065 auto it = task_queue_.begin();
6066 if (it->time > now) {
6067 break;
6068 }
6069
6070 Task task = *it;
6071 task_queue_.erase(it);
6072 task.callback();
6073
6074 // Re-insert periodic tasks after updating the
6075 // time by the period.
6076 if (task.periodic) {
6077 task.time = now + task.period;
6078 task_queue_.insert(task);
6079 }
6080 }
6081 }
6082
6083 } // namespace rootcanal
6084