Skip to content

Commit

Permalink
Add some HCI commands and events
Browse files Browse the repository at this point in the history
  • Loading branch information
zxzxwu committed Sep 12, 2024
1 parent 00e660d commit 9609ddf
Show file tree
Hide file tree
Showing 2 changed files with 297 additions and 7 deletions.
257 changes: 250 additions & 7 deletions bumble/hci.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,19 @@ def phy_list_to_bits(phys: Optional[Iterable[int]]) -> int:
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_LE_READ_ALL_REMOTE_FEATURES_COMPLETE_EVENT = 0x2A
HCI_LE_CIS_ESTABLISHED_V2_EVENT = 0x2B
HCI_LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES_COMPLETE_EVENT = 0x2C
HCI_LE_CS_READ_REMOTE_FAE_TABLE_COMPLETE_EVENT = 0x2D
HCI_LE_CS_SECURITY_ENABLE_COMPLETE_EVENT = 0x2E
HCI_LE_CS_CONFIG_COMPLETE_EVENT = 0x2F
HCI_LE_CS_PROCEDURE_ENABLE_EVENT = 0x30
HCI_LE_CS_SUBEVENT_RESULT_EVENT = 0x31
HCI_LE_CS_SUBEVENT_RESULT_CONTINUE_EVENT = 0x32
HCI_LE_CS_TEST_END_COMPLETE_EVENT = 0x33
HCI_LE_MONITORED_ADVERTISERS_REPORT_EVENT = 0x34
HCI_LE_FRAME_SPACE_UPDATE_EVENT = 0x35



# HCI Command
Expand Down Expand Up @@ -573,11 +586,36 @@ def phy_list_to_bits(phys: Optional[Iterable[int]]) -> int:
HCI_LE_SET_DEFAULT_SUBRATE_COMMAND = hci_command_op_code(0x08, 0x007D)
HCI_LE_SUBRATE_REQUEST_COMMAND = hci_command_op_code(0x08, 0x007E)
HCI_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_V2_COMMAND = hci_command_op_code(0x08, 0x007F)
HCI_LE_SET_DECISION_DATA_COMMAND = hci_command_op_code(0x08, 0x0080)
HCI_LE_SET_DECISION_INSTRUCTIONS_COMMAND = hci_command_op_code(0x08, 0x0081)
HCI_LE_SET_PERIODIC_ADVERTISING_SUBEVENT_DATA_COMMAND = hci_command_op_code(0x08, 0x0082)
HCI_LE_SET_PERIODIC_ADVERTISING_RESPONSE_DATA_COMMAND = hci_command_op_code(0x08, 0x0083)
HCI_LE_SET_PERIODIC_SYNC_SUBEVENT_COMMAND = hci_command_op_code(0x08, 0x0084)
HCI_LE_EXTENDED_CREATE_CONNECTION_V2_COMMAND = hci_command_op_code(0x08, 0x0085)
HCI_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_V2_COMMAND = hci_command_op_code(0x08, 0x0086)
HCI_LE_READ_ALL_LOCAL_SUPPORTED_FEATURES_COMMAND = hci_command_op_code(0x08, 0x0087)
HCI_LE_READ_ALL_REMOTE_FEATURES_COMMAND = hci_command_op_code(0x08, 0x0088)
HCI_LE_CS_READ_LOCAL_SUPPORTED_CAPABILITIES_COMMAND = hci_command_op_code(0x08, 0x0089)
HCI_LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES_COMMAND = hci_command_op_code(0x08, 0x008A)
HCI_LE_CS_WRITE_CACHED_REMOTE_SUPPORTED_CAPABILITIES = hci_command_op_code(0x08, 0x008B)
HCI_LE_CS_SECURITY_ENABLE_COMMAND = hci_command_op_code(0x08, 0x008C)
HCI_LE_CS_SET_DEFAULT_SETTINGS_COMMAND = hci_command_op_code(0x08, 0x008D)
HCI_LE_CS_READ_REMOTE_FAE_TABLE_COMMAND = hci_command_op_code(0x08, 0x008E)
HCI_LE_CS_WRITE_CACHED_REMOTE_FAE_TABLE_COMMAND = hci_command_op_code(0x08, 0x008F)
HCI_LE_CS_CREATE_CONFIG_COMMAND = hci_command_op_code(0x08, 0x0090)
HCI_LE_CS_REMOVE_CONFIG_COMMAND = hci_command_op_code(0x08, 0x0091)
HCI_LE_CS_SET_CHANNEL_CLASSIFICATION_COMMAND = hci_command_op_code(0x08, 0x0092)
HCI_LE_CS_SET_PROCEDURE_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0093)
HCI_LE_CS_PROCEDURE_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0094)
HCI_LE_CS_TEST_COMMAND = hci_command_op_code(0x08, 0x0095)
HCI_LE_CS_TEST_END_COMMAND = hci_command_op_code(0x08, 0x0096)
HCI_LE_SET_HOST_FEATURE_V2_COMMAND = hci_command_op_code(0x08, 0x0097)
HCI_LE_ADD_DEVICE_TO_MONITORED_ADVERTISERS_LIST_COMMAND = hci_command_op_code(0x08, 0x0098)
HCI_LE_REMOVE_DEVICE_FROM_MONITORED_ADVERTISERS_LIST_COMMAND = hci_command_op_code(0x08, 0x0099)
HCI_LE_CLEAR_MONITORED_ADVERTISERS_LIST_COMMAND = hci_command_op_code(0x08, 0x009A)
HCI_LE_READ_MONITORED_ADVERTISERS_LIST_SIZE_COMMAND = hci_command_op_code(0x08, 0x009B)
HCI_LE_ENABLE_MONITORING_ADVERTISERS_COMMAND = hci_command_op_code(0x08, 0x009C)
HCI_LE_FRAME_SPACE_UPDATE_COMMAND = hci_command_op_code(0x08, 0x009D)


# HCI Error Codes
Expand Down Expand Up @@ -1150,8 +1188,16 @@ class LeFeature(OpenIntEnum):
CHANNEL_CLASSIFICATION = 39
ADVERTISING_CODING_SELECTION = 40
ADVERTISING_CODING_SELECTION_HOST_SUPPORT = 41
DECISION_BASED_ADVERTISING_FILTERING = 42
PERIODIC_ADVERTISING_WITH_RESPONSES_ADVERTISER = 43
PERIODIC_ADVERTISING_WITH_RESPONSES_SCANNER = 44
UNSEGMENTED_FRAMED_MODE = 45
CHANNEL_SOUNDING = 46
CHANNEL_SOUNDING_HOST_SUPPORT = 47
CHANNEL_SOUNDING_TONE_QUALITY_INDICATION = 48
LL_EXTENDED_FEATURE_SET = 63
MONITORING_ADVERTISERS = 64
FRAME_SPACE_UPDATE = 65

class LeFeatureMask(enum.IntFlag):
LE_ENCRYPTION = 1 << LeFeature.LE_ENCRYPTION
Expand Down Expand Up @@ -1196,8 +1242,16 @@ class LeFeatureMask(enum.IntFlag):
CHANNEL_CLASSIFICATION = 1 << LeFeature.CHANNEL_CLASSIFICATION
ADVERTISING_CODING_SELECTION = 1 << LeFeature.ADVERTISING_CODING_SELECTION
ADVERTISING_CODING_SELECTION_HOST_SUPPORT = 1 << LeFeature.ADVERTISING_CODING_SELECTION_HOST_SUPPORT
DECISION_BASED_ADVERTISING_FILTERING = 1 << LeFeature.DECISION_BASED_ADVERTISING_FILTERING
PERIODIC_ADVERTISING_WITH_RESPONSES_ADVERTISER = 1 << LeFeature.PERIODIC_ADVERTISING_WITH_RESPONSES_ADVERTISER
PERIODIC_ADVERTISING_WITH_RESPONSES_SCANNER = 1 << LeFeature.PERIODIC_ADVERTISING_WITH_RESPONSES_SCANNER
UNSEGMENTED_FRAMED_MODE = 1 << LeFeature.UNSEGMENTED_FRAMED_MODE
CHANNEL_SOUNDING = 1 << LeFeature.CHANNEL_SOUNDING
CHANNEL_SOUNDING_HOST_SUPPORT = 1 << LeFeature.CHANNEL_SOUNDING_HOST_SUPPORT
CHANNEL_SOUNDING_TONE_QUALITY_INDICATION = 1 << LeFeature.CHANNEL_SOUNDING_TONE_QUALITY_INDICATION
LL_EXTENDED_FEATURE_SET = 1 << LeFeature.LL_EXTENDED_FEATURE_SET
MONITORING_ADVERTISERS = 1 << LeFeature.MONITORING_ADVERTISERS
FRAME_SPACE_UPDATE = 1 << LeFeature.FRAME_SPACE_UPDATE

class LmpFeature(enum.IntEnum):
# Page 0 (Legacy LMP features)
Expand Down Expand Up @@ -1565,12 +1619,16 @@ def dict_from_bytes(data, offset, fields):
# This is an array field, starting with a 1-byte item count.
item_count = data[offset]
offset += 1
# Set fields first, because item_count might be 0.
for sub_field_name, sub_field_type in field:
result.setdefault(sub_field_name, [])

for _ in range(item_count):
for sub_field_name, sub_field_type in field:
value, size = HCI_Object.parse_field(
data, offset, sub_field_type
)
result.setdefault(sub_field_name, []).append(value)
result[sub_field_name].append(value)
offset += size
continue

Expand Down Expand Up @@ -3022,7 +3080,12 @@ class HCI_Write_Voice_Setting_Command(HCI_Command):


# -----------------------------------------------------------------------------
@HCI_Command.command()
@HCI_Command.command(
return_parameters_fields=[
('status', STATUS_SPEC),
('synchronous_flow_control_enable', 1),
]
)
class HCI_Read_Synchronous_Flow_Control_Enable_Command(HCI_Command):
'''
See Bluetooth spec @ 7.3.36 Read Synchronous Flow Control Enable Command
Expand Down Expand Up @@ -3191,7 +3254,13 @@ class HCI_Set_Event_Mask_Page_2_Command(HCI_Command):


# -----------------------------------------------------------------------------
@HCI_Command.command()
@HCI_Command.command(
return_parameters_fields=[
('status', STATUS_SPEC),
('le_supported_host', 1),
('unused', 1),
]
)
class HCI_Read_LE_Host_Support_Command(HCI_Command):
'''
See Bluetooth spec @ 7.3.78 Read LE Host Support Command
Expand Down Expand Up @@ -3324,13 +3393,39 @@ class HCI_Read_BD_ADDR_Command(HCI_Command):


# -----------------------------------------------------------------------------
@HCI_Command.command()
@HCI_Command.command(
return_parameters_fields=[
("status", STATUS_SPEC),
[("standard_codec_ids", 1)],
[("vendor_specific_codec_ids", 4)],
]
)
class HCI_Read_Local_Supported_Codecs_Command(HCI_Command):
'''
See Bluetooth spec @ 7.4.8 Read Local Supported Codecs Command
'''


# -----------------------------------------------------------------------------
@HCI_Command.command(
return_parameters_fields=[
("status", STATUS_SPEC),
[("standard_codec_ids", 1), ("standard_codec_transports", 1)],
[("vendor_specific_codec_ids", 4), ("vendor_specific_codec_transports", 1)],
]
)
class HCI_Read_Local_Supported_Codecs_V2_Command(HCI_Command):
'''
See Bluetooth spec @ 7.4.8 Read Local Supported Codecs Command
'''

class Transport(OpenIntEnum):
BR_EDR_ACL = 0x00
BR_EDR_SCO = 0x01
LE_CIS = 0x02
LE_BIS = 0x03


# -----------------------------------------------------------------------------
@HCI_Command.command(
fields=[('handle', 2)],
Expand Down Expand Up @@ -3488,7 +3583,12 @@ def advertising_type_name(cls, advertising_type):


# -----------------------------------------------------------------------------
@HCI_Command.command()
@HCI_Command.command(
return_parameters_fields=[
('status', STATUS_SPEC),
('tx_power_level', 1),
]
)
class HCI_LE_Read_Advertising_Physical_Channel_Tx_Power_Command(HCI_Command):
'''
See Bluetooth spec @ 7.8.6 LE Read Advertising Physical Channel Tx Power Command
Expand Down Expand Up @@ -3612,7 +3712,12 @@ class HCI_LE_Create_Connection_Cancel_Command(HCI_Command):


# -----------------------------------------------------------------------------
@HCI_Command.command()
@HCI_Command.command(
return_parameters_fields=[
('status', STATUS_SPEC),
('filter_accept_list_size', 1),
]
)
class HCI_LE_Read_Filter_Accept_List_Size_Command(HCI_Command):
'''
See Bluetooth spec @ 7.8.14 LE Read Filter Accept List Size Command
Expand Down Expand Up @@ -3723,7 +3828,12 @@ class HCI_LE_Long_Term_Key_Request_Negative_Reply_Command(HCI_Command):


# -----------------------------------------------------------------------------
@HCI_Command.command()
@HCI_Command.command(
return_parameters_fields=[
('status', STATUS_SPEC),
('le_states', 8),
]
)
class HCI_LE_Read_Supported_States_Command(HCI_Command):
'''
See Bluetooth spec @ 7.8.27 LE Read Supported States Command
Expand Down Expand Up @@ -4698,6 +4808,102 @@ class HCI_LE_Reject_CIS_Request_Command(HCI_Command):
reason: int


# -----------------------------------------------------------------------------
@HCI_Command.command(
fields=[
('big_handle', 1),
('advertising_handle', 1),
('num_bis', 1),
('sdu_interval', 3),
('max_sdu', 2),
('max_transport_latency', 2),
('rtn', 1),
('phy', 1),
('packing', 1),
('framing', 1),
('encryption', 1),
('broadcast_code', 16),
],
)
class HCI_LE_Create_BIG_Command(HCI_Command):
'''
See Bluetooth spec @ 7.8.103 LE Create BIG command
'''

big_handle: int
advertising_handle: int
num_bis: int
sdu_interval: int
max_sdu: int
max_transport_latency: int
rtn: int
phy: int
packing: int
framing: int
encryption: int
broadcast_code: int


# -----------------------------------------------------------------------------
@HCI_Command.command(
fields=[
('big_handle', 1),
('reason', {'size': 1, 'mapper': HCI_Constant.error_name}),
],
)
class HCI_LE_Terminate_BIG_Command(HCI_Command):
'''
See Bluetooth spec @ 7.8.105 LE Terminate BIG command
'''

big_handle: int
reason: int


# -----------------------------------------------------------------------------
@HCI_Command.command(
fields=[
('big_handle', 1),
('sync_handle', 2),
('encryption', 1),
('broadcast_code', 16),
('mse', 1),
('big_sync_timeout', 2),
[('bis', 1)],
],
)
class HCI_LE_BIG_Create_Sync_Command(HCI_Command):
'''
See Bluetooth spec @ 7.8.106 LE BIG Create Sync command
'''

big_handle: int
sync_handle: int
encryption: int
broadcast_code: int
mse: int
big_sync_timeout: int
bis: List[int]


# -----------------------------------------------------------------------------
@HCI_Command.command(
fields=[
('big_handle', 1),
],
return_parameters_fields=[
('status', STATUS_SPEC),
('big_handle', 2),
],
)
class HCI_LE_BIG_Terminate_Sync_Command(HCI_Command):
'''
See Bluetooth spec @ 7.8.107. LE BIG Terminate Sync command
'''

big_handle: int


# -----------------------------------------------------------------------------
@HCI_Command.command(
fields=[
Expand Down Expand Up @@ -5533,6 +5739,26 @@ class HCI_LE_Channel_Selection_Algorithm_Event(HCI_LE_Meta_Event):
'''


# -----------------------------------------------------------------------------
@HCI_LE_Meta_Event.event(
[
('connection_handle', 2),
('service_data', 2),
('sync_handle', 2),
('advertising_sid', 1),
('advertiser_address_type', Address.ADDRESS_TYPE_SPEC),
('advertiser_address', Address.parse_address_preceded_by_type),
('advertiser_phy', 1),
('periodic_advertising_interval', 2),
('advertiser_clock_accuracy', 1),
]
)
class HCI_LE_Periodic_Advertising_Sync_Transfer_Received_Event(HCI_LE_Meta_Event):
'''
See Bluetooth spec @ 7.7.65.24 LE Periodic Advertising Sync Transfer Received Event
'''


# -----------------------------------------------------------------------------
@HCI_LE_Meta_Event.event(
[
Expand Down Expand Up @@ -6225,6 +6451,23 @@ class HCI_Synchronous_Connection_Changed_Event(HCI_Event):
'''


# -----------------------------------------------------------------------------
@HCI_Event.event(
[
('status', STATUS_SPEC),
('connection_handle', 2),
('max_tx_latency', 2),
('max_rx_latency', 2),
('min_remote_timeout', 2),
('min_local_timeout', 2),
]
)
class HCI_Sniff_Subrating_Event(HCI_Event):
'''
See Bluetooth spec @ 7.7.37 Sniff Subrating Event
'''


# -----------------------------------------------------------------------------
@HCI_Event.event(
[
Expand Down
Loading

0 comments on commit 9609ddf

Please sign in to comment.