format (+3 squashed commits)

Squashed commits:
[60e610f] wip
[eeab73d] wip
[3cdd5b8] basic first pass
This commit is contained in:
Gilles Boccon-Gibod
2023-12-18 09:49:57 -08:00
parent 071fc2723a
commit d3273ffa8c
11 changed files with 1118 additions and 577 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -23,7 +23,7 @@ import functools
import logging
import secrets
import struct
from typing import Any, Dict, Callable, Optional, Type, Union, List
from typing import Any, Callable, Dict, Iterable, List, Optional, Type, Union
from bumble import crypto
from .colors import color
@@ -223,41 +223,47 @@ HCI_VENDOR_EVENT = 0xFF
# HCI Subevent Codes
HCI_LE_CONNECTION_COMPLETE_EVENT = 0x01
HCI_LE_ADVERTISING_REPORT_EVENT = 0x02
HCI_LE_CONNECTION_UPDATE_COMPLETE_EVENT = 0x03
HCI_LE_READ_REMOTE_FEATURES_COMPLETE_EVENT = 0x04
HCI_LE_LONG_TERM_KEY_REQUEST_EVENT = 0x05
HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_EVENT = 0x06
HCI_LE_DATA_LENGTH_CHANGE_EVENT = 0x07
HCI_LE_READ_LOCAL_P_256_PUBLIC_KEY_COMPLETE_EVENT = 0x08
HCI_LE_GENERATE_DHKEY_COMPLETE_EVENT = 0x09
HCI_LE_ENHANCED_CONNECTION_COMPLETE_EVENT = 0x0A
HCI_LE_DIRECTED_ADVERTISING_REPORT_EVENT = 0x0B
HCI_LE_PHY_UPDATE_COMPLETE_EVENT = 0x0C
HCI_LE_EXTENDED_ADVERTISING_REPORT_EVENT = 0x0D
HCI_LE_PERIODIC_ADVERTISING_SYNC_ESTABLISHED_EVENT = 0x0E
HCI_LE_PERIODIC_ADVERTISING_REPORT_EVENT = 0x0F
HCI_LE_PERIODIC_ADVERTISING_SYNC_LOST_EVENT = 0x10
HCI_LE_SCAN_TIMEOUT_EVENT = 0x11
HCI_LE_ADVERTISING_SET_TERMINATED_EVENT = 0x12
HCI_LE_SCAN_REQUEST_RECEIVED_EVENT = 0x13
HCI_LE_CHANNEL_SELECTION_ALGORITHM_EVENT = 0x14
HCI_LE_CONNECTIONLESS_IQ_REPORT_EVENT = 0X15
HCI_LE_CONNECTION_IQ_REPORT_EVENT = 0X16
HCI_LE_CTE_REQUEST_FAILED_EVENT = 0X17
HCI_LE_PERIODIC_ADVERTISING_SYNC_TRANSFER_RECEIVED_EVENT = 0X18
HCI_LE_CIS_ESTABLISHED_EVENT = 0X19
HCI_LE_CIS_REQUEST_EVENT = 0X1A
HCI_LE_CREATE_BIG_COMPLETE_EVENT = 0X1B
HCI_LE_TERMINATE_BIG_COMPLETE_EVENT = 0X1C
HCI_LE_BIG_SYNC_ESTABLISHED_EVENT = 0X1D
HCI_LE_BIG_SYNC_LOST_EVENT = 0X1E
HCI_LE_REQUEST_PEER_SCA_COMPLETE_EVENT = 0X1F
HCI_LE_PATH_LOSS_THRESHOLD_EVENT = 0X20
HCI_LE_TRANSMIT_POWER_REPORTING_EVENT = 0X21
HCI_LE_BIGINFO_ADVERTISING_REPORT_EVENT = 0X22
HCI_LE_SUBRATE_CHANGE_EVENT = 0X23
HCI_LE_CONNECTION_COMPLETE_EVENT = 0x01
HCI_LE_ADVERTISING_REPORT_EVENT = 0x02
HCI_LE_CONNECTION_UPDATE_COMPLETE_EVENT = 0x03
HCI_LE_READ_REMOTE_FEATURES_COMPLETE_EVENT = 0x04
HCI_LE_LONG_TERM_KEY_REQUEST_EVENT = 0x05
HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_EVENT = 0x06
HCI_LE_DATA_LENGTH_CHANGE_EVENT = 0x07
HCI_LE_READ_LOCAL_P_256_PUBLIC_KEY_COMPLETE_EVENT = 0x08
HCI_LE_GENERATE_DHKEY_COMPLETE_EVENT = 0x09
HCI_LE_ENHANCED_CONNECTION_COMPLETE_EVENT = 0x0A
HCI_LE_DIRECTED_ADVERTISING_REPORT_EVENT = 0x0B
HCI_LE_PHY_UPDATE_COMPLETE_EVENT = 0x0C
HCI_LE_EXTENDED_ADVERTISING_REPORT_EVENT = 0x0D
HCI_LE_PERIODIC_ADVERTISING_SYNC_ESTABLISHED_EVENT = 0x0E
HCI_LE_PERIODIC_ADVERTISING_REPORT_EVENT = 0x0F
HCI_LE_PERIODIC_ADVERTISING_SYNC_LOST_EVENT = 0x10
HCI_LE_SCAN_TIMEOUT_EVENT = 0x11
HCI_LE_ADVERTISING_SET_TERMINATED_EVENT = 0x12
HCI_LE_SCAN_REQUEST_RECEIVED_EVENT = 0x13
HCI_LE_CHANNEL_SELECTION_ALGORITHM_EVENT = 0x14
HCI_LE_CONNECTIONLESS_IQ_REPORT_EVENT = 0X15
HCI_LE_CONNECTION_IQ_REPORT_EVENT = 0X16
HCI_LE_CTE_REQUEST_FAILED_EVENT = 0X17
HCI_LE_PERIODIC_ADVERTISING_SYNC_TRANSFER_RECEIVED_EVENT = 0X18
HCI_LE_CIS_ESTABLISHED_EVENT = 0X19
HCI_LE_CIS_REQUEST_EVENT = 0X1A
HCI_LE_CREATE_BIG_COMPLETE_EVENT = 0X1B
HCI_LE_TERMINATE_BIG_COMPLETE_EVENT = 0X1C
HCI_LE_BIG_SYNC_ESTABLISHED_EVENT = 0X1D
HCI_LE_BIG_SYNC_LOST_EVENT = 0X1E
HCI_LE_REQUEST_PEER_SCA_COMPLETE_EVENT = 0X1F
HCI_LE_PATH_LOSS_THRESHOLD_EVENT = 0X20
HCI_LE_TRANSMIT_POWER_REPORTING_EVENT = 0X21
HCI_LE_BIGINFO_ADVERTISING_REPORT_EVENT = 0X22
HCI_LE_SUBRATE_CHANGE_EVENT = 0X23
HCI_LE_PERIODIC_ADVERTISING_SYNC_ESTABLISHED_V2_EVENT = 0X24
HCI_LE_PERIODIC_ADVERTISING_REPORT_V2_EVENT = 0X25
HCI_LE_PERIODIC_ADVERTISING_SYNC_TRANSFER_RECEIVED_V2_EVENT = 0X26
HCI_LE_PERIODIC_ADVERTISING_SUBEVENT_DATA_REQUEST_EVENT = 0X27
HCI_LE_PERIODIC_ADVERTISING_RESPONSE_REPORT_EVENT = 0X28
HCI_LE_ENHANCED_CONNECTION_COMPLETE_V2_EVENT = 0X29
# HCI Command
@@ -650,47 +656,6 @@ HCI_ERROR_NAMES[HCI_SUCCESS] = 'HCI_SUCCESS'
# Command Status codes
HCI_COMMAND_STATUS_PENDING = 0
# LE Event Masks
HCI_LE_CONNECTION_COMPLETE_EVENT_MASK = (1 << 0)
HCI_LE_ADVERTISING_REPORT_EVENT_MASK = (1 << 1)
HCI_LE_CONNECTION_UPDATE_COMPLETE_EVENT_MASK = (1 << 2)
HCI_LE_READ_REMOTE_FEATURES_COMPLETE_EVENT_MASK = (1 << 3)
HCI_LE_LONG_TERM_KEY_REQUEST_EVENT_MASK = (1 << 4)
HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_EVENT_MASK = (1 << 5)
HCI_LE_DATA_LENGTH_CHANGE_EVENT_MASK = (1 << 6)
HCI_LE_READ_LOCAL_P_256_PUBLIC_KEY_COMPLETE_EVENT_MASK = (1 << 7)
HCI_LE_GENERATE_DHKEY_COMPLETE_EVENT_MASK = (1 << 8)
HCI_LE_ENHANCED_CONNECTION_COMPLETE_EVENT_MASK = (1 << 9)
HCI_LE_DIRECTED_ADVERTISING_REPORT_EVENT_MASK = (1 << 10)
HCI_LE_PHY_UPDATE_COMPLETE_EVENT_MASK = (1 << 11)
HCI_LE_EXTENDED_ADVERTISING_REPORT_EVENT_MASK = (1 << 12)
HCI_LE_PERIODIC_ADVERTISING_SYNC_ESTABLISHED_EVENT_MASK = (1 << 13)
HCI_LE_PERIODIC_ADVERTISING_REPORT_EVENT_MASK = (1 << 14)
HCI_LE_PERIODIC_ADVERTISING_SYNC_LOST_EVENT_MASK = (1 << 15)
HCI_LE_EXTENDED_SCAN_TIMEOUT_EVENT_MASK = (1 << 16)
HCI_LE_EXTENDED_ADVERTISING_SET_TERMINATED_EVENT_MASK = (1 << 17)
HCI_LE_SCAN_REQUEST_RECEIVED_EVENT_MASK = (1 << 18)
HCI_LE_CHANNEL_SELECTION_ALGORITHM_EVENT_MASK = (1 << 19)
HCI_LE_CONNECTIONLESS_IQ_REPORT_EVENT_MASK = (1 << 20)
HCI_LE_CONNECTION_IQ_REPORT_EVENT_MASK = (1 << 21)
HCI_LE_CTE_REQUEST_FAILED_EVENT_MASK = (1 << 22)
HCI_LE_PERIODIC_ADVERTISING_SYNC_TRANSFER_RECEIVED_EVENT_MASK = (1 << 23)
HCI_LE_CIS_ESTABLISHED_EVENT_MASK = (1 << 24)
HCI_LE_CIS_REQUEST_EVENT_MASK = (1 << 25)
HCI_LE_CREATE_BIG_COMPLETE_EVENT_MASK = (1 << 26)
HCI_LE_TERMINATE_BIG_COMPLETE_EVENT_MASK = (1 << 27)
HCI_LE_BIG_SYNC_ESTABLISHED_EVENT_MASK = (1 << 28)
HCI_LE_BIG_SYNC_LOST_EVENT_MASK = (1 << 29)
HCI_LE_REQUEST_PEER_SCA_COMPLETE_EVENT_MASK = (1 << 30)
HCI_LE_PATH_LOSS_THRESHOLD_EVENT_MASK = (1 << 31)
HCI_LE_TRANSMIT_POWER_REPORTING_EVENT_MASK = (1 << 32)
HCI_LE_BIGINFO_ADVERTISING_REPORT_EVENT_MASK = (1 << 33)
HCI_LE_SUBRATE_CHANGE_EVENT_MASK = (1 << 34)
HCI_LE_EVENT_MASK_NAMES = {
mask: mask_name for (mask_name, mask) in globals().items()
if mask_name.startswith('HCI_LE_') and mask_name.endswith('_EVENT_MASK')
}
# ACL
HCI_ACL_PB_FIRST_NON_FLUSHABLE = 0
@@ -732,15 +697,15 @@ HCI_LE_PHY_TYPE_TO_BIT = {
class Phy(enum.IntEnum):
LE_1M = 0x01
LE_2M = 0x02
LE_CODED = 0x03
LE_1M = HCI_LE_1M_PHY
LE_2M = HCI_LE_2M_PHY
LE_CODED = HCI_LE_CODED_PHY
class PhyBit(enum.IntFlag):
LE_1M = 0b00000001
LE_2M = 0b00000010
LE_CODED = 0b00000100
LE_1M = 1 << HCI_LE_1M_PHY_BIT
LE_2M = 1 << HCI_LE_2M_PHY_BIT
LE_CODED = 1 << HCI_LE_CODED_PHY_BIT
# Connection Parameters
@@ -2910,6 +2875,20 @@ class HCI_Set_Event_Mask_Command(HCI_Command):
See Bluetooth spec @ 7.3.1 Set Event Mask Command
'''
@staticmethod
def mask(event_codes: Iterable[int]) -> bytes:
'''
Compute the event mask value for a list of events.
'''
# NOTE: this implementation takes advantage of the fact that as of version 5.4
# of the core specification, the bit number for each event code is equal to one
# less than the event code.
# If future versions of the specification deviate from that, a different
# implementation would be needed.
return sum((1 << event_code - 1) for event_code in event_codes).to_bytes(
8, 'little'
)
# -----------------------------------------------------------------------------
@HCI_Command.command()
@@ -3433,6 +3412,20 @@ class HCI_LE_Set_Event_Mask_Command(HCI_Command):
See Bluetooth spec @ 7.8.1 LE Set Event Mask Command
'''
@staticmethod
def mask(event_codes: Iterable[int]) -> bytes:
'''
Compute the event mask value for a list of events.
'''
# NOTE: this implementation takes advantage of the fact that as of version 5.4
# of the core specification, the bit number for each event code is equal to one
# less than the event code.
# If future versions of the specification deviate from that, a different
# implementation would be needed.
return sum((1 << event_code - 1) for event_code in event_codes).to_bytes(
8, 'little'
)
# -----------------------------------------------------------------------------
@HCI_Command.command(
@@ -4040,13 +4033,16 @@ class HCI_LE_Set_Advertising_Set_Random_Address_Command(HCI_Command):
('advertising_sid', 1),
('scan_request_notification_enable', 1),
],
return_parameters_fields=[('status', STATUS_SPEC), ('selected_tx__power', 1)],
return_parameters_fields=[('status', STATUS_SPEC), ('selected_tx_power', 1)],
)
class HCI_LE_Set_Extended_Advertising_Parameters_Command(HCI_Command):
'''
See Bluetooth spec @ 7.8.53 LE Set Extended Advertising Parameters Command
'''
TX_POWER_NO_PREFERENCE = 0x7F
SHOULD_NOT_FRAGMENT = 0x01
class AdvertisingProperties(enum.IntFlag):
CONNECTABLE_ADVERTISING = 1 << 0
SCANNABLE_ADVERTISING = 1 << 1
@@ -4291,7 +4287,7 @@ class HCI_LE_Set_Extended_Scan_Parameters_Command(HCI_Command):
('scanning_filter_policy:', self.scanning_filter_policy),
('scanning_phys: ', ','.join(scanning_phys_strs)),
]
for (i, scanning_phy_str) in enumerate(scanning_phys_strs):
for i, scanning_phy_str in enumerate(scanning_phys_strs):
fields.append(
(
f'{scanning_phy_str}.scan_type: ',
@@ -4434,7 +4430,7 @@ class HCI_LE_Extended_Create_Connection_Command(HCI_Command):
('peer_address: ', str(self.peer_address)),
('initiating_phys: ', ','.join(initiating_phys_strs)),
]
for (i, initiating_phys_str) in enumerate(initiating_phys_strs):
for i, initiating_phys_str in enumerate(initiating_phys_strs):
fields.append(
(
f'{initiating_phys_str}.scan_interval: ',
@@ -5321,7 +5317,7 @@ HCI_LE_Meta_Event.subevent_classes[
('status', 1),
('advertising_handle', 1),
('connection_handle', 2),
('number_completed_extended_advertising_events', 1),
('num_completed_extended_advertising_events', 1),
]
)
class HCI_LE_Advertising_Set_Terminated_Event(HCI_LE_Meta_Event):
@@ -6262,7 +6258,7 @@ class HCI_IsoDataPacket(HCI_Packet):
if ts_flag:
if not should_include_sdu_info:
logger.warn(f'Timestamp included when pb_flag={bin(pb_flag)}')
logger.warning(f'Timestamp included when pb_flag={bin(pb_flag)}')
time_stamp, *_ = struct.unpack_from('<I', packet, pos)
pos += 4

View File

@@ -39,6 +39,8 @@ from .hci import (
HCI_LE_READ_LOCAL_SUPPORTED_FEATURES_COMMAND,
HCI_LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH_COMMAND,
HCI_LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH_COMMAND,
HCI_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS_COMMAND,
HCI_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH_COMMAND,
HCI_READ_BUFFER_SIZE_COMMAND,
HCI_READ_LOCAL_VERSION_INFORMATION_COMMAND,
HCI_RESET_COMMAND,
@@ -46,6 +48,88 @@ from .hci import (
HCI_SUPPORTED_COMMANDS_FLAGS,
HCI_SYNCHRONOUS_DATA_PACKET,
HCI_VERSION_BLUETOOTH_CORE_4_0,
HCI_INQUIRY_COMPLETE_EVENT,
HCI_INQUIRY_RESULT_EVENT,
HCI_CONNECTION_COMPLETE_EVENT,
HCI_CONNECTION_REQUEST_EVENT,
HCI_DISCONNECTION_COMPLETE_EVENT,
HCI_AUTHENTICATION_COMPLETE_EVENT,
HCI_REMOTE_NAME_REQUEST_COMPLETE_EVENT,
HCI_ENCRYPTION_CHANGE_EVENT,
HCI_CHANGE_CONNECTION_LINK_KEY_COMPLETE_EVENT,
HCI_LINK_KEY_TYPE_CHANGED_EVENT,
HCI_READ_REMOTE_SUPPORTED_FEATURES_COMPLETE_EVENT,
HCI_READ_REMOTE_VERSION_INFORMATION_COMPLETE_EVENT,
HCI_QOS_SETUP_COMPLETE_EVENT,
HCI_HARDWARE_ERROR_EVENT,
HCI_FLUSH_OCCURRED_EVENT,
HCI_ROLE_CHANGE_EVENT,
HCI_MODE_CHANGE_EVENT,
HCI_RETURN_LINK_KEYS_EVENT,
HCI_PIN_CODE_REQUEST_EVENT,
HCI_LINK_KEY_REQUEST_EVENT,
HCI_LINK_KEY_NOTIFICATION_EVENT,
HCI_LOOPBACK_COMMAND_EVENT,
HCI_DATA_BUFFER_OVERFLOW_EVENT,
HCI_MAX_SLOTS_CHANGE_EVENT,
HCI_READ_CLOCK_OFFSET_COMPLETE_EVENT,
HCI_CONNECTION_PACKET_TYPE_CHANGED_EVENT,
HCI_QOS_VIOLATION_EVENT,
HCI_PAGE_SCAN_REPETITION_MODE_CHANGE_EVENT,
HCI_FLOW_SPECIFICATION_COMPLETE_EVENT,
HCI_INQUIRY_RESULT_WITH_RSSI_EVENT,
HCI_READ_REMOTE_EXTENDED_FEATURES_COMPLETE_EVENT,
HCI_SYNCHRONOUS_CONNECTION_COMPLETE_EVENT,
HCI_SYNCHRONOUS_CONNECTION_CHANGED_EVENT,
HCI_SNIFF_SUBRATING_EVENT,
HCI_EXTENDED_INQUIRY_RESULT_EVENT,
HCI_ENCRYPTION_KEY_REFRESH_COMPLETE_EVENT,
HCI_IO_CAPABILITY_REQUEST_EVENT,
HCI_IO_CAPABILITY_RESPONSE_EVENT,
HCI_USER_CONFIRMATION_REQUEST_EVENT,
HCI_USER_PASSKEY_REQUEST_EVENT,
HCI_REMOTE_OOB_DATA_REQUEST_EVENT,
HCI_SIMPLE_PAIRING_COMPLETE_EVENT,
HCI_LINK_SUPERVISION_TIMEOUT_CHANGED_EVENT,
HCI_ENHANCED_FLUSH_COMPLETE_EVENT,
HCI_USER_PASSKEY_NOTIFICATION_EVENT,
HCI_KEYPRESS_NOTIFICATION_EVENT,
HCI_REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION_EVENT,
HCI_LE_META_EVENT,
HCI_LE_CONNECTION_COMPLETE_EVENT,
HCI_LE_ADVERTISING_REPORT_EVENT,
HCI_LE_CONNECTION_UPDATE_COMPLETE_EVENT,
HCI_LE_READ_REMOTE_FEATURES_COMPLETE_EVENT,
HCI_LE_LONG_TERM_KEY_REQUEST_EVENT,
HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_EVENT,
HCI_LE_DATA_LENGTH_CHANGE_EVENT,
HCI_LE_READ_LOCAL_P_256_PUBLIC_KEY_COMPLETE_EVENT,
HCI_LE_GENERATE_DHKEY_COMPLETE_EVENT,
HCI_LE_ENHANCED_CONNECTION_COMPLETE_EVENT,
HCI_LE_DIRECTED_ADVERTISING_REPORT_EVENT,
HCI_LE_PHY_UPDATE_COMPLETE_EVENT,
HCI_LE_EXTENDED_ADVERTISING_REPORT_EVENT,
HCI_LE_PERIODIC_ADVERTISING_SYNC_ESTABLISHED_EVENT,
HCI_LE_PERIODIC_ADVERTISING_REPORT_EVENT,
HCI_LE_PERIODIC_ADVERTISING_SYNC_LOST_EVENT,
HCI_LE_SCAN_TIMEOUT_EVENT,
HCI_LE_ADVERTISING_SET_TERMINATED_EVENT,
HCI_LE_SCAN_REQUEST_RECEIVED_EVENT,
HCI_LE_CONNECTIONLESS_IQ_REPORT_EVENT,
HCI_LE_CONNECTION_IQ_REPORT_EVENT,
HCI_LE_CTE_REQUEST_FAILED_EVENT,
HCI_LE_PERIODIC_ADVERTISING_SYNC_TRANSFER_RECEIVED_EVENT,
HCI_LE_CIS_ESTABLISHED_EVENT,
HCI_LE_CIS_REQUEST_EVENT,
HCI_LE_CREATE_BIG_COMPLETE_EVENT,
HCI_LE_TERMINATE_BIG_COMPLETE_EVENT,
HCI_LE_BIG_SYNC_ESTABLISHED_EVENT,
HCI_LE_BIG_SYNC_LOST_EVENT,
HCI_LE_REQUEST_PEER_SCA_COMPLETE_EVENT,
HCI_LE_PATH_LOSS_THRESHOLD_EVENT,
HCI_LE_TRANSMIT_POWER_REPORTING_EVENT,
HCI_LE_BIGINFO_ADVERTISING_REPORT_EVENT,
HCI_LE_SUBRATE_CHANGE_EVENT,
HCI_AclDataPacket,
HCI_AclDataPacketAssembler,
HCI_Command,
@@ -56,12 +140,14 @@ from .hci import (
HCI_IsoDataPacket,
HCI_LE_Long_Term_Key_Request_Negative_Reply_Command,
HCI_LE_Long_Term_Key_Request_Reply_Command,
HCI_LE_Read_Number_Of_Supported_Advertising_Sets_Command,
HCI_LE_Read_Buffer_Size_Command,
HCI_LE_Read_Local_Supported_Features_Command,
HCI_LE_Read_Suggested_Default_Data_Length_Command,
HCI_LE_Remote_Connection_Parameter_Request_Reply_Command,
HCI_LE_Set_Event_Mask_Command,
HCI_LE_Write_Suggested_Default_Data_Length_Command,
HCI_LE_Read_Maximum_Advertising_Data_Length_Command,
HCI_Link_Key_Request_Negative_Reply_Command,
HCI_Link_Key_Request_Reply_Command,
HCI_Packet,
@@ -204,6 +290,8 @@ class Host(AbortableEventEmitter):
self.sco_links = {} # SCO links, by connection handle
self.pending_command = None
self.pending_response = None
self.number_of_supported_advertising_sets = 0
self.maximum_advertising_data_length = 31
self.local_version = None
self.local_supported_commands = bytes(64)
self.local_le_features = 0
@@ -288,7 +376,60 @@ class Host(AbortableEventEmitter):
self.local_version = response.return_parameters
await self.send_command(
HCI_Set_Event_Mask_Command(event_mask=bytes.fromhex('FFFFFFFFFFFFFF3F'))
HCI_Set_Event_Mask_Command(
event_mask=HCI_Set_Event_Mask_Command.mask(
[
HCI_INQUIRY_COMPLETE_EVENT,
HCI_INQUIRY_RESULT_EVENT,
HCI_CONNECTION_COMPLETE_EVENT,
HCI_CONNECTION_REQUEST_EVENT,
HCI_DISCONNECTION_COMPLETE_EVENT,
HCI_AUTHENTICATION_COMPLETE_EVENT,
HCI_REMOTE_NAME_REQUEST_COMPLETE_EVENT,
HCI_ENCRYPTION_CHANGE_EVENT,
HCI_CHANGE_CONNECTION_LINK_KEY_COMPLETE_EVENT,
HCI_LINK_KEY_TYPE_CHANGED_EVENT,
HCI_READ_REMOTE_SUPPORTED_FEATURES_COMPLETE_EVENT,
HCI_READ_REMOTE_VERSION_INFORMATION_COMPLETE_EVENT,
HCI_QOS_SETUP_COMPLETE_EVENT,
HCI_HARDWARE_ERROR_EVENT,
HCI_FLUSH_OCCURRED_EVENT,
HCI_ROLE_CHANGE_EVENT,
HCI_MODE_CHANGE_EVENT,
HCI_RETURN_LINK_KEYS_EVENT,
HCI_PIN_CODE_REQUEST_EVENT,
HCI_LINK_KEY_REQUEST_EVENT,
HCI_LINK_KEY_NOTIFICATION_EVENT,
HCI_LOOPBACK_COMMAND_EVENT,
HCI_DATA_BUFFER_OVERFLOW_EVENT,
HCI_MAX_SLOTS_CHANGE_EVENT,
HCI_READ_CLOCK_OFFSET_COMPLETE_EVENT,
HCI_CONNECTION_PACKET_TYPE_CHANGED_EVENT,
HCI_QOS_VIOLATION_EVENT,
HCI_PAGE_SCAN_REPETITION_MODE_CHANGE_EVENT,
HCI_FLOW_SPECIFICATION_COMPLETE_EVENT,
HCI_INQUIRY_RESULT_WITH_RSSI_EVENT,
HCI_READ_REMOTE_EXTENDED_FEATURES_COMPLETE_EVENT,
HCI_SYNCHRONOUS_CONNECTION_COMPLETE_EVENT,
HCI_SYNCHRONOUS_CONNECTION_CHANGED_EVENT,
HCI_SNIFF_SUBRATING_EVENT,
HCI_EXTENDED_INQUIRY_RESULT_EVENT,
HCI_ENCRYPTION_KEY_REFRESH_COMPLETE_EVENT,
HCI_IO_CAPABILITY_REQUEST_EVENT,
HCI_IO_CAPABILITY_RESPONSE_EVENT,
HCI_USER_CONFIRMATION_REQUEST_EVENT,
HCI_USER_PASSKEY_REQUEST_EVENT,
HCI_REMOTE_OOB_DATA_REQUEST_EVENT,
HCI_SIMPLE_PAIRING_COMPLETE_EVENT,
HCI_LINK_SUPERVISION_TIMEOUT_CHANGED_EVENT,
HCI_ENHANCED_FLUSH_COMPLETE_EVENT,
HCI_USER_PASSKEY_NOTIFICATION_EVENT,
HCI_KEYPRESS_NOTIFICATION_EVENT,
HCI_REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION_EVENT,
HCI_LE_META_EVENT,
]
)
)
)
if (
@@ -299,7 +440,44 @@ class Host(AbortableEventEmitter):
# understand
le_event_mask = bytes.fromhex('1F00000000000000')
else:
le_event_mask = bytes.fromhex('FFFFFFFF00000000')
le_event_mask = HCI_LE_Set_Event_Mask_Command.mask(
[
HCI_LE_CONNECTION_COMPLETE_EVENT,
HCI_LE_ADVERTISING_REPORT_EVENT,
HCI_LE_CONNECTION_UPDATE_COMPLETE_EVENT,
HCI_LE_READ_REMOTE_FEATURES_COMPLETE_EVENT,
HCI_LE_LONG_TERM_KEY_REQUEST_EVENT,
HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_EVENT,
HCI_LE_DATA_LENGTH_CHANGE_EVENT,
HCI_LE_READ_LOCAL_P_256_PUBLIC_KEY_COMPLETE_EVENT,
HCI_LE_GENERATE_DHKEY_COMPLETE_EVENT,
HCI_LE_ENHANCED_CONNECTION_COMPLETE_EVENT,
HCI_LE_DIRECTED_ADVERTISING_REPORT_EVENT,
HCI_LE_PHY_UPDATE_COMPLETE_EVENT,
HCI_LE_EXTENDED_ADVERTISING_REPORT_EVENT,
HCI_LE_PERIODIC_ADVERTISING_SYNC_ESTABLISHED_EVENT,
HCI_LE_PERIODIC_ADVERTISING_REPORT_EVENT,
HCI_LE_PERIODIC_ADVERTISING_SYNC_LOST_EVENT,
HCI_LE_SCAN_TIMEOUT_EVENT,
HCI_LE_ADVERTISING_SET_TERMINATED_EVENT,
HCI_LE_SCAN_REQUEST_RECEIVED_EVENT,
HCI_LE_CONNECTIONLESS_IQ_REPORT_EVENT,
HCI_LE_CONNECTION_IQ_REPORT_EVENT,
HCI_LE_CTE_REQUEST_FAILED_EVENT,
HCI_LE_PERIODIC_ADVERTISING_SYNC_TRANSFER_RECEIVED_EVENT,
HCI_LE_CIS_ESTABLISHED_EVENT,
HCI_LE_CIS_REQUEST_EVENT,
HCI_LE_CREATE_BIG_COMPLETE_EVENT,
HCI_LE_TERMINATE_BIG_COMPLETE_EVENT,
HCI_LE_BIG_SYNC_ESTABLISHED_EVENT,
HCI_LE_BIG_SYNC_LOST_EVENT,
HCI_LE_REQUEST_PEER_SCA_COMPLETE_EVENT,
HCI_LE_PATH_LOSS_THRESHOLD_EVENT,
HCI_LE_TRANSMIT_POWER_REPORTING_EVENT,
HCI_LE_BIGINFO_ADVERTISING_REPORT_EVENT,
HCI_LE_SUBRATE_CHANGE_EVENT,
]
)
await self.send_command(
HCI_LE_Set_Event_Mask_Command(le_event_mask=le_event_mask)
@@ -377,6 +555,25 @@ class Host(AbortableEventEmitter):
)
)
if self.supports_command(
HCI_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS_COMMAND
):
response = await self.send_command(
HCI_LE_Read_Number_Of_Supported_Advertising_Sets_Command(),
check_result=True,
)
self.number_of_supported_advertising_sets = (
response.return_parameters.num_supported_advertising_sets
)
if self.supports_command(HCI_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH_COMMAND):
response = await self.send_command(
HCI_LE_Read_Maximum_Advertising_Data_Length_Command(), check_result=True
)
self.maximum_advertising_data_length = (
response.return_parameters.max_advertising_data_length
)
@property
def controller(self) -> Optional[TransportSink]:
return self.hci_sink
@@ -791,6 +988,7 @@ class Host(AbortableEventEmitter):
event.status,
event.advertising_handle,
event.connection_handle,
event.num_completed_extended_advertising_events,
)
def on_hci_le_cis_request_event(self, event):

View File

@@ -226,13 +226,13 @@ class CompositeEventEmitter(AbortableEventEmitter):
if self._listener:
# Call the deregistration methods for each base class that has them
for cls in self._listener.__class__.mro():
if hasattr(cls, '_bumble_register_composite'):
cls._bumble_deregister_composite(listener, self)
if '_bumble_register_composite' in cls.__dict__:
cls._bumble_deregister_composite(self._listener, self)
self._listener = listener
if listener:
# Call the registration methods for each base class that has them
for cls in listener.__class__.mro():
if hasattr(cls, '_bumble_deregister_composite'):
if '_bumble_deregister_composite' in cls.__dict__:
cls._bumble_register_composite(listener, self)