1# Copyright 2021-2022 Google LLC 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15# ----------------------------------------------------------------------------- 16# Imports 17# ----------------------------------------------------------------------------- 18import struct 19import collections 20import logging 21import functools 22from colors import color 23 24from .core import * 25 26# ----------------------------------------------------------------------------- 27# Logging 28# ----------------------------------------------------------------------------- 29logger = logging.getLogger(__name__) 30 31 32# ----------------------------------------------------------------------------- 33# Utils 34# ----------------------------------------------------------------------------- 35def hci_command_op_code(ogf, ocf): 36 return (ogf << 10 | ocf) 37 38 39def key_with_value(dictionary, target_value): 40 for key, value in dictionary.items(): 41 if value == target_value: 42 return key 43 return None 44 45 46def indent_lines(str): 47 return '\n'.join([' ' + line for line in str.split('\n')]) 48 49 50def map_null_terminated_utf8_string(utf8_bytes): 51 try: 52 terminator = utf8_bytes.find(0) 53 if terminator < 0: 54 return utf8_bytes 55 return utf8_bytes[0:terminator].decode('utf8') 56 except UnicodeDecodeError: 57 return utf8_bytes 58 59 60def map_class_of_device(class_of_device): 61 service_classes, major_device_class, minor_device_class = DeviceClass.split_class_of_device(class_of_device) 62 return f'[{class_of_device:06X}] Services({",".join(DeviceClass.service_class_labels(service_classes))}),Class({DeviceClass.major_device_class_name(major_device_class)}|{DeviceClass.minor_device_class_name(major_device_class, minor_device_class)})' 63 64 65# ----------------------------------------------------------------------------- 66# Constants 67# ----------------------------------------------------------------------------- 68 69# HCI Version 70HCI_VERSION_BLUETOOTH_CORE_1_0B = 0 71HCI_VERSION_BLUETOOTH_CORE_1_1 = 1 72HCI_VERSION_BLUETOOTH_CORE_1_2 = 2 73HCI_VERSION_BLUETOOTH_CORE_2_0_EDR = 3 74HCI_VERSION_BLUETOOTH_CORE_2_1_EDR = 4 75HCI_VERSION_BLUETOOTH_CORE_3_0_HS = 5 76HCI_VERSION_BLUETOOTH_CORE_4_0 = 6 77HCI_VERSION_BLUETOOTH_CORE_4_1 = 7 78HCI_VERSION_BLUETOOTH_CORE_4_2 = 8 79HCI_VERSION_BLUETOOTH_CORE_5_0 = 9 80HCI_VERSION_BLUETOOTH_CORE_5_1 = 10 81HCI_VERSION_BLUETOOTH_CORE_5_2 = 11 82HCI_VERSION_BLUETOOTH_CORE_5_3 = 12 83 84# HCI Packet types 85HCI_COMMAND_PACKET = 0x01 86HCI_ACL_DATA_PACKET = 0x02 87HCI_SYNCHRONOUS_DATA_PACKET = 0x03 88HCI_EVENT_PACKET = 0x04 89 90# HCI Event Codes 91HCI_INQUIRY_COMPLETE_EVENT = 0x01 92HCI_INQUIRY_RESULT_EVENT = 0x02 93HCI_CONNECTION_COMPLETE_EVENT = 0x03 94HCI_CONNECTION_REQUEST_EVENT = 0x04 95HCI_DISCONNECTION_COMPLETE_EVENT = 0x05 96HCI_AUTHENTICATION_COMPLETE_EVENT = 0x06 97HCI_REMOTE_NAME_REQUEST_COMPLETE_EVENT = 0x07 98HCI_ENCRYPTION_CHANGE_EVENT = 0x08 99HCI_CHANGE_CONNECTION_LINK_KEY_COMPLETE_EVENT = 0x09 100HCI_LINK_KEY_TYPE_CHANGED_EVENT = 0x0A 101HCI_READ_REMOTE_SUPPORTED_FEATURES_COMPLETE_EVENT = 0x0B 102HCI_READ_REMOTE_VERSION_INFORMATION_COMPLETE_EVENT = 0x0C 103HCI_QOS_SETUP_COMPLETE_EVENT = 0x0D 104HCI_COMMAND_COMPLETE_EVENT = 0x0E 105HCI_COMMAND_STATUS_EVENT = 0x0F 106HCI_HARDWARE_ERROR_EVENT = 0x10 107HCI_FLUSH_OCCURRED_EVENT = 0x11 108HCI_ROLE_CHANGE_EVENT = 0x12 109HCI_NUMBER_OF_COMPLETED_PACKETS_EVENT = 0x13 110HCI_MODE_CHANGE_EVENT = 0x14 111HCI_RETURN_LINK_KEYS_EVENT = 0x15 112HCI_PIN_CODE_REQUEST_EVENT = 0x16 113HCI_LINK_KEY_REQUEST_EVENT = 0x17 114HCI_LINK_KEY_NOTIFICATION_EVENT = 0x18 115HCI_LOOPBACK_COMMAND_EVENT = 0x19 116HCI_DATA_BUFFER_OVERFLOW_EVENT = 0x1A 117HCI_MAX_SLOTS_CHANGE_EVENT = 0x1B 118HCI_READ_CLOCK_OFFSET_COMPLETE_EVENT = 0x1C 119HCI_CONNECTION_PACKET_TYPE_CHANGED_EVENT = 0x1D 120HCI_QOS_VIOLATION_EVENT = 0x1E 121HCI_PAGE_SCAN_REPETITION_MODE_CHANGE_EVENT = 0x20 122HCI_FLOW_SPECIFICATION_COMPLETE_EVENT = 0x21 123HCI_INQUIRY_RESULT_WITH_RSSI_EVENT = 0x22 124HCI_READ_REMOTE_EXTENDED_FEATURES_COMPLETE_EVENT = 0x23 125HCI_SYNCHRONOUS_CONNECTION_COMPLETE_EVENT = 0x2C 126HCI_SYNCHRONOUS_CONNECTION_CHANGED_EVENT = 0x2D 127HCI_SNIFF_SUBRATING_EVENT = 0x2E 128HCI_EXTENDED_INQUIRY_RESULT_EVENT = 0x2F 129HCI_ENCRYPTION_KEY_REFRESH_COMPLETE_EVENT = 0x30 130HCI_IO_CAPABILITY_REQUEST_EVENT = 0x31 131HCI_IO_CAPABILITY_RESPONSE_EVENT = 0x32 132HCI_USER_CONFIRMATION_REQUEST_EVENT = 0x33 133HCI_USER_PASSKEY_REQUEST_EVENT = 0x34 134HCI_REMOTE_OOB_DATA_REQUEST = 0x35 135HCI_SIMPLE_PAIRING_COMPLETE_EVENT = 0x36 136HCI_LINK_SUPERVISION_TIMEOUT_CHANGED_EVENT = 0x38 137HCI_ENHANCED_FLUSH_COMPLETE_EVENT = 0x39 138HCI_USER_PASSKEY_NOTIFICATION_EVENT = 0x3B 139HCI_KEYPRESS_NOTIFICATION_EVENT = 0x3C 140HCI_REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION_EVENT = 0x3D 141HCI_LE_META_EVENT = 0x3E 142HCI_NUMBER_OF_COMPLETED_DATA_BLOCKS_EVENT = 0x48 143 144HCI_EVENT_NAMES = { 145 HCI_INQUIRY_COMPLETE_EVENT: 'HCI_INQUIRY_COMPLETE_EVENT', 146 HCI_INQUIRY_RESULT_EVENT: 'HCI_INQUIRY_RESULT_EVENT', 147 HCI_CONNECTION_COMPLETE_EVENT: 'HCI_CONNECTION_COMPLETE_EVENT', 148 HCI_CONNECTION_REQUEST_EVENT: 'HCI_CONNECTION_REQUEST_EVENT', 149 HCI_DISCONNECTION_COMPLETE_EVENT: 'HCI_DISCONNECTION_COMPLETE_EVENT', 150 HCI_AUTHENTICATION_COMPLETE_EVENT: 'HCI_AUTHENTICATION_COMPLETE_EVENT', 151 HCI_REMOTE_NAME_REQUEST_COMPLETE_EVENT: 'HCI_REMOTE_NAME_REQUEST_COMPLETE_EVENT', 152 HCI_ENCRYPTION_CHANGE_EVENT: 'HCI_ENCRYPTION_CHANGE_EVENT', 153 HCI_CHANGE_CONNECTION_LINK_KEY_COMPLETE_EVENT: 'HCI_CHANGE_CONNECTION_LINK_KEY_COMPLETE_EVENT', 154 HCI_LINK_KEY_TYPE_CHANGED_EVENT: 'HCI_LINK_KEY_TYPE_CHANGED_EVENT', 155 HCI_INQUIRY_RESULT_WITH_RSSI_EVENT: 'HCI_INQUIRY_RESULT_WITH_RSSI_EVENT', 156 HCI_READ_REMOTE_SUPPORTED_FEATURES_COMPLETE_EVENT: 'HCI_READ_REMOTE_SUPPORTED_FEATURES_COMPLETE_EVENT', 157 HCI_READ_REMOTE_VERSION_INFORMATION_COMPLETE_EVENT: 'HCI_READ_REMOTE_VERSION_INFORMATION_COMPLETE_EVENT', 158 HCI_QOS_SETUP_COMPLETE_EVENT: 'HCI_QOS_SETUP_COMPLETE_EVENT', 159 HCI_SYNCHRONOUS_CONNECTION_COMPLETE_EVENT: 'HCI_SYNCHRONOUS_CONNECTION_COMPLETE_EVENT', 160 HCI_SYNCHRONOUS_CONNECTION_CHANGED_EVENT: 'HCI_SYNCHRONOUS_CONNECTION_CHANGED_EVENT', 161 HCI_SNIFF_SUBRATING_EVENT: 'HCI_SNIFF_SUBRATING_EVENT', 162 HCI_COMMAND_COMPLETE_EVENT: 'HCI_COMMAND_COMPLETE_EVENT', 163 HCI_COMMAND_STATUS_EVENT: 'HCI_COMMAND_STATUS_EVENT', 164 HCI_HARDWARE_ERROR_EVENT: 'HCI_HARDWARE_ERROR_EVENT', 165 HCI_FLUSH_OCCURRED_EVENT: 'HCI_FLUSH_OCCURRED_EVENT', 166 HCI_ROLE_CHANGE_EVENT: 'HCI_ROLE_CHANGE_EVENT', 167 HCI_NUMBER_OF_COMPLETED_PACKETS_EVENT: 'HCI_NUMBER_OF_COMPLETED_PACKETS_EVENT', 168 HCI_MODE_CHANGE_EVENT: 'HCI_MODE_CHANGE_EVENT', 169 HCI_RETURN_LINK_KEYS_EVENT: 'HCI_RETURN_LINK_KEYS_EVENT', 170 HCI_PIN_CODE_REQUEST_EVENT: 'HCI_PIN_CODE_REQUEST_EVENT', 171 HCI_LINK_KEY_REQUEST_EVENT: 'HCI_LINK_KEY_REQUEST_EVENT', 172 HCI_LINK_KEY_NOTIFICATION_EVENT: 'HCI_LINK_KEY_NOTIFICATION_EVENT', 173 HCI_LOOPBACK_COMMAND_EVENT: 'HCI_LOOPBACK_COMMAND_EVENT', 174 HCI_DATA_BUFFER_OVERFLOW_EVENT: 'HCI_DATA_BUFFER_OVERFLOW_EVENT', 175 HCI_MAX_SLOTS_CHANGE_EVENT: 'HCI_MAX_SLOTS_CHANGE_EVENT', 176 HCI_READ_CLOCK_OFFSET_COMPLETE_EVENT: 'HCI_READ_CLOCK_OFFSET_COMPLETE_EVENT', 177 HCI_CONNECTION_PACKET_TYPE_CHANGED_EVENT: 'HCI_CONNECTION_PACKET_TYPE_CHANGED_EVENT', 178 HCI_QOS_VIOLATION_EVENT: 'HCI_QOS_VIOLATION_EVENT', 179 HCI_PAGE_SCAN_REPETITION_MODE_CHANGE_EVENT: 'HCI_PAGE_SCAN_REPETITION_MODE_CHANGE_EVENT', 180 HCI_FLOW_SPECIFICATION_COMPLETE_EVENT: 'HCI_FLOW_SPECIFICATION_COMPLETE_EVENT', 181 HCI_READ_REMOTE_EXTENDED_FEATURES_COMPLETE_EVENT: 'HCI_READ_REMOTE_EXTENDED_FEATURES_COMPLETE_EVENT', 182 HCI_EXTENDED_INQUIRY_RESULT_EVENT: 'HCI_EXTENDED_INQUIRY_RESULT_EVENT', 183 HCI_ENCRYPTION_KEY_REFRESH_COMPLETE_EVENT: 'HCI_ENCRYPTION_KEY_REFRESH_COMPLETE_EVENT', 184 HCI_IO_CAPABILITY_REQUEST_EVENT: 'HCI_IO_CAPABILITY_REQUEST_EVENT', 185 HCI_IO_CAPABILITY_RESPONSE_EVENT: 'HCI_IO_CAPABILITY_RESPONSE_EVENT', 186 HCI_USER_CONFIRMATION_REQUEST_EVENT: 'HCI_USER_CONFIRMATION_REQUEST_EVENT', 187 HCI_USER_PASSKEY_REQUEST_EVENT: 'HCI_USER_PASSKEY_REQUEST_EVENT', 188 HCI_REMOTE_OOB_DATA_REQUEST: 'HCI_REMOTE_OOB_DATA_REQUEST', 189 HCI_SIMPLE_PAIRING_COMPLETE_EVENT: 'HCI_SIMPLE_PAIRING_COMPLETE_EVENT', 190 HCI_LINK_SUPERVISION_TIMEOUT_CHANGED_EVENT: 'HCI_LINK_SUPERVISION_TIMEOUT_CHANGED_EVENT', 191 HCI_ENHANCED_FLUSH_COMPLETE_EVENT: 'HCI_ENHANCED_FLUSH_COMPLETE_EVENT', 192 HCI_USER_PASSKEY_NOTIFICATION_EVENT: 'HCI_USER_PASSKEY_NOTIFICATION_EVENT', 193 HCI_KEYPRESS_NOTIFICATION_EVENT: 'HCI_KEYPRESS_NOTIFICATION_EVENT', 194 HCI_REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION_EVENT: 'HCI_REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION_EVENT', 195 HCI_LE_META_EVENT: 'HCI_LE_META_EVENT' 196} 197 198# HCI Subevent Codes 199HCI_LE_CONNECTION_COMPLETE_EVENT = 0x01 200HCI_LE_ADVERTISING_REPORT_EVENT = 0x02 201HCI_LE_CONNECTION_UPDATE_COMPLETE_EVENT = 0x03 202HCI_LE_READ_REMOTE_FEATURES_COMPLETE_EVENT = 0x04 203HCI_LE_LONG_TERM_KEY_REQUEST_EVENT = 0x05 204HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_EVENT = 0x06 205HCI_LE_DATA_LENGTH_CHANGE_EVENT = 0x07 206HCI_LE_READ_LOCAL_P_256_PUBLIC_KEY_COMPLETE_EVENT = 0x08 207HCI_LE_GENERATE_DHKEY_COMPLETE_EVENT = 0x09 208HCI_LE_ENHANCED_CONNECTION_COMPLETE_EVENT = 0x0A 209HCI_LE_DIRECTED_ADVERTISING_REPORT_EVENT = 0x0B 210HCI_LE_PHY_UPDATE_COMPLETE_EVENT = 0x0C 211HCI_LE_EXTENDED_ADVERTISING_REPORT_EVENT = 0x0D 212HCI_LE_PERIODIC_ADVERTISING_SYNC_ESTABLISHED_EVENT = 0x0E 213HCI_LE_PERIODIC_ADVERTISING_REPORT_EVENT = 0x0F 214HCI_LE_PERIODIC_ADVERTISING_SYNC_LOST_EVENT = 0x10 215HCI_LE_SCAN_TIMEOUT_EVENT = 0x11 216HCI_LE_ADVERTISING_SET_TERMINATED_EVENT = 0x12 217HCI_LE_SCAN_REQUEST_RECEIVED_EVENT = 0x13 218HCI_LE_CHANNEL_SELECTION_ALGORITHM_EVENT = 0x14 219 220HCI_SUBEVENT_NAMES = { 221 HCI_LE_CONNECTION_COMPLETE_EVENT: 'HCI_LE_CONNECTION_COMPLETE_EVENT', 222 HCI_LE_ADVERTISING_REPORT_EVENT: 'HCI_LE_ADVERTISING_REPORT_EVENT', 223 HCI_LE_CONNECTION_UPDATE_COMPLETE_EVENT: 'HCI_LE_CONNECTION_UPDATE_COMPLETE_EVENT', 224 HCI_LE_READ_REMOTE_FEATURES_COMPLETE_EVENT: 'HCI_LE_READ_REMOTE_FEATURES_COMPLETE_EVENT', 225 HCI_LE_LONG_TERM_KEY_REQUEST_EVENT: 'HCI_LE_LONG_TERM_KEY_REQUEST_EVENT', 226 HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_EVENT: 'HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_EVENT', 227 HCI_LE_DATA_LENGTH_CHANGE_EVENT: 'HCI_LE_DATA_LENGTH_CHANGE_EVENT', 228 HCI_LE_READ_LOCAL_P_256_PUBLIC_KEY_COMPLETE_EVENT: 'HCI_LE_READ_LOCAL_P_256_PUBLIC_KEY_COMPLETE_EVENT', 229 HCI_LE_GENERATE_DHKEY_COMPLETE_EVENT: 'HCI_LE_GENERATE_DHKEY_COMPLETE_EVENT', 230 HCI_LE_ENHANCED_CONNECTION_COMPLETE_EVENT: 'HCI_LE_ENHANCED_CONNECTION_COMPLETE_EVENT', 231 HCI_LE_DIRECTED_ADVERTISING_REPORT_EVENT: 'HCI_LE_DIRECTED_ADVERTISING_REPORT_EVENT', 232 HCI_LE_PHY_UPDATE_COMPLETE_EVENT: 'HCI_LE_PHY_UPDATE_COMPLETE_EVENT', 233 HCI_LE_EXTENDED_ADVERTISING_REPORT_EVENT: 'HCI_LE_EXTENDED_ADVERTISING_REPORT_EVENT', 234 HCI_LE_PERIODIC_ADVERTISING_SYNC_ESTABLISHED_EVENT: 'HCI_LE_PERIODIC_ADVERTISING_SYNC_ESTABLISHED_EVENT', 235 HCI_LE_PERIODIC_ADVERTISING_REPORT_EVENT: 'HCI_LE_PERIODIC_ADVERTISING_REPORT_EVENT', 236 HCI_LE_PERIODIC_ADVERTISING_SYNC_LOST_EVENT: 'HCI_LE_PERIODIC_ADVERTISING_SYNC_LOST_EVENT', 237 HCI_LE_SCAN_TIMEOUT_EVENT: 'HCI_LE_SCAN_TIMEOUT_EVENT', 238 HCI_LE_ADVERTISING_SET_TERMINATED_EVENT: 'HCI_LE_ADVERTISING_SET_TERMINATED_EVENT', 239 HCI_LE_SCAN_REQUEST_RECEIVED_EVENT: 'HCI_LE_SCAN_REQUEST_RECEIVED_EVENT', 240 HCI_LE_CHANNEL_SELECTION_ALGORITHM_EVENT: 'HCI_LE_CHANNEL_SELECTION_ALGORITHM_EVENT' 241} 242 243# HCI Command 244HCI_INQUIRY_COMMAND = hci_command_op_code(0x01, 0x0001) 245HCI_INQUIRY_CANCEL_COMMAND = hci_command_op_code(0x01, 0x0002) 246HCI_CREATE_CONNECTION_COMMAND = hci_command_op_code(0x01, 0x0005) 247HCI_DISCONNECT_COMMAND = hci_command_op_code(0x01, 0x0006) 248HCI_ACCEPT_CONNECTION_REQUEST_COMMAND = hci_command_op_code(0x01, 0x0009) 249HCI_LINK_KEY_REQUEST_REPLY_COMMAND = hci_command_op_code(0x01, 0x000B) 250HCI_LINK_KEY_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x01, 0x000C) 251HCI_PIN_CODE_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x01, 0x000E) 252HCI_CHANGE_CONNECTION_PACKET_TYPE_COMMAND = hci_command_op_code(0x01, 0x000F) 253HCI_AUTHENTICATION_REQUESTED_COMMAND = hci_command_op_code(0x01, 0x0011) 254HCI_SET_CONNECTION_ENCRYPTION_COMMAND = hci_command_op_code(0x01, 0x0013) 255HCI_REMOTE_NAME_REQUEST_COMMAND = hci_command_op_code(0x01, 0x0019) 256HCI_READ_REMOTE_SUPPORTED_FEATURES_COMMAND = hci_command_op_code(0x01, 0x001B) 257HCI_READ_REMOTE_EXTENDED_FEATURES_COMMAND = hci_command_op_code(0x01, 0x001C) 258HCI_READ_REMOTE_VERSION_INFORMATION_COMMAND = hci_command_op_code(0x01, 0x001D) 259HCI_READ_CLOCK_OFFSET_COMMAND = hci_command_op_code(0x01, 0x001F) 260HCI_IO_CAPABILITY_REQUEST_REPLY_COMMAND = hci_command_op_code(0x01, 0x002B) 261HCI_USER_CONFIRMATION_REQUEST_REPLY_COMMAND = hci_command_op_code(0x01, 0x002C) 262HCI_USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x01, 0x002D) 263HCI_USER_PASSKEY_REQUEST_REPLY_COMMAND = hci_command_op_code(0x01, 0x002E) 264HCI_USER_PASSKEY_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x01, 0x002F) 265HCI_ENHANCED_SETUP_SYNCHRONOUS_CONNECTION_COMMAND = hci_command_op_code(0x01, 0x003D) 266HCI_SNIFF_MODE_COMMAND = hci_command_op_code(0x02, 0x0003) 267HCI_EXIT_SNIFF_MODE_COMMAND = hci_command_op_code(0x02, 0x0004) 268HCI_SWITCH_ROLE_COMMAND = hci_command_op_code(0x02, 0x000B) 269HCI_WRITE_LINK_POLICY_SETTINGS_COMMAND = hci_command_op_code(0x02, 0x000D) 270HCI_WRITE_DEFAULT_LINK_POLICY_SETTINGS_COMMAND = hci_command_op_code(0x02, 0x000F) 271HCI_SNIFF_SUBRATING_COMMAND = hci_command_op_code(0x02, 0x0011) 272HCI_SET_EVENT_MASK_COMMAND = hci_command_op_code(0x03, 0x0001) 273HCI_RESET_COMMAND = hci_command_op_code(0x03, 0x0003) 274HCI_SET_EVENT_FILTER_COMMAND = hci_command_op_code(0x03, 0x0005) 275HCI_READ_STORED_LINK_KEY_COMMAND = hci_command_op_code(0x03, 0x000D) 276HCI_DELETE_STORED_LINK_KEY_COMMAND = hci_command_op_code(0x03, 0x0012) 277HCI_WRITE_LOCAL_NAME_COMMAND = hci_command_op_code(0x03, 0x0013) 278HCI_READ_LOCAL_NAME_COMMAND = hci_command_op_code(0x03, 0x0014) 279HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x0016) 280HCI_WRITE_PAGE_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x0018) 281HCI_WRITE_SCAN_ENABLE_COMMAND = hci_command_op_code(0x03, 0x001A) 282HCI_READ_PAGE_SCAN_ACTIVITY_COMMAND = hci_command_op_code(0x03, 0x001B) 283HCI_WRITE_PAGE_SCAN_ACTIVITY_COMMAND = hci_command_op_code(0x03, 0x001C) 284HCI_WRITE_INQUIRY_SCAN_ACTIVITY_COMMAND = hci_command_op_code(0x03, 0x001E) 285HCI_READ_CLASS_OF_DEVICE_COMMAND = hci_command_op_code(0x03, 0x0023) 286HCI_WRITE_CLASS_OF_DEVICE_COMMAND = hci_command_op_code(0x03, 0x0024) 287HCI_READ_VOICE_SETTING_COMMAND = hci_command_op_code(0x03, 0x0025) 288HCI_WRITE_VOICE_SETTING_COMMAND = hci_command_op_code(0x03, 0x0026) 289HCI_READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE_COMMAND = hci_command_op_code(0x03, 0x002E) 290HCI_WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE_COMMAND = hci_command_op_code(0x03, 0x002F) 291HCI_HOST_BUFFER_SIZE_COMMAND = hci_command_op_code(0x03, 0x0033) 292HCI_WRITE_LINK_SUPERVISION_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x0037) 293HCI_READ_NUMBER_OF_SUPPORTED_IAC_COMMAND = hci_command_op_code(0x03, 0x0038) 294HCI_READ_CURRENT_IAC_LAP_COMMAND = hci_command_op_code(0x03, 0x0039) 295HCI_WRITE_INQUIRY_SCAN_TYPE_COMMAND = hci_command_op_code(0x03, 0x0043) 296HCI_WRITE_INQUIRY_MODE_COMMAND = hci_command_op_code(0x03, 0x0045) 297HCI_READ_PAGE_SCAN_TYPE_COMMAND = hci_command_op_code(0x03, 0x0046) 298HCI_WRITE_PAGE_SCAN_TYPE_COMMAND = hci_command_op_code(0x03, 0x0047) 299HCI_WRITE_EXTENDED_INQUIRY_RESPONSE_COMMAND = hci_command_op_code(0x03, 0x0052) 300HCI_WRITE_SIMPLE_PAIRING_MODE_COMMAND = hci_command_op_code(0x03, 0x0056) 301HCI_READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL_COMMAND = hci_command_op_code(0x03, 0x0058) 302HCI_SET_EVENT_MASK_PAGE_2_COMMAND = hci_command_op_code(0x03, 0x0063) 303HCI_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_COMMAND = hci_command_op_code(0x03, 0x005A) 304HCI_READ_LE_HOST_SUPPORT_COMMAND = hci_command_op_code(0x03, 0x006C) 305HCI_WRITE_LE_HOST_SUPPORT_COMMAND = hci_command_op_code(0x03, 0x006D) 306HCI_WRITE_SECURE_CONNECTIONS_HOST_SUPPORT_COMMAND = hci_command_op_code(0x03, 0x007A) 307HCI_WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x007C) 308HCI_READ_LOCAL_VERSION_INFORMATION_COMMAND = hci_command_op_code(0x04, 0x0001) 309HCI_READ_LOCAL_SUPPORTED_COMMANDS_COMMAND = hci_command_op_code(0x04, 0x0002) 310HCI_READ_LOCAL_SUPPORTED_FEATURES_COMMAND = hci_command_op_code(0x04, 0x0003) 311HCI_READ_LOCAL_EXTENDED_FEATURES_COMMAND = hci_command_op_code(0x04, 0x0004) 312HCI_READ_BUFFER_SIZE_COMMAND = hci_command_op_code(0x04, 0x0005) 313HCI_READ_BD_ADDR_COMMAND = hci_command_op_code(0x04, 0x0009) 314HCI_READ_LOCAL_SUPPORTED_CODECS_COMMAND = hci_command_op_code(0x04, 0x000B) 315HCI_READ_ENCRYPTION_KEY_SIZE_COMMAND = hci_command_op_code(0x05, 0x0008) 316HCI_LE_SET_EVENT_MASK_COMMAND = hci_command_op_code(0x08, 0x0001) 317HCI_LE_READ_BUFFER_SIZE_COMMAND = hci_command_op_code(0x08, 0x0002) 318HCI_LE_READ_LOCAL_SUPPORTED_FEATURES_COMMAND = hci_command_op_code(0x08, 0x0003) 319HCI_LE_SET_RANDOM_ADDRESS_COMMAND = hci_command_op_code(0x08, 0x0005) 320HCI_LE_SET_ADVERTISING_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0006) 321HCI_LE_READ_ADVERTISING_CHANNEL_TX_POWER_COMMAND = hci_command_op_code(0x08, 0x0007) 322HCI_LE_SET_ADVERTISING_DATA_COMMAND = hci_command_op_code(0x08, 0x0008) 323HCI_LE_SET_SCAN_RESPONSE_DATA_COMMAND = hci_command_op_code(0x08, 0x0009) 324HCI_LE_SET_ADVERTISING_ENABLE_COMMAND = hci_command_op_code(0x08, 0x000A) 325HCI_LE_SET_SCAN_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x000B) 326HCI_LE_SET_SCAN_ENABLE_COMMAND = hci_command_op_code(0x08, 0x000C) 327HCI_LE_CREATE_CONNECTION_COMMAND = hci_command_op_code(0x08, 0x000D) 328HCI_LE_CREATE_CONNECTION_CANCEL_COMMAND = hci_command_op_code(0x08, 0x000E) 329HCI_LE_READ_WHITE_LIST_SIZE_COMMAND = hci_command_op_code(0x08, 0x000F) 330HCI_LE_CLEAR_WHITE_LIST_COMMAND = hci_command_op_code(0x08, 0x0010) 331HCI_LE_ADD_DEVICE_TO_WHITE_LIST_COMMAND = hci_command_op_code(0x08, 0x0011) 332HCI_LE_REMOVE_DEVICE_FROM_WHITE_LIST_COMMAND = hci_command_op_code(0x08, 0x0012) 333HCI_LE_CONNECTION_UPDATE_COMMAND = hci_command_op_code(0x08, 0x0013) 334HCI_LE_SET_HOST_CHANNEL_CLASSIFICATION_COMMAND = hci_command_op_code(0x08, 0x0014) 335HCI_LE_READ_CHANNEL_MAP_COMMAND = hci_command_op_code(0x08, 0x0015) 336HCI_LE_READ_REMOTE_FEATURES_COMMAND = hci_command_op_code(0x08, 0x0016) 337HCI_LE_ENCRYPT_COMMAND = hci_command_op_code(0x08, 0x0017) 338HCI_LE_RAND_COMMAND = hci_command_op_code(0x08, 0x0018) 339HCI_LE_START_ENCRYPTION_COMMAND = hci_command_op_code(0x08, 0x0019) 340HCI_LE_LONG_TERM_KEY_REQUEST_REPLY_COMMAND = hci_command_op_code(0x08, 0x001A) 341HCI_LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x08, 0x001B) 342HCI_LE_READ_SUPPORTED_STATES_COMMAND = hci_command_op_code(0x08, 0x001C) 343HCI_LE_RECEIVER_TEST_COMMAND = hci_command_op_code(0x08, 0x001D) 344HCI_LE_TRANSMITTER_TEST_COMMAND = hci_command_op_code(0x08, 0x001E) 345HCI_LE_TEST_END_COMMAND = hci_command_op_code(0x08, 0x001F) 346HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY_COMMAND = hci_command_op_code(0x08, 0x0020) 347HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x08, 0x0021) 348HCI_LE_SET_DATA_LENGTH_COMMAND = hci_command_op_code(0x08, 0x0022) 349HCI_LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH_COMMAND = hci_command_op_code(0x08, 0x0023) 350HCI_LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH_COMMAND = hci_command_op_code(0x08, 0x0024) 351HCI_LE_READ_LOCAL_P_256_PUBLIC_KEY_COMMAND = hci_command_op_code(0x08, 0x0025) 352HCI_LE_GENERATE_DHKEY_COMMAND = hci_command_op_code(0x08, 0x0026) 353HCI_LE_ADD_DEVICE_TO_RESOLVING_LIST_COMMAND = hci_command_op_code(0x08, 0x0027) 354HCI_LE_REMOVE_DEVICE_FROM_RESOLVING_LIST_COMMAND = hci_command_op_code(0x08, 0x0028) 355HCI_LE_CLEAR_RESOLVING_LIST_COMMAND = hci_command_op_code(0x08, 0x0029) 356HCI_LE_READ_RESOLVING_LIST_SIZE_COMMAND = hci_command_op_code(0x08, 0x002A) 357HCI_LE_READ_PEER_RESOLVABLE_ADDRESS_COMMAND = hci_command_op_code(0x08, 0x002B) 358HCI_LE_READ_LOCAL_RESOLVABLE_ADDRESS_COMMAND = hci_command_op_code(0x08, 0x002C) 359HCI_LE_SET_ADDRESS_RESOLUTION_ENABLE_COMMAND = hci_command_op_code(0x08, 0x002D) 360HCI_LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT_COMMAND = hci_command_op_code(0x08, 0x002E) 361HCI_LE_READ_MAXIMUM_DATA_LENGTH_COMMAND = hci_command_op_code(0x08, 0x002F) 362HCI_LE_READ_PHY_COMMAND = hci_command_op_code(0x08, 0x0030) 363HCI_LE_SET_DEFAULT_PHY_COMMAND = hci_command_op_code(0x08, 0x0031) 364HCI_LE_SET_PHY_COMMAND = hci_command_op_code(0x08, 0x0032) 365HCI_LE_ENHANCED_RECEIVER_TEST_COMMAND = hci_command_op_code(0x08, 0x0033) 366HCI_LE_ENHANCED_TRANSMITTER_TEST_COMMAND = hci_command_op_code(0x08, 0x0034) 367HCI_LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_COMMAND = hci_command_op_code(0x08, 0x0035) 368HCI_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0036) 369HCI_LE_SET_EXTENDED_ADVERTISING_DATA_COMMAND = hci_command_op_code(0x08, 0x0037) 370HCI_LE_SET_EXTENDED_SCAN_RESPONSE_DATA_COMMAND = hci_command_op_code(0x08, 0x0038) 371HCI_LE_SET_EXTENDED_ADVERTISING_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0039) 372HCI_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH_COMMAND = hci_command_op_code(0x08, 0x003A) 373HCI_LE_READ_NUMBER_OF_SUPPORTED_ADVERETISING_SETS_COMMAND = hci_command_op_code(0x08, 0x003B) 374HCI_LE_REMOVE_ADVERTISING_SET_COMMAND = hci_command_op_code(0x08, 0x003C) 375HCI_LE_CLEAR_ADVERTISING_SETS_COMMAND = hci_command_op_code(0x08, 0x003D) 376HCI_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x003E) 377HCI_LE_SET_PERIODIC_ADVERTISING_DATA_COMMAND = hci_command_op_code(0x08, 0x003F) 378HCI_LE_SET_PERIODIC_ADVERTISING_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0040) 379HCI_LE_SET_EXTENDED_SCAN_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0041) 380HCI_LE_SET_EXTENDED_SCAN_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0042) 381HCI_LE_SET_EXTENDED_CREATE_CONNECTION_COMMAND = hci_command_op_code(0x08, 0x0043) 382HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC_COMMAND = hci_command_op_code(0x08, 0x0044) 383HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL_COMMAND = hci_command_op_code(0x08, 0x0045) 384HCI_LE_PERIODIC_ADVERTISING_TERMINATE_SYNC_COMMAND = hci_command_op_code(0x08, 0x0046) 385HCI_LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST_COMMAND = hci_command_op_code(0x08, 0x0047) 386HCI_LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST_COMMAND = hci_command_op_code(0x08, 0x0048) 387HCI_LE_CLEAR_PERIODIC_ADVERTISER_LIST_COMMAND = hci_command_op_code(0x08, 0x0049) 388HCI_LE_READ_PERIODIC_ADVERTISER_LIST_SIZE_COMMAND = hci_command_op_code(0x08, 0x004A) 389HCI_LE_READ_TRANSMIT_POWER_COMMAND = hci_command_op_code(0x08, 0x004B) 390HCI_LE_READ_RF_PATH_COMPENSATION_COMMAND = hci_command_op_code(0x08, 0x004C) 391HCI_LE_WRITE_RF_PATH_COMPENSATION_COMMAND = hci_command_op_code(0x08, 0x004D) 392HCI_LE_SET_PRIVACY_MODE_COMMAND = hci_command_op_code(0x08, 0x004E) 393 394 395HCI_COMMAND_NAMES = { 396 HCI_INQUIRY_COMMAND: 'HCI_INQUIRY_COMMAND', 397 HCI_INQUIRY_CANCEL_COMMAND: 'HCI_INQUIRY_CANCEL_COMMAND', 398 HCI_CREATE_CONNECTION_COMMAND: 'HCI_CREATE_CONNECTION_COMMAND', 399 HCI_DISCONNECT_COMMAND: 'HCI_DISCONNECT_COMMAND', 400 HCI_ACCEPT_CONNECTION_REQUEST_COMMAND: 'HCI_ACCEPT_CONNECTION_REQUEST_COMMAND', 401 HCI_LINK_KEY_REQUEST_REPLY_COMMAND: 'HCI_LINK_KEY_REQUEST_REPLY_COMMAND', 402 HCI_LINK_KEY_REQUEST_NEGATIVE_REPLY_COMMAND: 'HCI_LINK_KEY_REQUEST_NEGATIVE_REPLY_COMMAND', 403 HCI_PIN_CODE_REQUEST_NEGATIVE_REPLY_COMMAND: 'HCI_PIN_CODE_REQUEST_NEGATIVE_REPLY_COMMAND', 404 HCI_CHANGE_CONNECTION_PACKET_TYPE_COMMAND: 'HCI_CHANGE_CONNECTION_PACKET_TYPE_COMMAND', 405 HCI_AUTHENTICATION_REQUESTED_COMMAND: 'HCI_AUTHENTICATION_REQUESTED_COMMAND', 406 HCI_SET_CONNECTION_ENCRYPTION_COMMAND: 'HCI_SET_CONNECTION_ENCRYPTION_COMMAND', 407 HCI_REMOTE_NAME_REQUEST_COMMAND: 'HCI_REMOTE_NAME_REQUEST_COMMAND', 408 HCI_READ_REMOTE_SUPPORTED_FEATURES_COMMAND: 'HCI_READ_REMOTE_SUPPORTED_FEATURES_COMMAND', 409 HCI_READ_REMOTE_EXTENDED_FEATURES_COMMAND: 'HCI_READ_REMOTE_EXTENDED_FEATURES_COMMAND', 410 HCI_READ_REMOTE_VERSION_INFORMATION_COMMAND: 'HCI_READ_REMOTE_VERSION_INFORMATION_COMMAND', 411 HCI_READ_CLOCK_OFFSET_COMMAND: 'HCI_READ_CLOCK_OFFSET_COMMAND', 412 HCI_IO_CAPABILITY_REQUEST_REPLY_COMMAND: 'HCI_IO_CAPABILITY_REQUEST_REPLY_COMMAND', 413 HCI_USER_CONFIRMATION_REQUEST_REPLY_COMMAND: 'HCI_USER_CONFIRMATION_REQUEST_REPLY_COMMAND', 414 HCI_USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY_COMMAND: 'HCI_USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY_COMMAND', 415 HCI_USER_PASSKEY_REQUEST_REPLY_COMMAND: 'HCI_USER_PASSKEY_REQUEST_REPLY_COMMAND', 416 HCI_USER_PASSKEY_REQUEST_NEGATIVE_REPLY_COMMAND: 'HCI_USER_PASSKEY_REQUEST_NEGATIVE_REPLY_COMMAND', 417 HCI_ENHANCED_SETUP_SYNCHRONOUS_CONNECTION_COMMAND: 'HCI_ENHANCED_SETUP_SYNCHRONOUS_CONNECTION_COMMAND', 418 HCI_SNIFF_MODE_COMMAND: 'HCI_SNIFF_MODE_COMMAND', 419 HCI_EXIT_SNIFF_MODE_COMMAND: 'HCI_EXIT_SNIFF_MODE_COMMAND', 420 HCI_SWITCH_ROLE_COMMAND: 'HCI_SWITCH_ROLE_COMMAND', 421 HCI_WRITE_LINK_POLICY_SETTINGS_COMMAND: 'HCI_WRITE_LINK_POLICY_SETTINGS_COMMAND', 422 HCI_WRITE_DEFAULT_LINK_POLICY_SETTINGS_COMMAND: 'HCI_WRITE_DEFAULT_LINK_POLICY_SETTINGS_COMMAND', 423 HCI_SNIFF_SUBRATING_COMMAND: 'HCI_SNIFF_SUBRATING_COMMAND', 424 HCI_SET_EVENT_MASK_COMMAND: 'HCI_SET_EVENT_MASK_COMMAND', 425 HCI_RESET_COMMAND: 'HCI_RESET_COMMAND', 426 HCI_SET_EVENT_FILTER_COMMAND: 'HCI_SET_EVENT_FILTER_COMMAND', 427 HCI_READ_STORED_LINK_KEY_COMMAND: 'HCI_READ_STORED_LINK_KEY_COMMAND', 428 HCI_DELETE_STORED_LINK_KEY_COMMAND: 'HCI_DELETE_STORED_LINK_KEY_COMMAND', 429 HCI_WRITE_LOCAL_NAME_COMMAND: 'HCI_WRITE_LOCAL_NAME_COMMAND', 430 HCI_READ_LOCAL_NAME_COMMAND: 'HCI_READ_LOCAL_NAME_COMMAND', 431 HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT_COMMAND: 'HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT_COMMAND', 432 HCI_WRITE_PAGE_TIMEOUT_COMMAND: 'HCI_WRITE_PAGE_TIMEOUT_COMMAND', 433 HCI_WRITE_SCAN_ENABLE_COMMAND: 'HCI_WRITE_SCAN_ENABLE_COMMAND', 434 HCI_READ_PAGE_SCAN_ACTIVITY_COMMAND: 'HCI_READ_PAGE_SCAN_ACTIVITY_COMMAND', 435 HCI_WRITE_PAGE_SCAN_ACTIVITY_COMMAND: 'HCI_WRITE_PAGE_SCAN_ACTIVITY_COMMAND', 436 HCI_WRITE_INQUIRY_SCAN_ACTIVITY_COMMAND: 'HCI_WRITE_INQUIRY_SCAN_ACTIVITY_COMMAND', 437 HCI_READ_CLASS_OF_DEVICE_COMMAND: 'HCI_READ_CLASS_OF_DEVICE_COMMAND', 438 HCI_WRITE_CLASS_OF_DEVICE_COMMAND: 'HCI_WRITE_CLASS_OF_DEVICE_COMMAND', 439 HCI_READ_VOICE_SETTING_COMMAND: 'HCI_READ_VOICE_SETTING_COMMAND', 440 HCI_WRITE_VOICE_SETTING_COMMAND: 'HCI_WRITE_VOICE_SETTING_COMMAND', 441 HCI_READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE_COMMAND: 'HCI_READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE_COMMAND', 442 HCI_WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE_COMMAND: 'HCI_WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE_COMMAND', 443 HCI_HOST_BUFFER_SIZE_COMMAND: 'HCI_HOST_BUFFER_SIZE_COMMAND', 444 HCI_WRITE_LINK_SUPERVISION_TIMEOUT_COMMAND: 'HCI_WRITE_LINK_SUPERVISION_TIMEOUT_COMMAND', 445 HCI_READ_NUMBER_OF_SUPPORTED_IAC_COMMAND: 'HCI_READ_NUMBER_OF_SUPPORTED_IAC_COMMAND', 446 HCI_READ_CURRENT_IAC_LAP_COMMAND: 'HCI_READ_CURRENT_IAC_LAP_COMMAND', 447 HCI_WRITE_INQUIRY_SCAN_TYPE_COMMAND: 'HCI_WRITE_INQUIRY_SCAN_TYPE_COMMAND', 448 HCI_WRITE_INQUIRY_MODE_COMMAND: 'HCI_WRITE_INQUIRY_MODE_COMMAND', 449 HCI_READ_PAGE_SCAN_TYPE_COMMAND: 'HCI_READ_PAGE_SCAN_TYPE_COMMAND', 450 HCI_WRITE_PAGE_SCAN_TYPE_COMMAND: 'HCI_WRITE_PAGE_SCAN_TYPE_COMMAND', 451 HCI_WRITE_EXTENDED_INQUIRY_RESPONSE_COMMAND: 'HCI_WRITE_EXTENDED_INQUIRY_RESPONSE_COMMAND', 452 HCI_WRITE_SIMPLE_PAIRING_MODE_COMMAND: 'HCI_WRITE_SIMPLE_PAIRING_MODE_COMMAND', 453 HCI_READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL_COMMAND: 'HCI_READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL_COMMAND', 454 HCI_SET_EVENT_MASK_PAGE_2_COMMAND: 'HCI_SET_EVENT_MASK_PAGE_2_COMMAND', 455 HCI_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_COMMAND: 'HCI_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_COMMAND', 456 HCI_READ_LOCAL_VERSION_INFORMATION_COMMAND: 'HCI_READ_LOCAL_VERSION_INFORMATION_COMMAND', 457 HCI_READ_LOCAL_SUPPORTED_COMMANDS_COMMAND: 'HCI_READ_LOCAL_SUPPORTED_COMMANDS_COMMAND', 458 HCI_READ_LOCAL_SUPPORTED_FEATURES_COMMAND: 'HCI_READ_LOCAL_SUPPORTED_FEATURES_COMMAND', 459 HCI_READ_LOCAL_EXTENDED_FEATURES_COMMAND: 'HCI_READ_LOCAL_EXTENDED_FEATURES_COMMAND', 460 HCI_READ_BUFFER_SIZE_COMMAND: 'HCI_READ_BUFFER_SIZE_COMMAND', 461 HCI_READ_LE_HOST_SUPPORT_COMMAND: 'HCI_READ_LE_HOST_SUPPORT_COMMAND', 462 HCI_WRITE_LE_HOST_SUPPORT_COMMAND: 'HCI_WRITE_LE_HOST_SUPPORT_COMMAND', 463 HCI_WRITE_SECURE_CONNECTIONS_HOST_SUPPORT_COMMAND: 'HCI_WRITE_SECURE_CONNECTIONS_HOST_SUPPORT_COMMAND', 464 HCI_WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT_COMMAND: 'HCI_WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT_COMMAND', 465 HCI_READ_BD_ADDR_COMMAND: 'HCI_READ_BD_ADDR_COMMAND', 466 HCI_READ_LOCAL_SUPPORTED_CODECS_COMMAND: 'HCI_READ_LOCAL_SUPPORTED_CODECS_COMMAND', 467 HCI_READ_ENCRYPTION_KEY_SIZE_COMMAND: 'HCI_READ_ENCRYPTION_KEY_SIZE_COMMAND', 468 HCI_LE_SET_EVENT_MASK_COMMAND: 'HCI_LE_SET_EVENT_MASK_COMMAND', 469 HCI_LE_READ_BUFFER_SIZE_COMMAND: 'HCI_LE_READ_BUFFER_SIZE_COMMAND', 470 HCI_LE_READ_LOCAL_SUPPORTED_FEATURES_COMMAND: 'HCI_LE_READ_LOCAL_SUPPORTED_FEATURES_COMMAND', 471 HCI_LE_SET_RANDOM_ADDRESS_COMMAND: 'HCI_LE_SET_RANDOM_ADDRESS_COMMAND', 472 HCI_LE_SET_ADVERTISING_PARAMETERS_COMMAND: 'HCI_LE_SET_ADVERTISING_PARAMETERS_COMMAND', 473 HCI_LE_READ_ADVERTISING_CHANNEL_TX_POWER_COMMAND: 'HCI_LE_READ_ADVERTISING_CHANNEL_TX_POWER_COMMAND', 474 HCI_LE_SET_ADVERTISING_DATA_COMMAND: 'HCI_LE_SET_ADVERTISING_DATA_COMMAND', 475 HCI_LE_SET_SCAN_RESPONSE_DATA_COMMAND: 'HCI_LE_SET_SCAN_RESPONSE_DATA_COMMAND', 476 HCI_LE_SET_ADVERTISING_ENABLE_COMMAND: 'HCI_LE_SET_ADVERTISING_ENABLE_COMMAND', 477 HCI_LE_SET_SCAN_PARAMETERS_COMMAND: 'HCI_LE_SET_SCAN_PARAMETERS_COMMAND', 478 HCI_LE_SET_SCAN_ENABLE_COMMAND: 'HCI_LE_SET_SCAN_ENABLE_COMMAND', 479 HCI_LE_CREATE_CONNECTION_COMMAND: 'HCI_LE_CREATE_CONNECTION_COMMAND', 480 HCI_LE_CREATE_CONNECTION_CANCEL_COMMAND: 'HCI_LE_CREATE_CONNECTION_CANCEL_COMMAND', 481 HCI_LE_READ_WHITE_LIST_SIZE_COMMAND: 'HCI_LE_READ_WHITE_LIST_SIZE_COMMAND', 482 HCI_LE_CLEAR_WHITE_LIST_COMMAND: 'HCI_LE_CLEAR_WHITE_LIST_COMMAND', 483 HCI_LE_ADD_DEVICE_TO_WHITE_LIST_COMMAND: 'HCI_LE_ADD_DEVICE_TO_WHITE_LIST_COMMAND', 484 HCI_LE_REMOVE_DEVICE_FROM_WHITE_LIST_COMMAND: 'HCI_LE_REMOVE_DEVICE_FROM_WHITE_LIST_COMMAND', 485 HCI_LE_CONNECTION_UPDATE_COMMAND: 'HCI_LE_CONNECTION_UPDATE_COMMAND', 486 HCI_LE_SET_HOST_CHANNEL_CLASSIFICATION_COMMAND: 'HCI_LE_SET_HOST_CHANNEL_CLASSIFICATION_COMMAND', 487 HCI_LE_READ_CHANNEL_MAP_COMMAND: 'HCI_LE_READ_CHANNEL_MAP_COMMAND', 488 HCI_LE_READ_REMOTE_FEATURES_COMMAND: 'HCI_LE_READ_REMOTE_FEATURES_COMMAND', 489 HCI_LE_ENCRYPT_COMMAND: 'HCI_LE_ENCRYPT_COMMAND', 490 HCI_LE_RAND_COMMAND: 'HCI_LE_RAND_COMMAND', 491 HCI_LE_START_ENCRYPTION_COMMAND: 'HCI_LE_START_ENCRYPTION_COMMAND', 492 HCI_LE_LONG_TERM_KEY_REQUEST_REPLY_COMMAND: 'HCI_LE_LONG_TERM_KEY_REQUEST_REPLY_COMMAND', 493 HCI_LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY_COMMAND: 'HCI_LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY_COMMAND', 494 HCI_LE_READ_SUPPORTED_STATES_COMMAND: 'HCI_LE_READ_SUPPORTED_STATES_COMMAND', 495 HCI_LE_RECEIVER_TEST_COMMAND: 'HCI_LE_RECEIVER_TEST_COMMAND', 496 HCI_LE_TRANSMITTER_TEST_COMMAND: 'HCI_LE_TRANSMITTER_TEST_COMMAND', 497 HCI_LE_TEST_END_COMMAND: 'HCI_LE_TEST_END_COMMAND', 498 HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY_COMMAND: 'HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY_COMMAND', 499 HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY_COMMAND: 'HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY_COMMAND', 500 HCI_LE_SET_DATA_LENGTH_COMMAND: 'HCI_LE_SET_DATA_LENGTH_COMMAND', 501 HCI_LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH_COMMAND: 'HCI_LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH_COMMAND', 502 HCI_LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH_COMMAND: 'HCI_LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH_COMMAND', 503 HCI_LE_READ_LOCAL_P_256_PUBLIC_KEY_COMMAND: 'HCI_LE_READ_LOCAL_P_256_PUBLIC_KEY_COMMAND', 504 HCI_LE_GENERATE_DHKEY_COMMAND: 'HCI_LE_GENERATE_DHKEY_COMMAND', 505 HCI_LE_ADD_DEVICE_TO_RESOLVING_LIST_COMMAND: 'HCI_LE_ADD_DEVICE_TO_RESOLVING_LIST_COMMAND', 506 HCI_LE_REMOVE_DEVICE_FROM_RESOLVING_LIST_COMMAND: 'HCI_LE_REMOVE_DEVICE_FROM_RESOLVING_LIST_COMMAND', 507 HCI_LE_CLEAR_RESOLVING_LIST_COMMAND: 'HCI_LE_CLEAR_RESOLVING_LIST_COMMAND', 508 HCI_LE_READ_RESOLVING_LIST_SIZE_COMMAND: 'HCI_LE_READ_RESOLVING_LIST_SIZE_COMMAND', 509 HCI_LE_READ_PEER_RESOLVABLE_ADDRESS_COMMAND: 'HCI_LE_READ_PEER_RESOLVABLE_ADDRESS_COMMAND', 510 HCI_LE_READ_LOCAL_RESOLVABLE_ADDRESS_COMMAND: 'HCI_LE_READ_LOCAL_RESOLVABLE_ADDRESS_COMMAND', 511 HCI_LE_SET_ADDRESS_RESOLUTION_ENABLE_COMMAND: 'HCI_LE_SET_ADDRESS_RESOLUTION_ENABLE_COMMAND', 512 HCI_LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT_COMMAND: 'HCI_LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT_COMMAND', 513 HCI_LE_READ_MAXIMUM_DATA_LENGTH_COMMAND: 'HCI_LE_READ_MAXIMUM_DATA_LENGTH_COMMAND', 514 HCI_LE_READ_PHY_COMMAND: 'HCI_LE_READ_PHY_COMMAND', 515 HCI_LE_SET_DEFAULT_PHY_COMMAND: 'HCI_LE_SET_DEFAULT_PHY_COMMAND', 516 HCI_LE_SET_PHY_COMMAND: 'HCI_LE_SET_PHY_COMMAND', 517 HCI_LE_ENHANCED_RECEIVER_TEST_COMMAND: 'HCI_LE_ENHANCED_RECEIVER_TEST_COMMAND', 518 HCI_LE_ENHANCED_TRANSMITTER_TEST_COMMAND: 'HCI_LE_ENHANCED_TRANSMITTER_TEST_COMMAND', 519 HCI_LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_COMMAND: 'HCI_LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_COMMAND', 520 HCI_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_COMMAND: 'HCI_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_COMMAND', 521 HCI_LE_SET_EXTENDED_ADVERTISING_DATA_COMMAND: 'HCI_LE_SET_EXTENDED_ADVERTISING_DATA_COMMAND', 522 HCI_LE_SET_EXTENDED_SCAN_RESPONSE_DATA_COMMAND: 'HCI_LE_SET_EXTENDED_SCAN_RESPONSE_DATA_COMMAND', 523 HCI_LE_SET_EXTENDED_ADVERTISING_ENABLE_COMMAND: 'HCI_LE_SET_EXTENDED_ADVERTISING_ENABLE_COMMAND', 524 HCI_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH_COMMAND: 'HCI_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH_COMMAND', 525 HCI_LE_READ_NUMBER_OF_SUPPORTED_ADVERETISING_SETS_COMMAND: 'HCI_LE_READ_NUMBER_OF_SUPPORTED_ADVERETISING_SETS_COMMAND', 526 HCI_LE_REMOVE_ADVERTISING_SET_COMMAND: 'HCI_LE_REMOVE_ADVERTISING_SET_COMMAND', 527 HCI_LE_CLEAR_ADVERTISING_SETS_COMMAND: 'HCI_LE_CLEAR_ADVERTISING_SETS_COMMAND', 528 HCI_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_COMMAND: 'HCI_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_COMMAND', 529 HCI_LE_SET_PERIODIC_ADVERTISING_DATA_COMMAND: 'HCI_LE_SET_PERIODIC_ADVERTISING_DATA_COMMAND', 530 HCI_LE_SET_PERIODIC_ADVERTISING_ENABLE_COMMAND: 'HCI_LE_SET_PERIODIC_ADVERTISING_ENABLE_COMMAND', 531 HCI_LE_SET_EXTENDED_SCAN_PARAMETERS_COMMAND: 'HCI_LE_SET_EXTENDED_SCAN_PARAMETERS_COMMAND', 532 HCI_LE_SET_EXTENDED_SCAN_ENABLE_COMMAND: 'HCI_LE_SET_EXTENDED_SCAN_ENABLE_COMMAND', 533 HCI_LE_SET_EXTENDED_CREATE_CONNECTION_COMMAND: 'HCI_LE_SET_EXTENDED_CREATE_CONNECTION_COMMAND', 534 HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC_COMMAND: 'HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC_COMMAND', 535 HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL_COMMAND: 'HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL_COMMAND', 536 HCI_LE_PERIODIC_ADVERTISING_TERMINATE_SYNC_COMMAND: 'HCI_LE_PERIODIC_ADVERTISING_TERMINATE_SYNC_COMMAND', 537 HCI_LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST_COMMAND: 'HCI_LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST_COMMAND', 538 HCI_LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST_COMMAND: 'HCI_LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST_COMMAND', 539 HCI_LE_CLEAR_PERIODIC_ADVERTISER_LIST_COMMAND: 'HCI_LE_CLEAR_PERIODIC_ADVERTISER_LIST_COMMAND', 540 HCI_LE_READ_PERIODIC_ADVERTISER_LIST_SIZE_COMMAND: 'HCI_LE_READ_PERIODIC_ADVERTISER_LIST_SIZE_COMMAND', 541 HCI_LE_READ_TRANSMIT_POWER_COMMAND: 'HCI_LE_READ_TRANSMIT_POWER_COMMAND', 542 HCI_LE_READ_RF_PATH_COMPENSATION_COMMAND: 'HCI_LE_READ_RF_PATH_COMPENSATION_COMMAND', 543 HCI_LE_WRITE_RF_PATH_COMPENSATION_COMMAND: 'HCI_LE_WRITE_RF_PATH_COMPENSATION_COMMAND', 544 HCI_LE_SET_PRIVACY_MODE_COMMAND: 'HCI_LE_SET_PRIVACY_MODE_COMMAND' 545} 546 547 548# HCI Error Codes 549# See Bluetooth spec Vol 2, Part D - 1.3 LIST OF ERROR CODES 550HCI_SUCCESS = 0x00 551HCI_UNKNOWN_HCI_COMMAND_ERROR = 0x01 552HCI_UNKNOWN_CONNECTION_IDENTIFIER_ERROR = 0x02 553HCI_HARDWARE_FAILURE_ERROR = 0x03 554HCI_PAGE_TIMEOUT_ERROR = 0x04 555HCI_AUTHENTICATION_FAILURE_ERROR = 0x05 556HCI_PIN_OR_KEY_MISSING_ERROR = 0x06 557HCI_MEMORY_CAPACITY_EXCEEDED_ERROR = 0x07 558HCI_CONNECTION_TIMEOUT_ERROR = 0x08 559HCI_CONNECTION_LIMIT_EXCEEDED_ERROR = 0x09 560HCI_SYNCHRONOUS_CONNECTION_LIMIT_TO_A_DEVICE_EXCEEDED_ERROR = 0x0A 561HCI_CONNECTION_ALREADY_EXISTS_ERROR = 0x0B 562HCI_COMMAND_DISALLOWED_ERROR = 0x0C 563HCI_CONNECTION_REJECTED_DUE_TO_LIMITED_RESOURCES_ERROR = 0x0D 564HCI_CONNECTION_REJECTED_DUE_TO_SECURITY_REASONS_ERROR = 0x0E 565HCI_CONNECTION_REJECTED_DUE_TO_UNACCEPTABLE_BD_ADDR_ERROR = 0x0F 566HCI_CONNECTION_ACCEPT_TIMEOUT_ERROR = 0x10 567HCI_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE_ERROR = 0x11 568HCI_INVALID_HCI_COMMAND_PARAMETERS_ERROR = 0x12 569HCI_REMOTE_USER_TERMINATED_CONNECTION_ERROR = 0x13 570HCI_REMOTE_DEVICE_TERMINATED_CONNECTION_DUE_TO_LOW_RESOURCES_ERROR = 0x14 571HCI_REMOTE_DEVICE_TERMINATED_CONNECTION_DUE_TO_POWER_OFF_ERROR = 0x15 572HCI_CONNECTION_TERMINATED_BY_LOCAL_HOST_ERROR = 0x16 573HCI_UNACCEPTABLE_CONNECTION_PARAMETERS_ERROR = 0x3B 574HCI_CONNECTION_FAILED_TO_BE_ESTABLISHED_ERROR = 0x3E 575# TODO: more error codes 576 577HCI_ERROR_NAMES = { 578 HCI_SUCCESS: 'HCI_SUCCESS', 579 HCI_UNKNOWN_HCI_COMMAND_ERROR: 'HCI_UNKNOWN_HCI_COMMAND_ERROR', 580 HCI_UNKNOWN_CONNECTION_IDENTIFIER_ERROR: 'HCI_UNKNOWN_CONNECTION_IDENTIFIER_ERROR', 581 HCI_HARDWARE_FAILURE_ERROR: 'HCI_HARDWARE_FAILURE_ERROR', 582 HCI_PAGE_TIMEOUT_ERROR: 'HCI_PAGE_TIMEOUT_ERROR', 583 HCI_AUTHENTICATION_FAILURE_ERROR: 'HCI_AUTHENTICATION_FAILURE_ERROR', 584 HCI_PIN_OR_KEY_MISSING_ERROR: 'HCI_PIN_OR_KEY_MISSING_ERROR', 585 HCI_MEMORY_CAPACITY_EXCEEDED_ERROR: 'HCI_MEMORY_CAPACITY_EXCEEDED_ERROR', 586 HCI_CONNECTION_TIMEOUT_ERROR: 'HCI_CONNECTION_TIMEOUT_ERROR', 587 HCI_CONNECTION_LIMIT_EXCEEDED_ERROR: 'HCI_CONNECTION_LIMIT_EXCEEDED_ERROR', 588 HCI_SYNCHRONOUS_CONNECTION_LIMIT_TO_A_DEVICE_EXCEEDED_ERROR: 'HCI_SYNCHRONOUS_CONNECTION_LIMIT_TO_A_DEVICE_EXCEEDED_ERROR', 589 HCI_CONNECTION_ALREADY_EXISTS_ERROR: 'HCI_CONNECTION_ALREADY_EXISTS_ERROR', 590 HCI_COMMAND_DISALLOWED_ERROR: 'HCI_COMMAND_DISALLOWED_ERROR', 591 HCI_CONNECTION_REJECTED_DUE_TO_LIMITED_RESOURCES_ERROR: 'HCI_CONNECTION_REJECTED_DUE_TO_LIMITED_RESOURCES_ERROR', 592 HCI_CONNECTION_REJECTED_DUE_TO_SECURITY_REASONS_ERROR: 'HCI_CONNECTION_REJECTED_DUE_TO_SECURITY_REASONS_ERROR', 593 HCI_CONNECTION_REJECTED_DUE_TO_UNACCEPTABLE_BD_ADDR_ERROR: 'HCI_CONNECTION_REJECTED_DUE_TO_UNACCEPTABLE_BD_ADDR_ERROR', 594 HCI_CONNECTION_ACCEPT_TIMEOUT_ERROR: 'HCI_CONNECTION_ACCEPT_TIMEOUT_ERROR', 595 HCI_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE_ERROR: 'HCI_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE_ERROR', 596 HCI_INVALID_HCI_COMMAND_PARAMETERS_ERROR: 'HCI_INVALID_HCI_COMMAND_PARAMETERS_ERROR', 597 HCI_REMOTE_USER_TERMINATED_CONNECTION_ERROR: 'HCI_REMOTE_USER_TERMINATED_CONNECTION_ERROR', 598 HCI_REMOTE_DEVICE_TERMINATED_CONNECTION_DUE_TO_LOW_RESOURCES_ERROR: 'HCI_REMOTE_DEVICE_TERMINATED_CONNECTION_DUE_TO_LOW_RESOURCES_ERROR', 599 HCI_REMOTE_DEVICE_TERMINATED_CONNECTION_DUE_TO_POWER_OFF_ERROR: 'HCI_REMOTE_DEVICE_TERMINATED_CONNECTION_DUE_TO_POWER_OFF_ERROR', 600 HCI_CONNECTION_TERMINATED_BY_LOCAL_HOST_ERROR: 'HCI_CONNECTION_TERMINATED_BY_LOCAL_HOST_ERROR', 601 HCI_UNACCEPTABLE_CONNECTION_PARAMETERS_ERROR: 'HCI_UNACCEPTABLE_CONNECTION_PARAMETERS_ERROR', 602 HCI_CONNECTION_FAILED_TO_BE_ESTABLISHED_ERROR: 'HCI_CONNECTION_FAILED_TO_BE_ESTABLISHED_ERROR' 603} 604 605# Command Status codes 606HCI_COMMAND_STATUS_PENDING = 0 607 608# LE Event Masks 609LE_CONNECTION_COMPLETE_EVENT_MASK = (1 << 0) 610LE_ADVERTISING_REPORT_EVENT_MASK = (1 << 1) 611LE_CONNECTION_UPDATE_COMPLETE_EVENT_MASK = (1 << 2) 612LE_READ_REMOTE_FEATURES_COMPLETE_EVENT_MASK = (1 << 3) 613LE_LONG_TERM_KEY_REQUEST_EVENT_MASK = (1 << 4) 614LE_REMOTE_CONNECTION_PARAMETER_REQUEST_EVENT_MASK = (1 << 5) 615LE_DATA_LENGTH_CHANGE_EVENT_MASK = (1 << 6) 616LE_READ_LOCAL_P_256_PUBLIC_KEY_COMPLETE_EVENT_MASK = (1 << 7) 617LE_GENERATE_DHKEY_COMPLETE_EVENT_MASK = (1 << 8) 618LE_ENHANCED_CONNECTION_COMPLETE_EVENT_MASK = (1 << 9) 619LE_DIRECTED_ADVERTISING_REPORT_EVENT_MASK = (1 << 10) 620LE_PHY_UPDATE_COMPLETE_EVENT_MASK = (1 << 11) 621LE_EXTENDED_ADVERTISING_REPORT_EVENT_MASK = (1 << 12) 622LE_PERIODIC_ADVERTISING_SYNC_ESTABLISHED_EVENT_MASK = (1 << 13) 623LE_PERIODIC_ADVERTISING_REPORT_EVENT_MASK = (1 << 14) 624LE_PERIODIC_ADVERTISING_SYNC_LOST_EVENT_MASK = (1 << 15) 625LE_EXTENDED_SCAN_TIMEOUT_EVENT_MASK = (1 << 16) 626LE_EXTENDED_ADVERTISING_SET_TERMINATED_EVENT_MASK = (1 << 17) 627LE_SCAN_REQUEST_RECEIVED_EVENT_MASK = (1 << 18) 628LE_CHANNEL_SELECTION_ALGORITHM_EVENT_MASK = (1 << 19) 629 630# ACL 631HCI_ACL_PB_FIRST_NON_FLUSHABLE = 0 632HCI_ACL_PB_CONTINUATION = 1 633HCI_ACL_PB_FIRST_FLUSHABLE = 2 634HCI_ACK_PB_COMPLETE_L2CAP = 3 635 636# Roles 637HCI_CENTRAL_ROLE = 0 638HCI_PERIPHERAL_ROLE = 1 639 640HCI_ROLE_NAMES = { 641 HCI_CENTRAL_ROLE: 'CENTRAL', 642 HCI_PERIPHERAL_ROLE: 'PERIPHERAL' 643} 644 645# LE PHY Types 646HCI_LE_1M_PHY = 1 647HCI_LE_2M_PHY = 2 648HCI_LE_CODED_PHY = 3 649 650HCI_LE_PHY_NAMES = { 651 HCI_LE_1M_PHY: 'LE 1M', 652 HCI_LE_2M_PHY: 'L2 2M', 653 HCI_LE_CODED_PHY: 'LE Coded' 654} 655 656# Connection Parameters 657HCI_CONNECTION_INTERVAL_MS_PER_UNIT = 1.25 658HCI_CONNECTION_LATENCY_MS_PER_UNIT = 1.25 659HCI_SUPERVISION_TIMEOUT_MS_PER_UNIT = 10 660 661# Inquiry LAP 662HCI_LIMITED_DEDICATED_INQUIRY_LAP = 0x9E8B00 663HCI_GENERAL_INQUIRY_LAP = 0x9E8B33 664HCI_INQUIRY_LAP_NAMES = { 665 HCI_LIMITED_DEDICATED_INQUIRY_LAP: 'Limited Dedicated Inquiry', 666 HCI_GENERAL_INQUIRY_LAP: 'General Inquiry' 667} 668 669# Inquiry Mode 670HCI_STANDARD_INQUIRY_MODE = 0x00 671HCI_INQUIRY_WITH_RSSI_MODE = 0x01 672HCI_EXTENDED_INQUIRY_MODE = 0x02 673 674# Page Scan Repetition Mode 675HCI_R0_PAGE_SCAN_REPETITION_MODE = 0x00 676HCI_R1_PAGE_SCAN_REPETITION_MODE = 0x01 677HCI_R2_PAGE_SCAN_REPETITION_MODE = 0x02 678 679# IO Capability 680HCI_DISPLAY_ONLY_IO_CAPABILITY = 0x00 681HCI_DISPLAY_YES_NO_IO_CAPABILITY = 0x01 682HCI_KEYBOARD_ONLY_IO_CAPABILITY = 0x02 683HCI_NO_INPUT_NO_OUTPUT_IO_CAPABILITY = 0x03 684 685HCI_IO_CAPABILITY_NAMES = { 686 HCI_DISPLAY_ONLY_IO_CAPABILITY: 'HCI_DISPLAY_ONLY_IO_CAPABILITY', 687 HCI_DISPLAY_YES_NO_IO_CAPABILITY: 'HCI_DISPLAY_YES_NO_IO_CAPABILITY', 688 HCI_KEYBOARD_ONLY_IO_CAPABILITY: 'HCI_KEYBOARD_ONLY_IO_CAPABILITY', 689 HCI_NO_INPUT_NO_OUTPUT_IO_CAPABILITY: 'HCI_NO_INPUT_NO_OUTPUT_IO_CAPABILITY' 690} 691 692# Authentication Requirements 693HCI_MITM_NOT_REQUIRED_NO_BONDING_AUTHENTICATION_REQUIREMENTS = 0x00 694HCI_MITM_REQUIRED_NO_BONDING_AUTHENTICATION_REQUIREMENTS = 0x01 695HCI_MITM_NOT_REQUIRED_DEDICATED_BONDING_AUTHENTICATION_REQUIREMENTS = 0x02 696HCI_MITM_REQUIRED_DEDICATED_BONDING_AUTHENTICATION_REQUIREMENTS = 0x03 697HCI_MITM_NOT_REQUIRED_GENERAL_BONDING_AUTHENTICATION_REQUIREMENTS = 0x04 698HCI_MITM_REQUIRED_GENERAL_BONDING_AUTHENTICATION_REQUIREMENTS = 0x05 699 700HCI_AUTHENTICATION_REQUIREMENTS_NAMES = { 701 HCI_MITM_NOT_REQUIRED_NO_BONDING_AUTHENTICATION_REQUIREMENTS: 'HCI_MITM_NOT_REQUIRED_NO_BONDING_AUTHENTICATION_REQUIREMENTS', 702 HCI_MITM_REQUIRED_NO_BONDING_AUTHENTICATION_REQUIREMENTS: 'HCI_MITM_REQUIRED_NO_BONDING_AUTHENTICATION_REQUIREMENTS', 703 HCI_MITM_NOT_REQUIRED_DEDICATED_BONDING_AUTHENTICATION_REQUIREMENTS: 'HCI_MITM_NOT_REQUIRED_DEDICATED_BONDING_AUTHENTICATION_REQUIREMENTS', 704 HCI_MITM_REQUIRED_DEDICATED_BONDING_AUTHENTICATION_REQUIREMENTS: 'HCI_MITM_REQUIRED_DEDICATED_BONDING_AUTHENTICATION_REQUIREMENTS', 705 HCI_MITM_NOT_REQUIRED_GENERAL_BONDING_AUTHENTICATION_REQUIREMENTS: 'HCI_MITM_NOT_REQUIRED_GENERAL_BONDING_AUTHENTICATION_REQUIREMENTS', 706 HCI_MITM_REQUIRED_GENERAL_BONDING_AUTHENTICATION_REQUIREMENTS: 'HCI_MITM_REQUIRED_GENERAL_BONDING_AUTHENTICATION_REQUIREMENTS' 707} 708 709# Link Key Types 710HCI_COMBINATION_KEY_TYPE = 0X00 711HCI_LOCAL_UNIT_KEY_TYPE = 0X01 712HCI_REMOTE_UNIT_KEY_TYPE = 0X02 713HCI_DEBUG_COMBINATION_KEY_TYPE = 0X03 714HCI_UNAUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_192_TYPE = 0X04 715HCI_AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_192_TYPE = 0X05 716HCI_CHANGED_COMBINATION_KEY_TYPE = 0X06 717HCI_UNAUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_256_TYPE = 0X07 718HCI_AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_256_TYPE = 0X08 719 720HCI_LINK_TYPE_NAMES = { 721 HCI_COMBINATION_KEY_TYPE: 'HCI_COMBINATION_KEY_TYPE', 722 HCI_LOCAL_UNIT_KEY_TYPE: 'HCI_LOCAL_UNIT_KEY_TYPE', 723 HCI_REMOTE_UNIT_KEY_TYPE: 'HCI_REMOTE_UNIT_KEY_TYPE', 724 HCI_DEBUG_COMBINATION_KEY_TYPE: 'HCI_DEBUG_COMBINATION_KEY_TYPE', 725 HCI_UNAUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_192_TYPE: 'HCI_UNAUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_192_TYPE', 726 HCI_AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_192_TYPE: 'HCI_AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_192_TYPE', 727 HCI_CHANGED_COMBINATION_KEY_TYPE: 'HCI_CHANGED_COMBINATION_KEY_TYPE', 728 HCI_UNAUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_256_TYPE: 'HCI_UNAUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_256_TYPE', 729 HCI_AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_256_TYPE: 'HCI_AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_256_TYPE' 730} 731 732# Address types 733HCI_PUBLIC_DEVICE_ADDRESS_TYPE = 0x00 734HCI_RANDOM_DEVICE_ADDRESS_TYPE = 0x01 735HCI_PUBLIC_IDENTITY_ADDRESS_TYPE = 0x02 736HCI_RANDOM_IDENTITY_ADDRESS_TYPE = 0x03 737 738# ----------------------------------------------------------------------------- 739STATUS_SPEC = {'size': 1, 'mapper': lambda x: HCI_Constant.status_name(x)} 740 741 742# ----------------------------------------------------------------------------- 743class HCI_Constant: 744 @staticmethod 745 def status_name(status): 746 return HCI_ERROR_NAMES.get(status, f'0x{status:02X}') 747 748 @staticmethod 749 def error_name(status): 750 return HCI_ERROR_NAMES.get(status, f'0x{status:02X}') 751 752 @staticmethod 753 def role_name(role): 754 return HCI_ROLE_NAMES.get(role, str(role)) 755 756 @staticmethod 757 def le_phy_name(phy): 758 return HCI_LE_PHY_NAMES.get(phy, str(phy)) 759 760 @staticmethod 761 def inquiry_lap_name(lap): 762 return HCI_INQUIRY_LAP_NAMES.get(lap, f'0x{lap:06X}') 763 764 @staticmethod 765 def io_capability_name(io_capability): 766 return HCI_IO_CAPABILITY_NAMES.get(io_capability, f'0x{io_capability:02X}') 767 768 @staticmethod 769 def authentication_requirements_name(authentication_requirements): 770 return HCI_AUTHENTICATION_REQUIREMENTS_NAMES.get( 771 authentication_requirements, 772 f'0x{authentication_requirements:02X}' 773 ) 774 775 @staticmethod 776 def link_key_type_name(link_key_type): 777 return HCI_LINK_TYPE_NAMES.get(link_key_type, f'0x{link_key_type:02X}') 778 779 780# ----------------------------------------------------------------------------- 781class HCI_Error(ProtocolError): 782 def __init__(self, error_code): 783 super().__init__(error_code, 'hci', HCI_Constant.error_name(error_code)) 784 785 786# ----------------------------------------------------------------------------- 787# Generic HCI object 788# ----------------------------------------------------------------------------- 789class HCI_Object: 790 @staticmethod 791 def init_from_fields(object, fields, values): 792 if type(values) is dict: 793 for field_name, _ in fields: 794 setattr(object, field_name, values[field_name]) 795 else: 796 for field_name, field_value in zip(fields, values): 797 setattr(object, field_name, field_value) 798 799 @staticmethod 800 def init_from_bytes(object, data, offset, fields): 801 parsed = HCI_Object.dict_from_bytes(data, offset, fields) 802 HCI_Object.init_from_fields(object, parsed.keys(), parsed.values()) 803 804 @staticmethod 805 def dict_from_bytes(data, offset, fields): 806 result = collections.OrderedDict() 807 for (field_name, field_type) in fields: 808 # The field_type may be a dictionnary with a mapper, parser, and/or size 809 if type(field_type) is dict: 810 if 'size' in field_type: 811 field_type = field_type['size'] 812 elif 'parser' in field_type: 813 field_type = field_type['parser'] 814 815 # Parse the field 816 if field_type == '*': 817 # The rest of the bytes 818 field_value = data[offset:] 819 offset += len(field_value) 820 elif field_type == 1: 821 # 8-bit unsigned 822 field_value = data[offset] 823 offset += 1 824 elif field_type == -1: 825 # 8-bit signed 826 field_value = struct.unpack_from('b', data, offset)[0] 827 offset += 1 828 elif field_type == 2: 829 # 16-bit unsigned 830 field_value = struct.unpack_from('<H', data, offset)[0] 831 offset += 2 832 elif field_type == '>2': 833 # 16-bit unsigned big-endian 834 field_value = struct.unpack_from('>H', data, offset)[0] 835 offset += 2 836 elif field_type == -2: 837 # 16-bit signed 838 field_value = struct.unpack_from('<h', data, offset)[0] 839 offset += 1 840 elif field_type == 3: 841 # 24-bit unsigned 842 padded = data[offset:offset + 3] + bytes([0]) 843 field_value = struct.unpack('<I', padded)[0] 844 offset += 3 845 elif field_type == 4: 846 # 32-bit unsigned 847 field_value = struct.unpack_from('<I', data, offset)[0] 848 offset += 4 849 elif field_type == '>4': 850 # 32-bit unsigned big-endian 851 field_value = struct.unpack_from('>I', data, offset)[0] 852 offset += 4 853 elif type(field_type) is int and field_type > 4 and field_type <= 256: 854 # Byte array (from 5 up to 256 bytes) 855 field_value = data[offset:offset + field_type] 856 offset += field_type 857 elif callable(field_type): 858 offset, field_value = field_type(data, offset) 859 else: 860 raise ValueError(f'unknown field type {field_type}') 861 862 result[field_name] = field_value 863 864 return result 865 866 @staticmethod 867 def dict_to_bytes(object, fields): 868 result = bytearray() 869 for (field_name, field_type) in fields: 870 # The field_type may be a dictionnary with a mapper, parser, serializer, and/or size 871 serializer = None 872 if type(field_type) is dict: 873 if 'serializer' in field_type: 874 serializer = field_type['serializer'] 875 if 'size' in field_type: 876 field_type = field_type['size'] 877 878 # Serialize the field 879 field_value = object[field_name] 880 if serializer: 881 field_bytes = serializer(field_value) 882 elif field_type == 1: 883 # 8-bit unsigned 884 field_bytes = bytes([field_value]) 885 elif field_type == -1: 886 # 8-bit signed 887 field_bytes = struct.pack('b', field_value) 888 elif field_type == 2: 889 # 16-bit unsigned 890 field_bytes = struct.pack('<H', field_value) 891 elif field_type == '>2': 892 # 16-bit unsigned big-endian 893 field_bytes = struct.pack('>H', field_value) 894 elif field_type == -2: 895 # 16-bit signed 896 field_bytes = struct.pack('<h', field_value) 897 elif field_type == 3: 898 # 24-bit unsigned 899 field_bytes = struct.pack('<I', field_value)[0:3] 900 elif field_type == 4: 901 # 32-bit unsigned 902 field_bytes = struct.pack('<I', field_value) 903 elif field_type == '>4': 904 # 32-bit unsigned big-endian 905 field_bytes = struct.pack('>I', field_value) 906 elif field_type == '*': 907 if type(field_value) is int: 908 if field_value >= 0 and field_value <= 255: 909 field_bytes = bytes([field_value]) 910 else: 911 raise ValueError('value too large for *-typed field') 912 else: 913 field_bytes = bytes(field_value) 914 elif type(field_value) is bytes or type(field_value) is bytearray or hasattr(field_value, 'to_bytes'): 915 field_bytes = bytes(field_value) 916 if type(field_type) is int and field_type > 4 and field_type <= 256: 917 # Truncate or Pad with zeros if the field is too long or too short 918 if len(field_bytes) < field_type: 919 field_bytes += bytes(field_type - len(field_bytes)) 920 elif len(field_bytes) > field_type: 921 field_bytes = field_bytes[:field_type] 922 else: 923 raise ValueError(f"don't know how to serialize type {type(field_value)}") 924 925 result += field_bytes 926 927 return bytes(result) 928 929 @staticmethod 930 def from_bytes(data, offset, fields): 931 return HCI_Object(fields, **HCI_Object.dict_from_bytes(data, offset, fields)) 932 933 def to_bytes(self): 934 return HCI_Object.dict_to_bytes(self.__dict__, self.fields) 935 936 @staticmethod 937 def parse_length_prefixed_bytes(data, offset): 938 length = data[offset] 939 return offset + 1 + length, data[offset + 1:offset + 1 + length] 940 941 @staticmethod 942 def serialize_length_prefixed_bytes(data, padded_size=0): 943 prefixed_size = 1 + len(data) 944 padding = bytes(padded_size - prefixed_size) if prefixed_size < padded_size else b'' 945 return bytes([len(data)]) + data + padding 946 947 @staticmethod 948 def format_field_value(value, indentation): 949 if type(value) is bytes: 950 return value.hex() 951 elif isinstance(value, HCI_Object): 952 return '\n' + value.to_string(indentation) 953 else: 954 return str(value) 955 956 @staticmethod 957 def format_fields(object, keys, indentation='', value_mappers={}): 958 if not keys: 959 return '' 960 961 # Measure the widest field name 962 max_field_name_length = max([len(key[0] if type(key) is tuple else key) for key in keys]) 963 964 # Build array of formatted key:value pairs 965 fields = [] 966 for key in keys: 967 value_mapper = None 968 if type(key) is tuple: 969 # The key has an associated specifier 970 key, specifier = key 971 972 # Get the value mapper from the specifier 973 if type(specifier) is dict: 974 value_mapper = specifier.get('mapper') 975 976 # Get the value for the field 977 value = object[key] 978 979 # Map the value if needed 980 value_mapper = value_mappers.get(key, value_mapper) 981 if value_mapper is not None: 982 value = value_mapper(value) 983 984 # Get the string representation of the value 985 value_str = HCI_Object.format_field_value(value, indentation = indentation + ' ') 986 987 # Add the field to the formatted result 988 key_str = color(f'{key + ":":{1 + max_field_name_length}}', 'cyan') 989 fields.append(f'{indentation}{key_str} {value_str}') 990 991 return '\n'.join(fields) 992 993 def __bytes__(self): 994 return self.to_bytes() 995 996 def __init__(self, fields, **kwargs): 997 self.fields = fields 998 self.init_from_fields(self, fields, kwargs) 999 1000 def to_string(self, indentation='', value_mappers={}): 1001 return HCI_Object.format_fields(self.__dict__, self.fields, indentation, value_mappers) 1002 1003 def __str__(self): 1004 return self.to_string() 1005 1006 1007# ----------------------------------------------------------------------------- 1008# Bluetooth Address 1009# ----------------------------------------------------------------------------- 1010class Address: 1011 ''' 1012 Bluetooth Address (see Bluetooth spec Vol 6, Part B - 1.3 DEVICE ADDRESS) 1013 NOTE: the address bytes are stored in little-endian byte order here, so 1014 address[0] is the LSB of the address, address[5] is the MSB. 1015 ''' 1016 1017 PUBLIC_DEVICE_ADDRESS = 0x00 1018 RANDOM_DEVICE_ADDRESS = 0x01 1019 PUBLIC_IDENTITY_ADDRESS = 0x02 1020 RANDOM_IDENTITY_ADDRESS = 0x03 1021 1022 ADDRESS_TYPE_NAMES = { 1023 PUBLIC_DEVICE_ADDRESS: 'PUBLIC_DEVICE_ADDRESS', 1024 RANDOM_DEVICE_ADDRESS: 'RANDOM_DEVICE_ADDRESS', 1025 PUBLIC_IDENTITY_ADDRESS: 'PUBLIC_IDENTITY_ADDRESS', 1026 RANDOM_IDENTITY_ADDRESS: 'RANDOM_IDENTITY_ADDRESS' 1027 } 1028 1029 ADDRESS_TYPE_SPEC = {'size': 1, 'mapper': lambda x: Address.address_type_name(x)} 1030 1031 @staticmethod 1032 def address_type_name(address_type): 1033 return name_or_number(Address.ADDRESS_TYPE_NAMES, address_type) 1034 1035 @staticmethod 1036 def parse_address(data, offset): 1037 # Fix the type to a default value. This is used for parsing type-less Classic addresses 1038 return Address.parse_address_with_type(data, offset, Address.PUBLIC_DEVICE_ADDRESS) 1039 1040 @staticmethod 1041 def parse_address_with_type(data, offset, address_type): 1042 return offset + 6, Address(data[offset:offset + 6], address_type) 1043 1044 @staticmethod 1045 def parse_address_preceded_by_type(data, offset): 1046 address_type = data[offset - 1] 1047 return Address.parse_address_with_type(data, offset, address_type) 1048 1049 def __init__(self, address, address_type = RANDOM_DEVICE_ADDRESS): 1050 ''' 1051 Initialize an instance. `address` may be a byte array in little-endian 1052 format, or a hex string in big-endian format (with optional ':' 1053 separators between the bytes). 1054 If the address is a string suffixed with '/P', `address_type` is ignored and the type 1055 is set to PUBLIC_DEVICE_ADDRESS. 1056 ''' 1057 if type(address) is bytes: 1058 self.address_bytes = address 1059 else: 1060 # Check if there's a '/P' type specifier 1061 if address.endswith('P'): 1062 address_type = Address.PUBLIC_DEVICE_ADDRESS 1063 address = address[:-2] 1064 1065 if len(address) == 12 + 5: 1066 # Form with ':' separators 1067 address = address.replace(':', '') 1068 self.address_bytes = bytes(reversed(bytes.fromhex(address))) 1069 1070 if len(self.address_bytes) != 6: 1071 raise ValueError('invalid address length') 1072 1073 self.address_type = address_type 1074 1075 @property 1076 def is_public(self): 1077 return self.address_type == self.PUBLIC_DEVICE_ADDRESS or self.address_type == self.PUBLIC_IDENTITY_ADDRESS 1078 1079 @property 1080 def is_random(self): 1081 return not self.is_public 1082 1083 @property 1084 def is_resolved(self): 1085 return self.address_type == self.PUBLIC_IDENTITY_ADDRESS or self.address_type == self.RANDOM_IDENTITY_ADDRESS 1086 1087 @property 1088 def is_resolvable(self): 1089 return self.address_type == self.RANDOM_DEVICE_ADDRESS and (self.address_bytes[5] >> 6 == 1) 1090 1091 @property 1092 def is_static(self): 1093 return self.is_random and (self.address_bytes[5] >> 6 == 3) 1094 1095 def to_bytes(self): 1096 return self.address_bytes 1097 1098 def __bytes__(self): 1099 return self.to_bytes() 1100 1101 def __hash__(self): 1102 return hash(self.address_bytes) 1103 1104 def __eq__(self, other): 1105 return self.address_bytes == other.address_bytes and self.is_public == other.is_public 1106 1107 def __str__(self): 1108 ''' 1109 String representation of the address, MSB first 1110 ''' 1111 return ':'.join([f'{x:02X}' for x in reversed(self.address_bytes)]) 1112 1113 1114# ----------------------------------------------------------------------------- 1115class HCI_Packet: 1116 ''' 1117 Abstract Base class for HCI packets 1118 ''' 1119 1120 @staticmethod 1121 def from_bytes(packet): 1122 packet_type = packet[0] 1123 if packet_type == HCI_COMMAND_PACKET: 1124 return HCI_Command.from_bytes(packet) 1125 elif packet_type == HCI_ACL_DATA_PACKET: 1126 return HCI_AclDataPacket.from_bytes(packet) 1127 elif packet_type == HCI_EVENT_PACKET: 1128 return HCI_Event.from_bytes(packet) 1129 else: 1130 return HCI_CustomPacket(packet) 1131 1132 def __init__(self, name): 1133 self.name = name 1134 1135 def __repr__(self) -> str: 1136 return self.name 1137 1138 1139# ----------------------------------------------------------------------------- 1140class HCI_CustomPacket(HCI_Packet): 1141 def __init__(self, payload): 1142 super().__init__('HCI_CUSTOM_PACKET') 1143 self.hci_packet_type = payload[0] 1144 self.payload = payload 1145 1146 1147# ----------------------------------------------------------------------------- 1148class HCI_Command(HCI_Packet): 1149 ''' 1150 See Bluetooth spec @ Vol 2, Part E - 5.4.1 HCI Command Packet 1151 ''' 1152 hci_packet_type = HCI_COMMAND_PACKET 1153 command_classes = {} 1154 1155 @staticmethod 1156 def command(fields=[], return_parameters_fields=[]): 1157 ''' 1158 Decorator used to declare and register subclasses 1159 ''' 1160 1161 def inner(cls): 1162 cls.name = cls.__name__.upper() 1163 cls.op_code = key_with_value(HCI_COMMAND_NAMES, cls.name) 1164 if cls.op_code is None: 1165 raise KeyError('command not found in HCI_COMMAND_NAMES') 1166 cls.fields = fields 1167 cls.return_parameters_fields = return_parameters_fields 1168 1169 # Patch the __init__ method to fix the op_code 1170 def init(self, parameters=None, **kwargs): 1171 return HCI_Command.__init__(self, cls.op_code, parameters, **kwargs) 1172 cls.__init__ = init 1173 1174 # Register a factory for this class 1175 HCI_Command.command_classes[cls.op_code] = cls 1176 1177 return cls 1178 1179 return inner 1180 1181 @staticmethod 1182 def from_bytes(packet): 1183 op_code, length = struct.unpack_from('<HB', packet, 1) 1184 parameters = packet[4:] 1185 if len(parameters) != length: 1186 raise ValueError('invalid packet length') 1187 1188 # Look for a registered class 1189 cls = HCI_Command.command_classes.get(op_code) 1190 if cls is None: 1191 # No class registered, just use a generic instance 1192 return HCI_Command(op_code, parameters) 1193 1194 # Create a new instance 1195 self = cls.__new__(cls) 1196 HCI_Command.__init__(self, op_code, parameters) 1197 if fields := getattr(self, 'fields', None): 1198 HCI_Object.init_from_bytes(self, parameters, 0, fields) 1199 return self 1200 1201 @staticmethod 1202 def command_name(op_code): 1203 name = HCI_COMMAND_NAMES.get(op_code) 1204 if name is not None: 1205 return name 1206 return f'[OGF=0x{op_code >> 10:02x}, OCF=0x{op_code & 0x3FF:04x}]' 1207 1208 @classmethod 1209 def create_return_parameters(cls, **kwargs): 1210 return HCI_Object(cls.return_parameters_fields, **kwargs) 1211 1212 def __init__(self, op_code, parameters=None, **kwargs): 1213 super().__init__(HCI_Command.command_name(op_code)) 1214 if (fields := getattr(self, 'fields', None)) and kwargs: 1215 HCI_Object.init_from_fields(self, fields, kwargs) 1216 if parameters is None: 1217 parameters = HCI_Object.dict_to_bytes(kwargs, fields) 1218 self.op_code = op_code 1219 self.parameters = parameters 1220 1221 def to_bytes(self): 1222 parameters = b'' if self.parameters is None else self.parameters 1223 return struct.pack('<BHB', HCI_COMMAND_PACKET, self.op_code, len(parameters)) + parameters 1224 1225 def __bytes__(self): 1226 return self.to_bytes() 1227 1228 def __str__(self): 1229 result = color(self.name, 'green') 1230 if fields := getattr(self, 'fields', None): 1231 result += ':\n' + HCI_Object.format_fields(self.__dict__, fields, ' ') 1232 else: 1233 if self.parameters: 1234 result += f': {self.parameters.hex()}' 1235 return result 1236 1237 1238# ----------------------------------------------------------------------------- 1239@HCI_Command.command([ 1240 ('lap', {'size': 3, 'mapper': HCI_Constant.inquiry_lap_name}), 1241 ('inquiry_length', 1), 1242 ('num_responses', 1) 1243]) 1244class HCI_Inquiry_Command(HCI_Command): 1245 ''' 1246 See Bluetooth spec @ 7.1.1 Inquiry Command 1247 ''' 1248 1249 1250# ----------------------------------------------------------------------------- 1251@HCI_Command.command() 1252class HCI_Inquiry_Cancel_Command(HCI_Command): 1253 ''' 1254 See Bluetooth spec @ 7.1.2 Inquiry Cancel Command 1255 ''' 1256 1257 1258# ----------------------------------------------------------------------------- 1259@HCI_Command.command([ 1260 ('bd_addr', Address.parse_address), 1261 ('packet_type', 2), 1262 ('page_scan_repetition_mode', 1), 1263 ('reserved', 1), 1264 ('clock_offset', 2), 1265 ('allow_role_switch', 1) 1266]) 1267class HCI_Create_Connection_Command(HCI_Command): 1268 ''' 1269 See Bluetooth spec @ 7.1.5 Create Connection Command 1270 ''' 1271 1272 1273# ----------------------------------------------------------------------------- 1274@HCI_Command.command([ 1275 ('connection_handle', 2), 1276 ('reason', {'size': 1, 'mapper': HCI_Constant.error_name}) 1277]) 1278class HCI_Disconnect_Command(HCI_Command): 1279 ''' 1280 See Bluetooth spec @ 7.1.6 Disconnect Command 1281 ''' 1282 1283 1284# ----------------------------------------------------------------------------- 1285@HCI_Command.command([ 1286 ('bd_addr', Address.parse_address), 1287 ('role', 1) 1288]) 1289class HCI_Accept_Connection_Request_Command(HCI_Command): 1290 ''' 1291 See Bluetooth spec @ 7.1.8 Accept Connection Request Command 1292 ''' 1293 1294 1295# ----------------------------------------------------------------------------- 1296@HCI_Command.command([ 1297 ('bd_addr', Address.parse_address), 1298 ('link_key', 16) 1299]) 1300class HCI_Link_Key_Request_Reply_Command(HCI_Command): 1301 ''' 1302 See Bluetooth spec @ 7.1.10 Link Key Request Reply Command 1303 ''' 1304 1305 1306# ----------------------------------------------------------------------------- 1307@HCI_Command.command( 1308 fields=[ 1309 ('bd_addr', Address.parse_address) 1310 ], 1311 return_parameters_fields=[ 1312 ('status', STATUS_SPEC), 1313 ('bd_addr', Address.parse_address) 1314 ] 1315) 1316class HCI_Link_Key_Request_Negative_Reply_Command(HCI_Command): 1317 ''' 1318 See Bluetooth spec @ 7.1.11 Link Key Request Negative Reply Command 1319 ''' 1320 1321 1322# ----------------------------------------------------------------------------- 1323@HCI_Command.command( 1324 fields=[ 1325 ('bd_addr', Address.parse_address) 1326 ], 1327 return_parameters_fields=[ 1328 ('status', STATUS_SPEC), 1329 ('bd_addr', Address.parse_address) 1330 ] 1331) 1332class HCI_PIN_Code_Request_Negative_Reply_Command(HCI_Command): 1333 ''' 1334 See Bluetooth spec @ 7.1.13 PIN Code Request Negative Reply Command 1335 ''' 1336 1337 1338# ----------------------------------------------------------------------------- 1339@HCI_Command.command([ 1340 ('connection_handle', 2), 1341 ('packet_type', 2) 1342]) 1343class HCI_Change_Connection_Packet_Type_Command(HCI_Command): 1344 ''' 1345 See Bluetooth spec @ 7.1.14 Change Connection Packet Type Command 1346 ''' 1347 1348 1349# ----------------------------------------------------------------------------- 1350@HCI_Command.command([ 1351 ('connection_handle', 2) 1352]) 1353class HCI_Authentication_Requested_Command(HCI_Command): 1354 ''' 1355 See Bluetooth spec @ 7.1.15 Authentication Requested Command 1356 ''' 1357 1358 1359# ----------------------------------------------------------------------------- 1360@HCI_Command.command([ 1361 ('connection_handle', 2), 1362 ('encryption_enable', 1) 1363]) 1364class HCI_Set_Connection_Encryption_Command(HCI_Command): 1365 ''' 1366 See Bluetooth spec @ 7.1.16 Set Connection Encryption Command 1367 ''' 1368 1369 1370# ----------------------------------------------------------------------------- 1371@HCI_Command.command([ 1372 ('bd_addr', Address.parse_address), 1373 ('page_scan_repetition_mode', 1), 1374 ('reserved', 1), 1375 ('clock_offset', 2) 1376]) 1377class HCI_Remote_Name_Request_Command(HCI_Command): 1378 ''' 1379 See Bluetooth spec @ 7.1.19 Remote Name Request Command 1380 ''' 1381 R0 = 0x00 1382 R1 = 0x01 1383 R2 = 0x02 1384 1385 1386# ----------------------------------------------------------------------------- 1387@HCI_Command.command([ 1388 ('connection_handle', 2) 1389]) 1390class HCI_Read_Remote_Supported_Features_Command(HCI_Command): 1391 ''' 1392 See Bluetooth spec @ 7.1.21 Read Remote Supported Features Command 1393 ''' 1394 1395 1396# ----------------------------------------------------------------------------- 1397@HCI_Command.command([ 1398 ('connection_handle', 2), 1399 ('page_number', 1) 1400]) 1401class HCI_Read_Remote_Extended_Features_Command(HCI_Command): 1402 ''' 1403 See Bluetooth spec @ 7.1.22 Read Remote Extended Features Command 1404 ''' 1405 1406 1407# ----------------------------------------------------------------------------- 1408@HCI_Command.command([ 1409 ('connection_handle', 2) 1410]) 1411class HCI_Read_Remote_Version_Information_Command(HCI_Command): 1412 ''' 1413 See Bluetooth spec @ 7.1.23 Read Remote Version Information Command 1414 ''' 1415 1416 1417# ----------------------------------------------------------------------------- 1418@HCI_Command.command([ 1419 ('connection_handle', 2) 1420]) 1421class HCI_Read_Clock_Offset_Command(HCI_Command): 1422 ''' 1423 See Bluetooth spec @ 7.1.23 Read Clock Offset Command 1424 ''' 1425 1426 1427# ----------------------------------------------------------------------------- 1428@HCI_Command.command( 1429 fields=[ 1430 ('bd_addr', Address.parse_address), 1431 ('io_capability', {'size': 1, 'mapper': HCI_Constant.io_capability_name}), 1432 ('oob_data_present', 1), 1433 ('authentication_requirements', {'size': 1, 'mapper': HCI_Constant.authentication_requirements_name}) 1434 ], 1435 return_parameters_fields=[ 1436 ('status', STATUS_SPEC), 1437 ('bd_addr', Address.parse_address) 1438 ] 1439) 1440class HCI_IO_Capability_Request_Reply_Command(HCI_Command): 1441 ''' 1442 See Bluetooth spec @ 7.1.29 IO Capability Request Reply Command 1443 ''' 1444 1445 1446# ----------------------------------------------------------------------------- 1447@HCI_Command.command( 1448 fields=[ 1449 ('bd_addr', Address.parse_address) 1450 ], 1451 return_parameters_fields=[ 1452 ('status', STATUS_SPEC), 1453 ('bd_addr', Address.parse_address) 1454 ] 1455) 1456class HCI_User_Confirmation_Request_Reply_Command(HCI_Command): 1457 ''' 1458 See Bluetooth spec @ 7.1.30 User Confirmation Request Reply Command 1459 ''' 1460 1461 1462# ----------------------------------------------------------------------------- 1463@HCI_Command.command( 1464 fields=[ 1465 ('bd_addr', Address.parse_address) 1466 ], 1467 return_parameters_fields=[ 1468 ('status', STATUS_SPEC), 1469 ('bd_addr', Address.parse_address) 1470 ] 1471) 1472class HCI_User_Confirmation_Request_Negative_Reply_Command(HCI_Command): 1473 ''' 1474 See Bluetooth spec @ 7.1.31 User Confirmation Request Negative Reply Command 1475 ''' 1476 1477 1478# ----------------------------------------------------------------------------- 1479@HCI_Command.command( 1480 fields=[ 1481 ('bd_addr', Address.parse_address), 1482 ('numeric_value', 4) 1483 ], 1484 return_parameters_fields=[ 1485 ('status', STATUS_SPEC), 1486 ('bd_addr', Address.parse_address) 1487 ] 1488) 1489class HCI_User_Passkey_Request_Reply_Command(HCI_Command): 1490 ''' 1491 See Bluetooth spec @ 7.1.32 User Passkey Request Reply Command 1492 ''' 1493 1494 1495# ----------------------------------------------------------------------------- 1496@HCI_Command.command( 1497 fields=[ 1498 ('bd_addr', Address.parse_address) 1499 ], 1500 return_parameters_fields=[ 1501 ('status', STATUS_SPEC), 1502 ('bd_addr', Address.parse_address) 1503 ] 1504) 1505class HCI_User_Passkey_Request_Negative_Reply_Command(HCI_Command): 1506 ''' 1507 See Bluetooth spec @ 7.1.33 User Passkey Request Negative Reply Command 1508 ''' 1509 1510 1511# ----------------------------------------------------------------------------- 1512@HCI_Command.command([ 1513 ('connection_handle', 2), 1514 ('transmit_bandwidth', 4), 1515 ('receive_bandwidth', 4), 1516 ('transmit_coding_format', 5), 1517 ('receive_coding_format', 5), 1518 ('transmit_codec_frame_size', 2), 1519 ('receive_codec_frame_size', 2), 1520 ('input_bandwidth', 4), 1521 ('output_bandwidth', 4), 1522 ('input_coding_format', 5), 1523 ('output_coding_format', 5), 1524 ('input_coded_data_size', 2), 1525 ('output_coded_data_size', 2), 1526 ('input_pcm_data_format', 1), 1527 ('output_pcm_data_format', 1), 1528 ('input_pcm_sample_payload_msb_position', 1), 1529 ('output_pcm_sample_payload_msb_position', 1), 1530 ('input_data_path', 1), 1531 ('output_data_path', 1), 1532 ('input_transport_unit_size', 1), 1533 ('output_transport_unit_size', 1), 1534 ('max_latency', 2), 1535 ('packet_type', 2), 1536 ('retransmission_effort', 1) 1537]) 1538class HCI_Enhanced_Setup_Synchronous_Connection_Command(HCI_Command): 1539 ''' 1540 See Bluetooth spec @ 7.1.45 Enhanced Setup Synchronous Connection Command 1541 ''' 1542 1543 1544# ----------------------------------------------------------------------------- 1545@HCI_Command.command([ 1546 ('connection_handle', 2), 1547 ('sniff_max_interval', 2), 1548 ('sniff_min_interval', 2), 1549 ('sniff_attempt', 2), 1550 ('sniff_timeout', 2) 1551]) 1552class HCI_Sniff_Mode_Command(HCI_Command): 1553 ''' 1554 See Bluetooth spec @ 7.2.2 Sniff Mode Command 1555 ''' 1556 1557 1558# ----------------------------------------------------------------------------- 1559@HCI_Command.command([ 1560 ('connection_handle', 2) 1561]) 1562class HCI_Exit_Sniff_Mode_Command(HCI_Command): 1563 ''' 1564 See Bluetooth spec @ 7.2.3 Exit Sniff Mode Command 1565 ''' 1566 1567 1568# ----------------------------------------------------------------------------- 1569@HCI_Command.command([ 1570 ('bd_addr', Address.parse_address), 1571 ('role', {'size': 1, 'mapper': HCI_Constant.role_name}) 1572]) 1573class HCI_Switch_Role_Command(HCI_Command): 1574 ''' 1575 See Bluetooth spec @ 7.2.8 Switch Role Command 1576 ''' 1577 1578 1579# ----------------------------------------------------------------------------- 1580@HCI_Command.command([ 1581 ('connection_handle', 2), 1582 ('link_policy_settings', 2) 1583]) 1584class HCI_Write_Link_Policy_Settings_Command(HCI_Command): 1585 ''' 1586 See Bluetooth spec @ 7.2.10 Write Link Policy Settings Command 1587 ''' 1588 1589 1590# ----------------------------------------------------------------------------- 1591@HCI_Command.command([ 1592 ('default_link_policy_settings', 2) 1593]) 1594class HCI_Write_Default_Link_Policy_Settings_Command(HCI_Command): 1595 ''' 1596 See Bluetooth spec @ 7.2.12 Write Default Link Policy Settings Command 1597 ''' 1598 1599 1600# ----------------------------------------------------------------------------- 1601@HCI_Command.command([ 1602 ('connection_handle', 2), 1603 ('maximum_latency', 2), 1604 ('minimum_remote_timeout', 2), 1605 ('minimum_local_timeout', 2) 1606]) 1607class HCI_Sniff_Subrating_Command(HCI_Command): 1608 ''' 1609 See Bluetooth spec @ 7.2.14 Sniff Subrating Command 1610 ''' 1611 1612 1613# ----------------------------------------------------------------------------- 1614@HCI_Command.command([ 1615 ('event_mask', 8) 1616]) 1617class HCI_Set_Event_Mask_Command(HCI_Command): 1618 ''' 1619 See Bluetooth spec @ 7.3.1 Set Event Mask Command 1620 ''' 1621 1622 1623# ----------------------------------------------------------------------------- 1624@HCI_Command.command() 1625class HCI_Reset_Command(HCI_Command): 1626 ''' 1627 See Bluetooth spec @ 7.3.2 Reset Command 1628 ''' 1629 1630 1631# ----------------------------------------------------------------------------- 1632@HCI_Command.command([ 1633 ('filter_type', 1), 1634 ('filter_condition', '*'), 1635]) 1636class HCI_Set_Event_Filter_Command(HCI_Command): 1637 ''' 1638 See Bluetooth spec @ 7.3.3 Set Event Filter Command 1639 ''' 1640 1641 1642# ----------------------------------------------------------------------------- 1643@HCI_Command.command( 1644 fields=[ 1645 ('bd_addr', Address.parse_address), 1646 ('read_all_flag', 1) 1647 ], 1648 return_parameters_fields=[ 1649 ('status', STATUS_SPEC), 1650 ('max_num_keys', 2), 1651 ('num_keys_read', 2) 1652 ] 1653) 1654class HCI_Read_Stored_Link_Key_Command(HCI_Command): 1655 ''' 1656 See Bluetooth spec @ 7.3.8 Read Stored Link Key Command 1657 ''' 1658 1659 1660# ----------------------------------------------------------------------------- 1661@HCI_Command.command( 1662 fields=[ 1663 ('bd_addr', Address.parse_address), 1664 ('delete_all_flag', 1) 1665 ], 1666 return_parameters_fields=[ 1667 ('status', STATUS_SPEC), 1668 ('num_keys_deleted', 2) 1669 ] 1670) 1671class HCI_Delete_Stored_Link_Key_Command(HCI_Command): 1672 ''' 1673 See Bluetooth spec @ 7.3.10 Delete Stored Link Key Command 1674 ''' 1675 1676 1677# ----------------------------------------------------------------------------- 1678@HCI_Command.command([ 1679 ('local_name', {'size': 248, 'mapper': map_null_terminated_utf8_string}) 1680]) 1681class HCI_Write_Local_Name_Command(HCI_Command): 1682 ''' 1683 See Bluetooth spec @ 7.3.11 Write Local Name Command 1684 ''' 1685 1686 1687# ----------------------------------------------------------------------------- 1688@HCI_Command.command(return_parameters_fields=[ 1689 ('status', STATUS_SPEC), 1690 ('local_name', {'size': 248, 'mapper': map_null_terminated_utf8_string}) 1691]) 1692class HCI_Read_Local_Name_Command(HCI_Command): 1693 ''' 1694 See Bluetooth spec @ 7.3.12 Read Local Name Command 1695 ''' 1696 1697 1698# ----------------------------------------------------------------------------- 1699@HCI_Command.command([ 1700 ('conn_accept_timeout', 2) 1701]) 1702class HCI_Write_Connection_Accept_Timeout_Command(HCI_Command): 1703 ''' 1704 See Bluetooth spec @ 7.3.14 Write Connection Accept Timeout Command 1705 ''' 1706 1707 1708# ----------------------------------------------------------------------------- 1709@HCI_Command.command([ 1710 ('page_timeout', 2) 1711]) 1712class HCI_Write_Page_Timeout_Command(HCI_Command): 1713 ''' 1714 See Bluetooth spec @ 7.3.16 Write Page Timeout Command 1715 ''' 1716 1717 1718# ----------------------------------------------------------------------------- 1719@HCI_Command.command([ 1720 ('scan_enable', 1) 1721]) 1722class HCI_Write_Scan_Enable_Command(HCI_Command): 1723 ''' 1724 See Bluetooth spec @ 7.3.18 Write Scan Enable Command 1725 ''' 1726 1727 1728# ----------------------------------------------------------------------------- 1729@HCI_Command.command(return_parameters_fields=[ 1730 ('status', STATUS_SPEC), 1731 ('page_scan_interval', 2), 1732 ('page_scan_window', 2) 1733]) 1734class HCI_Read_Page_Scan_Activity_Command(HCI_Command): 1735 ''' 1736 See Bluetooth spec @ 7.3.19 Read Page Scan Activity Command 1737 ''' 1738 1739 1740# ----------------------------------------------------------------------------- 1741@HCI_Command.command([ 1742 ('page_scan_interval', 2), 1743 ('page_scan_window', 2) 1744]) 1745class HCI_Write_Page_Scan_Activity_Command(HCI_Command): 1746 ''' 1747 See Bluetooth spec @ 7.3.20 Write Page Scan Activity Command 1748 ''' 1749 1750 1751# ----------------------------------------------------------------------------- 1752@HCI_Command.command([ 1753 ('inquiry_scan_interval', 2), 1754 ('inquiry_scan_window', 2) 1755]) 1756class HCI_Write_Inquiry_Scan_Activity_Command(HCI_Command): 1757 ''' 1758 See Bluetooth spec @ 7.3.22 Write Inquiry Scan Activity Command 1759 ''' 1760 1761 1762# ----------------------------------------------------------------------------- 1763@HCI_Command.command(return_parameters_fields=[ 1764 ('status', STATUS_SPEC), 1765 ('class_of_device', {'size': 3, 'mapper': map_class_of_device}) 1766]) 1767class HCI_Read_Class_Of_Device_Command(HCI_Command): 1768 ''' 1769 See Bluetooth spec @ 7.3.25 Read Class of Device Command 1770 ''' 1771 1772 1773# ----------------------------------------------------------------------------- 1774@HCI_Command.command([ 1775 ('class_of_device', {'size': 3, 'mapper': map_class_of_device}) 1776]) 1777class HCI_Write_Class_Of_Device_Command(HCI_Command): 1778 ''' 1779 See Bluetooth spec @ 7.3.26 Write Class of Device Command 1780 ''' 1781 1782 1783# ----------------------------------------------------------------------------- 1784@HCI_Command.command(return_parameters_fields=[ 1785 ('status', STATUS_SPEC), 1786 ('voice_setting', 2) 1787]) 1788class HCI_Read_Voice_Setting_Command(HCI_Command): 1789 ''' 1790 See Bluetooth spec @ 7.3.27 Read Voice Setting Command 1791 ''' 1792 1793 1794# ----------------------------------------------------------------------------- 1795@HCI_Command.command([ 1796 ('voice_setting', 2) 1797]) 1798class HCI_Write_Voice_Setting_Command(HCI_Command): 1799 ''' 1800 See Bluetooth spec @ 7.3.28 Write Voice Setting Command 1801 ''' 1802 1803 1804# ----------------------------------------------------------------------------- 1805class HCI_Read_Synchronous_Flow_Control_Enable_Command(HCI_Command): 1806 ''' 1807 See Bluetooth spec @ 7.3.36 Write Synchronous Flow Control Enable Command 1808 ''' 1809 1810 1811# ----------------------------------------------------------------------------- 1812@HCI_Command.command([ 1813 ('synchronous_flow_control_enable', 1) 1814]) 1815class HCI_Write_Synchronous_Flow_Control_Enable_Command(HCI_Command): 1816 ''' 1817 See Bluetooth spec @ 7.3.37 Write Synchronous Flow Control Enable Command 1818 ''' 1819 1820 1821# ----------------------------------------------------------------------------- 1822@HCI_Command.command([ 1823 ('host_acl_data_packet_length', 2), 1824 ('host_synchronous_data_packet_length', 1), 1825 ('host_total_num_acl_data_packets', 2), 1826 ('host_total_num_synchronous_data_packets', 2) 1827]) 1828class HCI_Host_Buffer_Size_Command(HCI_Command): 1829 ''' 1830 See Bluetooth spec @ 7.3.39 Host Buffer Size Command 1831 ''' 1832 1833 1834# ----------------------------------------------------------------------------- 1835@HCI_Command.command( 1836 fields=[ 1837 ('handle', 2), 1838 ('link_supervision_timeout', 2) 1839 ], 1840 return_parameters_fields=[ 1841 ('status', STATUS_SPEC), 1842 ('handle', 2), 1843 ] 1844) 1845class HCI_Write_Link_Supervision_Timeout_Command(HCI_Command): 1846 ''' 1847 See Bluetooth spec @ 7.3.42 Write Link Supervision Timeout Command 1848 ''' 1849 1850 1851# ----------------------------------------------------------------------------- 1852@HCI_Command.command(return_parameters_fields=[ 1853 ('status', STATUS_SPEC), 1854 ('num_support_iac', 1) 1855]) 1856class HCI_Read_Number_Of_Supported_IAC_Command(HCI_Command): 1857 ''' 1858 See Bluetooth spec @ 7.3.43 Read Number Of Supported IAC Command 1859 ''' 1860 1861 1862# ----------------------------------------------------------------------------- 1863@HCI_Command.command(return_parameters_fields=[ 1864 ('status', STATUS_SPEC), 1865 ('num_current_iac', 1), 1866 ('iac_lap', '*') # TODO: this should be parsed as an array 1867]) 1868class HCI_Read_Current_IAC_LAP_Command(HCI_Command): 1869 ''' 1870 See Bluetooth spec @ 7.3.44 Read Current IAC LAP Command 1871 ''' 1872 1873 1874# ----------------------------------------------------------------------------- 1875@HCI_Command.command([ 1876 ('scan_type', 1) 1877]) 1878class HCI_Write_Inquiry_Scan_Type_Command(HCI_Command): 1879 ''' 1880 See Bluetooth spec @ 7.3.48 Write Inquiry Scan Type Command 1881 ''' 1882 1883 1884# ----------------------------------------------------------------------------- 1885@HCI_Command.command([ 1886 ('inquiry_mode', 1) 1887]) 1888class HCI_Write_Inquiry_Mode_Command(HCI_Command): 1889 ''' 1890 See Bluetooth spec @ 7.3.50 Write Inquiry Mode Command 1891 ''' 1892 1893 1894# ----------------------------------------------------------------------------- 1895@HCI_Command.command(return_parameters_fields=[ 1896 ('status', STATUS_SPEC), 1897 ('page_scan_type', 1) 1898]) 1899class HCI_Read_Page_Scan_Type_Command(HCI_Command): 1900 ''' 1901 See Bluetooth spec @ 7.3.51 Read Page Scan Type Command 1902 ''' 1903 1904 1905# ----------------------------------------------------------------------------- 1906@HCI_Command.command([ 1907 ('page_scan_type', 1) 1908]) 1909class HCI_Write_Page_Scan_Type_Command(HCI_Command): 1910 ''' 1911 See Bluetooth spec @ 7.3.52 Write Page Scan Type Command 1912 ''' 1913 1914 1915# ----------------------------------------------------------------------------- 1916@HCI_Command.command([ 1917 ('fec_required', 1), 1918 ('extended_inquiry_response', {'size': 240, 'serializer': lambda x: padded_bytes(x, 240)}) 1919]) 1920class HCI_Write_Extended_Inquiry_Response_Command(HCI_Command): 1921 ''' 1922 See Bluetooth spec @ 7.3.56 Write Extended Inquiry Response Command 1923 ''' 1924 1925 1926# ----------------------------------------------------------------------------- 1927@HCI_Command.command([ 1928 ('simple_pairing_mode', 1) 1929]) 1930class HCI_Write_Simple_Pairing_Mode_Command(HCI_Command): 1931 ''' 1932 See Bluetooth spec @ 7.3.59 Write Simple Pairing Mode Command 1933 ''' 1934 1935 1936# ----------------------------------------------------------------------------- 1937@HCI_Command.command(return_parameters_fields=[ 1938 ('status', STATUS_SPEC), 1939 ('tx_power', -1) 1940]) 1941class HCI_Read_Inquiry_Response_Transmit_Power_Level_Command(HCI_Command): 1942 ''' 1943 See Bluetooth spec @ 7.3.61 Read Inquiry Response Transmit Power Level Command 1944 ''' 1945 1946 1947# ----------------------------------------------------------------------------- 1948@HCI_Command.command(return_parameters_fields=[ 1949 ('status', STATUS_SPEC), 1950 ('erroneous_data_reporting', 1) 1951]) 1952class HCI_Read_Default_Erroneous_Data_Reporting_Command(HCI_Command): 1953 ''' 1954 See Bluetooth spec @ 7.3.64 Read Default Erroneous Data Reporting Command 1955 ''' 1956 1957 1958# ----------------------------------------------------------------------------- 1959@HCI_Command.command([ 1960 ('event_mask_page_2', 8) 1961]) 1962class HCI_Set_Event_Mask_Page_2_Command(HCI_Command): 1963 ''' 1964 See Bluetooth spec @ 7.3.69 Set Event Mask Page 2 Command 1965 ''' 1966 1967 1968# ----------------------------------------------------------------------------- 1969@HCI_Command.command() 1970class HCI_Read_LE_Host_Support_Command(HCI_Command): 1971 ''' 1972 See Bluetooth spec @ 7.3.78 Read LE Host Support Command 1973 ''' 1974 1975 1976# ----------------------------------------------------------------------------- 1977@HCI_Command.command([ 1978 ('le_supported_host', 1), 1979 ('simultaneous_le_host', 1) 1980]) 1981class HCI_Write_LE_Host_Support_Command(HCI_Command): 1982 ''' 1983 See Bluetooth spec @ 7.3.79 Write LE Host Support Command 1984 ''' 1985 1986 1987# ----------------------------------------------------------------------------- 1988@HCI_Command.command([ 1989 ('secure_connections_host_support', 1) 1990]) 1991class HCI_Write_Secure_Connections_Host_Support_Command(HCI_Command): 1992 ''' 1993 See Bluetooth spec @ 7.3.92 Write Secure Connections Host Support Command 1994 ''' 1995 1996 1997# ----------------------------------------------------------------------------- 1998@HCI_Command.command([ 1999 ('connection_handle', 2), 2000 ('authenticated_payload_timeout', 2) 2001]) 2002class HCI_Write_Authenticated_Payload_Timeout_Command(HCI_Command): 2003 ''' 2004 See Bluetooth spec @ 7.3.94 Write Authenticated Payload Timeout Command 2005 ''' 2006 2007 2008# ----------------------------------------------------------------------------- 2009@HCI_Command.command(return_parameters_fields=[ 2010 ('status', STATUS_SPEC), 2011 ('hci_version', 1), 2012 ('hci_revsion', 2), 2013 ('lmp_pal_version', 1), 2014 ('manufacturer_name', 2), 2015 ('lmp_pal_subversion', 2) 2016]) 2017class HCI_Read_Local_Version_Information_Command(HCI_Command): 2018 ''' 2019 See Bluetooth spec @ 7.4.1 Read Local Version Information Command 2020 ''' 2021 2022 2023# ----------------------------------------------------------------------------- 2024@HCI_Command.command(return_parameters_fields=[ 2025 ('status', STATUS_SPEC), 2026 ('supported_commands', 64) 2027]) 2028class HCI_Read_Local_Supported_Commands_Command(HCI_Command): 2029 ''' 2030 See Bluetooth spec @ 7.4.2 Read Local Supported Commands Command 2031 ''' 2032 2033 2034# ----------------------------------------------------------------------------- 2035@HCI_Command.command() 2036class HCI_Read_Local_Supported_Features_Command(HCI_Command): 2037 ''' 2038 See Bluetooth spec @ 7.4.3 Read Local Supported Features Command 2039 ''' 2040 2041 2042# ----------------------------------------------------------------------------- 2043@HCI_Command.command( 2044 fields=[ 2045 ('page_number', 1) 2046 ], 2047 return_parameters_fields=[ 2048 ('status', STATUS_SPEC), 2049 ('page_number', 1), 2050 ('maximum_page_number', 1), 2051 ('extended_lmp_features', 8) 2052 ] 2053) 2054class HCI_Read_Local_Extended_Features_Command(HCI_Command): 2055 ''' 2056 See Bluetooth spec @ 7.4.4 Read Local Extended Features Command 2057 ''' 2058 2059 2060# ----------------------------------------------------------------------------- 2061@HCI_Command.command(return_parameters_fields=[ 2062 ('status', STATUS_SPEC), 2063 ('hc_acl_data_packet_length', 2), 2064 ('hc_synchronous_data_packet_length', 1), 2065 ('hc_total_num_acl_data_packets', 2), 2066 ('hc_total_num_synchronous_data_packets', 2) 2067]) 2068class HCI_Read_Buffer_Size_Command(HCI_Command): 2069 ''' 2070 See Bluetooth spec @ 7.4.5 Read Buffer Size Command 2071 ''' 2072 2073 2074# ----------------------------------------------------------------------------- 2075@HCI_Command.command(return_parameters_fields=[ 2076 ('status', STATUS_SPEC), 2077 ('bd_addr', Address.parse_address) 2078]) 2079class HCI_Read_BD_ADDR_Command(HCI_Command): 2080 ''' 2081 See Bluetooth spec @ 7.4.6 Read BD_ADDR Command 2082 ''' 2083 2084 2085# ----------------------------------------------------------------------------- 2086@HCI_Command.command() 2087class HCI_Read_Local_Supported_Codecs_Command(HCI_Command): 2088 ''' 2089 See Bluetooth spec @ 7.4.8 Read Local Supported Codecs Command 2090 ''' 2091 2092 2093# ----------------------------------------------------------------------------- 2094@HCI_Command.command( 2095 fields=[ 2096 ('connection_handle', 2) 2097 ], 2098 return_parameters_fields=[ 2099 ('status', STATUS_SPEC), 2100 ('connection_handle', 2), 2101 ('key_size', 1) 2102 ] 2103) 2104class HCI_Read_Encryption_Key_Size_Command(HCI_Command): 2105 ''' 2106 See Bluetooth spec @ 7.5.7 Read Encryption Key Size Command 2107 ''' 2108 2109 2110# ----------------------------------------------------------------------------- 2111@HCI_Command.command([ 2112 ('le_event_mask', 8) 2113]) 2114class HCI_LE_Set_Event_Mask_Command(HCI_Command): 2115 ''' 2116 See Bluetooth spec @ 7.8.1 LE Set Event Mask Command 2117 ''' 2118 2119 2120# ----------------------------------------------------------------------------- 2121@HCI_Command.command(return_parameters_fields=[ 2122 ('status', STATUS_SPEC), 2123 ('hc_le_acl_data_packet_length', 2), 2124 ('hc_total_num_le_acl_data_packets', 1) 2125]) 2126class HCI_LE_Read_Buffer_Size_Command(HCI_Command): 2127 ''' 2128 See Bluetooth spec @ 7.8.2 LE Read Buffer Size Command 2129 ''' 2130 2131 2132# ----------------------------------------------------------------------------- 2133@HCI_Command.command([ 2134 ('random_address', lambda data, offset: Address.parse_address_with_type(data, offset, Address.RANDOM_DEVICE_ADDRESS)) 2135]) 2136class HCI_LE_Set_Random_Address_Command(HCI_Command): 2137 ''' 2138 See Bluetooth spec @ 7.8.4 LE Set Random Address Command 2139 ''' 2140 2141 2142# ----------------------------------------------------------------------------- 2143@HCI_Command.command([ 2144 ('advertising_interval_min', 2), 2145 ('advertising_interval_max', 2), 2146 ('advertising_type', {'size': 1, 'mapper': lambda x: HCI_LE_Set_Advertising_Parameters_Command.advertising_type_name(x)}), 2147 ('own_address_type', Address.ADDRESS_TYPE_SPEC), 2148 ('peer_address_type', Address.ADDRESS_TYPE_SPEC), 2149 ('peer_address', Address.parse_address_preceded_by_type), 2150 ('advertising_channel_map', 1), 2151 ('advertising_filter_policy', 1), 2152]) 2153class HCI_LE_Set_Advertising_Parameters_Command(HCI_Command): 2154 ''' 2155 See Bluetooth spec @ 7.8.5 LE Set Advertising Parameters Command 2156 ''' 2157 2158 ADV_IND = 0x00 2159 ADV_DIRECT_IND = 0x01 2160 ADV_SCAN_IND = 0x02 2161 ADV_NONCONN_IND = 0x03 2162 ADV_DIRECT_IND = 0x04 2163 2164 ADVERTISING_TYPE_NAMES = { 2165 ADV_IND: 'ADV_IND', 2166 ADV_DIRECT_IND: 'ADV_DIRECT_IND', 2167 ADV_SCAN_IND: 'ADV_SCAN_IND', 2168 ADV_NONCONN_IND: 'ADV_NONCONN_IND', 2169 ADV_DIRECT_IND: 'ADV_DIRECT_IND' 2170 } 2171 2172 @classmethod 2173 def advertising_type_name(cls, advertising_type): 2174 return name_or_number(cls.ADVERTISING_TYPE_NAMES, advertising_type) 2175 2176 2177# ----------------------------------------------------------------------------- 2178@HCI_Command.command() 2179class HCI_LE_Read_Advertising_Channel_Tx_Power_Command(HCI_Command): 2180 ''' 2181 See Bluetooth spec @ 7.8.6 LE Read Advertising Channel Tx Power Command 2182 ''' 2183 2184 2185# ----------------------------------------------------------------------------- 2186@HCI_Command.command([ 2187 ('advertising_data', { 2188 'parser': HCI_Object.parse_length_prefixed_bytes, 2189 'serializer': functools.partial(HCI_Object.serialize_length_prefixed_bytes, padded_size=32) 2190 }) 2191]) 2192class HCI_LE_Set_Advertising_Data_Command(HCI_Command): 2193 ''' 2194 See Bluetooth spec @ 7.8.7 LE Set Advertising Data Command 2195 ''' 2196 2197 2198# ----------------------------------------------------------------------------- 2199@HCI_Command.command([ 2200 ('scan_response_data', { 2201 'parser': HCI_Object.parse_length_prefixed_bytes, 2202 'serializer': functools.partial(HCI_Object.serialize_length_prefixed_bytes, padded_size=32) 2203 }) 2204]) 2205class HCI_LE_Set_Scan_Response_Data_Command(HCI_Command): 2206 ''' 2207 See Bluetooth spec @ 7.8.8 LE Set Scan Response Data Command 2208 ''' 2209 2210 2211# ----------------------------------------------------------------------------- 2212@HCI_Command.command([ 2213 ('advertising_enable', 1) 2214]) 2215class HCI_LE_Set_Advertising_Enable_Command(HCI_Command): 2216 ''' 2217 See Bluetooth spec @ 7.8.9 LE Set Advertising Enable Command 2218 ''' 2219 2220 2221# ----------------------------------------------------------------------------- 2222@HCI_Command.command([ 2223 ('le_scan_type', 1), 2224 ('le_scan_interval', 2), 2225 ('le_scan_window', 2), 2226 ('own_address_type', Address.ADDRESS_TYPE_SPEC), 2227 ('scanning_filter_policy', 1) 2228]) 2229class HCI_LE_Set_Scan_Parameters_Command(HCI_Command): 2230 ''' 2231 See Bluetooth spec @ 7.8.10 LE Set Scan Parameters Command 2232 ''' 2233 PASSIVE_SCANNING = 0 2234 ACTIVE_SCANNING = 1 2235 2236 BASIC_UNFILTERED_POLICY = 0x00 2237 BASIC_FILTERED_POLICY = 0x01 2238 EXTENDED_UNFILTERED_POLICY = 0x02 2239 EXTENDED_FILTERED_POLICY = 0x03 2240 2241 2242# ----------------------------------------------------------------------------- 2243@HCI_Command.command([ 2244 ('le_scan_enable', 1), 2245 ('filter_duplicates', 1), 2246]) 2247class HCI_LE_Set_Scan_Enable_Command(HCI_Command): 2248 ''' 2249 See Bluetooth spec @ 7.8.11 LE Set Scan Enable Command 2250 ''' 2251 2252 2253# ----------------------------------------------------------------------------- 2254@HCI_Command.command([ 2255 ('le_scan_interval', 2), 2256 ('le_scan_window', 2), 2257 ('initiator_filter_policy', 1), 2258 ('peer_address_type', Address.ADDRESS_TYPE_SPEC), 2259 ('peer_address', Address.parse_address_preceded_by_type), 2260 ('own_address_type', Address.ADDRESS_TYPE_SPEC), 2261 ('conn_interval_min', 2), 2262 ('conn_interval_max', 2), 2263 ('conn_latency', 2), 2264 ('supervision_timeout', 2), 2265 ('minimum_ce_length', 2), 2266 ('maximum_ce_length', 2) 2267]) 2268class HCI_LE_Create_Connection_Command(HCI_Command): 2269 ''' 2270 See Bluetooth spec @ 7.8.12 LE Create Connection Command 2271 ''' 2272 2273 2274# ----------------------------------------------------------------------------- 2275@HCI_Command.command() 2276class HCI_LE_Create_Connection_Cancel_Command(HCI_Command): 2277 ''' 2278 See Bluetooth spec @ 7.8.13 LE Create Connection Cancel Command 2279 ''' 2280 2281 2282# ----------------------------------------------------------------------------- 2283@HCI_Command.command() 2284class HCI_LE_Read_White_List_Size_Command(HCI_Command): 2285 ''' 2286 See Bluetooth spec @ 7.8.14 LE Read White List Size Command 2287 ''' 2288 2289 2290# ----------------------------------------------------------------------------- 2291@HCI_Command.command() 2292class HCI_LE_Clear_White_List_Command(HCI_Command): 2293 ''' 2294 See Bluetooth spec @ 7.8.15 LE Clear White List Command 2295 ''' 2296 2297 2298# ----------------------------------------------------------------------------- 2299@HCI_Command.command([ 2300 ('address_type', Address.ADDRESS_TYPE_SPEC), 2301 ('address', Address.parse_address_preceded_by_type) 2302]) 2303class HCI_LE_Add_Device_To_White_List_Command(HCI_Command): 2304 ''' 2305 See Bluetooth spec @ 7.8.16 LE Add Device To White List Command 2306 ''' 2307 2308 2309# ----------------------------------------------------------------------------- 2310@HCI_Command.command([ 2311 ('address_type', Address.ADDRESS_TYPE_SPEC), 2312 ('address', Address.parse_address_preceded_by_type) 2313]) 2314class HCI_LE_Remove_Device_From_White_List_Command(HCI_Command): 2315 ''' 2316 See Bluetooth spec @ 7.8.17 LE Remove Device From White List Command 2317 ''' 2318 2319 2320# ----------------------------------------------------------------------------- 2321@HCI_Command.command([ 2322 ('connection_handle', 2), 2323 ('conn_interval_min', 2), 2324 ('conn_interval_max', 2), 2325 ('conn_latency', 2), 2326 ('supervision_timeout', 2), 2327 ('minimum_ce_length', 2), 2328 ('maximum_ce_length', 2) 2329]) 2330class HCI_LE_Connection_Update_Command(HCI_Command): 2331 ''' 2332 See Bluetooth spec @ 7.8.18 LE Connection Update Command 2333 ''' 2334 2335 2336# ----------------------------------------------------------------------------- 2337@HCI_Command.command([ 2338 ('connection_handle', 2) 2339]) 2340class HCI_LE_Read_Remote_Features_Command(HCI_Command): 2341 ''' 2342 See Bluetooth spec @ 7.8.21 LE Read Remote Features Command 2343 ''' 2344 2345 2346# ----------------------------------------------------------------------------- 2347@HCI_Command.command([ 2348 ('connection_handle', 2), 2349 ('random_number', 8), 2350 ('encrypted_diversifier', 2), 2351 ('long_term_key', 16) 2352]) 2353class HCI_LE_Start_Encryption_Command(HCI_Command): 2354 ''' 2355 See Bluetooth spec @ 7.8.24 LE Start Encryption Command 2356 (renamed to "LE Enable Encryption Command" in version 5.2 of the specification) 2357 ''' 2358 2359 2360# ----------------------------------------------------------------------------- 2361@HCI_Command.command([ 2362 ('connection_handle', 2), 2363 ('long_term_key', 16) 2364]) 2365class HCI_LE_Long_Term_Key_Request_Reply_Command(HCI_Command): 2366 ''' 2367 See Bluetooth spec @ 7.8.25 LE Long Term Key Request Reply Command 2368 ''' 2369 2370 2371# ----------------------------------------------------------------------------- 2372@HCI_Command.command([ 2373 ('connection_handle', 2) 2374]) 2375class HCI_LE_Long_Term_Key_Request_Negative_Reply_Command(HCI_Command): 2376 ''' 2377 See Bluetooth spec @ 7.8.26 LE Long Term Key Request Negative Reply Command 2378 ''' 2379 2380 2381# ----------------------------------------------------------------------------- 2382@HCI_Command.command() 2383class HCI_LE_Read_Supported_States_Command(HCI_Command): 2384 ''' 2385 See Bluetooth spec @ 7.8.27 LE Read Supported States Command 2386 ''' 2387 2388 2389# ----------------------------------------------------------------------------- 2390@HCI_Command.command([ 2391 ('connection_handle', 2), 2392 ('interval_min', 2), 2393 ('interval_max', 2), 2394 ('latency', 2), 2395 ('timeout', 2), 2396 ('minimum_ce_length', 2), 2397 ('maximum_ce_length', 2) 2398]) 2399class HCI_LE_Remote_Connection_Parameter_Request_Reply_Command(HCI_Command): 2400 ''' 2401 See Bluetooth spec @ 7.8.31 LE Remote Connection Parameter Request Reply Command 2402 ''' 2403 2404 2405# ----------------------------------------------------------------------------- 2406@HCI_Command.command([ 2407 ('connection_handle', 2), 2408 ('reason', {'size': 1, 'mapper': HCI_Constant.error_name}) 2409]) 2410class HCI_LE_Remote_Connection_Parameter_Request_Negative_Reply_Command(HCI_Command): 2411 ''' 2412 See Bluetooth spec @ 7.8.32 LE Remote Connection Parameter Request Negative Reply Command 2413 ''' 2414 2415 2416# ----------------------------------------------------------------------------- 2417@HCI_Command.command([ 2418 ('suggested_max_tx_octets', 2), 2419 ('suggested_max_tx_time', 2) 2420]) 2421class HCI_LE_Write_Suggested_Default_Data_Length_Command(HCI_Command): 2422 ''' 2423 See Bluetooth spec @ 7.8.35 LE Write Suggested Default Data Length Command 2424 ''' 2425 2426 2427# ----------------------------------------------------------------------------- 2428@HCI_Command.command([ 2429 ('peer_identity_address_type', Address.ADDRESS_TYPE_SPEC), 2430 ('peer_identity_address', Address.parse_address_preceded_by_type), 2431 ('peer_irk', 16), 2432 ('local_irk', 16), 2433]) 2434class HCI_LE_Add_Device_To_Resolving_List_Command(HCI_Command): 2435 ''' 2436 See Bluetooth spec @ 7.8.38 LE Add Device To Resolving List Command 2437 ''' 2438 2439 2440# ----------------------------------------------------------------------------- 2441@HCI_Command.command() 2442class HCI_LE_Clear_Resolving_List_Command(HCI_Command): 2443 ''' 2444 See Bluetooth spec @ 7.8.40 LE Clear Resolving List Command 2445 ''' 2446 2447 2448# ----------------------------------------------------------------------------- 2449@HCI_Command.command([ 2450 ('all_phys', 1), 2451 ('tx_phys', 1), 2452 ('rx_phys', 1) 2453]) 2454class HCI_LE_Set_Default_PHY_Command(HCI_Command): 2455 ''' 2456 See Bluetooth spec @ 7.8.48 LE Set Default PHY Command 2457 ''' 2458 2459 2460# ----------------------------------------------------------------------------- 2461@HCI_Command.command([ 2462 ('address_resolution_enable', 1) 2463]) 2464class HCI_LE_Set_Address_Resolution_Enable_Command(HCI_Command): 2465 ''' 2466 See Bluetooth spec @ 7.8.44 LE Set Address Resolution Enable Command 2467 ''' 2468 2469 2470# ----------------------------------------------------------------------------- 2471@HCI_Command.command([ 2472 ('rpa_timeout', 2) 2473]) 2474class HCI_LE_Set_Resolvable_Private_Address_Timeout_Command(HCI_Command): 2475 ''' 2476 See Bluetooth spec @ 7.8.45 LE Set Resolvable Private Address Timeout Command 2477 ''' 2478 2479 2480# ----------------------------------------------------------------------------- 2481# HCI Events 2482# ----------------------------------------------------------------------------- 2483class HCI_Event(HCI_Packet): 2484 ''' 2485 See Bluetooth spec @ Vol 2, Part E - 5.4.4 HCI Event Packet 2486 ''' 2487 hci_packet_type = HCI_EVENT_PACKET 2488 event_classes = {} 2489 meta_event_classes = {} 2490 2491 @staticmethod 2492 def event(fields=[]): 2493 ''' 2494 Decorator used to declare and register subclasses 2495 ''' 2496 2497 def inner(cls): 2498 cls.name = cls.__name__.upper() 2499 cls.event_code = key_with_value(HCI_EVENT_NAMES, cls.name) 2500 if cls.event_code is None: 2501 raise KeyError('event not found in HCI_EVENT_NAMES') 2502 cls.fields = fields 2503 2504 # Patch the __init__ method to fix the event_code 2505 def init(self, parameters=None, **kwargs): 2506 return HCI_Event.__init__(self, cls.event_code, parameters, **kwargs) 2507 cls.__init__ = init 2508 2509 # Register a factory for this class 2510 HCI_Event.event_classes[cls.event_code] = cls 2511 2512 return cls 2513 2514 return inner 2515 2516 @staticmethod 2517 def registered(cls): 2518 cls.name = cls.__name__.upper() 2519 cls.event_code = key_with_value(HCI_EVENT_NAMES, cls.name) 2520 if cls.event_code is None: 2521 raise KeyError('event not found in HCI_EVENT_NAMES') 2522 2523 # Register a factory for this class 2524 HCI_Event.event_classes[cls.event_code] = cls 2525 2526 return cls 2527 2528 @staticmethod 2529 def from_bytes(packet): 2530 event_code = packet[1] 2531 length = packet[2] 2532 parameters = packet[3:] 2533 if len(parameters) != length: 2534 raise ValueError('invalid packet length') 2535 2536 if event_code == HCI_LE_META_EVENT: 2537 # We do this dispatch here and not in the subclass in order to avoid call loops 2538 subevent_code = parameters[0] 2539 cls = HCI_Event.meta_event_classes.get(subevent_code) 2540 if cls is None: 2541 # No class registered, just use a generic class instance 2542 return HCI_LE_Meta_Event(subevent_code, parameters) 2543 2544 else: 2545 cls = HCI_Event.event_classes.get(event_code) 2546 if cls is None: 2547 # No class registered, just use a generic class instance 2548 return HCI_Event(event_code, parameters) 2549 2550 # Invoke the factory to create a new instance 2551 return cls.from_parameters(parameters) 2552 2553 @classmethod 2554 def from_parameters(cls, parameters): 2555 self = cls.__new__(cls) 2556 HCI_Event.__init__(self, self.event_code, parameters) 2557 if fields := getattr(self, 'fields', None): 2558 HCI_Object.init_from_bytes(self, parameters, 0, fields) 2559 return self 2560 2561 @staticmethod 2562 def event_name(event_code): 2563 return name_or_number(HCI_EVENT_NAMES, event_code) 2564 2565 def __init__(self, event_code, parameters=None, **kwargs): 2566 super().__init__(HCI_Event.event_name(event_code)) 2567 if (fields := getattr(self, 'fields', None)) and kwargs: 2568 HCI_Object.init_from_fields(self, fields, kwargs) 2569 if parameters is None: 2570 parameters = HCI_Object.dict_to_bytes(kwargs, fields) 2571 self.event_code = event_code 2572 self.parameters = parameters 2573 2574 def to_bytes(self): 2575 parameters = b'' if self.parameters is None else self.parameters 2576 return bytes([HCI_EVENT_PACKET, self.event_code, len(parameters)]) + parameters 2577 2578 def __str__(self): 2579 result = color(self.name, 'magenta') 2580 if fields := getattr(self, 'fields', None): 2581 result += ':\n' + HCI_Object.format_fields(self.__dict__, fields, ' ') 2582 else: 2583 if self.parameters: 2584 result += f': {self.parameters.hex()}' 2585 return result 2586 2587 2588# ----------------------------------------------------------------------------- 2589class HCI_LE_Meta_Event(HCI_Event): 2590 ''' 2591 See Bluetooth spec @ 7.7.65 LE Meta Event 2592 ''' 2593 2594 @staticmethod 2595 def event(fields=[]): 2596 ''' 2597 Decorator used to declare and register subclasses 2598 ''' 2599 2600 def inner(cls): 2601 cls.name = cls.__name__.upper() 2602 cls.subevent_code = key_with_value(HCI_SUBEVENT_NAMES, cls.name) 2603 if cls.subevent_code is None: 2604 raise KeyError('subevent not found in HCI_SUBEVENT_NAMES') 2605 cls.fields = fields 2606 2607 # Patch the __init__ method to fix the subevent_code 2608 def init(self, parameters=None, **kwargs): 2609 return HCI_LE_Meta_Event.__init__(self, cls.subevent_code, parameters, **kwargs) 2610 cls.__init__ = init 2611 2612 # Register a factory for this class 2613 HCI_Event.meta_event_classes[cls.subevent_code] = cls 2614 2615 return cls 2616 2617 return inner 2618 2619 @classmethod 2620 def from_parameters(cls, parameters): 2621 self = cls.__new__(cls) 2622 HCI_LE_Meta_Event.__init__(self, self.subevent_code, parameters) 2623 if fields := getattr(self, 'fields', None): 2624 HCI_Object.init_from_bytes(self, parameters, 1, fields) 2625 return self 2626 2627 @staticmethod 2628 def subevent_name(subevent_code): 2629 return name_or_number(HCI_SUBEVENT_NAMES, subevent_code) 2630 2631 def __init__(self, subevent_code, parameters, **kwargs): 2632 self.subevent_code = subevent_code 2633 if parameters is None and (fields := getattr(self, 'fields', None)) and kwargs: 2634 parameters = bytes([subevent_code]) + HCI_Object.dict_to_bytes(kwargs, fields) 2635 super().__init__(HCI_LE_META_EVENT, parameters, **kwargs) 2636 2637 # Override the name in order to adopt the subevent name instead 2638 self.name = self.subevent_name(subevent_code) 2639 2640 def __str__(self): 2641 result = color(self.subevent_name(self.subevent_code), 'magenta') 2642 if fields := getattr(self, 'fields', None): 2643 result += ':\n' + HCI_Object.format_fields(self.__dict__, fields, ' ') 2644 else: 2645 if self.parameters: 2646 result += f': {self.parameters.hex()}' 2647 return result 2648 2649 2650# ----------------------------------------------------------------------------- 2651@HCI_LE_Meta_Event.event([ 2652 ('status', STATUS_SPEC), 2653 ('connection_handle', 2), 2654 ('role', {'size': 1, 'mapper': lambda x: 'CENTRAL' if x == 0 else 'PERIPHERAL'}), 2655 ('peer_address_type', Address.ADDRESS_TYPE_SPEC), 2656 ('peer_address', Address.parse_address_preceded_by_type), 2657 ('conn_interval', 2), 2658 ('conn_latency', 2), 2659 ('supervision_timeout', 2), 2660 ('master_clock_accuracy', 1) 2661]) 2662class HCI_LE_Connection_Complete_Event(HCI_LE_Meta_Event): 2663 ''' 2664 See Bluetooth spec @ 7.7.65.1 LE Connection Complete Event 2665 ''' 2666 2667 2668# ----------------------------------------------------------------------------- 2669class HCI_LE_Advertising_Report_Event(HCI_LE_Meta_Event): 2670 ''' 2671 See Bluetooth spec @ 7.7.65.2 LE Advertising Report Event 2672 ''' 2673 subevent_code = HCI_LE_ADVERTISING_REPORT_EVENT 2674 2675 # Event Types 2676 ADV_IND = 0x00 2677 ADV_DIRECT_IND = 0x01 2678 ADV_SCAN_IND = 0x02 2679 ADV_NONCONN_IND = 0x03 2680 SCAN_RSP = 0x04 2681 2682 EVENT_TYPE_NAMES = { 2683 ADV_IND: 'ADV_IND', # Connectable and scannable undirected advertising 2684 ADV_DIRECT_IND: 'ADV_DIRECT_IND', # Connectable directed advertising 2685 ADV_SCAN_IND: 'ADV_SCAN_IND', # Scannable undirected advertising 2686 ADV_NONCONN_IND: 'ADV_NONCONN_IND', # Non connectable undirected advertising 2687 SCAN_RSP: 'SCAN_RSP' # Scan Response 2688 } 2689 2690 REPORT_FIELDS = [ 2691 ('event_type', 1), 2692 ('address_type', Address.ADDRESS_TYPE_SPEC), 2693 ('address', Address.parse_address_preceded_by_type), 2694 ('data', {'parser': HCI_Object.parse_length_prefixed_bytes, 'serializer': HCI_Object.serialize_length_prefixed_bytes}), 2695 ('rssi', -1) 2696 ] 2697 2698 @classmethod 2699 def event_type_name(cls, event_type): 2700 return name_or_number(cls.EVENT_TYPE_NAMES, event_type) 2701 2702 @staticmethod 2703 def from_parameters(parameters): 2704 num_reports = parameters[1] 2705 reports = [] 2706 offset = 2 2707 for _ in range(num_reports): 2708 report = HCI_Object.from_bytes(parameters, offset, HCI_LE_Advertising_Report_Event.REPORT_FIELDS) 2709 offset += 10 + len(report.data) 2710 reports.append(report) 2711 2712 return HCI_LE_Advertising_Report_Event(reports) 2713 2714 def __init__(self, reports): 2715 self.reports = reports[:] 2716 2717 # Serialize the fields 2718 parameters = bytes([HCI_LE_ADVERTISING_REPORT_EVENT, len(reports)]) + b''.join([bytes(report) for report in reports]) 2719 2720 super().__init__(self.subevent_code, parameters) 2721 2722 def __str__(self): 2723 reports = '\n'.join([report.to_string(' ', { 2724 'event_type': self.event_type_name, 2725 'address_type': Address.address_type_name, 2726 'data': lambda x: str(AdvertisingData.from_bytes(x)) 2727 }) for report in self.reports]) 2728 return f'{color(self.subevent_name(self.subevent_code), "magenta")}:\n{reports}' 2729 2730 2731HCI_Event.meta_event_classes[HCI_LE_ADVERTISING_REPORT_EVENT] = HCI_LE_Advertising_Report_Event 2732 2733 2734# ----------------------------------------------------------------------------- 2735@HCI_LE_Meta_Event.event([ 2736 ('status', STATUS_SPEC), 2737 ('connection_handle', 2), 2738 ('conn_interval', 2), 2739 ('conn_latency', 2), 2740 ('supervision_timeout', 2) 2741]) 2742class HCI_LE_Connection_Update_Complete_Event(HCI_LE_Meta_Event): 2743 ''' 2744 See Bluetooth spec @ 7.7.65.3 LE Connection Update Complete Event 2745 ''' 2746 2747 2748# ----------------------------------------------------------------------------- 2749@HCI_LE_Meta_Event.event([ 2750 ('status', STATUS_SPEC), 2751 ('connection_handle', 2), 2752 ('le_features', 8) 2753]) 2754class HCI_LE_Read_Remote_Features_Complete_Event(HCI_LE_Meta_Event): 2755 ''' 2756 See Bluetooth spec @ 7.7.65.4 LE Read Remote Features Complete Event 2757 ''' 2758 2759 2760# ----------------------------------------------------------------------------- 2761@HCI_LE_Meta_Event.event([ 2762 ('connection_handle', 2), 2763 ('random_number', 8), 2764 ('encryption_diversifier', 2) 2765]) 2766class HCI_LE_Long_Term_Key_Request_Event(HCI_LE_Meta_Event): 2767 ''' 2768 See Bluetooth spec @ 7.7.65.5 LE Long Term Key Request Event 2769 ''' 2770 2771 2772# ----------------------------------------------------------------------------- 2773@HCI_LE_Meta_Event.event([ 2774 ('connection_handle', 2), 2775 ('interval_min', 2), 2776 ('interval_max', 2), 2777 ('latency', 2), 2778 ('timeout', 2) 2779]) 2780class HCI_LE_Remote_Connection_Parameter_Request_Event(HCI_LE_Meta_Event): 2781 ''' 2782 See Bluetooth spec @ 7.7.65.6 LE Remote Connection Parameter Request Event 2783 ''' 2784 2785 2786# ----------------------------------------------------------------------------- 2787@HCI_LE_Meta_Event.event([ 2788 ('connection_handle', 2), 2789 ('max_tx_octets', 2), 2790 ('max_tx_time', 2), 2791 ('max_rx_octets', 2), 2792 ('max_rx_time', 2), 2793]) 2794class HCI_LE_Data_Length_Change_Event(HCI_LE_Meta_Event): 2795 ''' 2796 See Bluetooth spec @ 7.7.65.7 LE Data Length Change Event 2797 ''' 2798 2799 2800# ----------------------------------------------------------------------------- 2801@HCI_LE_Meta_Event.event([ 2802 ('status', STATUS_SPEC), 2803 ('connection_handle', 2), 2804 ('role', {'size': 1, 'mapper': lambda x: 'CENTRAL' if x == 0 else 'PERIPHERAL'}), 2805 ('peer_address_type', Address.ADDRESS_TYPE_SPEC), 2806 ('peer_address', Address.parse_address_preceded_by_type), 2807 ('local_resolvable_private_address', Address.parse_address), 2808 ('peer_resolvable_private_address', Address.parse_address), 2809 ('conn_interval', 2), 2810 ('conn_latency', 2), 2811 ('supervision_timeout', 2), 2812 ('master_clock_accuracy', 1) 2813]) 2814class HCI_LE_Enhanced_Connection_Complete_Event(HCI_LE_Meta_Event): 2815 ''' 2816 See Bluetooth spec @ 7.7.65.10 LE Enhanced Connection Complete Event 2817 ''' 2818 2819 2820# ----------------------------------------------------------------------------- 2821@HCI_LE_Meta_Event.event([ 2822 ('status', STATUS_SPEC), 2823 ('connection_handle', 2), 2824 ('tx_phy', {'size': 1, 'mapper': HCI_Constant.le_phy_name}), 2825 ('rx_phy', {'size': 1, 'mapper': HCI_Constant.le_phy_name}) 2826]) 2827class HCI_LE_PHY_Update_Complete_Event(HCI_LE_Meta_Event): 2828 ''' 2829 See Bluetooth spec @ 7.7.65.12 LE PHY Update Complete Event 2830 ''' 2831 2832 2833# ----------------------------------------------------------------------------- 2834@HCI_LE_Meta_Event.event([ 2835 ('connection_handle', 2), 2836 ('channel_selection_algorithm', 1) 2837]) 2838class HCI_LE_Channel_Selection_Algorithm_Event(HCI_LE_Meta_Event): 2839 ''' 2840 See Bluetooth spec @ 7.7.65.20 LE Channel Selection Algorithm Event 2841 ''' 2842 2843 2844# ----------------------------------------------------------------------------- 2845@HCI_Event.event([ 2846 ('status', STATUS_SPEC) 2847]) 2848class HCI_Inquiry_Complete_Event(HCI_Event): 2849 ''' 2850 See Bluetooth spec @ 7.7.1 Inquiry Complete Event 2851 ''' 2852 2853 2854# ----------------------------------------------------------------------------- 2855@HCI_Event.registered 2856class HCI_Inquiry_Result_Event(HCI_Event): 2857 ''' 2858 See Bluetooth spec @ 7.7.2 Inquiry Result Event 2859 ''' 2860 2861 RESPONSE_FIELDS = [ 2862 ('bd_addr', Address.parse_address), 2863 ('page_scan_repetition_mode', 1), 2864 ('reserved', 1), 2865 ('reserved', 1), 2866 ('class_of_device', {'size': 3, 'mapper': map_class_of_device}), 2867 ('clock_offset', 2) 2868 ] 2869 2870 @staticmethod 2871 def from_parameters(parameters): 2872 num_responses = parameters[0] 2873 responses = [] 2874 offset = 1 2875 for _ in range(num_responses): 2876 response = HCI_Object.from_bytes(parameters, offset, HCI_Inquiry_Result_Event.RESPONSE_FIELDS) 2877 offset += 14 2878 responses.append(response) 2879 2880 return HCI_Inquiry_Result_Event(responses) 2881 2882 def __init__(self, responses): 2883 self.responses = responses[:] 2884 2885 # Serialize the fields 2886 parameters = bytes([HCI_INQUIRY_RESULT_EVENT, len(responses)]) + b''.join([bytes(response) for response in responses]) 2887 2888 super().__init__(HCI_INQUIRY_RESULT_EVENT, parameters) 2889 2890 def __str__(self): 2891 responses = '\n'.join([response.to_string(indentation=' ') for response in self.responses]) 2892 return f'{color("HCI_INQUIRY_RESULT_EVENT", "magenta")}:\n{responses}' 2893 2894 2895# ----------------------------------------------------------------------------- 2896@HCI_Event.event([ 2897 ('status', STATUS_SPEC), 2898 ('connection_handle', 2), 2899 ('bd_addr', Address.parse_address), 2900 ('link_type', {'size': 1, 'mapper': lambda x: HCI_Connection_Complete_Event.link_type_name(x)}), 2901 ('encryption_enabled', 1) 2902]) 2903class HCI_Connection_Complete_Event(HCI_Event): 2904 ''' 2905 See Bluetooth spec @ 7.7.3 Connection Complete Event 2906 ''' 2907 2908 SCO_LINK_TYPE = 0x00 2909 ACL_LINK_TYPE = 0x01 2910 ESCO_LINK_TYPE = 0x02 2911 2912 LINK_TYPE_NAMES = { 2913 SCO_LINK_TYPE: 'SCO', 2914 ACL_LINK_TYPE: 'ACL', 2915 ESCO_LINK_TYPE: 'eSCO' 2916 } 2917 2918 @staticmethod 2919 def link_type_name(link_type): 2920 return name_or_number(HCI_Connection_Complete_Event.LINK_TYPE_NAMES, link_type) 2921 2922 2923# ----------------------------------------------------------------------------- 2924@HCI_Event.event([ 2925 ('bd_addr', Address.parse_address), 2926 ('class_of_device', 3), 2927 ('link_type', {'size': 1, 'mapper': lambda x: HCI_Connection_Complete_Event.link_type_name(x)}) 2928]) 2929class HCI_Connection_Request_Event(HCI_Event): 2930 ''' 2931 See Bluetooth spec @ 7.7.4 Connection Request Event 2932 ''' 2933 2934 2935# ----------------------------------------------------------------------------- 2936@HCI_Event.event([ 2937 ('status', STATUS_SPEC), 2938 ('connection_handle', 2), 2939 ('reason', {'size': 1, 'mapper': HCI_Constant.error_name}) 2940]) 2941class HCI_Disconnection_Complete_Event(HCI_Event): 2942 ''' 2943 See Bluetooth spec @ 7.7.5 Disconnection Complete Event 2944 ''' 2945 2946 2947# ----------------------------------------------------------------------------- 2948@HCI_Event.event([ 2949 ('status', STATUS_SPEC), 2950 ('connection_handle', 2) 2951]) 2952class HCI_Authentication_Complete_Event(HCI_Event): 2953 ''' 2954 See Bluetooth spec @ 7.7.6 Authentication Complete Event 2955 ''' 2956 2957 2958# ----------------------------------------------------------------------------- 2959@HCI_Event.event([ 2960 ('status', STATUS_SPEC), 2961 ('bd_addr', Address.parse_address), 2962 ('remote_name', {'size': 248, 'mapper': map_null_terminated_utf8_string}) 2963]) 2964class HCI_Remote_Name_Request_Complete_Event(HCI_Event): 2965 ''' 2966 See Bluetooth spec @ 7.7.7 Remote Name Request Complete Event 2967 ''' 2968 2969 2970# ----------------------------------------------------------------------------- 2971@HCI_Event.event([ 2972 ('status', STATUS_SPEC), 2973 ('connection_handle', 2), 2974 ('encryption_enabled', {'size': 1, 'mapper': lambda x: HCI_Encryption_Change_Event.encryption_enabled_name(x)}) 2975]) 2976class HCI_Encryption_Change_Event(HCI_Event): 2977 ''' 2978 See Bluetooth spec @ 7.7.8 Encryption Change Event 2979 ''' 2980 2981 OFF = 0x00 2982 E0_OR_AES_CCM = 0x01 2983 AES_CCM = 0x02 2984 2985 ENCYRPTION_ENABLED_NAMES = { 2986 OFF: 'OFF', 2987 E0_OR_AES_CCM: 'E0_OR_AES_CCM', 2988 AES_CCM: 'AES_CCM' 2989 } 2990 2991 @staticmethod 2992 def encryption_enabled_name(encryption_enabled): 2993 return name_or_number(HCI_Encryption_Change_Event.ENCYRPTION_ENABLED_NAMES, encryption_enabled) 2994 2995 2996# ----------------------------------------------------------------------------- 2997@HCI_Event.event([ 2998 ('status', STATUS_SPEC), 2999 ('connection_handle', 2), 3000 ('lmp_features', 8) 3001]) 3002class HCI_Read_Remote_Supported_Features_Complete_Event(HCI_Event): 3003 ''' 3004 See Bluetooth spec @ 7.7.11 Read Remote Supported Features Complete Event 3005 ''' 3006 3007 3008# ----------------------------------------------------------------------------- 3009@HCI_Event.event([ 3010 ('status', STATUS_SPEC), 3011 ('connection_handle', 2), 3012 ('version', 1), 3013 ('manufacturer_name', 2), 3014 ('subversion', 2) 3015]) 3016class HCI_Read_Remote_Version_Information_Complete_Event(HCI_Event): 3017 ''' 3018 See Bluetooth spec @ 7.7.12 Read Remote Version Information Complete Event 3019 ''' 3020 3021 3022# ----------------------------------------------------------------------------- 3023@HCI_Event.event([ 3024 ('num_hci_command_packets', 1), 3025 ('command_opcode', {'size': 2, 'mapper': HCI_Command.command_name}), 3026 ('return_parameters', '*') 3027]) 3028class HCI_Command_Complete_Event(HCI_Event): 3029 ''' 3030 See Bluetooth spec @ 7.7.14 Command Complete Event 3031 ''' 3032 3033 def map_return_parameters(self, return_parameters): 3034 # Map simple 'status' return parameters to their named constant form 3035 if type(return_parameters) is bytes and len(return_parameters) == 1: 3036 # Byte-array form 3037 return HCI_Constant.status_name(return_parameters[0]) 3038 elif type(return_parameters) is int: 3039 # Already converted to an integer status code 3040 return HCI_Constant.status_name(return_parameters) 3041 else: 3042 return return_parameters 3043 3044 @staticmethod 3045 def from_parameters(parameters): 3046 self = HCI_Command_Complete_Event.__new__(HCI_Command_Complete_Event) 3047 HCI_Event.__init__(self, self.event_code, parameters) 3048 HCI_Object.init_from_bytes(self, parameters, 0, HCI_Command_Complete_Event.fields) 3049 3050 # Parse the return parameters 3051 if type(self.return_parameters) is bytes and len(self.return_parameters) == 1: 3052 # All commands with 1-byte return parameters return a 'status' field, convert it to an integer 3053 self.return_parameters = self.return_parameters[0] 3054 else: 3055 cls = HCI_Command.command_classes.get(self.command_opcode) 3056 if cls and cls.return_parameters_fields: 3057 self.return_parameters = HCI_Object.from_bytes(self.return_parameters, 0, cls.return_parameters_fields) 3058 self.return_parameters.fields = cls.return_parameters_fields 3059 3060 return self 3061 3062 def __str__(self): 3063 return f'{color(self.name, "magenta")}:\n' + HCI_Object.format_fields(self.__dict__, self.fields, ' ', { 3064 'return_parameters': self.map_return_parameters 3065 }) 3066 3067 3068# ----------------------------------------------------------------------------- 3069@HCI_Event.event([ 3070 ('status', {'size': 1, 'mapper': lambda x: HCI_Command_Status_Event.status_name(x)}), 3071 ('num_hci_command_packets', 1), 3072 ('command_opcode', {'size': 2, 'mapper': HCI_Command.command_name}) 3073]) 3074class HCI_Command_Status_Event(HCI_Event): 3075 ''' 3076 See Bluetooth spec @ 7.7.15 Command Complete Event 3077 ''' 3078 PENDING = 0 3079 3080 @staticmethod 3081 def status_name(status): 3082 if status == HCI_Command_Status_Event.PENDING: 3083 return 'PENDING' 3084 else: 3085 return HCI_Constant.error_name(status) 3086 3087 3088# ----------------------------------------------------------------------------- 3089@HCI_Event.event([ 3090 ('status', STATUS_SPEC), 3091 ('bd_addr', Address.parse_address), 3092 ('new_role', {'size': 1, 'mapper': HCI_Constant.role_name}) 3093]) 3094class HCI_Role_Change_Event(HCI_Event): 3095 ''' 3096 See Bluetooth spec @ 7.7.18 Role Change Event 3097 ''' 3098 3099 3100# ----------------------------------------------------------------------------- 3101@HCI_Event.registered 3102class HCI_Number_Of_Completed_Packets_Event(HCI_Event): 3103 ''' 3104 See Bluetooth spec @ 7.7.19 Number Of Completed Packets Event 3105 ''' 3106 3107 @classmethod 3108 def from_parameters(cls, parameters): 3109 self = cls.__new__(cls) 3110 self.parameters = parameters 3111 num_handles = parameters[0] 3112 self.connection_handles = [] 3113 self.num_completed_packets = [] 3114 for i in range(num_handles): 3115 self.connection_handles.append( 3116 struct.unpack_from('<H', parameters, 1 + i * 4)[0] 3117 ) 3118 self.num_completed_packets.append( 3119 struct.unpack_from('<H', parameters, 1 + i * 4 + 2)[0] 3120 ) 3121 3122 return self 3123 3124 def __init__(self, connection_handle_and_completed_packets_list): 3125 self.connection_handles = [] 3126 self.num_completed_packets = [] 3127 parameters = bytes([len(connection_handle_and_completed_packets_list)]) 3128 for handle, completed_packets in connection_handle_and_completed_packets_list: 3129 self.connection_handles.append(handle) 3130 self.num_completed_packets.append(completed_packets) 3131 parameters += struct.pack('<H', handle) 3132 parameters += struct.pack('<H', completed_packets) 3133 super().__init__(HCI_NUMBER_OF_COMPLETED_PACKETS_EVENT, parameters) 3134 3135 def __str__(self): 3136 lines = [ 3137 color(self.name, 'magenta') + ':', 3138 color(' number_of_handles: ', 'cyan') + f'{len(self.connection_handles)}' 3139 ] 3140 for i in range(len(self.connection_handles)): 3141 lines.append(color(f' connection_handle[{i}]: ', 'cyan') + f'{self.connection_handles[i]}') 3142 lines.append(color(f' num_completed_packets[{i}]: ', 'cyan') + f'{self.num_completed_packets[i]}') 3143 return '\n'.join(lines) 3144 3145 3146# ----------------------------------------------------------------------------- 3147@HCI_Event.event([ 3148 ('status', STATUS_SPEC), 3149 ('connection_handle', 2), 3150 ('current_mode', {'size': 1, 'mapper': lambda x: HCI_Mode_Change_Event.mode_name(x)}), 3151 ('interval', 2) 3152]) 3153class HCI_Mode_Change_Event(HCI_Event): 3154 ''' 3155 See Bluetooth spec @ 7.7.20 Mode Change Event 3156 ''' 3157 3158 ACTIVE_MODE = 0x00 3159 HOLD_MODE = 0x01 3160 SNIFF_MODE = 0x02 3161 3162 MODE_NAMES = { 3163 ACTIVE_MODE: 'ACTIVE_MODE', 3164 HOLD_MODE: 'HOLD_MODE', 3165 SNIFF_MODE: 'SNIFF_MODE' 3166 } 3167 3168 @staticmethod 3169 def mode_name(mode): 3170 return name_or_number(HCI_Mode_Change_Event.MODE_NAMES, mode) 3171 3172 3173# ----------------------------------------------------------------------------- 3174@HCI_Event.event([ 3175 ('bd_addr', Address.parse_address) 3176]) 3177class HCI_PIN_Code_Request_Event(HCI_Event): 3178 ''' 3179 See Bluetooth spec @ 7.7.22 PIN Code Request Event 3180 ''' 3181 3182 3183# ----------------------------------------------------------------------------- 3184@HCI_Event.event([ 3185 ('bd_addr', Address.parse_address) 3186]) 3187class HCI_Link_Key_Request_Event(HCI_Event): 3188 ''' 3189 See Bluetooth spec @ 7.7.24 7.7.23 Link Key Request Event 3190 ''' 3191 3192 3193# ----------------------------------------------------------------------------- 3194@HCI_Event.event([ 3195 ('bd_addr', Address.parse_address), 3196 ('link_key', 16), 3197 ('key_type', {'size': 1, 'mapper': HCI_Constant.link_key_type_name}) 3198]) 3199class HCI_Link_Key_Notification_Event(HCI_Event): 3200 ''' 3201 See Bluetooth spec @ 7.7.24 Link Key Notification Event 3202 ''' 3203 3204 3205# ----------------------------------------------------------------------------- 3206@HCI_Event.event([ 3207 ('connection_handle', 2), 3208 ('lmp_max_slots', 1) 3209]) 3210class HCI_Max_Slots_Change_Event(HCI_Event): 3211 ''' 3212 See Bluetooth spec @ 7.7.27 Max Slots Change Event 3213 ''' 3214 3215 3216# ----------------------------------------------------------------------------- 3217@HCI_Event.event([ 3218 ('status', STATUS_SPEC), 3219 ('connection_handle', 2), 3220 ('clock_offset', 2) 3221]) 3222class HCI_Read_Clock_Offset_Complete_Event(HCI_Event): 3223 ''' 3224 See Bluetooth spec @ 7.7.28 Read Clock Offset Complete Event 3225 ''' 3226 3227 3228# ----------------------------------------------------------------------------- 3229@HCI_Event.event([ 3230 ('status', STATUS_SPEC), 3231 ('connection_handle', 2), 3232 ('packet_type', 2) 3233]) 3234class HCI_Connection_Packet_Type_Changed_Event(HCI_Event): 3235 ''' 3236 See Bluetooth spec @ 7.7.29 Connection Packet Type Changed Event 3237 ''' 3238 3239 3240# ----------------------------------------------------------------------------- 3241@HCI_Event.event([ 3242 ('bd_addr', Address.parse_address), 3243 ('page_scan_repetition_mode', 1) 3244]) 3245class HCI_Page_Scan_Repetition_Mode_Change_Event(HCI_Event): 3246 ''' 3247 See Bluetooth spec @ 7.7.31 Page Scan Repetition Mode Change Event 3248 ''' 3249 3250 3251# ----------------------------------------------------------------------------- 3252@HCI_Event.registered 3253class HCI_Inquiry_Result_With_Rssi_Event(HCI_Event): 3254 ''' 3255 See Bluetooth spec @ 7.7.33 Inquiry Result with RSSI Event 3256 ''' 3257 3258 RESPONSE_FIELDS = [ 3259 ('bd_addr', Address.parse_address), 3260 ('page_scan_repetition_mode', 1), 3261 ('reserved', 1), 3262 ('class_of_device', {'size': 3, 'mapper': map_class_of_device}), 3263 ('clock_offset', 2), 3264 ('rssi', -1) 3265 ] 3266 3267 @staticmethod 3268 def from_parameters(parameters): 3269 num_responses = parameters[0] 3270 responses = [] 3271 offset = 1 3272 for _ in range(num_responses): 3273 response = HCI_Object.from_bytes(parameters, offset, HCI_Inquiry_Result_With_Rssi_Event.RESPONSE_FIELDS) 3274 offset += 14 3275 responses.append(response) 3276 3277 return HCI_Inquiry_Result_With_Rssi_Event(responses) 3278 3279 def __init__(self, responses): 3280 self.responses = responses[:] 3281 3282 # Serialize the fields 3283 parameters = bytes([HCI_INQUIRY_RESULT_WITH_RSSI_EVENT, len(responses)]) + b''.join([bytes(response) for response in responses]) 3284 3285 super().__init__(HCI_INQUIRY_RESULT_WITH_RSSI_EVENT, parameters) 3286 3287 def __str__(self): 3288 responses = '\n'.join([response.to_string(indentation=' ') for response in self.responses]) 3289 return f'{color("HCI_INQUIRY_RESULT_WITH_RSSI_EVENT", "magenta")}:\n{responses}' 3290 3291 3292# ----------------------------------------------------------------------------- 3293@HCI_Event.event([ 3294 ('status', STATUS_SPEC), 3295 ('connection_handle', 2), 3296 ('page_number', 1), 3297 ('maximum_page_number', 1), 3298 ('extended_lmp_features', 8) 3299]) 3300class HCI_Read_Remote_Extended_Features_Complete_Event(HCI_Event): 3301 ''' 3302 See Bluetooth spec @ 7.7.34 Read Remote Extended Features Complete Event 3303 ''' 3304 3305 3306# ----------------------------------------------------------------------------- 3307@HCI_Event.event([ 3308 ('status', STATUS_SPEC), 3309 ('connection_handle', 2), 3310 ('bd_addr', Address.parse_address), 3311 ('link_type', {'size': 1, 'mapper': lambda x: HCI_Synchronous_Connection_Complete_Event.link_type_name(x)}), 3312 ('transmission_interval', 1), 3313 ('retransmission_window', 1), 3314 ('rx_packet_length', 2), 3315 ('tx_packet_length', 2), 3316 ('air_mode', {'size': 1, 'mapper': lambda x: HCI_Synchronous_Connection_Complete_Event.air_mode_name(x)}), 3317]) 3318class HCI_Synchronous_Connection_Complete_Event(HCI_Event): 3319 ''' 3320 See Bluetooth spec @ 7.7.35 Synchronous Connection Complete Event 3321 ''' 3322 3323 SCO_CONNECTION_LINK_TYPE = 0x00 3324 ESCO_CONNECTION_LINK_TYPE = 0x02 3325 3326 LINK_TYPE_NAMES = { 3327 SCO_CONNECTION_LINK_TYPE: 'SCO', 3328 ESCO_CONNECTION_LINK_TYPE: 'eSCO' 3329 } 3330 3331 U_LAW_LOG_AIR_MODE = 0x00 3332 A_LAW_LOG_AIR_MORE = 0x01 3333 CVSD_AIR_MODE = 0x02 3334 TRANSPARENT_DATA_AIR_MODE = 0x03 3335 3336 AIR_MODE_NAMES = { 3337 U_LAW_LOG_AIR_MODE: 'u-law log', 3338 A_LAW_LOG_AIR_MORE: 'A-law log', 3339 CVSD_AIR_MODE: 'CVSD', 3340 TRANSPARENT_DATA_AIR_MODE: 'Transparend Data' 3341 } 3342 3343 @staticmethod 3344 def link_type_name(link_type): 3345 return name_or_number(HCI_Synchronous_Connection_Complete_Event.LINK_TYPE_NAMES, link_type) 3346 3347 @staticmethod 3348 def air_mode_name(air_mode): 3349 return name_or_number(HCI_Synchronous_Connection_Complete_Event.AIR_MODE_NAMES, air_mode) 3350 3351 3352# ----------------------------------------------------------------------------- 3353@HCI_Event.event([ 3354 ('status', STATUS_SPEC), 3355 ('connection_handle', 2), 3356 ('transmission_interval', 1), 3357 ('retransmission_window', 1), 3358 ('rx_packet_length', 2), 3359 ('tx_packet_length', 2) 3360]) 3361class HCI_Synchronous_Connection_Changed_Event(HCI_Event): 3362 ''' 3363 See Bluetooth spec @ 7.7.36 Synchronous Connection Changed Event 3364 ''' 3365 3366 3367# ----------------------------------------------------------------------------- 3368@HCI_Event.event([ 3369 ('num_responses', 1), 3370 ('bd_addr', Address.parse_address), 3371 ('page_scan_repetition_mode', 1), 3372 ('reserved', 1), 3373 ('class_of_device', {'size': 3, 'mapper': map_class_of_device}), 3374 ('clock_offset', 2), 3375 ('rssi', -1), 3376 ('extended_inquiry_response', 240), 3377]) 3378class HCI_Extended_Inquiry_Result_Event(HCI_Event): 3379 ''' 3380 See Bluetooth spec @ 7.7.38 Extended Inquiry Result Event 3381 ''' 3382 3383 3384# ----------------------------------------------------------------------------- 3385@HCI_Event.event([ 3386 ('status', STATUS_SPEC), 3387 ('connection_handle', 2) 3388]) 3389class HCI_Encryption_Key_Refresh_Complete_Event(HCI_Event): 3390 ''' 3391 See Bluetooth spec @ 7.7.39 Encryption Key Refresh Complete Event 3392 ''' 3393 3394 3395# ----------------------------------------------------------------------------- 3396@HCI_Event.event([ 3397 ('bd_addr', Address.parse_address) 3398]) 3399class HCI_IO_Capability_Request_Event(HCI_Event): 3400 ''' 3401 See Bluetooth spec @ 7.7.40 IO Capability Request Event 3402 ''' 3403 3404 3405# ----------------------------------------------------------------------------- 3406@HCI_Event.event([ 3407 ('bd_addr', Address.parse_address), 3408 ('io_capability', {'size': 1, 'mapper': HCI_Constant.io_capability_name}), 3409 ('oob_data_present', 1), 3410 ('authentication_requirements', {'size': 1, 'mapper': HCI_Constant.authentication_requirements_name}) 3411]) 3412class HCI_IO_Capability_Response_Event(HCI_Event): 3413 ''' 3414 See Bluetooth spec @ 7.7.41 IO Capability Response Event 3415 ''' 3416 3417 3418# ----------------------------------------------------------------------------- 3419@HCI_Event.event([ 3420 ('bd_addr', Address.parse_address), 3421 ('numeric_value', 4) 3422]) 3423class HCI_User_Confirmation_Request_Event(HCI_Event): 3424 ''' 3425 See Bluetooth spec @ 7.7.42 User Confirmation Request Event 3426 ''' 3427 3428 3429# ----------------------------------------------------------------------------- 3430@HCI_Event.event([ 3431 ('bd_addr', Address.parse_address) 3432]) 3433class HCI_User_Passkey_Request_Event(HCI_Event): 3434 ''' 3435 See Bluetooth spec @ 7.7.43 User Passkey Request Event 3436 ''' 3437 3438 3439# ----------------------------------------------------------------------------- 3440@HCI_Event.event([ 3441 ('status', STATUS_SPEC), 3442 ('bd_addr', Address.parse_address) 3443]) 3444class HCI_Simple_Pairing_Complete_Event(HCI_Event): 3445 ''' 3446 See Bluetooth spec @ 7.7.45 Simple Pairing Complete Event 3447 ''' 3448 3449 3450# ----------------------------------------------------------------------------- 3451@HCI_Event.event([ 3452 ('connection_handle', 2), 3453 ('link_supervision_timeout', 2) 3454]) 3455class HCI_Link_Supervision_Timeout_Changed_Event(HCI_Event): 3456 ''' 3457 See Bluetooth spec @ 7.7.46 Link Supervision Timeout Changed Event 3458 ''' 3459 3460 3461# ----------------------------------------------------------------------------- 3462@HCI_Event.event([ 3463 ('bd_addr', Address.parse_address), 3464 ('host_supported_features', 8) 3465]) 3466class HCI_Remote_Host_Supported_Features_Notification_Event(HCI_Event): 3467 ''' 3468 See Bluetooth spec @ 7.7.50 Remote Host Supported Features Notification Event 3469 ''' 3470 3471 3472# ----------------------------------------------------------------------------- 3473class HCI_AclDataPacket(HCI_Packet): 3474 ''' 3475 See Bluetooth spec @ 5.4.2 HCI ACL Data Packets 3476 ''' 3477 hci_packet_type = HCI_ACL_DATA_PACKET 3478 3479 @staticmethod 3480 def from_bytes(packet): 3481 # Read the header 3482 h, data_total_length = struct.unpack_from('<HH', packet, 1) 3483 connection_handle = h & 0xFFF 3484 pb_flag = (h >> 12) & 3 3485 bc_flag = (h >> 14) & 3 3486 data = packet[5:] 3487 if len(data) != data_total_length: 3488 raise ValueError('invalid packet length') 3489 return HCI_AclDataPacket(connection_handle, pb_flag, bc_flag, data_total_length, data) 3490 3491 def to_bytes(self): 3492 h = (self.pb_flag << 12) | (self.bc_flag << 14) | self.connection_handle 3493 return struct.pack('<BHH', HCI_ACL_DATA_PACKET, h, self.data_total_length) + self.data 3494 3495 def __init__(self, connection_handle, pb_flag, bc_flag, data_total_length, data): 3496 self.connection_handle = connection_handle 3497 self.pb_flag = pb_flag 3498 self.bc_flag = bc_flag 3499 self.data_total_length = data_total_length 3500 self.data = data 3501 3502 def __bytes__(self): 3503 return self.to_bytes() 3504 3505 def __str__(self): 3506 return f'{color("ACL", "blue")}: handle=0x{self.connection_handle:04x}, pb={self.pb_flag}, bc={self.bc_flag}, data_total_length={self.data_total_length}, data={self.data.hex()}' 3507 3508 3509# ----------------------------------------------------------------------------- 3510class HCI_AclDataPacketAssembler: 3511 def __init__(self, callback): 3512 self.callback = callback 3513 self.current_data = None 3514 self.l2cap_pdu_length = 0 3515 3516 def feed_packet(self, packet): 3517 if packet.pb_flag == HCI_ACL_PB_FIRST_NON_FLUSHABLE or packet.pb_flag == HCI_ACL_PB_FIRST_FLUSHABLE: 3518 (l2cap_pdu_length,) = struct.unpack_from('<H', packet.data, 0) 3519 self.current_data = packet.data 3520 self.l2cap_pdu_length = l2cap_pdu_length 3521 elif packet.pb_flag == HCI_ACL_PB_CONTINUATION: 3522 if self.current_data is None: 3523 logger.warning('!!! ACL continuation without start') 3524 return 3525 self.current_data += packet.data 3526 3527 if len(self.current_data) == self.l2cap_pdu_length + 4: 3528 # The packet is complete, invoke the callback 3529 logger.debug(f'<<< ACL PDU: {self.current_data.hex()}') 3530 self.callback(self.current_data) 3531 3532 # Reset 3533 self.current_data = None 3534 self.l2cap_pdu_length = 0 3535 else: 3536 # Sanity check 3537 if len(self.current_data) > self.l2cap_pdu_length + 4: 3538 logger.warning('!!! ACL data exceeds L2CAP PDU') 3539 self.current_data = None 3540 self.l2cap_pdu_length = 0 3541