From e62f94743059a7aa5e797335d347b7d8f28ccbe0 Mon Sep 17 00:00:00 2001 From: Gilles Boccon-Gibod Date: Mon, 2 Feb 2026 13:19:55 -0800 Subject: [PATCH] add workaround for some buggy controllers --- bumble/host.py | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/bumble/host.py b/bumble/host.py index 649b18a2..f7bf5398 100644 --- a/bumble/host.py +++ b/bumble/host.py @@ -616,22 +616,28 @@ class Host(utils.EventEmitter): if self.supports_command( hci.HCI_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS_COMMAND ): - response10 = await self.send_sync_command( - hci.HCI_LE_Read_Number_Of_Supported_Advertising_Sets_Command() - ) - self.number_of_supported_advertising_sets = ( - response10.num_supported_advertising_sets - ) + try: + response10 = await self.send_sync_command( + hci.HCI_LE_Read_Number_Of_Supported_Advertising_Sets_Command() + ) + self.number_of_supported_advertising_sets = ( + response10.num_supported_advertising_sets + ) + except hci.HCI_Error: + logger.warning('Failed to read number of supported advertising sets') if self.supports_command( hci.HCI_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH_COMMAND ): - response11 = await self.send_sync_command( - hci.HCI_LE_Read_Maximum_Advertising_Data_Length_Command() - ) - self.maximum_advertising_data_length = ( - response11.max_advertising_data_length - ) + try: + response11 = await self.send_sync_command( + hci.HCI_LE_Read_Maximum_Advertising_Data_Length_Command() + ) + self.maximum_advertising_data_length = ( + response11.max_advertising_data_length + ) + except hci.HCI_Error: + logger.warning('Failed to read maximum advertising data length') @property def controller(self) -> TransportSink | None: @@ -776,6 +782,20 @@ class Host(utils.EventEmitter): ) -> hci.HCI_Command_Complete_Event[_RP]: response = await self._send_command(command, response_timeout) + # Some buggy controllers return Command Status instead of Command Complete... + if isinstance(response, hci.HCI_Command_Status_Event): + logger.warning( + f'expected Command Complete for {command.name}, ' + 'but got Command Status instead' + ) + return hci.HCI_Command_Complete_Event( + num_hci_command_packets=response.num_hci_command_packets, + command_opcode=command.op_code, + return_parameters=hci.HCI_StatusReturnParameters( + status=hci.HCI_ErrorCode(response.status) + ), # type: ignore + ) + # Check that the response is of the expected type assert isinstance(response, hci.HCI_Command_Complete_Event)