• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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