aboutsummaryrefslogtreecommitdiff
path: root/bumble/hci.py
diff options
context:
space:
mode:
Diffstat (limited to 'bumble/hci.py')
-rw-r--r--bumble/hci.py2046
1 files changed, 1302 insertions, 744 deletions
diff --git a/bumble/hci.py b/bumble/hci.py
index 057c04a..013a2d3 100644
--- a/bumble/hci.py
+++ b/bumble/hci.py
@@ -17,11 +17,15 @@
# -----------------------------------------------------------------------------
from __future__ import annotations
import collections
+import dataclasses
+import enum
import functools
import logging
+import secrets
import struct
-from typing import Any, Dict, Callable, Optional, Type, Union
+from typing import Any, Callable, Dict, Iterable, List, Optional, Type, Union
+from bumble import crypto
from .colors import color
from .core import (
BT_BR_EDR_TRANSPORT,
@@ -148,6 +152,7 @@ HCI_COMMAND_PACKET = 0x01
HCI_ACL_DATA_PACKET = 0x02
HCI_SYNCHRONOUS_DATA_PACKET = 0x03
HCI_EVENT_PACKET = 0x04
+HCI_ISO_DATA_PACKET = 0x05
# HCI Event Codes
HCI_INQUIRY_COMPLETE_EVENT = 0x01
@@ -218,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
@@ -558,6 +569,12 @@ HCI_LE_TRANSMITTER_TEST_V4_COMMAND = hci_c
HCI_LE_SET_DATA_RELATED_ADDRESS_CHANGES_COMMAND = hci_command_op_code(0x08, 0x007C)
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_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 Error Codes
@@ -639,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
@@ -719,6 +695,19 @@ HCI_LE_PHY_TYPE_TO_BIT = {
HCI_LE_CODED_PHY: HCI_LE_CODED_PHY_BIT
}
+
+class Phy(enum.IntEnum):
+ LE_1M = HCI_LE_1M_PHY
+ LE_2M = HCI_LE_2M_PHY
+ LE_CODED = HCI_LE_CODED_PHY
+
+
+class PhyBit(enum.IntFlag):
+ 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
HCI_CONNECTION_INTERVAL_MS_PER_UNIT = 1.25
HCI_CONNECTION_LATENCY_MS_PER_UNIT = 1.25
@@ -801,574 +790,586 @@ HCI_RANDOM_DEVICE_ADDRESS_TYPE = 0x01
HCI_PUBLIC_IDENTITY_ADDRESS_TYPE = 0x02
HCI_RANDOM_IDENTITY_ADDRESS_TYPE = 0x03
-# Supported Commands Flags
+# Supported Commands Masks
# See Bluetooth spec @ 6.27 SUPPORTED COMMANDS
-HCI_SUPPORTED_COMMANDS_FLAGS = (
- # Octet 0
- (
- HCI_INQUIRY_COMMAND,
- HCI_INQUIRY_CANCEL_COMMAND,
- HCI_PERIODIC_INQUIRY_MODE_COMMAND,
- HCI_EXIT_PERIODIC_INQUIRY_MODE_COMMAND,
- HCI_CREATE_CONNECTION_COMMAND,
- HCI_DISCONNECT_COMMAND,
- None,
- HCI_CREATE_CONNECTION_CANCEL_COMMAND
- ),
- # Octet 1
- (
- HCI_ACCEPT_CONNECTION_REQUEST_COMMAND,
- HCI_REJECT_CONNECTION_REQUEST_COMMAND,
- HCI_LINK_KEY_REQUEST_REPLY_COMMAND,
- HCI_LINK_KEY_REQUEST_NEGATIVE_REPLY_COMMAND,
- HCI_PIN_CODE_REQUEST_REPLY_COMMAND,
- HCI_PIN_CODE_REQUEST_NEGATIVE_REPLY_COMMAND,
- HCI_CHANGE_CONNECTION_PACKET_TYPE_COMMAND,
- HCI_AUTHENTICATION_REQUESTED_COMMAND
- ),
- # Octet 2
- (
- HCI_SET_CONNECTION_ENCRYPTION_COMMAND,
- HCI_CHANGE_CONNECTION_LINK_KEY_COMMAND,
- HCI_LINK_KEY_SELECTION_COMMAND,
- HCI_REMOTE_NAME_REQUEST_COMMAND,
- HCI_REMOTE_NAME_REQUEST_CANCEL_COMMAND,
- HCI_READ_REMOTE_SUPPORTED_FEATURES_COMMAND,
- HCI_READ_REMOTE_EXTENDED_FEATURES_COMMAND,
- HCI_READ_REMOTE_VERSION_INFORMATION_COMMAND
- ),
- # Octet 3
- (
- HCI_READ_CLOCK_OFFSET_COMMAND,
- HCI_READ_LMP_HANDLE_COMMAND,
- None,
- None,
- None,
- None,
- None,
- None
- ),
- # Octet 4
- (
- None,
- HCI_HOLD_MODE_COMMAND,
- HCI_SNIFF_MODE_COMMAND,
- HCI_EXIT_SNIFF_MODE_COMMAND,
- None,
- None,
- HCI_QOS_SETUP_COMMAND,
- HCI_ROLE_DISCOVERY_COMMAND
- ),
- # Octet 5
- (
- HCI_SWITCH_ROLE_COMMAND,
- HCI_READ_LINK_POLICY_SETTINGS_COMMAND,
- HCI_WRITE_LINK_POLICY_SETTINGS_COMMAND,
- HCI_READ_DEFAULT_LINK_POLICY_SETTINGS_COMMAND,
- HCI_WRITE_DEFAULT_LINK_POLICY_SETTINGS_COMMAND,
- HCI_FLOW_SPECIFICATION_COMMAND,
- HCI_SET_EVENT_MASK_COMMAND,
- HCI_RESET_COMMAND
- ),
- # Octet 6
- (
- HCI_SET_EVENT_FILTER_COMMAND,
- HCI_FLUSH_COMMAND,
- HCI_READ_PIN_TYPE_COMMAND,
- HCI_WRITE_PIN_TYPE_COMMAND,
- None,
- HCI_READ_STORED_LINK_KEY_COMMAND,
- HCI_WRITE_STORED_LINK_KEY_COMMAND,
- HCI_DELETE_STORED_LINK_KEY_COMMAND
- ),
- # Octet 7
- (
- HCI_WRITE_LOCAL_NAME_COMMAND,
- HCI_READ_LOCAL_NAME_COMMAND,
- HCI_READ_CONNECTION_ACCEPT_TIMEOUT_COMMAND,
- HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT_COMMAND,
- HCI_READ_PAGE_TIMEOUT_COMMAND,
- HCI_WRITE_PAGE_TIMEOUT_COMMAND,
- HCI_READ_SCAN_ENABLE_COMMAND,
- HCI_WRITE_SCAN_ENABLE_COMMAND
- ),
- # Octet 8
- (
- HCI_READ_PAGE_SCAN_ACTIVITY_COMMAND,
- HCI_WRITE_PAGE_SCAN_ACTIVITY_COMMAND,
- HCI_READ_INQUIRY_SCAN_ACTIVITY_COMMAND,
- HCI_WRITE_INQUIRY_SCAN_ACTIVITY_COMMAND,
- HCI_READ_AUTHENTICATION_ENABLE_COMMAND,
- HCI_WRITE_AUTHENTICATION_ENABLE_COMMAND,
- None,
- None
- ),
- # Octet 9
- (
- HCI_READ_CLASS_OF_DEVICE_COMMAND,
- HCI_WRITE_CLASS_OF_DEVICE_COMMAND,
- HCI_READ_VOICE_SETTING_COMMAND,
- HCI_WRITE_VOICE_SETTING_COMMAND,
- HCI_READ_AUTOMATIC_FLUSH_TIMEOUT_COMMAND,
- HCI_WRITE_AUTOMATIC_FLUSH_TIMEOUT_COMMAND,
- HCI_READ_NUM_BROADCAST_RETRANSMISSIONS_COMMAND,
- HCI_WRITE_NUM_BROADCAST_RETRANSMISSIONS_COMMAND
- ),
- # Octet 10
- (
- HCI_READ_HOLD_MODE_ACTIVITY_COMMAND,
- HCI_WRITE_HOLD_MODE_ACTIVITY_COMMAND,
- HCI_READ_TRANSMIT_POWER_LEVEL_COMMAND,
- HCI_READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE_COMMAND,
- HCI_WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE_COMMAND,
- HCI_SET_CONTROLLER_TO_HOST_FLOW_CONTROL_COMMAND,
- HCI_HOST_BUFFER_SIZE_COMMAND,
- HCI_HOST_NUMBER_OF_COMPLETED_PACKETS_COMMAND
- ),
- # Octet 11
- (
- HCI_READ_LINK_SUPERVISION_TIMEOUT_COMMAND,
- HCI_WRITE_LINK_SUPERVISION_TIMEOUT_COMMAND,
- HCI_READ_NUMBER_OF_SUPPORTED_IAC_COMMAND,
- HCI_READ_CURRENT_IAC_LAP_COMMAND,
- HCI_WRITE_CURRENT_IAC_LAP_COMMAND,
- None,
- None,
- None
- ),
- # Octet 12
- (
- None,
- HCI_SET_AFH_HOST_CHANNEL_CLASSIFICATION_COMMAND,
- None,
- None,
- HCI_READ_INQUIRY_SCAN_TYPE_COMMAND,
- HCI_WRITE_INQUIRY_SCAN_TYPE_COMMAND,
- HCI_READ_INQUIRY_MODE_COMMAND,
- HCI_WRITE_INQUIRY_MODE_COMMAND
- ),
- # Octet 13
- (
- HCI_READ_PAGE_SCAN_TYPE_COMMAND,
- HCI_WRITE_PAGE_SCAN_TYPE_COMMAND,
- HCI_READ_AFH_CHANNEL_ASSESSMENT_MODE_COMMAND,
- HCI_WRITE_AFH_CHANNEL_ASSESSMENT_MODE_COMMAND,
- None,
- None,
- None,
- None,
- ),
- # Octet 14
- (
- None,
- None,
- None,
- HCI_READ_LOCAL_VERSION_INFORMATION_COMMAND,
- None,
- HCI_READ_LOCAL_SUPPORTED_FEATURES_COMMAND,
- HCI_READ_LOCAL_EXTENDED_FEATURES_COMMAND,
- HCI_READ_BUFFER_SIZE_COMMAND
- ),
- # Octet 15
- (
- None,
- HCI_READ_BD_ADDR_COMMAND,
- HCI_READ_FAILED_CONTACT_COUNTER_COMMAND,
- HCI_RESET_FAILED_CONTACT_COUNTER_COMMAND,
- HCI_READ_LINK_QUALITY_COMMAND,
- HCI_READ_RSSI_COMMAND,
- HCI_READ_AFH_CHANNEL_MAP_COMMAND,
- HCI_READ_CLOCK_COMMAND
- ),
- # Octet 16
- (
- HCI_READ_LOOPBACK_MODE_COMMAND,
- HCI_WRITE_LOOPBACK_MODE_COMMAND,
- HCI_ENABLE_DEVICE_UNDER_TEST_MODE_COMMAND,
- HCI_SETUP_SYNCHRONOUS_CONNECTION_COMMAND,
- HCI_ACCEPT_SYNCHRONOUS_CONNECTION_REQUEST_COMMAND,
- HCI_REJECT_SYNCHRONOUS_CONNECTION_REQUEST_COMMAND,
- None,
- None,
- ),
- # Octet 17
- (
- HCI_READ_EXTENDED_INQUIRY_RESPONSE_COMMAND,
- HCI_WRITE_EXTENDED_INQUIRY_RESPONSE_COMMAND,
- HCI_REFRESH_ENCRYPTION_KEY_COMMAND,
- None,
- HCI_SNIFF_SUBRATING_COMMAND,
- HCI_READ_SIMPLE_PAIRING_MODE_COMMAND,
- HCI_WRITE_SIMPLE_PAIRING_MODE_COMMAND,
- HCI_READ_LOCAL_OOB_DATA_COMMAND
- ),
- # Octet 18
- (
- HCI_READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL_COMMAND,
- HCI_WRITE_INQUIRY_TRANSMIT_POWER_LEVEL_COMMAND,
- HCI_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_COMMAND,
- HCI_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_COMMAND,
- None,
- None,
- None,
- HCI_IO_CAPABILITY_REQUEST_REPLY_COMMAND
- ),
- # Octet 19
- (
- HCI_USER_CONFIRMATION_REQUEST_REPLY_COMMAND,
- HCI_USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY_COMMAND,
- HCI_USER_PASSKEY_REQUEST_REPLY_COMMAND,
- HCI_USER_PASSKEY_REQUEST_NEGATIVE_REPLY_COMMAND,
- HCI_REMOTE_OOB_DATA_REQUEST_REPLY_COMMAND,
- HCI_WRITE_SIMPLE_PAIRING_DEBUG_MODE_COMMAND,
- HCI_ENHANCED_FLUSH_COMMAND,
- HCI_REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY_COMMAND
- ),
- # Octet 20
- (
- None,
- None,
- HCI_SEND_KEYPRESS_NOTIFICATION_COMMAND,
- HCI_IO_CAPABILITY_REQUEST_NEGATIVE_REPLY_COMMAND,
- HCI_READ_ENCRYPTION_KEY_SIZE_COMMAND,
- None,
- None,
- None,
- ),
- # Octet 21
- (
- None,
- None,
- None,
- None,
- None,
- None,
- None,
- None,
- ),
- # Octet 22
- (
- None,
- None,
- HCI_SET_EVENT_MASK_PAGE_2_COMMAND,
- None,
- None,
- None,
- None,
- None,
- ),
- # Octet 23
- (
- HCI_READ_FLOW_CONTROL_MODE_COMMAND,
- HCI_WRITE_FLOW_CONTROL_MODE_COMMAND,
- HCI_READ_DATA_BLOCK_SIZE_COMMAND,
- None,
- None,
- None,
- None,
- None,
- ),
- # Octet 24
- (
- HCI_READ_ENHANCED_TRANSMIT_POWER_LEVEL_COMMAND,
- None,
- None,
- None,
- None,
- HCI_READ_LE_HOST_SUPPORT_COMMAND,
- HCI_WRITE_LE_HOST_SUPPORT_COMMAND,
- None,
- ),
- # Octet 25
- (
- HCI_LE_SET_EVENT_MASK_COMMAND,
- HCI_LE_READ_BUFFER_SIZE_COMMAND,
- HCI_LE_READ_LOCAL_SUPPORTED_FEATURES_COMMAND,
- None,
- HCI_LE_SET_RANDOM_ADDRESS_COMMAND,
- HCI_LE_SET_ADVERTISING_PARAMETERS_COMMAND,
- HCI_LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER_COMMAND,
- HCI_LE_SET_ADVERTISING_DATA_COMMAND,
- ),
- # Octet 26
- (
- HCI_LE_SET_SCAN_RESPONSE_DATA_COMMAND,
- HCI_LE_SET_ADVERTISING_ENABLE_COMMAND,
- HCI_LE_SET_SCAN_PARAMETERS_COMMAND,
- HCI_LE_SET_SCAN_ENABLE_COMMAND,
- HCI_LE_CREATE_CONNECTION_COMMAND,
- HCI_LE_CREATE_CONNECTION_CANCEL_COMMAND,
- HCI_LE_READ_FILTER_ACCEPT_LIST_SIZE_COMMAND,
- HCI_LE_CLEAR_FILTER_ACCEPT_LIST_COMMAND
- ),
- # Octet 27
- (
- HCI_LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST_COMMAND,
- HCI_LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST_COMMAND,
- HCI_LE_CONNECTION_UPDATE_COMMAND,
- HCI_LE_SET_HOST_CHANNEL_CLASSIFICATION_COMMAND,
- HCI_LE_READ_CHANNEL_MAP_COMMAND,
- HCI_LE_READ_REMOTE_FEATURES_COMMAND,
- HCI_LE_ENCRYPT_COMMAND,
- HCI_LE_RAND_COMMAND
- ),
- # Octet 28
- (
- HCI_LE_ENABLE_ENCRYPTION_COMMAND,
- HCI_LE_LONG_TERM_KEY_REQUEST_REPLY_COMMAND,
- HCI_LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY_COMMAND,
- HCI_LE_READ_SUPPORTED_STATES_COMMAND,
- HCI_LE_RECEIVER_TEST_COMMAND,
- HCI_LE_TRANSMITTER_TEST_COMMAND,
- HCI_LE_TEST_END_COMMAND,
- None,
- ),
- # Octet 29
- (
- None,
- None,
- None,
- HCI_ENHANCED_SETUP_SYNCHRONOUS_CONNECTION_COMMAND,
- HCI_ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION_REQUEST_COMMAND,
- HCI_READ_LOCAL_SUPPORTED_CODECS_COMMAND,
- HCI_SET_MWS_CHANNEL_PARAMETERS_COMMAND,
- HCI_SET_EXTERNAL_FRAME_CONFIGURATION_COMMAND
- ),
- # Octet 30
- (
- HCI_SET_MWS_SIGNALING_COMMAND,
- HCI_SET_MWS_TRANSPORT_LAYER_COMMAND,
- HCI_SET_MWS_SCAN_FREQUENCY_TABLE_COMMAND,
- HCI_GET_MWS_TRANSPORT_LAYER_CONFIGURATION_COMMAND,
- HCI_SET_MWS_PATTERN_CONFIGURATION_COMMAND,
- HCI_SET_TRIGGERED_CLOCK_CAPTURE_COMMAND,
- HCI_TRUNCATED_PAGE_COMMAND,
- HCI_TRUNCATED_PAGE_CANCEL_COMMAND
- ),
- # Octet 31
- (
- HCI_SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_COMMAND,
- HCI_SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVE_COMMAND,
- HCI_START_SYNCHRONIZATION_TRAIN_COMMAND,
- HCI_RECEIVE_SYNCHRONIZATION_TRAIN_COMMAND,
- HCI_SET_RESERVED_LT_ADDR_COMMAND,
- HCI_DELETE_RESERVED_LT_ADDR_COMMAND,
- HCI_SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_DATA_COMMAND,
- HCI_READ_SYNCHRONIZATION_TRAIN_PARAMETERS_COMMAND
- ),
- # Octet 32
- (
- HCI_WRITE_SYNCHRONIZATION_TRAIN_PARAMETERS_COMMAND,
- HCI_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_COMMAND,
- HCI_READ_SECURE_CONNECTIONS_HOST_SUPPORT_COMMAND,
- HCI_WRITE_SECURE_CONNECTIONS_HOST_SUPPORT_COMMAND,
- HCI_READ_AUTHENTICATED_PAYLOAD_TIMEOUT_COMMAND,
- HCI_WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT_COMMAND,
- HCI_READ_LOCAL_OOB_EXTENDED_DATA_COMMAND,
- HCI_WRITE_SECURE_CONNECTIONS_TEST_MODE_COMMAND
- ),
- # Octet 33
- (
- HCI_READ_EXTENDED_PAGE_TIMEOUT_COMMAND,
- HCI_WRITE_EXTENDED_PAGE_TIMEOUT_COMMAND,
- HCI_READ_EXTENDED_INQUIRY_LENGTH_COMMAND,
- HCI_WRITE_EXTENDED_INQUIRY_LENGTH_COMMAND,
- HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY_COMMAND,
- HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY_COMMAND,
- HCI_LE_SET_DATA_LENGTH_COMMAND,
- HCI_LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH_COMMAND
- ),
- # Octet 34
- (
- HCI_LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH_COMMAND,
- HCI_LE_READ_LOCAL_P_256_PUBLIC_KEY_COMMAND,
- HCI_LE_GENERATE_DHKEY_COMMAND,
- HCI_LE_ADD_DEVICE_TO_RESOLVING_LIST_COMMAND,
- HCI_LE_REMOVE_DEVICE_FROM_RESOLVING_LIST_COMMAND,
- HCI_LE_CLEAR_RESOLVING_LIST_COMMAND,
- HCI_LE_READ_RESOLVING_LIST_SIZE_COMMAND,
- HCI_LE_READ_PEER_RESOLVABLE_ADDRESS_COMMAND
- ),
- # Octet 35
- (
- HCI_LE_READ_LOCAL_RESOLVABLE_ADDRESS_COMMAND,
- HCI_LE_SET_ADDRESS_RESOLUTION_ENABLE_COMMAND,
- HCI_LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT_COMMAND,
- HCI_LE_READ_MAXIMUM_DATA_LENGTH_COMMAND,
- HCI_LE_READ_PHY_COMMAND,
- HCI_LE_SET_DEFAULT_PHY_COMMAND,
- HCI_LE_SET_PHY_COMMAND,
- HCI_LE_RECEIVER_TEST_V2_COMMAND
- ),
- # Octet 36
- (
- HCI_LE_TRANSMITTER_TEST_V2_COMMAND,
- HCI_LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_COMMAND,
- HCI_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_COMMAND,
- HCI_LE_SET_EXTENDED_ADVERTISING_DATA_COMMAND,
- HCI_LE_SET_EXTENDED_SCAN_RESPONSE_DATA_COMMAND,
- HCI_LE_SET_EXTENDED_ADVERTISING_ENABLE_COMMAND,
- HCI_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH_COMMAND,
- HCI_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS_COMMAND,
- ),
- # Octet 37
- (
- HCI_LE_REMOVE_ADVERTISING_SET_COMMAND,
- HCI_LE_CLEAR_ADVERTISING_SETS_COMMAND,
- HCI_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_COMMAND,
- HCI_LE_SET_PERIODIC_ADVERTISING_DATA_COMMAND,
- HCI_LE_SET_PERIODIC_ADVERTISING_ENABLE_COMMAND,
- HCI_LE_SET_EXTENDED_SCAN_PARAMETERS_COMMAND,
- HCI_LE_SET_EXTENDED_SCAN_ENABLE_COMMAND,
- HCI_LE_EXTENDED_CREATE_CONNECTION_COMMAND
- ),
- # Octet 38
- (
- HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC_COMMAND,
- HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL_COMMAND,
- HCI_LE_PERIODIC_ADVERTISING_TERMINATE_SYNC_COMMAND,
- HCI_LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST_COMMAND,
- HCI_LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST_COMMAND,
- HCI_LE_CLEAR_PERIODIC_ADVERTISER_LIST_COMMAND,
- HCI_LE_READ_PERIODIC_ADVERTISER_LIST_SIZE_COMMAND,
- HCI_LE_READ_TRANSMIT_POWER_COMMAND
- ),
- # Octet 39
- (
- HCI_LE_READ_RF_PATH_COMPENSATION_COMMAND,
- HCI_LE_WRITE_RF_PATH_COMPENSATION_COMMAND,
- HCI_LE_SET_PRIVACY_MODE_COMMAND,
- HCI_LE_RECEIVER_TEST_V3_COMMAND,
- HCI_LE_TRANSMITTER_TEST_V3_COMMAND,
- HCI_LE_SET_CONNECTIONLESS_CTE_TRANSMIT_PARAMETERS_COMMAND,
- HCI_LE_SET_CONNECTIONLESS_CTE_TRANSMIT_ENABLE_COMMAND,
- HCI_LE_SET_CONNECTIONLESS_IQ_SAMPLING_ENABLE_COMMAND,
- ),
- # Octet 40
- (
- HCI_LE_SET_CONNECTION_CTE_RECEIVE_PARAMETERS_COMMAND,
- HCI_LE_SET_CONNECTION_CTE_TRANSMIT_PARAMETERS_COMMAND,
- HCI_LE_CONNECTION_CTE_REQUEST_ENABLE_COMMAND,
- HCI_LE_CONNECTION_CTE_RESPONSE_ENABLE_COMMAND,
- HCI_LE_READ_ANTENNA_INFORMATION_COMMAND,
- HCI_LE_SET_PERIODIC_ADVERTISING_RECEIVE_ENABLE_COMMAND,
- HCI_LE_PERIODIC_ADVERTISING_SYNC_TRANSFER_COMMAND,
- HCI_LE_PERIODIC_ADVERTISING_SET_INFO_TRANSFER_COMMAND
- ),
- # Octet 41
- (
- HCI_LE_SET_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS_COMMAND,
- HCI_LE_SET_DEFAULT_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS_COMMAND,
- HCI_LE_GENERATE_DHKEY_V2_COMMAND,
- HCI_READ_LOCAL_SIMPLE_PAIRING_OPTIONS_COMMAND,
- HCI_LE_MODIFY_SLEEP_CLOCK_ACCURACY_COMMAND,
- HCI_LE_READ_BUFFER_SIZE_V2_COMMAND,
- HCI_LE_READ_ISO_TX_SYNC_COMMAND,
- HCI_LE_SET_CIG_PARAMETERS_COMMAND
- ),
- # Octet 42
- (
- HCI_LE_SET_CIG_PARAMETERS_TEST_COMMAND,
- HCI_LE_CREATE_CIS_COMMAND,
- HCI_LE_REMOVE_CIG_COMMAND,
- HCI_LE_ACCEPT_CIS_REQUEST_COMMAND,
- HCI_LE_REJECT_CIS_REQUEST_COMMAND,
- HCI_LE_CREATE_BIG_COMMAND,
- HCI_LE_CREATE_BIG_TEST_COMMAND,
- HCI_LE_TERMINATE_BIG_COMMAND,
- ),
- # Octet 43
- (
- HCI_LE_BIG_CREATE_SYNC_COMMAND,
- HCI_LE_BIG_TERMINATE_SYNC_COMMAND,
- HCI_LE_REQUEST_PEER_SCA_COMMAND,
- HCI_LE_SETUP_ISO_DATA_PATH_COMMAND,
- HCI_LE_REMOVE_ISO_DATA_PATH_COMMAND,
- HCI_LE_ISO_TRANSMIT_TEST_COMMAND,
- HCI_LE_ISO_RECEIVE_TEST_COMMAND,
- HCI_LE_ISO_READ_TEST_COUNTERS_COMMAND
- ),
- # Octet 44
- (
- HCI_LE_ISO_TEST_END_COMMAND,
- HCI_LE_SET_HOST_FEATURE_COMMAND,
- HCI_LE_READ_ISO_LINK_QUALITY_COMMAND,
- HCI_LE_ENHANCED_READ_TRANSMIT_POWER_LEVEL_COMMAND,
- HCI_LE_READ_REMOTE_TRANSMIT_POWER_LEVEL_COMMAND,
- HCI_LE_SET_PATH_LOSS_REPORTING_PARAMETERS_COMMAND,
- HCI_LE_SET_PATH_LOSS_REPORTING_ENABLE_COMMAND,
- HCI_LE_SET_TRANSMIT_POWER_REPORTING_ENABLE_COMMAND
- ),
- # Octet 45
- (
- HCI_LE_TRANSMITTER_TEST_V4_COMMAND,
- HCI_SET_ECOSYSTEM_BASE_INTERVAL_COMMAND,
- HCI_READ_LOCAL_SUPPORTED_CODECS_V2_COMMAND,
- HCI_READ_LOCAL_SUPPORTED_CODEC_CAPABILITIES_COMMAND,
- HCI_READ_LOCAL_SUPPORTED_CONTROLLER_DELAY_COMMAND,
- HCI_CONFIGURE_DATA_PATH_COMMAND,
- HCI_LE_SET_DATA_RELATED_ADDRESS_CHANGES_COMMAND,
- HCI_SET_MIN_ENCRYPTION_KEY_SIZE_COMMAND
- ),
- # Octet 46
- (
- HCI_LE_SET_DEFAULT_SUBRATE_COMMAND,
- HCI_LE_SUBRATE_REQUEST_COMMAND,
- None,
- None,
- None,
- None,
- None,
- None
- )
-)
+HCI_SUPPORTED_COMMANDS_MASKS = {
+ HCI_INQUIRY_COMMAND : 1 << (0*8+0),
+ HCI_INQUIRY_CANCEL_COMMAND : 1 << (0*8+1),
+ HCI_PERIODIC_INQUIRY_MODE_COMMAND : 1 << (0*8+2),
+ HCI_EXIT_PERIODIC_INQUIRY_MODE_COMMAND : 1 << (0*8+3),
+ HCI_CREATE_CONNECTION_COMMAND : 1 << (0*8+4),
+ HCI_DISCONNECT_COMMAND : 1 << (0*8+5),
+ HCI_CREATE_CONNECTION_CANCEL_COMMAND : 1 << (0*8+7),
+ HCI_ACCEPT_CONNECTION_REQUEST_COMMAND : 1 << (1*8+0),
+ HCI_REJECT_CONNECTION_REQUEST_COMMAND : 1 << (1*8+1),
+ HCI_LINK_KEY_REQUEST_REPLY_COMMAND : 1 << (1*8+2),
+ HCI_LINK_KEY_REQUEST_NEGATIVE_REPLY_COMMAND : 1 << (1*8+3),
+ HCI_PIN_CODE_REQUEST_REPLY_COMMAND : 1 << (1*8+4),
+ HCI_PIN_CODE_REQUEST_NEGATIVE_REPLY_COMMAND : 1 << (1*8+5),
+ HCI_CHANGE_CONNECTION_PACKET_TYPE_COMMAND : 1 << (1*8+6),
+ HCI_AUTHENTICATION_REQUESTED_COMMAND : 1 << (1*8+7),
+ HCI_SET_CONNECTION_ENCRYPTION_COMMAND : 1 << (2*8+0),
+ HCI_CHANGE_CONNECTION_LINK_KEY_COMMAND : 1 << (2*8+1),
+ HCI_LINK_KEY_SELECTION_COMMAND : 1 << (2*8+2),
+ HCI_REMOTE_NAME_REQUEST_COMMAND : 1 << (2*8+3),
+ HCI_REMOTE_NAME_REQUEST_CANCEL_COMMAND : 1 << (2*8+4),
+ HCI_READ_REMOTE_SUPPORTED_FEATURES_COMMAND : 1 << (2*8+5),
+ HCI_READ_REMOTE_EXTENDED_FEATURES_COMMAND : 1 << (2*8+6),
+ HCI_READ_REMOTE_VERSION_INFORMATION_COMMAND : 1 << (2*8+7),
+ HCI_READ_CLOCK_OFFSET_COMMAND : 1 << (3*8+0),
+ HCI_READ_LMP_HANDLE_COMMAND : 1 << (3*8+1),
+ HCI_HOLD_MODE_COMMAND : 1 << (4*8+1),
+ HCI_SNIFF_MODE_COMMAND : 1 << (4*8+2),
+ HCI_EXIT_SNIFF_MODE_COMMAND : 1 << (4*8+3),
+ HCI_QOS_SETUP_COMMAND : 1 << (4*8+6),
+ HCI_ROLE_DISCOVERY_COMMAND : 1 << (4*8+7),
+ HCI_SWITCH_ROLE_COMMAND : 1 << (5*8+0),
+ HCI_READ_LINK_POLICY_SETTINGS_COMMAND : 1 << (5*8+1),
+ HCI_WRITE_LINK_POLICY_SETTINGS_COMMAND : 1 << (5*8+2),
+ HCI_READ_DEFAULT_LINK_POLICY_SETTINGS_COMMAND : 1 << (5*8+3),
+ HCI_WRITE_DEFAULT_LINK_POLICY_SETTINGS_COMMAND : 1 << (5*8+4),
+ HCI_FLOW_SPECIFICATION_COMMAND : 1 << (5*8+5),
+ HCI_SET_EVENT_MASK_COMMAND : 1 << (5*8+6),
+ HCI_RESET_COMMAND : 1 << (5*8+7),
+ HCI_SET_EVENT_FILTER_COMMAND : 1 << (6*8+0),
+ HCI_FLUSH_COMMAND : 1 << (6*8+1),
+ HCI_READ_PIN_TYPE_COMMAND : 1 << (6*8+2),
+ HCI_WRITE_PIN_TYPE_COMMAND : 1 << (6*8+3),
+ HCI_READ_STORED_LINK_KEY_COMMAND : 1 << (6*8+5),
+ HCI_WRITE_STORED_LINK_KEY_COMMAND : 1 << (6*8+6),
+ HCI_DELETE_STORED_LINK_KEY_COMMAND : 1 << (6*8+7),
+ HCI_WRITE_LOCAL_NAME_COMMAND : 1 << (7*8+0),
+ HCI_READ_LOCAL_NAME_COMMAND : 1 << (7*8+1),
+ HCI_READ_CONNECTION_ACCEPT_TIMEOUT_COMMAND : 1 << (7*8+2),
+ HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT_COMMAND : 1 << (7*8+3),
+ HCI_READ_PAGE_TIMEOUT_COMMAND : 1 << (7*8+4),
+ HCI_WRITE_PAGE_TIMEOUT_COMMAND : 1 << (7*8+5),
+ HCI_READ_SCAN_ENABLE_COMMAND : 1 << (7*8+6),
+ HCI_WRITE_SCAN_ENABLE_COMMAND : 1 << (7*8+7),
+ HCI_READ_PAGE_SCAN_ACTIVITY_COMMAND : 1 << (8*8+0),
+ HCI_WRITE_PAGE_SCAN_ACTIVITY_COMMAND : 1 << (8*8+1),
+ HCI_READ_INQUIRY_SCAN_ACTIVITY_COMMAND : 1 << (8*8+2),
+ HCI_WRITE_INQUIRY_SCAN_ACTIVITY_COMMAND : 1 << (8*8+3),
+ HCI_READ_AUTHENTICATION_ENABLE_COMMAND : 1 << (8*8+4),
+ HCI_WRITE_AUTHENTICATION_ENABLE_COMMAND : 1 << (8*8+5),
+ HCI_READ_CLASS_OF_DEVICE_COMMAND : 1 << (9*8+0),
+ HCI_WRITE_CLASS_OF_DEVICE_COMMAND : 1 << (9*8+1),
+ HCI_READ_VOICE_SETTING_COMMAND : 1 << (9*8+2),
+ HCI_WRITE_VOICE_SETTING_COMMAND : 1 << (9*8+3),
+ HCI_READ_AUTOMATIC_FLUSH_TIMEOUT_COMMAND : 1 << (9*8+4),
+ HCI_WRITE_AUTOMATIC_FLUSH_TIMEOUT_COMMAND : 1 << (9*8+5),
+ HCI_READ_NUM_BROADCAST_RETRANSMISSIONS_COMMAND : 1 << (9*8+6),
+ HCI_WRITE_NUM_BROADCAST_RETRANSMISSIONS_COMMAND : 1 << (9*8+7),
+ HCI_READ_HOLD_MODE_ACTIVITY_COMMAND : 1 << (10*8+0),
+ HCI_WRITE_HOLD_MODE_ACTIVITY_COMMAND : 1 << (10*8+1),
+ HCI_READ_TRANSMIT_POWER_LEVEL_COMMAND : 1 << (10*8+2),
+ HCI_READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE_COMMAND : 1 << (10*8+3),
+ HCI_WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE_COMMAND : 1 << (10*8+4),
+ HCI_SET_CONTROLLER_TO_HOST_FLOW_CONTROL_COMMAND : 1 << (10*8+5),
+ HCI_HOST_BUFFER_SIZE_COMMAND : 1 << (10*8+6),
+ HCI_HOST_NUMBER_OF_COMPLETED_PACKETS_COMMAND : 1 << (10*8+7),
+ HCI_READ_LINK_SUPERVISION_TIMEOUT_COMMAND : 1 << (11*8+0),
+ HCI_WRITE_LINK_SUPERVISION_TIMEOUT_COMMAND : 1 << (11*8+1),
+ HCI_READ_NUMBER_OF_SUPPORTED_IAC_COMMAND : 1 << (11*8+2),
+ HCI_READ_CURRENT_IAC_LAP_COMMAND : 1 << (11*8+3),
+ HCI_WRITE_CURRENT_IAC_LAP_COMMAND : 1 << (11*8+4),
+ HCI_SET_AFH_HOST_CHANNEL_CLASSIFICATION_COMMAND : 1 << (12*8+1),
+ HCI_READ_INQUIRY_SCAN_TYPE_COMMAND : 1 << (12*8+4),
+ HCI_WRITE_INQUIRY_SCAN_TYPE_COMMAND : 1 << (12*8+5),
+ HCI_READ_INQUIRY_MODE_COMMAND : 1 << (12*8+6),
+ HCI_WRITE_INQUIRY_MODE_COMMAND : 1 << (12*8+7),
+ HCI_READ_PAGE_SCAN_TYPE_COMMAND : 1 << (13*8+0),
+ HCI_WRITE_PAGE_SCAN_TYPE_COMMAND : 1 << (13*8+1),
+ HCI_READ_AFH_CHANNEL_ASSESSMENT_MODE_COMMAND : 1 << (13*8+2),
+ HCI_WRITE_AFH_CHANNEL_ASSESSMENT_MODE_COMMAND : 1 << (13*8+3),
+ HCI_READ_LOCAL_VERSION_INFORMATION_COMMAND : 1 << (14*8+3),
+ HCI_READ_LOCAL_SUPPORTED_FEATURES_COMMAND : 1 << (14*8+5),
+ HCI_READ_LOCAL_EXTENDED_FEATURES_COMMAND : 1 << (14*8+6),
+ HCI_READ_BUFFER_SIZE_COMMAND : 1 << (14*8+7),
+ HCI_READ_BD_ADDR_COMMAND : 1 << (15*8+1),
+ HCI_READ_FAILED_CONTACT_COUNTER_COMMAND : 1 << (15*8+2),
+ HCI_RESET_FAILED_CONTACT_COUNTER_COMMAND : 1 << (15*8+3),
+ HCI_READ_LINK_QUALITY_COMMAND : 1 << (15*8+4),
+ HCI_READ_RSSI_COMMAND : 1 << (15*8+5),
+ HCI_READ_AFH_CHANNEL_MAP_COMMAND : 1 << (15*8+6),
+ HCI_READ_CLOCK_COMMAND : 1 << (15*8+7),
+ HCI_READ_LOOPBACK_MODE_COMMAND : 1 << (16*8+0),
+ HCI_WRITE_LOOPBACK_MODE_COMMAND : 1 << (16*8+1),
+ HCI_ENABLE_DEVICE_UNDER_TEST_MODE_COMMAND : 1 << (16*8+2),
+ HCI_SETUP_SYNCHRONOUS_CONNECTION_COMMAND : 1 << (16*8+3),
+ HCI_ACCEPT_SYNCHRONOUS_CONNECTION_REQUEST_COMMAND : 1 << (16*8+4),
+ HCI_REJECT_SYNCHRONOUS_CONNECTION_REQUEST_COMMAND : 1 << (16*8+5),
+ HCI_READ_EXTENDED_INQUIRY_RESPONSE_COMMAND : 1 << (17*8+0),
+ HCI_WRITE_EXTENDED_INQUIRY_RESPONSE_COMMAND : 1 << (17*8+1),
+ HCI_REFRESH_ENCRYPTION_KEY_COMMAND : 1 << (17*8+2),
+ HCI_SNIFF_SUBRATING_COMMAND : 1 << (17*8+4),
+ HCI_READ_SIMPLE_PAIRING_MODE_COMMAND : 1 << (17*8+5),
+ HCI_WRITE_SIMPLE_PAIRING_MODE_COMMAND : 1 << (17*8+6),
+ HCI_READ_LOCAL_OOB_DATA_COMMAND : 1 << (17*8+7),
+ HCI_READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL_COMMAND : 1 << (18*8+0),
+ HCI_WRITE_INQUIRY_TRANSMIT_POWER_LEVEL_COMMAND : 1 << (18*8+1),
+ HCI_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_COMMAND : 1 << (18*8+2),
+ HCI_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_COMMAND : 1 << (18*8+3),
+ HCI_IO_CAPABILITY_REQUEST_REPLY_COMMAND : 1 << (18*8+7),
+ HCI_USER_CONFIRMATION_REQUEST_REPLY_COMMAND : 1 << (19*8+0),
+ HCI_USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY_COMMAND : 1 << (19*8+1),
+ HCI_USER_PASSKEY_REQUEST_REPLY_COMMAND : 1 << (19*8+2),
+ HCI_USER_PASSKEY_REQUEST_NEGATIVE_REPLY_COMMAND : 1 << (19*8+3),
+ HCI_REMOTE_OOB_DATA_REQUEST_REPLY_COMMAND : 1 << (19*8+4),
+ HCI_WRITE_SIMPLE_PAIRING_DEBUG_MODE_COMMAND : 1 << (19*8+5),
+ HCI_ENHANCED_FLUSH_COMMAND : 1 << (19*8+6),
+ HCI_REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY_COMMAND : 1 << (19*8+7),
+ HCI_SEND_KEYPRESS_NOTIFICATION_COMMAND : 1 << (20*8+2),
+ HCI_IO_CAPABILITY_REQUEST_NEGATIVE_REPLY_COMMAND : 1 << (20*8+3),
+ HCI_READ_ENCRYPTION_KEY_SIZE_COMMAND : 1 << (20*8+4),
+ HCI_SET_EVENT_MASK_PAGE_2_COMMAND : 1 << (22*8+2),
+ HCI_READ_FLOW_CONTROL_MODE_COMMAND : 1 << (23*8+0),
+ HCI_WRITE_FLOW_CONTROL_MODE_COMMAND : 1 << (23*8+1),
+ HCI_READ_DATA_BLOCK_SIZE_COMMAND : 1 << (23*8+2),
+ HCI_READ_ENHANCED_TRANSMIT_POWER_LEVEL_COMMAND : 1 << (24*8+0),
+ HCI_READ_LE_HOST_SUPPORT_COMMAND : 1 << (24*8+5),
+ HCI_WRITE_LE_HOST_SUPPORT_COMMAND : 1 << (24*8+6),
+ HCI_LE_SET_EVENT_MASK_COMMAND : 1 << (25*8+0),
+ HCI_LE_READ_BUFFER_SIZE_COMMAND : 1 << (25*8+1),
+ HCI_LE_READ_LOCAL_SUPPORTED_FEATURES_COMMAND : 1 << (25*8+2),
+ HCI_LE_SET_RANDOM_ADDRESS_COMMAND : 1 << (25*8+4),
+ HCI_LE_SET_ADVERTISING_PARAMETERS_COMMAND : 1 << (25*8+5),
+ HCI_LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER_COMMAND : 1 << (25*8+6),
+ HCI_LE_SET_ADVERTISING_DATA_COMMAND : 1 << (25*8+7),
+ HCI_LE_SET_SCAN_RESPONSE_DATA_COMMAND : 1 << (26*8+0),
+ HCI_LE_SET_ADVERTISING_ENABLE_COMMAND : 1 << (26*8+1),
+ HCI_LE_SET_SCAN_PARAMETERS_COMMAND : 1 << (26*8+2),
+ HCI_LE_SET_SCAN_ENABLE_COMMAND : 1 << (26*8+3),
+ HCI_LE_CREATE_CONNECTION_COMMAND : 1 << (26*8+4),
+ HCI_LE_CREATE_CONNECTION_CANCEL_COMMAND : 1 << (26*8+5),
+ HCI_LE_READ_FILTER_ACCEPT_LIST_SIZE_COMMAND : 1 << (26*8+6),
+ HCI_LE_CLEAR_FILTER_ACCEPT_LIST_COMMAND : 1 << (26*8+7),
+ HCI_LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST_COMMAND : 1 << (27*8+0),
+ HCI_LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST_COMMAND : 1 << (27*8+1),
+ HCI_LE_CONNECTION_UPDATE_COMMAND : 1 << (27*8+2),
+ HCI_LE_SET_HOST_CHANNEL_CLASSIFICATION_COMMAND : 1 << (27*8+3),
+ HCI_LE_READ_CHANNEL_MAP_COMMAND : 1 << (27*8+4),
+ HCI_LE_READ_REMOTE_FEATURES_COMMAND : 1 << (27*8+5),
+ HCI_LE_ENCRYPT_COMMAND : 1 << (27*8+6),
+ HCI_LE_RAND_COMMAND : 1 << (27*8+7),
+ HCI_LE_ENABLE_ENCRYPTION_COMMAND : 1 << (28*8+0),
+ HCI_LE_LONG_TERM_KEY_REQUEST_REPLY_COMMAND : 1 << (28*8+1),
+ HCI_LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY_COMMAND : 1 << (28*8+2),
+ HCI_LE_READ_SUPPORTED_STATES_COMMAND : 1 << (28*8+3),
+ HCI_LE_RECEIVER_TEST_COMMAND : 1 << (28*8+4),
+ HCI_LE_TRANSMITTER_TEST_COMMAND : 1 << (28*8+5),
+ HCI_LE_TEST_END_COMMAND : 1 << (28*8+6),
+ HCI_ENHANCED_SETUP_SYNCHRONOUS_CONNECTION_COMMAND : 1 << (29*8+3),
+ HCI_ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION_REQUEST_COMMAND : 1 << (29*8+4),
+ HCI_READ_LOCAL_SUPPORTED_CODECS_COMMAND : 1 << (29*8+5),
+ HCI_SET_MWS_CHANNEL_PARAMETERS_COMMAND : 1 << (29*8+6),
+ HCI_SET_EXTERNAL_FRAME_CONFIGURATION_COMMAND : 1 << (29*8+7),
+ HCI_SET_MWS_SIGNALING_COMMAND : 1 << (30*8+0),
+ HCI_SET_MWS_TRANSPORT_LAYER_COMMAND : 1 << (30*8+1),
+ HCI_SET_MWS_SCAN_FREQUENCY_TABLE_COMMAND : 1 << (30*8+2),
+ HCI_GET_MWS_TRANSPORT_LAYER_CONFIGURATION_COMMAND : 1 << (30*8+3),
+ HCI_SET_MWS_PATTERN_CONFIGURATION_COMMAND : 1 << (30*8+4),
+ HCI_SET_TRIGGERED_CLOCK_CAPTURE_COMMAND : 1 << (30*8+5),
+ HCI_TRUNCATED_PAGE_COMMAND : 1 << (30*8+6),
+ HCI_TRUNCATED_PAGE_CANCEL_COMMAND : 1 << (30*8+7),
+ HCI_SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_COMMAND : 1 << (31*8+0),
+ HCI_SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVE_COMMAND : 1 << (31*8+1),
+ HCI_START_SYNCHRONIZATION_TRAIN_COMMAND : 1 << (31*8+2),
+ HCI_RECEIVE_SYNCHRONIZATION_TRAIN_COMMAND : 1 << (31*8+3),
+ HCI_SET_RESERVED_LT_ADDR_COMMAND : 1 << (31*8+4),
+ HCI_DELETE_RESERVED_LT_ADDR_COMMAND : 1 << (31*8+5),
+ HCI_SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_DATA_COMMAND : 1 << (31*8+6),
+ HCI_READ_SYNCHRONIZATION_TRAIN_PARAMETERS_COMMAND : 1 << (31*8+7),
+ HCI_WRITE_SYNCHRONIZATION_TRAIN_PARAMETERS_COMMAND : 1 << (32*8+0),
+ HCI_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_COMMAND : 1 << (32*8+1),
+ HCI_READ_SECURE_CONNECTIONS_HOST_SUPPORT_COMMAND : 1 << (32*8+2),
+ HCI_WRITE_SECURE_CONNECTIONS_HOST_SUPPORT_COMMAND : 1 << (32*8+3),
+ HCI_READ_AUTHENTICATED_PAYLOAD_TIMEOUT_COMMAND : 1 << (32*8+4),
+ HCI_WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT_COMMAND : 1 << (32*8+5),
+ HCI_READ_LOCAL_OOB_EXTENDED_DATA_COMMAND : 1 << (32*8+6),
+ HCI_WRITE_SECURE_CONNECTIONS_TEST_MODE_COMMAND : 1 << (32*8+7),
+ HCI_READ_EXTENDED_PAGE_TIMEOUT_COMMAND : 1 << (33*8+0),
+ HCI_WRITE_EXTENDED_PAGE_TIMEOUT_COMMAND : 1 << (33*8+1),
+ HCI_READ_EXTENDED_INQUIRY_LENGTH_COMMAND : 1 << (33*8+2),
+ HCI_WRITE_EXTENDED_INQUIRY_LENGTH_COMMAND : 1 << (33*8+3),
+ HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY_COMMAND : 1 << (33*8+4),
+ HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY_COMMAND : 1 << (33*8+5),
+ HCI_LE_SET_DATA_LENGTH_COMMAND : 1 << (33*8+6),
+ HCI_LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH_COMMAND : 1 << (33*8+7),
+ HCI_LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH_COMMAND : 1 << (34*8+0),
+ HCI_LE_READ_LOCAL_P_256_PUBLIC_KEY_COMMAND : 1 << (34*8+1),
+ HCI_LE_GENERATE_DHKEY_COMMAND : 1 << (34*8+2),
+ HCI_LE_ADD_DEVICE_TO_RESOLVING_LIST_COMMAND : 1 << (34*8+3),
+ HCI_LE_REMOVE_DEVICE_FROM_RESOLVING_LIST_COMMAND : 1 << (34*8+4),
+ HCI_LE_CLEAR_RESOLVING_LIST_COMMAND : 1 << (34*8+5),
+ HCI_LE_READ_RESOLVING_LIST_SIZE_COMMAND : 1 << (34*8+6),
+ HCI_LE_READ_PEER_RESOLVABLE_ADDRESS_COMMAND : 1 << (34*8+7),
+ HCI_LE_READ_LOCAL_RESOLVABLE_ADDRESS_COMMAND : 1 << (35*8+0),
+ HCI_LE_SET_ADDRESS_RESOLUTION_ENABLE_COMMAND : 1 << (35*8+1),
+ HCI_LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT_COMMAND : 1 << (35*8+2),
+ HCI_LE_READ_MAXIMUM_DATA_LENGTH_COMMAND : 1 << (35*8+3),
+ HCI_LE_READ_PHY_COMMAND : 1 << (35*8+4),
+ HCI_LE_SET_DEFAULT_PHY_COMMAND : 1 << (35*8+5),
+ HCI_LE_SET_PHY_COMMAND : 1 << (35*8+6),
+ HCI_LE_RECEIVER_TEST_V2_COMMAND : 1 << (35*8+7),
+ HCI_LE_TRANSMITTER_TEST_V2_COMMAND : 1 << (36*8+0),
+ HCI_LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_COMMAND : 1 << (36*8+1),
+ HCI_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_COMMAND : 1 << (36*8+2),
+ HCI_LE_SET_EXTENDED_ADVERTISING_DATA_COMMAND : 1 << (36*8+3),
+ HCI_LE_SET_EXTENDED_SCAN_RESPONSE_DATA_COMMAND : 1 << (36*8+4),
+ HCI_LE_SET_EXTENDED_ADVERTISING_ENABLE_COMMAND : 1 << (36*8+5),
+ HCI_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH_COMMAND : 1 << (36*8+6),
+ HCI_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS_COMMAND : 1 << (36*8+7),
+ HCI_LE_REMOVE_ADVERTISING_SET_COMMAND : 1 << (37*8+0),
+ HCI_LE_CLEAR_ADVERTISING_SETS_COMMAND : 1 << (37*8+1),
+ HCI_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_COMMAND : 1 << (37*8+2),
+ HCI_LE_SET_PERIODIC_ADVERTISING_DATA_COMMAND : 1 << (37*8+3),
+ HCI_LE_SET_PERIODIC_ADVERTISING_ENABLE_COMMAND : 1 << (37*8+4),
+ HCI_LE_SET_EXTENDED_SCAN_PARAMETERS_COMMAND : 1 << (37*8+5),
+ HCI_LE_SET_EXTENDED_SCAN_ENABLE_COMMAND : 1 << (37*8+6),
+ HCI_LE_EXTENDED_CREATE_CONNECTION_COMMAND : 1 << (37*8+7),
+ HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC_COMMAND : 1 << (38*8+0),
+ HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL_COMMAND : 1 << (38*8+1),
+ HCI_LE_PERIODIC_ADVERTISING_TERMINATE_SYNC_COMMAND : 1 << (38*8+2),
+ HCI_LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST_COMMAND : 1 << (38*8+3),
+ HCI_LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST_COMMAND : 1 << (38*8+4),
+ HCI_LE_CLEAR_PERIODIC_ADVERTISER_LIST_COMMAND : 1 << (38*8+5),
+ HCI_LE_READ_PERIODIC_ADVERTISER_LIST_SIZE_COMMAND : 1 << (38*8+6),
+ HCI_LE_READ_TRANSMIT_POWER_COMMAND : 1 << (38*8+7),
+ HCI_LE_READ_RF_PATH_COMPENSATION_COMMAND : 1 << (39*8+0),
+ HCI_LE_WRITE_RF_PATH_COMPENSATION_COMMAND : 1 << (39*8+1),
+ HCI_LE_SET_PRIVACY_MODE_COMMAND : 1 << (39*8+2),
+ HCI_LE_RECEIVER_TEST_V3_COMMAND : 1 << (39*8+3),
+ HCI_LE_TRANSMITTER_TEST_V3_COMMAND : 1 << (39*8+4),
+ HCI_LE_SET_CONNECTIONLESS_CTE_TRANSMIT_PARAMETERS_COMMAND : 1 << (39*8+5),
+ HCI_LE_SET_CONNECTIONLESS_CTE_TRANSMIT_ENABLE_COMMAND : 1 << (39*8+6),
+ HCI_LE_SET_CONNECTIONLESS_IQ_SAMPLING_ENABLE_COMMAND : 1 << (39*8+7),
+ HCI_LE_SET_CONNECTION_CTE_RECEIVE_PARAMETERS_COMMAND : 1 << (40*8+0),
+ HCI_LE_SET_CONNECTION_CTE_TRANSMIT_PARAMETERS_COMMAND : 1 << (40*8+1),
+ HCI_LE_CONNECTION_CTE_REQUEST_ENABLE_COMMAND : 1 << (40*8+2),
+ HCI_LE_CONNECTION_CTE_RESPONSE_ENABLE_COMMAND : 1 << (40*8+3),
+ HCI_LE_READ_ANTENNA_INFORMATION_COMMAND : 1 << (40*8+4),
+ HCI_LE_SET_PERIODIC_ADVERTISING_RECEIVE_ENABLE_COMMAND : 1 << (40*8+5),
+ HCI_LE_PERIODIC_ADVERTISING_SYNC_TRANSFER_COMMAND : 1 << (40*8+6),
+ HCI_LE_PERIODIC_ADVERTISING_SET_INFO_TRANSFER_COMMAND : 1 << (40*8+7),
+ HCI_LE_SET_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS_COMMAND : 1 << (41*8+0),
+ HCI_LE_SET_DEFAULT_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS_COMMAND : 1 << (41*8+1),
+ HCI_LE_GENERATE_DHKEY_V2_COMMAND : 1 << (41*8+2),
+ HCI_READ_LOCAL_SIMPLE_PAIRING_OPTIONS_COMMAND : 1 << (41*8+3),
+ HCI_LE_MODIFY_SLEEP_CLOCK_ACCURACY_COMMAND : 1 << (41*8+4),
+ HCI_LE_READ_BUFFER_SIZE_V2_COMMAND : 1 << (41*8+5),
+ HCI_LE_READ_ISO_TX_SYNC_COMMAND : 1 << (41*8+6),
+ HCI_LE_SET_CIG_PARAMETERS_COMMAND : 1 << (41*8+7),
+ HCI_LE_SET_CIG_PARAMETERS_TEST_COMMAND : 1 << (42*8+0),
+ HCI_LE_CREATE_CIS_COMMAND : 1 << (42*8+1),
+ HCI_LE_REMOVE_CIG_COMMAND : 1 << (42*8+2),
+ HCI_LE_ACCEPT_CIS_REQUEST_COMMAND : 1 << (42*8+3),
+ HCI_LE_REJECT_CIS_REQUEST_COMMAND : 1 << (42*8+4),
+ HCI_LE_CREATE_BIG_COMMAND : 1 << (42*8+5),
+ HCI_LE_CREATE_BIG_TEST_COMMAND : 1 << (42*8+6),
+ HCI_LE_TERMINATE_BIG_COMMAND : 1 << (42*8+7),
+ HCI_LE_BIG_CREATE_SYNC_COMMAND : 1 << (43*8+0),
+ HCI_LE_BIG_TERMINATE_SYNC_COMMAND : 1 << (43*8+1),
+ HCI_LE_REQUEST_PEER_SCA_COMMAND : 1 << (43*8+2),
+ HCI_LE_SETUP_ISO_DATA_PATH_COMMAND : 1 << (43*8+3),
+ HCI_LE_REMOVE_ISO_DATA_PATH_COMMAND : 1 << (43*8+4),
+ HCI_LE_ISO_TRANSMIT_TEST_COMMAND : 1 << (43*8+5),
+ HCI_LE_ISO_RECEIVE_TEST_COMMAND : 1 << (43*8+6),
+ HCI_LE_ISO_READ_TEST_COUNTERS_COMMAND : 1 << (43*8+7),
+ HCI_LE_ISO_TEST_END_COMMAND : 1 << (44*8+0),
+ HCI_LE_SET_HOST_FEATURE_COMMAND : 1 << (44*8+1),
+ HCI_LE_READ_ISO_LINK_QUALITY_COMMAND : 1 << (44*8+2),
+ HCI_LE_ENHANCED_READ_TRANSMIT_POWER_LEVEL_COMMAND : 1 << (44*8+3),
+ HCI_LE_READ_REMOTE_TRANSMIT_POWER_LEVEL_COMMAND : 1 << (44*8+4),
+ HCI_LE_SET_PATH_LOSS_REPORTING_PARAMETERS_COMMAND : 1 << (44*8+5),
+ HCI_LE_SET_PATH_LOSS_REPORTING_ENABLE_COMMAND : 1 << (44*8+6),
+ HCI_LE_SET_TRANSMIT_POWER_REPORTING_ENABLE_COMMAND : 1 << (44*8+7),
+ HCI_LE_TRANSMITTER_TEST_V4_COMMAND : 1 << (45*8+0),
+ HCI_SET_ECOSYSTEM_BASE_INTERVAL_COMMAND : 1 << (45*8+1),
+ HCI_READ_LOCAL_SUPPORTED_CODECS_V2_COMMAND : 1 << (45*8+2),
+ HCI_READ_LOCAL_SUPPORTED_CODEC_CAPABILITIES_COMMAND : 1 << (45*8+3),
+ HCI_READ_LOCAL_SUPPORTED_CONTROLLER_DELAY_COMMAND : 1 << (45*8+4),
+ HCI_CONFIGURE_DATA_PATH_COMMAND : 1 << (45*8+5),
+ HCI_LE_SET_DATA_RELATED_ADDRESS_CHANGES_COMMAND : 1 << (45*8+6),
+ HCI_SET_MIN_ENCRYPTION_KEY_SIZE_COMMAND : 1 << (45*8+7),
+ HCI_LE_SET_DEFAULT_SUBRATE_COMMAND : 1 << (46*8+0),
+ HCI_LE_SUBRATE_REQUEST_COMMAND : 1 << (46*8+1),
+ HCI_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_V2_COMMAND : 1 << (46*8+2),
+ HCI_LE_SET_PERIODIC_ADVERTISING_SUBEVENT_DATA_COMMAND : 1 << (46*8+5),
+ HCI_LE_SET_PERIODIC_ADVERTISING_RESPONSE_DATA_COMMAND : 1 << (46*8+6),
+ HCI_LE_SET_PERIODIC_SYNC_SUBEVENT_COMMAND : 1 << (46*8+7),
+ HCI_LE_EXTENDED_CREATE_CONNECTION_V2_COMMAND : 1 << (47*8+0),
+ HCI_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_V2_COMMAND : 1 << (47*8+1),
+}
# LE Supported Features
-HCI_LE_ENCRYPTION_LE_SUPPORTED_FEATURE = 0
-HCI_CONNECTION_PARAMETERS_REQUEST_PROCEDURE_LE_SUPPORTED_FEATURE = 1
-HCI_EXTENDED_REJECT_INDICATION_LE_SUPPORTED_FEATURE = 2
-HCI_PERIPHERAL_INITIATED_FEATURE_EXCHANGE_LE_SUPPORTED_FEATURE = 3
-HCI_LE_PING_LE_SUPPORTED_FEATURE = 4
-HCI_LE_DATA_PACKET_LENGTH_EXTENSION_LE_SUPPORTED_FEATURE = 5
-HCI_LL_PRIVACY_LE_SUPPORTED_FEATURE = 6
-HCI_EXTENDED_SCANNER_FILTER_POLICIES_LE_SUPPORTED_FEATURE = 7
-HCI_LE_2M_PHY_LE_SUPPORTED_FEATURE = 8
-HCI_STABLE_MODULATION_INDEX_TRANSMITTER_LE_SUPPORTED_FEATURE = 9
-HCI_STABLE_MODULATION_INDEX_RECEIVER_LE_SUPPORTED_FEATURE = 10
-HCI_LE_CODED_PHY_LE_SUPPORTED_FEATURE = 11
-HCI_LE_EXTENDED_ADVERTISING_LE_SUPPORTED_FEATURE = 12
-HCI_LE_PERIODIC_ADVERTISING_LE_SUPPORTED_FEATURE = 13
-HCI_CHANNEL_SELECTION_ALGORITHM_2_LE_SUPPORTED_FEATURE = 14
-HCI_LE_POWER_CLASS_1_LE_SUPPORTED_FEATURE = 15
-HCI_MINIMUM_NUMBER_OF_USED_CHANNELS_PROCEDURE_LE_SUPPORTED_FEATURE = 16
-HCI_CONNECTION_CTE_REQUEST_LE_SUPPORTED_FEATURE = 17
-HCI_CONNECTION_CTE_RESPONSE_LE_SUPPORTED_FEATURE = 18
-HCI_CONNECTIONLESS_CTE_TRANSMITTER_LE_SUPPORTED_FEATURE = 19
-HCI_CONNECTIONLESS_CTR_RECEIVER_LE_SUPPORTED_FEATURE = 20
-HCI_ANTENNA_SWITCHING_DURING_CTE_TRANSMISSION_LE_SUPPORTED_FEATURE = 21
-HCI_ANTENNA_SWITCHING_DURING_CTE_RECEPTION_LE_SUPPORTED_FEATURE = 22
-HCI_RECEIVING_CONSTANT_TONE_EXTENSIONS_LE_SUPPORTED_FEATURE = 23
-HCI_PERIODIC_ADVERTISING_SYNC_TRANSFER_SENDER_LE_SUPPORTED_FEATURE = 24
-HCI_PERIODIC_ADVERTISING_SYNC_TRANSFER_RECIPIENT_LE_SUPPORTED_FEATURE = 25
-HCI_SLEEP_CLOCK_ACCURACY_UPDATES_LE_SUPPORTED_FEATURE = 26
-HCI_REMOTE_PUBLIC_KEY_VALIDATION_LE_SUPPORTED_FEATURE = 27
-HCI_CONNECTED_ISOCHRONOUS_STREAM_CENTRAL_LE_SUPPORTED_FEATURE = 28
-HCI_CONNECTED_ISOCHRONOUS_STREAM_PERIPHERAL_LE_SUPPORTED_FEATURE = 29
-HCI_ISOCHRONOUS_BROADCASTER_LE_SUPPORTED_FEATURE = 30
-HCI_SYNCHRONIZED_RECEIVER_LE_SUPPORTED_FEATURE = 31
-HCI_CONNECTED_ISOCHRONOUS_STREAM_LE_SUPPORTED_FEATURE = 32
-HCI_LE_POWER_CONTROL_REQUEST_LE_SUPPORTED_FEATURE = 33
-HCI_LE_POWER_CONTROL_REQUEST_DUP_LE_SUPPORTED_FEATURE = 34
-HCI_LE_PATH_LOSS_MONITORING_LE_SUPPORTED_FEATURE = 35
-HCI_PERIODIC_ADVERTISING_ADI_SUPPORT_LE_SUPPORTED_FEATURE = 36
-HCI_CONNECTION_SUBRATING_LE_SUPPORTED_FEATURE = 37
-HCI_CONNECTION_SUBRATING_HOST_SUPPORT_LE_SUPPORTED_FEATURE = 38
-HCI_CHANNEL_CLASSIFICATION_LE_SUPPORTED_FEATURE = 39
-
-HCI_LE_SUPPORTED_FEATURES_NAMES = {
- flag: feature_name for (feature_name, flag) in globals().items()
- if feature_name.startswith('HCI_') and feature_name.endswith('_LE_SUPPORTED_FEATURE')
-}
+# See Bluetooth spec @ Vol 6, Part B, 4.6 FEATURE SUPPORT
+class LeFeature(enum.IntEnum):
+ LE_ENCRYPTION = 0
+ CONNECTION_PARAMETERS_REQUEST_PROCEDURE = 1
+ EXTENDED_REJECT_INDICATION = 2
+ PERIPHERAL_INITIATED_FEATURE_EXCHANGE = 3
+ LE_PING = 4
+ LE_DATA_PACKET_LENGTH_EXTENSION = 5
+ LL_PRIVACY = 6
+ EXTENDED_SCANNER_FILTER_POLICIES = 7
+ LE_2M_PHY = 8
+ STABLE_MODULATION_INDEX_TRANSMITTER = 9
+ STABLE_MODULATION_INDEX_RECEIVER = 10
+ LE_CODED_PHY = 11
+ LE_EXTENDED_ADVERTISING = 12
+ LE_PERIODIC_ADVERTISING = 13
+ CHANNEL_SELECTION_ALGORITHM_2 = 14
+ LE_POWER_CLASS_1 = 15
+ MINIMUM_NUMBER_OF_USED_CHANNELS_PROCEDURE = 16
+ CONNECTION_CTE_REQUEST = 17
+ CONNECTION_CTE_RESPONSE = 18
+ CONNECTIONLESS_CTE_TRANSMITTER = 19
+ CONNECTIONLESS_CTR_RECEIVER = 20
+ ANTENNA_SWITCHING_DURING_CTE_TRANSMISSION = 21
+ ANTENNA_SWITCHING_DURING_CTE_RECEPTION = 22
+ RECEIVING_CONSTANT_TONE_EXTENSIONS = 23
+ PERIODIC_ADVERTISING_SYNC_TRANSFER_SENDER = 24
+ PERIODIC_ADVERTISING_SYNC_TRANSFER_RECIPIENT = 25
+ SLEEP_CLOCK_ACCURACY_UPDATES = 26
+ REMOTE_PUBLIC_KEY_VALIDATION = 27
+ CONNECTED_ISOCHRONOUS_STREAM_CENTRAL = 28
+ CONNECTED_ISOCHRONOUS_STREAM_PERIPHERAL = 29
+ ISOCHRONOUS_BROADCASTER = 30
+ SYNCHRONIZED_RECEIVER = 31
+ CONNECTED_ISOCHRONOUS_STREAM = 32
+ LE_POWER_CONTROL_REQUEST = 33
+ LE_POWER_CONTROL_REQUEST_DUP = 34
+ LE_PATH_LOSS_MONITORING = 35
+ PERIODIC_ADVERTISING_ADI_SUPPORT = 36
+ CONNECTION_SUBRATING = 37
+ CONNECTION_SUBRATING_HOST_SUPPORT = 38
+ CHANNEL_CLASSIFICATION = 39
+ ADVERTISING_CODING_SELECTION = 40
+ ADVERTISING_CODING_SELECTION_HOST_SUPPORT = 41
+ PERIODIC_ADVERTISING_WITH_RESPONSES_ADVERTISER = 43
+ PERIODIC_ADVERTISING_WITH_RESPONSES_SCANNER = 44
+
+class LeFeatureMask(enum.IntFlag):
+ LE_ENCRYPTION = 1 << LeFeature.LE_ENCRYPTION
+ CONNECTION_PARAMETERS_REQUEST_PROCEDURE = 1 << LeFeature.CONNECTION_PARAMETERS_REQUEST_PROCEDURE
+ EXTENDED_REJECT_INDICATION = 1 << LeFeature.EXTENDED_REJECT_INDICATION
+ PERIPHERAL_INITIATED_FEATURE_EXCHANGE = 1 << LeFeature.PERIPHERAL_INITIATED_FEATURE_EXCHANGE
+ LE_PING = 1 << LeFeature.LE_PING
+ LE_DATA_PACKET_LENGTH_EXTENSION = 1 << LeFeature.LE_DATA_PACKET_LENGTH_EXTENSION
+ LL_PRIVACY = 1 << LeFeature.LL_PRIVACY
+ EXTENDED_SCANNER_FILTER_POLICIES = 1 << LeFeature.EXTENDED_SCANNER_FILTER_POLICIES
+ LE_2M_PHY = 1 << LeFeature.LE_2M_PHY
+ STABLE_MODULATION_INDEX_TRANSMITTER = 1 << LeFeature.STABLE_MODULATION_INDEX_TRANSMITTER
+ STABLE_MODULATION_INDEX_RECEIVER = 1 << LeFeature.STABLE_MODULATION_INDEX_RECEIVER
+ LE_CODED_PHY = 1 << LeFeature.LE_CODED_PHY
+ LE_EXTENDED_ADVERTISING = 1 << LeFeature.LE_EXTENDED_ADVERTISING
+ LE_PERIODIC_ADVERTISING = 1 << LeFeature.LE_PERIODIC_ADVERTISING
+ CHANNEL_SELECTION_ALGORITHM_2 = 1 << LeFeature.CHANNEL_SELECTION_ALGORITHM_2
+ LE_POWER_CLASS_1 = 1 << LeFeature.LE_POWER_CLASS_1
+ MINIMUM_NUMBER_OF_USED_CHANNELS_PROCEDURE = 1 << LeFeature.MINIMUM_NUMBER_OF_USED_CHANNELS_PROCEDURE
+ CONNECTION_CTE_REQUEST = 1 << LeFeature.CONNECTION_CTE_REQUEST
+ CONNECTION_CTE_RESPONSE = 1 << LeFeature.CONNECTION_CTE_RESPONSE
+ CONNECTIONLESS_CTE_TRANSMITTER = 1 << LeFeature.CONNECTIONLESS_CTE_TRANSMITTER
+ CONNECTIONLESS_CTR_RECEIVER = 1 << LeFeature.CONNECTIONLESS_CTR_RECEIVER
+ ANTENNA_SWITCHING_DURING_CTE_TRANSMISSION = 1 << LeFeature.ANTENNA_SWITCHING_DURING_CTE_TRANSMISSION
+ ANTENNA_SWITCHING_DURING_CTE_RECEPTION = 1 << LeFeature.ANTENNA_SWITCHING_DURING_CTE_RECEPTION
+ RECEIVING_CONSTANT_TONE_EXTENSIONS = 1 << LeFeature.RECEIVING_CONSTANT_TONE_EXTENSIONS
+ PERIODIC_ADVERTISING_SYNC_TRANSFER_SENDER = 1 << LeFeature.PERIODIC_ADVERTISING_SYNC_TRANSFER_SENDER
+ PERIODIC_ADVERTISING_SYNC_TRANSFER_RECIPIENT = 1 << LeFeature.PERIODIC_ADVERTISING_SYNC_TRANSFER_RECIPIENT
+ SLEEP_CLOCK_ACCURACY_UPDATES = 1 << LeFeature.SLEEP_CLOCK_ACCURACY_UPDATES
+ REMOTE_PUBLIC_KEY_VALIDATION = 1 << LeFeature.REMOTE_PUBLIC_KEY_VALIDATION
+ CONNECTED_ISOCHRONOUS_STREAM_CENTRAL = 1 << LeFeature.CONNECTED_ISOCHRONOUS_STREAM_CENTRAL
+ CONNECTED_ISOCHRONOUS_STREAM_PERIPHERAL = 1 << LeFeature.CONNECTED_ISOCHRONOUS_STREAM_PERIPHERAL
+ ISOCHRONOUS_BROADCASTER = 1 << LeFeature.ISOCHRONOUS_BROADCASTER
+ SYNCHRONIZED_RECEIVER = 1 << LeFeature.SYNCHRONIZED_RECEIVER
+ CONNECTED_ISOCHRONOUS_STREAM = 1 << LeFeature.CONNECTED_ISOCHRONOUS_STREAM
+ LE_POWER_CONTROL_REQUEST = 1 << LeFeature.LE_POWER_CONTROL_REQUEST
+ LE_POWER_CONTROL_REQUEST_DUP = 1 << LeFeature.LE_POWER_CONTROL_REQUEST_DUP
+ LE_PATH_LOSS_MONITORING = 1 << LeFeature.LE_PATH_LOSS_MONITORING
+ PERIODIC_ADVERTISING_ADI_SUPPORT = 1 << LeFeature.PERIODIC_ADVERTISING_ADI_SUPPORT
+ CONNECTION_SUBRATING = 1 << LeFeature.CONNECTION_SUBRATING
+ CONNECTION_SUBRATING_HOST_SUPPORT = 1 << LeFeature.CONNECTION_SUBRATING_HOST_SUPPORT
+ 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
+ PERIODIC_ADVERTISING_WITH_RESPONSES_ADVERTISER = 1 << LeFeature.PERIODIC_ADVERTISING_WITH_RESPONSES_ADVERTISER
+ PERIODIC_ADVERTISING_WITH_RESPONSES_SCANNER = 1 << LeFeature.PERIODIC_ADVERTISING_WITH_RESPONSES_SCANNER
+
+class LmpFeature(enum.IntEnum):
+ # Page 0 (Legacy LMP features)
+ LMP_3_SLOT_PACKETS = 0
+ LMP_5_SLOT_PACKETS = 1
+ ENCRYPTION = 2
+ SLOT_OFFSET = 3
+ TIMING_ACCURACY = 4
+ ROLE_SWITCH = 5
+ HOLD_MODE = 6
+ SNIFF_MODE = 7
+ # PREVIOUSLY_USED = 8
+ POWER_CONTROL_REQUESTS = 9
+ CHANNEL_QUALITY_DRIVEN_DATA_RATE_CQDDR = 10
+ SCO_LINK = 11
+ HV2_PACKETS = 12
+ HV3_PACKETS = 13
+ U_LAW_LOG_SYNCHRONOUS_DATA = 14
+ A_LAW_LOG_SYNCHRONOUS_DATA = 15
+ CVSD_SYNCHRONOUS_DATA = 16
+ PAGING_PARAMETER_NEGOTIATION = 17
+ POWER_CONTROL = 18
+ TRANSPARENT_SYNCHRONOUS_DATA = 19
+ FLOW_CONTROL_LAG_LEAST_SIGNIFICANT_BIT = 20
+ FLOW_CONTROL_LAG_MIDDLE_BIT = 21
+ FLOW_CONTROL_LAG_MOST_SIGNIFICANT_BIT = 22
+ BROADCAST_ENCRYPTION = 23
+ # RESERVED_FOR_FUTURE_USE = 24
+ ENHANCED_DATA_RATE_ACL_2_MBPS_MODE = 25
+ ENHANCED_DATA_RATE_ACL_3_MBPS_MODE = 26
+ ENHANCED_INQUIRY_SCAN = 27
+ INTERLACED_INQUIRY_SCAN = 28
+ INTERLACED_PAGE_SCAN = 29
+ RSSI_WITH_INQUIRY_RESULTS = 30
+ EXTENDED_SCO_LINK_EV3_PACKETS = 31
+ EV4_PACKETS = 32
+ EV5_PACKETS = 33
+ # RESERVED_FOR_FUTURE_USE = 34
+ AFH_CAPABLE_PERIPHERAL = 35
+ AFH_CLASSIFICATION_PERIPHERAL = 36
+ BR_EDR_NOT_SUPPORTED = 37
+ LE_SUPPORTED_CONTROLLER = 38
+ LMP_3_SLOT_ENHANCED_DATA_RATE_ACL_PACKETS = 39
+ LMP_5_SLOT_ENHANCED_DATA_RATE_ACL_PACKETS = 40
+ SNIFF_SUBRATING = 41
+ PAUSE_ENCRYPTION = 42
+ AFH_CAPABLE_CENTRAL = 43
+ AFH_CLASSIFICATION_CENTRAL = 44
+ ENHANCED_DATA_RATE_ESCO_2_MBPS_MODE = 45
+ ENHANCED_DATA_RATE_ESCO_3_MBPS_MODE = 46
+ LMP_3_SLOT_ENHANCED_DATA_RATE_ESCO_PACKETS = 47
+ EXTENDED_INQUIRY_RESPONSE = 48
+ SIMULTANEOUS_LE_AND_BR_EDR_TO_SAME_DEVICE_CAPABLE_CONTROLLER = 49
+ # RESERVED_FOR_FUTURE_USE = 50
+ SECURE_SIMPLE_PAIRING_CONTROLLER_SUPPORT = 51
+ ENCAPSULATED_PDU = 52
+ ERRONEOUS_DATA_REPORTING = 53
+ NON_FLUSHABLE_PACKET_BOUNDARY_FLAG = 54
+ # RESERVED_FOR_FUTURE_USE = 55
+ HCI_LINK_SUPERVISION_TIMEOUT_CHANGED_EVENT = 56
+ VARIABLE_INQUIRY_TX_POWER_LEVEL = 57
+ ENHANCED_POWER_CONTROL = 58
+ # RESERVED_FOR_FUTURE_USE = 59
+ # RESERVED_FOR_FUTURE_USE = 60
+ # RESERVED_FOR_FUTURE_USE = 61
+ # RESERVED_FOR_FUTURE_USE = 62
+ EXTENDED_FEATURES = 63
+
+ # Page 1
+ SECURE_SIMPLE_PAIRING_HOST_SUPPORT = 64
+ LE_SUPPORTED_HOST = 65
+ # PREVIOUSLY_USED = 66
+ SECURE_CONNECTIONS_HOST_SUPPORT = 67
+
+ # Page 2
+ CONNECTIONLESS_PERIPHERAL_BROADCAST_TRANSMITTER_OPERATION = 128
+ CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVER_OPERATION = 129
+ SYNCHRONIZATION_TRAIN = 130
+ SYNCHRONIZATION_SCAN = 131
+ HCI_INQUIRY_RESPONSE_NOTIFICATION_EVENT = 132
+ GENERALIZED_INTERLACED_SCAN = 133
+ COARSE_CLOCK_ADJUSTMENT = 134
+ RESERVED_FOR_FUTURE_USE = 135
+ SECURE_CONNECTIONS_CONTROLLER_SUPPORT = 136
+ PING = 137
+ SLOT_AVAILABILITY_MASK = 138
+ TRAIN_NUDGING = 139
+
+class LmpFeatureMask(enum.IntFlag):
+ # Page 0 (Legacy LMP features)
+ LMP_3_SLOT_PACKETS = (1 << LmpFeature.LMP_3_SLOT_PACKETS)
+ LMP_5_SLOT_PACKETS = (1 << LmpFeature.LMP_5_SLOT_PACKETS)
+ ENCRYPTION = (1 << LmpFeature.ENCRYPTION)
+ SLOT_OFFSET = (1 << LmpFeature.SLOT_OFFSET)
+ TIMING_ACCURACY = (1 << LmpFeature.TIMING_ACCURACY)
+ ROLE_SWITCH = (1 << LmpFeature.ROLE_SWITCH)
+ HOLD_MODE = (1 << LmpFeature.HOLD_MODE)
+ SNIFF_MODE = (1 << LmpFeature.SNIFF_MODE)
+ # PREVIOUSLY_USED = (1 << LmpFeature.PREVIOUSLY_USED)
+ POWER_CONTROL_REQUESTS = (1 << LmpFeature.POWER_CONTROL_REQUESTS)
+ CHANNEL_QUALITY_DRIVEN_DATA_RATE_CQDDR = (1 << LmpFeature.CHANNEL_QUALITY_DRIVEN_DATA_RATE_CQDDR)
+ SCO_LINK = (1 << LmpFeature.SCO_LINK)
+ HV2_PACKETS = (1 << LmpFeature.HV2_PACKETS)
+ HV3_PACKETS = (1 << LmpFeature.HV3_PACKETS)
+ U_LAW_LOG_SYNCHRONOUS_DATA = (1 << LmpFeature.U_LAW_LOG_SYNCHRONOUS_DATA)
+ A_LAW_LOG_SYNCHRONOUS_DATA = (1 << LmpFeature.A_LAW_LOG_SYNCHRONOUS_DATA)
+ CVSD_SYNCHRONOUS_DATA = (1 << LmpFeature.CVSD_SYNCHRONOUS_DATA)
+ PAGING_PARAMETER_NEGOTIATION = (1 << LmpFeature.PAGING_PARAMETER_NEGOTIATION)
+ POWER_CONTROL = (1 << LmpFeature.POWER_CONTROL)
+ TRANSPARENT_SYNCHRONOUS_DATA = (1 << LmpFeature.TRANSPARENT_SYNCHRONOUS_DATA)
+ FLOW_CONTROL_LAG_LEAST_SIGNIFICANT_BIT = (1 << LmpFeature.FLOW_CONTROL_LAG_LEAST_SIGNIFICANT_BIT)
+ FLOW_CONTROL_LAG_MIDDLE_BIT = (1 << LmpFeature.FLOW_CONTROL_LAG_MIDDLE_BIT)
+ FLOW_CONTROL_LAG_MOST_SIGNIFICANT_BIT = (1 << LmpFeature.FLOW_CONTROL_LAG_MOST_SIGNIFICANT_BIT)
+ BROADCAST_ENCRYPTION = (1 << LmpFeature.BROADCAST_ENCRYPTION)
+ # RESERVED_FOR_FUTURE_USE = (1 << LmpFeature.RESERVED_FOR_FUTURE_USE)
+ ENHANCED_DATA_RATE_ACL_2_MBPS_MODE = (1 << LmpFeature.ENHANCED_DATA_RATE_ACL_2_MBPS_MODE)
+ ENHANCED_DATA_RATE_ACL_3_MBPS_MODE = (1 << LmpFeature.ENHANCED_DATA_RATE_ACL_3_MBPS_MODE)
+ ENHANCED_INQUIRY_SCAN = (1 << LmpFeature.ENHANCED_INQUIRY_SCAN)
+ INTERLACED_INQUIRY_SCAN = (1 << LmpFeature.INTERLACED_INQUIRY_SCAN)
+ INTERLACED_PAGE_SCAN = (1 << LmpFeature.INTERLACED_PAGE_SCAN)
+ RSSI_WITH_INQUIRY_RESULTS = (1 << LmpFeature.RSSI_WITH_INQUIRY_RESULTS)
+ EXTENDED_SCO_LINK_EV3_PACKETS = (1 << LmpFeature.EXTENDED_SCO_LINK_EV3_PACKETS)
+ EV4_PACKETS = (1 << LmpFeature.EV4_PACKETS)
+ EV5_PACKETS = (1 << LmpFeature.EV5_PACKETS)
+ # RESERVED_FOR_FUTURE_USE = (1 << LmpFeature.RESERVED_FOR_FUTURE_USE)
+ AFH_CAPABLE_PERIPHERAL = (1 << LmpFeature.AFH_CAPABLE_PERIPHERAL)
+ AFH_CLASSIFICATION_PERIPHERAL = (1 << LmpFeature.AFH_CLASSIFICATION_PERIPHERAL)
+ BR_EDR_NOT_SUPPORTED = (1 << LmpFeature.BR_EDR_NOT_SUPPORTED)
+ LE_SUPPORTED_CONTROLLER = (1 << LmpFeature.LE_SUPPORTED_CONTROLLER)
+ LMP_3_SLOT_ENHANCED_DATA_RATE_ACL_PACKETS = (1 << LmpFeature.LMP_3_SLOT_ENHANCED_DATA_RATE_ACL_PACKETS)
+ LMP_5_SLOT_ENHANCED_DATA_RATE_ACL_PACKETS = (1 << LmpFeature.LMP_5_SLOT_ENHANCED_DATA_RATE_ACL_PACKETS)
+ SNIFF_SUBRATING = (1 << LmpFeature.SNIFF_SUBRATING)
+ PAUSE_ENCRYPTION = (1 << LmpFeature.PAUSE_ENCRYPTION)
+ AFH_CAPABLE_CENTRAL = (1 << LmpFeature.AFH_CAPABLE_CENTRAL)
+ AFH_CLASSIFICATION_CENTRAL = (1 << LmpFeature.AFH_CLASSIFICATION_CENTRAL)
+ ENHANCED_DATA_RATE_ESCO_2_MBPS_MODE = (1 << LmpFeature.ENHANCED_DATA_RATE_ESCO_2_MBPS_MODE)
+ ENHANCED_DATA_RATE_ESCO_3_MBPS_MODE = (1 << LmpFeature.ENHANCED_DATA_RATE_ESCO_3_MBPS_MODE)
+ LMP_3_SLOT_ENHANCED_DATA_RATE_ESCO_PACKETS = (1 << LmpFeature.LMP_3_SLOT_ENHANCED_DATA_RATE_ESCO_PACKETS)
+ EXTENDED_INQUIRY_RESPONSE = (1 << LmpFeature.EXTENDED_INQUIRY_RESPONSE)
+ SIMULTANEOUS_LE_AND_BR_EDR_TO_SAME_DEVICE_CAPABLE_CONTROLLER = (1 << LmpFeature.SIMULTANEOUS_LE_AND_BR_EDR_TO_SAME_DEVICE_CAPABLE_CONTROLLER)
+ # RESERVED_FOR_FUTURE_USE = (1 << LmpFeature.RESERVED_FOR_FUTURE_USE)
+ SECURE_SIMPLE_PAIRING_CONTROLLER_SUPPORT = (1 << LmpFeature.SECURE_SIMPLE_PAIRING_CONTROLLER_SUPPORT)
+ ENCAPSULATED_PDU = (1 << LmpFeature.ENCAPSULATED_PDU)
+ ERRONEOUS_DATA_REPORTING = (1 << LmpFeature.ERRONEOUS_DATA_REPORTING)
+ NON_FLUSHABLE_PACKET_BOUNDARY_FLAG = (1 << LmpFeature.NON_FLUSHABLE_PACKET_BOUNDARY_FLAG)
+ # RESERVED_FOR_FUTURE_USE = (1 << LmpFeature.RESERVED_FOR_FUTURE_USE)
+ HCI_LINK_SUPERVISION_TIMEOUT_CHANGED_EVENT = (1 << LmpFeature.HCI_LINK_SUPERVISION_TIMEOUT_CHANGED_EVENT)
+ VARIABLE_INQUIRY_TX_POWER_LEVEL = (1 << LmpFeature.VARIABLE_INQUIRY_TX_POWER_LEVEL)
+ ENHANCED_POWER_CONTROL = (1 << LmpFeature.ENHANCED_POWER_CONTROL)
+ # RESERVED_FOR_FUTURE_USE = (1 << LmpFeature.RESERVED_FOR_FUTURE_USE)
+ # RESERVED_FOR_FUTURE_USE = (1 << LmpFeature.RESERVED_FOR_FUTURE_USE)
+ # RESERVED_FOR_FUTURE_USE = (1 << LmpFeature.RESERVED_FOR_FUTURE_USE)
+ # RESERVED_FOR_FUTURE_USE = (1 << LmpFeature.RESERVED_FOR_FUTURE_USE)
+ EXTENDED_FEATURES = (1 << LmpFeature.EXTENDED_FEATURES)
+
+ # Page 1
+ SECURE_SIMPLE_PAIRING_HOST_SUPPORT = (1 << LmpFeature.SECURE_SIMPLE_PAIRING_HOST_SUPPORT)
+ LE_SUPPORTED_HOST = (1 << LmpFeature.LE_SUPPORTED_HOST)
+ # PREVIOUSLY_USED = (1 << LmpFeature.PREVIOUSLY_USED)
+ SECURE_CONNECTIONS_HOST_SUPPORT = (1 << LmpFeature.SECURE_CONNECTIONS_HOST_SUPPORT)
+
+ # Page 2
+ CONNECTIONLESS_PERIPHERAL_BROADCAST_TRANSMITTER_OPERATION = (1 << LmpFeature.CONNECTIONLESS_PERIPHERAL_BROADCAST_TRANSMITTER_OPERATION)
+ CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVER_OPERATION = (1 << LmpFeature.CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVER_OPERATION)
+ SYNCHRONIZATION_TRAIN = (1 << LmpFeature.SYNCHRONIZATION_TRAIN)
+ SYNCHRONIZATION_SCAN = (1 << LmpFeature.SYNCHRONIZATION_SCAN)
+ HCI_INQUIRY_RESPONSE_NOTIFICATION_EVENT = (1 << LmpFeature.HCI_INQUIRY_RESPONSE_NOTIFICATION_EVENT)
+ GENERALIZED_INTERLACED_SCAN = (1 << LmpFeature.GENERALIZED_INTERLACED_SCAN)
+ COARSE_CLOCK_ADJUSTMENT = (1 << LmpFeature.COARSE_CLOCK_ADJUSTMENT)
+ RESERVED_FOR_FUTURE_USE = (1 << LmpFeature.RESERVED_FOR_FUTURE_USE)
+ SECURE_CONNECTIONS_CONTROLLER_SUPPORT = (1 << LmpFeature.SECURE_CONNECTIONS_CONTROLLER_SUPPORT)
+ PING = (1 << LmpFeature.PING)
+ SLOT_AVAILABILITY_MASK = (1 << LmpFeature.SLOT_AVAILABILITY_MASK)
+ TRAIN_NUDGING = (1 << LmpFeature.TRAIN_NUDGING)
+
# fmt: on
# pylint: enable=line-too-long
@@ -1379,6 +1380,45 @@ HCI_LE_SUPPORTED_FEATURES_NAMES = {
STATUS_SPEC = {'size': 1, 'mapper': lambda x: HCI_Constant.status_name(x)}
+class CodecID(enum.IntEnum):
+ # fmt: off
+ U_LOG = 0x00
+ A_LOG = 0x01
+ CVSD = 0x02
+ TRANSPARENT = 0x03
+ LINEAR_PCM = 0x04
+ MSBC = 0x05
+ LC3 = 0x06
+ G729A = 0x07
+ VENDOR_SPECIFIC = 0xFF
+
+
+@dataclasses.dataclass(frozen=True)
+class CodingFormat:
+ codec_id: CodecID
+ company_id: int = 0
+ vendor_specific_codec_id: int = 0
+
+ @classmethod
+ def parse_from_bytes(cls, data: bytes, offset: int):
+ (codec_id, company_id, vendor_specific_codec_id) = struct.unpack_from(
+ '<BHH', data, offset
+ )
+ return offset + 5, cls(
+ codec_id=CodecID(codec_id),
+ company_id=company_id,
+ vendor_specific_codec_id=vendor_specific_codec_id,
+ )
+
+ def to_bytes(self) -> bytes:
+ return struct.pack(
+ '<BHH', self.codec_id, self.company_id, self.vendor_specific_codec_id
+ )
+
+ def __bytes__(self) -> bytes:
+ return self.to_bytes()
+
+
# -----------------------------------------------------------------------------
class HCI_Constant:
@staticmethod
@@ -1474,6 +1514,12 @@ class HCI_Object:
# The rest of the bytes
field_value = data[offset:]
return (field_value, len(field_value))
+ if field_type == 'v':
+ # Variable-length bytes field, with 1-byte length at the beginning
+ field_length = data[offset]
+ offset += 1
+ field_value = data[offset : offset + field_length]
+ return (field_value, field_length + 1)
if field_type == 1:
# 8-bit unsigned
return (data[offset], 1)
@@ -1578,6 +1624,11 @@ class HCI_Object:
raise ValueError('value too large for *-typed field')
else:
field_bytes = bytes(field_value)
+ elif field_type == 'v':
+ # Variable-length bytes field, with 1-byte length at the beginning
+ field_bytes = bytes(field_value)
+ field_length = len(field_bytes)
+ field_bytes = bytes([field_length]) + field_bytes
elif isinstance(field_value, (bytes, bytearray)) or hasattr(
field_value, 'to_bytes'
):
@@ -1792,6 +1843,43 @@ class Address:
address_type = data[offset - 1]
return Address.parse_address_with_type(data, offset, address_type)
+ @classmethod
+ def generate_static_address(cls) -> Address:
+ '''Generates Random Static Address, with the 2 most significant bits of 0b11.
+
+ See Bluetooth spec, Vol 6, Part B - Table 1.2.
+ '''
+ address_bytes = secrets.token_bytes(6)
+ address_bytes = address_bytes[:5] + bytes([address_bytes[5] | 0b11000000])
+ return Address(
+ address=address_bytes, address_type=Address.RANDOM_DEVICE_ADDRESS
+ )
+
+ @classmethod
+ def generate_private_address(cls, irk: bytes = b'') -> Address:
+ '''Generates Random Private MAC Address.
+
+ If IRK is present, a Resolvable Private Address, with the 2 most significant
+ bits of 0b01 will be generated. Otherwise, a Non-resolvable Private Address,
+ with the 2 most significant bits of 0b00 will be generated.
+
+ See Bluetooth spec, Vol 6, Part B - Table 1.2.
+
+ Args:
+ irk: Local Identity Resolving Key(IRK), in little-endian. If not set, a
+ non-resolvable address will be generated.
+ '''
+ if irk:
+ prand = crypto.generate_prand()
+ address_bytes = crypto.ah(irk, prand) + prand
+ else:
+ address_bytes = secrets.token_bytes(6)
+ address_bytes = address_bytes[:5] + bytes([address_bytes[5] & 0b00111111])
+
+ return Address(
+ address=address_bytes, address_type=Address.RANDOM_DEVICE_ADDRESS
+ )
+
def __init__(
self, address: Union[bytes, str], address_type: int = RANDOM_DEVICE_ADDRESS
):
@@ -1885,26 +1973,28 @@ 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:
+class OwnAddressType(enum.IntEnum):
PUBLIC = 0
RANDOM = 1
RESOLVABLE_OR_PUBLIC = 2
RESOLVABLE_OR_RANDOM = 3
- TYPE_NAMES = {
- PUBLIC: 'PUBLIC',
- RANDOM: 'RANDOM',
- RESOLVABLE_OR_PUBLIC: 'RESOLVABLE_OR_PUBLIC',
- RESOLVABLE_OR_RANDOM: 'RESOLVABLE_OR_RANDOM',
- }
+ @classmethod
+ def type_spec(cls):
+ return {'size': 1, 'mapper': lambda x: OwnAddressType(x).name}
- @staticmethod
- def type_name(type_id):
- return name_or_number(OwnAddressType.TYPE_NAMES, type_id)
- # pylint: disable-next=unnecessary-lambda
- TYPE_SPEC = {'size': 1, 'mapper': lambda x: OwnAddressType.type_name(x)}
+# -----------------------------------------------------------------------------
+class LoopbackMode(enum.IntEnum):
+ DISABLED = 0
+ LOCAL = 1
+ REMOTE = 2
+
+ @classmethod
+ def type_spec(cls):
+ return {'size': 1, 'mapper': lambda x: LoopbackMode(x).name}
# -----------------------------------------------------------------------------
@@ -1925,9 +2015,15 @@ class HCI_Packet:
if packet_type == HCI_ACL_DATA_PACKET:
return HCI_AclDataPacket.from_bytes(packet)
+ if packet_type == HCI_SYNCHRONOUS_DATA_PACKET:
+ return HCI_SynchronousDataPacket.from_bytes(packet)
+
if packet_type == HCI_EVENT_PACKET:
return HCI_Event.from_bytes(packet)
+ if packet_type == HCI_ISO_DATA_PACKET:
+ return HCI_IsoDataPacket.from_bytes(packet)
+
return HCI_CustomPacket(packet)
def __init__(self, name):
@@ -1960,6 +2056,7 @@ class HCI_Command(HCI_Packet):
hci_packet_type = HCI_COMMAND_PACKET
command_names: Dict[int, str] = {}
command_classes: Dict[int, Type[HCI_Command]] = {}
+ op_code: int
@staticmethod
def command(fields=(), return_parameters_fields=()):
@@ -2045,7 +2142,11 @@ class HCI_Command(HCI_Packet):
return_parameters.fields = cls.return_parameters_fields
return return_parameters
- def __init__(self, op_code, parameters=None, **kwargs):
+ def __init__(self, op_code=-1, parameters=None, **kwargs):
+ # Since the legacy implementation relies on an __init__ injector, typing always
+ # complains that positional argument op_code is not passed, so here sets a
+ # default value to allow building derived HCI_Command without op_code.
+ assert op_code != -1
super().__init__(HCI_Command.command_name(op_code))
if (fields := getattr(self, 'fields', None)) and kwargs:
HCI_Object.init_from_fields(self, fields, kwargs)
@@ -2297,6 +2398,19 @@ class HCI_Read_Clock_Offset_Command(HCI_Command):
@HCI_Command.command(
fields=[
('bd_addr', Address.parse_address),
+ ('reason', {'size': 1, 'mapper': HCI_Constant.error_name}),
+ ],
+)
+class HCI_Reject_Synchronous_Connection_Request_Command(HCI_Command):
+ '''
+ See Bluetooth spec @ 7.1.28 Reject Synchronous Connection Request Command
+ '''
+
+
+# -----------------------------------------------------------------------------
+@HCI_Command.command(
+ fields=[
+ ('bd_addr', Address.parse_address),
('io_capability', {'size': 1, 'mapper': HCI_Constant.io_capability_name}),
('oob_data_present', 1),
(
@@ -2426,14 +2540,14 @@ class HCI_IO_Capability_Request_Negative_Reply_Command(HCI_Command):
('connection_handle', 2),
('transmit_bandwidth', 4),
('receive_bandwidth', 4),
- ('transmit_coding_format', 5),
- ('receive_coding_format', 5),
+ ('transmit_coding_format', CodingFormat.parse_from_bytes),
+ ('receive_coding_format', CodingFormat.parse_from_bytes),
('transmit_codec_frame_size', 2),
('receive_codec_frame_size', 2),
('input_bandwidth', 4),
('output_bandwidth', 4),
- ('input_coding_format', 5),
- ('output_coding_format', 5),
+ ('input_coding_format', CodingFormat.parse_from_bytes),
+ ('output_coding_format', CodingFormat.parse_from_bytes),
('input_coded_data_size', 2),
('output_coded_data_size', 2),
('input_pcm_data_format', 1),
@@ -2454,6 +2568,35 @@ class HCI_Enhanced_Setup_Synchronous_Connection_Command(HCI_Command):
See Bluetooth spec @ 7.1.45 Enhanced Setup Synchronous Connection Command
'''
+ class PcmDataFormat(enum.IntEnum):
+ NA = 0x00
+ ONES_COMPLEMENT = 0x01
+ TWOS_COMPLEMENT = 0x02
+ SIGN_MAGNITUDE = 0x03
+ UNSIGNED = 0x04
+
+ class DataPath(enum.IntEnum):
+ HCI = 0x00
+ PCM = 0x01
+
+ class RetransmissionEffort(enum.IntEnum):
+ NO_RETRANSMISSION = 0x00
+ OPTIMIZE_FOR_POWER = 0x01
+ OPTIMIZE_FOR_QUALITY = 0x02
+ DONT_CARE = 0xFF
+
+ class PacketType(enum.IntFlag):
+ HV1 = 0x0001
+ HV2 = 0x0002
+ HV3 = 0x0004
+ EV3 = 0x0008
+ EV4 = 0x0010
+ EV5 = 0x0020
+ NO_2_EV3 = 0x0040
+ NO_3_EV3 = 0x0080
+ NO_2_EV5 = 0x0100
+ NO_3_EV5 = 0x0200
+
# -----------------------------------------------------------------------------
@HCI_Command.command(
@@ -2461,14 +2604,14 @@ class HCI_Enhanced_Setup_Synchronous_Connection_Command(HCI_Command):
('bd_addr', Address.parse_address),
('transmit_bandwidth', 4),
('receive_bandwidth', 4),
- ('transmit_coding_format', 5),
- ('receive_coding_format', 5),
+ ('transmit_coding_format', CodingFormat.parse_from_bytes),
+ ('receive_coding_format', CodingFormat.parse_from_bytes),
('transmit_codec_frame_size', 2),
('receive_codec_frame_size', 2),
('input_bandwidth', 4),
('output_bandwidth', 4),
- ('input_coding_format', 5),
- ('output_coding_format', 5),
+ ('input_coding_format', CodingFormat.parse_from_bytes),
+ ('output_coding_format', CodingFormat.parse_from_bytes),
('input_coded_data_size', 2),
('output_coded_data_size', 2),
('input_pcm_data_format', 1),
@@ -2685,6 +2828,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()
@@ -3094,7 +3251,12 @@ class HCI_Read_Local_Supported_Commands_Command(HCI_Command):
# -----------------------------------------------------------------------------
-@HCI_Command.command()
+@HCI_Command.command(
+ return_parameters_fields=[
+ ('status', STATUS_SPEC),
+ ('lmp_features', 8),
+ ]
+)
class HCI_Read_Local_Supported_Features_Command(HCI_Command):
'''
See Bluetooth spec @ 7.4.3 Read Local Supported Features Command
@@ -3181,12 +3343,47 @@ class HCI_Read_Encryption_Key_Size_Command(HCI_Command):
# -----------------------------------------------------------------------------
+@HCI_Command.command(
+ return_parameters_fields=[
+ ('status', STATUS_SPEC),
+ ('loopback_mode', LoopbackMode.type_spec()),
+ ],
+)
+class HCI_Read_Loopback_Mode_Command(HCI_Command):
+ '''
+ See Bluetooth spec @ 7.6.1 Read Loopback Mode Command
+ '''
+
+
+# -----------------------------------------------------------------------------
+@HCI_Command.command([('loopback_mode', 1)])
+class HCI_Write_Loopback_Mode_Command(HCI_Command):
+ '''
+ See Bluetooth spec @ 7.6.2 Write Loopback Mode Command
+ '''
+
+
+# -----------------------------------------------------------------------------
@HCI_Command.command([('le_event_mask', 8)])
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(
@@ -3244,7 +3441,7 @@ class HCI_LE_Set_Random_Address_Command(HCI_Command):
),
},
),
- ('own_address_type', OwnAddressType.TYPE_SPEC),
+ ('own_address_type', OwnAddressType.type_spec()),
('peer_address_type', Address.ADDRESS_TYPE_SPEC),
('peer_address', Address.parse_address_preceded_by_type),
('advertising_channel_map', 1),
@@ -3337,7 +3534,7 @@ class HCI_LE_Set_Advertising_Enable_Command(HCI_Command):
('le_scan_type', 1),
('le_scan_interval', 2),
('le_scan_window', 2),
- ('own_address_type', OwnAddressType.TYPE_SPEC),
+ ('own_address_type', OwnAddressType.type_spec()),
('scanning_filter_policy', 1),
]
)
@@ -3376,7 +3573,7 @@ class HCI_LE_Set_Scan_Enable_Command(HCI_Command):
('initiator_filter_policy', 1),
('peer_address_type', Address.ADDRESS_TYPE_SPEC),
('peer_address', Address.parse_address_preceded_by_type),
- ('own_address_type', OwnAddressType.TYPE_SPEC),
+ ('own_address_type', OwnAddressType.type_spec()),
('connection_interval_min', 2),
('connection_interval_max', 2),
('max_latency', 2),
@@ -3765,8 +3962,10 @@ class HCI_LE_Set_Advertising_Set_Random_Address_Command(HCI_Command):
'advertising_event_properties',
{
'size': 2,
- 'mapper': lambda x: HCI_LE_Set_Extended_Advertising_Parameters_Command.advertising_properties_string(
- x
+ 'mapper': lambda x: str(
+ HCI_LE_Set_Extended_Advertising_Parameters_Command.AdvertisingProperties(
+ x
+ )
),
},
),
@@ -3776,12 +3975,12 @@ class HCI_LE_Set_Advertising_Set_Random_Address_Command(HCI_Command):
'primary_advertising_channel_map',
{
'size': 1,
- 'mapper': lambda x: HCI_LE_Set_Extended_Advertising_Parameters_Command.channel_map_string(
- x
+ 'mapper': lambda x: str(
+ HCI_LE_Set_Extended_Advertising_Parameters_Command.ChannelMap(x)
),
},
),
- ('own_address_type', OwnAddressType.TYPE_SPEC),
+ ('own_address_type', OwnAddressType.type_spec()),
('peer_address_type', Address.ADDRESS_TYPE_SPEC),
('peer_address', Address.parse_address_preceded_by_type),
('advertising_filter_policy', 1),
@@ -3792,45 +3991,43 @@ 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
'''
- CONNECTABLE_ADVERTISING = 0
- SCANNABLE_ADVERTISING = 1
- DIRECTED_ADVERTISING = 2
- HIGH_DUTY_CYCLE_DIRECTED_CONNECTABLE_ADVERTISING = 3
- USE_LEGACY_ADVERTISING_PDUS = 4
- ANONYMOUS_ADVERTISING = 5
- INCLUDE_TX_POWER = 6
-
- ADVERTISING_PROPERTIES_NAMES = (
- 'CONNECTABLE_ADVERTISING',
- 'SCANNABLE_ADVERTISING',
- 'DIRECTED_ADVERTISING',
- 'HIGH_DUTY_CYCLE_DIRECTED_CONNECTABLE_ADVERTISING',
- 'USE_LEGACY_ADVERTISING_PDUS',
- 'ANONYMOUS_ADVERTISING',
- 'INCLUDE_TX_POWER',
- )
+ TX_POWER_NO_PREFERENCE = 0x7F
+ SHOULD_NOT_FRAGMENT = 0x01
- CHANNEL_37 = 0
- CHANNEL_38 = 1
- CHANNEL_39 = 2
+ class AdvertisingProperties(enum.IntFlag):
+ CONNECTABLE_ADVERTISING = 1 << 0
+ SCANNABLE_ADVERTISING = 1 << 1
+ DIRECTED_ADVERTISING = 1 << 2
+ HIGH_DUTY_CYCLE_DIRECTED_CONNECTABLE_ADVERTISING = 1 << 3
+ USE_LEGACY_ADVERTISING_PDUS = 1 << 4
+ ANONYMOUS_ADVERTISING = 1 << 5
+ INCLUDE_TX_POWER = 1 << 6
- CHANNEL_NAMES = ('37', '38', '39')
+ def __str__(self) -> str:
+ return '|'.join(
+ flag.name
+ for flag in HCI_LE_Set_Extended_Advertising_Parameters_Command.AdvertisingProperties
+ if self.value & flag.value and flag.name is not None
+ )
- @classmethod
- def advertising_properties_string(cls, properties):
- # pylint: disable=line-too-long
- return f'[{",".join(bit_flags_to_strings(properties, cls.ADVERTISING_PROPERTIES_NAMES))}]'
+ class ChannelMap(enum.IntFlag):
+ CHANNEL_37 = 1 << 0
+ CHANNEL_38 = 1 << 1
+ CHANNEL_39 = 1 << 2
- @classmethod
- def channel_map_string(cls, channel_map):
- return f'[{",".join(bit_flags_to_strings(channel_map, cls.CHANNEL_NAMES))}]'
+ def __str__(self) -> str:
+ return '|'.join(
+ flag.name
+ for flag in HCI_LE_Set_Extended_Advertising_Parameters_Command.ChannelMap
+ if self.value & flag.value and flag.name is not None
+ )
# -----------------------------------------------------------------------------
@@ -3842,9 +4039,9 @@ class HCI_LE_Set_Extended_Advertising_Parameters_Command(HCI_Command):
'operation',
{
'size': 1,
- 'mapper': lambda x: HCI_LE_Set_Extended_Advertising_Data_Command.operation_name(
+ 'mapper': lambda x: HCI_LE_Set_Extended_Advertising_Data_Command.Operation(
x
- ),
+ ).name,
},
),
('fragment_preference', 1),
@@ -3862,23 +4059,12 @@ class HCI_LE_Set_Extended_Advertising_Data_Command(HCI_Command):
See Bluetooth spec @ 7.8.54 LE Set Extended Advertising Data Command
'''
- INTERMEDIATE_FRAGMENT = 0x00
- FIRST_FRAGMENT = 0x01
- LAST_FRAGMENT = 0x02
- COMPLETE_DATA = 0x03
- UNCHANGED_DATA = 0x04
-
- OPERATION_NAMES = {
- INTERMEDIATE_FRAGMENT: 'INTERMEDIATE_FRAGMENT',
- FIRST_FRAGMENT: 'FIRST_FRAGMENT',
- LAST_FRAGMENT: 'LAST_FRAGMENT',
- COMPLETE_DATA: 'COMPLETE_DATA',
- UNCHANGED_DATA: 'UNCHANGED_DATA',
- }
-
- @classmethod
- def operation_name(cls, operation):
- return name_or_number(cls.OPERATION_NAMES, operation)
+ class Operation(enum.IntEnum):
+ INTERMEDIATE_FRAGMENT = 0x00
+ FIRST_FRAGMENT = 0x01
+ LAST_FRAGMENT = 0x02
+ COMPLETE_DATA = 0x03
+ UNCHANGED_DATA = 0x04
# -----------------------------------------------------------------------------
@@ -3890,9 +4076,9 @@ class HCI_LE_Set_Extended_Advertising_Data_Command(HCI_Command):
'operation',
{
'size': 1,
- 'mapper': lambda x: HCI_LE_Set_Extended_Advertising_Data_Command.operation_name(
+ 'mapper': lambda x: HCI_LE_Set_Extended_Advertising_Data_Command.Operation(
x
- ),
+ ).name,
},
),
('fragment_preference', 1),
@@ -3910,22 +4096,6 @@ class HCI_LE_Set_Extended_Scan_Response_Data_Command(HCI_Command):
See Bluetooth spec @ 7.8.55 LE Set Extended Scan Response Data Command
'''
- INTERMEDIATE_FRAGMENT = 0x00
- FIRST_FRAGMENT = 0x01
- LAST_FRAGMENT = 0x02
- COMPLETE_DATA = 0x03
-
- OPERATION_NAMES = {
- INTERMEDIATE_FRAGMENT: 'INTERMEDIATE_FRAGMENT',
- FIRST_FRAGMENT: 'FIRST_FRAGMENT',
- LAST_FRAGMENT: 'LAST_FRAGMENT',
- COMPLETE_DATA: 'COMPLETE_DATA',
- }
-
- @classmethod
- def operation_name(cls, operation):
- return name_or_number(cls.OPERATION_NAMES, operation)
-
# -----------------------------------------------------------------------------
@HCI_Command.command(
@@ -4075,7 +4245,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: ',
@@ -4209,7 +4379,7 @@ class HCI_LE_Extended_Create_Connection_Command(HCI_Command):
('initiator_filter_policy:', self.initiator_filter_policy),
(
'own_address_type: ',
- OwnAddressType.type_name(self.own_address_type),
+ OwnAddressType(self.own_address_type).name,
),
(
'peer_address_type: ',
@@ -4218,7 +4388,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: ',
@@ -4324,6 +4494,166 @@ class HCI_LE_Set_Host_Feature_Command(HCI_Command):
# -----------------------------------------------------------------------------
+@HCI_Command.command(
+ fields=[
+ ('cig_id', 1),
+ ('sdu_interval_c_to_p', 3),
+ ('sdu_interval_p_to_c', 3),
+ ('worst_case_sca', 1),
+ ('packing', 1),
+ ('framing', 1),
+ ('max_transport_latency_c_to_p', 2),
+ ('max_transport_latency_p_to_c', 2),
+ [
+ ('cis_id', 1),
+ ('max_sdu_c_to_p', 2),
+ ('max_sdu_p_to_c', 2),
+ ('phy_c_to_p', 1),
+ ('phy_p_to_c', 1),
+ ('rtn_c_to_p', 1),
+ ('rtn_p_to_c', 1),
+ ],
+ ],
+ return_parameters_fields=[
+ ('status', STATUS_SPEC),
+ ('cig_id', 1),
+ [('connection_handle', 2)],
+ ],
+)
+class HCI_LE_Set_CIG_Parameters_Command(HCI_Command):
+ '''
+ See Bluetooth spec @ 7.8.97 LE Set CIG Parameters Command
+ '''
+
+ cig_id: int
+ sdu_interval_c_to_p: int
+ sdu_interval_p_to_c: int
+ worst_case_sca: int
+ packing: int
+ framing: int
+ max_transport_latency_c_to_p: int
+ max_transport_latency_p_to_c: int
+ cis_id: List[int]
+ max_sdu_c_to_p: List[int]
+ max_sdu_p_to_c: List[int]
+ phy_c_to_p: List[int]
+ phy_p_to_c: List[int]
+ rtn_c_to_p: List[int]
+ rtn_p_to_c: List[int]
+
+
+# -----------------------------------------------------------------------------
+@HCI_Command.command(
+ fields=[
+ [
+ ('cis_connection_handle', 2),
+ ('acl_connection_handle', 2),
+ ],
+ ],
+)
+class HCI_LE_Create_CIS_Command(HCI_Command):
+ '''
+ See Bluetooth spec @ 7.8.99 LE Create CIS command
+ '''
+
+ cis_connection_handle: List[int]
+ acl_connection_handle: List[int]
+
+
+# -----------------------------------------------------------------------------
+@HCI_Command.command(
+ fields=[('cig_id', 1)],
+ return_parameters_fields=[('status', STATUS_SPEC), ('cig_id', 1)],
+)
+class HCI_LE_Remove_CIG_Command(HCI_Command):
+ '''
+ See Bluetooth spec @ 7.8.100 LE Remove CIG command
+ '''
+
+ cig_id: int
+
+
+# -----------------------------------------------------------------------------
+@HCI_Command.command(
+ fields=[('connection_handle', 2)],
+)
+class HCI_LE_Accept_CIS_Request_Command(HCI_Command):
+ '''
+ See Bluetooth spec @ 7.8.101 LE Accept CIS Request command
+ '''
+
+ connection_handle: int
+
+
+# -----------------------------------------------------------------------------
+@HCI_Command.command(
+ fields=[
+ ('connection_handle', 2),
+ ('reason', {'size': 1, 'mapper': HCI_Constant.error_name}),
+ ],
+)
+class HCI_LE_Reject_CIS_Request_Command(HCI_Command):
+ '''
+ See Bluetooth spec @ 7.8.102 LE Reject CIS Request command
+ '''
+
+ connection_handle: int
+ reason: int
+
+
+# -----------------------------------------------------------------------------
+@HCI_Command.command(
+ fields=[
+ ('connection_handle', 2),
+ ('data_path_direction', 1),
+ ('data_path_id', 1),
+ ('codec_id', CodingFormat.parse_from_bytes),
+ ('controller_delay', 3),
+ ('codec_configuration', 'v'),
+ ],
+ return_parameters_fields=[
+ ('status', STATUS_SPEC),
+ ('connection_handle', 2),
+ ],
+)
+class HCI_LE_Setup_ISO_Data_Path_Command(HCI_Command):
+ '''
+ See Bluetooth spec @ 7.8.109 LE Setup ISO Data Path command
+ '''
+
+ class Direction(enum.IntEnum):
+ HOST_TO_CONTROLLER = 0x00
+ CONTROLLER_TO_HOST = 0x01
+
+ connection_handle: int
+ data_path_direction: int
+ data_path_id: int
+ codec_id: CodingFormat
+ controller_delay: int
+ codec_configuration: bytes
+
+
+# -----------------------------------------------------------------------------
+@HCI_Command.command(
+ fields=[
+ ('connection_handle', 2),
+ ('data_path_direction', 1),
+ ],
+ return_parameters_fields=[
+ ('status', STATUS_SPEC),
+ ('connection_handle', 2),
+ ],
+)
+class HCI_LE_Remove_ISO_Data_Path_Command(HCI_Command):
+ '''
+ See Bluetooth spec @ 7.8.110 LE Remove ISO Data Path command
+ '''
+
+ connection_handle: int
+ data_path_direction: int
+
+
+# -----------------------------------------------------------------------------
# HCI Events
# -----------------------------------------------------------------------------
class HCI_Event(HCI_Packet):
@@ -4431,7 +4761,11 @@ class HCI_Event(HCI_Packet):
HCI_Object.init_from_bytes(self, parameters, 0, fields)
return self
- def __init__(self, event_code, parameters=None, **kwargs):
+ def __init__(self, event_code=-1, parameters=None, **kwargs):
+ # Since the legacy implementation relies on an __init__ injector, typing always
+ # complains that positional argument event_code is not passed, so here sets a
+ # default value to allow building derived HCI_Event without event_code.
+ assert event_code != -1
super().__init__(HCI_Event.event_name(event_code))
if (fields := getattr(self, 'fields', None)) and kwargs:
HCI_Object.init_from_fields(self, fields, kwargs)
@@ -4525,7 +4859,8 @@ class HCI_Extended_Event(HCI_Event):
HCI_Object.init_from_bytes(self, parameters, 1, fields)
return self
- def __init__(self, subevent_code, parameters, **kwargs):
+ def __init__(self, subevent_code=None, parameters=None, **kwargs):
+ assert subevent_code is not None
self.subevent_code = subevent_code
if parameters is None and (fields := getattr(self, 'fields', None)) and kwargs:
parameters = bytes([subevent_code]) + HCI_Object.dict_to_bytes(
@@ -4935,6 +5270,21 @@ HCI_LE_Meta_Event.subevent_classes[
# -----------------------------------------------------------------------------
+@HCI_LE_Meta_Event.event(
+ [
+ ('status', 1),
+ ('advertising_handle', 1),
+ ('connection_handle', 2),
+ ('num_completed_extended_advertising_events', 1),
+ ]
+)
+class HCI_LE_Advertising_Set_Terminated_Event(HCI_LE_Meta_Event):
+ '''
+ See Bluetooth spec @ 7.7.65.18 LE Advertising Set Terminated Event
+ '''
+
+
+# -----------------------------------------------------------------------------
@HCI_LE_Meta_Event.event([('connection_handle', 2), ('channel_selection_algorithm', 1)])
class HCI_LE_Channel_Selection_Algorithm_Event(HCI_LE_Meta_Event):
'''
@@ -4943,6 +5293,48 @@ class HCI_LE_Channel_Selection_Algorithm_Event(HCI_LE_Meta_Event):
# -----------------------------------------------------------------------------
+@HCI_LE_Meta_Event.event(
+ [
+ ('status', STATUS_SPEC),
+ ('connection_handle', 2),
+ ('cig_sync_delay', 3),
+ ('cis_sync_delay', 3),
+ ('transport_latency_c_to_p', 3),
+ ('transport_latency_p_to_c', 3),
+ ('phy_c_to_p', 1),
+ ('phy_p_to_c', 1),
+ ('nse', 1),
+ ('bn_c_to_p', 1),
+ ('bn_p_to_c', 1),
+ ('ft_c_to_p', 1),
+ ('ft_p_to_c', 1),
+ ('max_pdu_c_to_p', 2),
+ ('max_pdu_p_to_c', 2),
+ ('iso_interval', 2),
+ ]
+)
+class HCI_LE_CIS_Established_Event(HCI_LE_Meta_Event):
+ '''
+ See Bluetooth spec @ 7.7.65.25 LE CIS Established Event
+ '''
+
+
+# -----------------------------------------------------------------------------
+@HCI_LE_Meta_Event.event(
+ [
+ ('acl_connection_handle', 2),
+ ('cis_connection_handle', 2),
+ ('cig_id', 1),
+ ('cis_id', 1),
+ ]
+)
+class HCI_LE_CIS_Request_Event(HCI_LE_Meta_Event):
+ '''
+ See Bluetooth spec @ 7.7.65.26 LE CIS Request Event
+ '''
+
+
+# -----------------------------------------------------------------------------
@HCI_Event.event([('status', STATUS_SPEC)])
class HCI_Inquiry_Complete_Event(HCI_Event):
'''
@@ -5068,6 +5460,10 @@ class HCI_Disconnection_Complete_Event(HCI_Event):
See Bluetooth spec @ 7.7.5 Disconnection Complete Event
'''
+ status: int
+ connection_handle: int
+ reason: int
+
# -----------------------------------------------------------------------------
@HCI_Event.event([('status', STATUS_SPEC), ('connection_handle', 2)])
@@ -5739,6 +6135,168 @@ class HCI_AclDataPacket(HCI_Packet):
# -----------------------------------------------------------------------------
+class HCI_SynchronousDataPacket(HCI_Packet):
+ '''
+ See Bluetooth spec @ 5.4.3 HCI SCO Data Packets
+ '''
+
+ hci_packet_type = HCI_SYNCHRONOUS_DATA_PACKET
+
+ @staticmethod
+ def from_bytes(packet: bytes) -> HCI_SynchronousDataPacket:
+ # Read the header
+ h, data_total_length = struct.unpack_from('<HB', packet, 1)
+ connection_handle = h & 0xFFF
+ packet_status = (h >> 12) & 0b11
+ data = packet[4:]
+ if len(data) != data_total_length:
+ raise ValueError(
+ f'invalid packet length {len(data)} != {data_total_length}'
+ )
+ return HCI_SynchronousDataPacket(
+ connection_handle, packet_status, data_total_length, data
+ )
+
+ def to_bytes(self) -> bytes:
+ h = (self.packet_status << 12) | self.connection_handle
+ return (
+ struct.pack('<BHB', HCI_SYNCHRONOUS_DATA_PACKET, h, self.data_total_length)
+ + self.data
+ )
+
+ def __init__(
+ self,
+ connection_handle: int,
+ packet_status: int,
+ data_total_length: int,
+ data: bytes,
+ ) -> None:
+ self.connection_handle = connection_handle
+ self.packet_status = packet_status
+ self.data_total_length = data_total_length
+ self.data = data
+
+ def __bytes__(self) -> bytes:
+ return self.to_bytes()
+
+ def __str__(self) -> str:
+ return (
+ f'{color("SCO", "blue")}: '
+ f'handle=0x{self.connection_handle:04x}, '
+ f'ps={self.packet_status}, '
+ f'data_total_length={self.data_total_length}, '
+ f'data={self.data.hex()}'
+ )
+
+
+# -----------------------------------------------------------------------------
+class HCI_IsoDataPacket(HCI_Packet):
+ '''
+ See Bluetooth spec @ 5.4.5 HCI ISO Data Packets
+ '''
+
+ hci_packet_type = HCI_ISO_DATA_PACKET
+
+ @staticmethod
+ def from_bytes(packet: bytes) -> HCI_IsoDataPacket:
+ time_stamp: Optional[int] = None
+ packet_sequence_number: Optional[int] = None
+ iso_sdu_length: Optional[int] = None
+ packet_status_flag: Optional[int] = None
+
+ pos = 1
+ pdu_info, data_total_length = struct.unpack_from('<HH', packet, pos)
+ connection_handle = pdu_info & 0xFFF
+ pb_flag = (pdu_info >> 12) & 0b11
+ ts_flag = (pdu_info >> 14) & 0b01
+ pos += 4
+
+ # pb_flag in (0b00, 0b10) but faster
+ should_include_sdu_info = not (pb_flag & 0b01)
+
+ if ts_flag:
+ if not should_include_sdu_info:
+ logger.warning(f'Timestamp included when pb_flag={bin(pb_flag)}')
+ time_stamp, *_ = struct.unpack_from('<I', packet, pos)
+ pos += 4
+
+ if should_include_sdu_info:
+ packet_sequence_number, sdu_info = struct.unpack_from('<HH', packet, pos)
+ iso_sdu_length = sdu_info & 0xFFF
+ packet_status_flag = sdu_info >> 14
+ pos += 4
+
+ iso_sdu_fragment = packet[pos:]
+ return HCI_IsoDataPacket(
+ connection_handle=connection_handle,
+ pb_flag=pb_flag,
+ ts_flag=ts_flag,
+ data_total_length=data_total_length,
+ time_stamp=time_stamp,
+ packet_sequence_number=packet_sequence_number,
+ iso_sdu_length=iso_sdu_length,
+ packet_status_flag=packet_status_flag,
+ iso_sdu_fragment=iso_sdu_fragment,
+ )
+
+ def __init__(
+ self,
+ connection_handle: int,
+ pb_flag: int,
+ ts_flag: int,
+ data_total_length: int,
+ time_stamp: Optional[int],
+ packet_sequence_number: Optional[int],
+ iso_sdu_length: Optional[int],
+ packet_status_flag: Optional[int],
+ iso_sdu_fragment: bytes,
+ ) -> None:
+ self.connection_handle = connection_handle
+ self.pb_flag = pb_flag
+ self.ts_flag = ts_flag
+ self.data_total_length = data_total_length
+ self.time_stamp = time_stamp
+ self.packet_sequence_number = packet_sequence_number
+ self.iso_sdu_length = iso_sdu_length
+ self.packet_status_flag = packet_status_flag
+ self.iso_sdu_fragment = iso_sdu_fragment
+
+ def __bytes__(self) -> bytes:
+ return self.to_bytes()
+
+ def to_bytes(self) -> bytes:
+ fmt = '<BHH'
+ args = [
+ HCI_ISO_DATA_PACKET,
+ self.ts_flag << 14 | self.pb_flag << 12 | self.connection_handle,
+ self.data_total_length,
+ ]
+ if self.time_stamp is not None:
+ fmt += 'I'
+ args.append(self.time_stamp)
+ if (
+ self.packet_sequence_number is not None
+ and self.iso_sdu_length is not None
+ and self.packet_status_flag is not None
+ ):
+ fmt += 'HH'
+ args += [
+ self.packet_sequence_number,
+ self.iso_sdu_length | self.packet_status_flag << 14,
+ ]
+ return struct.pack(fmt, *args) + self.iso_sdu_fragment
+
+ def __str__(self) -> str:
+ return (
+ f'{color("ISO", "blue")}: '
+ f'handle=0x{self.connection_handle:04x}, '
+ f'ps={self.packet_status_flag}, '
+ f'data_total_length={self.data_total_length}, '
+ f'sdu={self.iso_sdu_fragment.hex()}'
+ )
+
+
+# -----------------------------------------------------------------------------
class HCI_AclDataPacketAssembler:
current_data: Optional[bytes]
@@ -5771,7 +6329,7 @@ class HCI_AclDataPacketAssembler:
self.current_data = None
self.l2cap_pdu_length = 0
else:
- # Sanity check
+ # Compliance check
if len(self.current_data) > self.l2cap_pdu_length + 4:
logger.warning('!!! ACL data exceeds L2CAP PDU')
self.current_data = None