Skip to content

Commit 92b8672

Browse files
committed
Sync with aosp/main
Synchronized to packages/modules/Bluetooth commit ed4ceaf45f86efe5d37e842605308e5ddc8f34ad Changelist: - Fix directed advertising with privacy enabled - Fix endianness of version numbers in android vendor capabilities
1 parent 72d015c commit 92b8672

File tree

6 files changed

+259
-20
lines changed

6 files changed

+259
-20
lines changed

model/controller/le_advertiser.cc

+19-3
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,10 @@ slots operator"" _slots(unsigned long long count) { return slots(count); }
4747
// =============================================================================
4848

4949
// Vol 6, Part B § 4.4.2.4.3 High duty cycle connectable directed advertising.
50+
// NB: The interval is specified to be 3.75ms, but it does not make sense to
51+
// use this value with the timer tick at 5ms.
5052
const chrono::duration adv_direct_ind_high_timeout = 1280ms;
51-
const chrono::duration adv_direct_ind_high_interval = 3750us;
53+
const chrono::duration adv_direct_ind_high_interval = 10ms /*3750us*/;
5254

5355
// Vol 6, Part B § 2.3.4.9 Host Advertising Data.
5456
const uint16_t max_legacy_advertising_pdu_size = 31;
@@ -546,7 +548,7 @@ ErrorCode LinkLayerController::LeSetExtendedAdvertisingParameters(
546548
#if 0
547549
if (advertiser.periodic_advertising_enable) {
548550
// TODO
549-
INFO(id_,
551+
INFO(id_,
550552
"periodic advertising is enabled for the specified advertising set"
551553
" and the secondary PHY does not match the periodic"
552554
" advertising PHY");
@@ -1148,6 +1150,19 @@ ErrorCode LinkLayerController::LeSetExtendedAdvertisingEnable(
11481150
}
11491151
break;
11501152
}
1153+
1154+
// If an IRK is available in the Link Layer Resolving List for the peer
1155+
// device, then the target’s device address (TargetA field) shall
1156+
// use a resolvable private address. If an IRK is not available in the
1157+
// Link Layer Resolving List or the IRK is set to zero for the peer device,
1158+
// then the target’s device address (TargetA field) shall use the Identity
1159+
// Address when entering the Advertising State and using connectable
1160+
// directed events.
1161+
if (advertiser.IsDirected()) {
1162+
advertiser.target_address =
1163+
GenerateResolvablePrivateAddress(peer_address, IrkSelection::Peer)
1164+
.value_or(peer_address);
1165+
}
11511166
}
11521167

11531168
for (auto& set : sets) {
@@ -1661,7 +1676,8 @@ void LinkLayerController::LeAdvertising() {
16611676
// Generate Link Layer Advertising events when advertising is enabled
16621677
// and a full interval has passed since the last event.
16631678
if (legacy_advertiser_.IsEnabled() && now >= legacy_advertiser_.next_event) {
1664-
legacy_advertiser_.next_event += legacy_advertiser_.advertising_interval;
1679+
legacy_advertiser_.next_event =
1680+
now + legacy_advertiser_.advertising_interval;
16651681
model::packets::LegacyAdvertisingType type;
16661682
bool attach_advertising_data = true;
16671683
switch (legacy_advertiser_.advertising_type) {

model/controller/link_layer_controller.cc

+12-10
Original file line numberDiff line numberDiff line change
@@ -262,10 +262,6 @@ bool LinkLayerController::ValidateTargetA(AddressWithType target_a,
262262
std::optional<AddressWithType>
263263
LinkLayerController::GenerateResolvablePrivateAddress(AddressWithType address,
264264
IrkSelection irk) {
265-
if (!le_resolving_list_enabled_) {
266-
return {};
267-
}
268-
269265
for (auto& entry : le_resolving_list_) {
270266
if (address.GetAddress() == entry.peer_identity_address &&
271267
address.ToPeerAddressType() == entry.peer_identity_address_type) {
@@ -4335,11 +4331,14 @@ bool LinkLayerController::ProcessIncomingLegacyConnectRequest(
43354331
// When the Link Layer is [...] connectable directed advertising events the
43364332
// advertising filter policy shall be ignored.
43374333
if (legacy_advertiser_.IsDirected()) {
4338-
if (legacy_advertiser_.GetTargetAddress() != resolved_initiating_address) {
4334+
if (resolved_initiating_address !=
4335+
PeerDeviceAddress(legacy_advertiser_.peer_address,
4336+
legacy_advertiser_.peer_address_type)) {
43394337
DEBUG(id_,
43404338
"LE Connect request ignored by legacy advertiser because the "
4341-
"initiating address {} does not match the target address {}",
4342-
resolved_initiating_address, legacy_advertiser_.GetTargetAddress());
4339+
"initiating address {} does not match the target address {}[{}]",
4340+
resolved_initiating_address, legacy_advertiser_.peer_address,
4341+
PeerAddressTypeText(legacy_advertiser_.peer_address_type));
43434342
return false;
43444343
}
43454344
} else {
@@ -4446,12 +4445,15 @@ bool LinkLayerController::ProcessIncomingExtendedConnectRequest(
44464445
// When the Link Layer is [...] connectable directed advertising events the
44474446
// advertising filter policy shall be ignored.
44484447
if (advertiser.IsDirected()) {
4449-
if (advertiser.GetTargetAddress() != resolved_initiating_address) {
4448+
if (resolved_initiating_address !=
4449+
PeerDeviceAddress(advertiser.peer_address,
4450+
advertiser.peer_address_type)) {
44504451
DEBUG(id_,
44514452
"LE Connect request ignored by extended advertiser {} because the "
4452-
"initiating address {} does not match the target address {}",
4453+
"initiating address {} does not match the target address {}[{}]",
44534454
advertiser.advertising_handle, resolved_initiating_address,
4454-
advertiser.GetTargetAddress());
4455+
advertiser.peer_address,
4456+
PeerAddressTypeText(advertiser.peer_address_type));
44554457
return false;
44564458
}
44574459
} else {

packets/hci_packets.pdl

+3-3
Original file line numberDiff line numberDiff line change
@@ -5646,7 +5646,7 @@ struct VendorCapabilities_V_0_96 {
56465646
filtering_support: 8,
56475647
max_filter: 8,
56485648
activity_energy_info_support: 8,
5649-
_fixed_ = 0x6000 : 16, // v0.96
5649+
_fixed_ = 0x0060 : 16, // v0.96
56505650
total_num_of_advt_tracked: 16,
56515651
extended_scan_support: 8,
56525652
debug_logging_supported: 8,
@@ -5661,7 +5661,7 @@ struct VendorCapabilities_V_0_98 {
56615661
filtering_support: 8,
56625662
max_filter: 8,
56635663
activity_energy_info_support: 8,
5664-
_fixed_ = 0x6200 : 16, // v0.98
5664+
_fixed_ = 0x0062 : 16, // v0.98
56655665
total_num_of_advt_tracked: 16,
56665666
extended_scan_support: 8,
56675667
debug_logging_supported: 8,
@@ -5678,7 +5678,7 @@ struct VendorCapabilities_V_1_03 {
56785678
filtering_support: 8,
56795679
max_filter: 8,
56805680
activity_energy_info_support: 8,
5681-
_fixed_ = 0x0301 : 16, // v1.03
5681+
_fixed_ = 0x0103 : 16, // v1.03
56825682
total_num_of_advt_tracked: 16,
56835683
extended_scan_support: 8,
56845684
debug_logging_supported: 8,

test/LL/DDI/ADV/BV_11_C.py

-4
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,6 @@ async def test(self):
115115
conn_supervision_timeout=self.LL_initiator_connSupervisionTimeout),
116116
rssi=-16)
117117

118-
# Note: another advertising pdu is received waiting from the connect
119-
# complete.
120-
await self.expect_ll(ll.LeLegacyAdvertisingPdu)
121-
122118
# Note: Link layer sends LeConnectComplete here.
123119
await self.expect_ll(
124120
ll.LeConnectComplete(source_address=controller.address,

test/LL/SEC/ADV/BV_11_C.py

+224
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
# Copyright 2023 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import asyncio
16+
import hci_packets as hci
17+
import link_layer_packets as ll
18+
import math
19+
import random
20+
import unittest
21+
from dataclasses import dataclass
22+
from hci_packets import ErrorCode, FragmentPreference
23+
from py.bluetooth import Address
24+
from py.controller import ControllerTest, generate_rpa
25+
from typing import List
26+
27+
28+
@dataclass
29+
class TestRound:
30+
data_length: int
31+
32+
33+
class Test(ControllerTest):
34+
# Test parameters.
35+
LL_advertiser_advInterval_MIN = 0x800
36+
LL_advertiser_advInterval_MAX = 0x800
37+
LL_advertiser_Adv_Channel_Map = 0x7
38+
LL_initiator_connInterval = 0x200
39+
LL_initiator_connPeripheralLatency = 0x200
40+
LL_initiator_connSupervisionTimeout = 0x200
41+
42+
# LL/SEC/ADV/BV-11-C [Network Privacy - Directed Connectable Advertising
43+
# using local and remote IRK]
44+
#
45+
# Verify that the IUT, when transmitting directed connectable advertising
46+
# events, is using resolvable private addresses for AdvA and InitA fields
47+
# when the Lower Tester has distributed its own IRK.
48+
#
49+
# Verify that when address resolution is disabled on the IUT, the Lower
50+
# Tester resolvable private address is not resolved, and therefore a
51+
# connection is not established.
52+
async def test(self):
53+
controller = self.controller
54+
local_irk = bytes([1] * 16)
55+
peer_irk = bytes([2] * 16)
56+
random_irk = bytes([3] * 16)
57+
peer_address = Address('aa:bb:cc:dd:ee:ff')
58+
59+
# 1. The Lower Tester adds the Device Identity of the IUT to its resolving list.
60+
# 2. Configure the Lower Tester to initiate a connection while using a resolvable private address.
61+
62+
# 3. The Upper Tester populates the resolving list with the device identity of the Lower Tester
63+
# connected with the local device identity. The IUT use these when generating resolvable private
64+
# addresses for use in the advertising packet’s AdvA and InitA fields.
65+
controller.send_cmd(
66+
hci.LeAddDeviceToResolvingList(
67+
peer_irk=peer_irk,
68+
local_irk=local_irk,
69+
peer_identity_address=peer_address,
70+
peer_identity_address_type=hci.PeerAddressType.PUBLIC_DEVICE_OR_IDENTITY_ADDRESS))
71+
72+
await self.expect_evt(
73+
hci.LeAddDeviceToResolvingListComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))
74+
75+
controller.send_cmd(hci.LeSetResolvablePrivateAddressTimeout(rpa_timeout=0x10))
76+
77+
await self.expect_evt(
78+
hci.LeSetResolvablePrivateAddressTimeoutComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))
79+
80+
# 4. The Upper Tester enables resolving list and directed connectable advertising in the IUT.
81+
controller.send_cmd(
82+
hci.LeSetAdvertisingParameters(advertising_interval_min=Test.LL_advertiser_advInterval_MIN,
83+
advertising_interval_max=Test.LL_advertiser_advInterval_MAX,
84+
advertising_type=hci.AdvertisingType.ADV_DIRECT_IND_HIGH,
85+
own_address_type=hci.OwnAddressType.RESOLVABLE_OR_PUBLIC_ADDRESS,
86+
peer_address=peer_address,
87+
peer_address_type=hci.PeerAddressType.PUBLIC_DEVICE_OR_IDENTITY_ADDRESS,
88+
advertising_channel_map=0x7,
89+
advertising_filter_policy=hci.AdvertisingFilterPolicy.ALL_DEVICES))
90+
91+
await self.expect_evt(
92+
hci.LeSetAdvertisingParametersComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))
93+
94+
controller.send_cmd(hci.LeSetAdvertisingData())
95+
96+
await self.expect_evt(hci.LeSetAdvertisingDataComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))
97+
98+
controller.send_cmd(hci.LeSetAddressResolutionEnable(address_resolution_enable=hci.Enable.ENABLED))
99+
100+
await self.expect_evt(
101+
hci.LeSetAddressResolutionEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))
102+
103+
controller.send_cmd(hci.LeSetAdvertisingEnable(advertising_enable=True))
104+
105+
await self.expect_evt(hci.LeSetAdvertisingEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))
106+
107+
# 5. The Lower Tester expects the IUT to send ADV_DIRECT_IND packets on an applicable
108+
# advertising channel.
109+
direct_ind = await self.expect_ll(ll.LeLegacyAdvertisingPdu(
110+
source_address=self.Any,
111+
destination_address=self.Any,
112+
advertising_address_type=ll.AddressType.RANDOM,
113+
target_address_type=ll.AddressType.RANDOM,
114+
advertising_type=ll.LegacyAdvertisingType.ADV_DIRECT_IND,
115+
advertising_data=[]),
116+
timeout=5)
117+
118+
self.assertTrue(direct_ind.source_address.is_resolvable())
119+
self.assertTrue(direct_ind.destination_address.is_resolvable())
120+
121+
# 6. The Lower Tester identifies the IUT. The Lower Tester sends a CONNECT_IND with the AdvA
122+
# address of the ADV_DIRECT_IND and the InitA generated based on its Device Identity. The IUT
123+
# verifies AdvA and resolves the InitA Address and identifies the Lower Tester.
124+
# 7. The Lower Tester connects to the IUT. The Lower Tester sends empty LL DATA packets starting
125+
# with the first event one connection interval after the connection request using the common data
126+
# channel selection parameters.
127+
init_a = generate_rpa(peer_irk)
128+
controller.send_ll(
129+
ll.LeConnect(source_address=init_a,
130+
destination_address=direct_ind.source_address,
131+
initiating_address_type=ll.AddressType.RANDOM,
132+
advertising_address_type=ll.AddressType.RANDOM,
133+
conn_interval=Test.LL_initiator_connInterval,
134+
conn_peripheral_latency=0x6,
135+
conn_supervision_timeout=0xc80))
136+
137+
await self.expect_ll(
138+
ll.LeConnectComplete(source_address=direct_ind.source_address,
139+
destination_address=init_a,
140+
initiating_address_type=ll.AddressType.RANDOM,
141+
advertising_address_type=ll.AddressType.RANDOM,
142+
conn_interval=Test.LL_initiator_connInterval,
143+
conn_peripheral_latency=0x6,
144+
conn_supervision_timeout=0xc80))
145+
146+
connection_complete_evt = await self.expect_evt(
147+
hci.LeEnhancedConnectionComplete(
148+
status=hci.ErrorCode.SUCCESS,
149+
connection_handle=self.Any,
150+
role=hci.Role.PERIPHERAL,
151+
peer_address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS,
152+
peer_address=peer_address,
153+
local_resolvable_private_address=direct_ind.source_address,
154+
peer_resolvable_private_address=init_a,
155+
connection_interval=0x200,
156+
peripheral_latency=0x6,
157+
supervision_timeout=0xc80,
158+
central_clock_accuracy=hci.ClockAccuracy.PPM_500,
159+
))
160+
161+
# 8. The Upper Tester terminates the connection.
162+
controller.send_cmd(
163+
hci.Disconnect(connection_handle=connection_complete_evt.connection_handle,
164+
reason=hci.DisconnectReason.REMOTE_USER_TERMINATED_CONNECTION))
165+
166+
await self.expect_evt(hci.DisconnectStatus(status=ErrorCode.SUCCESS, num_hci_command_packets=1))
167+
168+
await self.expect_ll(
169+
ll.Disconnect(source_address=direct_ind.source_address,
170+
destination_address=init_a,
171+
reason=hci.DisconnectReason.REMOTE_USER_TERMINATED_CONNECTION))
172+
173+
await self.expect_evt(
174+
hci.DisconnectionComplete(status=ErrorCode.SUCCESS,
175+
connection_handle=connection_complete_evt.connection_handle,
176+
reason=ErrorCode.CONNECTION_TERMINATED_BY_LOCAL_HOST))
177+
178+
# 9. The Upper Tester disables address resolution in the IUT.
179+
controller.send_cmd(hci.LeSetAddressResolutionEnable(address_resolution_enable=hci.Enable.DISABLED))
180+
181+
await self.expect_evt(
182+
hci.LeSetAddressResolutionEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))
183+
184+
# 10. Repeat steps 11–14 at least 20 times.
185+
186+
# 11. The Upper Tester enables directed connectable advertising in the IUT.
187+
controller.send_cmd(hci.LeSetAdvertisingEnable(advertising_enable=True))
188+
189+
await self.expect_evt(hci.LeSetAdvertisingEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))
190+
191+
# 12. The Lower Tester expects the IUT to send ADV_DIRECT_IND packets on an applicable
192+
# advertising channel. The Lower Tester resolves the AdvA address and identifies the IUT.
193+
direct_ind = await self.expect_ll(ll.LeLegacyAdvertisingPdu(
194+
source_address=self.Any,
195+
destination_address=self.Any,
196+
advertising_address_type=ll.AddressType.RANDOM,
197+
target_address_type=ll.AddressType.RANDOM,
198+
advertising_type=ll.LegacyAdvertisingType.ADV_DIRECT_IND,
199+
advertising_data=[]),
200+
timeout=5)
201+
202+
self.assertTrue(direct_ind.source_address.is_resolvable())
203+
self.assertTrue(direct_ind.destination_address.is_resolvable())
204+
205+
# 13. The Lower Tester sends a CONNECT_IND with the AdvA address of the ADV_IND and the InitA
206+
# set to a different address than the last CONNECT_IND. The IUT does not resolve the address in
207+
# the InitA field. No connection event is sent to the Upper Tester.
208+
init_a = generate_rpa(local_irk)
209+
controller.send_ll(
210+
ll.LeConnect(source_address=init_a,
211+
destination_address=direct_ind.source_address,
212+
initiating_address_type=ll.AddressType.RANDOM,
213+
advertising_address_type=ll.AddressType.RANDOM,
214+
conn_interval=0x200,
215+
conn_peripheral_latency=0x6,
216+
conn_supervision_timeout=0xc80))
217+
218+
# 14. The Upper Tester receives an HCI_LE_Connection_Complete event or an
219+
# HCI_LE_Enhanced_Connection_Complete event with the Status code set to Advertising Timeout
220+
# (0x3C).
221+
await self.expect_evt(hci.LeConnectionComplete(status=hci.ErrorCode.ADVERTISING_TIMEOUT,))
222+
223+
# Empty the LL queue.
224+
controller.ll_queue.clear()

test/main.py

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
'LL.DDI.SCN.BV_18_C',
6060
'LL.DDI.SCN.BV_19_C',
6161
'LL.DDI.SCN.BV_79_C',
62+
'LL.SEC.ADV.BV_11_C',
6263
'LMP.LIH.BV_01_C',
6364
'LMP.LIH.BV_02_C',
6465
'LMP.LIH.BV_78_C',

0 commit comments

Comments
 (0)