# Copyright 2021-2022 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ----------------------------------------------------------------------------- # Imports # ----------------------------------------------------------------------------- import struct import collections import logging import functools from colors import color from .core import ( BT_BR_EDR_TRANSPORT, AdvertisingData, DeviceClass, ProtocolError, bit_flags_to_strings, name_or_number, padded_bytes, ) # ----------------------------------------------------------------------------- # Logging # ----------------------------------------------------------------------------- logger = logging.getLogger(__name__) # ----------------------------------------------------------------------------- # Utils # ----------------------------------------------------------------------------- def hci_command_op_code(ogf, ocf): return ogf << 10 | ocf def key_with_value(dictionary, target_value): for key, value in dictionary.items(): if value == target_value: return key return None def indent_lines(string): return '\n'.join([' ' + line for line in string.split('\n')]) def map_null_terminated_utf8_string(utf8_bytes): try: terminator = utf8_bytes.find(0) if terminator < 0: return utf8_bytes return utf8_bytes[0:terminator].decode('utf8') except UnicodeDecodeError: return utf8_bytes def map_class_of_device(class_of_device): ( service_classes, major_device_class, minor_device_class, ) = DeviceClass.split_class_of_device(class_of_device) return ( f'[{class_of_device:06X}] Services(' f'{",".join(DeviceClass.service_class_labels(service_classes))}),' f'Class({DeviceClass.major_device_class_name(major_device_class)}|' f'{DeviceClass.minor_device_class_name(major_device_class, minor_device_class)}' ')' ) def phy_list_to_bits(phys): if phys is None: return 0 phy_bits = 0 for phy in phys: if phy not in HCI_LE_PHY_TYPE_TO_BIT: raise ValueError('invalid PHY') phy_bits |= 1 << HCI_LE_PHY_TYPE_TO_BIT[phy] return phy_bits # ----------------------------------------------------------------------------- # Constants # ----------------------------------------------------------------------------- # fmt: off # pylint: disable=line-too-long # HCI Version HCI_VERSION_BLUETOOTH_CORE_1_0B = 0 HCI_VERSION_BLUETOOTH_CORE_1_1 = 1 HCI_VERSION_BLUETOOTH_CORE_1_2 = 2 HCI_VERSION_BLUETOOTH_CORE_2_0_EDR = 3 HCI_VERSION_BLUETOOTH_CORE_2_1_EDR = 4 HCI_VERSION_BLUETOOTH_CORE_3_0_HS = 5 HCI_VERSION_BLUETOOTH_CORE_4_0 = 6 HCI_VERSION_BLUETOOTH_CORE_4_1 = 7 HCI_VERSION_BLUETOOTH_CORE_4_2 = 8 HCI_VERSION_BLUETOOTH_CORE_5_0 = 9 HCI_VERSION_BLUETOOTH_CORE_5_1 = 10 HCI_VERSION_BLUETOOTH_CORE_5_2 = 11 HCI_VERSION_BLUETOOTH_CORE_5_3 = 12 HCI_VERSION_NAMES = { HCI_VERSION_BLUETOOTH_CORE_1_0B: 'HCI_VERSION_BLUETOOTH_CORE_1_0B', HCI_VERSION_BLUETOOTH_CORE_1_1: 'HCI_VERSION_BLUETOOTH_CORE_1_1', HCI_VERSION_BLUETOOTH_CORE_1_2: 'HCI_VERSION_BLUETOOTH_CORE_1_2', HCI_VERSION_BLUETOOTH_CORE_2_0_EDR: 'HCI_VERSION_BLUETOOTH_CORE_2_0_EDR', HCI_VERSION_BLUETOOTH_CORE_2_1_EDR: 'HCI_VERSION_BLUETOOTH_CORE_2_1_EDR', HCI_VERSION_BLUETOOTH_CORE_3_0_HS: 'HCI_VERSION_BLUETOOTH_CORE_3_0_HS', HCI_VERSION_BLUETOOTH_CORE_4_0: 'HCI_VERSION_BLUETOOTH_CORE_4_0', HCI_VERSION_BLUETOOTH_CORE_4_1: 'HCI_VERSION_BLUETOOTH_CORE_4_1', HCI_VERSION_BLUETOOTH_CORE_4_2: 'HCI_VERSION_BLUETOOTH_CORE_4_2', HCI_VERSION_BLUETOOTH_CORE_5_0: 'HCI_VERSION_BLUETOOTH_CORE_5_0', HCI_VERSION_BLUETOOTH_CORE_5_1: 'HCI_VERSION_BLUETOOTH_CORE_5_1', HCI_VERSION_BLUETOOTH_CORE_5_2: 'HCI_VERSION_BLUETOOTH_CORE_5_2', HCI_VERSION_BLUETOOTH_CORE_5_3: 'HCI_VERSION_BLUETOOTH_CORE_5_3' } # LMP Version LMP_VERSION_NAMES = HCI_VERSION_NAMES # HCI Packet types HCI_COMMAND_PACKET = 0x01 HCI_ACL_DATA_PACKET = 0x02 HCI_SYNCHRONOUS_DATA_PACKET = 0x03 HCI_EVENT_PACKET = 0x04 # HCI Event Codes HCI_INQUIRY_COMPLETE_EVENT = 0x01 HCI_INQUIRY_RESULT_EVENT = 0x02 HCI_CONNECTION_COMPLETE_EVENT = 0x03 HCI_CONNECTION_REQUEST_EVENT = 0x04 HCI_DISCONNECTION_COMPLETE_EVENT = 0x05 HCI_AUTHENTICATION_COMPLETE_EVENT = 0x06 HCI_REMOTE_NAME_REQUEST_COMPLETE_EVENT = 0x07 HCI_ENCRYPTION_CHANGE_EVENT = 0x08 HCI_CHANGE_CONNECTION_LINK_KEY_COMPLETE_EVENT = 0x09 HCI_LINK_KEY_TYPE_CHANGED_EVENT = 0x0A HCI_READ_REMOTE_SUPPORTED_FEATURES_COMPLETE_EVENT = 0x0B HCI_READ_REMOTE_VERSION_INFORMATION_COMPLETE_EVENT = 0x0C HCI_QOS_SETUP_COMPLETE_EVENT = 0x0D HCI_COMMAND_COMPLETE_EVENT = 0x0E HCI_COMMAND_STATUS_EVENT = 0x0F HCI_HARDWARE_ERROR_EVENT = 0x10 HCI_FLUSH_OCCURRED_EVENT = 0x11 HCI_ROLE_CHANGE_EVENT = 0x12 HCI_NUMBER_OF_COMPLETED_PACKETS_EVENT = 0x13 HCI_MODE_CHANGE_EVENT = 0x14 HCI_RETURN_LINK_KEYS_EVENT = 0x15 HCI_PIN_CODE_REQUEST_EVENT = 0x16 HCI_LINK_KEY_REQUEST_EVENT = 0x17 HCI_LINK_KEY_NOTIFICATION_EVENT = 0x18 HCI_LOOPBACK_COMMAND_EVENT = 0x19 HCI_DATA_BUFFER_OVERFLOW_EVENT = 0x1A HCI_MAX_SLOTS_CHANGE_EVENT = 0x1B HCI_READ_CLOCK_OFFSET_COMPLETE_EVENT = 0x1C HCI_CONNECTION_PACKET_TYPE_CHANGED_EVENT = 0x1D HCI_QOS_VIOLATION_EVENT = 0x1E HCI_PAGE_SCAN_REPETITION_MODE_CHANGE_EVENT = 0x20 HCI_FLOW_SPECIFICATION_COMPLETE_EVENT = 0x21 HCI_INQUIRY_RESULT_WITH_RSSI_EVENT = 0x22 HCI_READ_REMOTE_EXTENDED_FEATURES_COMPLETE_EVENT = 0x23 HCI_SYNCHRONOUS_CONNECTION_COMPLETE_EVENT = 0x2C HCI_SYNCHRONOUS_CONNECTION_CHANGED_EVENT = 0x2D HCI_SNIFF_SUBRATING_EVENT = 0x2E HCI_EXTENDED_INQUIRY_RESULT_EVENT = 0x2F HCI_ENCRYPTION_KEY_REFRESH_COMPLETE_EVENT = 0x30 HCI_IO_CAPABILITY_REQUEST_EVENT = 0x31 HCI_IO_CAPABILITY_RESPONSE_EVENT = 0x32 HCI_USER_CONFIRMATION_REQUEST_EVENT = 0x33 HCI_USER_PASSKEY_REQUEST_EVENT = 0x34 HCI_REMOTE_OOB_DATA_REQUEST = 0x35 HCI_SIMPLE_PAIRING_COMPLETE_EVENT = 0x36 HCI_LINK_SUPERVISION_TIMEOUT_CHANGED_EVENT = 0x38 HCI_ENHANCED_FLUSH_COMPLETE_EVENT = 0x39 HCI_USER_PASSKEY_NOTIFICATION_EVENT = 0x3B HCI_KEYPRESS_NOTIFICATION_EVENT = 0x3C HCI_REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION_EVENT = 0x3D HCI_LE_META_EVENT = 0x3E HCI_NUMBER_OF_COMPLETED_DATA_BLOCKS_EVENT = 0x48 HCI_TRIGGERED_CLOCK_CAPTURE_EVENT = 0X4E HCI_SYNCHRONIZATION_TRAIN_COMPLETE_EVENT = 0X4F HCI_SYNCHRONIZATION_TRAIN_RECEIVED_EVENT = 0X50 HCI_CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVE_EVENT = 0X51 HCI_CONNECTIONLESS_PERIPHERAL_BROADCAST_TIMEOUT_EVENT = 0X52 HCI_TRUNCATED_PAGE_COMPLETE_EVENT = 0X53 HCI_PERIPHERAL_PAGE_RESPONSE_TIMEOUT_EVENT = 0X54 HCI_CONNECTIONLESS_PERIPHERAL_BROADCAST_CHANNEL_MAP_CHANGE_EVENT = 0X55 HCI_INQUIRY_RESPONSE_NOTIFICATION_EVENT = 0X56 HCI_AUTHENTICATED_PAYLOAD_TIMEOUT_EXPIRED_EVENT = 0X57 HCI_SAM_STATUS_CHANGE_EVENT = 0X58 HCI_EVENT_NAMES = { event_code: event_name for (event_name, event_code) in globals().items() if event_name.startswith('HCI_') and event_name.endswith('_EVENT') } # 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_SUBEVENT_NAMES = { event_code: event_name for (event_name, event_code) in globals().items() if event_name.startswith('HCI_LE_') and event_name.endswith('_EVENT') and event_code != HCI_LE_META_EVENT } # HCI Command HCI_INQUIRY_COMMAND = hci_command_op_code(0x01, 0x0001) HCI_INQUIRY_CANCEL_COMMAND = hci_command_op_code(0x01, 0x0002) HCI_PERIODIC_INQUIRY_MODE_COMMAND = hci_command_op_code(0x01, 0x0003) HCI_EXIT_PERIODIC_INQUIRY_MODE_COMMAND = hci_command_op_code(0x01, 0x0004) HCI_CREATE_CONNECTION_COMMAND = hci_command_op_code(0x01, 0x0005) HCI_DISCONNECT_COMMAND = hci_command_op_code(0x01, 0x0006) HCI_CREATE_CONNECTION_CANCEL_COMMAND = hci_command_op_code(0x01, 0x0008) HCI_ACCEPT_CONNECTION_REQUEST_COMMAND = hci_command_op_code(0x01, 0x0009) HCI_REJECT_CONNECTION_REQUEST_COMMAND = hci_command_op_code(0x01, 0x000A) HCI_LINK_KEY_REQUEST_REPLY_COMMAND = hci_command_op_code(0x01, 0x000B) HCI_LINK_KEY_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x01, 0x000C) HCI_PIN_CODE_REQUEST_REPLY_COMMAND = hci_command_op_code(0x01, 0x000D) HCI_PIN_CODE_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x01, 0x000E) HCI_CHANGE_CONNECTION_PACKET_TYPE_COMMAND = hci_command_op_code(0x01, 0x000F) HCI_AUTHENTICATION_REQUESTED_COMMAND = hci_command_op_code(0x01, 0x0011) HCI_SET_CONNECTION_ENCRYPTION_COMMAND = hci_command_op_code(0x01, 0x0013) HCI_CHANGE_CONNECTION_LINK_KEY_COMMAND = hci_command_op_code(0x01, 0x0015) HCI_LINK_KEY_SELECTION_COMMAND = hci_command_op_code(0x01, 0x0017) HCI_REMOTE_NAME_REQUEST_COMMAND = hci_command_op_code(0x01, 0x0019) HCI_REMOTE_NAME_REQUEST_CANCEL_COMMAND = hci_command_op_code(0x01, 0x001A) HCI_READ_REMOTE_SUPPORTED_FEATURES_COMMAND = hci_command_op_code(0x01, 0x001B) HCI_READ_REMOTE_EXTENDED_FEATURES_COMMAND = hci_command_op_code(0x01, 0x001C) HCI_READ_REMOTE_VERSION_INFORMATION_COMMAND = hci_command_op_code(0x01, 0x001D) HCI_READ_CLOCK_OFFSET_COMMAND = hci_command_op_code(0x01, 0x001F) HCI_READ_LMP_HANDLE_COMMAND = hci_command_op_code(0x01, 0x0020) HCI_SETUP_SYNCHRONOUS_CONNECTION_COMMAND = hci_command_op_code(0x01, 0x0028) HCI_ACCEPT_SYNCHRONOUS_CONNECTION_REQUEST_COMMAND = hci_command_op_code(0x01, 0x0029) HCI_REJECT_SYNCHRONOUS_CONNECTION_REQUEST_COMMAND = hci_command_op_code(0x01, 0x002A) HCI_IO_CAPABILITY_REQUEST_REPLY_COMMAND = hci_command_op_code(0x01, 0x002B) HCI_USER_CONFIRMATION_REQUEST_REPLY_COMMAND = hci_command_op_code(0x01, 0x002C) HCI_USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x01, 0x002D) HCI_USER_PASSKEY_REQUEST_REPLY_COMMAND = hci_command_op_code(0x01, 0x002E) HCI_USER_PASSKEY_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x01, 0x002F) HCI_REMOTE_OOB_DATA_REQUEST_REPLY_COMMAND = hci_command_op_code(0x01, 0x0030) HCI_REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x01, 0x0033) HCI_IO_CAPABILITY_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x01, 0x0034) HCI_ENHANCED_SETUP_SYNCHRONOUS_CONNECTION_COMMAND = hci_command_op_code(0x01, 0x003D) HCI_ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION_REQUEST_COMMAND = hci_command_op_code(0x01, 0x003E) HCI_TRUNCATED_PAGE_COMMAND = hci_command_op_code(0x01, 0x003F) HCI_TRUNCATED_PAGE_CANCEL_COMMAND = hci_command_op_code(0x01, 0x0040) HCI_SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_COMMAND = hci_command_op_code(0x01, 0x0041) HCI_SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVE_COMMAND = hci_command_op_code(0x01, 0x0042) HCI_START_SYNCHRONIZATION_TRAIN_COMMAND = hci_command_op_code(0x01, 0x0043) HCI_RECEIVE_SYNCHRONIZATION_TRAIN_COMMAND = hci_command_op_code(0x01, 0x0044) HCI_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_COMMAND = hci_command_op_code(0x01, 0x0045) HCI_HOLD_MODE_COMMAND = hci_command_op_code(0x02, 0x0001) HCI_SNIFF_MODE_COMMAND = hci_command_op_code(0x02, 0x0003) HCI_EXIT_SNIFF_MODE_COMMAND = hci_command_op_code(0x02, 0x0004) HCI_QOS_SETUP_COMMAND = hci_command_op_code(0x02, 0x0007) HCI_ROLE_DISCOVERY_COMMAND = hci_command_op_code(0x02, 0x0009) HCI_SWITCH_ROLE_COMMAND = hci_command_op_code(0x02, 0x000B) HCI_READ_LINK_POLICY_SETTINGS_COMMAND = hci_command_op_code(0x02, 0x000C) HCI_WRITE_LINK_POLICY_SETTINGS_COMMAND = hci_command_op_code(0x02, 0x000D) HCI_READ_DEFAULT_LINK_POLICY_SETTINGS_COMMAND = hci_command_op_code(0x02, 0x000E) HCI_WRITE_DEFAULT_LINK_POLICY_SETTINGS_COMMAND = hci_command_op_code(0x02, 0x000F) HCI_FLOW_SPECIFICATION_COMMAND = hci_command_op_code(0x02, 0x0010) HCI_SNIFF_SUBRATING_COMMAND = hci_command_op_code(0x02, 0x0011) HCI_SET_EVENT_MASK_COMMAND = hci_command_op_code(0x03, 0x0001) HCI_RESET_COMMAND = hci_command_op_code(0x03, 0x0003) HCI_SET_EVENT_FILTER_COMMAND = hci_command_op_code(0x03, 0x0005) HCI_FLUSH_COMMAND = hci_command_op_code(0x03, 0x0008) HCI_READ_PIN_TYPE_COMMAND = hci_command_op_code(0x03, 0x0009) HCI_WRITE_PIN_TYPE_COMMAND = hci_command_op_code(0x03, 0x000A) HCI_READ_STORED_LINK_KEY_COMMAND = hci_command_op_code(0x03, 0x000D) HCI_WRITE_STORED_LINK_KEY_COMMAND = hci_command_op_code(0x03, 0x0011) HCI_DELETE_STORED_LINK_KEY_COMMAND = hci_command_op_code(0x03, 0x0012) HCI_WRITE_LOCAL_NAME_COMMAND = hci_command_op_code(0x03, 0x0013) HCI_READ_LOCAL_NAME_COMMAND = hci_command_op_code(0x03, 0x0014) HCI_READ_CONNECTION_ACCEPT_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x0015) HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x0016) HCI_READ_PAGE_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x0017) HCI_WRITE_PAGE_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x0018) HCI_READ_SCAN_ENABLE_COMMAND = hci_command_op_code(0x03, 0x0019) HCI_WRITE_SCAN_ENABLE_COMMAND = hci_command_op_code(0x03, 0x001A) HCI_READ_PAGE_SCAN_ACTIVITY_COMMAND = hci_command_op_code(0x03, 0x001B) HCI_WRITE_PAGE_SCAN_ACTIVITY_COMMAND = hci_command_op_code(0x03, 0x001C) HCI_READ_INQUIRY_SCAN_ACTIVITY_COMMAND = hci_command_op_code(0x03, 0x001D) HCI_WRITE_INQUIRY_SCAN_ACTIVITY_COMMAND = hci_command_op_code(0x03, 0x001E) HCI_READ_AUTHENTICATION_ENABLE_COMMAND = hci_command_op_code(0x03, 0x001F) HCI_WRITE_AUTHENTICATION_ENABLE_COMMAND = hci_command_op_code(0x03, 0x0020) HCI_READ_CLASS_OF_DEVICE_COMMAND = hci_command_op_code(0x03, 0x0023) HCI_WRITE_CLASS_OF_DEVICE_COMMAND = hci_command_op_code(0x03, 0x0024) HCI_READ_VOICE_SETTING_COMMAND = hci_command_op_code(0x03, 0x0025) HCI_WRITE_VOICE_SETTING_COMMAND = hci_command_op_code(0x03, 0x0026) HCI_READ_AUTOMATIC_FLUSH_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x0027) HCI_WRITE_AUTOMATIC_FLUSH_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x0028) HCI_READ_NUM_BROADCAST_RETRANSMISSIONS_COMMAND = hci_command_op_code(0x03, 0x0029) HCI_WRITE_NUM_BROADCAST_RETRANSMISSIONS_COMMAND = hci_command_op_code(0x03, 0x002A) HCI_READ_HOLD_MODE_ACTIVITY_COMMAND = hci_command_op_code(0x03, 0x002B) HCI_WRITE_HOLD_MODE_ACTIVITY_COMMAND = hci_command_op_code(0x03, 0x002C) HCI_READ_TRANSMIT_POWER_LEVEL_COMMAND = hci_command_op_code(0x03, 0x002D) HCI_READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE_COMMAND = hci_command_op_code(0x03, 0x002E) HCI_WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE_COMMAND = hci_command_op_code(0x03, 0x002F) HCI_SET_CONTROLLER_TO_HOST_FLOW_CONTROL_COMMAND = hci_command_op_code(0x03, 0x0031) HCI_HOST_BUFFER_SIZE_COMMAND = hci_command_op_code(0x03, 0x0033) HCI_HOST_NUMBER_OF_COMPLETED_PACKETS_COMMAND = hci_command_op_code(0x03, 0x0035) HCI_READ_LINK_SUPERVISION_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x0036) HCI_WRITE_LINK_SUPERVISION_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x0037) HCI_READ_NUMBER_OF_SUPPORTED_IAC_COMMAND = hci_command_op_code(0x03, 0x0038) HCI_READ_CURRENT_IAC_LAP_COMMAND = hci_command_op_code(0x03, 0x0039) HCI_WRITE_CURRENT_IAC_LAP_COMMAND = hci_command_op_code(0x03, 0x003A) HCI_SET_AFH_HOST_CHANNEL_CLASSIFICATION_COMMAND = hci_command_op_code(0x03, 0x003F) HCI_READ_INQUIRY_SCAN_TYPE_COMMAND = hci_command_op_code(0x03, 0x0042) HCI_WRITE_INQUIRY_SCAN_TYPE_COMMAND = hci_command_op_code(0x03, 0x0043) HCI_READ_INQUIRY_MODE_COMMAND = hci_command_op_code(0x03, 0x0044) HCI_WRITE_INQUIRY_MODE_COMMAND = hci_command_op_code(0x03, 0x0045) HCI_READ_PAGE_SCAN_TYPE_COMMAND = hci_command_op_code(0x03, 0x0046) HCI_WRITE_PAGE_SCAN_TYPE_COMMAND = hci_command_op_code(0x03, 0x0047) HCI_READ_AFH_CHANNEL_ASSESSMENT_MODE_COMMAND = hci_command_op_code(0x03, 0x0048) HCI_WRITE_AFH_CHANNEL_ASSESSMENT_MODE_COMMAND = hci_command_op_code(0x03, 0x0049) HCI_READ_EXTENDED_INQUIRY_RESPONSE_COMMAND = hci_command_op_code(0x03, 0x0051) HCI_WRITE_EXTENDED_INQUIRY_RESPONSE_COMMAND = hci_command_op_code(0x03, 0x0052) HCI_REFRESH_ENCRYPTION_KEY_COMMAND = hci_command_op_code(0x03, 0x0053) HCI_READ_SIMPLE_PAIRING_MODE_COMMAND = hci_command_op_code(0x03, 0x0055) HCI_WRITE_SIMPLE_PAIRING_MODE_COMMAND = hci_command_op_code(0x03, 0x0056) HCI_READ_LOCAL_OOB_DATA_COMMAND = hci_command_op_code(0x03, 0x0057) HCI_READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL_COMMAND = hci_command_op_code(0x03, 0x0058) HCI_WRITE_INQUIRY_TRANSMIT_POWER_LEVEL_COMMAND = hci_command_op_code(0x03, 0x0059) HCI_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_COMMAND = hci_command_op_code(0x03, 0x005A) HCI_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_COMMAND = hci_command_op_code(0x03, 0x005B) HCI_ENHANCED_FLUSH_COMMAND = hci_command_op_code(0x03, 0x005F) HCI_SEND_KEYPRESS_NOTIFICATION_COMMAND = hci_command_op_code(0x03, 0x0060) HCI_SET_EVENT_MASK_PAGE_2_COMMAND = hci_command_op_code(0x03, 0x0063) HCI_READ_FLOW_CONTROL_MODE_COMMAND = hci_command_op_code(0x03, 0x0066) HCI_WRITE_FLOW_CONTROL_MODE_COMMAND = hci_command_op_code(0x03, 0x0067) HCI_READ_ENHANCED_TRANSMIT_POWER_LEVEL_COMMAND = hci_command_op_code(0x03, 0x0068) HCI_READ_LE_HOST_SUPPORT_COMMAND = hci_command_op_code(0x03, 0x006C) HCI_WRITE_LE_HOST_SUPPORT_COMMAND = hci_command_op_code(0x03, 0x006D) HCI_SET_MWS_CHANNEL_PARAMETERS_COMMAND = hci_command_op_code(0x03, 0x006E) HCI_SET_EXTERNAL_FRAME_CONFIGURATION_COMMAND = hci_command_op_code(0x03, 0x006F) HCI_SET_MWS_SIGNALING_COMMAND = hci_command_op_code(0x03, 0x0070) HCI_SET_MWS_TRANSPORT_LAYER_COMMAND = hci_command_op_code(0x03, 0x0071) HCI_SET_MWS_SCAN_FREQUENCY_TABLE_COMMAND = hci_command_op_code(0x03, 0x0072) HCI_SET_MWS_PATTERN_CONFIGURATION_COMMAND = hci_command_op_code(0x03, 0x0073) HCI_SET_RESERVED_LT_ADDR_COMMAND = hci_command_op_code(0x03, 0x0074) HCI_DELETE_RESERVED_LT_ADDR_COMMAND = hci_command_op_code(0x03, 0x0075) HCI_SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_DATA_COMMAND = hci_command_op_code(0x03, 0x0076) HCI_READ_SYNCHRONIZATION_TRAIN_PARAMETERS_COMMAND = hci_command_op_code(0x03, 0x0077) HCI_WRITE_SYNCHRONIZATION_TRAIN_PARAMETERS_COMMAND = hci_command_op_code(0x03, 0x0078) HCI_READ_SECURE_CONNECTIONS_HOST_SUPPORT_COMMAND = hci_command_op_code(0x03, 0x0079) HCI_WRITE_SECURE_CONNECTIONS_HOST_SUPPORT_COMMAND = hci_command_op_code(0x03, 0x007A) HCI_READ_AUTHENTICATED_PAYLOAD_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x007B) HCI_WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x007C) HCI_READ_LOCAL_OOB_EXTENDED_DATA_COMMAND = hci_command_op_code(0x03, 0x007D) HCI_READ_EXTENDED_PAGE_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x007E) HCI_WRITE_EXTENDED_PAGE_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x007F) HCI_READ_EXTENDED_INQUIRY_LENGTH_COMMAND = hci_command_op_code(0x03, 0x0080) HCI_WRITE_EXTENDED_INQUIRY_LENGTH_COMMAND = hci_command_op_code(0x03, 0x0081) HCI_SET_ECOSYSTEM_BASE_INTERVAL_COMMAND = hci_command_op_code(0x03, 0x0082) HCI_CONFIGURE_DATA_PATH_COMMAND = hci_command_op_code(0x03, 0x0083) HCI_SET_MIN_ENCRYPTION_KEY_SIZE_COMMAND = hci_command_op_code(0x03, 0x0084) HCI_READ_LOCAL_VERSION_INFORMATION_COMMAND = hci_command_op_code(0x04, 0x0001) HCI_READ_LOCAL_SUPPORTED_COMMANDS_COMMAND = hci_command_op_code(0x04, 0x0002) HCI_READ_LOCAL_SUPPORTED_FEATURES_COMMAND = hci_command_op_code(0x04, 0x0003) HCI_READ_LOCAL_EXTENDED_FEATURES_COMMAND = hci_command_op_code(0x04, 0x0004) HCI_READ_BUFFER_SIZE_COMMAND = hci_command_op_code(0x04, 0x0005) HCI_READ_BD_ADDR_COMMAND = hci_command_op_code(0x04, 0x0009) HCI_READ_DATA_BLOCK_SIZE_COMMAND = hci_command_op_code(0x04, 0x000A) HCI_READ_LOCAL_SUPPORTED_CODECS_COMMAND = hci_command_op_code(0x04, 0x000B) HCI_READ_LOCAL_SIMPLE_PAIRING_OPTIONS_COMMAND = hci_command_op_code(0x04, 0x000C) HCI_READ_LOCAL_SUPPORTED_CODECS_V2_COMMAND = hci_command_op_code(0x04, 0x000D) HCI_READ_LOCAL_SUPPORTED_CODEC_CAPABILITIES_COMMAND = hci_command_op_code(0x04, 0x000E) HCI_READ_LOCAL_SUPPORTED_CONTROLLER_DELAY_COMMAND = hci_command_op_code(0x04, 0x000F) HCI_READ_FAILED_CONTACT_COUNTER_COMMAND = hci_command_op_code(0x05, 0x0001) HCI_RESET_FAILED_CONTACT_COUNTER_COMMAND = hci_command_op_code(0x05, 0x0002) HCI_READ_LINK_QUALITY_COMMAND = hci_command_op_code(0x05, 0x0003) HCI_READ_RSSI_COMMAND = hci_command_op_code(0x05, 0x0005) HCI_READ_AFH_CHANNEL_MAP_COMMAND = hci_command_op_code(0x05, 0x0006) HCI_READ_CLOCK_COMMAND = hci_command_op_code(0x05, 0x0007) HCI_READ_ENCRYPTION_KEY_SIZE_COMMAND = hci_command_op_code(0x05, 0x0008) HCI_GET_MWS_TRANSPORT_LAYER_CONFIGURATION_COMMAND = hci_command_op_code(0x05, 0x000C) HCI_SET_TRIGGERED_CLOCK_CAPTURE_COMMAND = hci_command_op_code(0x05, 0x000D) HCI_READ_LOOPBACK_MODE_COMMAND = hci_command_op_code(0x06, 0x0001) HCI_WRITE_LOOPBACK_MODE_COMMAND = hci_command_op_code(0x06, 0x0002) HCI_ENABLE_DEVICE_UNDER_TEST_MODE_COMMAND = hci_command_op_code(0x06, 0x0003) HCI_WRITE_SIMPLE_PAIRING_DEBUG_MODE_COMMAND = hci_command_op_code(0x06, 0x0004) HCI_WRITE_SECURE_CONNECTIONS_TEST_MODE_COMMAND = hci_command_op_code(0x06, 0x000A) HCI_LE_SET_EVENT_MASK_COMMAND = hci_command_op_code(0x08, 0x0001) HCI_LE_READ_BUFFER_SIZE_COMMAND = hci_command_op_code(0x08, 0x0002) HCI_LE_READ_LOCAL_SUPPORTED_FEATURES_COMMAND = hci_command_op_code(0x08, 0x0003) HCI_LE_SET_RANDOM_ADDRESS_COMMAND = hci_command_op_code(0x08, 0x0005) HCI_LE_SET_ADVERTISING_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0006) HCI_LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER_COMMAND = hci_command_op_code(0x08, 0x0007) HCI_LE_SET_ADVERTISING_DATA_COMMAND = hci_command_op_code(0x08, 0x0008) HCI_LE_SET_SCAN_RESPONSE_DATA_COMMAND = hci_command_op_code(0x08, 0x0009) HCI_LE_SET_ADVERTISING_ENABLE_COMMAND = hci_command_op_code(0x08, 0x000A) HCI_LE_SET_SCAN_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x000B) HCI_LE_SET_SCAN_ENABLE_COMMAND = hci_command_op_code(0x08, 0x000C) HCI_LE_CREATE_CONNECTION_COMMAND = hci_command_op_code(0x08, 0x000D) HCI_LE_CREATE_CONNECTION_CANCEL_COMMAND = hci_command_op_code(0x08, 0x000E) HCI_LE_READ_FILTER_ACCEPT_LIST_SIZE_COMMAND = hci_command_op_code(0x08, 0x000F) HCI_LE_CLEAR_FILTER_ACCEPT_LIST_COMMAND = hci_command_op_code(0x08, 0x0010) HCI_LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST_COMMAND = hci_command_op_code(0x08, 0x0011) HCI_LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST_COMMAND = hci_command_op_code(0x08, 0x0012) HCI_LE_CONNECTION_UPDATE_COMMAND = hci_command_op_code(0x08, 0x0013) HCI_LE_SET_HOST_CHANNEL_CLASSIFICATION_COMMAND = hci_command_op_code(0x08, 0x0014) HCI_LE_READ_CHANNEL_MAP_COMMAND = hci_command_op_code(0x08, 0x0015) HCI_LE_READ_REMOTE_FEATURES_COMMAND = hci_command_op_code(0x08, 0x0016) HCI_LE_ENCRYPT_COMMAND = hci_command_op_code(0x08, 0x0017) HCI_LE_RAND_COMMAND = hci_command_op_code(0x08, 0x0018) HCI_LE_ENABLE_ENCRYPTION_COMMAND = hci_command_op_code(0x08, 0x0019) HCI_LE_LONG_TERM_KEY_REQUEST_REPLY_COMMAND = hci_command_op_code(0x08, 0x001A) HCI_LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x08, 0x001B) HCI_LE_READ_SUPPORTED_STATES_COMMAND = hci_command_op_code(0x08, 0x001C) HCI_LE_RECEIVER_TEST_COMMAND = hci_command_op_code(0x08, 0x001D) HCI_LE_TRANSMITTER_TEST_COMMAND = hci_command_op_code(0x08, 0x001E) HCI_LE_TEST_END_COMMAND = hci_command_op_code(0x08, 0x001F) HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY_COMMAND = hci_command_op_code(0x08, 0x0020) HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x08, 0x0021) HCI_LE_SET_DATA_LENGTH_COMMAND = hci_command_op_code(0x08, 0x0022) HCI_LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH_COMMAND = hci_command_op_code(0x08, 0x0023) HCI_LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH_COMMAND = hci_command_op_code(0x08, 0x0024) HCI_LE_READ_LOCAL_P_256_PUBLIC_KEY_COMMAND = hci_command_op_code(0x08, 0x0025) HCI_LE_GENERATE_DHKEY_COMMAND = hci_command_op_code(0x08, 0x0026) HCI_LE_ADD_DEVICE_TO_RESOLVING_LIST_COMMAND = hci_command_op_code(0x08, 0x0027) HCI_LE_REMOVE_DEVICE_FROM_RESOLVING_LIST_COMMAND = hci_command_op_code(0x08, 0x0028) HCI_LE_CLEAR_RESOLVING_LIST_COMMAND = hci_command_op_code(0x08, 0x0029) HCI_LE_READ_RESOLVING_LIST_SIZE_COMMAND = hci_command_op_code(0x08, 0x002A) HCI_LE_READ_PEER_RESOLVABLE_ADDRESS_COMMAND = hci_command_op_code(0x08, 0x002B) HCI_LE_READ_LOCAL_RESOLVABLE_ADDRESS_COMMAND = hci_command_op_code(0x08, 0x002C) HCI_LE_SET_ADDRESS_RESOLUTION_ENABLE_COMMAND = hci_command_op_code(0x08, 0x002D) HCI_LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT_COMMAND = hci_command_op_code(0x08, 0x002E) HCI_LE_READ_MAXIMUM_DATA_LENGTH_COMMAND = hci_command_op_code(0x08, 0x002F) HCI_LE_READ_PHY_COMMAND = hci_command_op_code(0x08, 0x0030) HCI_LE_SET_DEFAULT_PHY_COMMAND = hci_command_op_code(0x08, 0x0031) HCI_LE_SET_PHY_COMMAND = hci_command_op_code(0x08, 0x0032) HCI_LE_RECEIVER_TEST_V2_COMMAND = hci_command_op_code(0x08, 0x0033) HCI_LE_TRANSMITTER_TEST_V2_COMMAND = hci_command_op_code(0x08, 0x0034) HCI_LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_COMMAND = hci_command_op_code(0x08, 0x0035) HCI_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0036) HCI_LE_SET_EXTENDED_ADVERTISING_DATA_COMMAND = hci_command_op_code(0x08, 0x0037) HCI_LE_SET_EXTENDED_SCAN_RESPONSE_DATA_COMMAND = hci_command_op_code(0x08, 0x0038) HCI_LE_SET_EXTENDED_ADVERTISING_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0039) HCI_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH_COMMAND = hci_command_op_code(0x08, 0x003A) HCI_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS_COMMAND = hci_command_op_code(0x08, 0x003B) HCI_LE_REMOVE_ADVERTISING_SET_COMMAND = hci_command_op_code(0x08, 0x003C) HCI_LE_CLEAR_ADVERTISING_SETS_COMMAND = hci_command_op_code(0x08, 0x003D) HCI_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x003E) HCI_LE_SET_PERIODIC_ADVERTISING_DATA_COMMAND = hci_command_op_code(0x08, 0x003F) HCI_LE_SET_PERIODIC_ADVERTISING_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0040) HCI_LE_SET_EXTENDED_SCAN_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0041) HCI_LE_SET_EXTENDED_SCAN_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0042) HCI_LE_EXTENDED_CREATE_CONNECTION_COMMAND = hci_command_op_code(0x08, 0x0043) HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC_COMMAND = hci_command_op_code(0x08, 0x0044) HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL_COMMAND = hci_command_op_code(0x08, 0x0045) HCI_LE_PERIODIC_ADVERTISING_TERMINATE_SYNC_COMMAND = hci_command_op_code(0x08, 0x0046) HCI_LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST_COMMAND = hci_command_op_code(0x08, 0x0047) HCI_LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST_COMMAND = hci_command_op_code(0x08, 0x0048) HCI_LE_CLEAR_PERIODIC_ADVERTISER_LIST_COMMAND = hci_command_op_code(0x08, 0x0049) HCI_LE_READ_PERIODIC_ADVERTISER_LIST_SIZE_COMMAND = hci_command_op_code(0x08, 0x004A) HCI_LE_READ_TRANSMIT_POWER_COMMAND = hci_command_op_code(0x08, 0x004B) HCI_LE_READ_RF_PATH_COMPENSATION_COMMAND = hci_command_op_code(0x08, 0x004C) HCI_LE_WRITE_RF_PATH_COMPENSATION_COMMAND = hci_command_op_code(0x08, 0x004D) HCI_LE_SET_PRIVACY_MODE_COMMAND = hci_command_op_code(0x08, 0x004E) HCI_LE_RECEIVER_TEST_V3_COMMAND = hci_command_op_code(0x08, 0x004F) HCI_LE_TRANSMITTER_TEST_V3_COMMAND = hci_command_op_code(0x08, 0x0050) HCI_LE_SET_CONNECTIONLESS_CTE_TRANSMIT_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0051) HCI_LE_SET_CONNECTIONLESS_CTE_TRANSMIT_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0052) HCI_LE_SET_CONNECTIONLESS_IQ_SAMPLING_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0053) HCI_LE_SET_CONNECTION_CTE_RECEIVE_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0054) HCI_LE_SET_CONNECTION_CTE_TRANSMIT_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0055) HCI_LE_CONNECTION_CTE_REQUEST_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0056) HCI_LE_CONNECTION_CTE_RESPONSE_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0057) HCI_LE_READ_ANTENNA_INFORMATION_COMMAND = hci_command_op_code(0x08, 0x0058) HCI_LE_SET_PERIODIC_ADVERTISING_RECEIVE_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0059) HCI_LE_PERIODIC_ADVERTISING_SYNC_TRANSFER_COMMAND = hci_command_op_code(0x08, 0x005A) HCI_LE_PERIODIC_ADVERTISING_SET_INFO_TRANSFER_COMMAND = hci_command_op_code(0x08, 0x005B) HCI_LE_SET_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x005C) HCI_LE_SET_DEFAULT_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x005D) HCI_LE_GENERATE_DHKEY_V2_COMMAND = hci_command_op_code(0x08, 0x005E) HCI_LE_MODIFY_SLEEP_CLOCK_ACCURACY_COMMAND = hci_command_op_code(0x08, 0x005F) HCI_LE_READ_BUFFER_SIZE_V2_COMMAND = hci_command_op_code(0x08, 0x0060) HCI_LE_READ_ISO_TX_SYNC_COMMAND = hci_command_op_code(0x08, 0x0061) HCI_LE_SET_CIG_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0062) HCI_LE_SET_CIG_PARAMETERS_TEST_COMMAND = hci_command_op_code(0x08, 0x0063) HCI_LE_CREATE_CIS_COMMAND = hci_command_op_code(0x08, 0x0064) HCI_LE_REMOVE_CIG_COMMAND = hci_command_op_code(0x08, 0x0065) HCI_LE_ACCEPT_CIS_REQUEST_COMMAND = hci_command_op_code(0x08, 0x0066) HCI_LE_REJECT_CIS_REQUEST_COMMAND = hci_command_op_code(0x08, 0x0067) HCI_LE_CREATE_BIG_COMMAND = hci_command_op_code(0x08, 0x0068) HCI_LE_CREATE_BIG_TEST_COMMAND = hci_command_op_code(0x08, 0x0069) HCI_LE_TERMINATE_BIG_COMMAND = hci_command_op_code(0x08, 0x006A) HCI_LE_BIG_CREATE_SYNC_COMMAND = hci_command_op_code(0x08, 0x006B) HCI_LE_BIG_TERMINATE_SYNC_COMMAND = hci_command_op_code(0x08, 0x006C) HCI_LE_REQUEST_PEER_SCA_COMMAND = hci_command_op_code(0x08, 0x006D) HCI_LE_SETUP_ISO_DATA_PATH_COMMAND = hci_command_op_code(0x08, 0x006E) HCI_LE_REMOVE_ISO_DATA_PATH_COMMAND = hci_command_op_code(0x08, 0x006F) HCI_LE_ISO_TRANSMIT_TEST_COMMAND = hci_command_op_code(0x08, 0x0070) HCI_LE_ISO_RECEIVE_TEST_COMMAND = hci_command_op_code(0x08, 0x0071) HCI_LE_ISO_READ_TEST_COUNTERS_COMMAND = hci_command_op_code(0x08, 0x0072) HCI_LE_ISO_TEST_END_COMMAND = hci_command_op_code(0x08, 0x0073) HCI_LE_SET_HOST_FEATURE_COMMAND = hci_command_op_code(0x08, 0x0074) HCI_LE_READ_ISO_LINK_QUALITY_COMMAND = hci_command_op_code(0x08, 0x0075) HCI_LE_ENHANCED_READ_TRANSMIT_POWER_LEVEL_COMMAND = hci_command_op_code(0x08, 0x0076) HCI_LE_READ_REMOTE_TRANSMIT_POWER_LEVEL_COMMAND = hci_command_op_code(0x08, 0x0077) HCI_LE_SET_PATH_LOSS_REPORTING_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0078) HCI_LE_SET_PATH_LOSS_REPORTING_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0079) HCI_LE_SET_TRANSMIT_POWER_REPORTING_ENABLE_COMMAND = hci_command_op_code(0x08, 0x007A) HCI_LE_TRANSMITTER_TEST_V4_COMMAND = hci_command_op_code(0x08, 0x007B) 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_COMMAND_NAMES = { command_code: command_name for (command_name, command_code) in globals().items() if command_name.startswith('HCI_') and command_name.endswith('_COMMAND') } # HCI Error Codes # See Bluetooth spec Vol 2, Part D - 1.3 LIST OF ERROR CODES HCI_SUCCESS = 0x00 HCI_UNKNOWN_HCI_COMMAND_ERROR = 0x01 HCI_UNKNOWN_CONNECTION_IDENTIFIER_ERROR = 0x02 HCI_HARDWARE_FAILURE_ERROR = 0x03 HCI_PAGE_TIMEOUT_ERROR = 0x04 HCI_AUTHENTICATION_FAILURE_ERROR = 0x05 HCI_PIN_OR_KEY_MISSING_ERROR = 0x06 HCI_MEMORY_CAPACITY_EXCEEDED_ERROR = 0x07 HCI_CONNECTION_TIMEOUT_ERROR = 0x08 HCI_CONNECTION_LIMIT_EXCEEDED_ERROR = 0x09 HCI_SYNCHRONOUS_CONNECTION_LIMIT_TO_A_DEVICE_EXCEEDED_ERROR = 0x0A HCI_CONNECTION_ALREADY_EXISTS_ERROR = 0x0B HCI_COMMAND_DISALLOWED_ERROR = 0x0C HCI_CONNECTION_REJECTED_DUE_TO_LIMITED_RESOURCES_ERROR = 0x0D HCI_CONNECTION_REJECTED_DUE_TO_SECURITY_REASONS_ERROR = 0x0E HCI_CONNECTION_REJECTED_DUE_TO_UNACCEPTABLE_BD_ADDR_ERROR = 0x0F HCI_CONNECTION_ACCEPT_TIMEOUT_ERROR = 0x10 HCI_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE_ERROR = 0x11 HCI_INVALID_HCI_COMMAND_PARAMETERS_ERROR = 0x12 HCI_REMOTE_USER_TERMINATED_CONNECTION_ERROR = 0x13 HCI_REMOTE_DEVICE_TERMINATED_CONNECTION_DUE_TO_LOW_RESOURCES_ERROR = 0x14 HCI_REMOTE_DEVICE_TERMINATED_CONNECTION_DUE_TO_POWER_OFF_ERROR = 0x15 HCI_CONNECTION_TERMINATED_BY_LOCAL_HOST_ERROR = 0x16 HCI_REPEATED_ATTEMPTS_ERROR = 0X17 HCI_PAIRING_NOT_ALLOWED_ERROR = 0X18 HCI_UNKNOWN_LMP_PDU_ERROR = 0X19 HCI_UNSUPPORTED_REMOTE_FEATURE_ERROR = 0X1A HCI_SCO_OFFSET_REJECTED_ERROR = 0X1B HCI_SCO_INTERVAL_REJECTED_ERROR = 0X1C HCI_SCO_AIR_MODE_REJECTED_ERROR = 0X1D HCI_INVALID_LMP_OR_LL_PARAMETERS_ERROR = 0X1E HCI_UNSPECIFIED_ERROR_ERROR = 0X1F HCI_UNSUPPORTED_LMP_OR_LL_PARAMETER_VALUE_ERROR = 0X20 HCI_ROLE_CHANGE_NOT_ALLOWED_ERROR = 0X21 HCI_LMP_OR_LL_RESPONSE_TIMEOUT_ERROR = 0X22 HCI_LMP_ERROR_TRANSACTION_COLLISION_OR_LL_PROCEDURE_COLLISION_ERROR = 0X23 HCI_LMP_PDU_NOT_ALLOWED_ERROR = 0X24 HCI_ENCRYPTION_MODE_NOT_ACCEPTABLE_ERROR = 0X25 HCI_LINK_KEY_CANNOT_BE_CHANGED_ERROR = 0X26 HCI_REQUESTED_QOS_NOT_SUPPORTED_ERROR = 0X27 HCI_INSTANT_PASSED_ERROR = 0X28 HCI_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED_ERROR = 0X29 HCI_DIFFERENT_TRANSACTION_COLLISION_ERROR = 0X2A HCI_RESERVED_FOR_FUTURE_USE = 0X2B HCI_QOS_UNACCEPTABLE_PARAMETER_ERROR = 0X2C HCI_QOS_REJECTED_ERROR = 0X2D HCI_CHANNEL_CLASSIFICATION_NOT_SUPPORTED_ERROR = 0X2E HCI_INSUFFICIENT_SECURITY_ERROR = 0X2F HCI_PARAMETER_OUT_OF_MANDATORY_RANGE_ERROR = 0X30 HCI_ROLE_SWITCH_PENDING_ERROR = 0X32 HCI_RESERVED_SLOT_VIOLATION_ERROR = 0X34 HCI_ROLE_SWITCH_FAILED_ERROR = 0X35 HCI_EXTENDED_INQUIRY_RESPONSE_TOO_LARGE_ERROR = 0X36 HCI_SECURE_SIMPLE_PAIRING_NOT_SUPPORTED_BY_HOST_ERROR = 0X37 HCI_HOST_BUSY_PAIRING_ERROR = 0X38 HCI_CONNECTION_REJECTED_DUE_TO_NO_SUITABLE_CHANNEL_FOUND_ERROR = 0X39 HCI_CONTROLLER_BUSY_ERROR = 0X3A HCI_UNACCEPTABLE_CONNECTION_PARAMETERS_ERROR = 0X3B HCI_ADVERTISING_TIMEOUT_ERROR = 0X3C HCI_CONNECTION_TERMINATED_DUE_TO_MIC_FAILURE_ERROR = 0X3D HCI_CONNECTION_FAILED_TO_BE_ESTABLISHED_ERROR = 0X3E HCI_COARSE_CLOCK_ADJUSTMENT_REJECTED_BUT_WILL_TRY_TO_ADJUST_USING_CLOCK_DRAGGING_ERROR = 0X40 HCI_TYPE0_SUBMAP_NOT_DEFINED_ERROR = 0X41 HCI_UNKNOWN_ADVERTISING_IDENTIFIER_ERROR = 0X42 HCI_LIMIT_REACHED_ERROR = 0X43 HCI_OPERATION_CANCELLED_BY_HOST_ERROR = 0X44 HCI_PACKET_TOO_LONG_ERROR = 0X45 HCI_ERROR_NAMES = { error_code: error_name for (error_name, error_code) in globals().items() if error_name.startswith('HCI_') and error_name.endswith('_ERROR') } 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 HCI_ACL_PB_CONTINUATION = 1 HCI_ACL_PB_FIRST_FLUSHABLE = 2 HCI_ACK_PB_COMPLETE_L2CAP = 3 # Roles HCI_CENTRAL_ROLE = 0 HCI_PERIPHERAL_ROLE = 1 HCI_ROLE_NAMES = { HCI_CENTRAL_ROLE: 'CENTRAL', HCI_PERIPHERAL_ROLE: 'PERIPHERAL' } # LE PHY Types HCI_LE_1M_PHY = 1 HCI_LE_2M_PHY = 2 HCI_LE_CODED_PHY = 3 HCI_LE_PHY_NAMES = { HCI_LE_1M_PHY: 'LE 1M', HCI_LE_2M_PHY: 'LE 2M', HCI_LE_CODED_PHY: 'LE Coded' } HCI_LE_1M_PHY_BIT = 0 HCI_LE_2M_PHY_BIT = 1 HCI_LE_CODED_PHY_BIT = 2 HCI_LE_PHY_BIT_NAMES = ['LE_1M_PHY', 'LE_2M_PHY', 'LE_CODED_PHY'] HCI_LE_PHY_TYPE_TO_BIT = { HCI_LE_1M_PHY: HCI_LE_1M_PHY_BIT, HCI_LE_2M_PHY: HCI_LE_2M_PHY_BIT, HCI_LE_CODED_PHY: HCI_LE_CODED_PHY_BIT } # Connection Parameters HCI_CONNECTION_INTERVAL_MS_PER_UNIT = 1.25 HCI_CONNECTION_LATENCY_MS_PER_UNIT = 1.25 HCI_SUPERVISION_TIMEOUT_MS_PER_UNIT = 10 # Inquiry LAP HCI_LIMITED_DEDICATED_INQUIRY_LAP = 0x9E8B00 HCI_GENERAL_INQUIRY_LAP = 0x9E8B33 HCI_INQUIRY_LAP_NAMES = { HCI_LIMITED_DEDICATED_INQUIRY_LAP: 'Limited Dedicated Inquiry', HCI_GENERAL_INQUIRY_LAP: 'General Inquiry' } # Inquiry Mode HCI_STANDARD_INQUIRY_MODE = 0x00 HCI_INQUIRY_WITH_RSSI_MODE = 0x01 HCI_EXTENDED_INQUIRY_MODE = 0x02 # Page Scan Repetition Mode HCI_R0_PAGE_SCAN_REPETITION_MODE = 0x00 HCI_R1_PAGE_SCAN_REPETITION_MODE = 0x01 HCI_R2_PAGE_SCAN_REPETITION_MODE = 0x02 # IO Capability HCI_DISPLAY_ONLY_IO_CAPABILITY = 0x00 HCI_DISPLAY_YES_NO_IO_CAPABILITY = 0x01 HCI_KEYBOARD_ONLY_IO_CAPABILITY = 0x02 HCI_NO_INPUT_NO_OUTPUT_IO_CAPABILITY = 0x03 HCI_IO_CAPABILITY_NAMES = { HCI_DISPLAY_ONLY_IO_CAPABILITY: 'HCI_DISPLAY_ONLY_IO_CAPABILITY', HCI_DISPLAY_YES_NO_IO_CAPABILITY: 'HCI_DISPLAY_YES_NO_IO_CAPABILITY', HCI_KEYBOARD_ONLY_IO_CAPABILITY: 'HCI_KEYBOARD_ONLY_IO_CAPABILITY', HCI_NO_INPUT_NO_OUTPUT_IO_CAPABILITY: 'HCI_NO_INPUT_NO_OUTPUT_IO_CAPABILITY' } # Authentication Requirements HCI_MITM_NOT_REQUIRED_NO_BONDING_AUTHENTICATION_REQUIREMENTS = 0x00 HCI_MITM_REQUIRED_NO_BONDING_AUTHENTICATION_REQUIREMENTS = 0x01 HCI_MITM_NOT_REQUIRED_DEDICATED_BONDING_AUTHENTICATION_REQUIREMENTS = 0x02 HCI_MITM_REQUIRED_DEDICATED_BONDING_AUTHENTICATION_REQUIREMENTS = 0x03 HCI_MITM_NOT_REQUIRED_GENERAL_BONDING_AUTHENTICATION_REQUIREMENTS = 0x04 HCI_MITM_REQUIRED_GENERAL_BONDING_AUTHENTICATION_REQUIREMENTS = 0x05 HCI_AUTHENTICATION_REQUIREMENTS_NAMES = { HCI_MITM_NOT_REQUIRED_NO_BONDING_AUTHENTICATION_REQUIREMENTS: 'HCI_MITM_NOT_REQUIRED_NO_BONDING_AUTHENTICATION_REQUIREMENTS', HCI_MITM_REQUIRED_NO_BONDING_AUTHENTICATION_REQUIREMENTS: 'HCI_MITM_REQUIRED_NO_BONDING_AUTHENTICATION_REQUIREMENTS', HCI_MITM_NOT_REQUIRED_DEDICATED_BONDING_AUTHENTICATION_REQUIREMENTS: 'HCI_MITM_NOT_REQUIRED_DEDICATED_BONDING_AUTHENTICATION_REQUIREMENTS', HCI_MITM_REQUIRED_DEDICATED_BONDING_AUTHENTICATION_REQUIREMENTS: 'HCI_MITM_REQUIRED_DEDICATED_BONDING_AUTHENTICATION_REQUIREMENTS', HCI_MITM_NOT_REQUIRED_GENERAL_BONDING_AUTHENTICATION_REQUIREMENTS: 'HCI_MITM_NOT_REQUIRED_GENERAL_BONDING_AUTHENTICATION_REQUIREMENTS', HCI_MITM_REQUIRED_GENERAL_BONDING_AUTHENTICATION_REQUIREMENTS: 'HCI_MITM_REQUIRED_GENERAL_BONDING_AUTHENTICATION_REQUIREMENTS' } # Link Key Types HCI_COMBINATION_KEY_TYPE = 0X00 HCI_LOCAL_UNIT_KEY_TYPE = 0X01 HCI_REMOTE_UNIT_KEY_TYPE = 0X02 HCI_DEBUG_COMBINATION_KEY_TYPE = 0X03 HCI_UNAUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_192_TYPE = 0X04 HCI_AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_192_TYPE = 0X05 HCI_CHANGED_COMBINATION_KEY_TYPE = 0X06 HCI_UNAUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_256_TYPE = 0X07 HCI_AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_256_TYPE = 0X08 HCI_LINK_TYPE_NAMES = { HCI_COMBINATION_KEY_TYPE: 'HCI_COMBINATION_KEY_TYPE', HCI_LOCAL_UNIT_KEY_TYPE: 'HCI_LOCAL_UNIT_KEY_TYPE', HCI_REMOTE_UNIT_KEY_TYPE: 'HCI_REMOTE_UNIT_KEY_TYPE', HCI_DEBUG_COMBINATION_KEY_TYPE: 'HCI_DEBUG_COMBINATION_KEY_TYPE', HCI_UNAUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_192_TYPE: 'HCI_UNAUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_192_TYPE', HCI_AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_192_TYPE: 'HCI_AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_192_TYPE', HCI_CHANGED_COMBINATION_KEY_TYPE: 'HCI_CHANGED_COMBINATION_KEY_TYPE', HCI_UNAUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_256_TYPE: 'HCI_UNAUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_256_TYPE', HCI_AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_256_TYPE: 'HCI_AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_256_TYPE' } # Address types HCI_PUBLIC_DEVICE_ADDRESS_TYPE = 0x00 HCI_RANDOM_DEVICE_ADDRESS_TYPE = 0x01 HCI_PUBLIC_IDENTITY_ADDRESS_TYPE = 0x02 HCI_RANDOM_IDENTITY_ADDRESS_TYPE = 0x03 # Supported Commands Flags # 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 ) ) # 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') } # fmt: on # pylint: enable=line-too-long # pylint: disable=invalid-name # ----------------------------------------------------------------------------- # pylint: disable-next=unnecessary-lambda STATUS_SPEC = {'size': 1, 'mapper': lambda x: HCI_Constant.status_name(x)} # ----------------------------------------------------------------------------- class HCI_Constant: @staticmethod def status_name(status): return HCI_ERROR_NAMES.get(status, f'0x{status:02X}') @staticmethod def error_name(status): return HCI_ERROR_NAMES.get(status, f'0x{status:02X}') @staticmethod def role_name(role): return HCI_ROLE_NAMES.get(role, str(role)) @staticmethod def le_phy_name(phy): return HCI_LE_PHY_NAMES.get(phy, str(phy)) @staticmethod def inquiry_lap_name(lap): return HCI_INQUIRY_LAP_NAMES.get(lap, f'0x{lap:06X}') @staticmethod def io_capability_name(io_capability): return HCI_IO_CAPABILITY_NAMES.get(io_capability, f'0x{io_capability:02X}') @staticmethod def authentication_requirements_name(authentication_requirements): return HCI_AUTHENTICATION_REQUIREMENTS_NAMES.get( authentication_requirements, f'0x{authentication_requirements:02X}' ) @staticmethod def link_key_type_name(link_key_type): return HCI_LINK_TYPE_NAMES.get(link_key_type, f'0x{link_key_type:02X}') # ----------------------------------------------------------------------------- class HCI_Error(ProtocolError): def __init__(self, error_code): super().__init__(error_code, 'hci', HCI_Constant.error_name(error_code)) # ----------------------------------------------------------------------------- class HCI_StatusError(ProtocolError): def __init__(self, response): super().__init__( response.status, error_namespace=HCI_Command.command_name(response.command_opcode), error_name=HCI_Constant.status_name(response.status), ) # ----------------------------------------------------------------------------- # Generic HCI object # ----------------------------------------------------------------------------- class HCI_Object: @staticmethod def init_from_fields(hci_object, fields, values): if isinstance(values, dict): for field_name, _ in fields: setattr(hci_object, field_name, values[field_name]) else: for field_name, field_value in zip(fields, values): setattr(hci_object, field_name, field_value) @staticmethod def init_from_bytes(hci_object, data, offset, fields): parsed = HCI_Object.dict_from_bytes(data, offset, fields) HCI_Object.init_from_fields(hci_object, parsed.keys(), parsed.values()) @staticmethod def dict_from_bytes(data, offset, fields): result = collections.OrderedDict() for (field_name, field_type) in fields: # The field_type may be a dictionary with a mapper, parser, and/or size if isinstance(field_type, dict): if 'size' in field_type: field_type = field_type['size'] elif 'parser' in field_type: field_type = field_type['parser'] # Parse the field if field_type == '*': # The rest of the bytes field_value = data[offset:] offset += len(field_value) elif field_type == 1: # 8-bit unsigned field_value = data[offset] offset += 1 elif field_type == -1: # 8-bit signed field_value = struct.unpack_from('b', data, offset)[0] offset += 1 elif field_type == 2: # 16-bit unsigned field_value = struct.unpack_from('2': # 16-bit unsigned big-endian field_value = struct.unpack_from('>H', data, offset)[0] offset += 2 elif field_type == -2: # 16-bit signed field_value = struct.unpack_from('4': # 32-bit unsigned big-endian field_value = struct.unpack_from('>I', data, offset)[0] offset += 4 elif isinstance(field_type, int) and 4 < field_type <= 256: # Byte array (from 5 up to 256 bytes) field_value = data[offset : offset + field_type] offset += field_type elif callable(field_type): offset, field_value = field_type(data, offset) else: raise ValueError(f'unknown field type {field_type}') result[field_name] = field_value return result @staticmethod def dict_to_bytes(hci_object, fields): result = bytearray() for (field_name, field_type) in fields: # The field_type may be a dictionary with a mapper, parser, serializer, # and/or size serializer = None if isinstance(field_type, dict): if 'serializer' in field_type: serializer = field_type['serializer'] if 'size' in field_type: field_type = field_type['size'] # Serialize the field field_value = hci_object[field_name] if serializer: field_bytes = serializer(field_value) elif field_type == 1: # 8-bit unsigned field_bytes = bytes([field_value]) elif field_type == -1: # 8-bit signed field_bytes = struct.pack('b', field_value) elif field_type == 2: # 16-bit unsigned field_bytes = struct.pack('2': # 16-bit unsigned big-endian field_bytes = struct.pack('>H', field_value) elif field_type == -2: # 16-bit signed field_bytes = struct.pack('4': # 32-bit unsigned big-endian field_bytes = struct.pack('>I', field_value) elif field_type == '*': if isinstance(field_value, int): if 0 <= field_value <= 255: field_bytes = bytes([field_value]) else: raise ValueError('value too large for *-typed field') else: field_bytes = bytes(field_value) elif isinstance(field_value, (bytes, bytearray)) or hasattr( field_value, 'to_bytes' ): field_bytes = bytes(field_value) if isinstance(field_type, int) and 4 < field_type <= 256: # Truncate or Pad with zeros if the field is too long or too short if len(field_bytes) < field_type: field_bytes += bytes(field_type - len(field_bytes)) elif len(field_bytes) > field_type: field_bytes = field_bytes[:field_type] else: raise ValueError( f"don't know how to serialize type {type(field_value)}" ) result += field_bytes return bytes(result) @classmethod def from_bytes(cls, data, offset, fields): return cls(fields, **cls.dict_from_bytes(data, offset, fields)) def to_bytes(self): return HCI_Object.dict_to_bytes(self.__dict__, self.fields) @staticmethod def parse_length_prefixed_bytes(data, offset): length = data[offset] return offset + 1 + length, data[offset + 1 : offset + 1 + length] @staticmethod def serialize_length_prefixed_bytes(data, padded_size=0): prefixed_size = 1 + len(data) padding = ( bytes(padded_size - prefixed_size) if prefixed_size < padded_size else b'' ) return bytes([len(data)]) + data + padding @staticmethod def format_field_value(value, indentation): if isinstance(value, bytes): return value.hex() if isinstance(value, HCI_Object): return '\n' + value.to_string(indentation) return str(value) @staticmethod def format_fields(hci_object, keys, indentation='', value_mappers=None): if not keys: return '' # Measure the widest field name max_field_name_length = max( (len(key[0] if isinstance(key, tuple) else key) for key in keys) ) # Build array of formatted key:value pairs fields = [] for key in keys: value_mapper = None if isinstance(key, tuple): # The key has an associated specifier key, specifier = key # Get the value mapper from the specifier if isinstance(specifier, dict): value_mapper = specifier.get('mapper') # Get the value for the field value = hci_object[key] # Map the value if needed if value_mappers: value_mapper = value_mappers.get(key, value_mapper) if value_mapper is not None: value = value_mapper(value) # Get the string representation of the value value_str = HCI_Object.format_field_value( value, indentation=indentation + ' ' ) # Add the field to the formatted result key_str = color(f'{key + ":":{1 + max_field_name_length}}', 'cyan') fields.append(f'{indentation}{key_str} {value_str}') return '\n'.join(fields) def __bytes__(self): return self.to_bytes() def __init__(self, fields, **kwargs): self.fields = fields self.init_from_fields(self, fields, kwargs) def to_string(self, indentation='', value_mappers=None): return HCI_Object.format_fields( self.__dict__, self.fields, indentation, value_mappers ) def __str__(self): return self.to_string() # ----------------------------------------------------------------------------- # Bluetooth Address # ----------------------------------------------------------------------------- class Address: ''' Bluetooth Address (see Bluetooth spec Vol 6, Part B - 1.3 DEVICE ADDRESS) NOTE: the address bytes are stored in little-endian byte order here, so address[0] is the LSB of the address, address[5] is the MSB. ''' PUBLIC_DEVICE_ADDRESS = 0x00 RANDOM_DEVICE_ADDRESS = 0x01 PUBLIC_IDENTITY_ADDRESS = 0x02 RANDOM_IDENTITY_ADDRESS = 0x03 ADDRESS_TYPE_NAMES = { PUBLIC_DEVICE_ADDRESS: 'PUBLIC_DEVICE_ADDRESS', RANDOM_DEVICE_ADDRESS: 'RANDOM_DEVICE_ADDRESS', PUBLIC_IDENTITY_ADDRESS: 'PUBLIC_IDENTITY_ADDRESS', RANDOM_IDENTITY_ADDRESS: 'RANDOM_IDENTITY_ADDRESS', } # pylint: disable-next=unnecessary-lambda ADDRESS_TYPE_SPEC = {'size': 1, 'mapper': lambda x: Address.address_type_name(x)} @staticmethod def address_type_name(address_type): return name_or_number(Address.ADDRESS_TYPE_NAMES, address_type) @staticmethod def from_string_for_transport(string, transport): if transport == BT_BR_EDR_TRANSPORT: address_type = Address.PUBLIC_DEVICE_ADDRESS else: address_type = Address.RANDOM_DEVICE_ADDRESS return Address(string, address_type) @staticmethod def parse_address(data, offset): # Fix the type to a default value. This is used for parsing type-less Classic # addresses return Address.parse_address_with_type( data, offset, Address.PUBLIC_DEVICE_ADDRESS ) @staticmethod def parse_address_with_type(data, offset, address_type): return offset + 6, Address(data[offset : offset + 6], address_type) @staticmethod def parse_address_preceded_by_type(data, offset): address_type = data[offset - 1] return Address.parse_address_with_type(data, offset, address_type) def __init__(self, address, address_type=RANDOM_DEVICE_ADDRESS): ''' Initialize an instance. `address` may be a byte array in little-endian format, or a hex string in big-endian format (with optional ':' separators between the bytes). If the address is a string suffixed with '/P', `address_type` is ignored and the type is set to PUBLIC_DEVICE_ADDRESS. ''' if isinstance(address, bytes): self.address_bytes = address else: # Check if there's a '/P' type specifier if address.endswith('P'): address_type = Address.PUBLIC_DEVICE_ADDRESS address = address[:-2] if len(address) == 12 + 5: # Form with ':' separators address = address.replace(':', '') self.address_bytes = bytes(reversed(bytes.fromhex(address))) if len(self.address_bytes) != 6: raise ValueError('invalid address length') self.address_type = address_type def clone(self): return Address(self.address_bytes, self.address_type) @property def is_public(self): return self.address_type in ( self.PUBLIC_DEVICE_ADDRESS, self.PUBLIC_IDENTITY_ADDRESS, ) @property def is_random(self): return not self.is_public @property def is_resolved(self): return self.address_type in ( self.PUBLIC_IDENTITY_ADDRESS, self.RANDOM_IDENTITY_ADDRESS, ) @property def is_resolvable(self): return self.address_type == self.RANDOM_DEVICE_ADDRESS and ( self.address_bytes[5] >> 6 == 1 ) @property def is_static(self): return self.is_random and (self.address_bytes[5] >> 6 == 3) def to_bytes(self): return self.address_bytes def __bytes__(self): return self.to_bytes() def __hash__(self): return hash(self.address_bytes) def __eq__(self, other): return ( self.address_bytes == other.address_bytes and self.is_public == other.is_public ) def __str__(self): ''' String representation of the address, MSB first ''' result = ':'.join([f'{x:02X}' for x in reversed(self.address_bytes)]) if not self.is_public: return result return result + '/P' # Predefined address values 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) # ----------------------------------------------------------------------------- class OwnAddressType: 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', } @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 HCI_Packet: ''' Abstract Base class for HCI packets ''' @staticmethod def from_bytes(packet): packet_type = packet[0] if packet_type == HCI_COMMAND_PACKET: return HCI_Command.from_bytes(packet) if packet_type == HCI_ACL_DATA_PACKET: return HCI_AclDataPacket.from_bytes(packet) if packet_type == HCI_EVENT_PACKET: return HCI_Event.from_bytes(packet) return HCI_CustomPacket(packet) def __init__(self, name): self.name = name def __repr__(self) -> str: return self.name # ----------------------------------------------------------------------------- class HCI_CustomPacket(HCI_Packet): def __init__(self, payload): super().__init__('HCI_CUSTOM_PACKET') self.hci_packet_type = payload[0] self.payload = payload # ----------------------------------------------------------------------------- class HCI_Command(HCI_Packet): ''' See Bluetooth spec @ Vol 2, Part E - 5.4.1 HCI Command Packet ''' hci_packet_type = HCI_COMMAND_PACKET command_classes = {} @staticmethod def command(fields=(), return_parameters_fields=()): ''' Decorator used to declare and register subclasses ''' def inner(cls): cls.name = cls.__name__.upper() cls.op_code = key_with_value(HCI_COMMAND_NAMES, cls.name) if cls.op_code is None: raise KeyError(f'command {cls.name} not found in HCI_COMMAND_NAMES') cls.fields = fields cls.return_parameters_fields = return_parameters_fields # Patch the __init__ method to fix the op_code if fields is not None: def init(self, parameters=None, **kwargs): return HCI_Command.__init__(self, cls.op_code, parameters, **kwargs) cls.__init__ = init # Register a factory for this class HCI_Command.command_classes[cls.op_code] = cls return cls return inner @staticmethod def from_bytes(packet): op_code, length = struct.unpack_from('> 10:02x}, OCF=0x{op_code & 0x3FF:04x}]' @classmethod def create_return_parameters(cls, **kwargs): return HCI_Object(cls.return_parameters_fields, **kwargs) def __init__(self, op_code, parameters=None, **kwargs): super().__init__(HCI_Command.command_name(op_code)) if (fields := getattr(self, 'fields', None)) and kwargs: HCI_Object.init_from_fields(self, fields, kwargs) if parameters is None: parameters = HCI_Object.dict_to_bytes(kwargs, fields) self.op_code = op_code self.parameters = parameters def to_bytes(self): parameters = b'' if self.parameters is None else self.parameters return ( struct.pack('> 5) & 3] ) if event_type & ( 1 << HCI_LE_Extended_Advertising_Report_Event.LEGACY_ADVERTISING_PDU_USED ): legacy_pdu_type = ( HCI_LE_Extended_Advertising_Report_Event.LEGACY_PDU_TYPE_MAP.get( event_type & 0x0F ) ) if legacy_pdu_type is not None: # pylint: disable=line-too-long legacy_info_string = f'({HCI_LE_Advertising_Report_Event.event_type_name(legacy_pdu_type)})' else: legacy_info_string = '' else: legacy_info_string = '' return f'0x{event_type:04X} [{",".join(event_type_flags)}]{legacy_info_string}' @classmethod def from_parameters(cls, parameters): num_reports = parameters[1] reports = [] offset = 2 for _ in range(num_reports): report = cls.Report.from_parameters(parameters, offset) offset += 24 + len(report.data) reports.append(report) return cls(reports) def __init__(self, reports): self.reports = reports[:] # Serialize the fields parameters = bytes( [HCI_LE_EXTENDED_ADVERTISING_REPORT_EVENT, len(reports)] ) + b''.join([bytes(report) for report in reports]) super().__init__(self.subevent_code, parameters) def __str__(self): reports = '\n'.join( [f'{i}:\n{report.to_string(" ")}' for i, report in enumerate(self.reports)] ) return f'{color(self.subevent_name(self.subevent_code), "magenta")}:\n{reports}' HCI_Event.meta_event_classes[ HCI_LE_EXTENDED_ADVERTISING_REPORT_EVENT ] = HCI_LE_Extended_Advertising_Report_Event # ----------------------------------------------------------------------------- @HCI_LE_Meta_Event.event([('connection_handle', 2), ('channel_selection_algorithm', 1)]) class HCI_LE_Channel_Selection_Algorithm_Event(HCI_LE_Meta_Event): ''' See Bluetooth spec @ 7.7.65.20 LE Channel Selection Algorithm Event ''' # ----------------------------------------------------------------------------- @HCI_Event.event([('status', STATUS_SPEC)]) class HCI_Inquiry_Complete_Event(HCI_Event): ''' See Bluetooth spec @ 7.7.1 Inquiry Complete Event ''' # ----------------------------------------------------------------------------- @HCI_Event.registered class HCI_Inquiry_Result_Event(HCI_Event): ''' See Bluetooth spec @ 7.7.2 Inquiry Result Event ''' RESPONSE_FIELDS = [ ('bd_addr', Address.parse_address), ('page_scan_repetition_mode', 1), ('reserved', 1), ('reserved', 1), ('class_of_device', {'size': 3, 'mapper': map_class_of_device}), ('clock_offset', 2), ] @staticmethod def from_parameters(parameters): num_responses = parameters[0] responses = [] offset = 1 for _ in range(num_responses): response = HCI_Object.from_bytes( parameters, offset, HCI_Inquiry_Result_Event.RESPONSE_FIELDS ) offset += 14 responses.append(response) return HCI_Inquiry_Result_Event(responses) def __init__(self, responses): self.responses = responses[:] # Serialize the fields parameters = bytes([HCI_INQUIRY_RESULT_EVENT, len(responses)]) + b''.join( [bytes(response) for response in responses] ) super().__init__(HCI_INQUIRY_RESULT_EVENT, parameters) def __str__(self): responses = '\n'.join( [response.to_string(indentation=' ') for response in self.responses] ) return f'{color("HCI_INQUIRY_RESULT_EVENT", "magenta")}:\n{responses}' # ----------------------------------------------------------------------------- @HCI_Event.event( [ ('status', STATUS_SPEC), ('connection_handle', 2), ('bd_addr', Address.parse_address), ( 'link_type', { 'size': 1, # pylint: disable-next=unnecessary-lambda 'mapper': lambda x: HCI_Connection_Complete_Event.link_type_name(x), }, ), ('encryption_enabled', 1), ] ) class HCI_Connection_Complete_Event(HCI_Event): ''' See Bluetooth spec @ 7.7.3 Connection Complete Event ''' SCO_LINK_TYPE = 0x00 ACL_LINK_TYPE = 0x01 ESCO_LINK_TYPE = 0x02 LINK_TYPE_NAMES = { SCO_LINK_TYPE: 'SCO', ACL_LINK_TYPE: 'ACL', ESCO_LINK_TYPE: 'eSCO', } @staticmethod def link_type_name(link_type): return name_or_number(HCI_Connection_Complete_Event.LINK_TYPE_NAMES, link_type) # ----------------------------------------------------------------------------- @HCI_Event.event( [ ('bd_addr', Address.parse_address), ('class_of_device', 3), ( 'link_type', { 'size': 1, # pylint: disable-next=unnecessary-lambda 'mapper': lambda x: HCI_Connection_Complete_Event.link_type_name(x), }, ), ] ) class HCI_Connection_Request_Event(HCI_Event): ''' See Bluetooth spec @ 7.7.4 Connection Request Event ''' # ----------------------------------------------------------------------------- @HCI_Event.event( [ ('status', STATUS_SPEC), ('connection_handle', 2), ('reason', {'size': 1, 'mapper': HCI_Constant.error_name}), ] ) class HCI_Disconnection_Complete_Event(HCI_Event): ''' See Bluetooth spec @ 7.7.5 Disconnection Complete Event ''' # ----------------------------------------------------------------------------- @HCI_Event.event([('status', STATUS_SPEC), ('connection_handle', 2)]) class HCI_Authentication_Complete_Event(HCI_Event): ''' See Bluetooth spec @ 7.7.6 Authentication Complete Event ''' # ----------------------------------------------------------------------------- @HCI_Event.event( [ ('status', STATUS_SPEC), ('bd_addr', Address.parse_address), ('remote_name', {'size': 248, 'mapper': map_null_terminated_utf8_string}), ] ) class HCI_Remote_Name_Request_Complete_Event(HCI_Event): ''' See Bluetooth spec @ 7.7.7 Remote Name Request Complete Event ''' # ----------------------------------------------------------------------------- @HCI_Event.event( [ ('status', STATUS_SPEC), ('connection_handle', 2), ( 'encryption_enabled', { 'size': 1, # pylint: disable-next=unnecessary-lambda 'mapper': lambda x: HCI_Encryption_Change_Event.encryption_enabled_name( x ), }, ), ] ) class HCI_Encryption_Change_Event(HCI_Event): ''' See Bluetooth spec @ 7.7.8 Encryption Change Event ''' OFF = 0x00 E0_OR_AES_CCM = 0x01 AES_CCM = 0x02 ENCRYPTION_ENABLED_NAMES = { OFF: 'OFF', E0_OR_AES_CCM: 'E0_OR_AES_CCM', AES_CCM: 'AES_CCM', } @staticmethod def encryption_enabled_name(encryption_enabled): return name_or_number( HCI_Encryption_Change_Event.ENCRYPTION_ENABLED_NAMES, encryption_enabled ) # ----------------------------------------------------------------------------- @HCI_Event.event( [('status', STATUS_SPEC), ('connection_handle', 2), ('lmp_features', 8)] ) class HCI_Read_Remote_Supported_Features_Complete_Event(HCI_Event): ''' See Bluetooth spec @ 7.7.11 Read Remote Supported Features Complete Event ''' # ----------------------------------------------------------------------------- @HCI_Event.event( [ ('status', STATUS_SPEC), ('connection_handle', 2), ('version', 1), ('manufacturer_name', 2), ('subversion', 2), ] ) class HCI_Read_Remote_Version_Information_Complete_Event(HCI_Event): ''' See Bluetooth spec @ 7.7.12 Read Remote Version Information Complete Event ''' # ----------------------------------------------------------------------------- @HCI_Event.event( [ ('num_hci_command_packets', 1), ('command_opcode', {'size': 2, 'mapper': HCI_Command.command_name}), ('return_parameters', '*'), ] ) class HCI_Command_Complete_Event(HCI_Event): ''' See Bluetooth spec @ 7.7.14 Command Complete Event ''' return_parameters = b'' def map_return_parameters(self, return_parameters): '''Map simple 'status' return parameters to their named constant form''' if isinstance(return_parameters, bytes) and len(return_parameters) == 1: # Byte-array form return HCI_Constant.status_name(return_parameters[0]) if isinstance(return_parameters, int): # Already converted to an integer status code return HCI_Constant.status_name(return_parameters) return return_parameters @staticmethod def from_parameters(parameters): self = HCI_Command_Complete_Event.__new__(HCI_Command_Complete_Event) HCI_Event.__init__(self, self.event_code, parameters) HCI_Object.init_from_bytes( self, parameters, 0, HCI_Command_Complete_Event.fields ) # Parse the return parameters if ( isinstance(self.return_parameters, bytes) and len(self.return_parameters) == 1 ): # All commands with 1-byte return parameters return a 'status' field, # convert it to an integer self.return_parameters = self.return_parameters[0] else: cls = HCI_Command.command_classes.get(self.command_opcode) if cls and cls.return_parameters_fields: self.return_parameters = HCI_Object.from_bytes( self.return_parameters, 0, cls.return_parameters_fields ) self.return_parameters.fields = cls.return_parameters_fields return self def __str__(self): return f'{color(self.name, "magenta")}:\n' + HCI_Object.format_fields( self.__dict__, self.fields, ' ', {'return_parameters': self.map_return_parameters}, ) # ----------------------------------------------------------------------------- @HCI_Event.event( [ ( 'status', # pylint: disable-next=unnecessary-lambda {'size': 1, 'mapper': lambda x: HCI_Command_Status_Event.status_name(x)}, ), ('num_hci_command_packets', 1), ('command_opcode', {'size': 2, 'mapper': HCI_Command.command_name}), ] ) class HCI_Command_Status_Event(HCI_Event): ''' See Bluetooth spec @ 7.7.15 Command Complete Event ''' PENDING = 0 @staticmethod def status_name(status): if status == HCI_Command_Status_Event.PENDING: return 'PENDING' return HCI_Constant.error_name(status) # ----------------------------------------------------------------------------- @HCI_Event.event( [ ('status', STATUS_SPEC), ('bd_addr', Address.parse_address), ('new_role', {'size': 1, 'mapper': HCI_Constant.role_name}), ] ) class HCI_Role_Change_Event(HCI_Event): ''' See Bluetooth spec @ 7.7.18 Role Change Event ''' # ----------------------------------------------------------------------------- @HCI_Event.registered class HCI_Number_Of_Completed_Packets_Event(HCI_Event): ''' See Bluetooth spec @ 7.7.19 Number Of Completed Packets Event ''' @classmethod def from_parameters(cls, parameters): self = cls.__new__(cls) self.parameters = parameters num_handles = parameters[0] self.connection_handles = [] self.num_completed_packets = [] for i in range(num_handles): self.connection_handles.append( struct.unpack_from('> 12) & 3 bc_flag = (h >> 14) & 3 data = packet[5:] if len(data) != data_total_length: raise ValueError('invalid packet length') return HCI_AclDataPacket( connection_handle, pb_flag, bc_flag, data_total_length, data ) def to_bytes(self): h = (self.pb_flag << 12) | (self.bc_flag << 14) | self.connection_handle return ( struct.pack(' self.l2cap_pdu_length + 4: logger.warning('!!! ACL data exceeds L2CAP PDU') self.current_data = None self.l2cap_pdu_length = 0