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