Skip to content

Commit

Permalink
Sync with aosp/main
Browse files Browse the repository at this point in the history
Synchronized to packages/modules/Bluetooth
commit 90bd1333235434561513ccff8bcba868748bd468

Changelist:
- Address resolution failure in connection initiation
- Implement a timeout for receiving the response to a LE Scan request
  • Loading branch information
hchataing committed Jan 25, 2024
1 parent e673f5e commit 72d015c
Show file tree
Hide file tree
Showing 10 changed files with 896 additions and 70 deletions.
136 changes: 71 additions & 65 deletions model/controller/link_layer_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ using TaskId = rootcanal::LinkLayerController::TaskId;

namespace rootcanal {

constexpr milliseconds kScanRequestTimeout(200);
constexpr milliseconds kNoDelayMs(0);
constexpr milliseconds kPageInterval(1000);

Expand Down Expand Up @@ -207,7 +208,7 @@ bool LinkLayerController::ResolvingListBusy() {
}

std::optional<AddressWithType> LinkLayerController::ResolvePrivateAddress(
AddressWithType address, IrkSelection irk) {
AddressWithType address) {
if (!address.IsRpa()) {
return address;
}
Expand All @@ -217,24 +218,47 @@ std::optional<AddressWithType> LinkLayerController::ResolvePrivateAddress(
}

for (auto& entry : le_resolving_list_) {
std::array<uint8_t, LinkLayerController::kIrkSize> const& used_irk =
irk == IrkSelection::Local ? entry.local_irk : entry.peer_irk;

if (address.IsRpaThatMatchesIrk(used_irk)) {
if (address.IsRpaThatMatchesIrk(entry.peer_irk)) {
// Update the peer resolvable address used for the peer
// with the returned identity address.
if (irk == IrkSelection::Peer) {
entry.peer_resolvable_address = address.GetAddress();
}
entry.peer_resolvable_address = address.GetAddress();

return PeerIdentityAddress(entry.peer_identity_address,
entry.peer_identity_address_type);
return PeerDeviceAddress(entry.peer_identity_address,
entry.peer_identity_address_type);
}
}

return {};
}

bool LinkLayerController::ResolveTargetA(AddressWithType target_a,
AddressWithType adv_a) {
if (!le_resolving_list_enabled_) {
return false;
}

for (auto const& entry : le_resolving_list_) {
if (adv_a == PeerDeviceAddress(entry.peer_identity_address,
entry.peer_identity_address_type) &&
target_a.IsRpaThatMatchesIrk(entry.local_irk)) {
return true;
}
}

return false;
}

bool LinkLayerController::ValidateTargetA(AddressWithType target_a,
AddressWithType adv_a) {
if (IsLocalPublicOrRandomAddress(target_a)) {
return true;
}
if (target_a.IsRpa()) {
return ResolveTargetA(target_a, adv_a);
}
return false;
}

std::optional<AddressWithType>
LinkLayerController::GenerateResolvablePrivateAddress(AddressWithType address,
IrkSelection irk) {
Expand Down Expand Up @@ -1255,6 +1279,7 @@ ErrorCode LinkLayerController::LeSetScanEnable(bool enable,
if (!enable) {
scanner_.scan_enable = false;
scanner_.pending_scan_request = {};
scanner_.pending_scan_request_timeout = {};
scanner_.history.clear();
return ErrorCode::SUCCESS;
}
Expand Down Expand Up @@ -1284,6 +1309,7 @@ ErrorCode LinkLayerController::LeSetScanEnable(bool enable,
scanner_.timeout = {};
scanner_.periodical_timeout = {};
scanner_.pending_scan_request = {};
scanner_.pending_scan_request_timeout = {};
scanner_.filter_duplicates = filter_duplicates
? bluetooth::hci::FilterDuplicates::ENABLED
: bluetooth::hci::FilterDuplicates::DISABLED;
Expand Down Expand Up @@ -1415,6 +1441,7 @@ ErrorCode LinkLayerController::LeSetExtendedScanEnable(
if (!enable) {
scanner_.scan_enable = false;
scanner_.pending_scan_request = {};
scanner_.pending_scan_request_timeout = {};
scanner_.history.clear();
return ErrorCode::SUCCESS;
}
Expand Down Expand Up @@ -1472,6 +1499,7 @@ ErrorCode LinkLayerController::LeSetExtendedScanEnable(
scanner_.timeout = {};
scanner_.periodical_timeout = {};
scanner_.pending_scan_request = {};
scanner_.pending_scan_request_timeout = {};
scanner_.filter_duplicates = filter_duplicates;
scanner_.duration = duration_ms;
scanner_.period = period_ms;
Expand Down Expand Up @@ -2897,11 +2925,7 @@ void LinkLayerController::ScanIncomingLeLegacyAdvertisingPdu(
// address. The scanner’s filter policy shall then determine if the scanner
// responds with a scan request.
AddressWithType resolved_advertising_address =
ResolvePrivateAddress(advertising_address, IrkSelection::Peer)
.value_or(advertising_address);

std::optional<AddressWithType> resolved_target_address =
ResolvePrivateAddress(target_address, IrkSelection::Peer);
ResolvePrivateAddress(advertising_address).value_or(advertising_address);

if (resolved_advertising_address != advertising_address) {
DEBUG(id_, "Resolved the advertising address {} to {}", advertising_address,
Expand Down Expand Up @@ -2944,8 +2968,7 @@ void LinkLayerController::ScanIncomingLeLegacyAdvertisingPdu(
// resolution is enabled, and the address is resolved successfully
case bluetooth::hci::LeScanningFilterPolicy::ACCEPT_ALL:
case bluetooth::hci::LeScanningFilterPolicy::FILTER_ACCEPT_LIST_ONLY:
if (!IsLocalPublicOrRandomAddress(target_address) &&
!(target_address.IsRpa() && resolved_target_address)) {
if (!ValidateTargetA(target_address, resolved_advertising_address)) {
DEBUG(id_,
"Legacy advertising ignored by scanner because the directed "
"address {} does not match the current device or cannot be "
Expand All @@ -2971,7 +2994,8 @@ void LinkLayerController::ScanIncomingLeLegacyAdvertisingPdu(
return;
}
should_send_directed_advertising_report =
target_address.IsRpa() && !resolved_target_address;
target_address.IsRpa() &&
!ResolveTargetA(target_address, resolved_advertising_address);
break;
}
}
Expand Down Expand Up @@ -3146,6 +3170,8 @@ void LinkLayerController::ScanIncomingLeLegacyAdvertisingPdu(
// is connectable in the scan response report.
scanner_.connectable_scan_response = connectable_advertising;
scanner_.pending_scan_request = advertising_address;
scanner_.pending_scan_request_timeout =
std::chrono::steady_clock::now() + kScanRequestTimeout;

INFO(id_,
"Sending LE Scan request to advertising address {} with scanning "
Expand Down Expand Up @@ -3202,12 +3228,7 @@ void LinkLayerController::ConnectIncomingLeLegacyAdvertisingPdu(
static_cast<AddressType>(pdu.GetTargetAddressType())};

AddressWithType resolved_advertising_address =
ResolvePrivateAddress(advertising_address, IrkSelection::Peer)
.value_or(advertising_address);

AddressWithType resolved_target_address =
ResolvePrivateAddress(target_address, IrkSelection::Peer)
.value_or(target_address);
ResolvePrivateAddress(advertising_address).value_or(advertising_address);

// Vol 6, Part B § 4.3.5 Initiator filter policy.
switch (initiator_.initiator_filter_policy) {
Expand Down Expand Up @@ -3240,14 +3261,14 @@ void LinkLayerController::ConnectIncomingLeLegacyAdvertisingPdu(
// contain Public or Static addresses for the target’s address (TargetA
// field).
if (directed_advertising) {
if (!IsLocalPublicOrRandomAddress(resolved_target_address)) {
if (!ValidateTargetA(target_address, resolved_advertising_address)) {
DEBUG(id_,
"Directed legacy advertising ignored by initiator because the "
"target address {} does not match the current device addresses",
resolved_advertising_address);
target_address);
return;
}
if (resolved_target_address == target_address &&
if (!target_address.IsRpa() &&
(initiator_.own_address_type ==
OwnAddressType::RESOLVABLE_OR_PUBLIC_ADDRESS ||
initiator_.own_address_type ==
Expand All @@ -3256,7 +3277,7 @@ void LinkLayerController::ConnectIncomingLeLegacyAdvertisingPdu(
"Directed legacy advertising ignored by initiator because the "
"target address {} is static or public and the initiator is "
"configured to use resolvable addresses",
resolved_advertising_address);
target_address);
return;
}
}
Expand Down Expand Up @@ -3370,11 +3391,7 @@ void LinkLayerController::ScanIncomingLeExtendedAdvertisingPdu(
// address. The scanner’s filter policy shall then determine if the scanner
// responds with a scan request.
AddressWithType resolved_advertising_address =
ResolvePrivateAddress(advertising_address, IrkSelection::Peer)
.value_or(advertising_address);

std::optional<AddressWithType> resolved_target_address =
ResolvePrivateAddress(target_address, IrkSelection::Peer);
ResolvePrivateAddress(advertising_address).value_or(advertising_address);

if (resolved_advertising_address != advertising_address) {
DEBUG(id_, "Resolved the advertising address {} to {}", advertising_address,
Expand Down Expand Up @@ -3411,8 +3428,7 @@ void LinkLayerController::ScanIncomingLeExtendedAdvertisingPdu(
// resolution is enabled, and the address is resolved successfully
case bluetooth::hci::LeScanningFilterPolicy::ACCEPT_ALL:
case bluetooth::hci::LeScanningFilterPolicy::FILTER_ACCEPT_LIST_ONLY:
if (!IsLocalPublicOrRandomAddress(target_address) &&
!(target_address.IsRpa() && resolved_target_address)) {
if (!ValidateTargetA(target_address, resolved_advertising_address)) {
DEBUG(id_,
"Extended advertising ignored by scanner because the directed "
"address {} does not match the current device or cannot be "
Expand Down Expand Up @@ -3631,12 +3647,7 @@ void LinkLayerController::ConnectIncomingLeExtendedAdvertisingPdu(
static_cast<AddressType>(pdu.GetTargetAddressType())};

AddressWithType resolved_advertising_address =
ResolvePrivateAddress(advertising_address, IrkSelection::Peer)
.value_or(advertising_address);

AddressWithType resolved_target_address =
ResolvePrivateAddress(target_address, IrkSelection::Peer)
.value_or(target_address);
ResolvePrivateAddress(advertising_address).value_or(advertising_address);

// Vol 6, Part B § 4.3.5 Initiator filter policy.
switch (initiator_.initiator_filter_policy) {
Expand Down Expand Up @@ -3669,14 +3680,14 @@ void LinkLayerController::ConnectIncomingLeExtendedAdvertisingPdu(
// contain Public or Static addresses for the target’s address (TargetA
// field).
if (pdu.GetDirected()) {
if (!IsLocalPublicOrRandomAddress(resolved_target_address)) {
if (!ValidateTargetA(target_address, resolved_advertising_address)) {
DEBUG(id_,
"Directed extended advertising ignored by initiator because the "
"target address {} does not match the current device addresses",
resolved_advertising_address);
target_address);
return;
}
if (resolved_target_address == target_address &&
if (!target_address.IsRpa() &&
(initiator_.own_address_type ==
OwnAddressType::RESOLVABLE_OR_PUBLIC_ADDRESS ||
initiator_.own_address_type ==
Expand All @@ -3685,7 +3696,7 @@ void LinkLayerController::ConnectIncomingLeExtendedAdvertisingPdu(
"Directed extended advertising ignored by initiator because the "
"target address {} is static or public and the initiator is "
"configured to use resolvable addresses",
resolved_advertising_address);
target_address);
return;
}
}
Expand Down Expand Up @@ -3792,8 +3803,7 @@ void LinkLayerController::IncomingLePeriodicAdvertisingPdu(
// address. The scanner's periodic sync establishment filter policy shall
// determine if the scanner processes the advertising packet.
AddressWithType resolved_advertiser_address =
ResolvePrivateAddress(advertiser_address, IrkSelection::Peer)
.value_or(advertiser_address);
ResolvePrivateAddress(advertiser_address).value_or(advertiser_address);

bluetooth::hci::AdvertiserAddressType advertiser_address_type;
switch (resolved_advertiser_address.GetAddressType()) {
Expand Down Expand Up @@ -4234,16 +4244,7 @@ uint16_t LinkLayerController::HandleLeConnection(
AddressType peer_address_type = address.GetAddressType();
if (peer_resolved_address != AddressWithType()) {
peer_resolvable_private_address = address.GetAddress();
if (peer_resolved_address.GetAddressType() ==
AddressType::PUBLIC_DEVICE_ADDRESS) {
peer_address_type = AddressType::PUBLIC_IDENTITY_ADDRESS;
} else if (peer_resolved_address.GetAddressType() ==
AddressType::RANDOM_DEVICE_ADDRESS) {
peer_address_type = AddressType::RANDOM_IDENTITY_ADDRESS;
} else {
WARNING(id_, "Unhandled resolved address type {} -> {}", address,
peer_resolved_address);
}
peer_address_type = peer_resolved_address.GetAddressType();
connection_address = peer_resolved_address.GetAddress();
}
Address local_resolved_address = own_address.GetAddress();
Expand Down Expand Up @@ -4324,8 +4325,7 @@ bool LinkLayerController::ProcessIncomingLegacyConnectRequest(
// The advertising filter policy shall then determine if the
// advertiser establishes a connection.
AddressWithType resolved_initiating_address =
ResolvePrivateAddress(initiating_address, IrkSelection::Peer)
.value_or(initiating_address);
ResolvePrivateAddress(initiating_address).value_or(initiating_address);

if (resolved_initiating_address != initiating_address) {
DEBUG(id_, "Resolved the initiating address {} to {}", initiating_address,
Expand Down Expand Up @@ -4436,8 +4436,7 @@ bool LinkLayerController::ProcessIncomingExtendedConnectRequest(
// The advertising filter policy shall then determine if the
// advertiser establishes a connection.
AddressWithType resolved_initiating_address =
ResolvePrivateAddress(initiating_address, IrkSelection::Peer)
.value_or(initiating_address);
ResolvePrivateAddress(initiating_address).value_or(initiating_address);

if (resolved_initiating_address != initiating_address) {
DEBUG(id_, "Resolved the initiating address {} to {}", initiating_address,
Expand Down Expand Up @@ -4871,8 +4870,7 @@ void LinkLayerController::IncomingLeScanPacket(
// address. The advertising filter policy shall then determine if
// the advertiser processes the scan request.
AddressWithType resolved_scanning_address =
ResolvePrivateAddress(scanning_address, IrkSelection::Peer)
.value_or(scanning_address);
ResolvePrivateAddress(scanning_address).value_or(scanning_address);

if (resolved_scanning_address != scanning_address) {
DEBUG(id_, "Resolved the scanning address {} to {}", scanning_address,
Expand Down Expand Up @@ -4921,8 +4919,7 @@ void LinkLayerController::IncomingLeScanResponsePacket(
}

AddressWithType resolved_advertising_address =
ResolvePrivateAddress(advertising_address, IrkSelection::Peer)
.value_or(advertising_address);
ResolvePrivateAddress(advertising_address).value_or(advertising_address);

if (advertising_address != resolved_advertising_address) {
DEBUG(id_, "Resolved the advertising address {} to {}", advertising_address,
Expand Down Expand Up @@ -5019,6 +5016,15 @@ void LinkLayerController::LeScanning() {
scanner_.timeout = now + scanner_.duration;
scanner_.periodical_timeout = now + scanner_.period;
}

// Pending scan timeout.
// Cancel the pending scan request. This may condition may be triggered
// when the advertiser is stopped before sending the scan request.
if (scanner_.pending_scan_request_timeout.has_value() &&
now >= scanner_.pending_scan_request_timeout.value()) {
scanner_.pending_scan_request = {};
scanner_.pending_scan_request_timeout = {};
}
}

void LinkLayerController::LeSynchronization() {
Expand Down
15 changes: 13 additions & 2 deletions model/controller/link_layer_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,17 @@ class LinkLayerController {
// resolve the address using the resolving list. If the address cannot
// be resolved none is returned. If the address is not a Resolvable
// Private Address, the original address is returned.
std::optional<AddressWithType> ResolvePrivateAddress(AddressWithType address,
IrkSelection irk);
std::optional<AddressWithType> ResolvePrivateAddress(AddressWithType address);

// Returns true if the input address resolves with the local IRK
// associated with the given peer identity address.
bool ResolveTargetA(AddressWithType target_a, AddressWithType adv_a);

// Returns true if either:
// • TargetA is identical to the device address, or
// • TargetA is a resolvable private address, address
// resolution is enabled, and the address is resolved successfully
bool ValidateTargetA(AddressWithType target_a, AddressWithType adv_a);

// Generate a Resolvable Private for the selected peer.
// If the address is not found in the resolving list none is returned.
Expand Down Expand Up @@ -1062,6 +1071,8 @@ class LinkLayerController {
// Save information about the advertising PDU being scanned.
bool connectable_scan_response;
std::optional<AddressWithType> pending_scan_request{};
std::optional<std::chrono::steady_clock::time_point>
pending_scan_request_timeout{};

// Time keeping
std::optional<std::chrono::steady_clock::time_point> timeout;
Expand Down
Loading

0 comments on commit 72d015c

Please sign in to comment.