forked from auracaster/bumble_mirror
support controller-generated rpa
This commit is contained in:
@@ -182,6 +182,7 @@ from .core import (
|
|||||||
BaseBumbleError,
|
BaseBumbleError,
|
||||||
ConnectionParameterUpdateError,
|
ConnectionParameterUpdateError,
|
||||||
CommandTimeoutError,
|
CommandTimeoutError,
|
||||||
|
ConnectionParameters,
|
||||||
ConnectionPHY,
|
ConnectionPHY,
|
||||||
InvalidArgumentError,
|
InvalidArgumentError,
|
||||||
InvalidOperationError,
|
InvalidOperationError,
|
||||||
@@ -1304,6 +1305,7 @@ class Connection(CompositeEventEmitter):
|
|||||||
handle: int
|
handle: int
|
||||||
transport: int
|
transport: int
|
||||||
self_address: Address
|
self_address: Address
|
||||||
|
self_resolvable_address: Optional[Address]
|
||||||
peer_address: Address
|
peer_address: Address
|
||||||
peer_resolvable_address: Optional[Address]
|
peer_resolvable_address: Optional[Address]
|
||||||
peer_le_features: Optional[LeFeatureMask]
|
peer_le_features: Optional[LeFeatureMask]
|
||||||
@@ -1351,6 +1353,7 @@ class Connection(CompositeEventEmitter):
|
|||||||
handle,
|
handle,
|
||||||
transport,
|
transport,
|
||||||
self_address,
|
self_address,
|
||||||
|
self_resolvable_address,
|
||||||
peer_address,
|
peer_address,
|
||||||
peer_resolvable_address,
|
peer_resolvable_address,
|
||||||
role,
|
role,
|
||||||
@@ -1362,6 +1365,7 @@ class Connection(CompositeEventEmitter):
|
|||||||
self.handle = handle
|
self.handle = handle
|
||||||
self.transport = transport
|
self.transport = transport
|
||||||
self.self_address = self_address
|
self.self_address = self_address
|
||||||
|
self.self_resolvable_address = self_resolvable_address
|
||||||
self.peer_address = peer_address
|
self.peer_address = peer_address
|
||||||
self.peer_resolvable_address = peer_resolvable_address
|
self.peer_resolvable_address = peer_resolvable_address
|
||||||
self.peer_name = None # Classic only
|
self.peer_name = None # Classic only
|
||||||
@@ -1395,6 +1399,7 @@ class Connection(CompositeEventEmitter):
|
|||||||
None,
|
None,
|
||||||
BT_BR_EDR_TRANSPORT,
|
BT_BR_EDR_TRANSPORT,
|
||||||
device.public_address,
|
device.public_address,
|
||||||
|
None,
|
||||||
peer_address,
|
peer_address,
|
||||||
None,
|
None,
|
||||||
role,
|
role,
|
||||||
@@ -1553,7 +1558,9 @@ class Connection(CompositeEventEmitter):
|
|||||||
f'Connection(handle=0x{self.handle:04X}, '
|
f'Connection(handle=0x{self.handle:04X}, '
|
||||||
f'role={self.role_name}, '
|
f'role={self.role_name}, '
|
||||||
f'self_address={self.self_address}, '
|
f'self_address={self.self_address}, '
|
||||||
f'peer_address={self.peer_address})'
|
f'self_resolvable_address={self.self_resolvable_address}, '
|
||||||
|
f'peer_address={self.peer_address}, '
|
||||||
|
f'peer_resolvable_address={self.peer_resolvable_address})'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -1586,6 +1593,7 @@ class DeviceConfiguration:
|
|||||||
irk: bytes = bytes(16) # This really must be changed for any level of security
|
irk: bytes = bytes(16) # This really must be changed for any level of security
|
||||||
keystore: Optional[str] = None
|
keystore: Optional[str] = None
|
||||||
address_resolution_offload: bool = False
|
address_resolution_offload: bool = False
|
||||||
|
address_generation_offload: bool = False
|
||||||
cis_enabled: bool = False
|
cis_enabled: bool = False
|
||||||
|
|
||||||
def __post_init__(self) -> None:
|
def __post_init__(self) -> None:
|
||||||
@@ -1891,6 +1899,7 @@ class Device(CompositeEventEmitter):
|
|||||||
self.connectable = config.connectable
|
self.connectable = config.connectable
|
||||||
self.classic_accept_any = config.classic_accept_any
|
self.classic_accept_any = config.classic_accept_any
|
||||||
self.address_resolution_offload = config.address_resolution_offload
|
self.address_resolution_offload = config.address_resolution_offload
|
||||||
|
self.address_generation_offload = config.address_generation_offload
|
||||||
|
|
||||||
# Extended advertising.
|
# Extended advertising.
|
||||||
self.extended_advertising_sets: Dict[int, AdvertisingSet] = {}
|
self.extended_advertising_sets: Dict[int, AdvertisingSet] = {}
|
||||||
@@ -2313,7 +2322,7 @@ class Device(CompositeEventEmitter):
|
|||||||
# Create a host-side address resolver
|
# Create a host-side address resolver
|
||||||
self.address_resolver = smp.AddressResolver(resolving_keys)
|
self.address_resolver = smp.AddressResolver(resolving_keys)
|
||||||
|
|
||||||
if self.address_resolution_offload:
|
if self.address_resolution_offload or self.address_generation_offload:
|
||||||
await self.send_command(HCI_LE_Clear_Resolving_List_Command())
|
await self.send_command(HCI_LE_Clear_Resolving_List_Command())
|
||||||
|
|
||||||
# Add an empty entry for non-directed address generation.
|
# Add an empty entry for non-directed address generation.
|
||||||
@@ -4158,12 +4167,14 @@ class Device(CompositeEventEmitter):
|
|||||||
@host_event_handler
|
@host_event_handler
|
||||||
def on_connection(
|
def on_connection(
|
||||||
self,
|
self,
|
||||||
connection_handle,
|
connection_handle: int,
|
||||||
transport,
|
transport: int,
|
||||||
peer_address,
|
peer_address: Address,
|
||||||
role,
|
self_resolvable_address: Optional[Address],
|
||||||
connection_parameters,
|
peer_resolvable_address: Optional[Address],
|
||||||
):
|
role: int,
|
||||||
|
connection_parameters: ConnectionParameters,
|
||||||
|
) -> None:
|
||||||
logger.debug(
|
logger.debug(
|
||||||
f'*** Connection: [0x{connection_handle:04X}] '
|
f'*** Connection: [0x{connection_handle:04X}] '
|
||||||
f'{peer_address} {"" if role is None else HCI_Constant.role_name(role)}'
|
f'{peer_address} {"" if role is None else HCI_Constant.role_name(role)}'
|
||||||
@@ -4184,15 +4195,15 @@ class Device(CompositeEventEmitter):
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# Resolve the peer address if we can
|
if peer_resolvable_address is None:
|
||||||
peer_resolvable_address = None
|
# Resolve the peer address if we can
|
||||||
if self.address_resolver:
|
if self.address_resolver:
|
||||||
if peer_address.is_resolvable:
|
if peer_address.is_resolvable:
|
||||||
resolved_address = self.address_resolver.resolve(peer_address)
|
resolved_address = self.address_resolver.resolve(peer_address)
|
||||||
if resolved_address is not None:
|
if resolved_address is not None:
|
||||||
logger.debug(f'*** Address resolved as {resolved_address}')
|
logger.debug(f'*** Address resolved as {resolved_address}')
|
||||||
peer_resolvable_address = peer_address
|
peer_resolvable_address = peer_address
|
||||||
peer_address = resolved_address
|
peer_address = resolved_address
|
||||||
|
|
||||||
self_address = None
|
self_address = None
|
||||||
if role == HCI_CENTRAL_ROLE:
|
if role == HCI_CENTRAL_ROLE:
|
||||||
@@ -4223,12 +4234,19 @@ class Device(CompositeEventEmitter):
|
|||||||
else self.random_address
|
else self.random_address
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Convert all-zeros addresses into None.
|
||||||
|
if self_resolvable_address == Address.ANY_RANDOM:
|
||||||
|
self_resolvable_address = None
|
||||||
|
if peer_resolvable_address == Address.ANY_RANDOM:
|
||||||
|
peer_resolvable_address = None
|
||||||
|
|
||||||
# Create a connection.
|
# Create a connection.
|
||||||
connection = Connection(
|
connection = Connection(
|
||||||
self,
|
self,
|
||||||
connection_handle,
|
connection_handle,
|
||||||
transport,
|
transport,
|
||||||
self_address,
|
self_address,
|
||||||
|
self_resolvable_address,
|
||||||
peer_address,
|
peer_address,
|
||||||
peer_resolvable_address,
|
peer_resolvable_address,
|
||||||
role,
|
role,
|
||||||
@@ -4239,9 +4257,10 @@ class Device(CompositeEventEmitter):
|
|||||||
|
|
||||||
if role == HCI_PERIPHERAL_ROLE and self.legacy_advertiser:
|
if role == HCI_PERIPHERAL_ROLE and self.legacy_advertiser:
|
||||||
if self.legacy_advertiser.auto_restart:
|
if self.legacy_advertiser.auto_restart:
|
||||||
|
advertiser = self.legacy_advertiser
|
||||||
connection.once(
|
connection.once(
|
||||||
'disconnection',
|
'disconnection',
|
||||||
lambda _: self.abort_on('flush', self.legacy_advertiser.start()),
|
lambda _: self.abort_on('flush', advertiser.start()),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.legacy_advertiser = None
|
self.legacy_advertiser = None
|
||||||
|
|||||||
@@ -1839,6 +1839,12 @@ class Address:
|
|||||||
data, offset, Address.PUBLIC_DEVICE_ADDRESS
|
data, offset, Address.PUBLIC_DEVICE_ADDRESS
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def parse_random_address(data, offset):
|
||||||
|
return Address.parse_address_with_type(
|
||||||
|
data, offset, Address.RANDOM_DEVICE_ADDRESS
|
||||||
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def parse_address_with_type(data, offset, address_type):
|
def parse_address_with_type(data, offset, address_type):
|
||||||
return offset + 6, Address(data[offset : offset + 6], address_type)
|
return offset + 6, Address(data[offset : offset + 6], address_type)
|
||||||
@@ -1965,7 +1971,8 @@ class Address:
|
|||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return (
|
return (
|
||||||
self.address_bytes == other.address_bytes
|
isinstance(other, Address)
|
||||||
|
and self.address_bytes == other.address_bytes
|
||||||
and self.is_public == other.is_public
|
and self.is_public == other.is_public
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -5178,8 +5185,8 @@ class HCI_LE_Data_Length_Change_Event(HCI_LE_Meta_Event):
|
|||||||
),
|
),
|
||||||
('peer_address_type', Address.ADDRESS_TYPE_SPEC),
|
('peer_address_type', Address.ADDRESS_TYPE_SPEC),
|
||||||
('peer_address', Address.parse_address_preceded_by_type),
|
('peer_address', Address.parse_address_preceded_by_type),
|
||||||
('local_resolvable_private_address', Address.parse_address),
|
('local_resolvable_private_address', Address.parse_random_address),
|
||||||
('peer_resolvable_private_address', Address.parse_address),
|
('peer_resolvable_private_address', Address.parse_random_address),
|
||||||
('connection_interval', 2),
|
('connection_interval', 2),
|
||||||
('peripheral_latency', 2),
|
('peripheral_latency', 2),
|
||||||
('supervision_timeout', 2),
|
('supervision_timeout', 2),
|
||||||
|
|||||||
@@ -772,6 +772,8 @@ class Host(AbortableEventEmitter):
|
|||||||
event.connection_handle,
|
event.connection_handle,
|
||||||
BT_LE_TRANSPORT,
|
BT_LE_TRANSPORT,
|
||||||
event.peer_address,
|
event.peer_address,
|
||||||
|
getattr(event, 'local_resolvable_private_address', None),
|
||||||
|
getattr(event, 'peer_resolvable_private_address', None),
|
||||||
event.role,
|
event.role,
|
||||||
connection_parameters,
|
connection_parameters,
|
||||||
)
|
)
|
||||||
@@ -817,6 +819,8 @@ class Host(AbortableEventEmitter):
|
|||||||
event.bd_addr,
|
event.bd_addr,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
logger.debug(f'### BR/EDR CONNECTION FAILED: {event.status}')
|
logger.debug(f'### BR/EDR CONNECTION FAILED: {event.status}')
|
||||||
|
|||||||
@@ -767,8 +767,11 @@ class Session:
|
|||||||
self.oob_data_flag = 0 if pairing_config.oob is None else 1
|
self.oob_data_flag = 0 if pairing_config.oob is None else 1
|
||||||
|
|
||||||
# Set up addresses
|
# Set up addresses
|
||||||
self_address = connection.self_address
|
self_address = connection.self_resolvable_address or connection.self_address
|
||||||
peer_address = connection.peer_resolvable_address or connection.peer_address
|
peer_address = connection.peer_resolvable_address or connection.peer_address
|
||||||
|
logger.debug(
|
||||||
|
f"pairing with self_address={self_address}, peer_address={peer_address}"
|
||||||
|
)
|
||||||
if self.is_initiator:
|
if self.is_initiator:
|
||||||
self.ia = bytes(self_address)
|
self.ia = bytes(self_address)
|
||||||
self.iat = 1 if self_address.is_random else 0
|
self.iat = 1 if self_address.is_random else 0
|
||||||
|
|||||||
@@ -290,6 +290,8 @@ async def test_legacy_advertising_disconnection(auto_restart):
|
|||||||
0x0001,
|
0x0001,
|
||||||
BT_LE_TRANSPORT,
|
BT_LE_TRANSPORT,
|
||||||
peer_address,
|
peer_address,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
BT_PERIPHERAL_ROLE,
|
BT_PERIPHERAL_ROLE,
|
||||||
ConnectionParameters(0, 0, 0),
|
ConnectionParameters(0, 0, 0),
|
||||||
)
|
)
|
||||||
@@ -339,6 +341,8 @@ async def test_extended_advertising_connection(own_address_type):
|
|||||||
0x0001,
|
0x0001,
|
||||||
BT_LE_TRANSPORT,
|
BT_LE_TRANSPORT,
|
||||||
peer_address,
|
peer_address,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
BT_PERIPHERAL_ROLE,
|
BT_PERIPHERAL_ROLE,
|
||||||
ConnectionParameters(0, 0, 0),
|
ConnectionParameters(0, 0, 0),
|
||||||
)
|
)
|
||||||
@@ -379,6 +383,8 @@ async def test_extended_advertising_connection_out_of_order(own_address_type):
|
|||||||
0x0001,
|
0x0001,
|
||||||
BT_LE_TRANSPORT,
|
BT_LE_TRANSPORT,
|
||||||
peer_address,
|
peer_address,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
BT_PERIPHERAL_ROLE,
|
BT_PERIPHERAL_ROLE,
|
||||||
ConnectionParameters(0, 0, 0),
|
ConnectionParameters(0, 0, 0),
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user