From 422b05ad51b5472cfc73c6a9db333a1001de5498 Mon Sep 17 00:00:00 2001 From: Gilles Boccon-Gibod Date: Fri, 13 Jan 2023 13:22:27 -0800 Subject: [PATCH 1/2] don't set a random address when it is 00:00:00:00:00:00 --- bumble/device.py | 11 +++++++---- bumble/hci.py | 5 +++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/bumble/device.py b/bumble/device.py index 5dd23bf..075f312 100644 --- a/bumble/device.py +++ b/bumble/device.py @@ -1113,10 +1113,13 @@ class Device(CompositeEventEmitter): if self.le_enabled: # Set the controller address - await self.send_command( - HCI_LE_Set_Random_Address_Command(random_address=self.random_address), - check_result=True, - ) + if self.random_address != Address.ANY_RANDOM: + await self.send_command( + HCI_LE_Set_Random_Address_Command( + random_address=self.random_address + ), + check_result=True, + ) # Load the address resolving list if self.keystore and self.host.supports_command( diff --git a/bumble/hci.py b/bumble/hci.py index 257b303..e23fb17 100644 --- a/bumble/hci.py +++ b/bumble/hci.py @@ -1638,8 +1638,8 @@ class HCI_Object: # Map the value if needed if value_mappers: value_mapper = value_mappers.get(key, value_mapper) - if value_mapper is not None: - value = value_mapper(value) + if value_mapper is not None: + value = value_mapper(value) # Get the string representation of the value value_str = HCI_Object.format_field_value( @@ -1807,6 +1807,7 @@ class Address: # Predefined address values Address.NIL = Address(b"\xff\xff\xff\xff\xff\xff", Address.PUBLIC_DEVICE_ADDRESS) Address.ANY = Address(b"\x00\x00\x00\x00\x00\x00", Address.PUBLIC_DEVICE_ADDRESS) +Address.ANY_RANDOM = Address(b"\x00\x00\x00\x00\x00\x00", Address.RANDOM_DEVICE_ADDRESS) # ----------------------------------------------------------------------------- class OwnAddressType: From 0a22f2f7c7607b4e471fe220fa64b2c448923eb3 Mon Sep 17 00:00:00 2001 From: Gilles Boccon-Gibod Date: Fri, 13 Jan 2023 16:59:34 -0800 Subject: [PATCH 2/2] use HCI_LE_Rand --- bumble/device.py | 24 ++++++++++++++++++++++++ bumble/hci.py | 10 ++++++++++ 2 files changed, 34 insertions(+) diff --git a/bumble/device.py b/bumble/device.py index 075f312..1ffc5c6 100644 --- a/bumble/device.py +++ b/bumble/device.py @@ -46,6 +46,7 @@ from .hci import ( HCI_LE_CODED_PHY_LE_SUPPORTED_FEATURE, HCI_LE_EXTENDED_ADVERTISING_LE_SUPPORTED_FEATURE, HCI_LE_EXTENDED_CREATE_CONNECTION_COMMAND, + HCI_LE_RAND_COMMAND, HCI_LE_READ_PHY_COMMAND, HCI_MITM_NOT_REQUIRED_GENERAL_BONDING_AUTHENTICATION_REQUIREMENTS, HCI_MITM_NOT_REQUIRED_NO_BONDING_AUTHENTICATION_REQUIREMENTS, @@ -78,6 +79,7 @@ from .hci import ( HCI_LE_Enable_Encryption_Command, HCI_LE_Extended_Advertising_Report_Event, HCI_LE_Extended_Create_Connection_Command, + HCI_LE_Rand_Command, HCI_LE_Read_PHY_Command, HCI_LE_Set_Advertising_Data_Command, HCI_LE_Set_Advertising_Enable_Command, @@ -1113,7 +1115,29 @@ class Device(CompositeEventEmitter): if self.le_enabled: # Set the controller address + if self.random_address == Address.ANY_RANDOM: + # Try to use an address generated at random by the controller + if self.host.supports_command(HCI_LE_RAND_COMMAND): + # Get 8 random bytes + response = await self.send_command( + HCI_LE_Rand_Command(), check_result=True + ) + + # Ensure the address bytes can be a static random address + address_bytes = response.return_parameters.random_number[ + :5 + ] + bytes([response.return_parameters.random_number[5] | 0xC0]) + + # Create a static random address from the random bytes + self.random_address = Address(address_bytes) + if self.random_address != Address.ANY_RANDOM: + logger.debug( + color( + f'LE Random Address: {self.random_address}', + 'yellow', + ) + ) await self.send_command( HCI_LE_Set_Random_Address_Command( random_address=self.random_address diff --git a/bumble/hci.py b/bumble/hci.py index e23fb17..b721700 100644 --- a/bumble/hci.py +++ b/bumble/hci.py @@ -3105,6 +3105,16 @@ class HCI_LE_Read_Remote_Features_Command(HCI_Command): ''' +# ----------------------------------------------------------------------------- +@HCI_Command.command( + return_parameters_fields=[("status", STATUS_SPEC), ("random_number", 8)] +) +class HCI_LE_Rand_Command(HCI_Command): + """ + See Bluetooth spec @ 7.8.23 LE Rand Command + """ + + # ----------------------------------------------------------------------------- @HCI_Command.command( [