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