From d3bd5a759f0e3389ac9b4383d42fa28917b864cb Mon Sep 17 00:00:00 2001 From: Gilles Boccon-Gibod Date: Sat, 3 May 2025 12:05:31 -0700 Subject: [PATCH] Revert "fix a few timescale adjustments" This reverts commit dedef79bef1f3f559a720bcf6433fb7f2a7e4948. --- apps/bench.py | 4 +- apps/console.py | 4 +- bumble/device.py | 145 ++++++++++++++++------------------------------- bumble/hci.py | 27 --------- bumble/host.py | 1 - 5 files changed, 54 insertions(+), 127 deletions(-) diff --git a/apps/bench.py b/apps/bench.py index 0c74f722..c306f196 100644 --- a/apps/bench.py +++ b/apps/bench.py @@ -121,9 +121,9 @@ def print_connection(connection): params.append( 'Parameters=' - f'{connection.parameters.connection_interval:.2f}/' + f'{connection.parameters.connection_interval * 1.25:.2f}/' f'{connection.parameters.peripheral_latency}/' - f'{connection.parameters.supervision_timeout:.2f} ' + f'{connection.parameters.supervision_timeout * 10} ' ) params.append(f'MTU={connection.att_mtu}') diff --git a/apps/console.py b/apps/console.py index 7ad313df..606aadb8 100644 --- a/apps/console.py +++ b/apps/console.py @@ -335,9 +335,9 @@ class ConsoleApp: elif self.connected_peer: connection = self.connected_peer.connection connection_parameters = ( - f'{connection.parameters.connection_interval:.2f}/' + f'{connection.parameters.connection_interval}/' f'{connection.parameters.peripheral_latency}/' - f'{connection.parameters.supervision_timeout:.2f}' + f'{connection.parameters.supervision_timeout}' ) if self.connection_phy is not None: phy_state = ( diff --git a/bumble/device.py b/bumble/device.py index f9c032bb..4b0222dd 100644 --- a/bumble/device.py +++ b/bumble/device.py @@ -61,6 +61,7 @@ from bumble.core import ( BaseBumbleError, ConnectionParameterUpdateError, CommandTimeoutError, + ConnectionParameters, ConnectionPHY, InvalidArgumentError, InvalidOperationError, @@ -483,7 +484,7 @@ class BIGInfoAdvertisement: sid: int num_bis: int nse: int - iso_interval: float + iso_interval: int bn: int pto: int irc: int @@ -501,7 +502,7 @@ class BIGInfoAdvertisement: sid, report.num_bis, report.nse, - report.iso_interval * 1.25, + report.iso_interval, report.bn, report.pto, report.irc, @@ -528,8 +529,8 @@ class AdvertisingParameters: advertising_event_properties: AdvertisingEventProperties = field( default_factory=AdvertisingEventProperties ) - primary_advertising_interval_min: float = DEVICE_DEFAULT_ADVERTISING_INTERVAL - primary_advertising_interval_max: float = DEVICE_DEFAULT_ADVERTISING_INTERVAL + primary_advertising_interval_min: int = DEVICE_DEFAULT_ADVERTISING_INTERVAL + primary_advertising_interval_max: int = DEVICE_DEFAULT_ADVERTISING_INTERVAL primary_advertising_channel_map: ( hci.HCI_LE_Set_Extended_Advertising_Parameters_Command.ChannelMap ) = ( @@ -553,8 +554,8 @@ class AdvertisingParameters: # ----------------------------------------------------------------------------- @dataclass class PeriodicAdvertisingParameters: - periodic_advertising_interval_min: float = DEVICE_DEFAULT_ADVERTISING_INTERVAL - periodic_advertising_interval_max: float = DEVICE_DEFAULT_ADVERTISING_INTERVAL + periodic_advertising_interval_min: int = DEVICE_DEFAULT_ADVERTISING_INTERVAL + periodic_advertising_interval_max: int = DEVICE_DEFAULT_ADVERTISING_INTERVAL periodic_advertising_properties: ( hci.HCI_LE_Set_Periodic_Advertising_Parameters_Command.Properties ) = field( @@ -684,12 +685,8 @@ class AdvertisingSet(utils.EventEmitter): await self.device.send_command( hci.HCI_LE_Set_Periodic_Advertising_Parameters_Command( advertising_handle=self.advertising_handle, - periodic_advertising_interval_min=int( - advertising_parameters.periodic_advertising_interval_min / 1.25 - ), - periodic_advertising_interval_max=int( - advertising_parameters.periodic_advertising_interval_max / 1.25 - ), + periodic_advertising_interval_min=advertising_parameters.periodic_advertising_interval_min, + periodic_advertising_interval_max=advertising_parameters.periodic_advertising_interval_max, periodic_advertising_properties=advertising_parameters.periodic_advertising_properties, ), check_result=True, @@ -829,7 +826,7 @@ class PeriodicAdvertisingSync(utils.EventEmitter): filter_duplicates: bool status: int advertiser_phy: int - periodic_advertising_interval: float # Advertising interval, in milliseconds + periodic_advertising_interval: int advertiser_clock_accuracy: int EVENT_STATE_CHANGE = "state_change" @@ -953,7 +950,7 @@ class PeriodicAdvertisingSync(utils.EventEmitter): if status == hci.HCI_SUCCESS: self.sync_handle = sync_handle self.advertiser_phy = advertiser_phy - self.periodic_advertising_interval = periodic_advertising_interval * 1.25 + self.periodic_advertising_interval = periodic_advertising_interval self.advertiser_clock_accuracy = advertiser_clock_accuracy self.state = self.State.ESTABLISHED self.emit(self.EVENT_ESTABLISHMENT) @@ -1058,7 +1055,7 @@ class Big(utils.EventEmitter): pto: int = 0 irc: int = 0 max_pdu: int = 0 - iso_interval: float = 0.0 + iso_interval: int = 0 bis_links: Sequence[BisLink] = () def __post_init__(self) -> None: @@ -1119,7 +1116,7 @@ class BigSync(utils.EventEmitter): pto: int = 0 irc: int = 0 max_pdu: int = 0 - iso_interval: float = 0.0 + iso_interval: int = 0 bis_links: Sequence[BisLink] = () def __post_init__(self) -> None: @@ -1200,11 +1197,11 @@ class ChannelSoundingProcedure: selected_tx_power: int subevent_len: int subevents_per_event: int - subevent_interval: float # milliseconds. + subevent_interval: int event_interval: int procedure_interval: int procedure_count: int - max_procedure_len: float # milliseconds. + max_procedure_len: int # ----------------------------------------------------------------------------- @@ -1229,8 +1226,9 @@ class Peer: def __init__(self, connection: Connection) -> None: self.connection = connection - # Shortcut to the connection's GATT client - self.gatt_client = connection.gatt_client + # Create a GATT client for the connection + self.gatt_client = gatt_client.Client(connection) + connection.gatt_client = self.gatt_client @property def services(self) -> list[gatt_client.ServiceProxy]: @@ -1588,7 +1586,7 @@ class Connection(utils.CompositeEventEmitter): encryption: int authenticated: bool sc: bool - link_key_type: Optional[int] + link_key_type: int gatt_client: gatt_client.Client pairing_peer_io_capability: Optional[int] pairing_peer_authentication_requirements: Optional[int] @@ -1658,23 +1656,17 @@ class Connection(utils.CompositeEventEmitter): def on_connection_encryption_key_refresh(self): pass - @dataclass - class Parameters: - connection_interval: float # Connection interval, in milliseconds. [LE only] - peripheral_latency: int # Peripheral latency, in number of intervals. [LE only] - supervision_timeout: float # Supervision timeout, in milliseconds. - def __init__( self, - device: Device, - handle: int, - transport: core.PhysicalTransport, - self_address: hci.Address, - self_resolvable_address: Optional[hci.Address], - peer_address: hci.Address, - peer_resolvable_address: Optional[hci.Address], - role: hci.Role, - parameters: Parameters, + device, + handle, + transport, + self_address, + self_resolvable_address, + peer_address, + peer_resolvable_address, + role, + parameters, ): super().__init__() self.device = device @@ -1693,7 +1685,7 @@ class Connection(utils.CompositeEventEmitter): self.link_key_type = None self.att_mtu = ATT_DEFAULT_MTU self.data_length = DEVICE_DEFAULT_DATA_LENGTH - self.gatt_client = gatt_client.Client(self) # Per-connection client + self.gatt_client = None # Per-connection client self.gatt_server = ( device.gatt_server ) # By default, use the device's shared server @@ -1820,22 +1812,12 @@ class Connection(utils.CompositeEventEmitter): async def update_parameters( self, - connection_interval_min: float, - connection_interval_max: float, - max_latency: int, - supervision_timeout: float, + connection_interval_min, + connection_interval_max, + max_latency, + supervision_timeout, use_l2cap=False, - ) -> None: - """ - Request an update of the connection parameters. - - Args: - connection_interval_min: Minimum interval, in milliseconds. - connection_interval_max: Maximum interval, in milliseconds. - max_latency: Latency, in number of intervals. - supervision_timeout: Timeout, in milliseconds. - use_l2cap: Request the update via L2CAP. - """ + ): return await self.device.update_connection_parameters( self, connection_interval_min, @@ -1922,8 +1904,8 @@ class DeviceConfiguration: address: hci.Address = hci.Address(DEVICE_DEFAULT_ADDRESS) class_of_device: int = DEVICE_DEFAULT_CLASS_OF_DEVICE scan_response_data: bytes = DEVICE_DEFAULT_SCAN_RESPONSE_DATA - advertising_interval_min: float = DEVICE_DEFAULT_ADVERTISING_INTERVAL - advertising_interval_max: float = DEVICE_DEFAULT_ADVERTISING_INTERVAL + advertising_interval_min: int = DEVICE_DEFAULT_ADVERTISING_INTERVAL + advertising_interval_max: int = DEVICE_DEFAULT_ADVERTISING_INTERVAL le_enabled: bool = True le_simultaneous_enabled: bool = False le_privacy_enabled: bool = False @@ -2842,8 +2824,8 @@ class Device(utils.CompositeEventEmitter): auto_restart: bool = False, advertising_data: Optional[bytes] = None, scan_response_data: Optional[bytes] = None, - advertising_interval_min: Optional[float] = None, - advertising_interval_max: Optional[float] = None, + advertising_interval_min: Optional[int] = None, + advertising_interval_max: Optional[int] = None, ) -> None: """Start legacy advertising. @@ -3998,39 +3980,20 @@ class Device(utils.CompositeEventEmitter): async def update_connection_parameters( self, - connection: Connection, - connection_interval_min: float, - connection_interval_max: float, - max_latency: int, - supervision_timeout: float, - min_ce_length: float = 0.0, - max_ce_length: float = 0.0, - use_l2cap: bool = False, + connection, + connection_interval_min, + connection_interval_max, + max_latency, + supervision_timeout, + min_ce_length=0, + max_ce_length=0, + use_l2cap=False, ) -> None: ''' - Request an update of the connection parameters. - - Args: - connection: The connection to update - connection_interval_min: Minimum interval, in milliseconds. - connection_interval_max: Maximum interval, in milliseconds. - max_latency: Latency, in number of intervals. - supervision_timeout: Timeout, in milliseconds. - min_ce_length: Minimum connection event length, in milliseconds. - max_ce_length: Maximum connection event length, in milliseconds. - use_l2cap: Request the update via L2CAP. - NOTE: the name of the parameters may look odd, but it just follows the names used in the Bluetooth spec. ''' - # Convert the input parameters - connection_interval_min = int(connection_interval_min / 1.25) - connection_interval_max = int(connection_interval_max / 1.25) - supervision_timeout = int(supervision_timeout / 10) - min_ce_length = int(min_ce_length / 0.625) - max_ce_length = int(max_ce_length / 0.625) - if use_l2cap: if connection.role != hci.Role.PERIPHERAL: raise InvalidStateError( @@ -4048,8 +4011,6 @@ class Device(utils.CompositeEventEmitter): if l2cap_result != l2cap.L2CAP_CONNECTION_PARAMETERS_ACCEPTED_RESULT: raise ConnectionParameterUpdateError(l2cap_result) - return - result = await self.send_command( hci.HCI_LE_Connection_Update_Command( connection_handle=connection.handle, @@ -5247,7 +5208,7 @@ class Device(utils.CompositeEventEmitter): big.pto = pto big.irc = irc big.max_pdu = max_pdu - big.iso_interval = iso_interval * 1.25 + big.iso_interval = iso_interval big.state = Big.State.ACTIVE for bis_link in big.bis_links: @@ -5296,7 +5257,7 @@ class Device(utils.CompositeEventEmitter): big_sync.pto = pto big_sync.irc = irc big_sync.max_pdu = max_pdu - big_sync.iso_interval = iso_interval * 1.25 + big_sync.iso_interval = iso_interval big_sync.bis_links = [ BisLink(handle=handle, big=big_sync) for handle in bis_handles ] @@ -5353,7 +5314,7 @@ class Device(utils.CompositeEventEmitter): self_resolvable_address: Optional[hci.Address], peer_resolvable_address: Optional[hci.Address], role: hci.Role, - connection_parameters: Optional[core.ConnectionParameters], + connection_parameters: ConnectionParameters, ) -> None: # Convert all-zeros addresses into None. if self_resolvable_address == hci.Address.ANY_RANDOM: @@ -5384,8 +5345,6 @@ class Device(utils.CompositeEventEmitter): return - assert connection_parameters is not None - if peer_resolvable_address is None: # Resolve the peer address if we can if self.address_resolver: @@ -5441,11 +5400,7 @@ class Device(utils.CompositeEventEmitter): peer_address, peer_resolvable_address, role, - Connection.Parameters( - connection_parameters.connection_interval * 1.25, - connection_parameters.peripheral_latency, - connection_parameters.supervision_timeout * 10.0, - ), + connection_parameters, ) self.connections[connection_handle] = connection diff --git a/bumble/hci.py b/bumble/hci.py index 2ab46e41..4c9259ff 100644 --- a/bumble/hci.py +++ b/bumble/hci.py @@ -5971,33 +5971,6 @@ class HCI_LE_Enhanced_Connection_Complete_Event(HCI_LE_Meta_Event): ''' -# ----------------------------------------------------------------------------- -@HCI_LE_Meta_Event.event( - [ - ('status', STATUS_SPEC), - ('connection_handle', 2), - ( - 'role', - {'size': 1, 'mapper': lambda x: 'CENTRAL' if x == 0 else 'PERIPHERAL'}, - ), - ('peer_address_type', Address.ADDRESS_TYPE_SPEC), - ('peer_address', Address.parse_address_preceded_by_type), - ('local_resolvable_private_address', Address.parse_random_address), - ('peer_resolvable_private_address', Address.parse_random_address), - ('connection_interval', 2), - ('peripheral_latency', 2), - ('supervision_timeout', 2), - ('central_clock_accuracy', 1), - ('advertising_handle', 1), - ('sync_handle', 2), - ] -) -class HCI_LE_Enhanced_Connection_Complete_V2_Event(HCI_LE_Meta_Event): - ''' - See Bluetooth spec @ 7.7.65.10 LE Enhanced Connection Complete Event - ''' - - # ----------------------------------------------------------------------------- @HCI_LE_Meta_Event.event( [ diff --git a/bumble/host.py b/bumble/host.py index 183c5a7e..3b53b8aa 100644 --- a/bumble/host.py +++ b/bumble/host.py @@ -456,7 +456,6 @@ class Host(utils.EventEmitter): hci.HCI_LE_READ_LOCAL_P_256_PUBLIC_KEY_COMPLETE_EVENT, hci.HCI_LE_GENERATE_DHKEY_COMPLETE_EVENT, hci.HCI_LE_ENHANCED_CONNECTION_COMPLETE_EVENT, - hci.HCI_LE_ENHANCED_CONNECTION_COMPLETE_V2_EVENT, hci.HCI_LE_DIRECTED_ADVERTISING_REPORT_EVENT, hci.HCI_LE_PHY_UPDATE_COMPLETE_EVENT, hci.HCI_LE_EXTENDED_ADVERTISING_REPORT_EVENT,