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 15import asyncio 16import hci_packets as hci 17import link_layer_packets as ll 18import math 19import random 20import unittest 21from dataclasses import dataclass 22from hci_packets import ErrorCode, FragmentPreference 23from py.bluetooth import Address 24from py.controller import ControllerTest, generate_rpa 25from typing import List 26 27 28@dataclass 29class TestRound: 30 data_length: int 31 32 33class 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.LeEnhancedConnectionCompleteV1( 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() 225