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# ----------------------------------------------------------------------------- 18from __future__ import annotations 19import collections 20import dataclasses 21import enum 22import functools 23import logging 24import secrets 25import struct 26from typing import Any, Callable, Dict, Iterable, List, Optional, Type, Union, ClassVar 27 28from bumble import crypto 29from bumble.colors import color 30from bumble.core import ( 31 BT_BR_EDR_TRANSPORT, 32 AdvertisingData, 33 DeviceClass, 34 InvalidArgumentError, 35 InvalidPacketError, 36 ProtocolError, 37 bit_flags_to_strings, 38 name_or_number, 39 padded_bytes, 40) 41from bumble.utils import OpenIntEnum 42 43 44# ----------------------------------------------------------------------------- 45# Logging 46# ----------------------------------------------------------------------------- 47logger = logging.getLogger(__name__) 48 49 50# ----------------------------------------------------------------------------- 51# Utils 52# ----------------------------------------------------------------------------- 53def hci_command_op_code(ogf, ocf): 54 return ogf << 10 | ocf 55 56 57def hci_vendor_command_op_code(ocf): 58 return hci_command_op_code(HCI_VENDOR_OGF, ocf) 59 60 61def key_with_value(dictionary, target_value): 62 for key, value in dictionary.items(): 63 if value == target_value: 64 return key 65 return None 66 67 68def indent_lines(string): 69 return '\n'.join([' ' + line for line in string.split('\n')]) 70 71 72def map_null_terminated_utf8_string(utf8_bytes): 73 try: 74 terminator = utf8_bytes.find(0) 75 if terminator < 0: 76 terminator = len(utf8_bytes) 77 return utf8_bytes[0:terminator].decode('utf8') 78 except UnicodeDecodeError: 79 return utf8_bytes 80 81 82def map_class_of_device(class_of_device): 83 ( 84 service_classes, 85 major_device_class, 86 minor_device_class, 87 ) = DeviceClass.split_class_of_device(class_of_device) 88 return ( 89 f'[{class_of_device:06X}] Services(' 90 f'{",".join(DeviceClass.service_class_labels(service_classes))}),' 91 f'Class({DeviceClass.major_device_class_name(major_device_class)}|' 92 f'{DeviceClass.minor_device_class_name(major_device_class, minor_device_class)}' 93 ')' 94 ) 95 96 97def phy_list_to_bits(phys: Optional[Iterable[int]]) -> int: 98 if phys is None: 99 return 0 100 101 phy_bits = 0 102 for phy in phys: 103 if phy not in HCI_LE_PHY_TYPE_TO_BIT: 104 raise InvalidArgumentError('invalid PHY') 105 phy_bits |= 1 << HCI_LE_PHY_TYPE_TO_BIT[phy] 106 return phy_bits 107 108 109# ----------------------------------------------------------------------------- 110# Constants 111# ----------------------------------------------------------------------------- 112# fmt: off 113# pylint: disable=line-too-long 114 115HCI_VENDOR_OGF = 0x3F 116 117# HCI Version 118HCI_VERSION_BLUETOOTH_CORE_1_0B = 0 119HCI_VERSION_BLUETOOTH_CORE_1_1 = 1 120HCI_VERSION_BLUETOOTH_CORE_1_2 = 2 121HCI_VERSION_BLUETOOTH_CORE_2_0_EDR = 3 122HCI_VERSION_BLUETOOTH_CORE_2_1_EDR = 4 123HCI_VERSION_BLUETOOTH_CORE_3_0_HS = 5 124HCI_VERSION_BLUETOOTH_CORE_4_0 = 6 125HCI_VERSION_BLUETOOTH_CORE_4_1 = 7 126HCI_VERSION_BLUETOOTH_CORE_4_2 = 8 127HCI_VERSION_BLUETOOTH_CORE_5_0 = 9 128HCI_VERSION_BLUETOOTH_CORE_5_1 = 10 129HCI_VERSION_BLUETOOTH_CORE_5_2 = 11 130HCI_VERSION_BLUETOOTH_CORE_5_3 = 12 131HCI_VERSION_BLUETOOTH_CORE_5_4 = 13 132 133HCI_VERSION_NAMES = { 134 HCI_VERSION_BLUETOOTH_CORE_1_0B: 'HCI_VERSION_BLUETOOTH_CORE_1_0B', 135 HCI_VERSION_BLUETOOTH_CORE_1_1: 'HCI_VERSION_BLUETOOTH_CORE_1_1', 136 HCI_VERSION_BLUETOOTH_CORE_1_2: 'HCI_VERSION_BLUETOOTH_CORE_1_2', 137 HCI_VERSION_BLUETOOTH_CORE_2_0_EDR: 'HCI_VERSION_BLUETOOTH_CORE_2_0_EDR', 138 HCI_VERSION_BLUETOOTH_CORE_2_1_EDR: 'HCI_VERSION_BLUETOOTH_CORE_2_1_EDR', 139 HCI_VERSION_BLUETOOTH_CORE_3_0_HS: 'HCI_VERSION_BLUETOOTH_CORE_3_0_HS', 140 HCI_VERSION_BLUETOOTH_CORE_4_0: 'HCI_VERSION_BLUETOOTH_CORE_4_0', 141 HCI_VERSION_BLUETOOTH_CORE_4_1: 'HCI_VERSION_BLUETOOTH_CORE_4_1', 142 HCI_VERSION_BLUETOOTH_CORE_4_2: 'HCI_VERSION_BLUETOOTH_CORE_4_2', 143 HCI_VERSION_BLUETOOTH_CORE_5_0: 'HCI_VERSION_BLUETOOTH_CORE_5_0', 144 HCI_VERSION_BLUETOOTH_CORE_5_1: 'HCI_VERSION_BLUETOOTH_CORE_5_1', 145 HCI_VERSION_BLUETOOTH_CORE_5_2: 'HCI_VERSION_BLUETOOTH_CORE_5_2', 146 HCI_VERSION_BLUETOOTH_CORE_5_3: 'HCI_VERSION_BLUETOOTH_CORE_5_3', 147 HCI_VERSION_BLUETOOTH_CORE_5_4: 'HCI_VERSION_BLUETOOTH_CORE_5_4', 148} 149 150# LMP Version 151LMP_VERSION_NAMES = HCI_VERSION_NAMES 152 153# HCI Packet types 154HCI_COMMAND_PACKET = 0x01 155HCI_ACL_DATA_PACKET = 0x02 156HCI_SYNCHRONOUS_DATA_PACKET = 0x03 157HCI_EVENT_PACKET = 0x04 158HCI_ISO_DATA_PACKET = 0x05 159 160# HCI Event Codes 161HCI_INQUIRY_COMPLETE_EVENT = 0x01 162HCI_INQUIRY_RESULT_EVENT = 0x02 163HCI_CONNECTION_COMPLETE_EVENT = 0x03 164HCI_CONNECTION_REQUEST_EVENT = 0x04 165HCI_DISCONNECTION_COMPLETE_EVENT = 0x05 166HCI_AUTHENTICATION_COMPLETE_EVENT = 0x06 167HCI_REMOTE_NAME_REQUEST_COMPLETE_EVENT = 0x07 168HCI_ENCRYPTION_CHANGE_EVENT = 0x08 169HCI_CHANGE_CONNECTION_LINK_KEY_COMPLETE_EVENT = 0x09 170HCI_LINK_KEY_TYPE_CHANGED_EVENT = 0x0A 171HCI_READ_REMOTE_SUPPORTED_FEATURES_COMPLETE_EVENT = 0x0B 172HCI_READ_REMOTE_VERSION_INFORMATION_COMPLETE_EVENT = 0x0C 173HCI_QOS_SETUP_COMPLETE_EVENT = 0x0D 174HCI_COMMAND_COMPLETE_EVENT = 0x0E 175HCI_COMMAND_STATUS_EVENT = 0x0F 176HCI_HARDWARE_ERROR_EVENT = 0x10 177HCI_FLUSH_OCCURRED_EVENT = 0x11 178HCI_ROLE_CHANGE_EVENT = 0x12 179HCI_NUMBER_OF_COMPLETED_PACKETS_EVENT = 0x13 180HCI_MODE_CHANGE_EVENT = 0x14 181HCI_RETURN_LINK_KEYS_EVENT = 0x15 182HCI_PIN_CODE_REQUEST_EVENT = 0x16 183HCI_LINK_KEY_REQUEST_EVENT = 0x17 184HCI_LINK_KEY_NOTIFICATION_EVENT = 0x18 185HCI_LOOPBACK_COMMAND_EVENT = 0x19 186HCI_DATA_BUFFER_OVERFLOW_EVENT = 0x1A 187HCI_MAX_SLOTS_CHANGE_EVENT = 0x1B 188HCI_READ_CLOCK_OFFSET_COMPLETE_EVENT = 0x1C 189HCI_CONNECTION_PACKET_TYPE_CHANGED_EVENT = 0x1D 190HCI_QOS_VIOLATION_EVENT = 0x1E 191HCI_PAGE_SCAN_REPETITION_MODE_CHANGE_EVENT = 0x20 192HCI_FLOW_SPECIFICATION_COMPLETE_EVENT = 0x21 193HCI_INQUIRY_RESULT_WITH_RSSI_EVENT = 0x22 194HCI_READ_REMOTE_EXTENDED_FEATURES_COMPLETE_EVENT = 0x23 195HCI_SYNCHRONOUS_CONNECTION_COMPLETE_EVENT = 0x2C 196HCI_SYNCHRONOUS_CONNECTION_CHANGED_EVENT = 0x2D 197HCI_SNIFF_SUBRATING_EVENT = 0x2E 198HCI_EXTENDED_INQUIRY_RESULT_EVENT = 0x2F 199HCI_ENCRYPTION_KEY_REFRESH_COMPLETE_EVENT = 0x30 200HCI_IO_CAPABILITY_REQUEST_EVENT = 0x31 201HCI_IO_CAPABILITY_RESPONSE_EVENT = 0x32 202HCI_USER_CONFIRMATION_REQUEST_EVENT = 0x33 203HCI_USER_PASSKEY_REQUEST_EVENT = 0x34 204HCI_REMOTE_OOB_DATA_REQUEST_EVENT = 0x35 205HCI_SIMPLE_PAIRING_COMPLETE_EVENT = 0x36 206HCI_LINK_SUPERVISION_TIMEOUT_CHANGED_EVENT = 0x38 207HCI_ENHANCED_FLUSH_COMPLETE_EVENT = 0x39 208HCI_USER_PASSKEY_NOTIFICATION_EVENT = 0x3B 209HCI_KEYPRESS_NOTIFICATION_EVENT = 0x3C 210HCI_REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION_EVENT = 0x3D 211HCI_LE_META_EVENT = 0x3E 212HCI_NUMBER_OF_COMPLETED_DATA_BLOCKS_EVENT = 0x48 213HCI_TRIGGERED_CLOCK_CAPTURE_EVENT = 0X4E 214HCI_SYNCHRONIZATION_TRAIN_COMPLETE_EVENT = 0X4F 215HCI_SYNCHRONIZATION_TRAIN_RECEIVED_EVENT = 0X50 216HCI_CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVE_EVENT = 0X51 217HCI_CONNECTIONLESS_PERIPHERAL_BROADCAST_TIMEOUT_EVENT = 0X52 218HCI_TRUNCATED_PAGE_COMPLETE_EVENT = 0X53 219HCI_PERIPHERAL_PAGE_RESPONSE_TIMEOUT_EVENT = 0X54 220HCI_CONNECTIONLESS_PERIPHERAL_BROADCAST_CHANNEL_MAP_CHANGE_EVENT = 0X55 221HCI_INQUIRY_RESPONSE_NOTIFICATION_EVENT = 0X56 222HCI_AUTHENTICATED_PAYLOAD_TIMEOUT_EXPIRED_EVENT = 0X57 223HCI_SAM_STATUS_CHANGE_EVENT = 0X58 224 225HCI_VENDOR_EVENT = 0xFF 226 227 228# HCI Subevent Codes 229HCI_LE_CONNECTION_COMPLETE_EVENT = 0x01 230HCI_LE_ADVERTISING_REPORT_EVENT = 0x02 231HCI_LE_CONNECTION_UPDATE_COMPLETE_EVENT = 0x03 232HCI_LE_READ_REMOTE_FEATURES_COMPLETE_EVENT = 0x04 233HCI_LE_LONG_TERM_KEY_REQUEST_EVENT = 0x05 234HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_EVENT = 0x06 235HCI_LE_DATA_LENGTH_CHANGE_EVENT = 0x07 236HCI_LE_READ_LOCAL_P_256_PUBLIC_KEY_COMPLETE_EVENT = 0x08 237HCI_LE_GENERATE_DHKEY_COMPLETE_EVENT = 0x09 238HCI_LE_ENHANCED_CONNECTION_COMPLETE_EVENT = 0x0A 239HCI_LE_DIRECTED_ADVERTISING_REPORT_EVENT = 0x0B 240HCI_LE_PHY_UPDATE_COMPLETE_EVENT = 0x0C 241HCI_LE_EXTENDED_ADVERTISING_REPORT_EVENT = 0x0D 242HCI_LE_PERIODIC_ADVERTISING_SYNC_ESTABLISHED_EVENT = 0x0E 243HCI_LE_PERIODIC_ADVERTISING_REPORT_EVENT = 0x0F 244HCI_LE_PERIODIC_ADVERTISING_SYNC_LOST_EVENT = 0x10 245HCI_LE_SCAN_TIMEOUT_EVENT = 0x11 246HCI_LE_ADVERTISING_SET_TERMINATED_EVENT = 0x12 247HCI_LE_SCAN_REQUEST_RECEIVED_EVENT = 0x13 248HCI_LE_CHANNEL_SELECTION_ALGORITHM_EVENT = 0x14 249HCI_LE_CONNECTIONLESS_IQ_REPORT_EVENT = 0X15 250HCI_LE_CONNECTION_IQ_REPORT_EVENT = 0X16 251HCI_LE_CTE_REQUEST_FAILED_EVENT = 0X17 252HCI_LE_PERIODIC_ADVERTISING_SYNC_TRANSFER_RECEIVED_EVENT = 0X18 253HCI_LE_CIS_ESTABLISHED_EVENT = 0X19 254HCI_LE_CIS_REQUEST_EVENT = 0X1A 255HCI_LE_CREATE_BIG_COMPLETE_EVENT = 0X1B 256HCI_LE_TERMINATE_BIG_COMPLETE_EVENT = 0X1C 257HCI_LE_BIG_SYNC_ESTABLISHED_EVENT = 0X1D 258HCI_LE_BIG_SYNC_LOST_EVENT = 0X1E 259HCI_LE_REQUEST_PEER_SCA_COMPLETE_EVENT = 0X1F 260HCI_LE_PATH_LOSS_THRESHOLD_EVENT = 0X20 261HCI_LE_TRANSMIT_POWER_REPORTING_EVENT = 0X21 262HCI_LE_BIGINFO_ADVERTISING_REPORT_EVENT = 0X22 263HCI_LE_SUBRATE_CHANGE_EVENT = 0X23 264HCI_LE_PERIODIC_ADVERTISING_SYNC_ESTABLISHED_V2_EVENT = 0X24 265HCI_LE_PERIODIC_ADVERTISING_REPORT_V2_EVENT = 0X25 266HCI_LE_PERIODIC_ADVERTISING_SYNC_TRANSFER_RECEIVED_V2_EVENT = 0X26 267HCI_LE_PERIODIC_ADVERTISING_SUBEVENT_DATA_REQUEST_EVENT = 0X27 268HCI_LE_PERIODIC_ADVERTISING_RESPONSE_REPORT_EVENT = 0X28 269HCI_LE_ENHANCED_CONNECTION_COMPLETE_V2_EVENT = 0X29 270HCI_LE_READ_ALL_REMOTE_FEATURES_COMPLETE_EVENT = 0x2A 271HCI_LE_CIS_ESTABLISHED_V2_EVENT = 0x2B 272HCI_LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES_COMPLETE_EVENT = 0x2C 273HCI_LE_CS_READ_REMOTE_FAE_TABLE_COMPLETE_EVENT = 0x2D 274HCI_LE_CS_SECURITY_ENABLE_COMPLETE_EVENT = 0x2E 275HCI_LE_CS_CONFIG_COMPLETE_EVENT = 0x2F 276HCI_LE_CS_PROCEDURE_ENABLE_EVENT = 0x30 277HCI_LE_CS_SUBEVENT_RESULT_EVENT = 0x31 278HCI_LE_CS_SUBEVENT_RESULT_CONTINUE_EVENT = 0x32 279HCI_LE_CS_TEST_END_COMPLETE_EVENT = 0x33 280HCI_LE_MONITORED_ADVERTISERS_REPORT_EVENT = 0x34 281HCI_LE_FRAME_SPACE_UPDATE_EVENT = 0x35 282 283 284 285# HCI Command 286HCI_INQUIRY_COMMAND = hci_command_op_code(0x01, 0x0001) 287HCI_INQUIRY_CANCEL_COMMAND = hci_command_op_code(0x01, 0x0002) 288HCI_PERIODIC_INQUIRY_MODE_COMMAND = hci_command_op_code(0x01, 0x0003) 289HCI_EXIT_PERIODIC_INQUIRY_MODE_COMMAND = hci_command_op_code(0x01, 0x0004) 290HCI_CREATE_CONNECTION_COMMAND = hci_command_op_code(0x01, 0x0005) 291HCI_DISCONNECT_COMMAND = hci_command_op_code(0x01, 0x0006) 292HCI_CREATE_CONNECTION_CANCEL_COMMAND = hci_command_op_code(0x01, 0x0008) 293HCI_ACCEPT_CONNECTION_REQUEST_COMMAND = hci_command_op_code(0x01, 0x0009) 294HCI_REJECT_CONNECTION_REQUEST_COMMAND = hci_command_op_code(0x01, 0x000A) 295HCI_LINK_KEY_REQUEST_REPLY_COMMAND = hci_command_op_code(0x01, 0x000B) 296HCI_LINK_KEY_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x01, 0x000C) 297HCI_PIN_CODE_REQUEST_REPLY_COMMAND = hci_command_op_code(0x01, 0x000D) 298HCI_PIN_CODE_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x01, 0x000E) 299HCI_CHANGE_CONNECTION_PACKET_TYPE_COMMAND = hci_command_op_code(0x01, 0x000F) 300HCI_AUTHENTICATION_REQUESTED_COMMAND = hci_command_op_code(0x01, 0x0011) 301HCI_SET_CONNECTION_ENCRYPTION_COMMAND = hci_command_op_code(0x01, 0x0013) 302HCI_CHANGE_CONNECTION_LINK_KEY_COMMAND = hci_command_op_code(0x01, 0x0015) 303HCI_LINK_KEY_SELECTION_COMMAND = hci_command_op_code(0x01, 0x0017) 304HCI_REMOTE_NAME_REQUEST_COMMAND = hci_command_op_code(0x01, 0x0019) 305HCI_REMOTE_NAME_REQUEST_CANCEL_COMMAND = hci_command_op_code(0x01, 0x001A) 306HCI_READ_REMOTE_SUPPORTED_FEATURES_COMMAND = hci_command_op_code(0x01, 0x001B) 307HCI_READ_REMOTE_EXTENDED_FEATURES_COMMAND = hci_command_op_code(0x01, 0x001C) 308HCI_READ_REMOTE_VERSION_INFORMATION_COMMAND = hci_command_op_code(0x01, 0x001D) 309HCI_READ_CLOCK_OFFSET_COMMAND = hci_command_op_code(0x01, 0x001F) 310HCI_READ_LMP_HANDLE_COMMAND = hci_command_op_code(0x01, 0x0020) 311HCI_SETUP_SYNCHRONOUS_CONNECTION_COMMAND = hci_command_op_code(0x01, 0x0028) 312HCI_ACCEPT_SYNCHRONOUS_CONNECTION_REQUEST_COMMAND = hci_command_op_code(0x01, 0x0029) 313HCI_REJECT_SYNCHRONOUS_CONNECTION_REQUEST_COMMAND = hci_command_op_code(0x01, 0x002A) 314HCI_IO_CAPABILITY_REQUEST_REPLY_COMMAND = hci_command_op_code(0x01, 0x002B) 315HCI_USER_CONFIRMATION_REQUEST_REPLY_COMMAND = hci_command_op_code(0x01, 0x002C) 316HCI_USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x01, 0x002D) 317HCI_USER_PASSKEY_REQUEST_REPLY_COMMAND = hci_command_op_code(0x01, 0x002E) 318HCI_USER_PASSKEY_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x01, 0x002F) 319HCI_REMOTE_OOB_DATA_REQUEST_REPLY_COMMAND = hci_command_op_code(0x01, 0x0030) 320HCI_REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x01, 0x0033) 321HCI_IO_CAPABILITY_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x01, 0x0034) 322HCI_ENHANCED_SETUP_SYNCHRONOUS_CONNECTION_COMMAND = hci_command_op_code(0x01, 0x003D) 323HCI_ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION_REQUEST_COMMAND = hci_command_op_code(0x01, 0x003E) 324HCI_TRUNCATED_PAGE_COMMAND = hci_command_op_code(0x01, 0x003F) 325HCI_TRUNCATED_PAGE_CANCEL_COMMAND = hci_command_op_code(0x01, 0x0040) 326HCI_SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_COMMAND = hci_command_op_code(0x01, 0x0041) 327HCI_SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVE_COMMAND = hci_command_op_code(0x01, 0x0042) 328HCI_START_SYNCHRONIZATION_TRAIN_COMMAND = hci_command_op_code(0x01, 0x0043) 329HCI_RECEIVE_SYNCHRONIZATION_TRAIN_COMMAND = hci_command_op_code(0x01, 0x0044) 330HCI_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_COMMAND = hci_command_op_code(0x01, 0x0045) 331HCI_HOLD_MODE_COMMAND = hci_command_op_code(0x02, 0x0001) 332HCI_SNIFF_MODE_COMMAND = hci_command_op_code(0x02, 0x0003) 333HCI_EXIT_SNIFF_MODE_COMMAND = hci_command_op_code(0x02, 0x0004) 334HCI_QOS_SETUP_COMMAND = hci_command_op_code(0x02, 0x0007) 335HCI_ROLE_DISCOVERY_COMMAND = hci_command_op_code(0x02, 0x0009) 336HCI_SWITCH_ROLE_COMMAND = hci_command_op_code(0x02, 0x000B) 337HCI_READ_LINK_POLICY_SETTINGS_COMMAND = hci_command_op_code(0x02, 0x000C) 338HCI_WRITE_LINK_POLICY_SETTINGS_COMMAND = hci_command_op_code(0x02, 0x000D) 339HCI_READ_DEFAULT_LINK_POLICY_SETTINGS_COMMAND = hci_command_op_code(0x02, 0x000E) 340HCI_WRITE_DEFAULT_LINK_POLICY_SETTINGS_COMMAND = hci_command_op_code(0x02, 0x000F) 341HCI_FLOW_SPECIFICATION_COMMAND = hci_command_op_code(0x02, 0x0010) 342HCI_SNIFF_SUBRATING_COMMAND = hci_command_op_code(0x02, 0x0011) 343HCI_SET_EVENT_MASK_COMMAND = hci_command_op_code(0x03, 0x0001) 344HCI_RESET_COMMAND = hci_command_op_code(0x03, 0x0003) 345HCI_SET_EVENT_FILTER_COMMAND = hci_command_op_code(0x03, 0x0005) 346HCI_FLUSH_COMMAND = hci_command_op_code(0x03, 0x0008) 347HCI_READ_PIN_TYPE_COMMAND = hci_command_op_code(0x03, 0x0009) 348HCI_WRITE_PIN_TYPE_COMMAND = hci_command_op_code(0x03, 0x000A) 349HCI_READ_STORED_LINK_KEY_COMMAND = hci_command_op_code(0x03, 0x000D) 350HCI_WRITE_STORED_LINK_KEY_COMMAND = hci_command_op_code(0x03, 0x0011) 351HCI_DELETE_STORED_LINK_KEY_COMMAND = hci_command_op_code(0x03, 0x0012) 352HCI_WRITE_LOCAL_NAME_COMMAND = hci_command_op_code(0x03, 0x0013) 353HCI_READ_LOCAL_NAME_COMMAND = hci_command_op_code(0x03, 0x0014) 354HCI_READ_CONNECTION_ACCEPT_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x0015) 355HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x0016) 356HCI_READ_PAGE_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x0017) 357HCI_WRITE_PAGE_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x0018) 358HCI_READ_SCAN_ENABLE_COMMAND = hci_command_op_code(0x03, 0x0019) 359HCI_WRITE_SCAN_ENABLE_COMMAND = hci_command_op_code(0x03, 0x001A) 360HCI_READ_PAGE_SCAN_ACTIVITY_COMMAND = hci_command_op_code(0x03, 0x001B) 361HCI_WRITE_PAGE_SCAN_ACTIVITY_COMMAND = hci_command_op_code(0x03, 0x001C) 362HCI_READ_INQUIRY_SCAN_ACTIVITY_COMMAND = hci_command_op_code(0x03, 0x001D) 363HCI_WRITE_INQUIRY_SCAN_ACTIVITY_COMMAND = hci_command_op_code(0x03, 0x001E) 364HCI_READ_AUTHENTICATION_ENABLE_COMMAND = hci_command_op_code(0x03, 0x001F) 365HCI_WRITE_AUTHENTICATION_ENABLE_COMMAND = hci_command_op_code(0x03, 0x0020) 366HCI_READ_CLASS_OF_DEVICE_COMMAND = hci_command_op_code(0x03, 0x0023) 367HCI_WRITE_CLASS_OF_DEVICE_COMMAND = hci_command_op_code(0x03, 0x0024) 368HCI_READ_VOICE_SETTING_COMMAND = hci_command_op_code(0x03, 0x0025) 369HCI_WRITE_VOICE_SETTING_COMMAND = hci_command_op_code(0x03, 0x0026) 370HCI_READ_AUTOMATIC_FLUSH_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x0027) 371HCI_WRITE_AUTOMATIC_FLUSH_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x0028) 372HCI_READ_NUM_BROADCAST_RETRANSMISSIONS_COMMAND = hci_command_op_code(0x03, 0x0029) 373HCI_WRITE_NUM_BROADCAST_RETRANSMISSIONS_COMMAND = hci_command_op_code(0x03, 0x002A) 374HCI_READ_HOLD_MODE_ACTIVITY_COMMAND = hci_command_op_code(0x03, 0x002B) 375HCI_WRITE_HOLD_MODE_ACTIVITY_COMMAND = hci_command_op_code(0x03, 0x002C) 376HCI_READ_TRANSMIT_POWER_LEVEL_COMMAND = hci_command_op_code(0x03, 0x002D) 377HCI_READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE_COMMAND = hci_command_op_code(0x03, 0x002E) 378HCI_WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE_COMMAND = hci_command_op_code(0x03, 0x002F) 379HCI_SET_CONTROLLER_TO_HOST_FLOW_CONTROL_COMMAND = hci_command_op_code(0x03, 0x0031) 380HCI_HOST_BUFFER_SIZE_COMMAND = hci_command_op_code(0x03, 0x0033) 381HCI_HOST_NUMBER_OF_COMPLETED_PACKETS_COMMAND = hci_command_op_code(0x03, 0x0035) 382HCI_READ_LINK_SUPERVISION_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x0036) 383HCI_WRITE_LINK_SUPERVISION_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x0037) 384HCI_READ_NUMBER_OF_SUPPORTED_IAC_COMMAND = hci_command_op_code(0x03, 0x0038) 385HCI_READ_CURRENT_IAC_LAP_COMMAND = hci_command_op_code(0x03, 0x0039) 386HCI_WRITE_CURRENT_IAC_LAP_COMMAND = hci_command_op_code(0x03, 0x003A) 387HCI_SET_AFH_HOST_CHANNEL_CLASSIFICATION_COMMAND = hci_command_op_code(0x03, 0x003F) 388HCI_READ_INQUIRY_SCAN_TYPE_COMMAND = hci_command_op_code(0x03, 0x0042) 389HCI_WRITE_INQUIRY_SCAN_TYPE_COMMAND = hci_command_op_code(0x03, 0x0043) 390HCI_READ_INQUIRY_MODE_COMMAND = hci_command_op_code(0x03, 0x0044) 391HCI_WRITE_INQUIRY_MODE_COMMAND = hci_command_op_code(0x03, 0x0045) 392HCI_READ_PAGE_SCAN_TYPE_COMMAND = hci_command_op_code(0x03, 0x0046) 393HCI_WRITE_PAGE_SCAN_TYPE_COMMAND = hci_command_op_code(0x03, 0x0047) 394HCI_READ_AFH_CHANNEL_ASSESSMENT_MODE_COMMAND = hci_command_op_code(0x03, 0x0048) 395HCI_WRITE_AFH_CHANNEL_ASSESSMENT_MODE_COMMAND = hci_command_op_code(0x03, 0x0049) 396HCI_READ_EXTENDED_INQUIRY_RESPONSE_COMMAND = hci_command_op_code(0x03, 0x0051) 397HCI_WRITE_EXTENDED_INQUIRY_RESPONSE_COMMAND = hci_command_op_code(0x03, 0x0052) 398HCI_REFRESH_ENCRYPTION_KEY_COMMAND = hci_command_op_code(0x03, 0x0053) 399HCI_READ_SIMPLE_PAIRING_MODE_COMMAND = hci_command_op_code(0x03, 0x0055) 400HCI_WRITE_SIMPLE_PAIRING_MODE_COMMAND = hci_command_op_code(0x03, 0x0056) 401HCI_READ_LOCAL_OOB_DATA_COMMAND = hci_command_op_code(0x03, 0x0057) 402HCI_READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL_COMMAND = hci_command_op_code(0x03, 0x0058) 403HCI_WRITE_INQUIRY_TRANSMIT_POWER_LEVEL_COMMAND = hci_command_op_code(0x03, 0x0059) 404HCI_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_COMMAND = hci_command_op_code(0x03, 0x005A) 405HCI_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_COMMAND = hci_command_op_code(0x03, 0x005B) 406HCI_ENHANCED_FLUSH_COMMAND = hci_command_op_code(0x03, 0x005F) 407HCI_SEND_KEYPRESS_NOTIFICATION_COMMAND = hci_command_op_code(0x03, 0x0060) 408HCI_SET_EVENT_MASK_PAGE_2_COMMAND = hci_command_op_code(0x03, 0x0063) 409HCI_READ_FLOW_CONTROL_MODE_COMMAND = hci_command_op_code(0x03, 0x0066) 410HCI_WRITE_FLOW_CONTROL_MODE_COMMAND = hci_command_op_code(0x03, 0x0067) 411HCI_READ_ENHANCED_TRANSMIT_POWER_LEVEL_COMMAND = hci_command_op_code(0x03, 0x0068) 412HCI_READ_LE_HOST_SUPPORT_COMMAND = hci_command_op_code(0x03, 0x006C) 413HCI_WRITE_LE_HOST_SUPPORT_COMMAND = hci_command_op_code(0x03, 0x006D) 414HCI_SET_MWS_CHANNEL_PARAMETERS_COMMAND = hci_command_op_code(0x03, 0x006E) 415HCI_SET_EXTERNAL_FRAME_CONFIGURATION_COMMAND = hci_command_op_code(0x03, 0x006F) 416HCI_SET_MWS_SIGNALING_COMMAND = hci_command_op_code(0x03, 0x0070) 417HCI_SET_MWS_TRANSPORT_LAYER_COMMAND = hci_command_op_code(0x03, 0x0071) 418HCI_SET_MWS_SCAN_FREQUENCY_TABLE_COMMAND = hci_command_op_code(0x03, 0x0072) 419HCI_SET_MWS_PATTERN_CONFIGURATION_COMMAND = hci_command_op_code(0x03, 0x0073) 420HCI_SET_RESERVED_LT_ADDR_COMMAND = hci_command_op_code(0x03, 0x0074) 421HCI_DELETE_RESERVED_LT_ADDR_COMMAND = hci_command_op_code(0x03, 0x0075) 422HCI_SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_DATA_COMMAND = hci_command_op_code(0x03, 0x0076) 423HCI_READ_SYNCHRONIZATION_TRAIN_PARAMETERS_COMMAND = hci_command_op_code(0x03, 0x0077) 424HCI_WRITE_SYNCHRONIZATION_TRAIN_PARAMETERS_COMMAND = hci_command_op_code(0x03, 0x0078) 425HCI_READ_SECURE_CONNECTIONS_HOST_SUPPORT_COMMAND = hci_command_op_code(0x03, 0x0079) 426HCI_WRITE_SECURE_CONNECTIONS_HOST_SUPPORT_COMMAND = hci_command_op_code(0x03, 0x007A) 427HCI_READ_AUTHENTICATED_PAYLOAD_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x007B) 428HCI_WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x007C) 429HCI_READ_LOCAL_OOB_EXTENDED_DATA_COMMAND = hci_command_op_code(0x03, 0x007D) 430HCI_READ_EXTENDED_PAGE_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x007E) 431HCI_WRITE_EXTENDED_PAGE_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x007F) 432HCI_READ_EXTENDED_INQUIRY_LENGTH_COMMAND = hci_command_op_code(0x03, 0x0080) 433HCI_WRITE_EXTENDED_INQUIRY_LENGTH_COMMAND = hci_command_op_code(0x03, 0x0081) 434HCI_SET_ECOSYSTEM_BASE_INTERVAL_COMMAND = hci_command_op_code(0x03, 0x0082) 435HCI_CONFIGURE_DATA_PATH_COMMAND = hci_command_op_code(0x03, 0x0083) 436HCI_SET_MIN_ENCRYPTION_KEY_SIZE_COMMAND = hci_command_op_code(0x03, 0x0084) 437HCI_READ_LOCAL_VERSION_INFORMATION_COMMAND = hci_command_op_code(0x04, 0x0001) 438HCI_READ_LOCAL_SUPPORTED_COMMANDS_COMMAND = hci_command_op_code(0x04, 0x0002) 439HCI_READ_LOCAL_SUPPORTED_FEATURES_COMMAND = hci_command_op_code(0x04, 0x0003) 440HCI_READ_LOCAL_EXTENDED_FEATURES_COMMAND = hci_command_op_code(0x04, 0x0004) 441HCI_READ_BUFFER_SIZE_COMMAND = hci_command_op_code(0x04, 0x0005) 442HCI_READ_BD_ADDR_COMMAND = hci_command_op_code(0x04, 0x0009) 443HCI_READ_DATA_BLOCK_SIZE_COMMAND = hci_command_op_code(0x04, 0x000A) 444HCI_READ_LOCAL_SUPPORTED_CODECS_COMMAND = hci_command_op_code(0x04, 0x000B) 445HCI_READ_LOCAL_SIMPLE_PAIRING_OPTIONS_COMMAND = hci_command_op_code(0x04, 0x000C) 446HCI_READ_LOCAL_SUPPORTED_CODECS_V2_COMMAND = hci_command_op_code(0x04, 0x000D) 447HCI_READ_LOCAL_SUPPORTED_CODEC_CAPABILITIES_COMMAND = hci_command_op_code(0x04, 0x000E) 448HCI_READ_LOCAL_SUPPORTED_CONTROLLER_DELAY_COMMAND = hci_command_op_code(0x04, 0x000F) 449HCI_READ_FAILED_CONTACT_COUNTER_COMMAND = hci_command_op_code(0x05, 0x0001) 450HCI_RESET_FAILED_CONTACT_COUNTER_COMMAND = hci_command_op_code(0x05, 0x0002) 451HCI_READ_LINK_QUALITY_COMMAND = hci_command_op_code(0x05, 0x0003) 452HCI_READ_RSSI_COMMAND = hci_command_op_code(0x05, 0x0005) 453HCI_READ_AFH_CHANNEL_MAP_COMMAND = hci_command_op_code(0x05, 0x0006) 454HCI_READ_CLOCK_COMMAND = hci_command_op_code(0x05, 0x0007) 455HCI_READ_ENCRYPTION_KEY_SIZE_COMMAND = hci_command_op_code(0x05, 0x0008) 456HCI_GET_MWS_TRANSPORT_LAYER_CONFIGURATION_COMMAND = hci_command_op_code(0x05, 0x000C) 457HCI_SET_TRIGGERED_CLOCK_CAPTURE_COMMAND = hci_command_op_code(0x05, 0x000D) 458HCI_READ_LOOPBACK_MODE_COMMAND = hci_command_op_code(0x06, 0x0001) 459HCI_WRITE_LOOPBACK_MODE_COMMAND = hci_command_op_code(0x06, 0x0002) 460HCI_ENABLE_DEVICE_UNDER_TEST_MODE_COMMAND = hci_command_op_code(0x06, 0x0003) 461HCI_WRITE_SIMPLE_PAIRING_DEBUG_MODE_COMMAND = hci_command_op_code(0x06, 0x0004) 462HCI_WRITE_SECURE_CONNECTIONS_TEST_MODE_COMMAND = hci_command_op_code(0x06, 0x000A) 463HCI_LE_SET_EVENT_MASK_COMMAND = hci_command_op_code(0x08, 0x0001) 464HCI_LE_READ_BUFFER_SIZE_COMMAND = hci_command_op_code(0x08, 0x0002) 465HCI_LE_READ_LOCAL_SUPPORTED_FEATURES_COMMAND = hci_command_op_code(0x08, 0x0003) 466HCI_LE_SET_RANDOM_ADDRESS_COMMAND = hci_command_op_code(0x08, 0x0005) 467HCI_LE_SET_ADVERTISING_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0006) 468HCI_LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER_COMMAND = hci_command_op_code(0x08, 0x0007) 469HCI_LE_SET_ADVERTISING_DATA_COMMAND = hci_command_op_code(0x08, 0x0008) 470HCI_LE_SET_SCAN_RESPONSE_DATA_COMMAND = hci_command_op_code(0x08, 0x0009) 471HCI_LE_SET_ADVERTISING_ENABLE_COMMAND = hci_command_op_code(0x08, 0x000A) 472HCI_LE_SET_SCAN_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x000B) 473HCI_LE_SET_SCAN_ENABLE_COMMAND = hci_command_op_code(0x08, 0x000C) 474HCI_LE_CREATE_CONNECTION_COMMAND = hci_command_op_code(0x08, 0x000D) 475HCI_LE_CREATE_CONNECTION_CANCEL_COMMAND = hci_command_op_code(0x08, 0x000E) 476HCI_LE_READ_FILTER_ACCEPT_LIST_SIZE_COMMAND = hci_command_op_code(0x08, 0x000F) 477HCI_LE_CLEAR_FILTER_ACCEPT_LIST_COMMAND = hci_command_op_code(0x08, 0x0010) 478HCI_LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST_COMMAND = hci_command_op_code(0x08, 0x0011) 479HCI_LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST_COMMAND = hci_command_op_code(0x08, 0x0012) 480HCI_LE_CONNECTION_UPDATE_COMMAND = hci_command_op_code(0x08, 0x0013) 481HCI_LE_SET_HOST_CHANNEL_CLASSIFICATION_COMMAND = hci_command_op_code(0x08, 0x0014) 482HCI_LE_READ_CHANNEL_MAP_COMMAND = hci_command_op_code(0x08, 0x0015) 483HCI_LE_READ_REMOTE_FEATURES_COMMAND = hci_command_op_code(0x08, 0x0016) 484HCI_LE_ENCRYPT_COMMAND = hci_command_op_code(0x08, 0x0017) 485HCI_LE_RAND_COMMAND = hci_command_op_code(0x08, 0x0018) 486HCI_LE_ENABLE_ENCRYPTION_COMMAND = hci_command_op_code(0x08, 0x0019) 487HCI_LE_LONG_TERM_KEY_REQUEST_REPLY_COMMAND = hci_command_op_code(0x08, 0x001A) 488HCI_LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x08, 0x001B) 489HCI_LE_READ_SUPPORTED_STATES_COMMAND = hci_command_op_code(0x08, 0x001C) 490HCI_LE_RECEIVER_TEST_COMMAND = hci_command_op_code(0x08, 0x001D) 491HCI_LE_TRANSMITTER_TEST_COMMAND = hci_command_op_code(0x08, 0x001E) 492HCI_LE_TEST_END_COMMAND = hci_command_op_code(0x08, 0x001F) 493HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY_COMMAND = hci_command_op_code(0x08, 0x0020) 494HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x08, 0x0021) 495HCI_LE_SET_DATA_LENGTH_COMMAND = hci_command_op_code(0x08, 0x0022) 496HCI_LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH_COMMAND = hci_command_op_code(0x08, 0x0023) 497HCI_LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH_COMMAND = hci_command_op_code(0x08, 0x0024) 498HCI_LE_READ_LOCAL_P_256_PUBLIC_KEY_COMMAND = hci_command_op_code(0x08, 0x0025) 499HCI_LE_GENERATE_DHKEY_COMMAND = hci_command_op_code(0x08, 0x0026) 500HCI_LE_ADD_DEVICE_TO_RESOLVING_LIST_COMMAND = hci_command_op_code(0x08, 0x0027) 501HCI_LE_REMOVE_DEVICE_FROM_RESOLVING_LIST_COMMAND = hci_command_op_code(0x08, 0x0028) 502HCI_LE_CLEAR_RESOLVING_LIST_COMMAND = hci_command_op_code(0x08, 0x0029) 503HCI_LE_READ_RESOLVING_LIST_SIZE_COMMAND = hci_command_op_code(0x08, 0x002A) 504HCI_LE_READ_PEER_RESOLVABLE_ADDRESS_COMMAND = hci_command_op_code(0x08, 0x002B) 505HCI_LE_READ_LOCAL_RESOLVABLE_ADDRESS_COMMAND = hci_command_op_code(0x08, 0x002C) 506HCI_LE_SET_ADDRESS_RESOLUTION_ENABLE_COMMAND = hci_command_op_code(0x08, 0x002D) 507HCI_LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT_COMMAND = hci_command_op_code(0x08, 0x002E) 508HCI_LE_READ_MAXIMUM_DATA_LENGTH_COMMAND = hci_command_op_code(0x08, 0x002F) 509HCI_LE_READ_PHY_COMMAND = hci_command_op_code(0x08, 0x0030) 510HCI_LE_SET_DEFAULT_PHY_COMMAND = hci_command_op_code(0x08, 0x0031) 511HCI_LE_SET_PHY_COMMAND = hci_command_op_code(0x08, 0x0032) 512HCI_LE_RECEIVER_TEST_V2_COMMAND = hci_command_op_code(0x08, 0x0033) 513HCI_LE_TRANSMITTER_TEST_V2_COMMAND = hci_command_op_code(0x08, 0x0034) 514HCI_LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_COMMAND = hci_command_op_code(0x08, 0x0035) 515HCI_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0036) 516HCI_LE_SET_EXTENDED_ADVERTISING_DATA_COMMAND = hci_command_op_code(0x08, 0x0037) 517HCI_LE_SET_EXTENDED_SCAN_RESPONSE_DATA_COMMAND = hci_command_op_code(0x08, 0x0038) 518HCI_LE_SET_EXTENDED_ADVERTISING_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0039) 519HCI_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH_COMMAND = hci_command_op_code(0x08, 0x003A) 520HCI_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS_COMMAND = hci_command_op_code(0x08, 0x003B) 521HCI_LE_REMOVE_ADVERTISING_SET_COMMAND = hci_command_op_code(0x08, 0x003C) 522HCI_LE_CLEAR_ADVERTISING_SETS_COMMAND = hci_command_op_code(0x08, 0x003D) 523HCI_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x003E) 524HCI_LE_SET_PERIODIC_ADVERTISING_DATA_COMMAND = hci_command_op_code(0x08, 0x003F) 525HCI_LE_SET_PERIODIC_ADVERTISING_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0040) 526HCI_LE_SET_EXTENDED_SCAN_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0041) 527HCI_LE_SET_EXTENDED_SCAN_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0042) 528HCI_LE_EXTENDED_CREATE_CONNECTION_COMMAND = hci_command_op_code(0x08, 0x0043) 529HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC_COMMAND = hci_command_op_code(0x08, 0x0044) 530HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL_COMMAND = hci_command_op_code(0x08, 0x0045) 531HCI_LE_PERIODIC_ADVERTISING_TERMINATE_SYNC_COMMAND = hci_command_op_code(0x08, 0x0046) 532HCI_LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST_COMMAND = hci_command_op_code(0x08, 0x0047) 533HCI_LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST_COMMAND = hci_command_op_code(0x08, 0x0048) 534HCI_LE_CLEAR_PERIODIC_ADVERTISER_LIST_COMMAND = hci_command_op_code(0x08, 0x0049) 535HCI_LE_READ_PERIODIC_ADVERTISER_LIST_SIZE_COMMAND = hci_command_op_code(0x08, 0x004A) 536HCI_LE_READ_TRANSMIT_POWER_COMMAND = hci_command_op_code(0x08, 0x004B) 537HCI_LE_READ_RF_PATH_COMPENSATION_COMMAND = hci_command_op_code(0x08, 0x004C) 538HCI_LE_WRITE_RF_PATH_COMPENSATION_COMMAND = hci_command_op_code(0x08, 0x004D) 539HCI_LE_SET_PRIVACY_MODE_COMMAND = hci_command_op_code(0x08, 0x004E) 540HCI_LE_RECEIVER_TEST_V3_COMMAND = hci_command_op_code(0x08, 0x004F) 541HCI_LE_TRANSMITTER_TEST_V3_COMMAND = hci_command_op_code(0x08, 0x0050) 542HCI_LE_SET_CONNECTIONLESS_CTE_TRANSMIT_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0051) 543HCI_LE_SET_CONNECTIONLESS_CTE_TRANSMIT_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0052) 544HCI_LE_SET_CONNECTIONLESS_IQ_SAMPLING_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0053) 545HCI_LE_SET_CONNECTION_CTE_RECEIVE_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0054) 546HCI_LE_SET_CONNECTION_CTE_TRANSMIT_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0055) 547HCI_LE_CONNECTION_CTE_REQUEST_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0056) 548HCI_LE_CONNECTION_CTE_RESPONSE_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0057) 549HCI_LE_READ_ANTENNA_INFORMATION_COMMAND = hci_command_op_code(0x08, 0x0058) 550HCI_LE_SET_PERIODIC_ADVERTISING_RECEIVE_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0059) 551HCI_LE_PERIODIC_ADVERTISING_SYNC_TRANSFER_COMMAND = hci_command_op_code(0x08, 0x005A) 552HCI_LE_PERIODIC_ADVERTISING_SET_INFO_TRANSFER_COMMAND = hci_command_op_code(0x08, 0x005B) 553HCI_LE_SET_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x005C) 554HCI_LE_SET_DEFAULT_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x005D) 555HCI_LE_GENERATE_DHKEY_V2_COMMAND = hci_command_op_code(0x08, 0x005E) 556HCI_LE_MODIFY_SLEEP_CLOCK_ACCURACY_COMMAND = hci_command_op_code(0x08, 0x005F) 557HCI_LE_READ_BUFFER_SIZE_V2_COMMAND = hci_command_op_code(0x08, 0x0060) 558HCI_LE_READ_ISO_TX_SYNC_COMMAND = hci_command_op_code(0x08, 0x0061) 559HCI_LE_SET_CIG_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0062) 560HCI_LE_SET_CIG_PARAMETERS_TEST_COMMAND = hci_command_op_code(0x08, 0x0063) 561HCI_LE_CREATE_CIS_COMMAND = hci_command_op_code(0x08, 0x0064) 562HCI_LE_REMOVE_CIG_COMMAND = hci_command_op_code(0x08, 0x0065) 563HCI_LE_ACCEPT_CIS_REQUEST_COMMAND = hci_command_op_code(0x08, 0x0066) 564HCI_LE_REJECT_CIS_REQUEST_COMMAND = hci_command_op_code(0x08, 0x0067) 565HCI_LE_CREATE_BIG_COMMAND = hci_command_op_code(0x08, 0x0068) 566HCI_LE_CREATE_BIG_TEST_COMMAND = hci_command_op_code(0x08, 0x0069) 567HCI_LE_TERMINATE_BIG_COMMAND = hci_command_op_code(0x08, 0x006A) 568HCI_LE_BIG_CREATE_SYNC_COMMAND = hci_command_op_code(0x08, 0x006B) 569HCI_LE_BIG_TERMINATE_SYNC_COMMAND = hci_command_op_code(0x08, 0x006C) 570HCI_LE_REQUEST_PEER_SCA_COMMAND = hci_command_op_code(0x08, 0x006D) 571HCI_LE_SETUP_ISO_DATA_PATH_COMMAND = hci_command_op_code(0x08, 0x006E) 572HCI_LE_REMOVE_ISO_DATA_PATH_COMMAND = hci_command_op_code(0x08, 0x006F) 573HCI_LE_ISO_TRANSMIT_TEST_COMMAND = hci_command_op_code(0x08, 0x0070) 574HCI_LE_ISO_RECEIVE_TEST_COMMAND = hci_command_op_code(0x08, 0x0071) 575HCI_LE_ISO_READ_TEST_COUNTERS_COMMAND = hci_command_op_code(0x08, 0x0072) 576HCI_LE_ISO_TEST_END_COMMAND = hci_command_op_code(0x08, 0x0073) 577HCI_LE_SET_HOST_FEATURE_COMMAND = hci_command_op_code(0x08, 0x0074) 578HCI_LE_READ_ISO_LINK_QUALITY_COMMAND = hci_command_op_code(0x08, 0x0075) 579HCI_LE_ENHANCED_READ_TRANSMIT_POWER_LEVEL_COMMAND = hci_command_op_code(0x08, 0x0076) 580HCI_LE_READ_REMOTE_TRANSMIT_POWER_LEVEL_COMMAND = hci_command_op_code(0x08, 0x0077) 581HCI_LE_SET_PATH_LOSS_REPORTING_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0078) 582HCI_LE_SET_PATH_LOSS_REPORTING_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0079) 583HCI_LE_SET_TRANSMIT_POWER_REPORTING_ENABLE_COMMAND = hci_command_op_code(0x08, 0x007A) 584HCI_LE_TRANSMITTER_TEST_V4_COMMAND = hci_command_op_code(0x08, 0x007B) 585HCI_LE_SET_DATA_RELATED_ADDRESS_CHANGES_COMMAND = hci_command_op_code(0x08, 0x007C) 586HCI_LE_SET_DEFAULT_SUBRATE_COMMAND = hci_command_op_code(0x08, 0x007D) 587HCI_LE_SUBRATE_REQUEST_COMMAND = hci_command_op_code(0x08, 0x007E) 588HCI_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_V2_COMMAND = hci_command_op_code(0x08, 0x007F) 589HCI_LE_SET_DECISION_DATA_COMMAND = hci_command_op_code(0x08, 0x0080) 590HCI_LE_SET_DECISION_INSTRUCTIONS_COMMAND = hci_command_op_code(0x08, 0x0081) 591HCI_LE_SET_PERIODIC_ADVERTISING_SUBEVENT_DATA_COMMAND = hci_command_op_code(0x08, 0x0082) 592HCI_LE_SET_PERIODIC_ADVERTISING_RESPONSE_DATA_COMMAND = hci_command_op_code(0x08, 0x0083) 593HCI_LE_SET_PERIODIC_SYNC_SUBEVENT_COMMAND = hci_command_op_code(0x08, 0x0084) 594HCI_LE_EXTENDED_CREATE_CONNECTION_V2_COMMAND = hci_command_op_code(0x08, 0x0085) 595HCI_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_V2_COMMAND = hci_command_op_code(0x08, 0x0086) 596HCI_LE_READ_ALL_LOCAL_SUPPORTED_FEATURES_COMMAND = hci_command_op_code(0x08, 0x0087) 597HCI_LE_READ_ALL_REMOTE_FEATURES_COMMAND = hci_command_op_code(0x08, 0x0088) 598HCI_LE_CS_READ_LOCAL_SUPPORTED_CAPABILITIES_COMMAND = hci_command_op_code(0x08, 0x0089) 599HCI_LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES_COMMAND = hci_command_op_code(0x08, 0x008A) 600HCI_LE_CS_WRITE_CACHED_REMOTE_SUPPORTED_CAPABILITIES = hci_command_op_code(0x08, 0x008B) 601HCI_LE_CS_SECURITY_ENABLE_COMMAND = hci_command_op_code(0x08, 0x008C) 602HCI_LE_CS_SET_DEFAULT_SETTINGS_COMMAND = hci_command_op_code(0x08, 0x008D) 603HCI_LE_CS_READ_REMOTE_FAE_TABLE_COMMAND = hci_command_op_code(0x08, 0x008E) 604HCI_LE_CS_WRITE_CACHED_REMOTE_FAE_TABLE_COMMAND = hci_command_op_code(0x08, 0x008F) 605HCI_LE_CS_CREATE_CONFIG_COMMAND = hci_command_op_code(0x08, 0x0090) 606HCI_LE_CS_REMOVE_CONFIG_COMMAND = hci_command_op_code(0x08, 0x0091) 607HCI_LE_CS_SET_CHANNEL_CLASSIFICATION_COMMAND = hci_command_op_code(0x08, 0x0092) 608HCI_LE_CS_SET_PROCEDURE_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0093) 609HCI_LE_CS_PROCEDURE_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0094) 610HCI_LE_CS_TEST_COMMAND = hci_command_op_code(0x08, 0x0095) 611HCI_LE_CS_TEST_END_COMMAND = hci_command_op_code(0x08, 0x0096) 612HCI_LE_SET_HOST_FEATURE_V2_COMMAND = hci_command_op_code(0x08, 0x0097) 613HCI_LE_ADD_DEVICE_TO_MONITORED_ADVERTISERS_LIST_COMMAND = hci_command_op_code(0x08, 0x0098) 614HCI_LE_REMOVE_DEVICE_FROM_MONITORED_ADVERTISERS_LIST_COMMAND = hci_command_op_code(0x08, 0x0099) 615HCI_LE_CLEAR_MONITORED_ADVERTISERS_LIST_COMMAND = hci_command_op_code(0x08, 0x009A) 616HCI_LE_READ_MONITORED_ADVERTISERS_LIST_SIZE_COMMAND = hci_command_op_code(0x08, 0x009B) 617HCI_LE_ENABLE_MONITORING_ADVERTISERS_COMMAND = hci_command_op_code(0x08, 0x009C) 618HCI_LE_FRAME_SPACE_UPDATE_COMMAND = hci_command_op_code(0x08, 0x009D) 619 620 621# HCI Error Codes 622# See Bluetooth spec Vol 2, Part D - 1.3 LIST OF ERROR CODES 623HCI_SUCCESS = 0x00 624HCI_UNKNOWN_HCI_COMMAND_ERROR = 0x01 625HCI_UNKNOWN_CONNECTION_IDENTIFIER_ERROR = 0x02 626HCI_HARDWARE_FAILURE_ERROR = 0x03 627HCI_PAGE_TIMEOUT_ERROR = 0x04 628HCI_AUTHENTICATION_FAILURE_ERROR = 0x05 629HCI_PIN_OR_KEY_MISSING_ERROR = 0x06 630HCI_MEMORY_CAPACITY_EXCEEDED_ERROR = 0x07 631HCI_CONNECTION_TIMEOUT_ERROR = 0x08 632HCI_CONNECTION_LIMIT_EXCEEDED_ERROR = 0x09 633HCI_SYNCHRONOUS_CONNECTION_LIMIT_TO_A_DEVICE_EXCEEDED_ERROR = 0x0A 634HCI_CONNECTION_ALREADY_EXISTS_ERROR = 0x0B 635HCI_COMMAND_DISALLOWED_ERROR = 0x0C 636HCI_CONNECTION_REJECTED_DUE_TO_LIMITED_RESOURCES_ERROR = 0x0D 637HCI_CONNECTION_REJECTED_DUE_TO_SECURITY_REASONS_ERROR = 0x0E 638HCI_CONNECTION_REJECTED_DUE_TO_UNACCEPTABLE_BD_ADDR_ERROR = 0x0F 639HCI_CONNECTION_ACCEPT_TIMEOUT_ERROR = 0x10 640HCI_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE_ERROR = 0x11 641HCI_INVALID_HCI_COMMAND_PARAMETERS_ERROR = 0x12 642HCI_REMOTE_USER_TERMINATED_CONNECTION_ERROR = 0x13 643HCI_REMOTE_DEVICE_TERMINATED_CONNECTION_DUE_TO_LOW_RESOURCES_ERROR = 0x14 644HCI_REMOTE_DEVICE_TERMINATED_CONNECTION_DUE_TO_POWER_OFF_ERROR = 0x15 645HCI_CONNECTION_TERMINATED_BY_LOCAL_HOST_ERROR = 0x16 646HCI_REPEATED_ATTEMPTS_ERROR = 0X17 647HCI_PAIRING_NOT_ALLOWED_ERROR = 0X18 648HCI_UNKNOWN_LMP_PDU_ERROR = 0X19 649HCI_UNSUPPORTED_REMOTE_FEATURE_ERROR = 0X1A 650HCI_SCO_OFFSET_REJECTED_ERROR = 0X1B 651HCI_SCO_INTERVAL_REJECTED_ERROR = 0X1C 652HCI_SCO_AIR_MODE_REJECTED_ERROR = 0X1D 653HCI_INVALID_LMP_OR_LL_PARAMETERS_ERROR = 0X1E 654HCI_UNSPECIFIED_ERROR_ERROR = 0X1F 655HCI_UNSUPPORTED_LMP_OR_LL_PARAMETER_VALUE_ERROR = 0X20 656HCI_ROLE_CHANGE_NOT_ALLOWED_ERROR = 0X21 657HCI_LMP_OR_LL_RESPONSE_TIMEOUT_ERROR = 0X22 658HCI_LMP_ERROR_TRANSACTION_COLLISION_OR_LL_PROCEDURE_COLLISION_ERROR = 0X23 659HCI_LMP_PDU_NOT_ALLOWED_ERROR = 0X24 660HCI_ENCRYPTION_MODE_NOT_ACCEPTABLE_ERROR = 0X25 661HCI_LINK_KEY_CANNOT_BE_CHANGED_ERROR = 0X26 662HCI_REQUESTED_QOS_NOT_SUPPORTED_ERROR = 0X27 663HCI_INSTANT_PASSED_ERROR = 0X28 664HCI_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED_ERROR = 0X29 665HCI_DIFFERENT_TRANSACTION_COLLISION_ERROR = 0X2A 666HCI_RESERVED_FOR_FUTURE_USE = 0X2B 667HCI_QOS_UNACCEPTABLE_PARAMETER_ERROR = 0X2C 668HCI_QOS_REJECTED_ERROR = 0X2D 669HCI_CHANNEL_CLASSIFICATION_NOT_SUPPORTED_ERROR = 0X2E 670HCI_INSUFFICIENT_SECURITY_ERROR = 0X2F 671HCI_PARAMETER_OUT_OF_MANDATORY_RANGE_ERROR = 0X30 672HCI_ROLE_SWITCH_PENDING_ERROR = 0X32 673HCI_RESERVED_SLOT_VIOLATION_ERROR = 0X34 674HCI_ROLE_SWITCH_FAILED_ERROR = 0X35 675HCI_EXTENDED_INQUIRY_RESPONSE_TOO_LARGE_ERROR = 0X36 676HCI_SECURE_SIMPLE_PAIRING_NOT_SUPPORTED_BY_HOST_ERROR = 0X37 677HCI_HOST_BUSY_PAIRING_ERROR = 0X38 678HCI_CONNECTION_REJECTED_DUE_TO_NO_SUITABLE_CHANNEL_FOUND_ERROR = 0X39 679HCI_CONTROLLER_BUSY_ERROR = 0X3A 680HCI_UNACCEPTABLE_CONNECTION_PARAMETERS_ERROR = 0X3B 681HCI_ADVERTISING_TIMEOUT_ERROR = 0X3C 682HCI_CONNECTION_TERMINATED_DUE_TO_MIC_FAILURE_ERROR = 0X3D 683HCI_CONNECTION_FAILED_TO_BE_ESTABLISHED_ERROR = 0X3E 684HCI_COARSE_CLOCK_ADJUSTMENT_REJECTED_BUT_WILL_TRY_TO_ADJUST_USING_CLOCK_DRAGGING_ERROR = 0X40 685HCI_TYPE0_SUBMAP_NOT_DEFINED_ERROR = 0X41 686HCI_UNKNOWN_ADVERTISING_IDENTIFIER_ERROR = 0X42 687HCI_LIMIT_REACHED_ERROR = 0X43 688HCI_OPERATION_CANCELLED_BY_HOST_ERROR = 0X44 689HCI_PACKET_TOO_LONG_ERROR = 0X45 690 691HCI_ERROR_NAMES = { 692 error_code: error_name for (error_name, error_code) in globals().items() 693 if error_name.startswith('HCI_') and error_name.endswith('_ERROR') 694} 695HCI_ERROR_NAMES[HCI_SUCCESS] = 'HCI_SUCCESS' 696 697# Command Status codes 698HCI_COMMAND_STATUS_PENDING = 0 699 700 701# ACL 702HCI_ACL_PB_FIRST_NON_FLUSHABLE = 0 703HCI_ACL_PB_CONTINUATION = 1 704HCI_ACL_PB_FIRST_FLUSHABLE = 2 705HCI_ACK_PB_COMPLETE_L2CAP = 3 706 707# Roles 708HCI_CENTRAL_ROLE = 0 709HCI_PERIPHERAL_ROLE = 1 710 711HCI_ROLE_NAMES = { 712 HCI_CENTRAL_ROLE: 'CENTRAL', 713 HCI_PERIPHERAL_ROLE: 'PERIPHERAL' 714} 715 716# LE PHY Types 717HCI_LE_1M_PHY = 1 718HCI_LE_2M_PHY = 2 719HCI_LE_CODED_PHY = 3 720 721HCI_LE_PHY_NAMES = { 722 HCI_LE_1M_PHY: 'LE 1M', 723 HCI_LE_2M_PHY: 'LE 2M', 724 HCI_LE_CODED_PHY: 'LE Coded' 725} 726 727HCI_LE_1M_PHY_BIT = 0 728HCI_LE_2M_PHY_BIT = 1 729HCI_LE_CODED_PHY_BIT = 2 730 731HCI_LE_PHY_BIT_NAMES = ['LE_1M_PHY', 'LE_2M_PHY', 'LE_CODED_PHY'] 732 733HCI_LE_PHY_TYPE_TO_BIT = { 734 HCI_LE_1M_PHY: HCI_LE_1M_PHY_BIT, 735 HCI_LE_2M_PHY: HCI_LE_2M_PHY_BIT, 736 HCI_LE_CODED_PHY: HCI_LE_CODED_PHY_BIT 737} 738 739 740class Phy(enum.IntEnum): 741 LE_1M = HCI_LE_1M_PHY 742 LE_2M = HCI_LE_2M_PHY 743 LE_CODED = HCI_LE_CODED_PHY 744 745 746class PhyBit(enum.IntFlag): 747 LE_1M = 1 << HCI_LE_1M_PHY_BIT 748 LE_2M = 1 << HCI_LE_2M_PHY_BIT 749 LE_CODED = 1 << HCI_LE_CODED_PHY_BIT 750 751 752# Connection Parameters 753HCI_CONNECTION_INTERVAL_MS_PER_UNIT = 1.25 754HCI_CONNECTION_LATENCY_MS_PER_UNIT = 1.25 755HCI_SUPERVISION_TIMEOUT_MS_PER_UNIT = 10 756 757# Inquiry LAP 758HCI_LIMITED_DEDICATED_INQUIRY_LAP = 0x9E8B00 759HCI_GENERAL_INQUIRY_LAP = 0x9E8B33 760HCI_INQUIRY_LAP_NAMES = { 761 HCI_LIMITED_DEDICATED_INQUIRY_LAP: 'Limited Dedicated Inquiry', 762 HCI_GENERAL_INQUIRY_LAP: 'General Inquiry' 763} 764 765# Inquiry Mode 766HCI_STANDARD_INQUIRY_MODE = 0x00 767HCI_INQUIRY_WITH_RSSI_MODE = 0x01 768HCI_EXTENDED_INQUIRY_MODE = 0x02 769 770# Page Scan Repetition Mode 771HCI_R0_PAGE_SCAN_REPETITION_MODE = 0x00 772HCI_R1_PAGE_SCAN_REPETITION_MODE = 0x01 773HCI_R2_PAGE_SCAN_REPETITION_MODE = 0x02 774 775# IO Capability 776HCI_DISPLAY_ONLY_IO_CAPABILITY = 0x00 777HCI_DISPLAY_YES_NO_IO_CAPABILITY = 0x01 778HCI_KEYBOARD_ONLY_IO_CAPABILITY = 0x02 779HCI_NO_INPUT_NO_OUTPUT_IO_CAPABILITY = 0x03 780 781HCI_IO_CAPABILITY_NAMES = { 782 HCI_DISPLAY_ONLY_IO_CAPABILITY: 'HCI_DISPLAY_ONLY_IO_CAPABILITY', 783 HCI_DISPLAY_YES_NO_IO_CAPABILITY: 'HCI_DISPLAY_YES_NO_IO_CAPABILITY', 784 HCI_KEYBOARD_ONLY_IO_CAPABILITY: 'HCI_KEYBOARD_ONLY_IO_CAPABILITY', 785 HCI_NO_INPUT_NO_OUTPUT_IO_CAPABILITY: 'HCI_NO_INPUT_NO_OUTPUT_IO_CAPABILITY' 786} 787 788# Authentication Requirements 789HCI_MITM_NOT_REQUIRED_NO_BONDING_AUTHENTICATION_REQUIREMENTS = 0x00 790HCI_MITM_REQUIRED_NO_BONDING_AUTHENTICATION_REQUIREMENTS = 0x01 791HCI_MITM_NOT_REQUIRED_DEDICATED_BONDING_AUTHENTICATION_REQUIREMENTS = 0x02 792HCI_MITM_REQUIRED_DEDICATED_BONDING_AUTHENTICATION_REQUIREMENTS = 0x03 793HCI_MITM_NOT_REQUIRED_GENERAL_BONDING_AUTHENTICATION_REQUIREMENTS = 0x04 794HCI_MITM_REQUIRED_GENERAL_BONDING_AUTHENTICATION_REQUIREMENTS = 0x05 795 796HCI_AUTHENTICATION_REQUIREMENTS_NAMES = { 797 HCI_MITM_NOT_REQUIRED_NO_BONDING_AUTHENTICATION_REQUIREMENTS: 'HCI_MITM_NOT_REQUIRED_NO_BONDING_AUTHENTICATION_REQUIREMENTS', 798 HCI_MITM_REQUIRED_NO_BONDING_AUTHENTICATION_REQUIREMENTS: 'HCI_MITM_REQUIRED_NO_BONDING_AUTHENTICATION_REQUIREMENTS', 799 HCI_MITM_NOT_REQUIRED_DEDICATED_BONDING_AUTHENTICATION_REQUIREMENTS: 'HCI_MITM_NOT_REQUIRED_DEDICATED_BONDING_AUTHENTICATION_REQUIREMENTS', 800 HCI_MITM_REQUIRED_DEDICATED_BONDING_AUTHENTICATION_REQUIREMENTS: 'HCI_MITM_REQUIRED_DEDICATED_BONDING_AUTHENTICATION_REQUIREMENTS', 801 HCI_MITM_NOT_REQUIRED_GENERAL_BONDING_AUTHENTICATION_REQUIREMENTS: 'HCI_MITM_NOT_REQUIRED_GENERAL_BONDING_AUTHENTICATION_REQUIREMENTS', 802 HCI_MITM_REQUIRED_GENERAL_BONDING_AUTHENTICATION_REQUIREMENTS: 'HCI_MITM_REQUIRED_GENERAL_BONDING_AUTHENTICATION_REQUIREMENTS' 803} 804 805# Link Key Types 806HCI_COMBINATION_KEY_TYPE = 0X00 807HCI_LOCAL_UNIT_KEY_TYPE = 0X01 808HCI_REMOTE_UNIT_KEY_TYPE = 0X02 809HCI_DEBUG_COMBINATION_KEY_TYPE = 0X03 810HCI_UNAUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_192_TYPE = 0X04 811HCI_AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_192_TYPE = 0X05 812HCI_CHANGED_COMBINATION_KEY_TYPE = 0X06 813HCI_UNAUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_256_TYPE = 0X07 814HCI_AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_256_TYPE = 0X08 815 816HCI_LINK_TYPE_NAMES = { 817 HCI_COMBINATION_KEY_TYPE: 'HCI_COMBINATION_KEY_TYPE', 818 HCI_LOCAL_UNIT_KEY_TYPE: 'HCI_LOCAL_UNIT_KEY_TYPE', 819 HCI_REMOTE_UNIT_KEY_TYPE: 'HCI_REMOTE_UNIT_KEY_TYPE', 820 HCI_DEBUG_COMBINATION_KEY_TYPE: 'HCI_DEBUG_COMBINATION_KEY_TYPE', 821 HCI_UNAUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_192_TYPE: 'HCI_UNAUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_192_TYPE', 822 HCI_AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_192_TYPE: 'HCI_AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_192_TYPE', 823 HCI_CHANGED_COMBINATION_KEY_TYPE: 'HCI_CHANGED_COMBINATION_KEY_TYPE', 824 HCI_UNAUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_256_TYPE: 'HCI_UNAUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_256_TYPE', 825 HCI_AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_256_TYPE: 'HCI_AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_256_TYPE' 826} 827 828# Address types 829HCI_PUBLIC_DEVICE_ADDRESS_TYPE = 0x00 830HCI_RANDOM_DEVICE_ADDRESS_TYPE = 0x01 831HCI_PUBLIC_IDENTITY_ADDRESS_TYPE = 0x02 832HCI_RANDOM_IDENTITY_ADDRESS_TYPE = 0x03 833 834# Supported Commands Masks 835# See Bluetooth spec @ 6.27 SUPPORTED COMMANDS 836HCI_SUPPORTED_COMMANDS_MASKS = { 837 HCI_INQUIRY_COMMAND : 1 << (0*8+0), 838 HCI_INQUIRY_CANCEL_COMMAND : 1 << (0*8+1), 839 HCI_PERIODIC_INQUIRY_MODE_COMMAND : 1 << (0*8+2), 840 HCI_EXIT_PERIODIC_INQUIRY_MODE_COMMAND : 1 << (0*8+3), 841 HCI_CREATE_CONNECTION_COMMAND : 1 << (0*8+4), 842 HCI_DISCONNECT_COMMAND : 1 << (0*8+5), 843 HCI_CREATE_CONNECTION_CANCEL_COMMAND : 1 << (0*8+7), 844 HCI_ACCEPT_CONNECTION_REQUEST_COMMAND : 1 << (1*8+0), 845 HCI_REJECT_CONNECTION_REQUEST_COMMAND : 1 << (1*8+1), 846 HCI_LINK_KEY_REQUEST_REPLY_COMMAND : 1 << (1*8+2), 847 HCI_LINK_KEY_REQUEST_NEGATIVE_REPLY_COMMAND : 1 << (1*8+3), 848 HCI_PIN_CODE_REQUEST_REPLY_COMMAND : 1 << (1*8+4), 849 HCI_PIN_CODE_REQUEST_NEGATIVE_REPLY_COMMAND : 1 << (1*8+5), 850 HCI_CHANGE_CONNECTION_PACKET_TYPE_COMMAND : 1 << (1*8+6), 851 HCI_AUTHENTICATION_REQUESTED_COMMAND : 1 << (1*8+7), 852 HCI_SET_CONNECTION_ENCRYPTION_COMMAND : 1 << (2*8+0), 853 HCI_CHANGE_CONNECTION_LINK_KEY_COMMAND : 1 << (2*8+1), 854 HCI_LINK_KEY_SELECTION_COMMAND : 1 << (2*8+2), 855 HCI_REMOTE_NAME_REQUEST_COMMAND : 1 << (2*8+3), 856 HCI_REMOTE_NAME_REQUEST_CANCEL_COMMAND : 1 << (2*8+4), 857 HCI_READ_REMOTE_SUPPORTED_FEATURES_COMMAND : 1 << (2*8+5), 858 HCI_READ_REMOTE_EXTENDED_FEATURES_COMMAND : 1 << (2*8+6), 859 HCI_READ_REMOTE_VERSION_INFORMATION_COMMAND : 1 << (2*8+7), 860 HCI_READ_CLOCK_OFFSET_COMMAND : 1 << (3*8+0), 861 HCI_READ_LMP_HANDLE_COMMAND : 1 << (3*8+1), 862 HCI_HOLD_MODE_COMMAND : 1 << (4*8+1), 863 HCI_SNIFF_MODE_COMMAND : 1 << (4*8+2), 864 HCI_EXIT_SNIFF_MODE_COMMAND : 1 << (4*8+3), 865 HCI_QOS_SETUP_COMMAND : 1 << (4*8+6), 866 HCI_ROLE_DISCOVERY_COMMAND : 1 << (4*8+7), 867 HCI_SWITCH_ROLE_COMMAND : 1 << (5*8+0), 868 HCI_READ_LINK_POLICY_SETTINGS_COMMAND : 1 << (5*8+1), 869 HCI_WRITE_LINK_POLICY_SETTINGS_COMMAND : 1 << (5*8+2), 870 HCI_READ_DEFAULT_LINK_POLICY_SETTINGS_COMMAND : 1 << (5*8+3), 871 HCI_WRITE_DEFAULT_LINK_POLICY_SETTINGS_COMMAND : 1 << (5*8+4), 872 HCI_FLOW_SPECIFICATION_COMMAND : 1 << (5*8+5), 873 HCI_SET_EVENT_MASK_COMMAND : 1 << (5*8+6), 874 HCI_RESET_COMMAND : 1 << (5*8+7), 875 HCI_SET_EVENT_FILTER_COMMAND : 1 << (6*8+0), 876 HCI_FLUSH_COMMAND : 1 << (6*8+1), 877 HCI_READ_PIN_TYPE_COMMAND : 1 << (6*8+2), 878 HCI_WRITE_PIN_TYPE_COMMAND : 1 << (6*8+3), 879 HCI_READ_STORED_LINK_KEY_COMMAND : 1 << (6*8+5), 880 HCI_WRITE_STORED_LINK_KEY_COMMAND : 1 << (6*8+6), 881 HCI_DELETE_STORED_LINK_KEY_COMMAND : 1 << (6*8+7), 882 HCI_WRITE_LOCAL_NAME_COMMAND : 1 << (7*8+0), 883 HCI_READ_LOCAL_NAME_COMMAND : 1 << (7*8+1), 884 HCI_READ_CONNECTION_ACCEPT_TIMEOUT_COMMAND : 1 << (7*8+2), 885 HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT_COMMAND : 1 << (7*8+3), 886 HCI_READ_PAGE_TIMEOUT_COMMAND : 1 << (7*8+4), 887 HCI_WRITE_PAGE_TIMEOUT_COMMAND : 1 << (7*8+5), 888 HCI_READ_SCAN_ENABLE_COMMAND : 1 << (7*8+6), 889 HCI_WRITE_SCAN_ENABLE_COMMAND : 1 << (7*8+7), 890 HCI_READ_PAGE_SCAN_ACTIVITY_COMMAND : 1 << (8*8+0), 891 HCI_WRITE_PAGE_SCAN_ACTIVITY_COMMAND : 1 << (8*8+1), 892 HCI_READ_INQUIRY_SCAN_ACTIVITY_COMMAND : 1 << (8*8+2), 893 HCI_WRITE_INQUIRY_SCAN_ACTIVITY_COMMAND : 1 << (8*8+3), 894 HCI_READ_AUTHENTICATION_ENABLE_COMMAND : 1 << (8*8+4), 895 HCI_WRITE_AUTHENTICATION_ENABLE_COMMAND : 1 << (8*8+5), 896 HCI_READ_CLASS_OF_DEVICE_COMMAND : 1 << (9*8+0), 897 HCI_WRITE_CLASS_OF_DEVICE_COMMAND : 1 << (9*8+1), 898 HCI_READ_VOICE_SETTING_COMMAND : 1 << (9*8+2), 899 HCI_WRITE_VOICE_SETTING_COMMAND : 1 << (9*8+3), 900 HCI_READ_AUTOMATIC_FLUSH_TIMEOUT_COMMAND : 1 << (9*8+4), 901 HCI_WRITE_AUTOMATIC_FLUSH_TIMEOUT_COMMAND : 1 << (9*8+5), 902 HCI_READ_NUM_BROADCAST_RETRANSMISSIONS_COMMAND : 1 << (9*8+6), 903 HCI_WRITE_NUM_BROADCAST_RETRANSMISSIONS_COMMAND : 1 << (9*8+7), 904 HCI_READ_HOLD_MODE_ACTIVITY_COMMAND : 1 << (10*8+0), 905 HCI_WRITE_HOLD_MODE_ACTIVITY_COMMAND : 1 << (10*8+1), 906 HCI_READ_TRANSMIT_POWER_LEVEL_COMMAND : 1 << (10*8+2), 907 HCI_READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE_COMMAND : 1 << (10*8+3), 908 HCI_WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE_COMMAND : 1 << (10*8+4), 909 HCI_SET_CONTROLLER_TO_HOST_FLOW_CONTROL_COMMAND : 1 << (10*8+5), 910 HCI_HOST_BUFFER_SIZE_COMMAND : 1 << (10*8+6), 911 HCI_HOST_NUMBER_OF_COMPLETED_PACKETS_COMMAND : 1 << (10*8+7), 912 HCI_READ_LINK_SUPERVISION_TIMEOUT_COMMAND : 1 << (11*8+0), 913 HCI_WRITE_LINK_SUPERVISION_TIMEOUT_COMMAND : 1 << (11*8+1), 914 HCI_READ_NUMBER_OF_SUPPORTED_IAC_COMMAND : 1 << (11*8+2), 915 HCI_READ_CURRENT_IAC_LAP_COMMAND : 1 << (11*8+3), 916 HCI_WRITE_CURRENT_IAC_LAP_COMMAND : 1 << (11*8+4), 917 HCI_SET_AFH_HOST_CHANNEL_CLASSIFICATION_COMMAND : 1 << (12*8+1), 918 HCI_READ_INQUIRY_SCAN_TYPE_COMMAND : 1 << (12*8+4), 919 HCI_WRITE_INQUIRY_SCAN_TYPE_COMMAND : 1 << (12*8+5), 920 HCI_READ_INQUIRY_MODE_COMMAND : 1 << (12*8+6), 921 HCI_WRITE_INQUIRY_MODE_COMMAND : 1 << (12*8+7), 922 HCI_READ_PAGE_SCAN_TYPE_COMMAND : 1 << (13*8+0), 923 HCI_WRITE_PAGE_SCAN_TYPE_COMMAND : 1 << (13*8+1), 924 HCI_READ_AFH_CHANNEL_ASSESSMENT_MODE_COMMAND : 1 << (13*8+2), 925 HCI_WRITE_AFH_CHANNEL_ASSESSMENT_MODE_COMMAND : 1 << (13*8+3), 926 HCI_READ_LOCAL_VERSION_INFORMATION_COMMAND : 1 << (14*8+3), 927 HCI_READ_LOCAL_SUPPORTED_FEATURES_COMMAND : 1 << (14*8+5), 928 HCI_READ_LOCAL_EXTENDED_FEATURES_COMMAND : 1 << (14*8+6), 929 HCI_READ_BUFFER_SIZE_COMMAND : 1 << (14*8+7), 930 HCI_READ_BD_ADDR_COMMAND : 1 << (15*8+1), 931 HCI_READ_FAILED_CONTACT_COUNTER_COMMAND : 1 << (15*8+2), 932 HCI_RESET_FAILED_CONTACT_COUNTER_COMMAND : 1 << (15*8+3), 933 HCI_READ_LINK_QUALITY_COMMAND : 1 << (15*8+4), 934 HCI_READ_RSSI_COMMAND : 1 << (15*8+5), 935 HCI_READ_AFH_CHANNEL_MAP_COMMAND : 1 << (15*8+6), 936 HCI_READ_CLOCK_COMMAND : 1 << (15*8+7), 937 HCI_READ_LOOPBACK_MODE_COMMAND : 1 << (16*8+0), 938 HCI_WRITE_LOOPBACK_MODE_COMMAND : 1 << (16*8+1), 939 HCI_ENABLE_DEVICE_UNDER_TEST_MODE_COMMAND : 1 << (16*8+2), 940 HCI_SETUP_SYNCHRONOUS_CONNECTION_COMMAND : 1 << (16*8+3), 941 HCI_ACCEPT_SYNCHRONOUS_CONNECTION_REQUEST_COMMAND : 1 << (16*8+4), 942 HCI_REJECT_SYNCHRONOUS_CONNECTION_REQUEST_COMMAND : 1 << (16*8+5), 943 HCI_READ_EXTENDED_INQUIRY_RESPONSE_COMMAND : 1 << (17*8+0), 944 HCI_WRITE_EXTENDED_INQUIRY_RESPONSE_COMMAND : 1 << (17*8+1), 945 HCI_REFRESH_ENCRYPTION_KEY_COMMAND : 1 << (17*8+2), 946 HCI_SNIFF_SUBRATING_COMMAND : 1 << (17*8+4), 947 HCI_READ_SIMPLE_PAIRING_MODE_COMMAND : 1 << (17*8+5), 948 HCI_WRITE_SIMPLE_PAIRING_MODE_COMMAND : 1 << (17*8+6), 949 HCI_READ_LOCAL_OOB_DATA_COMMAND : 1 << (17*8+7), 950 HCI_READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL_COMMAND : 1 << (18*8+0), 951 HCI_WRITE_INQUIRY_TRANSMIT_POWER_LEVEL_COMMAND : 1 << (18*8+1), 952 HCI_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_COMMAND : 1 << (18*8+2), 953 HCI_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_COMMAND : 1 << (18*8+3), 954 HCI_IO_CAPABILITY_REQUEST_REPLY_COMMAND : 1 << (18*8+7), 955 HCI_USER_CONFIRMATION_REQUEST_REPLY_COMMAND : 1 << (19*8+0), 956 HCI_USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY_COMMAND : 1 << (19*8+1), 957 HCI_USER_PASSKEY_REQUEST_REPLY_COMMAND : 1 << (19*8+2), 958 HCI_USER_PASSKEY_REQUEST_NEGATIVE_REPLY_COMMAND : 1 << (19*8+3), 959 HCI_REMOTE_OOB_DATA_REQUEST_REPLY_COMMAND : 1 << (19*8+4), 960 HCI_WRITE_SIMPLE_PAIRING_DEBUG_MODE_COMMAND : 1 << (19*8+5), 961 HCI_ENHANCED_FLUSH_COMMAND : 1 << (19*8+6), 962 HCI_REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY_COMMAND : 1 << (19*8+7), 963 HCI_SEND_KEYPRESS_NOTIFICATION_COMMAND : 1 << (20*8+2), 964 HCI_IO_CAPABILITY_REQUEST_NEGATIVE_REPLY_COMMAND : 1 << (20*8+3), 965 HCI_READ_ENCRYPTION_KEY_SIZE_COMMAND : 1 << (20*8+4), 966 HCI_SET_EVENT_MASK_PAGE_2_COMMAND : 1 << (22*8+2), 967 HCI_READ_FLOW_CONTROL_MODE_COMMAND : 1 << (23*8+0), 968 HCI_WRITE_FLOW_CONTROL_MODE_COMMAND : 1 << (23*8+1), 969 HCI_READ_DATA_BLOCK_SIZE_COMMAND : 1 << (23*8+2), 970 HCI_READ_ENHANCED_TRANSMIT_POWER_LEVEL_COMMAND : 1 << (24*8+0), 971 HCI_READ_LE_HOST_SUPPORT_COMMAND : 1 << (24*8+5), 972 HCI_WRITE_LE_HOST_SUPPORT_COMMAND : 1 << (24*8+6), 973 HCI_LE_SET_EVENT_MASK_COMMAND : 1 << (25*8+0), 974 HCI_LE_READ_BUFFER_SIZE_COMMAND : 1 << (25*8+1), 975 HCI_LE_READ_LOCAL_SUPPORTED_FEATURES_COMMAND : 1 << (25*8+2), 976 HCI_LE_SET_RANDOM_ADDRESS_COMMAND : 1 << (25*8+4), 977 HCI_LE_SET_ADVERTISING_PARAMETERS_COMMAND : 1 << (25*8+5), 978 HCI_LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER_COMMAND : 1 << (25*8+6), 979 HCI_LE_SET_ADVERTISING_DATA_COMMAND : 1 << (25*8+7), 980 HCI_LE_SET_SCAN_RESPONSE_DATA_COMMAND : 1 << (26*8+0), 981 HCI_LE_SET_ADVERTISING_ENABLE_COMMAND : 1 << (26*8+1), 982 HCI_LE_SET_SCAN_PARAMETERS_COMMAND : 1 << (26*8+2), 983 HCI_LE_SET_SCAN_ENABLE_COMMAND : 1 << (26*8+3), 984 HCI_LE_CREATE_CONNECTION_COMMAND : 1 << (26*8+4), 985 HCI_LE_CREATE_CONNECTION_CANCEL_COMMAND : 1 << (26*8+5), 986 HCI_LE_READ_FILTER_ACCEPT_LIST_SIZE_COMMAND : 1 << (26*8+6), 987 HCI_LE_CLEAR_FILTER_ACCEPT_LIST_COMMAND : 1 << (26*8+7), 988 HCI_LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST_COMMAND : 1 << (27*8+0), 989 HCI_LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST_COMMAND : 1 << (27*8+1), 990 HCI_LE_CONNECTION_UPDATE_COMMAND : 1 << (27*8+2), 991 HCI_LE_SET_HOST_CHANNEL_CLASSIFICATION_COMMAND : 1 << (27*8+3), 992 HCI_LE_READ_CHANNEL_MAP_COMMAND : 1 << (27*8+4), 993 HCI_LE_READ_REMOTE_FEATURES_COMMAND : 1 << (27*8+5), 994 HCI_LE_ENCRYPT_COMMAND : 1 << (27*8+6), 995 HCI_LE_RAND_COMMAND : 1 << (27*8+7), 996 HCI_LE_ENABLE_ENCRYPTION_COMMAND : 1 << (28*8+0), 997 HCI_LE_LONG_TERM_KEY_REQUEST_REPLY_COMMAND : 1 << (28*8+1), 998 HCI_LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY_COMMAND : 1 << (28*8+2), 999 HCI_LE_READ_SUPPORTED_STATES_COMMAND : 1 << (28*8+3), 1000 HCI_LE_RECEIVER_TEST_COMMAND : 1 << (28*8+4), 1001 HCI_LE_TRANSMITTER_TEST_COMMAND : 1 << (28*8+5), 1002 HCI_LE_TEST_END_COMMAND : 1 << (28*8+6), 1003 HCI_ENHANCED_SETUP_SYNCHRONOUS_CONNECTION_COMMAND : 1 << (29*8+3), 1004 HCI_ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION_REQUEST_COMMAND : 1 << (29*8+4), 1005 HCI_READ_LOCAL_SUPPORTED_CODECS_COMMAND : 1 << (29*8+5), 1006 HCI_SET_MWS_CHANNEL_PARAMETERS_COMMAND : 1 << (29*8+6), 1007 HCI_SET_EXTERNAL_FRAME_CONFIGURATION_COMMAND : 1 << (29*8+7), 1008 HCI_SET_MWS_SIGNALING_COMMAND : 1 << (30*8+0), 1009 HCI_SET_MWS_TRANSPORT_LAYER_COMMAND : 1 << (30*8+1), 1010 HCI_SET_MWS_SCAN_FREQUENCY_TABLE_COMMAND : 1 << (30*8+2), 1011 HCI_GET_MWS_TRANSPORT_LAYER_CONFIGURATION_COMMAND : 1 << (30*8+3), 1012 HCI_SET_MWS_PATTERN_CONFIGURATION_COMMAND : 1 << (30*8+4), 1013 HCI_SET_TRIGGERED_CLOCK_CAPTURE_COMMAND : 1 << (30*8+5), 1014 HCI_TRUNCATED_PAGE_COMMAND : 1 << (30*8+6), 1015 HCI_TRUNCATED_PAGE_CANCEL_COMMAND : 1 << (30*8+7), 1016 HCI_SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_COMMAND : 1 << (31*8+0), 1017 HCI_SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVE_COMMAND : 1 << (31*8+1), 1018 HCI_START_SYNCHRONIZATION_TRAIN_COMMAND : 1 << (31*8+2), 1019 HCI_RECEIVE_SYNCHRONIZATION_TRAIN_COMMAND : 1 << (31*8+3), 1020 HCI_SET_RESERVED_LT_ADDR_COMMAND : 1 << (31*8+4), 1021 HCI_DELETE_RESERVED_LT_ADDR_COMMAND : 1 << (31*8+5), 1022 HCI_SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_DATA_COMMAND : 1 << (31*8+6), 1023 HCI_READ_SYNCHRONIZATION_TRAIN_PARAMETERS_COMMAND : 1 << (31*8+7), 1024 HCI_WRITE_SYNCHRONIZATION_TRAIN_PARAMETERS_COMMAND : 1 << (32*8+0), 1025 HCI_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_COMMAND : 1 << (32*8+1), 1026 HCI_READ_SECURE_CONNECTIONS_HOST_SUPPORT_COMMAND : 1 << (32*8+2), 1027 HCI_WRITE_SECURE_CONNECTIONS_HOST_SUPPORT_COMMAND : 1 << (32*8+3), 1028 HCI_READ_AUTHENTICATED_PAYLOAD_TIMEOUT_COMMAND : 1 << (32*8+4), 1029 HCI_WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT_COMMAND : 1 << (32*8+5), 1030 HCI_READ_LOCAL_OOB_EXTENDED_DATA_COMMAND : 1 << (32*8+6), 1031 HCI_WRITE_SECURE_CONNECTIONS_TEST_MODE_COMMAND : 1 << (32*8+7), 1032 HCI_READ_EXTENDED_PAGE_TIMEOUT_COMMAND : 1 << (33*8+0), 1033 HCI_WRITE_EXTENDED_PAGE_TIMEOUT_COMMAND : 1 << (33*8+1), 1034 HCI_READ_EXTENDED_INQUIRY_LENGTH_COMMAND : 1 << (33*8+2), 1035 HCI_WRITE_EXTENDED_INQUIRY_LENGTH_COMMAND : 1 << (33*8+3), 1036 HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY_COMMAND : 1 << (33*8+4), 1037 HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY_COMMAND : 1 << (33*8+5), 1038 HCI_LE_SET_DATA_LENGTH_COMMAND : 1 << (33*8+6), 1039 HCI_LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH_COMMAND : 1 << (33*8+7), 1040 HCI_LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH_COMMAND : 1 << (34*8+0), 1041 HCI_LE_READ_LOCAL_P_256_PUBLIC_KEY_COMMAND : 1 << (34*8+1), 1042 HCI_LE_GENERATE_DHKEY_COMMAND : 1 << (34*8+2), 1043 HCI_LE_ADD_DEVICE_TO_RESOLVING_LIST_COMMAND : 1 << (34*8+3), 1044 HCI_LE_REMOVE_DEVICE_FROM_RESOLVING_LIST_COMMAND : 1 << (34*8+4), 1045 HCI_LE_CLEAR_RESOLVING_LIST_COMMAND : 1 << (34*8+5), 1046 HCI_LE_READ_RESOLVING_LIST_SIZE_COMMAND : 1 << (34*8+6), 1047 HCI_LE_READ_PEER_RESOLVABLE_ADDRESS_COMMAND : 1 << (34*8+7), 1048 HCI_LE_READ_LOCAL_RESOLVABLE_ADDRESS_COMMAND : 1 << (35*8+0), 1049 HCI_LE_SET_ADDRESS_RESOLUTION_ENABLE_COMMAND : 1 << (35*8+1), 1050 HCI_LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT_COMMAND : 1 << (35*8+2), 1051 HCI_LE_READ_MAXIMUM_DATA_LENGTH_COMMAND : 1 << (35*8+3), 1052 HCI_LE_READ_PHY_COMMAND : 1 << (35*8+4), 1053 HCI_LE_SET_DEFAULT_PHY_COMMAND : 1 << (35*8+5), 1054 HCI_LE_SET_PHY_COMMAND : 1 << (35*8+6), 1055 HCI_LE_RECEIVER_TEST_V2_COMMAND : 1 << (35*8+7), 1056 HCI_LE_TRANSMITTER_TEST_V2_COMMAND : 1 << (36*8+0), 1057 HCI_LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_COMMAND : 1 << (36*8+1), 1058 HCI_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_COMMAND : 1 << (36*8+2), 1059 HCI_LE_SET_EXTENDED_ADVERTISING_DATA_COMMAND : 1 << (36*8+3), 1060 HCI_LE_SET_EXTENDED_SCAN_RESPONSE_DATA_COMMAND : 1 << (36*8+4), 1061 HCI_LE_SET_EXTENDED_ADVERTISING_ENABLE_COMMAND : 1 << (36*8+5), 1062 HCI_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH_COMMAND : 1 << (36*8+6), 1063 HCI_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS_COMMAND : 1 << (36*8+7), 1064 HCI_LE_REMOVE_ADVERTISING_SET_COMMAND : 1 << (37*8+0), 1065 HCI_LE_CLEAR_ADVERTISING_SETS_COMMAND : 1 << (37*8+1), 1066 HCI_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_COMMAND : 1 << (37*8+2), 1067 HCI_LE_SET_PERIODIC_ADVERTISING_DATA_COMMAND : 1 << (37*8+3), 1068 HCI_LE_SET_PERIODIC_ADVERTISING_ENABLE_COMMAND : 1 << (37*8+4), 1069 HCI_LE_SET_EXTENDED_SCAN_PARAMETERS_COMMAND : 1 << (37*8+5), 1070 HCI_LE_SET_EXTENDED_SCAN_ENABLE_COMMAND : 1 << (37*8+6), 1071 HCI_LE_EXTENDED_CREATE_CONNECTION_COMMAND : 1 << (37*8+7), 1072 HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC_COMMAND : 1 << (38*8+0), 1073 HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL_COMMAND : 1 << (38*8+1), 1074 HCI_LE_PERIODIC_ADVERTISING_TERMINATE_SYNC_COMMAND : 1 << (38*8+2), 1075 HCI_LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST_COMMAND : 1 << (38*8+3), 1076 HCI_LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST_COMMAND : 1 << (38*8+4), 1077 HCI_LE_CLEAR_PERIODIC_ADVERTISER_LIST_COMMAND : 1 << (38*8+5), 1078 HCI_LE_READ_PERIODIC_ADVERTISER_LIST_SIZE_COMMAND : 1 << (38*8+6), 1079 HCI_LE_READ_TRANSMIT_POWER_COMMAND : 1 << (38*8+7), 1080 HCI_LE_READ_RF_PATH_COMPENSATION_COMMAND : 1 << (39*8+0), 1081 HCI_LE_WRITE_RF_PATH_COMPENSATION_COMMAND : 1 << (39*8+1), 1082 HCI_LE_SET_PRIVACY_MODE_COMMAND : 1 << (39*8+2), 1083 HCI_LE_RECEIVER_TEST_V3_COMMAND : 1 << (39*8+3), 1084 HCI_LE_TRANSMITTER_TEST_V3_COMMAND : 1 << (39*8+4), 1085 HCI_LE_SET_CONNECTIONLESS_CTE_TRANSMIT_PARAMETERS_COMMAND : 1 << (39*8+5), 1086 HCI_LE_SET_CONNECTIONLESS_CTE_TRANSMIT_ENABLE_COMMAND : 1 << (39*8+6), 1087 HCI_LE_SET_CONNECTIONLESS_IQ_SAMPLING_ENABLE_COMMAND : 1 << (39*8+7), 1088 HCI_LE_SET_CONNECTION_CTE_RECEIVE_PARAMETERS_COMMAND : 1 << (40*8+0), 1089 HCI_LE_SET_CONNECTION_CTE_TRANSMIT_PARAMETERS_COMMAND : 1 << (40*8+1), 1090 HCI_LE_CONNECTION_CTE_REQUEST_ENABLE_COMMAND : 1 << (40*8+2), 1091 HCI_LE_CONNECTION_CTE_RESPONSE_ENABLE_COMMAND : 1 << (40*8+3), 1092 HCI_LE_READ_ANTENNA_INFORMATION_COMMAND : 1 << (40*8+4), 1093 HCI_LE_SET_PERIODIC_ADVERTISING_RECEIVE_ENABLE_COMMAND : 1 << (40*8+5), 1094 HCI_LE_PERIODIC_ADVERTISING_SYNC_TRANSFER_COMMAND : 1 << (40*8+6), 1095 HCI_LE_PERIODIC_ADVERTISING_SET_INFO_TRANSFER_COMMAND : 1 << (40*8+7), 1096 HCI_LE_SET_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS_COMMAND : 1 << (41*8+0), 1097 HCI_LE_SET_DEFAULT_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS_COMMAND : 1 << (41*8+1), 1098 HCI_LE_GENERATE_DHKEY_V2_COMMAND : 1 << (41*8+2), 1099 HCI_READ_LOCAL_SIMPLE_PAIRING_OPTIONS_COMMAND : 1 << (41*8+3), 1100 HCI_LE_MODIFY_SLEEP_CLOCK_ACCURACY_COMMAND : 1 << (41*8+4), 1101 HCI_LE_READ_BUFFER_SIZE_V2_COMMAND : 1 << (41*8+5), 1102 HCI_LE_READ_ISO_TX_SYNC_COMMAND : 1 << (41*8+6), 1103 HCI_LE_SET_CIG_PARAMETERS_COMMAND : 1 << (41*8+7), 1104 HCI_LE_SET_CIG_PARAMETERS_TEST_COMMAND : 1 << (42*8+0), 1105 HCI_LE_CREATE_CIS_COMMAND : 1 << (42*8+1), 1106 HCI_LE_REMOVE_CIG_COMMAND : 1 << (42*8+2), 1107 HCI_LE_ACCEPT_CIS_REQUEST_COMMAND : 1 << (42*8+3), 1108 HCI_LE_REJECT_CIS_REQUEST_COMMAND : 1 << (42*8+4), 1109 HCI_LE_CREATE_BIG_COMMAND : 1 << (42*8+5), 1110 HCI_LE_CREATE_BIG_TEST_COMMAND : 1 << (42*8+6), 1111 HCI_LE_TERMINATE_BIG_COMMAND : 1 << (42*8+7), 1112 HCI_LE_BIG_CREATE_SYNC_COMMAND : 1 << (43*8+0), 1113 HCI_LE_BIG_TERMINATE_SYNC_COMMAND : 1 << (43*8+1), 1114 HCI_LE_REQUEST_PEER_SCA_COMMAND : 1 << (43*8+2), 1115 HCI_LE_SETUP_ISO_DATA_PATH_COMMAND : 1 << (43*8+3), 1116 HCI_LE_REMOVE_ISO_DATA_PATH_COMMAND : 1 << (43*8+4), 1117 HCI_LE_ISO_TRANSMIT_TEST_COMMAND : 1 << (43*8+5), 1118 HCI_LE_ISO_RECEIVE_TEST_COMMAND : 1 << (43*8+6), 1119 HCI_LE_ISO_READ_TEST_COUNTERS_COMMAND : 1 << (43*8+7), 1120 HCI_LE_ISO_TEST_END_COMMAND : 1 << (44*8+0), 1121 HCI_LE_SET_HOST_FEATURE_COMMAND : 1 << (44*8+1), 1122 HCI_LE_READ_ISO_LINK_QUALITY_COMMAND : 1 << (44*8+2), 1123 HCI_LE_ENHANCED_READ_TRANSMIT_POWER_LEVEL_COMMAND : 1 << (44*8+3), 1124 HCI_LE_READ_REMOTE_TRANSMIT_POWER_LEVEL_COMMAND : 1 << (44*8+4), 1125 HCI_LE_SET_PATH_LOSS_REPORTING_PARAMETERS_COMMAND : 1 << (44*8+5), 1126 HCI_LE_SET_PATH_LOSS_REPORTING_ENABLE_COMMAND : 1 << (44*8+6), 1127 HCI_LE_SET_TRANSMIT_POWER_REPORTING_ENABLE_COMMAND : 1 << (44*8+7), 1128 HCI_LE_TRANSMITTER_TEST_V4_COMMAND : 1 << (45*8+0), 1129 HCI_SET_ECOSYSTEM_BASE_INTERVAL_COMMAND : 1 << (45*8+1), 1130 HCI_READ_LOCAL_SUPPORTED_CODECS_V2_COMMAND : 1 << (45*8+2), 1131 HCI_READ_LOCAL_SUPPORTED_CODEC_CAPABILITIES_COMMAND : 1 << (45*8+3), 1132 HCI_READ_LOCAL_SUPPORTED_CONTROLLER_DELAY_COMMAND : 1 << (45*8+4), 1133 HCI_CONFIGURE_DATA_PATH_COMMAND : 1 << (45*8+5), 1134 HCI_LE_SET_DATA_RELATED_ADDRESS_CHANGES_COMMAND : 1 << (45*8+6), 1135 HCI_SET_MIN_ENCRYPTION_KEY_SIZE_COMMAND : 1 << (45*8+7), 1136 HCI_LE_SET_DEFAULT_SUBRATE_COMMAND : 1 << (46*8+0), 1137 HCI_LE_SUBRATE_REQUEST_COMMAND : 1 << (46*8+1), 1138 HCI_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_V2_COMMAND : 1 << (46*8+2), 1139 HCI_LE_SET_PERIODIC_ADVERTISING_SUBEVENT_DATA_COMMAND : 1 << (46*8+5), 1140 HCI_LE_SET_PERIODIC_ADVERTISING_RESPONSE_DATA_COMMAND : 1 << (46*8+6), 1141 HCI_LE_SET_PERIODIC_SYNC_SUBEVENT_COMMAND : 1 << (46*8+7), 1142 HCI_LE_EXTENDED_CREATE_CONNECTION_V2_COMMAND : 1 << (47*8+0), 1143 HCI_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_V2_COMMAND : 1 << (47*8+1), 1144} 1145 1146# LE Supported Features 1147# See Bluetooth spec @ Vol 6, Part B, 4.6 FEATURE SUPPORT 1148class LeFeature(OpenIntEnum): 1149 LE_ENCRYPTION = 0 1150 CONNECTION_PARAMETERS_REQUEST_PROCEDURE = 1 1151 EXTENDED_REJECT_INDICATION = 2 1152 PERIPHERAL_INITIATED_FEATURE_EXCHANGE = 3 1153 LE_PING = 4 1154 LE_DATA_PACKET_LENGTH_EXTENSION = 5 1155 LL_PRIVACY = 6 1156 EXTENDED_SCANNER_FILTER_POLICIES = 7 1157 LE_2M_PHY = 8 1158 STABLE_MODULATION_INDEX_TRANSMITTER = 9 1159 STABLE_MODULATION_INDEX_RECEIVER = 10 1160 LE_CODED_PHY = 11 1161 LE_EXTENDED_ADVERTISING = 12 1162 LE_PERIODIC_ADVERTISING = 13 1163 CHANNEL_SELECTION_ALGORITHM_2 = 14 1164 LE_POWER_CLASS_1 = 15 1165 MINIMUM_NUMBER_OF_USED_CHANNELS_PROCEDURE = 16 1166 CONNECTION_CTE_REQUEST = 17 1167 CONNECTION_CTE_RESPONSE = 18 1168 CONNECTIONLESS_CTE_TRANSMITTER = 19 1169 CONNECTIONLESS_CTR_RECEIVER = 20 1170 ANTENNA_SWITCHING_DURING_CTE_TRANSMISSION = 21 1171 ANTENNA_SWITCHING_DURING_CTE_RECEPTION = 22 1172 RECEIVING_CONSTANT_TONE_EXTENSIONS = 23 1173 PERIODIC_ADVERTISING_SYNC_TRANSFER_SENDER = 24 1174 PERIODIC_ADVERTISING_SYNC_TRANSFER_RECIPIENT = 25 1175 SLEEP_CLOCK_ACCURACY_UPDATES = 26 1176 REMOTE_PUBLIC_KEY_VALIDATION = 27 1177 CONNECTED_ISOCHRONOUS_STREAM_CENTRAL = 28 1178 CONNECTED_ISOCHRONOUS_STREAM_PERIPHERAL = 29 1179 ISOCHRONOUS_BROADCASTER = 30 1180 SYNCHRONIZED_RECEIVER = 31 1181 CONNECTED_ISOCHRONOUS_STREAM = 32 1182 LE_POWER_CONTROL_REQUEST = 33 1183 LE_POWER_CONTROL_REQUEST_DUP = 34 1184 LE_PATH_LOSS_MONITORING = 35 1185 PERIODIC_ADVERTISING_ADI_SUPPORT = 36 1186 CONNECTION_SUBRATING = 37 1187 CONNECTION_SUBRATING_HOST_SUPPORT = 38 1188 CHANNEL_CLASSIFICATION = 39 1189 ADVERTISING_CODING_SELECTION = 40 1190 ADVERTISING_CODING_SELECTION_HOST_SUPPORT = 41 1191 DECISION_BASED_ADVERTISING_FILTERING = 42 1192 PERIODIC_ADVERTISING_WITH_RESPONSES_ADVERTISER = 43 1193 PERIODIC_ADVERTISING_WITH_RESPONSES_SCANNER = 44 1194 UNSEGMENTED_FRAMED_MODE = 45 1195 CHANNEL_SOUNDING = 46 1196 CHANNEL_SOUNDING_HOST_SUPPORT = 47 1197 CHANNEL_SOUNDING_TONE_QUALITY_INDICATION = 48 1198 LL_EXTENDED_FEATURE_SET = 63 1199 MONITORING_ADVERTISERS = 64 1200 FRAME_SPACE_UPDATE = 65 1201 1202class LeFeatureMask(enum.IntFlag): 1203 LE_ENCRYPTION = 1 << LeFeature.LE_ENCRYPTION 1204 CONNECTION_PARAMETERS_REQUEST_PROCEDURE = 1 << LeFeature.CONNECTION_PARAMETERS_REQUEST_PROCEDURE 1205 EXTENDED_REJECT_INDICATION = 1 << LeFeature.EXTENDED_REJECT_INDICATION 1206 PERIPHERAL_INITIATED_FEATURE_EXCHANGE = 1 << LeFeature.PERIPHERAL_INITIATED_FEATURE_EXCHANGE 1207 LE_PING = 1 << LeFeature.LE_PING 1208 LE_DATA_PACKET_LENGTH_EXTENSION = 1 << LeFeature.LE_DATA_PACKET_LENGTH_EXTENSION 1209 LL_PRIVACY = 1 << LeFeature.LL_PRIVACY 1210 EXTENDED_SCANNER_FILTER_POLICIES = 1 << LeFeature.EXTENDED_SCANNER_FILTER_POLICIES 1211 LE_2M_PHY = 1 << LeFeature.LE_2M_PHY 1212 STABLE_MODULATION_INDEX_TRANSMITTER = 1 << LeFeature.STABLE_MODULATION_INDEX_TRANSMITTER 1213 STABLE_MODULATION_INDEX_RECEIVER = 1 << LeFeature.STABLE_MODULATION_INDEX_RECEIVER 1214 LE_CODED_PHY = 1 << LeFeature.LE_CODED_PHY 1215 LE_EXTENDED_ADVERTISING = 1 << LeFeature.LE_EXTENDED_ADVERTISING 1216 LE_PERIODIC_ADVERTISING = 1 << LeFeature.LE_PERIODIC_ADVERTISING 1217 CHANNEL_SELECTION_ALGORITHM_2 = 1 << LeFeature.CHANNEL_SELECTION_ALGORITHM_2 1218 LE_POWER_CLASS_1 = 1 << LeFeature.LE_POWER_CLASS_1 1219 MINIMUM_NUMBER_OF_USED_CHANNELS_PROCEDURE = 1 << LeFeature.MINIMUM_NUMBER_OF_USED_CHANNELS_PROCEDURE 1220 CONNECTION_CTE_REQUEST = 1 << LeFeature.CONNECTION_CTE_REQUEST 1221 CONNECTION_CTE_RESPONSE = 1 << LeFeature.CONNECTION_CTE_RESPONSE 1222 CONNECTIONLESS_CTE_TRANSMITTER = 1 << LeFeature.CONNECTIONLESS_CTE_TRANSMITTER 1223 CONNECTIONLESS_CTR_RECEIVER = 1 << LeFeature.CONNECTIONLESS_CTR_RECEIVER 1224 ANTENNA_SWITCHING_DURING_CTE_TRANSMISSION = 1 << LeFeature.ANTENNA_SWITCHING_DURING_CTE_TRANSMISSION 1225 ANTENNA_SWITCHING_DURING_CTE_RECEPTION = 1 << LeFeature.ANTENNA_SWITCHING_DURING_CTE_RECEPTION 1226 RECEIVING_CONSTANT_TONE_EXTENSIONS = 1 << LeFeature.RECEIVING_CONSTANT_TONE_EXTENSIONS 1227 PERIODIC_ADVERTISING_SYNC_TRANSFER_SENDER = 1 << LeFeature.PERIODIC_ADVERTISING_SYNC_TRANSFER_SENDER 1228 PERIODIC_ADVERTISING_SYNC_TRANSFER_RECIPIENT = 1 << LeFeature.PERIODIC_ADVERTISING_SYNC_TRANSFER_RECIPIENT 1229 SLEEP_CLOCK_ACCURACY_UPDATES = 1 << LeFeature.SLEEP_CLOCK_ACCURACY_UPDATES 1230 REMOTE_PUBLIC_KEY_VALIDATION = 1 << LeFeature.REMOTE_PUBLIC_KEY_VALIDATION 1231 CONNECTED_ISOCHRONOUS_STREAM_CENTRAL = 1 << LeFeature.CONNECTED_ISOCHRONOUS_STREAM_CENTRAL 1232 CONNECTED_ISOCHRONOUS_STREAM_PERIPHERAL = 1 << LeFeature.CONNECTED_ISOCHRONOUS_STREAM_PERIPHERAL 1233 ISOCHRONOUS_BROADCASTER = 1 << LeFeature.ISOCHRONOUS_BROADCASTER 1234 SYNCHRONIZED_RECEIVER = 1 << LeFeature.SYNCHRONIZED_RECEIVER 1235 CONNECTED_ISOCHRONOUS_STREAM = 1 << LeFeature.CONNECTED_ISOCHRONOUS_STREAM 1236 LE_POWER_CONTROL_REQUEST = 1 << LeFeature.LE_POWER_CONTROL_REQUEST 1237 LE_POWER_CONTROL_REQUEST_DUP = 1 << LeFeature.LE_POWER_CONTROL_REQUEST_DUP 1238 LE_PATH_LOSS_MONITORING = 1 << LeFeature.LE_PATH_LOSS_MONITORING 1239 PERIODIC_ADVERTISING_ADI_SUPPORT = 1 << LeFeature.PERIODIC_ADVERTISING_ADI_SUPPORT 1240 CONNECTION_SUBRATING = 1 << LeFeature.CONNECTION_SUBRATING 1241 CONNECTION_SUBRATING_HOST_SUPPORT = 1 << LeFeature.CONNECTION_SUBRATING_HOST_SUPPORT 1242 CHANNEL_CLASSIFICATION = 1 << LeFeature.CHANNEL_CLASSIFICATION 1243 ADVERTISING_CODING_SELECTION = 1 << LeFeature.ADVERTISING_CODING_SELECTION 1244 ADVERTISING_CODING_SELECTION_HOST_SUPPORT = 1 << LeFeature.ADVERTISING_CODING_SELECTION_HOST_SUPPORT 1245 DECISION_BASED_ADVERTISING_FILTERING = 1 << LeFeature.DECISION_BASED_ADVERTISING_FILTERING 1246 PERIODIC_ADVERTISING_WITH_RESPONSES_ADVERTISER = 1 << LeFeature.PERIODIC_ADVERTISING_WITH_RESPONSES_ADVERTISER 1247 PERIODIC_ADVERTISING_WITH_RESPONSES_SCANNER = 1 << LeFeature.PERIODIC_ADVERTISING_WITH_RESPONSES_SCANNER 1248 UNSEGMENTED_FRAMED_MODE = 1 << LeFeature.UNSEGMENTED_FRAMED_MODE 1249 CHANNEL_SOUNDING = 1 << LeFeature.CHANNEL_SOUNDING 1250 CHANNEL_SOUNDING_HOST_SUPPORT = 1 << LeFeature.CHANNEL_SOUNDING_HOST_SUPPORT 1251 CHANNEL_SOUNDING_TONE_QUALITY_INDICATION = 1 << LeFeature.CHANNEL_SOUNDING_TONE_QUALITY_INDICATION 1252 LL_EXTENDED_FEATURE_SET = 1 << LeFeature.LL_EXTENDED_FEATURE_SET 1253 MONITORING_ADVERTISERS = 1 << LeFeature.MONITORING_ADVERTISERS 1254 FRAME_SPACE_UPDATE = 1 << LeFeature.FRAME_SPACE_UPDATE 1255 1256class LmpFeature(enum.IntEnum): 1257 # Page 0 (Legacy LMP features) 1258 LMP_3_SLOT_PACKETS = 0 1259 LMP_5_SLOT_PACKETS = 1 1260 ENCRYPTION = 2 1261 SLOT_OFFSET = 3 1262 TIMING_ACCURACY = 4 1263 ROLE_SWITCH = 5 1264 HOLD_MODE = 6 1265 SNIFF_MODE = 7 1266 # PREVIOUSLY_USED = 8 1267 POWER_CONTROL_REQUESTS = 9 1268 CHANNEL_QUALITY_DRIVEN_DATA_RATE_CQDDR = 10 1269 SCO_LINK = 11 1270 HV2_PACKETS = 12 1271 HV3_PACKETS = 13 1272 U_LAW_LOG_SYNCHRONOUS_DATA = 14 1273 A_LAW_LOG_SYNCHRONOUS_DATA = 15 1274 CVSD_SYNCHRONOUS_DATA = 16 1275 PAGING_PARAMETER_NEGOTIATION = 17 1276 POWER_CONTROL = 18 1277 TRANSPARENT_SYNCHRONOUS_DATA = 19 1278 FLOW_CONTROL_LAG_LEAST_SIGNIFICANT_BIT = 20 1279 FLOW_CONTROL_LAG_MIDDLE_BIT = 21 1280 FLOW_CONTROL_LAG_MOST_SIGNIFICANT_BIT = 22 1281 BROADCAST_ENCRYPTION = 23 1282 # RESERVED_FOR_FUTURE_USE = 24 1283 ENHANCED_DATA_RATE_ACL_2_MBPS_MODE = 25 1284 ENHANCED_DATA_RATE_ACL_3_MBPS_MODE = 26 1285 ENHANCED_INQUIRY_SCAN = 27 1286 INTERLACED_INQUIRY_SCAN = 28 1287 INTERLACED_PAGE_SCAN = 29 1288 RSSI_WITH_INQUIRY_RESULTS = 30 1289 EXTENDED_SCO_LINK_EV3_PACKETS = 31 1290 EV4_PACKETS = 32 1291 EV5_PACKETS = 33 1292 # RESERVED_FOR_FUTURE_USE = 34 1293 AFH_CAPABLE_PERIPHERAL = 35 1294 AFH_CLASSIFICATION_PERIPHERAL = 36 1295 BR_EDR_NOT_SUPPORTED = 37 1296 LE_SUPPORTED_CONTROLLER = 38 1297 LMP_3_SLOT_ENHANCED_DATA_RATE_ACL_PACKETS = 39 1298 LMP_5_SLOT_ENHANCED_DATA_RATE_ACL_PACKETS = 40 1299 SNIFF_SUBRATING = 41 1300 PAUSE_ENCRYPTION = 42 1301 AFH_CAPABLE_CENTRAL = 43 1302 AFH_CLASSIFICATION_CENTRAL = 44 1303 ENHANCED_DATA_RATE_ESCO_2_MBPS_MODE = 45 1304 ENHANCED_DATA_RATE_ESCO_3_MBPS_MODE = 46 1305 LMP_3_SLOT_ENHANCED_DATA_RATE_ESCO_PACKETS = 47 1306 EXTENDED_INQUIRY_RESPONSE = 48 1307 SIMULTANEOUS_LE_AND_BR_EDR_TO_SAME_DEVICE_CAPABLE_CONTROLLER = 49 1308 # RESERVED_FOR_FUTURE_USE = 50 1309 SECURE_SIMPLE_PAIRING_CONTROLLER_SUPPORT = 51 1310 ENCAPSULATED_PDU = 52 1311 ERRONEOUS_DATA_REPORTING = 53 1312 NON_FLUSHABLE_PACKET_BOUNDARY_FLAG = 54 1313 # RESERVED_FOR_FUTURE_USE = 55 1314 HCI_LINK_SUPERVISION_TIMEOUT_CHANGED_EVENT = 56 1315 VARIABLE_INQUIRY_TX_POWER_LEVEL = 57 1316 ENHANCED_POWER_CONTROL = 58 1317 # RESERVED_FOR_FUTURE_USE = 59 1318 # RESERVED_FOR_FUTURE_USE = 60 1319 # RESERVED_FOR_FUTURE_USE = 61 1320 # RESERVED_FOR_FUTURE_USE = 62 1321 EXTENDED_FEATURES = 63 1322 1323 # Page 1 1324 SECURE_SIMPLE_PAIRING_HOST_SUPPORT = 64 1325 LE_SUPPORTED_HOST = 65 1326 # PREVIOUSLY_USED = 66 1327 SECURE_CONNECTIONS_HOST_SUPPORT = 67 1328 1329 # Page 2 1330 CONNECTIONLESS_PERIPHERAL_BROADCAST_TRANSMITTER_OPERATION = 128 1331 CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVER_OPERATION = 129 1332 SYNCHRONIZATION_TRAIN = 130 1333 SYNCHRONIZATION_SCAN = 131 1334 HCI_INQUIRY_RESPONSE_NOTIFICATION_EVENT = 132 1335 GENERALIZED_INTERLACED_SCAN = 133 1336 COARSE_CLOCK_ADJUSTMENT = 134 1337 RESERVED_FOR_FUTURE_USE = 135 1338 SECURE_CONNECTIONS_CONTROLLER_SUPPORT = 136 1339 PING = 137 1340 SLOT_AVAILABILITY_MASK = 138 1341 TRAIN_NUDGING = 139 1342 1343class LmpFeatureMask(enum.IntFlag): 1344 # Page 0 (Legacy LMP features) 1345 LMP_3_SLOT_PACKETS = (1 << LmpFeature.LMP_3_SLOT_PACKETS) 1346 LMP_5_SLOT_PACKETS = (1 << LmpFeature.LMP_5_SLOT_PACKETS) 1347 ENCRYPTION = (1 << LmpFeature.ENCRYPTION) 1348 SLOT_OFFSET = (1 << LmpFeature.SLOT_OFFSET) 1349 TIMING_ACCURACY = (1 << LmpFeature.TIMING_ACCURACY) 1350 ROLE_SWITCH = (1 << LmpFeature.ROLE_SWITCH) 1351 HOLD_MODE = (1 << LmpFeature.HOLD_MODE) 1352 SNIFF_MODE = (1 << LmpFeature.SNIFF_MODE) 1353 # PREVIOUSLY_USED = (1 << LmpFeature.PREVIOUSLY_USED) 1354 POWER_CONTROL_REQUESTS = (1 << LmpFeature.POWER_CONTROL_REQUESTS) 1355 CHANNEL_QUALITY_DRIVEN_DATA_RATE_CQDDR = (1 << LmpFeature.CHANNEL_QUALITY_DRIVEN_DATA_RATE_CQDDR) 1356 SCO_LINK = (1 << LmpFeature.SCO_LINK) 1357 HV2_PACKETS = (1 << LmpFeature.HV2_PACKETS) 1358 HV3_PACKETS = (1 << LmpFeature.HV3_PACKETS) 1359 U_LAW_LOG_SYNCHRONOUS_DATA = (1 << LmpFeature.U_LAW_LOG_SYNCHRONOUS_DATA) 1360 A_LAW_LOG_SYNCHRONOUS_DATA = (1 << LmpFeature.A_LAW_LOG_SYNCHRONOUS_DATA) 1361 CVSD_SYNCHRONOUS_DATA = (1 << LmpFeature.CVSD_SYNCHRONOUS_DATA) 1362 PAGING_PARAMETER_NEGOTIATION = (1 << LmpFeature.PAGING_PARAMETER_NEGOTIATION) 1363 POWER_CONTROL = (1 << LmpFeature.POWER_CONTROL) 1364 TRANSPARENT_SYNCHRONOUS_DATA = (1 << LmpFeature.TRANSPARENT_SYNCHRONOUS_DATA) 1365 FLOW_CONTROL_LAG_LEAST_SIGNIFICANT_BIT = (1 << LmpFeature.FLOW_CONTROL_LAG_LEAST_SIGNIFICANT_BIT) 1366 FLOW_CONTROL_LAG_MIDDLE_BIT = (1 << LmpFeature.FLOW_CONTROL_LAG_MIDDLE_BIT) 1367 FLOW_CONTROL_LAG_MOST_SIGNIFICANT_BIT = (1 << LmpFeature.FLOW_CONTROL_LAG_MOST_SIGNIFICANT_BIT) 1368 BROADCAST_ENCRYPTION = (1 << LmpFeature.BROADCAST_ENCRYPTION) 1369 # RESERVED_FOR_FUTURE_USE = (1 << LmpFeature.RESERVED_FOR_FUTURE_USE) 1370 ENHANCED_DATA_RATE_ACL_2_MBPS_MODE = (1 << LmpFeature.ENHANCED_DATA_RATE_ACL_2_MBPS_MODE) 1371 ENHANCED_DATA_RATE_ACL_3_MBPS_MODE = (1 << LmpFeature.ENHANCED_DATA_RATE_ACL_3_MBPS_MODE) 1372 ENHANCED_INQUIRY_SCAN = (1 << LmpFeature.ENHANCED_INQUIRY_SCAN) 1373 INTERLACED_INQUIRY_SCAN = (1 << LmpFeature.INTERLACED_INQUIRY_SCAN) 1374 INTERLACED_PAGE_SCAN = (1 << LmpFeature.INTERLACED_PAGE_SCAN) 1375 RSSI_WITH_INQUIRY_RESULTS = (1 << LmpFeature.RSSI_WITH_INQUIRY_RESULTS) 1376 EXTENDED_SCO_LINK_EV3_PACKETS = (1 << LmpFeature.EXTENDED_SCO_LINK_EV3_PACKETS) 1377 EV4_PACKETS = (1 << LmpFeature.EV4_PACKETS) 1378 EV5_PACKETS = (1 << LmpFeature.EV5_PACKETS) 1379 # RESERVED_FOR_FUTURE_USE = (1 << LmpFeature.RESERVED_FOR_FUTURE_USE) 1380 AFH_CAPABLE_PERIPHERAL = (1 << LmpFeature.AFH_CAPABLE_PERIPHERAL) 1381 AFH_CLASSIFICATION_PERIPHERAL = (1 << LmpFeature.AFH_CLASSIFICATION_PERIPHERAL) 1382 BR_EDR_NOT_SUPPORTED = (1 << LmpFeature.BR_EDR_NOT_SUPPORTED) 1383 LE_SUPPORTED_CONTROLLER = (1 << LmpFeature.LE_SUPPORTED_CONTROLLER) 1384 LMP_3_SLOT_ENHANCED_DATA_RATE_ACL_PACKETS = (1 << LmpFeature.LMP_3_SLOT_ENHANCED_DATA_RATE_ACL_PACKETS) 1385 LMP_5_SLOT_ENHANCED_DATA_RATE_ACL_PACKETS = (1 << LmpFeature.LMP_5_SLOT_ENHANCED_DATA_RATE_ACL_PACKETS) 1386 SNIFF_SUBRATING = (1 << LmpFeature.SNIFF_SUBRATING) 1387 PAUSE_ENCRYPTION = (1 << LmpFeature.PAUSE_ENCRYPTION) 1388 AFH_CAPABLE_CENTRAL = (1 << LmpFeature.AFH_CAPABLE_CENTRAL) 1389 AFH_CLASSIFICATION_CENTRAL = (1 << LmpFeature.AFH_CLASSIFICATION_CENTRAL) 1390 ENHANCED_DATA_RATE_ESCO_2_MBPS_MODE = (1 << LmpFeature.ENHANCED_DATA_RATE_ESCO_2_MBPS_MODE) 1391 ENHANCED_DATA_RATE_ESCO_3_MBPS_MODE = (1 << LmpFeature.ENHANCED_DATA_RATE_ESCO_3_MBPS_MODE) 1392 LMP_3_SLOT_ENHANCED_DATA_RATE_ESCO_PACKETS = (1 << LmpFeature.LMP_3_SLOT_ENHANCED_DATA_RATE_ESCO_PACKETS) 1393 EXTENDED_INQUIRY_RESPONSE = (1 << LmpFeature.EXTENDED_INQUIRY_RESPONSE) 1394 SIMULTANEOUS_LE_AND_BR_EDR_TO_SAME_DEVICE_CAPABLE_CONTROLLER = (1 << LmpFeature.SIMULTANEOUS_LE_AND_BR_EDR_TO_SAME_DEVICE_CAPABLE_CONTROLLER) 1395 # RESERVED_FOR_FUTURE_USE = (1 << LmpFeature.RESERVED_FOR_FUTURE_USE) 1396 SECURE_SIMPLE_PAIRING_CONTROLLER_SUPPORT = (1 << LmpFeature.SECURE_SIMPLE_PAIRING_CONTROLLER_SUPPORT) 1397 ENCAPSULATED_PDU = (1 << LmpFeature.ENCAPSULATED_PDU) 1398 ERRONEOUS_DATA_REPORTING = (1 << LmpFeature.ERRONEOUS_DATA_REPORTING) 1399 NON_FLUSHABLE_PACKET_BOUNDARY_FLAG = (1 << LmpFeature.NON_FLUSHABLE_PACKET_BOUNDARY_FLAG) 1400 # RESERVED_FOR_FUTURE_USE = (1 << LmpFeature.RESERVED_FOR_FUTURE_USE) 1401 HCI_LINK_SUPERVISION_TIMEOUT_CHANGED_EVENT = (1 << LmpFeature.HCI_LINK_SUPERVISION_TIMEOUT_CHANGED_EVENT) 1402 VARIABLE_INQUIRY_TX_POWER_LEVEL = (1 << LmpFeature.VARIABLE_INQUIRY_TX_POWER_LEVEL) 1403 ENHANCED_POWER_CONTROL = (1 << LmpFeature.ENHANCED_POWER_CONTROL) 1404 # RESERVED_FOR_FUTURE_USE = (1 << LmpFeature.RESERVED_FOR_FUTURE_USE) 1405 # RESERVED_FOR_FUTURE_USE = (1 << LmpFeature.RESERVED_FOR_FUTURE_USE) 1406 # RESERVED_FOR_FUTURE_USE = (1 << LmpFeature.RESERVED_FOR_FUTURE_USE) 1407 # RESERVED_FOR_FUTURE_USE = (1 << LmpFeature.RESERVED_FOR_FUTURE_USE) 1408 EXTENDED_FEATURES = (1 << LmpFeature.EXTENDED_FEATURES) 1409 1410 # Page 1 1411 SECURE_SIMPLE_PAIRING_HOST_SUPPORT = (1 << LmpFeature.SECURE_SIMPLE_PAIRING_HOST_SUPPORT) 1412 LE_SUPPORTED_HOST = (1 << LmpFeature.LE_SUPPORTED_HOST) 1413 # PREVIOUSLY_USED = (1 << LmpFeature.PREVIOUSLY_USED) 1414 SECURE_CONNECTIONS_HOST_SUPPORT = (1 << LmpFeature.SECURE_CONNECTIONS_HOST_SUPPORT) 1415 1416 # Page 2 1417 CONNECTIONLESS_PERIPHERAL_BROADCAST_TRANSMITTER_OPERATION = (1 << LmpFeature.CONNECTIONLESS_PERIPHERAL_BROADCAST_TRANSMITTER_OPERATION) 1418 CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVER_OPERATION = (1 << LmpFeature.CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVER_OPERATION) 1419 SYNCHRONIZATION_TRAIN = (1 << LmpFeature.SYNCHRONIZATION_TRAIN) 1420 SYNCHRONIZATION_SCAN = (1 << LmpFeature.SYNCHRONIZATION_SCAN) 1421 HCI_INQUIRY_RESPONSE_NOTIFICATION_EVENT = (1 << LmpFeature.HCI_INQUIRY_RESPONSE_NOTIFICATION_EVENT) 1422 GENERALIZED_INTERLACED_SCAN = (1 << LmpFeature.GENERALIZED_INTERLACED_SCAN) 1423 COARSE_CLOCK_ADJUSTMENT = (1 << LmpFeature.COARSE_CLOCK_ADJUSTMENT) 1424 RESERVED_FOR_FUTURE_USE = (1 << LmpFeature.RESERVED_FOR_FUTURE_USE) 1425 SECURE_CONNECTIONS_CONTROLLER_SUPPORT = (1 << LmpFeature.SECURE_CONNECTIONS_CONTROLLER_SUPPORT) 1426 PING = (1 << LmpFeature.PING) 1427 SLOT_AVAILABILITY_MASK = (1 << LmpFeature.SLOT_AVAILABILITY_MASK) 1428 TRAIN_NUDGING = (1 << LmpFeature.TRAIN_NUDGING) 1429 1430 1431# fmt: on 1432# pylint: enable=line-too-long 1433# pylint: disable=invalid-name 1434 1435# ----------------------------------------------------------------------------- 1436# pylint: disable-next=unnecessary-lambda 1437STATUS_SPEC = {'size': 1, 'mapper': lambda x: HCI_Constant.status_name(x)} 1438 1439 1440class CodecID(OpenIntEnum): 1441 # fmt: off 1442 U_LOG = 0x00 1443 A_LOG = 0x01 1444 CVSD = 0x02 1445 TRANSPARENT = 0x03 1446 LINEAR_PCM = 0x04 1447 MSBC = 0x05 1448 LC3 = 0x06 1449 G729A = 0x07 1450 VENDOR_SPECIFIC = 0xFF 1451 1452 1453@dataclasses.dataclass(frozen=True) 1454class CodingFormat: 1455 codec_id: CodecID 1456 company_id: int = 0 1457 vendor_specific_codec_id: int = 0 1458 1459 @classmethod 1460 def parse_from_bytes(cls, data: bytes, offset: int): 1461 (codec_id, company_id, vendor_specific_codec_id) = struct.unpack_from( 1462 '<BHH', data, offset 1463 ) 1464 return offset + 5, cls( 1465 codec_id=CodecID(codec_id), 1466 company_id=company_id, 1467 vendor_specific_codec_id=vendor_specific_codec_id, 1468 ) 1469 1470 def to_bytes(self) -> bytes: 1471 return struct.pack( 1472 '<BHH', self.codec_id, self.company_id, self.vendor_specific_codec_id 1473 ) 1474 1475 def __bytes__(self) -> bytes: 1476 return self.to_bytes() 1477 1478 1479# ----------------------------------------------------------------------------- 1480class HCI_Constant: 1481 @staticmethod 1482 def status_name(status): 1483 return HCI_ERROR_NAMES.get(status, f'0x{status:02X}') 1484 1485 @staticmethod 1486 def error_name(status): 1487 return HCI_ERROR_NAMES.get(status, f'0x{status:02X}') 1488 1489 @staticmethod 1490 def role_name(role): 1491 return HCI_ROLE_NAMES.get(role, str(role)) 1492 1493 @staticmethod 1494 def le_phy_name(phy): 1495 return HCI_LE_PHY_NAMES.get(phy, str(phy)) 1496 1497 @staticmethod 1498 def inquiry_lap_name(lap): 1499 return HCI_INQUIRY_LAP_NAMES.get(lap, f'0x{lap:06X}') 1500 1501 @staticmethod 1502 def io_capability_name(io_capability): 1503 return HCI_IO_CAPABILITY_NAMES.get(io_capability, f'0x{io_capability:02X}') 1504 1505 @staticmethod 1506 def authentication_requirements_name(authentication_requirements): 1507 return HCI_AUTHENTICATION_REQUIREMENTS_NAMES.get( 1508 authentication_requirements, f'0x{authentication_requirements:02X}' 1509 ) 1510 1511 @staticmethod 1512 def link_key_type_name(link_key_type): 1513 return HCI_LINK_TYPE_NAMES.get(link_key_type, f'0x{link_key_type:02X}') 1514 1515 1516# ----------------------------------------------------------------------------- 1517class HCI_Error(ProtocolError): 1518 def __init__(self, error_code): 1519 super().__init__( 1520 error_code, 1521 error_namespace='hci', 1522 error_name=HCI_Constant.error_name(error_code), 1523 ) 1524 1525 1526# ----------------------------------------------------------------------------- 1527class HCI_StatusError(ProtocolError): 1528 def __init__(self, response): 1529 super().__init__( 1530 response.status, 1531 error_namespace=HCI_Command.command_name(response.command_opcode), 1532 error_name=HCI_Constant.status_name(response.status), 1533 ) 1534 1535 1536# ----------------------------------------------------------------------------- 1537# Generic HCI object 1538# ----------------------------------------------------------------------------- 1539class HCI_Object: 1540 @staticmethod 1541 def init_from_fields(hci_object, fields, values): 1542 if isinstance(values, dict): 1543 for field in fields: 1544 if isinstance(field, list): 1545 # The field is an array, up-level the array field names 1546 for sub_field_name, _ in field: 1547 setattr(hci_object, sub_field_name, values[sub_field_name]) 1548 else: 1549 field_name = field[0] 1550 setattr(hci_object, field_name, values[field_name]) 1551 else: 1552 for field_name, field_value in zip(fields, values): 1553 setattr(hci_object, field_name, field_value) 1554 1555 @staticmethod 1556 def init_from_bytes(hci_object, data, offset, fields): 1557 parsed = HCI_Object.dict_from_bytes(data, offset, fields) 1558 HCI_Object.init_from_fields(hci_object, parsed.keys(), parsed.values()) 1559 1560 @staticmethod 1561 def parse_field(data, offset, field_type): 1562 # The field_type may be a dictionary with a mapper, parser, and/or size 1563 if isinstance(field_type, dict): 1564 if 'size' in field_type: 1565 field_type = field_type['size'] 1566 elif 'parser' in field_type: 1567 field_type = field_type['parser'] 1568 1569 # Parse the field 1570 if field_type == '*': 1571 # The rest of the bytes 1572 field_value = data[offset:] 1573 return (field_value, len(field_value)) 1574 if field_type == 'v': 1575 # Variable-length bytes field, with 1-byte length at the beginning 1576 field_length = data[offset] 1577 offset += 1 1578 field_value = data[offset : offset + field_length] 1579 return (field_value, field_length + 1) 1580 if field_type == 1: 1581 # 8-bit unsigned 1582 return (data[offset], 1) 1583 if field_type == -1: 1584 # 8-bit signed 1585 return (struct.unpack_from('b', data, offset)[0], 1) 1586 if field_type == 2: 1587 # 16-bit unsigned 1588 return (struct.unpack_from('<H', data, offset)[0], 2) 1589 if field_type == '>2': 1590 # 16-bit unsigned big-endian 1591 return (struct.unpack_from('>H', data, offset)[0], 2) 1592 if field_type == -2: 1593 # 16-bit signed 1594 return (struct.unpack_from('<h', data, offset)[0], 2) 1595 if field_type == 3: 1596 # 24-bit unsigned 1597 padded = data[offset : offset + 3] + bytes([0]) 1598 return (struct.unpack('<I', padded)[0], 3) 1599 if field_type == 4: 1600 # 32-bit unsigned 1601 return (struct.unpack_from('<I', data, offset)[0], 4) 1602 if field_type == '>4': 1603 # 32-bit unsigned big-endian 1604 return (struct.unpack_from('>I', data, offset)[0], 4) 1605 if isinstance(field_type, int) and 4 < field_type <= 256: 1606 # Byte array (from 5 up to 256 bytes) 1607 return (data[offset : offset + field_type], field_type) 1608 if callable(field_type): 1609 new_offset, field_value = field_type(data, offset) 1610 return (field_value, new_offset - offset) 1611 1612 raise InvalidArgumentError(f'unknown field type {field_type}') 1613 1614 @staticmethod 1615 def dict_from_bytes(data, offset, fields): 1616 result = collections.OrderedDict() 1617 for field in fields: 1618 if isinstance(field, list): 1619 # This is an array field, starting with a 1-byte item count. 1620 item_count = data[offset] 1621 offset += 1 1622 # Set fields first, because item_count might be 0. 1623 for sub_field_name, _ in field: 1624 result[sub_field_name] = [] 1625 1626 for _ in range(item_count): 1627 for sub_field_name, sub_field_type in field: 1628 value, size = HCI_Object.parse_field( 1629 data, offset, sub_field_type 1630 ) 1631 result[sub_field_name].append(value) 1632 offset += size 1633 continue 1634 1635 field_name, field_type = field 1636 field_value, field_size = HCI_Object.parse_field(data, offset, field_type) 1637 result[field_name] = field_value 1638 offset += field_size 1639 1640 return result 1641 1642 @staticmethod 1643 def serialize_field(field_value, field_type): 1644 # The field_type may be a dictionary with a mapper, parser, serializer, 1645 # and/or size 1646 serializer = None 1647 if isinstance(field_type, dict): 1648 if 'serializer' in field_type: 1649 serializer = field_type['serializer'] 1650 if 'size' in field_type: 1651 field_type = field_type['size'] 1652 1653 # Serialize the field 1654 if serializer: 1655 field_bytes = serializer(field_value) 1656 elif field_type == 1: 1657 # 8-bit unsigned 1658 field_bytes = bytes([field_value]) 1659 elif field_type == -1: 1660 # 8-bit signed 1661 field_bytes = struct.pack('b', field_value) 1662 elif field_type == 2: 1663 # 16-bit unsigned 1664 field_bytes = struct.pack('<H', field_value) 1665 elif field_type == '>2': 1666 # 16-bit unsigned big-endian 1667 field_bytes = struct.pack('>H', field_value) 1668 elif field_type == -2: 1669 # 16-bit signed 1670 field_bytes = struct.pack('<h', field_value) 1671 elif field_type == 3: 1672 # 24-bit unsigned 1673 field_bytes = struct.pack('<I', field_value)[0:3] 1674 elif field_type == 4: 1675 # 32-bit unsigned 1676 field_bytes = struct.pack('<I', field_value) 1677 elif field_type == '>4': 1678 # 32-bit unsigned big-endian 1679 field_bytes = struct.pack('>I', field_value) 1680 elif field_type == '*': 1681 if isinstance(field_value, int): 1682 if 0 <= field_value <= 255: 1683 field_bytes = bytes([field_value]) 1684 else: 1685 raise InvalidArgumentError('value too large for *-typed field') 1686 else: 1687 field_bytes = bytes(field_value) 1688 elif field_type == 'v': 1689 # Variable-length bytes field, with 1-byte length at the beginning 1690 field_bytes = bytes(field_value) 1691 field_length = len(field_bytes) 1692 field_bytes = bytes([field_length]) + field_bytes 1693 elif isinstance(field_value, (bytes, bytearray)) or hasattr( 1694 field_value, 'to_bytes' 1695 ): 1696 field_bytes = bytes(field_value) 1697 if isinstance(field_type, int) and 4 < field_type <= 256: 1698 # Truncate or pad with zeros if the field is too long or too short 1699 if len(field_bytes) < field_type: 1700 field_bytes += bytes(field_type - len(field_bytes)) 1701 elif len(field_bytes) > field_type: 1702 field_bytes = field_bytes[:field_type] 1703 else: 1704 raise InvalidArgumentError( 1705 f"don't know how to serialize type {type(field_value)}" 1706 ) 1707 1708 return field_bytes 1709 1710 @staticmethod 1711 def dict_to_bytes(hci_object, fields): 1712 result = bytearray() 1713 for field in fields: 1714 if isinstance(field, list): 1715 # The field is an array. The serialized form starts with a 1-byte 1716 # item count. We use the length of the first array field as the 1717 # array count, since all array fields have the same number of items. 1718 item_count = len(hci_object[field[0][0]]) 1719 result += bytes([item_count]) + b''.join( 1720 b''.join( 1721 HCI_Object.serialize_field( 1722 hci_object[sub_field_name][i], sub_field_type 1723 ) 1724 for sub_field_name, sub_field_type in field 1725 ) 1726 for i in range(item_count) 1727 ) 1728 continue 1729 1730 (field_name, field_type) = field 1731 result += HCI_Object.serialize_field(hci_object[field_name], field_type) 1732 1733 return bytes(result) 1734 1735 @classmethod 1736 def from_bytes(cls, data, offset, fields): 1737 return cls(fields, **cls.dict_from_bytes(data, offset, fields)) 1738 1739 def to_bytes(self): 1740 return HCI_Object.dict_to_bytes(self.__dict__, self.fields) 1741 1742 @staticmethod 1743 def parse_length_prefixed_bytes(data, offset): 1744 length = data[offset] 1745 return offset + 1 + length, data[offset + 1 : offset + 1 + length] 1746 1747 @staticmethod 1748 def serialize_length_prefixed_bytes(data, padded_size=0): 1749 prefixed_size = 1 + len(data) 1750 padding = ( 1751 bytes(padded_size - prefixed_size) if prefixed_size < padded_size else b'' 1752 ) 1753 return bytes([len(data)]) + data + padding 1754 1755 @staticmethod 1756 def format_field_value(value, indentation): 1757 if isinstance(value, bytes): 1758 return value.hex() 1759 1760 if isinstance(value, HCI_Object): 1761 return '\n' + value.to_string(indentation) 1762 1763 return str(value) 1764 1765 @staticmethod 1766 def stringify_field( 1767 field_name, field_type, field_value, indentation, value_mappers 1768 ): 1769 value_mapper = None 1770 if isinstance(field_type, dict): 1771 # Get the value mapper from the specifier 1772 value_mapper = field_type.get('mapper') 1773 1774 # Check if there's a matching mapper passed 1775 if value_mappers: 1776 value_mapper = value_mappers.get(field_name, value_mapper) 1777 1778 # Map the value if we have a mapper 1779 if value_mapper is not None: 1780 field_value = value_mapper(field_value) 1781 1782 # Get the string representation of the value 1783 return HCI_Object.format_field_value( 1784 field_value, indentation=indentation + ' ' 1785 ) 1786 1787 @staticmethod 1788 def format_fields(hci_object, fields, indentation='', value_mappers=None): 1789 if not fields: 1790 return '' 1791 1792 # Build array of formatted key:value pairs 1793 field_strings = [] 1794 for field in fields: 1795 if isinstance(field, list): 1796 for sub_field in field: 1797 sub_field_name, sub_field_type = sub_field 1798 item_count = len(hci_object[sub_field_name]) 1799 for i in range(item_count): 1800 field_strings.append( 1801 ( 1802 f'{sub_field_name}[{i}]', 1803 HCI_Object.stringify_field( 1804 sub_field_name, 1805 sub_field_type, 1806 hci_object[sub_field_name][i], 1807 indentation, 1808 value_mappers, 1809 ), 1810 ), 1811 ) 1812 continue 1813 1814 field_name, field_type = field 1815 field_value = hci_object[field_name] 1816 field_strings.append( 1817 ( 1818 field_name, 1819 HCI_Object.stringify_field( 1820 field_name, field_type, field_value, indentation, value_mappers 1821 ), 1822 ), 1823 ) 1824 1825 # Measure the widest field name 1826 max_field_name_length = max(len(s[0]) for s in field_strings) 1827 sep = ':' 1828 return '\n'.join( 1829 f'{indentation}' 1830 f'{color(f"{field_name + sep:{1 + max_field_name_length}}", "cyan")} {field_value}' 1831 for field_name, field_value in field_strings 1832 ) 1833 1834 def __bytes__(self): 1835 return self.to_bytes() 1836 1837 def __init__(self, fields, **kwargs): 1838 self.fields = fields 1839 self.init_from_fields(self, fields, kwargs) 1840 1841 def to_string(self, indentation='', value_mappers=None): 1842 return HCI_Object.format_fields( 1843 self.__dict__, self.fields, indentation, value_mappers 1844 ) 1845 1846 def __str__(self): 1847 return self.to_string() 1848 1849 1850# ----------------------------------------------------------------------------- 1851# Bluetooth Address 1852# ----------------------------------------------------------------------------- 1853class Address: 1854 ''' 1855 Bluetooth Address (see Bluetooth spec Vol 6, Part B - 1.3 DEVICE ADDRESS) 1856 NOTE: the address bytes are stored in little-endian byte order here, so 1857 address[0] is the LSB of the address, address[5] is the MSB. 1858 ''' 1859 1860 PUBLIC_DEVICE_ADDRESS = 0x00 1861 RANDOM_DEVICE_ADDRESS = 0x01 1862 PUBLIC_IDENTITY_ADDRESS = 0x02 1863 RANDOM_IDENTITY_ADDRESS = 0x03 1864 1865 ADDRESS_TYPE_NAMES = { 1866 PUBLIC_DEVICE_ADDRESS: 'PUBLIC_DEVICE_ADDRESS', 1867 RANDOM_DEVICE_ADDRESS: 'RANDOM_DEVICE_ADDRESS', 1868 PUBLIC_IDENTITY_ADDRESS: 'PUBLIC_IDENTITY_ADDRESS', 1869 RANDOM_IDENTITY_ADDRESS: 'RANDOM_IDENTITY_ADDRESS', 1870 } 1871 1872 # Type declarations 1873 NIL: Address 1874 ANY: Address 1875 ANY_RANDOM: Address 1876 1877 # pylint: disable-next=unnecessary-lambda 1878 ADDRESS_TYPE_SPEC = {'size': 1, 'mapper': lambda x: Address.address_type_name(x)} 1879 1880 @staticmethod 1881 def address_type_name(address_type): 1882 return name_or_number(Address.ADDRESS_TYPE_NAMES, address_type) 1883 1884 @staticmethod 1885 def from_string_for_transport(string, transport): 1886 if transport == BT_BR_EDR_TRANSPORT: 1887 address_type = Address.PUBLIC_DEVICE_ADDRESS 1888 else: 1889 address_type = Address.RANDOM_DEVICE_ADDRESS 1890 return Address(string, address_type) 1891 1892 @staticmethod 1893 def parse_address(data, offset): 1894 # Fix the type to a default value. This is used for parsing type-less Classic 1895 # addresses 1896 return Address.parse_address_with_type( 1897 data, offset, Address.PUBLIC_DEVICE_ADDRESS 1898 ) 1899 1900 @staticmethod 1901 def parse_random_address(data, offset): 1902 return Address.parse_address_with_type( 1903 data, offset, Address.RANDOM_DEVICE_ADDRESS 1904 ) 1905 1906 @staticmethod 1907 def parse_address_with_type(data, offset, address_type): 1908 return offset + 6, Address(data[offset : offset + 6], address_type) 1909 1910 @staticmethod 1911 def parse_address_preceded_by_type(data, offset): 1912 address_type = data[offset - 1] 1913 return Address.parse_address_with_type(data, offset, address_type) 1914 1915 @classmethod 1916 def generate_static_address(cls) -> Address: 1917 '''Generates Random Static Address, with the 2 most significant bits of 0b11. 1918 1919 See Bluetooth spec, Vol 6, Part B - Table 1.2. 1920 ''' 1921 address_bytes = secrets.token_bytes(6) 1922 address_bytes = address_bytes[:5] + bytes([address_bytes[5] | 0b11000000]) 1923 return Address( 1924 address=address_bytes, address_type=Address.RANDOM_DEVICE_ADDRESS 1925 ) 1926 1927 @classmethod 1928 def generate_private_address(cls, irk: bytes = b'') -> Address: 1929 '''Generates Random Private MAC Address. 1930 1931 If IRK is present, a Resolvable Private Address, with the 2 most significant 1932 bits of 0b01 will be generated. Otherwise, a Non-resolvable Private Address, 1933 with the 2 most significant bits of 0b00 will be generated. 1934 1935 See Bluetooth spec, Vol 6, Part B - Table 1.2. 1936 1937 Args: 1938 irk: Local Identity Resolving Key(IRK), in little-endian. If not set, a 1939 non-resolvable address will be generated. 1940 ''' 1941 if irk: 1942 prand = crypto.generate_prand() 1943 address_bytes = crypto.ah(irk, prand) + prand 1944 else: 1945 address_bytes = secrets.token_bytes(6) 1946 address_bytes = address_bytes[:5] + bytes([address_bytes[5] & 0b00111111]) 1947 1948 return Address( 1949 address=address_bytes, address_type=Address.RANDOM_DEVICE_ADDRESS 1950 ) 1951 1952 def __init__( 1953 self, address: Union[bytes, str], address_type: int = RANDOM_DEVICE_ADDRESS 1954 ): 1955 ''' 1956 Initialize an instance. `address` may be a byte array in little-endian 1957 format, or a hex string in big-endian format (with optional ':' 1958 separators between the bytes). 1959 If the address is a string suffixed with '/P', `address_type` is ignored and 1960 the type is set to PUBLIC_DEVICE_ADDRESS. 1961 ''' 1962 if isinstance(address, bytes): 1963 self.address_bytes = address 1964 else: 1965 # Check if there's a '/P' type specifier 1966 if address.endswith('P'): 1967 address_type = Address.PUBLIC_DEVICE_ADDRESS 1968 address = address[:-2] 1969 1970 if len(address) == 12 + 5: 1971 # Form with ':' separators 1972 address = address.replace(':', '') 1973 self.address_bytes = bytes(reversed(bytes.fromhex(address))) 1974 1975 if len(self.address_bytes) != 6: 1976 raise InvalidArgumentError('invalid address length') 1977 1978 self.address_type = address_type 1979 1980 def clone(self): 1981 return Address(self.address_bytes, self.address_type) 1982 1983 @property 1984 def is_public(self): 1985 return self.address_type in ( 1986 self.PUBLIC_DEVICE_ADDRESS, 1987 self.PUBLIC_IDENTITY_ADDRESS, 1988 ) 1989 1990 @property 1991 def is_random(self): 1992 return not self.is_public 1993 1994 @property 1995 def is_resolved(self): 1996 return self.address_type in ( 1997 self.PUBLIC_IDENTITY_ADDRESS, 1998 self.RANDOM_IDENTITY_ADDRESS, 1999 ) 2000 2001 @property 2002 def is_resolvable(self): 2003 return self.address_type == self.RANDOM_DEVICE_ADDRESS and ( 2004 self.address_bytes[5] >> 6 == 1 2005 ) 2006 2007 @property 2008 def is_static(self): 2009 return self.is_random and (self.address_bytes[5] >> 6 == 3) 2010 2011 def to_bytes(self): 2012 return self.address_bytes 2013 2014 def to_string(self, with_type_qualifier=True): 2015 ''' 2016 String representation of the address, MSB first, with an optional type 2017 qualifier. 2018 ''' 2019 result = ':'.join([f'{x:02X}' for x in reversed(self.address_bytes)]) 2020 if not with_type_qualifier or not self.is_public: 2021 return result 2022 return result + '/P' 2023 2024 def __bytes__(self): 2025 return self.to_bytes() 2026 2027 def __hash__(self): 2028 return hash(self.address_bytes) 2029 2030 def __eq__(self, other): 2031 return ( 2032 isinstance(other, Address) 2033 and self.address_bytes == other.address_bytes 2034 and self.is_public == other.is_public 2035 ) 2036 2037 def __str__(self): 2038 return self.to_string() 2039 2040 def __repr__(self): 2041 return f'Address({self.to_string(False)}/{self.address_type_name(self.address_type)})' 2042 2043 2044# Predefined address values 2045Address.NIL = Address(b"\xff\xff\xff\xff\xff\xff", Address.PUBLIC_DEVICE_ADDRESS) 2046Address.ANY = Address(b"\x00\x00\x00\x00\x00\x00", Address.PUBLIC_DEVICE_ADDRESS) 2047Address.ANY_RANDOM = Address(b"\x00\x00\x00\x00\x00\x00", Address.RANDOM_DEVICE_ADDRESS) 2048 2049 2050# ----------------------------------------------------------------------------- 2051class OwnAddressType(enum.IntEnum): 2052 PUBLIC = 0 2053 RANDOM = 1 2054 RESOLVABLE_OR_PUBLIC = 2 2055 RESOLVABLE_OR_RANDOM = 3 2056 2057 @classmethod 2058 def type_spec(cls): 2059 return {'size': 1, 'mapper': lambda x: OwnAddressType(x).name} 2060 2061 2062# ----------------------------------------------------------------------------- 2063class LoopbackMode(enum.IntEnum): 2064 DISABLED = 0 2065 LOCAL = 1 2066 REMOTE = 2 2067 2068 @classmethod 2069 def type_spec(cls): 2070 return {'size': 1, 'mapper': lambda x: LoopbackMode(x).name} 2071 2072 2073# ----------------------------------------------------------------------------- 2074class HCI_Packet: 2075 ''' 2076 Abstract Base class for HCI packets 2077 ''' 2078 2079 hci_packet_type: ClassVar[int] 2080 2081 @staticmethod 2082 def from_bytes(packet: bytes) -> HCI_Packet: 2083 packet_type = packet[0] 2084 2085 if packet_type == HCI_COMMAND_PACKET: 2086 return HCI_Command.from_bytes(packet) 2087 2088 if packet_type == HCI_ACL_DATA_PACKET: 2089 return HCI_AclDataPacket.from_bytes(packet) 2090 2091 if packet_type == HCI_SYNCHRONOUS_DATA_PACKET: 2092 return HCI_SynchronousDataPacket.from_bytes(packet) 2093 2094 if packet_type == HCI_EVENT_PACKET: 2095 return HCI_Event.from_bytes(packet) 2096 2097 if packet_type == HCI_ISO_DATA_PACKET: 2098 return HCI_IsoDataPacket.from_bytes(packet) 2099 2100 return HCI_CustomPacket(packet) 2101 2102 def __init__(self, name): 2103 self.name = name 2104 2105 def __bytes__(self) -> bytes: 2106 raise NotImplementedError 2107 2108 def __repr__(self) -> str: 2109 return self.name 2110 2111 2112# ----------------------------------------------------------------------------- 2113class HCI_CustomPacket(HCI_Packet): 2114 def __init__(self, payload): 2115 super().__init__('HCI_CUSTOM_PACKET') 2116 self.hci_packet_type = payload[0] 2117 self.payload = payload 2118 2119 def __bytes__(self) -> bytes: 2120 return self.payload 2121 2122 2123# ----------------------------------------------------------------------------- 2124class HCI_Command(HCI_Packet): 2125 ''' 2126 See Bluetooth spec @ Vol 2, Part E - 5.4.1 HCI Command Packet 2127 ''' 2128 2129 hci_packet_type = HCI_COMMAND_PACKET 2130 command_names: Dict[int, str] = {} 2131 command_classes: Dict[int, Type[HCI_Command]] = {} 2132 op_code: int 2133 2134 @staticmethod 2135 def command(fields=(), return_parameters_fields=()): 2136 ''' 2137 Decorator used to declare and register subclasses 2138 ''' 2139 2140 def inner(cls): 2141 cls.name = cls.__name__.upper() 2142 cls.op_code = key_with_value(cls.command_names, cls.name) 2143 if cls.op_code is None: 2144 raise KeyError(f'command {cls.name} not found in command_names') 2145 cls.fields = fields 2146 cls.return_parameters_fields = return_parameters_fields 2147 2148 # Patch the __init__ method to fix the op_code 2149 if fields is not None: 2150 2151 def init(self, parameters=None, **kwargs): 2152 return HCI_Command.__init__(self, cls.op_code, parameters, **kwargs) 2153 2154 cls.__init__ = init 2155 2156 # Register a factory for this class 2157 HCI_Command.command_classes[cls.op_code] = cls 2158 2159 return cls 2160 2161 return inner 2162 2163 @staticmethod 2164 def command_map(symbols: Dict[str, Any]) -> Dict[int, str]: 2165 return { 2166 command_code: command_name 2167 for (command_name, command_code) in symbols.items() 2168 if command_name.startswith('HCI_') and command_name.endswith('_COMMAND') 2169 } 2170 2171 @classmethod 2172 def register_commands(cls, symbols: Dict[str, Any]) -> None: 2173 cls.command_names.update(cls.command_map(symbols)) 2174 2175 @staticmethod 2176 def from_bytes(packet: bytes) -> HCI_Command: 2177 op_code, length = struct.unpack_from('<HB', packet, 1) 2178 parameters = packet[4:] 2179 if len(parameters) != length: 2180 raise InvalidPacketError('invalid packet length') 2181 2182 # Look for a registered class 2183 cls = HCI_Command.command_classes.get(op_code) 2184 if cls is None: 2185 # No class registered, just use a generic instance 2186 return HCI_Command(op_code, parameters) 2187 2188 # Create a new instance 2189 if (fields := getattr(cls, 'fields', None)) is not None: 2190 self = cls.__new__(cls) 2191 HCI_Command.__init__(self, op_code, parameters) 2192 HCI_Object.init_from_bytes(self, parameters, 0, fields) 2193 return self 2194 2195 return cls.from_parameters(parameters) # type: ignore 2196 2197 @staticmethod 2198 def command_name(op_code): 2199 name = HCI_Command.command_names.get(op_code) 2200 if name is not None: 2201 return name 2202 return f'[OGF=0x{op_code >> 10:02x}, OCF=0x{op_code & 0x3FF:04x}]' 2203 2204 @classmethod 2205 def create_return_parameters(cls, **kwargs): 2206 return HCI_Object(cls.return_parameters_fields, **kwargs) 2207 2208 @classmethod 2209 def parse_return_parameters(cls, parameters): 2210 if not cls.return_parameters_fields: 2211 return None 2212 return_parameters = HCI_Object.from_bytes( 2213 parameters, 0, cls.return_parameters_fields 2214 ) 2215 return_parameters.fields = cls.return_parameters_fields 2216 return return_parameters 2217 2218 def __init__(self, op_code=-1, parameters=None, **kwargs): 2219 # Since the legacy implementation relies on an __init__ injector, typing always 2220 # complains that positional argument op_code is not passed, so here sets a 2221 # default value to allow building derived HCI_Command without op_code. 2222 assert op_code != -1 2223 super().__init__(HCI_Command.command_name(op_code)) 2224 if (fields := getattr(self, 'fields', None)) and kwargs: 2225 HCI_Object.init_from_fields(self, fields, kwargs) 2226 if parameters is None: 2227 parameters = HCI_Object.dict_to_bytes(kwargs, fields) 2228 self.op_code = op_code 2229 self.parameters = parameters 2230 2231 def to_bytes(self): 2232 parameters = b'' if self.parameters is None else self.parameters 2233 return ( 2234 struct.pack('<BHB', HCI_COMMAND_PACKET, self.op_code, len(parameters)) 2235 + parameters 2236 ) 2237 2238 def __bytes__(self): 2239 return self.to_bytes() 2240 2241 def __str__(self): 2242 result = color(self.name, 'green') 2243 if fields := getattr(self, 'fields', None): 2244 result += ':\n' + HCI_Object.format_fields(self.__dict__, fields, ' ') 2245 else: 2246 if self.parameters: 2247 result += f': {self.parameters.hex()}' 2248 return result 2249 2250 2251HCI_Command.register_commands(globals()) 2252 2253 2254# ----------------------------------------------------------------------------- 2255@HCI_Command.command( 2256 [ 2257 ('lap', {'size': 3, 'mapper': HCI_Constant.inquiry_lap_name}), 2258 ('inquiry_length', 1), 2259 ('num_responses', 1), 2260 ] 2261) 2262class HCI_Inquiry_Command(HCI_Command): 2263 ''' 2264 See Bluetooth spec @ 7.1.1 Inquiry Command 2265 ''' 2266 2267 2268# ----------------------------------------------------------------------------- 2269@HCI_Command.command() 2270class HCI_Inquiry_Cancel_Command(HCI_Command): 2271 ''' 2272 See Bluetooth spec @ 7.1.2 Inquiry Cancel Command 2273 ''' 2274 2275 2276# ----------------------------------------------------------------------------- 2277@HCI_Command.command( 2278 [ 2279 ('bd_addr', Address.parse_address), 2280 ('packet_type', 2), 2281 ('page_scan_repetition_mode', 1), 2282 ('reserved', 1), 2283 ('clock_offset', 2), 2284 ('allow_role_switch', 1), 2285 ] 2286) 2287class HCI_Create_Connection_Command(HCI_Command): 2288 ''' 2289 See Bluetooth spec @ 7.1.5 Create Connection Command 2290 ''' 2291 2292 2293# ----------------------------------------------------------------------------- 2294@HCI_Command.command( 2295 [ 2296 ('connection_handle', 2), 2297 ('reason', {'size': 1, 'mapper': HCI_Constant.error_name}), 2298 ] 2299) 2300class HCI_Disconnect_Command(HCI_Command): 2301 ''' 2302 See Bluetooth spec @ 7.1.6 Disconnect Command 2303 ''' 2304 2305 2306# ----------------------------------------------------------------------------- 2307@HCI_Command.command( 2308 fields=[('bd_addr', Address.parse_address)], 2309 return_parameters_fields=[ 2310 ('status', STATUS_SPEC), 2311 ('bd_addr', Address.parse_address), 2312 ], 2313) 2314class HCI_Create_Connection_Cancel_Command(HCI_Command): 2315 ''' 2316 See Bluetooth spec @ 7.1.7 Create Connection Cancel Command 2317 ''' 2318 2319 2320# ----------------------------------------------------------------------------- 2321@HCI_Command.command([('bd_addr', Address.parse_address), ('role', 1)]) 2322class HCI_Accept_Connection_Request_Command(HCI_Command): 2323 ''' 2324 See Bluetooth spec @ 7.1.8 Accept Connection Request Command 2325 ''' 2326 2327 2328# ----------------------------------------------------------------------------- 2329@HCI_Command.command( 2330 [ 2331 ('bd_addr', Address.parse_address), 2332 ('reason', {'size': 1, 'mapper': HCI_Constant.error_name}), 2333 ] 2334) 2335class HCI_Reject_Connection_Request_Command(HCI_Command): 2336 ''' 2337 See Bluetooth spec @ 7.1.9 Reject Connection Request Command 2338 ''' 2339 2340 2341# ----------------------------------------------------------------------------- 2342@HCI_Command.command([('bd_addr', Address.parse_address), ('link_key', 16)]) 2343class HCI_Link_Key_Request_Reply_Command(HCI_Command): 2344 ''' 2345 See Bluetooth spec @ 7.1.10 Link Key Request Reply Command 2346 ''' 2347 2348 2349# ----------------------------------------------------------------------------- 2350@HCI_Command.command( 2351 fields=[('bd_addr', Address.parse_address)], 2352 return_parameters_fields=[ 2353 ('status', STATUS_SPEC), 2354 ('bd_addr', Address.parse_address), 2355 ], 2356) 2357class HCI_Link_Key_Request_Negative_Reply_Command(HCI_Command): 2358 ''' 2359 See Bluetooth spec @ 7.1.11 Link Key Request Negative Reply Command 2360 ''' 2361 2362 2363# ----------------------------------------------------------------------------- 2364@HCI_Command.command( 2365 fields=[ 2366 ('bd_addr', Address.parse_address), 2367 ('pin_code_length', 1), 2368 ('pin_code', 16), 2369 ], 2370 return_parameters_fields=[ 2371 ('status', STATUS_SPEC), 2372 ('bd_addr', Address.parse_address), 2373 ], 2374) 2375class HCI_PIN_Code_Request_Reply_Command(HCI_Command): 2376 ''' 2377 See Bluetooth spec @ 7.1.12 PIN Code Request Reply Command 2378 ''' 2379 2380 2381# ----------------------------------------------------------------------------- 2382@HCI_Command.command( 2383 fields=[('bd_addr', Address.parse_address)], 2384 return_parameters_fields=[ 2385 ('status', STATUS_SPEC), 2386 ('bd_addr', Address.parse_address), 2387 ], 2388) 2389class HCI_PIN_Code_Request_Negative_Reply_Command(HCI_Command): 2390 ''' 2391 See Bluetooth spec @ 7.1.13 PIN Code Request Negative Reply Command 2392 ''' 2393 2394 2395# ----------------------------------------------------------------------------- 2396@HCI_Command.command([('connection_handle', 2), ('packet_type', 2)]) 2397class HCI_Change_Connection_Packet_Type_Command(HCI_Command): 2398 ''' 2399 See Bluetooth spec @ 7.1.14 Change Connection Packet Type Command 2400 ''' 2401 2402 2403# ----------------------------------------------------------------------------- 2404@HCI_Command.command([('connection_handle', 2)]) 2405class HCI_Authentication_Requested_Command(HCI_Command): 2406 ''' 2407 See Bluetooth spec @ 7.1.15 Authentication Requested Command 2408 ''' 2409 2410 2411# ----------------------------------------------------------------------------- 2412@HCI_Command.command([('connection_handle', 2), ('encryption_enable', 1)]) 2413class HCI_Set_Connection_Encryption_Command(HCI_Command): 2414 ''' 2415 See Bluetooth spec @ 7.1.16 Set Connection Encryption Command 2416 ''' 2417 2418 2419# ----------------------------------------------------------------------------- 2420@HCI_Command.command( 2421 [ 2422 ('bd_addr', Address.parse_address), 2423 ('page_scan_repetition_mode', 1), 2424 ('reserved', 1), 2425 ('clock_offset', 2), 2426 ] 2427) 2428class HCI_Remote_Name_Request_Command(HCI_Command): 2429 ''' 2430 See Bluetooth spec @ 7.1.19 Remote Name Request Command 2431 ''' 2432 2433 R0 = 0x00 2434 R1 = 0x01 2435 R2 = 0x02 2436 2437 2438# ----------------------------------------------------------------------------- 2439@HCI_Command.command([('connection_handle', 2)]) 2440class HCI_Read_Remote_Supported_Features_Command(HCI_Command): 2441 ''' 2442 See Bluetooth spec @ 7.1.21 Read Remote Supported Features Command 2443 ''' 2444 2445 2446# ----------------------------------------------------------------------------- 2447@HCI_Command.command([('connection_handle', 2), ('page_number', 1)]) 2448class HCI_Read_Remote_Extended_Features_Command(HCI_Command): 2449 ''' 2450 See Bluetooth spec @ 7.1.22 Read Remote Extended Features Command 2451 ''' 2452 2453 2454# ----------------------------------------------------------------------------- 2455@HCI_Command.command([('connection_handle', 2)]) 2456class HCI_Read_Remote_Version_Information_Command(HCI_Command): 2457 ''' 2458 See Bluetooth spec @ 7.1.23 Read Remote Version Information Command 2459 ''' 2460 2461 2462# ----------------------------------------------------------------------------- 2463@HCI_Command.command([('connection_handle', 2)]) 2464class HCI_Read_Clock_Offset_Command(HCI_Command): 2465 ''' 2466 See Bluetooth spec @ 7.1.23 Read Clock Offset Command 2467 ''' 2468 2469 2470# ----------------------------------------------------------------------------- 2471@HCI_Command.command( 2472 fields=[ 2473 ('bd_addr', Address.parse_address), 2474 ('reason', {'size': 1, 'mapper': HCI_Constant.error_name}), 2475 ], 2476) 2477class HCI_Reject_Synchronous_Connection_Request_Command(HCI_Command): 2478 ''' 2479 See Bluetooth spec @ 7.1.28 Reject Synchronous Connection Request Command 2480 ''' 2481 2482 2483# ----------------------------------------------------------------------------- 2484@HCI_Command.command( 2485 fields=[ 2486 ('bd_addr', Address.parse_address), 2487 ('io_capability', {'size': 1, 'mapper': HCI_Constant.io_capability_name}), 2488 ('oob_data_present', 1), 2489 ( 2490 'authentication_requirements', 2491 {'size': 1, 'mapper': HCI_Constant.authentication_requirements_name}, 2492 ), 2493 ], 2494 return_parameters_fields=[ 2495 ('status', STATUS_SPEC), 2496 ('bd_addr', Address.parse_address), 2497 ], 2498) 2499class HCI_IO_Capability_Request_Reply_Command(HCI_Command): 2500 ''' 2501 See Bluetooth spec @ 7.1.29 IO Capability Request Reply Command 2502 ''' 2503 2504 2505# ----------------------------------------------------------------------------- 2506@HCI_Command.command( 2507 fields=[('bd_addr', Address.parse_address)], 2508 return_parameters_fields=[ 2509 ('status', STATUS_SPEC), 2510 ('bd_addr', Address.parse_address), 2511 ], 2512) 2513class HCI_User_Confirmation_Request_Reply_Command(HCI_Command): 2514 ''' 2515 See Bluetooth spec @ 7.1.30 User Confirmation Request Reply Command 2516 ''' 2517 2518 2519# ----------------------------------------------------------------------------- 2520@HCI_Command.command( 2521 fields=[('bd_addr', Address.parse_address)], 2522 return_parameters_fields=[ 2523 ('status', STATUS_SPEC), 2524 ('bd_addr', Address.parse_address), 2525 ], 2526) 2527class HCI_User_Confirmation_Request_Negative_Reply_Command(HCI_Command): 2528 ''' 2529 See Bluetooth spec @ 7.1.31 User Confirmation Request Negative Reply Command 2530 ''' 2531 2532 2533# ----------------------------------------------------------------------------- 2534@HCI_Command.command( 2535 fields=[('bd_addr', Address.parse_address), ('numeric_value', 4)], 2536 return_parameters_fields=[ 2537 ('status', STATUS_SPEC), 2538 ('bd_addr', Address.parse_address), 2539 ], 2540) 2541class HCI_User_Passkey_Request_Reply_Command(HCI_Command): 2542 ''' 2543 See Bluetooth spec @ 7.1.32 User Passkey Request Reply Command 2544 ''' 2545 2546 2547# ----------------------------------------------------------------------------- 2548@HCI_Command.command( 2549 fields=[('bd_addr', Address.parse_address)], 2550 return_parameters_fields=[ 2551 ('status', STATUS_SPEC), 2552 ('bd_addr', Address.parse_address), 2553 ], 2554) 2555class HCI_User_Passkey_Request_Negative_Reply_Command(HCI_Command): 2556 ''' 2557 See Bluetooth spec @ 7.1.33 User Passkey Request Negative Reply Command 2558 ''' 2559 2560 2561# ----------------------------------------------------------------------------- 2562@HCI_Command.command( 2563 fields=[ 2564 ('bd_addr', Address.parse_address), 2565 ('c', 16), 2566 ('r', 16), 2567 ], 2568 return_parameters_fields=[ 2569 ('status', STATUS_SPEC), 2570 ('bd_addr', Address.parse_address), 2571 ], 2572) 2573class HCI_Remote_OOB_Data_Request_Reply_Command(HCI_Command): 2574 ''' 2575 See Bluetooth spec @ 7.1.34 Remote OOB Data Request Reply Command 2576 ''' 2577 2578 2579# ----------------------------------------------------------------------------- 2580@HCI_Command.command( 2581 fields=[('bd_addr', Address.parse_address)], 2582 return_parameters_fields=[ 2583 ('status', STATUS_SPEC), 2584 ('bd_addr', Address.parse_address), 2585 ], 2586) 2587class HCI_Remote_OOB_Data_Request_Negative_Reply_Command(HCI_Command): 2588 ''' 2589 See Bluetooth spec @ 7.1.35 Remote OOB Data Request Negative Reply Command 2590 ''' 2591 2592 2593# ----------------------------------------------------------------------------- 2594@HCI_Command.command( 2595 fields=[ 2596 ('bd_addr', Address.parse_address), 2597 ('reason', 1), 2598 ], 2599 return_parameters_fields=[ 2600 ('status', STATUS_SPEC), 2601 ('bd_addr', Address.parse_address), 2602 ], 2603) 2604class HCI_IO_Capability_Request_Negative_Reply_Command(HCI_Command): 2605 ''' 2606 See Bluetooth spec @ 7.1.36 IO Capability Request Negative Reply Command 2607 ''' 2608 2609 2610# ----------------------------------------------------------------------------- 2611@HCI_Command.command( 2612 [ 2613 ('connection_handle', 2), 2614 ('transmit_bandwidth', 4), 2615 ('receive_bandwidth', 4), 2616 ('transmit_coding_format', CodingFormat.parse_from_bytes), 2617 ('receive_coding_format', CodingFormat.parse_from_bytes), 2618 ('transmit_codec_frame_size', 2), 2619 ('receive_codec_frame_size', 2), 2620 ('input_bandwidth', 4), 2621 ('output_bandwidth', 4), 2622 ('input_coding_format', CodingFormat.parse_from_bytes), 2623 ('output_coding_format', CodingFormat.parse_from_bytes), 2624 ('input_coded_data_size', 2), 2625 ('output_coded_data_size', 2), 2626 ('input_pcm_data_format', 1), 2627 ('output_pcm_data_format', 1), 2628 ('input_pcm_sample_payload_msb_position', 1), 2629 ('output_pcm_sample_payload_msb_position', 1), 2630 ('input_data_path', 1), 2631 ('output_data_path', 1), 2632 ('input_transport_unit_size', 1), 2633 ('output_transport_unit_size', 1), 2634 ('max_latency', 2), 2635 ('packet_type', 2), 2636 ('retransmission_effort', 1), 2637 ] 2638) 2639class HCI_Enhanced_Setup_Synchronous_Connection_Command(HCI_Command): 2640 ''' 2641 See Bluetooth spec @ 7.1.45 Enhanced Setup Synchronous Connection Command 2642 ''' 2643 2644 class PcmDataFormat(enum.IntEnum): 2645 NA = 0x00 2646 ONES_COMPLEMENT = 0x01 2647 TWOS_COMPLEMENT = 0x02 2648 SIGN_MAGNITUDE = 0x03 2649 UNSIGNED = 0x04 2650 2651 class DataPath(enum.IntEnum): 2652 HCI = 0x00 2653 PCM = 0x01 2654 2655 class RetransmissionEffort(enum.IntEnum): 2656 NO_RETRANSMISSION = 0x00 2657 OPTIMIZE_FOR_POWER = 0x01 2658 OPTIMIZE_FOR_QUALITY = 0x02 2659 DONT_CARE = 0xFF 2660 2661 class PacketType(enum.IntFlag): 2662 HV1 = 0x0001 2663 HV2 = 0x0002 2664 HV3 = 0x0004 2665 EV3 = 0x0008 2666 EV4 = 0x0010 2667 EV5 = 0x0020 2668 NO_2_EV3 = 0x0040 2669 NO_3_EV3 = 0x0080 2670 NO_2_EV5 = 0x0100 2671 NO_3_EV5 = 0x0200 2672 2673 2674# ----------------------------------------------------------------------------- 2675@HCI_Command.command( 2676 [ 2677 ('bd_addr', Address.parse_address), 2678 ('transmit_bandwidth', 4), 2679 ('receive_bandwidth', 4), 2680 ('transmit_coding_format', CodingFormat.parse_from_bytes), 2681 ('receive_coding_format', CodingFormat.parse_from_bytes), 2682 ('transmit_codec_frame_size', 2), 2683 ('receive_codec_frame_size', 2), 2684 ('input_bandwidth', 4), 2685 ('output_bandwidth', 4), 2686 ('input_coding_format', CodingFormat.parse_from_bytes), 2687 ('output_coding_format', CodingFormat.parse_from_bytes), 2688 ('input_coded_data_size', 2), 2689 ('output_coded_data_size', 2), 2690 ('input_pcm_data_format', 1), 2691 ('output_pcm_data_format', 1), 2692 ('input_pcm_sample_payload_msb_position', 1), 2693 ('output_pcm_sample_payload_msb_position', 1), 2694 ('input_data_path', 1), 2695 ('output_data_path', 1), 2696 ('input_transport_unit_size', 1), 2697 ('output_transport_unit_size', 1), 2698 ('max_latency', 2), 2699 ('packet_type', 2), 2700 ('retransmission_effort', 1), 2701 ] 2702) 2703class HCI_Enhanced_Accept_Synchronous_Connection_Request_Command(HCI_Command): 2704 ''' 2705 See Bluetooth spec @ 7.1.46 Enhanced Accept Synchronous Connection Request Command 2706 ''' 2707 2708 2709# ----------------------------------------------------------------------------- 2710@HCI_Command.command( 2711 fields=[ 2712 ('bd_addr', Address.parse_address), 2713 ('page_scan_repetition_mode', 1), 2714 ('clock_offset', 2), 2715 ] 2716) 2717class HCI_Truncated_Page_Command(HCI_Command): 2718 ''' 2719 See Bluetooth spec @ 7.1.47 Truncated Page Command 2720 ''' 2721 2722 2723# ----------------------------------------------------------------------------- 2724@HCI_Command.command( 2725 fields=[('bd_addr', Address.parse_address)], 2726 return_parameters_fields=[ 2727 ('status', STATUS_SPEC), 2728 ('bd_addr', Address.parse_address), 2729 ], 2730) 2731class HCI_Truncated_Page_Cancel_Command(HCI_Command): 2732 ''' 2733 See Bluetooth spec @ 7.1.48 Truncated Page Cancel Command 2734 ''' 2735 2736 2737# ----------------------------------------------------------------------------- 2738@HCI_Command.command( 2739 fields=[ 2740 ('enable', 1), 2741 ('lt_addr', 1), 2742 ('lpo_allowed', 1), 2743 ('packet_type', 2), 2744 ('interval_min', 2), 2745 ('interval_max', 2), 2746 ('supervision_timeout', 2), 2747 ], 2748 return_parameters_fields=[ 2749 ('status', STATUS_SPEC), 2750 ('lt_addr', 1), 2751 ('interval', 2), 2752 ], 2753) 2754class HCI_Set_Connectionless_Peripheral_Broadcast_Command(HCI_Command): 2755 ''' 2756 See Bluetooth spec @ 7.1.49 Set Connectionless Peripheral Broadcast Command 2757 ''' 2758 2759 2760# ----------------------------------------------------------------------------- 2761@HCI_Command.command( 2762 fields=[ 2763 ('enable', 1), 2764 ('bd_addr', Address.parse_address), 2765 ('lt_addr', 1), 2766 ('interval', 2), 2767 ('clock_offset', 4), 2768 ('next_connectionless_peripheral_broadcast_clock', 4), 2769 ('supervision_timeout', 2), 2770 ('remote_timing_accuracy', 1), 2771 ('skip', 1), 2772 ('packet_type', 2), 2773 ('afh_channel_map', 10), 2774 ], 2775 return_parameters_fields=[ 2776 ('status', STATUS_SPEC), 2777 ('bd_addr', Address.parse_address), 2778 ('lt_addr', 1), 2779 ], 2780) 2781class HCI_Set_Connectionless_Peripheral_Broadcast_Receive_Command(HCI_Command): 2782 ''' 2783 See Bluetooth spec @ 7.1.50 Set Connectionless Peripheral Broadcast Receive Command 2784 ''' 2785 2786 2787# ----------------------------------------------------------------------------- 2788class HCI_Start_Synchronization_Train_Command(HCI_Command): 2789 ''' 2790 See Bluetooth spec @ 7.1.51 Start Synchronization Train Command 2791 ''' 2792 2793 2794# ----------------------------------------------------------------------------- 2795@HCI_Command.command( 2796 fields=[ 2797 ('bd_addr', Address.parse_address), 2798 ('sync_scan_timeout', 2), 2799 ('sync_scan_window', 2), 2800 ('sync_scan_interval', 2), 2801 ], 2802) 2803class HCI_Receive_Synchronization_Train_Command(HCI_Command): 2804 ''' 2805 See Bluetooth spec @ 7.1.52 Receive Synchronization Train Command 2806 ''' 2807 2808 2809# ----------------------------------------------------------------------------- 2810@HCI_Command.command( 2811 fields=[ 2812 ('bd_addr', Address.parse_address), 2813 ('c_192', 16), 2814 ('r_192', 16), 2815 ('c_256', 16), 2816 ('r_256', 16), 2817 ], 2818 return_parameters_fields=[ 2819 ('status', STATUS_SPEC), 2820 ('bd_addr', Address.parse_address), 2821 ], 2822) 2823class HCI_Remote_OOB_Extended_Data_Request_Reply_Command(HCI_Command): 2824 ''' 2825 See Bluetooth spec @ 7.1.53 Remote OOB Extended Data Request Reply Command 2826 ''' 2827 2828 2829# ----------------------------------------------------------------------------- 2830@HCI_Command.command( 2831 [ 2832 ('connection_handle', 2), 2833 ('sniff_max_interval', 2), 2834 ('sniff_min_interval', 2), 2835 ('sniff_attempt', 2), 2836 ('sniff_timeout', 2), 2837 ] 2838) 2839class HCI_Sniff_Mode_Command(HCI_Command): 2840 ''' 2841 See Bluetooth spec @ 7.2.2 Sniff Mode Command 2842 ''' 2843 2844 2845# ----------------------------------------------------------------------------- 2846@HCI_Command.command([('connection_handle', 2)]) 2847class HCI_Exit_Sniff_Mode_Command(HCI_Command): 2848 ''' 2849 See Bluetooth spec @ 7.2.3 Exit Sniff Mode Command 2850 ''' 2851 2852 2853# ----------------------------------------------------------------------------- 2854@HCI_Command.command( 2855 [ 2856 ('bd_addr', Address.parse_address), 2857 ('role', {'size': 1, 'mapper': HCI_Constant.role_name}), 2858 ] 2859) 2860class HCI_Switch_Role_Command(HCI_Command): 2861 ''' 2862 See Bluetooth spec @ 7.2.8 Switch Role Command 2863 ''' 2864 2865 2866# ----------------------------------------------------------------------------- 2867@HCI_Command.command([('connection_handle', 2), ('link_policy_settings', 2)]) 2868class HCI_Write_Link_Policy_Settings_Command(HCI_Command): 2869 ''' 2870 See Bluetooth spec @ 7.2.10 Write Link Policy Settings Command 2871 ''' 2872 2873 2874# ----------------------------------------------------------------------------- 2875@HCI_Command.command([('default_link_policy_settings', 2)]) 2876class HCI_Write_Default_Link_Policy_Settings_Command(HCI_Command): 2877 ''' 2878 See Bluetooth spec @ 7.2.12 Write Default Link Policy Settings Command 2879 ''' 2880 2881 2882# ----------------------------------------------------------------------------- 2883@HCI_Command.command( 2884 [ 2885 ('connection_handle', 2), 2886 ('maximum_latency', 2), 2887 ('minimum_remote_timeout', 2), 2888 ('minimum_local_timeout', 2), 2889 ] 2890) 2891class HCI_Sniff_Subrating_Command(HCI_Command): 2892 ''' 2893 See Bluetooth spec @ 7.2.14 Sniff Subrating Command 2894 ''' 2895 2896 2897# ----------------------------------------------------------------------------- 2898@HCI_Command.command([('event_mask', 8)]) 2899class HCI_Set_Event_Mask_Command(HCI_Command): 2900 ''' 2901 See Bluetooth spec @ 7.3.1 Set Event Mask Command 2902 ''' 2903 2904 @staticmethod 2905 def mask(event_codes: Iterable[int]) -> bytes: 2906 ''' 2907 Compute the event mask value for a list of events. 2908 ''' 2909 # NOTE: this implementation takes advantage of the fact that as of version 5.4 2910 # of the core specification, the bit number for each event code is equal to one 2911 # less than the event code. 2912 # If future versions of the specification deviate from that, a different 2913 # implementation would be needed. 2914 return sum((1 << event_code - 1) for event_code in event_codes).to_bytes( 2915 8, 'little' 2916 ) 2917 2918 2919# ----------------------------------------------------------------------------- 2920@HCI_Command.command() 2921class HCI_Reset_Command(HCI_Command): 2922 ''' 2923 See Bluetooth spec @ 7.3.2 Reset Command 2924 ''' 2925 2926 2927# ----------------------------------------------------------------------------- 2928@HCI_Command.command( 2929 [ 2930 ('filter_type', 1), 2931 ('filter_condition', '*'), 2932 ] 2933) 2934class HCI_Set_Event_Filter_Command(HCI_Command): 2935 ''' 2936 See Bluetooth spec @ 7.3.3 Set Event Filter Command 2937 ''' 2938 2939 2940# ----------------------------------------------------------------------------- 2941@HCI_Command.command( 2942 fields=[('bd_addr', Address.parse_address), ('read_all_flag', 1)], 2943 return_parameters_fields=[ 2944 ('status', STATUS_SPEC), 2945 ('max_num_keys', 2), 2946 ('num_keys_read', 2), 2947 ], 2948) 2949class HCI_Read_Stored_Link_Key_Command(HCI_Command): 2950 ''' 2951 See Bluetooth spec @ 7.3.8 Read Stored Link Key Command 2952 ''' 2953 2954 2955# ----------------------------------------------------------------------------- 2956@HCI_Command.command( 2957 fields=[('bd_addr', Address.parse_address), ('delete_all_flag', 1)], 2958 return_parameters_fields=[('status', STATUS_SPEC), ('num_keys_deleted', 2)], 2959) 2960class HCI_Delete_Stored_Link_Key_Command(HCI_Command): 2961 ''' 2962 See Bluetooth spec @ 7.3.10 Delete Stored Link Key Command 2963 ''' 2964 2965 2966# ----------------------------------------------------------------------------- 2967@HCI_Command.command( 2968 [('local_name', {'size': 248, 'mapper': map_null_terminated_utf8_string})] 2969) 2970class HCI_Write_Local_Name_Command(HCI_Command): 2971 ''' 2972 See Bluetooth spec @ 7.3.11 Write Local Name Command 2973 ''' 2974 2975 2976# ----------------------------------------------------------------------------- 2977@HCI_Command.command( 2978 return_parameters_fields=[ 2979 ('status', STATUS_SPEC), 2980 ('local_name', {'size': 248, 'mapper': map_null_terminated_utf8_string}), 2981 ] 2982) 2983class HCI_Read_Local_Name_Command(HCI_Command): 2984 ''' 2985 See Bluetooth spec @ 7.3.12 Read Local Name Command 2986 ''' 2987 2988 2989# ----------------------------------------------------------------------------- 2990@HCI_Command.command([('connection_accept_timeout', 2)]) 2991class HCI_Write_Connection_Accept_Timeout_Command(HCI_Command): 2992 ''' 2993 See Bluetooth spec @ 7.3.14 Write Connection Accept Timeout Command 2994 ''' 2995 2996 2997# ----------------------------------------------------------------------------- 2998@HCI_Command.command([('page_timeout', 2)]) 2999class HCI_Write_Page_Timeout_Command(HCI_Command): 3000 ''' 3001 See Bluetooth spec @ 7.3.16 Write Page Timeout Command 3002 ''' 3003 3004 3005# ----------------------------------------------------------------------------- 3006@HCI_Command.command([('scan_enable', 1)]) 3007class HCI_Write_Scan_Enable_Command(HCI_Command): 3008 ''' 3009 See Bluetooth spec @ 7.3.18 Write Scan Enable Command 3010 ''' 3011 3012 3013# ----------------------------------------------------------------------------- 3014@HCI_Command.command( 3015 return_parameters_fields=[ 3016 ('status', STATUS_SPEC), 3017 ('page_scan_interval', 2), 3018 ('page_scan_window', 2), 3019 ] 3020) 3021class HCI_Read_Page_Scan_Activity_Command(HCI_Command): 3022 ''' 3023 See Bluetooth spec @ 7.3.19 Read Page Scan Activity Command 3024 ''' 3025 3026 3027# ----------------------------------------------------------------------------- 3028@HCI_Command.command([('page_scan_interval', 2), ('page_scan_window', 2)]) 3029class HCI_Write_Page_Scan_Activity_Command(HCI_Command): 3030 ''' 3031 See Bluetooth spec @ 7.3.20 Write Page Scan Activity Command 3032 ''' 3033 3034 3035# ----------------------------------------------------------------------------- 3036@HCI_Command.command([('inquiry_scan_interval', 2), ('inquiry_scan_window', 2)]) 3037class HCI_Write_Inquiry_Scan_Activity_Command(HCI_Command): 3038 ''' 3039 See Bluetooth spec @ 7.3.22 Write Inquiry Scan Activity Command 3040 ''' 3041 3042 3043# ----------------------------------------------------------------------------- 3044@HCI_Command.command( 3045 return_parameters_fields=[ 3046 ('status', STATUS_SPEC), 3047 ('authentication_enable', 1), 3048 ] 3049) 3050class HCI_Read_Authentication_Enable_Command(HCI_Command): 3051 ''' 3052 See Bluetooth spec @ 7.3.23 Read Authentication Enable Command 3053 ''' 3054 3055 3056# ----------------------------------------------------------------------------- 3057@HCI_Command.command([('authentication_enable', 1)]) 3058class HCI_Write_Authentication_Enable_Command(HCI_Command): 3059 ''' 3060 See Bluetooth spec @ 7.3.24 Write Authentication Enable Command 3061 ''' 3062 3063 3064# ----------------------------------------------------------------------------- 3065@HCI_Command.command( 3066 return_parameters_fields=[ 3067 ('status', STATUS_SPEC), 3068 ('class_of_device', {'size': 3, 'mapper': map_class_of_device}), 3069 ] 3070) 3071class HCI_Read_Class_Of_Device_Command(HCI_Command): 3072 ''' 3073 See Bluetooth spec @ 7.3.25 Read Class of Device Command 3074 ''' 3075 3076 3077# ----------------------------------------------------------------------------- 3078@HCI_Command.command([('class_of_device', {'size': 3, 'mapper': map_class_of_device})]) 3079class HCI_Write_Class_Of_Device_Command(HCI_Command): 3080 ''' 3081 See Bluetooth spec @ 7.3.26 Write Class of Device Command 3082 ''' 3083 3084 3085# ----------------------------------------------------------------------------- 3086@HCI_Command.command( 3087 return_parameters_fields=[('status', STATUS_SPEC), ('voice_setting', 2)] 3088) 3089class HCI_Read_Voice_Setting_Command(HCI_Command): 3090 ''' 3091 See Bluetooth spec @ 7.3.27 Read Voice Setting Command 3092 ''' 3093 3094 3095# ----------------------------------------------------------------------------- 3096@HCI_Command.command([('voice_setting', 2)]) 3097class HCI_Write_Voice_Setting_Command(HCI_Command): 3098 ''' 3099 See Bluetooth spec @ 7.3.28 Write Voice Setting Command 3100 ''' 3101 3102 3103# ----------------------------------------------------------------------------- 3104@HCI_Command.command( 3105 return_parameters_fields=[ 3106 ('status', STATUS_SPEC), 3107 ('synchronous_flow_control_enable', 1), 3108 ] 3109) 3110class HCI_Read_Synchronous_Flow_Control_Enable_Command(HCI_Command): 3111 ''' 3112 See Bluetooth spec @ 7.3.36 Read Synchronous Flow Control Enable Command 3113 ''' 3114 3115 3116# ----------------------------------------------------------------------------- 3117@HCI_Command.command([('synchronous_flow_control_enable', 1)]) 3118class HCI_Write_Synchronous_Flow_Control_Enable_Command(HCI_Command): 3119 ''' 3120 See Bluetooth spec @ 7.3.37 Write Synchronous Flow Control Enable Command 3121 ''' 3122 3123 3124# ----------------------------------------------------------------------------- 3125@HCI_Command.command( 3126 [ 3127 ('host_acl_data_packet_length', 2), 3128 ('host_synchronous_data_packet_length', 1), 3129 ('host_total_num_acl_data_packets', 2), 3130 ('host_total_num_synchronous_data_packets', 2), 3131 ] 3132) 3133class HCI_Host_Buffer_Size_Command(HCI_Command): 3134 ''' 3135 See Bluetooth spec @ 7.3.39 Host Buffer Size Command 3136 ''' 3137 3138 3139# ----------------------------------------------------------------------------- 3140@HCI_Command.command( 3141 fields=[('handle', 2), ('link_supervision_timeout', 2)], 3142 return_parameters_fields=[ 3143 ('status', STATUS_SPEC), 3144 ('handle', 2), 3145 ], 3146) 3147class HCI_Write_Link_Supervision_Timeout_Command(HCI_Command): 3148 ''' 3149 See Bluetooth spec @ 7.3.42 Write Link Supervision Timeout Command 3150 ''' 3151 3152 3153# ----------------------------------------------------------------------------- 3154@HCI_Command.command( 3155 return_parameters_fields=[('status', STATUS_SPEC), ('num_support_iac', 1)] 3156) 3157class HCI_Read_Number_Of_Supported_IAC_Command(HCI_Command): 3158 ''' 3159 See Bluetooth spec @ 7.3.43 Read Number Of Supported IAC Command 3160 ''' 3161 3162 3163# ----------------------------------------------------------------------------- 3164@HCI_Command.command( 3165 return_parameters_fields=[ 3166 ('status', STATUS_SPEC), 3167 ('num_current_iac', 1), 3168 ('iac_lap', '*'), # TODO: this should be parsed as an array 3169 ] 3170) 3171class HCI_Read_Current_IAC_LAP_Command(HCI_Command): 3172 ''' 3173 See Bluetooth spec @ 7.3.44 Read Current IAC LAP Command 3174 ''' 3175 3176 3177# ----------------------------------------------------------------------------- 3178@HCI_Command.command([('scan_type', 1)]) 3179class HCI_Write_Inquiry_Scan_Type_Command(HCI_Command): 3180 ''' 3181 See Bluetooth spec @ 7.3.48 Write Inquiry Scan Type Command 3182 ''' 3183 3184 3185# ----------------------------------------------------------------------------- 3186@HCI_Command.command([('inquiry_mode', 1)]) 3187class HCI_Write_Inquiry_Mode_Command(HCI_Command): 3188 ''' 3189 See Bluetooth spec @ 7.3.50 Write Inquiry Mode Command 3190 ''' 3191 3192 3193# ----------------------------------------------------------------------------- 3194@HCI_Command.command( 3195 return_parameters_fields=[('status', STATUS_SPEC), ('page_scan_type', 1)] 3196) 3197class HCI_Read_Page_Scan_Type_Command(HCI_Command): 3198 ''' 3199 See Bluetooth spec @ 7.3.51 Read Page Scan Type Command 3200 ''' 3201 3202 3203# ----------------------------------------------------------------------------- 3204@HCI_Command.command([('page_scan_type', 1)]) 3205class HCI_Write_Page_Scan_Type_Command(HCI_Command): 3206 ''' 3207 See Bluetooth spec @ 7.3.52 Write Page Scan Type Command 3208 ''' 3209 3210 3211# ----------------------------------------------------------------------------- 3212@HCI_Command.command( 3213 [ 3214 ('fec_required', 1), 3215 ( 3216 'extended_inquiry_response', 3217 {'size': 240, 'serializer': lambda x: padded_bytes(x, 240)}, 3218 ), 3219 ] 3220) 3221class HCI_Write_Extended_Inquiry_Response_Command(HCI_Command): 3222 ''' 3223 See Bluetooth spec @ 7.3.56 Write Extended Inquiry Response Command 3224 ''' 3225 3226 3227# ----------------------------------------------------------------------------- 3228@HCI_Command.command([('simple_pairing_mode', 1)]) 3229class HCI_Write_Simple_Pairing_Mode_Command(HCI_Command): 3230 ''' 3231 See Bluetooth spec @ 7.3.59 Write Simple Pairing Mode Command 3232 ''' 3233 3234 3235# ----------------------------------------------------------------------------- 3236@HCI_Command.command( 3237 return_parameters_fields=[ 3238 ('status', STATUS_SPEC), 3239 ('c', 16), 3240 ('r', 16), 3241 ] 3242) 3243class HCI_Read_Local_OOB_Data_Command(HCI_Command): 3244 ''' 3245 See Bluetooth spec @ 7.3.60 Read Local OOB Data Command 3246 ''' 3247 3248 3249# ----------------------------------------------------------------------------- 3250@HCI_Command.command( 3251 return_parameters_fields=[('status', STATUS_SPEC), ('tx_power', -1)] 3252) 3253class HCI_Read_Inquiry_Response_Transmit_Power_Level_Command(HCI_Command): 3254 ''' 3255 See Bluetooth spec @ 7.3.61 Read Inquiry Response Transmit Power Level Command 3256 ''' 3257 3258 3259# ----------------------------------------------------------------------------- 3260@HCI_Command.command( 3261 return_parameters_fields=[('status', STATUS_SPEC), ('erroneous_data_reporting', 1)] 3262) 3263class HCI_Read_Default_Erroneous_Data_Reporting_Command(HCI_Command): 3264 ''' 3265 See Bluetooth spec @ 7.3.64 Read Default Erroneous Data Reporting Command 3266 ''' 3267 3268 3269# ----------------------------------------------------------------------------- 3270@HCI_Command.command([('event_mask_page_2', 8)]) 3271class HCI_Set_Event_Mask_Page_2_Command(HCI_Command): 3272 ''' 3273 See Bluetooth spec @ 7.3.69 Set Event Mask Page 2 Command 3274 ''' 3275 3276 3277# ----------------------------------------------------------------------------- 3278@HCI_Command.command( 3279 return_parameters_fields=[ 3280 ('status', STATUS_SPEC), 3281 ('le_supported_host', 1), 3282 ('unused', 1), 3283 ] 3284) 3285class HCI_Read_LE_Host_Support_Command(HCI_Command): 3286 ''' 3287 See Bluetooth spec @ 7.3.78 Read LE Host Support Command 3288 ''' 3289 3290 3291# ----------------------------------------------------------------------------- 3292@HCI_Command.command([('le_supported_host', 1), ('simultaneous_le_host', 1)]) 3293class HCI_Write_LE_Host_Support_Command(HCI_Command): 3294 ''' 3295 See Bluetooth spec @ 7.3.79 Write LE Host Support Command 3296 ''' 3297 3298 3299# ----------------------------------------------------------------------------- 3300@HCI_Command.command([('secure_connections_host_support', 1)]) 3301class HCI_Write_Secure_Connections_Host_Support_Command(HCI_Command): 3302 ''' 3303 See Bluetooth spec @ 7.3.92 Write Secure Connections Host Support Command 3304 ''' 3305 3306 3307# ----------------------------------------------------------------------------- 3308@HCI_Command.command([('connection_handle', 2), ('authenticated_payload_timeout', 2)]) 3309class HCI_Write_Authenticated_Payload_Timeout_Command(HCI_Command): 3310 ''' 3311 See Bluetooth spec @ 7.3.94 Write Authenticated Payload Timeout Command 3312 ''' 3313 3314 3315# ----------------------------------------------------------------------------- 3316@HCI_Command.command( 3317 return_parameters_fields=[ 3318 ('status', STATUS_SPEC), 3319 ('c_192', 16), 3320 ('r_192', 16), 3321 ('c_256', 16), 3322 ('r_256', 16), 3323 ] 3324) 3325class HCI_Read_Local_OOB_Extended_Data_Command(HCI_Command): 3326 ''' 3327 See Bluetooth spec @ 7.3.95 Read Local OOB Extended Data Command 3328 ''' 3329 3330 3331# ----------------------------------------------------------------------------- 3332@HCI_Command.command( 3333 return_parameters_fields=[ 3334 ('status', STATUS_SPEC), 3335 ('hci_version', 1), 3336 ('hci_subversion', 2), 3337 ('lmp_version', 1), 3338 ('company_identifier', 2), 3339 ('lmp_subversion', 2), 3340 ] 3341) 3342class HCI_Read_Local_Version_Information_Command(HCI_Command): 3343 ''' 3344 See Bluetooth spec @ 7.4.1 Read Local Version Information Command 3345 ''' 3346 3347 3348# ----------------------------------------------------------------------------- 3349@HCI_Command.command( 3350 return_parameters_fields=[('status', STATUS_SPEC), ('supported_commands', 64)] 3351) 3352class HCI_Read_Local_Supported_Commands_Command(HCI_Command): 3353 ''' 3354 See Bluetooth spec @ 7.4.2 Read Local Supported Commands Command 3355 ''' 3356 3357 3358# ----------------------------------------------------------------------------- 3359@HCI_Command.command( 3360 return_parameters_fields=[ 3361 ('status', STATUS_SPEC), 3362 ('lmp_features', 8), 3363 ] 3364) 3365class HCI_Read_Local_Supported_Features_Command(HCI_Command): 3366 ''' 3367 See Bluetooth spec @ 7.4.3 Read Local Supported Features Command 3368 ''' 3369 3370 3371# ----------------------------------------------------------------------------- 3372@HCI_Command.command( 3373 fields=[('page_number', 1)], 3374 return_parameters_fields=[ 3375 ('status', STATUS_SPEC), 3376 ('page_number', 1), 3377 ('maximum_page_number', 1), 3378 ('extended_lmp_features', 8), 3379 ], 3380) 3381class HCI_Read_Local_Extended_Features_Command(HCI_Command): 3382 ''' 3383 See Bluetooth spec @ 7.4.4 Read Local Extended Features Command 3384 ''' 3385 3386 3387# ----------------------------------------------------------------------------- 3388@HCI_Command.command( 3389 return_parameters_fields=[ 3390 ('status', STATUS_SPEC), 3391 ('hc_acl_data_packet_length', 2), 3392 ('hc_synchronous_data_packet_length', 1), 3393 ('hc_total_num_acl_data_packets', 2), 3394 ('hc_total_num_synchronous_data_packets', 2), 3395 ] 3396) 3397class HCI_Read_Buffer_Size_Command(HCI_Command): 3398 ''' 3399 See Bluetooth spec @ 7.4.5 Read Buffer Size Command 3400 ''' 3401 3402 3403# ----------------------------------------------------------------------------- 3404@HCI_Command.command( 3405 return_parameters_fields=[ 3406 ('status', STATUS_SPEC), 3407 ('bd_addr', Address.parse_address), 3408 ] 3409) 3410class HCI_Read_BD_ADDR_Command(HCI_Command): 3411 ''' 3412 See Bluetooth spec @ 7.4.6 Read BD_ADDR Command 3413 ''' 3414 3415 3416# ----------------------------------------------------------------------------- 3417@HCI_Command.command( 3418 return_parameters_fields=[ 3419 ("status", STATUS_SPEC), 3420 [("standard_codec_ids", 1)], 3421 [("vendor_specific_codec_ids", 4)], 3422 ] 3423) 3424class HCI_Read_Local_Supported_Codecs_Command(HCI_Command): 3425 ''' 3426 See Bluetooth spec @ 7.4.8 Read Local Supported Codecs Command 3427 ''' 3428 3429 3430# ----------------------------------------------------------------------------- 3431@HCI_Command.command( 3432 return_parameters_fields=[ 3433 ("status", STATUS_SPEC), 3434 [("standard_codec_ids", 1), ("standard_codec_transports", 1)], 3435 [("vendor_specific_codec_ids", 4), ("vendor_specific_codec_transports", 1)], 3436 ] 3437) 3438class HCI_Read_Local_Supported_Codecs_V2_Command(HCI_Command): 3439 ''' 3440 See Bluetooth spec @ 7.4.8 Read Local Supported Codecs Command 3441 ''' 3442 3443 class Transport(enum.IntFlag): 3444 BR_EDR_ACL = 1 << 0 3445 BR_EDR_SCO = 1 << 1 3446 LE_CIS = 1 << 2 3447 LE_BIS = 1 << 3 3448 3449 3450# ----------------------------------------------------------------------------- 3451@HCI_Command.command( 3452 fields=[('handle', 2)], 3453 return_parameters_fields=[('status', STATUS_SPEC), ('handle', 2), ('rssi', -1)], 3454) 3455class HCI_Read_RSSI_Command(HCI_Command): 3456 ''' 3457 See Bluetooth spec @ 7.5.4 Read RSSI Command 3458 ''' 3459 3460 3461# ----------------------------------------------------------------------------- 3462@HCI_Command.command( 3463 fields=[('connection_handle', 2)], 3464 return_parameters_fields=[ 3465 ('status', STATUS_SPEC), 3466 ('connection_handle', 2), 3467 ('key_size', 1), 3468 ], 3469) 3470class HCI_Read_Encryption_Key_Size_Command(HCI_Command): 3471 ''' 3472 See Bluetooth spec @ 7.5.7 Read Encryption Key Size Command 3473 ''' 3474 3475 3476# ----------------------------------------------------------------------------- 3477@HCI_Command.command( 3478 return_parameters_fields=[ 3479 ('status', STATUS_SPEC), 3480 ('loopback_mode', LoopbackMode.type_spec()), 3481 ], 3482) 3483class HCI_Read_Loopback_Mode_Command(HCI_Command): 3484 ''' 3485 See Bluetooth spec @ 7.6.1 Read Loopback Mode Command 3486 ''' 3487 3488 3489# ----------------------------------------------------------------------------- 3490@HCI_Command.command([('loopback_mode', 1)]) 3491class HCI_Write_Loopback_Mode_Command(HCI_Command): 3492 ''' 3493 See Bluetooth spec @ 7.6.2 Write Loopback Mode Command 3494 ''' 3495 3496 3497# ----------------------------------------------------------------------------- 3498@HCI_Command.command([('le_event_mask', 8)]) 3499class HCI_LE_Set_Event_Mask_Command(HCI_Command): 3500 ''' 3501 See Bluetooth spec @ 7.8.1 LE Set Event Mask Command 3502 ''' 3503 3504 @staticmethod 3505 def mask(event_codes: Iterable[int]) -> bytes: 3506 ''' 3507 Compute the event mask value for a list of events. 3508 ''' 3509 # NOTE: this implementation takes advantage of the fact that as of version 5.4 3510 # of the core specification, the bit number for each event code is equal to one 3511 # less than the event code. 3512 # If future versions of the specification deviate from that, a different 3513 # implementation would be needed. 3514 return sum((1 << event_code - 1) for event_code in event_codes).to_bytes( 3515 8, 'little' 3516 ) 3517 3518 3519# ----------------------------------------------------------------------------- 3520@HCI_Command.command( 3521 return_parameters_fields=[ 3522 ('status', STATUS_SPEC), 3523 ('hc_le_acl_data_packet_length', 2), 3524 ('hc_total_num_le_acl_data_packets', 1), 3525 ] 3526) 3527class HCI_LE_Read_Buffer_Size_Command(HCI_Command): 3528 ''' 3529 See Bluetooth spec @ 7.8.2 LE Read Buffer Size Command 3530 ''' 3531 3532 3533# ----------------------------------------------------------------------------- 3534@HCI_Command.command( 3535 return_parameters_fields=[('status', STATUS_SPEC), ('le_features', 8)] 3536) 3537class HCI_LE_Read_Local_Supported_Features_Command(HCI_Command): 3538 ''' 3539 See Bluetooth spec @ 7.8.3 LE Read Local Supported Features Command 3540 ''' 3541 3542 3543# ----------------------------------------------------------------------------- 3544@HCI_Command.command( 3545 [ 3546 ( 3547 'random_address', 3548 lambda data, offset: Address.parse_address_with_type( 3549 data, offset, Address.RANDOM_DEVICE_ADDRESS 3550 ), 3551 ) 3552 ] 3553) 3554class HCI_LE_Set_Random_Address_Command(HCI_Command): 3555 ''' 3556 See Bluetooth spec @ 7.8.4 LE Set Random Address Command 3557 ''' 3558 3559 3560# ----------------------------------------------------------------------------- 3561@HCI_Command.command( 3562 # pylint: disable=line-too-long,unnecessary-lambda 3563 [ 3564 ('advertising_interval_min', 2), 3565 ('advertising_interval_max', 2), 3566 ( 3567 'advertising_type', 3568 { 3569 'size': 1, 3570 'mapper': lambda x: HCI_LE_Set_Advertising_Parameters_Command.advertising_type_name( 3571 x 3572 ), 3573 }, 3574 ), 3575 ('own_address_type', OwnAddressType.type_spec()), 3576 ('peer_address_type', Address.ADDRESS_TYPE_SPEC), 3577 ('peer_address', Address.parse_address_preceded_by_type), 3578 ('advertising_channel_map', 1), 3579 ('advertising_filter_policy', 1), 3580 ] 3581) 3582class HCI_LE_Set_Advertising_Parameters_Command(HCI_Command): 3583 ''' 3584 See Bluetooth spec @ 7.8.5 LE Set Advertising Parameters Command 3585 ''' 3586 3587 ADV_IND = 0x00 3588 ADV_DIRECT_IND = 0x01 3589 ADV_SCAN_IND = 0x02 3590 ADV_NONCONN_IND = 0x03 3591 ADV_DIRECT_IND_LOW_DUTY = 0x04 3592 3593 ADVERTISING_TYPE_NAMES = { 3594 ADV_IND: 'ADV_IND', 3595 ADV_DIRECT_IND: 'ADV_DIRECT_IND', 3596 ADV_SCAN_IND: 'ADV_SCAN_IND', 3597 ADV_NONCONN_IND: 'ADV_NONCONN_IND', 3598 ADV_DIRECT_IND_LOW_DUTY: 'ADV_DIRECT_IND_LOW_DUTY', 3599 } 3600 3601 @classmethod 3602 def advertising_type_name(cls, advertising_type): 3603 return name_or_number(cls.ADVERTISING_TYPE_NAMES, advertising_type) 3604 3605 3606# ----------------------------------------------------------------------------- 3607@HCI_Command.command( 3608 return_parameters_fields=[ 3609 ('status', STATUS_SPEC), 3610 ('tx_power_level', 1), 3611 ] 3612) 3613class HCI_LE_Read_Advertising_Physical_Channel_Tx_Power_Command(HCI_Command): 3614 ''' 3615 See Bluetooth spec @ 7.8.6 LE Read Advertising Physical Channel Tx Power Command 3616 ''' 3617 3618 3619# ----------------------------------------------------------------------------- 3620@HCI_Command.command( 3621 [ 3622 ( 3623 'advertising_data', 3624 { 3625 'parser': HCI_Object.parse_length_prefixed_bytes, 3626 'serializer': functools.partial( 3627 HCI_Object.serialize_length_prefixed_bytes, padded_size=32 3628 ), 3629 }, 3630 ) 3631 ] 3632) 3633class HCI_LE_Set_Advertising_Data_Command(HCI_Command): 3634 ''' 3635 See Bluetooth spec @ 7.8.7 LE Set Advertising Data Command 3636 ''' 3637 3638 3639# ----------------------------------------------------------------------------- 3640@HCI_Command.command( 3641 [ 3642 ( 3643 'scan_response_data', 3644 { 3645 'parser': HCI_Object.parse_length_prefixed_bytes, 3646 'serializer': functools.partial( 3647 HCI_Object.serialize_length_prefixed_bytes, padded_size=32 3648 ), 3649 }, 3650 ) 3651 ] 3652) 3653class HCI_LE_Set_Scan_Response_Data_Command(HCI_Command): 3654 ''' 3655 See Bluetooth spec @ 7.8.8 LE Set Scan Response Data Command 3656 ''' 3657 3658 3659# ----------------------------------------------------------------------------- 3660@HCI_Command.command([('advertising_enable', 1)]) 3661class HCI_LE_Set_Advertising_Enable_Command(HCI_Command): 3662 ''' 3663 See Bluetooth spec @ 7.8.9 LE Set Advertising Enable Command 3664 ''' 3665 3666 3667# ----------------------------------------------------------------------------- 3668@HCI_Command.command( 3669 [ 3670 ('le_scan_type', 1), 3671 ('le_scan_interval', 2), 3672 ('le_scan_window', 2), 3673 ('own_address_type', OwnAddressType.type_spec()), 3674 ('scanning_filter_policy', 1), 3675 ] 3676) 3677class HCI_LE_Set_Scan_Parameters_Command(HCI_Command): 3678 ''' 3679 See Bluetooth spec @ 7.8.10 LE Set Scan Parameters Command 3680 ''' 3681 3682 PASSIVE_SCANNING = 0 3683 ACTIVE_SCANNING = 1 3684 3685 BASIC_UNFILTERED_POLICY = 0x00 3686 BASIC_FILTERED_POLICY = 0x01 3687 EXTENDED_UNFILTERED_POLICY = 0x02 3688 EXTENDED_FILTERED_POLICY = 0x03 3689 3690 3691# ----------------------------------------------------------------------------- 3692@HCI_Command.command( 3693 [ 3694 ('le_scan_enable', 1), 3695 ('filter_duplicates', 1), 3696 ] 3697) 3698class HCI_LE_Set_Scan_Enable_Command(HCI_Command): 3699 ''' 3700 See Bluetooth spec @ 7.8.11 LE Set Scan Enable Command 3701 ''' 3702 3703 3704# ----------------------------------------------------------------------------- 3705@HCI_Command.command( 3706 [ 3707 ('le_scan_interval', 2), 3708 ('le_scan_window', 2), 3709 ('initiator_filter_policy', 1), 3710 ('peer_address_type', Address.ADDRESS_TYPE_SPEC), 3711 ('peer_address', Address.parse_address_preceded_by_type), 3712 ('own_address_type', OwnAddressType.type_spec()), 3713 ('connection_interval_min', 2), 3714 ('connection_interval_max', 2), 3715 ('max_latency', 2), 3716 ('supervision_timeout', 2), 3717 ('min_ce_length', 2), 3718 ('max_ce_length', 2), 3719 ] 3720) 3721class HCI_LE_Create_Connection_Command(HCI_Command): 3722 ''' 3723 See Bluetooth spec @ 7.8.12 LE Create Connection Command 3724 ''' 3725 3726 3727# ----------------------------------------------------------------------------- 3728@HCI_Command.command() 3729class HCI_LE_Create_Connection_Cancel_Command(HCI_Command): 3730 ''' 3731 See Bluetooth spec @ 7.8.13 LE Create Connection Cancel Command 3732 ''' 3733 3734 3735# ----------------------------------------------------------------------------- 3736@HCI_Command.command( 3737 return_parameters_fields=[ 3738 ('status', STATUS_SPEC), 3739 ('filter_accept_list_size', 1), 3740 ] 3741) 3742class HCI_LE_Read_Filter_Accept_List_Size_Command(HCI_Command): 3743 ''' 3744 See Bluetooth spec @ 7.8.14 LE Read Filter Accept List Size Command 3745 ''' 3746 3747 3748# ----------------------------------------------------------------------------- 3749@HCI_Command.command() 3750class HCI_LE_Clear_Filter_Accept_List_Command(HCI_Command): 3751 ''' 3752 See Bluetooth spec @ 7.8.15 LE Clear Filter Accept List Command 3753 ''' 3754 3755 3756# ----------------------------------------------------------------------------- 3757@HCI_Command.command( 3758 [ 3759 ('address_type', Address.ADDRESS_TYPE_SPEC), 3760 ('address', Address.parse_address_preceded_by_type), 3761 ] 3762) 3763class HCI_LE_Add_Device_To_Filter_Accept_List_Command(HCI_Command): 3764 ''' 3765 See Bluetooth spec @ 7.8.16 LE Add Device To Filter Accept List Command 3766 ''' 3767 3768 3769# ----------------------------------------------------------------------------- 3770@HCI_Command.command( 3771 [ 3772 ('address_type', Address.ADDRESS_TYPE_SPEC), 3773 ('address', Address.parse_address_preceded_by_type), 3774 ] 3775) 3776class HCI_LE_Remove_Device_From_Filter_Accept_List_Command(HCI_Command): 3777 ''' 3778 See Bluetooth spec @ 7.8.17 LE Remove Device From Filter Accept List Command 3779 ''' 3780 3781 3782# ----------------------------------------------------------------------------- 3783@HCI_Command.command( 3784 [ 3785 ('connection_handle', 2), 3786 ('connection_interval_min', 2), 3787 ('connection_interval_max', 2), 3788 ('max_latency', 2), 3789 ('supervision_timeout', 2), 3790 ('min_ce_length', 2), 3791 ('max_ce_length', 2), 3792 ] 3793) 3794class HCI_LE_Connection_Update_Command(HCI_Command): 3795 ''' 3796 See Bluetooth spec @ 7.8.18 LE Connection Update Command 3797 ''' 3798 3799 3800# ----------------------------------------------------------------------------- 3801@HCI_Command.command([('connection_handle', 2)]) 3802class HCI_LE_Read_Remote_Features_Command(HCI_Command): 3803 ''' 3804 See Bluetooth spec @ 7.8.21 LE Read Remote Features Command 3805 ''' 3806 3807 3808# ----------------------------------------------------------------------------- 3809@HCI_Command.command( 3810 return_parameters_fields=[("status", STATUS_SPEC), ("random_number", 8)] 3811) 3812class HCI_LE_Rand_Command(HCI_Command): 3813 """ 3814 See Bluetooth spec @ 7.8.23 LE Rand Command 3815 """ 3816 3817 3818# ----------------------------------------------------------------------------- 3819@HCI_Command.command( 3820 [ 3821 ('connection_handle', 2), 3822 ('random_number', 8), 3823 ('encrypted_diversifier', 2), 3824 ('long_term_key', 16), 3825 ] 3826) 3827class HCI_LE_Enable_Encryption_Command(HCI_Command): 3828 ''' 3829 See Bluetooth spec @ 7.8.24 LE Enable Encryption Command 3830 (renamed from "LE Start Encryption Command" in version prior to 5.2 of the 3831 specification) 3832 ''' 3833 3834 3835# ----------------------------------------------------------------------------- 3836@HCI_Command.command([('connection_handle', 2), ('long_term_key', 16)]) 3837class HCI_LE_Long_Term_Key_Request_Reply_Command(HCI_Command): 3838 ''' 3839 See Bluetooth spec @ 7.8.25 LE Long Term Key Request Reply Command 3840 ''' 3841 3842 3843# ----------------------------------------------------------------------------- 3844@HCI_Command.command([('connection_handle', 2)]) 3845class HCI_LE_Long_Term_Key_Request_Negative_Reply_Command(HCI_Command): 3846 ''' 3847 See Bluetooth spec @ 7.8.26 LE Long Term Key Request Negative Reply Command 3848 ''' 3849 3850 3851# ----------------------------------------------------------------------------- 3852@HCI_Command.command( 3853 return_parameters_fields=[ 3854 ('status', STATUS_SPEC), 3855 ('le_states', 8), 3856 ] 3857) 3858class HCI_LE_Read_Supported_States_Command(HCI_Command): 3859 ''' 3860 See Bluetooth spec @ 7.8.27 LE Read Supported States Command 3861 ''' 3862 3863 3864# ----------------------------------------------------------------------------- 3865@HCI_Command.command( 3866 [ 3867 ('connection_handle', 2), 3868 ('interval_min', 2), 3869 ('interval_max', 2), 3870 ('max_latency', 2), 3871 ('timeout', 2), 3872 ('min_ce_length', 2), 3873 ('max_ce_length', 2), 3874 ] 3875) 3876class HCI_LE_Remote_Connection_Parameter_Request_Reply_Command(HCI_Command): 3877 ''' 3878 See Bluetooth spec @ 7.8.31 LE Remote Connection Parameter Request Reply Command 3879 ''' 3880 3881 3882# ----------------------------------------------------------------------------- 3883@HCI_Command.command( 3884 [ 3885 ('connection_handle', 2), 3886 ('reason', {'size': 1, 'mapper': HCI_Constant.error_name}), 3887 ] 3888) 3889class HCI_LE_Remote_Connection_Parameter_Request_Negative_Reply_Command(HCI_Command): 3890 ''' 3891 See Bluetooth spec @ 7.8.32 LE Remote Connection Parameter Request Negative Reply 3892 Command 3893 ''' 3894 3895 3896# ----------------------------------------------------------------------------- 3897@HCI_Command.command( 3898 fields=[ 3899 ('connection_handle', 2), 3900 ('tx_octets', 2), 3901 ('tx_time', 2), 3902 ], 3903 return_parameters_fields=[('status', STATUS_SPEC), ('connection_handle', 2)], 3904) 3905class HCI_LE_Set_Data_Length_Command(HCI_Command): 3906 ''' 3907 See Bluetooth spec @ 7.8.33 LE Set Data Length Command 3908 ''' 3909 3910 3911# ----------------------------------------------------------------------------- 3912@HCI_Command.command( 3913 return_parameters_fields=[ 3914 ('status', STATUS_SPEC), 3915 ('suggested_max_tx_octets', 2), 3916 ('suggested_max_tx_time', 2), 3917 ] 3918) 3919class HCI_LE_Read_Suggested_Default_Data_Length_Command(HCI_Command): 3920 ''' 3921 See Bluetooth spec @ 7.8.34 LE Read Suggested Default Data Length Command 3922 ''' 3923 3924 3925# ----------------------------------------------------------------------------- 3926@HCI_Command.command([('suggested_max_tx_octets', 2), ('suggested_max_tx_time', 2)]) 3927class HCI_LE_Write_Suggested_Default_Data_Length_Command(HCI_Command): 3928 ''' 3929 See Bluetooth spec @ 7.8.35 LE Write Suggested Default Data Length Command 3930 ''' 3931 3932 3933# ----------------------------------------------------------------------------- 3934@HCI_Command.command( 3935 [ 3936 ('peer_identity_address_type', Address.ADDRESS_TYPE_SPEC), 3937 ('peer_identity_address', Address.parse_address_preceded_by_type), 3938 ('peer_irk', 16), 3939 ('local_irk', 16), 3940 ] 3941) 3942class HCI_LE_Add_Device_To_Resolving_List_Command(HCI_Command): 3943 ''' 3944 See Bluetooth spec @ 7.8.38 LE Add Device To Resolving List Command 3945 ''' 3946 3947 3948# ----------------------------------------------------------------------------- 3949@HCI_Command.command() 3950class HCI_LE_Clear_Resolving_List_Command(HCI_Command): 3951 ''' 3952 See Bluetooth spec @ 7.8.40 LE Clear Resolving List Command 3953 ''' 3954 3955 3956# ----------------------------------------------------------------------------- 3957@HCI_Command.command([('address_resolution_enable', 1)]) 3958class HCI_LE_Set_Address_Resolution_Enable_Command(HCI_Command): 3959 ''' 3960 See Bluetooth spec @ 7.8.44 LE Set Address Resolution Enable Command 3961 ''' 3962 3963 3964# ----------------------------------------------------------------------------- 3965@HCI_Command.command([('rpa_timeout', 2)]) 3966class HCI_LE_Set_Resolvable_Private_Address_Timeout_Command(HCI_Command): 3967 ''' 3968 See Bluetooth spec @ 7.8.45 LE Set Resolvable Private Address Timeout Command 3969 ''' 3970 3971 3972# ----------------------------------------------------------------------------- 3973@HCI_Command.command( 3974 return_parameters_fields=[ 3975 ('status', STATUS_SPEC), 3976 ('supported_max_tx_octets', 2), 3977 ('supported_max_tx_time', 2), 3978 ('supported_max_rx_octets', 2), 3979 ('supported_max_rx_time', 2), 3980 ] 3981) 3982class HCI_LE_Read_Maximum_Data_Length_Command(HCI_Command): 3983 ''' 3984 See Bluetooth spec @ 7.8.46 LE Read Maximum Data Length Command 3985 ''' 3986 3987 3988# ----------------------------------------------------------------------------- 3989@HCI_Command.command( 3990 fields=[('connection_handle', 2)], 3991 return_parameters_fields=[ 3992 ('status', STATUS_SPEC), 3993 ('connection_handle', 2), 3994 ('tx_phy', {'size': 1, 'mapper': HCI_Constant.le_phy_name}), 3995 ('rx_phy', {'size': 1, 'mapper': HCI_Constant.le_phy_name}), 3996 ], 3997) 3998class HCI_LE_Read_PHY_Command(HCI_Command): 3999 ''' 4000 See Bluetooth spec @ 7.8.47 LE Read PHY Command 4001 ''' 4002 4003 4004# ----------------------------------------------------------------------------- 4005@HCI_Command.command( 4006 [ 4007 ( 4008 'all_phys', 4009 { 4010 'size': 1, 4011 'mapper': lambda x: bit_flags_to_strings( 4012 x, HCI_LE_Set_Default_PHY_Command.ANY_PHY_BIT_NAMES 4013 ), 4014 }, 4015 ), 4016 ( 4017 'tx_phys', 4018 { 4019 'size': 1, 4020 'mapper': lambda x: bit_flags_to_strings(x, HCI_LE_PHY_BIT_NAMES), 4021 }, 4022 ), 4023 ( 4024 'rx_phys', 4025 { 4026 'size': 1, 4027 'mapper': lambda x: bit_flags_to_strings(x, HCI_LE_PHY_BIT_NAMES), 4028 }, 4029 ), 4030 ] 4031) 4032class HCI_LE_Set_Default_PHY_Command(HCI_Command): 4033 ''' 4034 See Bluetooth spec @ 7.8.48 LE Set Default PHY Command 4035 ''' 4036 4037 ANY_TX_PHY_BIT = 0 4038 ANY_RX_PHY_BIT = 1 4039 4040 ANY_PHY_BIT_NAMES = ['Any TX', 'Any RX'] 4041 4042 4043# ----------------------------------------------------------------------------- 4044@HCI_Command.command( 4045 [ 4046 ('connection_handle', 2), 4047 ( 4048 'all_phys', 4049 { 4050 'size': 1, 4051 'mapper': lambda x: bit_flags_to_strings( 4052 x, HCI_LE_Set_PHY_Command.ANY_PHY_BIT_NAMES 4053 ), 4054 }, 4055 ), 4056 ( 4057 'tx_phys', 4058 { 4059 'size': 1, 4060 'mapper': lambda x: bit_flags_to_strings(x, HCI_LE_PHY_BIT_NAMES), 4061 }, 4062 ), 4063 ( 4064 'rx_phys', 4065 { 4066 'size': 1, 4067 'mapper': lambda x: bit_flags_to_strings(x, HCI_LE_PHY_BIT_NAMES), 4068 }, 4069 ), 4070 ('phy_options', 2), 4071 ] 4072) 4073class HCI_LE_Set_PHY_Command(HCI_Command): 4074 ''' 4075 See Bluetooth spec @ 7.8.49 LE Set PHY Command 4076 ''' 4077 4078 ANY_TX_PHY_BIT = 0 4079 ANY_RX_PHY_BIT = 1 4080 4081 ANY_PHY_BIT_NAMES = ['Any TX', 'Any RX'] 4082 4083 4084# ----------------------------------------------------------------------------- 4085@HCI_Command.command( 4086 [ 4087 ('advertising_handle', 1), 4088 ( 4089 'random_address', 4090 lambda data, offset: Address.parse_address_with_type( 4091 data, offset, Address.RANDOM_DEVICE_ADDRESS 4092 ), 4093 ), 4094 ] 4095) 4096class HCI_LE_Set_Advertising_Set_Random_Address_Command(HCI_Command): 4097 ''' 4098 See Bluetooth spec @ 7.8.52 LE Set Advertising Set Random Address Command 4099 ''' 4100 4101 4102# ----------------------------------------------------------------------------- 4103@HCI_Command.command( 4104 # pylint: disable=line-too-long,unnecessary-lambda 4105 fields=[ 4106 ('advertising_handle', 1), 4107 ( 4108 'advertising_event_properties', 4109 { 4110 'size': 2, 4111 'mapper': lambda x: str( 4112 HCI_LE_Set_Extended_Advertising_Parameters_Command.AdvertisingProperties( 4113 x 4114 ) 4115 ), 4116 }, 4117 ), 4118 ('primary_advertising_interval_min', 3), 4119 ('primary_advertising_interval_max', 3), 4120 ( 4121 'primary_advertising_channel_map', 4122 { 4123 'size': 1, 4124 'mapper': lambda x: str( 4125 HCI_LE_Set_Extended_Advertising_Parameters_Command.ChannelMap(x) 4126 ), 4127 }, 4128 ), 4129 ('own_address_type', OwnAddressType.type_spec()), 4130 ('peer_address_type', Address.ADDRESS_TYPE_SPEC), 4131 ('peer_address', Address.parse_address_preceded_by_type), 4132 ('advertising_filter_policy', 1), 4133 ('advertising_tx_power', 1), 4134 ('primary_advertising_phy', {'size': 1, 'mapper': HCI_Constant.le_phy_name}), 4135 ('secondary_advertising_max_skip', 1), 4136 ('secondary_advertising_phy', {'size': 1, 'mapper': HCI_Constant.le_phy_name}), 4137 ('advertising_sid', 1), 4138 ('scan_request_notification_enable', 1), 4139 ], 4140 return_parameters_fields=[('status', STATUS_SPEC), ('selected_tx_power', 1)], 4141) 4142class HCI_LE_Set_Extended_Advertising_Parameters_Command(HCI_Command): 4143 ''' 4144 See Bluetooth spec @ 7.8.53 LE Set Extended Advertising Parameters Command 4145 ''' 4146 4147 TX_POWER_NO_PREFERENCE = 0x7F 4148 SHOULD_NOT_FRAGMENT = 0x01 4149 4150 class AdvertisingProperties(enum.IntFlag): 4151 CONNECTABLE_ADVERTISING = 1 << 0 4152 SCANNABLE_ADVERTISING = 1 << 1 4153 DIRECTED_ADVERTISING = 1 << 2 4154 HIGH_DUTY_CYCLE_DIRECTED_CONNECTABLE_ADVERTISING = 1 << 3 4155 USE_LEGACY_ADVERTISING_PDUS = 1 << 4 4156 ANONYMOUS_ADVERTISING = 1 << 5 4157 INCLUDE_TX_POWER = 1 << 6 4158 4159 def __str__(self) -> str: 4160 return '|'.join( 4161 flag.name 4162 for flag in HCI_LE_Set_Extended_Advertising_Parameters_Command.AdvertisingProperties 4163 if self.value & flag.value and flag.name is not None 4164 ) 4165 4166 class ChannelMap(enum.IntFlag): 4167 CHANNEL_37 = 1 << 0 4168 CHANNEL_38 = 1 << 1 4169 CHANNEL_39 = 1 << 2 4170 4171 def __str__(self) -> str: 4172 return '|'.join( 4173 flag.name 4174 for flag in HCI_LE_Set_Extended_Advertising_Parameters_Command.ChannelMap 4175 if self.value & flag.value and flag.name is not None 4176 ) 4177 4178 4179# ----------------------------------------------------------------------------- 4180@HCI_Command.command( 4181 # pylint: disable=line-too-long,unnecessary-lambda 4182 [ 4183 ('advertising_handle', 1), 4184 ( 4185 'operation', 4186 { 4187 'size': 1, 4188 'mapper': lambda x: HCI_LE_Set_Extended_Advertising_Data_Command.Operation( 4189 x 4190 ).name, 4191 }, 4192 ), 4193 ('fragment_preference', 1), 4194 ( 4195 'advertising_data', 4196 { 4197 'parser': HCI_Object.parse_length_prefixed_bytes, 4198 'serializer': HCI_Object.serialize_length_prefixed_bytes, 4199 }, 4200 ), 4201 ] 4202) 4203class HCI_LE_Set_Extended_Advertising_Data_Command(HCI_Command): 4204 ''' 4205 See Bluetooth spec @ 7.8.54 LE Set Extended Advertising Data Command 4206 ''' 4207 4208 class Operation(enum.IntEnum): 4209 INTERMEDIATE_FRAGMENT = 0x00 4210 FIRST_FRAGMENT = 0x01 4211 LAST_FRAGMENT = 0x02 4212 COMPLETE_DATA = 0x03 4213 UNCHANGED_DATA = 0x04 4214 4215 4216# ----------------------------------------------------------------------------- 4217@HCI_Command.command( 4218 # pylint: disable=line-too-long,unnecessary-lambda 4219 [ 4220 ('advertising_handle', 1), 4221 ( 4222 'operation', 4223 { 4224 'size': 1, 4225 'mapper': lambda x: HCI_LE_Set_Extended_Advertising_Data_Command.Operation( 4226 x 4227 ).name, 4228 }, 4229 ), 4230 ('fragment_preference', 1), 4231 ( 4232 'scan_response_data', 4233 { 4234 'parser': HCI_Object.parse_length_prefixed_bytes, 4235 'serializer': HCI_Object.serialize_length_prefixed_bytes, 4236 }, 4237 ), 4238 ] 4239) 4240class HCI_LE_Set_Extended_Scan_Response_Data_Command(HCI_Command): 4241 ''' 4242 See Bluetooth spec @ 7.8.55 LE Set Extended Scan Response Data Command 4243 ''' 4244 4245 4246# ----------------------------------------------------------------------------- 4247@HCI_Command.command( 4248 [ 4249 ('enable', 1), 4250 [ 4251 ('advertising_handles', 1), 4252 ('durations', 2), 4253 ('max_extended_advertising_events', 1), 4254 ], 4255 ] 4256) 4257class HCI_LE_Set_Extended_Advertising_Enable_Command(HCI_Command): 4258 ''' 4259 See Bluetooth spec @ 7.8.56 LE Set Extended Advertising Enable Command 4260 ''' 4261 4262 4263# ----------------------------------------------------------------------------- 4264@HCI_Command.command( 4265 return_parameters_fields=[ 4266 ('status', STATUS_SPEC), 4267 ('max_advertising_data_length', 2), 4268 ] 4269) 4270class HCI_LE_Read_Maximum_Advertising_Data_Length_Command(HCI_Command): 4271 ''' 4272 See Bluetooth spec @ 7.8.57 LE Read Maximum Advertising Data Length Command 4273 ''' 4274 4275 4276# ----------------------------------------------------------------------------- 4277@HCI_Command.command( 4278 return_parameters_fields=[ 4279 ('status', STATUS_SPEC), 4280 ('num_supported_advertising_sets', 1), 4281 ] 4282) 4283class HCI_LE_Read_Number_Of_Supported_Advertising_Sets_Command(HCI_Command): 4284 ''' 4285 See Bluetooth spec @ 7.8.58 LE Read Number of Supported Advertising Sets Command 4286 ''' 4287 4288 4289# ----------------------------------------------------------------------------- 4290@HCI_Command.command([('advertising_handle', 1)]) 4291class HCI_LE_Remove_Advertising_Set_Command(HCI_Command): 4292 ''' 4293 See Bluetooth spec @ 7.8.59 LE Remove Advertising Set Command 4294 ''' 4295 4296 4297# ----------------------------------------------------------------------------- 4298@HCI_Command.command() 4299class HCI_LE_Clear_Advertising_Sets_Command(HCI_Command): 4300 ''' 4301 See Bluetooth spec @ 7.8.60 LE Clear Advertising Sets Command 4302 ''' 4303 4304 4305# ----------------------------------------------------------------------------- 4306@HCI_Command.command([('enable', 1), ('advertising_handle', 1)]) 4307class HCI_LE_Set_Periodic_Advertising_Enable_Command(HCI_Command): 4308 ''' 4309 See Bluetooth spec @ 7.8.63 LE Set Periodic Advertising Enable Command 4310 ''' 4311 4312 4313# ----------------------------------------------------------------------------- 4314@HCI_Command.command(fields=None) 4315class HCI_LE_Set_Extended_Scan_Parameters_Command(HCI_Command): 4316 ''' 4317 See Bluetooth spec @ 7.8.64 LE Set Extended Scan Parameters Command 4318 ''' 4319 4320 PASSIVE_SCANNING = 0 4321 ACTIVE_SCANNING = 1 4322 4323 BASIC_UNFILTERED_POLICY = 0x00 4324 BASIC_FILTERED_POLICY = 0x01 4325 EXTENDED_UNFILTERED_POLICY = 0x02 4326 EXTENDED_FILTERED_POLICY = 0x03 4327 4328 @classmethod 4329 def from_parameters(cls, parameters): 4330 own_address_type = parameters[0] 4331 scanning_filter_policy = parameters[1] 4332 scanning_phys = parameters[2] 4333 4334 phy_bits_set = bin(scanning_phys).count('1') 4335 scan_types = [] 4336 scan_intervals = [] 4337 scan_windows = [] 4338 for i in range(phy_bits_set): 4339 scan_types.append(parameters[3 + (5 * i)]) 4340 scan_intervals.append( 4341 struct.unpack_from('<H', parameters, 3 + (5 * i) + 1)[0] 4342 ) 4343 scan_windows.append( 4344 struct.unpack_from('<H', parameters, 3 + (5 * i) + 3)[0] 4345 ) 4346 4347 return cls( 4348 own_address_type=own_address_type, 4349 scanning_filter_policy=scanning_filter_policy, 4350 scanning_phys=scanning_phys, 4351 scan_types=scan_types, 4352 scan_intervals=scan_intervals, 4353 scan_windows=scan_windows, 4354 ) 4355 4356 def __init__( 4357 self, 4358 own_address_type, 4359 scanning_filter_policy, 4360 scanning_phys, 4361 scan_types, 4362 scan_intervals, 4363 scan_windows, 4364 ): 4365 super().__init__(HCI_LE_SET_EXTENDED_SCAN_PARAMETERS_COMMAND) 4366 self.own_address_type = own_address_type 4367 self.scanning_filter_policy = scanning_filter_policy 4368 self.scanning_phys = scanning_phys 4369 self.scan_types = scan_types 4370 self.scan_intervals = scan_intervals 4371 self.scan_windows = scan_windows 4372 4373 self.parameters = bytes( 4374 [own_address_type, scanning_filter_policy, scanning_phys] 4375 ) 4376 phy_bits_set = bin(scanning_phys).count('1') 4377 for i in range(phy_bits_set): 4378 self.parameters += struct.pack( 4379 '<BHH', scan_types[i], scan_intervals[i], scan_windows[i] 4380 ) 4381 4382 def __str__(self): 4383 scanning_phys_strs = bit_flags_to_strings( 4384 self.scanning_phys, HCI_LE_PHY_BIT_NAMES 4385 ) 4386 fields = [ 4387 ( 4388 'own_address_type: ', 4389 Address.address_type_name(self.own_address_type), 4390 ), 4391 ('scanning_filter_policy:', self.scanning_filter_policy), 4392 ('scanning_phys: ', ','.join(scanning_phys_strs)), 4393 ] 4394 for i, scanning_phy_str in enumerate(scanning_phys_strs): 4395 fields.append( 4396 ( 4397 f'{scanning_phy_str}.scan_type: ', 4398 ( 4399 'PASSIVE' 4400 if self.scan_types[i] == self.PASSIVE_SCANNING 4401 else 'ACTIVE' 4402 ), 4403 ) 4404 ) 4405 fields.append( 4406 (f'{scanning_phy_str}.scan_interval:', self.scan_intervals[i]) 4407 ) 4408 fields.append((f'{scanning_phy_str}.scan_window: ', self.scan_windows[i])) 4409 4410 return ( 4411 color(self.name, 'green') 4412 + ':\n' 4413 + '\n'.join( 4414 [ 4415 color(' ' + field[0], 'cyan') + ' ' + str(field[1]) 4416 for field in fields 4417 ] 4418 ) 4419 ) 4420 4421 4422# ----------------------------------------------------------------------------- 4423@HCI_Command.command( 4424 [('enable', 1), ('filter_duplicates', 1), ('duration', 2), ('period', 2)] 4425) 4426class HCI_LE_Set_Extended_Scan_Enable_Command(HCI_Command): 4427 ''' 4428 See Bluetooth spec @ 7.8.65 LE Set Extended Scan Enable Command 4429 ''' 4430 4431 4432# ----------------------------------------------------------------------------- 4433@HCI_Command.command(fields=None) 4434class HCI_LE_Extended_Create_Connection_Command(HCI_Command): 4435 ''' 4436 See Bluetooth spec @ 7.8.66 LE Extended Create Connection Command 4437 ''' 4438 4439 @classmethod 4440 def from_parameters(cls, parameters): 4441 initiator_filter_policy = parameters[0] 4442 own_address_type = parameters[1] 4443 peer_address_type = parameters[2] 4444 peer_address = Address.parse_address_preceded_by_type(parameters, 3)[1] 4445 initiating_phys = parameters[9] 4446 4447 phy_bits_set = bin(initiating_phys).count('1') 4448 4449 def read_parameter_list(offset): 4450 return [ 4451 struct.unpack_from('<H', parameters, offset + 16 * i)[0] 4452 for i in range(phy_bits_set) 4453 ] 4454 4455 return cls( 4456 initiator_filter_policy=initiator_filter_policy, 4457 own_address_type=own_address_type, 4458 peer_address_type=peer_address_type, 4459 peer_address=peer_address, 4460 initiating_phys=initiating_phys, 4461 scan_intervals=read_parameter_list(10), 4462 scan_windows=read_parameter_list(12), 4463 connection_interval_mins=read_parameter_list(14), 4464 connection_interval_maxs=read_parameter_list(16), 4465 max_latencies=read_parameter_list(18), 4466 supervision_timeouts=read_parameter_list(20), 4467 min_ce_lengths=read_parameter_list(22), 4468 max_ce_lengths=read_parameter_list(24), 4469 ) 4470 4471 def __init__( 4472 self, 4473 initiator_filter_policy, 4474 own_address_type, 4475 peer_address_type, 4476 peer_address, 4477 initiating_phys, 4478 scan_intervals, 4479 scan_windows, 4480 connection_interval_mins, 4481 connection_interval_maxs, 4482 max_latencies, 4483 supervision_timeouts, 4484 min_ce_lengths, 4485 max_ce_lengths, 4486 ): 4487 super().__init__(HCI_LE_EXTENDED_CREATE_CONNECTION_COMMAND) 4488 self.initiator_filter_policy = initiator_filter_policy 4489 self.own_address_type = own_address_type 4490 self.peer_address_type = peer_address_type 4491 self.peer_address = peer_address 4492 self.initiating_phys = initiating_phys 4493 self.scan_intervals = scan_intervals 4494 self.scan_windows = scan_windows 4495 self.connection_interval_mins = connection_interval_mins 4496 self.connection_interval_maxs = connection_interval_maxs 4497 self.max_latencies = max_latencies 4498 self.supervision_timeouts = supervision_timeouts 4499 self.min_ce_lengths = min_ce_lengths 4500 self.max_ce_lengths = max_ce_lengths 4501 4502 self.parameters = ( 4503 bytes([initiator_filter_policy, own_address_type, peer_address_type]) 4504 + bytes(peer_address) 4505 + bytes([initiating_phys]) 4506 ) 4507 4508 phy_bits_set = bin(initiating_phys).count('1') 4509 for i in range(phy_bits_set): 4510 self.parameters += struct.pack( 4511 '<HHHHHHHH', 4512 scan_intervals[i], 4513 scan_windows[i], 4514 connection_interval_mins[i], 4515 connection_interval_maxs[i], 4516 max_latencies[i], 4517 supervision_timeouts[i], 4518 min_ce_lengths[i], 4519 max_ce_lengths[i], 4520 ) 4521 4522 def __str__(self): 4523 initiating_phys_strs = bit_flags_to_strings( 4524 self.initiating_phys, HCI_LE_PHY_BIT_NAMES 4525 ) 4526 fields = [ 4527 ('initiator_filter_policy:', self.initiator_filter_policy), 4528 ( 4529 'own_address_type: ', 4530 OwnAddressType(self.own_address_type).name, 4531 ), 4532 ( 4533 'peer_address_type: ', 4534 Address.address_type_name(self.peer_address_type), 4535 ), 4536 ('peer_address: ', str(self.peer_address)), 4537 ('initiating_phys: ', ','.join(initiating_phys_strs)), 4538 ] 4539 for i, initiating_phys_str in enumerate(initiating_phys_strs): 4540 fields.append( 4541 ( 4542 f'{initiating_phys_str}.scan_interval: ', 4543 self.scan_intervals[i], 4544 ) 4545 ) 4546 fields.append( 4547 ( 4548 f'{initiating_phys_str}.scan_window: ', 4549 self.scan_windows[i], 4550 ) 4551 ) 4552 fields.append( 4553 ( 4554 f'{initiating_phys_str}.connection_interval_min:', 4555 self.connection_interval_mins[i], 4556 ) 4557 ) 4558 fields.append( 4559 ( 4560 f'{initiating_phys_str}.connection_interval_max:', 4561 self.connection_interval_maxs[i], 4562 ) 4563 ) 4564 fields.append( 4565 ( 4566 f'{initiating_phys_str}.max_latency: ', 4567 self.max_latencies[i], 4568 ) 4569 ) 4570 fields.append( 4571 ( 4572 f'{initiating_phys_str}.supervision_timeout: ', 4573 self.supervision_timeouts[i], 4574 ) 4575 ) 4576 fields.append( 4577 ( 4578 f'{initiating_phys_str}.min_ce_length: ', 4579 self.min_ce_lengths[i], 4580 ) 4581 ) 4582 fields.append( 4583 ( 4584 f'{initiating_phys_str}.max_ce_length: ', 4585 self.max_ce_lengths[i], 4586 ) 4587 ) 4588 4589 return ( 4590 color(self.name, 'green') 4591 + ':\n' 4592 + '\n'.join( 4593 [ 4594 color(' ' + field[0], 'cyan') + ' ' + str(field[1]) 4595 for field in fields 4596 ] 4597 ) 4598 ) 4599 4600 4601# ----------------------------------------------------------------------------- 4602@HCI_Command.command( 4603 [ 4604 ( 4605 'options', 4606 { 4607 'size': 1, 4608 'mapper': lambda x: HCI_LE_Periodic_Advertising_Create_Sync_Command.Options( 4609 x 4610 ).name, 4611 }, 4612 ), 4613 ('advertising_sid', 1), 4614 ('advertiser_address_type', Address.ADDRESS_TYPE_SPEC), 4615 ('advertiser_address', Address.parse_address_preceded_by_type), 4616 ('skip', 2), 4617 ('sync_timeout', 2), 4618 ( 4619 'sync_cte_type', 4620 { 4621 'size': 1, 4622 'mapper': lambda x: HCI_LE_Periodic_Advertising_Create_Sync_Command.CteType( 4623 x 4624 ).name, 4625 }, 4626 ), 4627 ] 4628) 4629class HCI_LE_Periodic_Advertising_Create_Sync_Command(HCI_Command): 4630 ''' 4631 See Bluetooth spec @ 7.8.67 LE Periodic Advertising Create Sync command 4632 ''' 4633 4634 class Options(enum.IntFlag): 4635 USE_PERIODIC_ADVERTISER_LIST = 1 << 0 4636 REPORTING_INITIALLY_DISABLED = 1 << 1 4637 DUPLICATE_FILTERING_INITIALLY_ENABLED = 1 << 2 4638 4639 class CteType(enum.IntFlag): 4640 DO_NOT_SYNC_TO_PACKETS_WITH_AN_AOA_CONSTANT_TONE_EXTENSION = 1 << 0 4641 DO_NOT_SYNC_TO_PACKETS_WITH_AN_AOD_CONSTANT_TONE_EXTENSION_1US = 1 << 1 4642 DO_NOT_SYNC_TO_PACKETS_WITH_AN_AOD_CONSTANT_TONE_EXTENSION_2US = 1 << 2 4643 DO_NOT_SYNC_TO_PACKETS_WITH_A_TYPE_3_CONSTANT_TONE_EXTENSION = 1 << 3 4644 DO_NOT_SYNC_TO_PACKETS_WITHOUT_A_CONSTANT_TONE_EXTENSION = 1 << 4 4645 4646 4647# ----------------------------------------------------------------------------- 4648@HCI_Command.command() 4649class HCI_LE_Periodic_Advertising_Create_Sync_Cancel_Command(HCI_Command): 4650 ''' 4651 See Bluetooth spec @ 7.8.68 LE Periodic Advertising Create Sync Cancel Command 4652 ''' 4653 4654 4655# ----------------------------------------------------------------------------- 4656@HCI_Command.command([('sync_handle', 2)]) 4657class HCI_LE_Periodic_Advertising_Terminate_Sync_Command(HCI_Command): 4658 ''' 4659 See Bluetooth spec @ 7.8.69 LE Periodic Advertising Terminate Sync Command 4660 ''' 4661 4662 4663# ----------------------------------------------------------------------------- 4664@HCI_Command.command( 4665 [ 4666 ('peer_identity_address_type', Address.ADDRESS_TYPE_SPEC), 4667 ('peer_identity_address', Address.parse_address_preceded_by_type), 4668 ( 4669 'privacy_mode', 4670 { 4671 'size': 1, 4672 # pylint: disable-next=unnecessary-lambda 4673 'mapper': lambda x: HCI_LE_Set_Privacy_Mode_Command.privacy_mode_name( 4674 x 4675 ), 4676 }, 4677 ), 4678 ] 4679) 4680class HCI_LE_Set_Privacy_Mode_Command(HCI_Command): 4681 ''' 4682 See Bluetooth spec @ 7.8.77 LE Set Privacy Mode Command 4683 ''' 4684 4685 NETWORK_PRIVACY_MODE = 0x00 4686 DEVICE_PRIVACY_MODE = 0x01 4687 4688 PRIVACY_MODE_NAMES = { 4689 NETWORK_PRIVACY_MODE: 'NETWORK_PRIVACY_MODE', 4690 DEVICE_PRIVACY_MODE: 'DEVICE_PRIVACY_MODE', 4691 } 4692 4693 @classmethod 4694 def privacy_mode_name(cls, privacy_mode): 4695 return name_or_number(cls.PRIVACY_MODE_NAMES, privacy_mode) 4696 4697 4698# ----------------------------------------------------------------------------- 4699@HCI_Command.command([('sync_handle', 2), ('enable', 1)]) 4700class HCI_LE_Set_Periodic_Advertising_Receive_Enable_Command(HCI_Command): 4701 ''' 4702 See Bluetooth spec @ 7.8.88 LE Set Periodic Advertising Receive Enable Command 4703 ''' 4704 4705 class Enable(enum.IntFlag): 4706 REPORTING_ENABLED = 1 << 0 4707 DUPLICATE_FILTERING_ENABLED = 1 << 1 4708 4709 4710# ----------------------------------------------------------------------------- 4711@HCI_Command.command( 4712 fields=[('connection_handle', 2), ('service_data', 2), ('sync_handle', 2)], 4713 return_parameters_fields=[ 4714 ('status', STATUS_SPEC), 4715 ('connection_handle', 2), 4716 ], 4717) 4718class HCI_LE_Periodic_Advertising_Sync_Transfer_Command(HCI_Command): 4719 ''' 4720 See Bluetooth spec @ 7.8.89 LE Periodic Advertising Sync Transfer Command 4721 ''' 4722 4723 4724# ----------------------------------------------------------------------------- 4725@HCI_Command.command( 4726 fields=[ 4727 ('cig_id', 1), 4728 ('sdu_interval_c_to_p', 3), 4729 ('sdu_interval_p_to_c', 3), 4730 ('worst_case_sca', 1), 4731 ('packing', 1), 4732 ('framing', 1), 4733 ('max_transport_latency_c_to_p', 2), 4734 ('max_transport_latency_p_to_c', 2), 4735 [ 4736 ('cis_id', 1), 4737 ('max_sdu_c_to_p', 2), 4738 ('max_sdu_p_to_c', 2), 4739 ('phy_c_to_p', 1), 4740 ('phy_p_to_c', 1), 4741 ('rtn_c_to_p', 1), 4742 ('rtn_p_to_c', 1), 4743 ], 4744 ], 4745 return_parameters_fields=[ 4746 ('status', STATUS_SPEC), 4747 ('cig_id', 1), 4748 [('connection_handle', 2)], 4749 ], 4750) 4751class HCI_LE_Set_CIG_Parameters_Command(HCI_Command): 4752 ''' 4753 See Bluetooth spec @ 7.8.97 LE Set CIG Parameters Command 4754 ''' 4755 4756 cig_id: int 4757 sdu_interval_c_to_p: int 4758 sdu_interval_p_to_c: int 4759 worst_case_sca: int 4760 packing: int 4761 framing: int 4762 max_transport_latency_c_to_p: int 4763 max_transport_latency_p_to_c: int 4764 cis_id: List[int] 4765 max_sdu_c_to_p: List[int] 4766 max_sdu_p_to_c: List[int] 4767 phy_c_to_p: List[int] 4768 phy_p_to_c: List[int] 4769 rtn_c_to_p: List[int] 4770 rtn_p_to_c: List[int] 4771 4772 4773# ----------------------------------------------------------------------------- 4774@HCI_Command.command( 4775 fields=[ 4776 [ 4777 ('cis_connection_handle', 2), 4778 ('acl_connection_handle', 2), 4779 ], 4780 ], 4781) 4782class HCI_LE_Create_CIS_Command(HCI_Command): 4783 ''' 4784 See Bluetooth spec @ 7.8.99 LE Create CIS command 4785 ''' 4786 4787 cis_connection_handle: List[int] 4788 acl_connection_handle: List[int] 4789 4790 4791# ----------------------------------------------------------------------------- 4792@HCI_Command.command( 4793 fields=[('cig_id', 1)], 4794 return_parameters_fields=[('status', STATUS_SPEC), ('cig_id', 1)], 4795) 4796class HCI_LE_Remove_CIG_Command(HCI_Command): 4797 ''' 4798 See Bluetooth spec @ 7.8.100 LE Remove CIG command 4799 ''' 4800 4801 cig_id: int 4802 4803 4804# ----------------------------------------------------------------------------- 4805@HCI_Command.command( 4806 fields=[('connection_handle', 2)], 4807) 4808class HCI_LE_Accept_CIS_Request_Command(HCI_Command): 4809 ''' 4810 See Bluetooth spec @ 7.8.101 LE Accept CIS Request command 4811 ''' 4812 4813 connection_handle: int 4814 4815 4816# ----------------------------------------------------------------------------- 4817@HCI_Command.command( 4818 fields=[ 4819 ('connection_handle', 2), 4820 ('reason', {'size': 1, 'mapper': HCI_Constant.error_name}), 4821 ], 4822) 4823class HCI_LE_Reject_CIS_Request_Command(HCI_Command): 4824 ''' 4825 See Bluetooth spec @ 7.8.102 LE Reject CIS Request command 4826 ''' 4827 4828 connection_handle: int 4829 reason: int 4830 4831 4832# ----------------------------------------------------------------------------- 4833@HCI_Command.command( 4834 fields=[ 4835 ('big_handle', 1), 4836 ('advertising_handle', 1), 4837 ('num_bis', 1), 4838 ('sdu_interval', 3), 4839 ('max_sdu', 2), 4840 ('max_transport_latency', 2), 4841 ('rtn', 1), 4842 ('phy', 1), 4843 ('packing', 1), 4844 ('framing', 1), 4845 ('encryption', 1), 4846 ('broadcast_code', 16), 4847 ], 4848) 4849class HCI_LE_Create_BIG_Command(HCI_Command): 4850 ''' 4851 See Bluetooth spec @ 7.8.103 LE Create BIG command 4852 ''' 4853 4854 big_handle: int 4855 advertising_handle: int 4856 num_bis: int 4857 sdu_interval: int 4858 max_sdu: int 4859 max_transport_latency: int 4860 rtn: int 4861 phy: int 4862 packing: int 4863 framing: int 4864 encryption: int 4865 broadcast_code: int 4866 4867 4868# ----------------------------------------------------------------------------- 4869@HCI_Command.command( 4870 fields=[ 4871 ('big_handle', 1), 4872 ('reason', {'size': 1, 'mapper': HCI_Constant.error_name}), 4873 ], 4874) 4875class HCI_LE_Terminate_BIG_Command(HCI_Command): 4876 ''' 4877 See Bluetooth spec @ 7.8.105 LE Terminate BIG command 4878 ''' 4879 4880 big_handle: int 4881 reason: int 4882 4883 4884# ----------------------------------------------------------------------------- 4885@HCI_Command.command( 4886 fields=[ 4887 ('big_handle', 1), 4888 ('sync_handle', 2), 4889 ('encryption', 1), 4890 ('broadcast_code', 16), 4891 ('mse', 1), 4892 ('big_sync_timeout', 2), 4893 [('bis', 1)], 4894 ], 4895) 4896class HCI_LE_BIG_Create_Sync_Command(HCI_Command): 4897 ''' 4898 See Bluetooth spec @ 7.8.106 LE BIG Create Sync command 4899 ''' 4900 4901 big_handle: int 4902 sync_handle: int 4903 encryption: int 4904 broadcast_code: int 4905 mse: int 4906 big_sync_timeout: int 4907 bis: List[int] 4908 4909 4910# ----------------------------------------------------------------------------- 4911@HCI_Command.command( 4912 fields=[ 4913 ('big_handle', 1), 4914 ], 4915 return_parameters_fields=[ 4916 ('status', STATUS_SPEC), 4917 ('big_handle', 2), 4918 ], 4919) 4920class HCI_LE_BIG_Terminate_Sync_Command(HCI_Command): 4921 ''' 4922 See Bluetooth spec @ 7.8.107. LE BIG Terminate Sync command 4923 ''' 4924 4925 big_handle: int 4926 4927 4928# ----------------------------------------------------------------------------- 4929@HCI_Command.command( 4930 fields=[ 4931 ('connection_handle', 2), 4932 ('data_path_direction', 1), 4933 ('data_path_id', 1), 4934 ('codec_id', CodingFormat.parse_from_bytes), 4935 ('controller_delay', 3), 4936 ('codec_configuration', 'v'), 4937 ], 4938 return_parameters_fields=[ 4939 ('status', STATUS_SPEC), 4940 ('connection_handle', 2), 4941 ], 4942) 4943class HCI_LE_Setup_ISO_Data_Path_Command(HCI_Command): 4944 ''' 4945 See Bluetooth spec @ 7.8.109 LE Setup ISO Data Path command 4946 ''' 4947 4948 class Direction(enum.IntEnum): 4949 HOST_TO_CONTROLLER = 0x00 4950 CONTROLLER_TO_HOST = 0x01 4951 4952 connection_handle: int 4953 data_path_direction: int 4954 data_path_id: int 4955 codec_id: CodingFormat 4956 controller_delay: int 4957 codec_configuration: bytes 4958 4959 4960# ----------------------------------------------------------------------------- 4961@HCI_Command.command( 4962 fields=[ 4963 ('connection_handle', 2), 4964 ('data_path_direction', 1), 4965 ], 4966 return_parameters_fields=[ 4967 ('status', STATUS_SPEC), 4968 ('connection_handle', 2), 4969 ], 4970) 4971class HCI_LE_Remove_ISO_Data_Path_Command(HCI_Command): 4972 ''' 4973 See Bluetooth spec @ 7.8.110 LE Remove ISO Data Path command 4974 ''' 4975 4976 connection_handle: int 4977 data_path_direction: int 4978 4979 4980# ----------------------------------------------------------------------------- 4981@HCI_Command.command([('bit_number', 1), ('bit_value', 1)]) 4982class HCI_LE_Set_Host_Feature_Command(HCI_Command): 4983 ''' 4984 See Bluetooth spec @ 7.8.115 LE Set Host Feature Command 4985 ''' 4986 4987 4988# ----------------------------------------------------------------------------- 4989# HCI Events 4990# ----------------------------------------------------------------------------- 4991class HCI_Event(HCI_Packet): 4992 ''' 4993 See Bluetooth spec @ Vol 2, Part E - 5.4.4 HCI Event Packet 4994 ''' 4995 4996 hci_packet_type = HCI_EVENT_PACKET 4997 event_names: Dict[int, str] = {} 4998 event_classes: Dict[int, Type[HCI_Event]] = {} 4999 5000 @staticmethod 5001 def event(fields=()): 5002 ''' 5003 Decorator used to declare and register subclasses 5004 ''' 5005 5006 def inner(cls): 5007 cls.name = cls.__name__.upper() 5008 cls.event_code = key_with_value(cls.event_names, cls.name) 5009 if cls.event_code is None: 5010 raise KeyError(f'event {cls.name} not found in event_names') 5011 cls.fields = fields 5012 5013 # Patch the __init__ method to fix the event_code 5014 def init(self, parameters=None, **kwargs): 5015 return HCI_Event.__init__(self, cls.event_code, parameters, **kwargs) 5016 5017 cls.__init__ = init 5018 5019 # Register a factory for this class 5020 HCI_Event.event_classes[cls.event_code] = cls 5021 5022 return cls 5023 5024 return inner 5025 5026 @staticmethod 5027 def event_map(symbols: Dict[str, Any]) -> Dict[int, str]: 5028 return { 5029 event_code: event_name 5030 for (event_name, event_code) in symbols.items() 5031 if event_name.startswith('HCI_') 5032 and not event_name.startswith('HCI_LE_') 5033 and event_name.endswith('_EVENT') 5034 } 5035 5036 @staticmethod 5037 def event_name(event_code): 5038 return name_or_number(HCI_Event.event_names, event_code) 5039 5040 @staticmethod 5041 def register_events(symbols: Dict[str, Any]) -> None: 5042 HCI_Event.event_names.update(HCI_Event.event_map(symbols)) 5043 5044 @staticmethod 5045 def registered(event_class): 5046 event_class.name = event_class.__name__.upper() 5047 event_class.event_code = key_with_value(HCI_Event.event_names, event_class.name) 5048 if event_class.event_code is None: 5049 raise KeyError(f'event {event_class.name} not found in event_names') 5050 5051 # Register a factory for this class 5052 HCI_Event.event_classes[event_class.event_code] = event_class 5053 5054 return event_class 5055 5056 @staticmethod 5057 def from_bytes(packet: bytes) -> HCI_Event: 5058 event_code = packet[1] 5059 length = packet[2] 5060 parameters = packet[3:] 5061 if len(parameters) != length: 5062 raise InvalidPacketError('invalid packet length') 5063 5064 cls: Any 5065 if event_code == HCI_LE_META_EVENT: 5066 # We do this dispatch here and not in the subclass in order to avoid call 5067 # loops 5068 subevent_code = parameters[0] 5069 cls = HCI_LE_Meta_Event.subevent_classes.get(subevent_code) 5070 if cls is None: 5071 # No class registered, just use a generic class instance 5072 return HCI_LE_Meta_Event(subevent_code, parameters) 5073 elif event_code == HCI_VENDOR_EVENT: 5074 subevent_code = parameters[0] 5075 cls = HCI_Vendor_Event.subevent_classes.get(subevent_code) 5076 if cls is None: 5077 # No class registered, just use a generic class instance 5078 return HCI_Vendor_Event(subevent_code, parameters) 5079 else: 5080 cls = HCI_Event.event_classes.get(event_code) 5081 if cls is None: 5082 # No class registered, just use a generic class instance 5083 return HCI_Event(event_code, parameters) 5084 5085 # Invoke the factory to create a new instance 5086 return cls.from_parameters(parameters) # type: ignore 5087 5088 @classmethod 5089 def from_parameters(cls, parameters): 5090 self = cls.__new__(cls) 5091 HCI_Event.__init__(self, self.event_code, parameters) 5092 if fields := getattr(self, 'fields', None): 5093 HCI_Object.init_from_bytes(self, parameters, 0, fields) 5094 return self 5095 5096 def __init__(self, event_code=-1, parameters=None, **kwargs): 5097 # Since the legacy implementation relies on an __init__ injector, typing always 5098 # complains that positional argument event_code is not passed, so here sets a 5099 # default value to allow building derived HCI_Event without event_code. 5100 assert event_code != -1 5101 super().__init__(HCI_Event.event_name(event_code)) 5102 if (fields := getattr(self, 'fields', None)) and kwargs: 5103 HCI_Object.init_from_fields(self, fields, kwargs) 5104 if parameters is None: 5105 parameters = HCI_Object.dict_to_bytes(kwargs, fields) 5106 self.event_code = event_code 5107 self.parameters = parameters 5108 5109 def to_bytes(self): 5110 parameters = b'' if self.parameters is None else self.parameters 5111 return bytes([HCI_EVENT_PACKET, self.event_code, len(parameters)]) + parameters 5112 5113 def __bytes__(self): 5114 return self.to_bytes() 5115 5116 def __str__(self): 5117 result = color(self.name, 'magenta') 5118 if fields := getattr(self, 'fields', None): 5119 result += ':\n' + HCI_Object.format_fields(self.__dict__, fields, ' ') 5120 else: 5121 if self.parameters: 5122 result += f': {self.parameters.hex()}' 5123 return result 5124 5125 5126HCI_Event.register_events(globals()) 5127 5128 5129# ----------------------------------------------------------------------------- 5130class HCI_Extended_Event(HCI_Event): 5131 ''' 5132 HCI_Event subclass for events that has a subevent code. 5133 ''' 5134 5135 subevent_names: Dict[int, str] = {} 5136 subevent_classes: Dict[int, Type[HCI_Extended_Event]] 5137 5138 @classmethod 5139 def event(cls, fields=()): 5140 ''' 5141 Decorator used to declare and register subclasses 5142 ''' 5143 5144 def inner(cls): 5145 cls.name = cls.__name__.upper() 5146 cls.subevent_code = key_with_value(cls.subevent_names, cls.name) 5147 if cls.subevent_code is None: 5148 raise KeyError(f'subevent {cls.name} not found in subevent_names') 5149 cls.fields = fields 5150 5151 # Patch the __init__ method to fix the subevent_code 5152 original_init = cls.__init__ 5153 5154 def init(self, parameters=None, **kwargs): 5155 return original_init(self, cls.subevent_code, parameters, **kwargs) 5156 5157 cls.__init__ = init 5158 5159 # Register a factory for this class 5160 cls.subevent_classes[cls.subevent_code] = cls 5161 5162 return cls 5163 5164 return inner 5165 5166 @classmethod 5167 def subevent_name(cls, subevent_code): 5168 subevent_name = cls.subevent_names.get(subevent_code) 5169 if subevent_name is not None: 5170 return subevent_name 5171 5172 return f'{cls.__name__.upper()}[0x{subevent_code:02X}]' 5173 5174 @staticmethod 5175 def subevent_map(symbols: Dict[str, Any]) -> Dict[int, str]: 5176 return { 5177 subevent_code: subevent_name 5178 for (subevent_name, subevent_code) in symbols.items() 5179 if subevent_name.startswith('HCI_') and subevent_name.endswith('_EVENT') 5180 } 5181 5182 @classmethod 5183 def register_subevents(cls, symbols: Dict[str, Any]) -> None: 5184 cls.subevent_names.update(cls.subevent_map(symbols)) 5185 5186 @classmethod 5187 def from_parameters(cls, parameters): 5188 self = cls.__new__(cls) 5189 HCI_Extended_Event.__init__(self, self.subevent_code, parameters) 5190 if fields := getattr(self, 'fields', None): 5191 HCI_Object.init_from_bytes(self, parameters, 1, fields) 5192 return self 5193 5194 def __init__(self, subevent_code=None, parameters=None, **kwargs): 5195 assert subevent_code is not None 5196 self.subevent_code = subevent_code 5197 if parameters is None and (fields := getattr(self, 'fields', None)) and kwargs: 5198 parameters = bytes([subevent_code]) + HCI_Object.dict_to_bytes( 5199 kwargs, fields 5200 ) 5201 super().__init__(self.event_code, parameters, **kwargs) 5202 5203 # Override the name in order to adopt the subevent name instead 5204 self.name = self.subevent_name(subevent_code) 5205 5206 5207# ----------------------------------------------------------------------------- 5208class HCI_LE_Meta_Event(HCI_Extended_Event): 5209 ''' 5210 See Bluetooth spec @ 7.7.65 LE Meta Event 5211 ''' 5212 5213 event_code: int = HCI_LE_META_EVENT 5214 subevent_classes = {} 5215 5216 @staticmethod 5217 def subevent_map(symbols: Dict[str, Any]) -> Dict[int, str]: 5218 return { 5219 subevent_code: subevent_name 5220 for (subevent_name, subevent_code) in symbols.items() 5221 if subevent_name.startswith('HCI_LE_') and subevent_name.endswith('_EVENT') 5222 } 5223 5224 5225HCI_LE_Meta_Event.register_subevents(globals()) 5226 5227 5228# ----------------------------------------------------------------------------- 5229class HCI_Vendor_Event(HCI_Extended_Event): 5230 event_code: int = HCI_VENDOR_EVENT 5231 subevent_classes = {} 5232 5233 5234# ----------------------------------------------------------------------------- 5235@HCI_LE_Meta_Event.event( 5236 [ 5237 ('status', STATUS_SPEC), 5238 ('connection_handle', 2), 5239 ( 5240 'role', 5241 {'size': 1, 'mapper': lambda x: 'CENTRAL' if x == 0 else 'PERIPHERAL'}, 5242 ), 5243 ('peer_address_type', Address.ADDRESS_TYPE_SPEC), 5244 ('peer_address', Address.parse_address_preceded_by_type), 5245 ('connection_interval', 2), 5246 ('peripheral_latency', 2), 5247 ('supervision_timeout', 2), 5248 ('central_clock_accuracy', 1), 5249 ] 5250) 5251class HCI_LE_Connection_Complete_Event(HCI_LE_Meta_Event): 5252 ''' 5253 See Bluetooth spec @ 7.7.65.1 LE Connection Complete Event 5254 ''' 5255 5256 5257# ----------------------------------------------------------------------------- 5258class HCI_LE_Advertising_Report_Event(HCI_LE_Meta_Event): 5259 ''' 5260 See Bluetooth spec @ 7.7.65.2 LE Advertising Report Event 5261 ''' 5262 5263 subevent_code = HCI_LE_ADVERTISING_REPORT_EVENT 5264 5265 # Event Types 5266 ADV_IND = 0x00 5267 ADV_DIRECT_IND = 0x01 5268 ADV_SCAN_IND = 0x02 5269 ADV_NONCONN_IND = 0x03 5270 SCAN_RSP = 0x04 5271 5272 EVENT_TYPE_NAMES = { 5273 ADV_IND: 'ADV_IND', # Connectable and scannable undirected advertising 5274 ADV_DIRECT_IND: 'ADV_DIRECT_IND', # Connectable directed advertising 5275 ADV_SCAN_IND: 'ADV_SCAN_IND', # Scannable undirected advertising 5276 ADV_NONCONN_IND: 'ADV_NONCONN_IND', # Non connectable undirected advertising 5277 SCAN_RSP: 'SCAN_RSP', # Scan Response 5278 } 5279 5280 class Report(HCI_Object): 5281 FIELDS = [ 5282 ('event_type', 1), 5283 ('address_type', Address.ADDRESS_TYPE_SPEC), 5284 ('address', Address.parse_address_preceded_by_type), 5285 ( 5286 'data', 5287 { 5288 'parser': HCI_Object.parse_length_prefixed_bytes, 5289 'serializer': HCI_Object.serialize_length_prefixed_bytes, 5290 }, 5291 ), 5292 ('rssi', -1), 5293 ] 5294 5295 @classmethod 5296 def from_parameters(cls, parameters, offset): 5297 return cls.from_bytes(parameters, offset, cls.FIELDS) 5298 5299 def event_type_string(self): 5300 return HCI_LE_Advertising_Report_Event.event_type_name(self.event_type) 5301 5302 def to_string(self, indentation='', _=None): 5303 return super().to_string( 5304 indentation, 5305 { 5306 'event_type': HCI_LE_Advertising_Report_Event.event_type_name, 5307 'address_type': Address.address_type_name, 5308 'data': lambda x: str(AdvertisingData.from_bytes(x)), 5309 }, 5310 ) 5311 5312 @classmethod 5313 def event_type_name(cls, event_type): 5314 return name_or_number(cls.EVENT_TYPE_NAMES, event_type) 5315 5316 @classmethod 5317 def from_parameters(cls, parameters): 5318 num_reports = parameters[1] 5319 reports = [] 5320 offset = 2 5321 for _ in range(num_reports): 5322 report = cls.Report.from_parameters(parameters, offset) 5323 offset += 10 + len(report.data) 5324 reports.append(report) 5325 5326 return cls(reports) 5327 5328 def __init__(self, reports): 5329 self.reports = reports[:] 5330 5331 # Serialize the fields 5332 parameters = bytes([HCI_LE_ADVERTISING_REPORT_EVENT, len(reports)]) + b''.join( 5333 [bytes(report) for report in reports] 5334 ) 5335 5336 super().__init__(self.subevent_code, parameters) 5337 5338 def __str__(self): 5339 reports = '\n'.join( 5340 [f'{i}:\n{report.to_string(" ")}' for i, report in enumerate(self.reports)] 5341 ) 5342 return f'{color(self.subevent_name(self.subevent_code), "magenta")}:\n{reports}' 5343 5344 5345HCI_LE_Meta_Event.subevent_classes[HCI_LE_ADVERTISING_REPORT_EVENT] = ( 5346 HCI_LE_Advertising_Report_Event 5347) 5348 5349 5350# ----------------------------------------------------------------------------- 5351@HCI_LE_Meta_Event.event( 5352 [ 5353 ('status', STATUS_SPEC), 5354 ('connection_handle', 2), 5355 ('connection_interval', 2), 5356 ('peripheral_latency', 2), 5357 ('supervision_timeout', 2), 5358 ] 5359) 5360class HCI_LE_Connection_Update_Complete_Event(HCI_LE_Meta_Event): 5361 ''' 5362 See Bluetooth spec @ 7.7.65.3 LE Connection Update Complete Event 5363 ''' 5364 5365 5366# ----------------------------------------------------------------------------- 5367@HCI_LE_Meta_Event.event( 5368 [('status', STATUS_SPEC), ('connection_handle', 2), ('le_features', 8)] 5369) 5370class HCI_LE_Read_Remote_Features_Complete_Event(HCI_LE_Meta_Event): 5371 ''' 5372 See Bluetooth spec @ 7.7.65.4 LE Read Remote Features Complete Event 5373 ''' 5374 5375 5376# ----------------------------------------------------------------------------- 5377@HCI_LE_Meta_Event.event( 5378 [('connection_handle', 2), ('random_number', 8), ('encryption_diversifier', 2)] 5379) 5380class HCI_LE_Long_Term_Key_Request_Event(HCI_LE_Meta_Event): 5381 ''' 5382 See Bluetooth spec @ 7.7.65.5 LE Long Term Key Request Event 5383 ''' 5384 5385 5386# ----------------------------------------------------------------------------- 5387@HCI_LE_Meta_Event.event( 5388 [ 5389 ('connection_handle', 2), 5390 ('interval_min', 2), 5391 ('interval_max', 2), 5392 ('max_latency', 2), 5393 ('timeout', 2), 5394 ] 5395) 5396class HCI_LE_Remote_Connection_Parameter_Request_Event(HCI_LE_Meta_Event): 5397 ''' 5398 See Bluetooth spec @ 7.7.65.6 LE Remote Connection Parameter Request Event 5399 ''' 5400 5401 5402# ----------------------------------------------------------------------------- 5403@HCI_LE_Meta_Event.event( 5404 [ 5405 ('connection_handle', 2), 5406 ('max_tx_octets', 2), 5407 ('max_tx_time', 2), 5408 ('max_rx_octets', 2), 5409 ('max_rx_time', 2), 5410 ] 5411) 5412class HCI_LE_Data_Length_Change_Event(HCI_LE_Meta_Event): 5413 ''' 5414 See Bluetooth spec @ 7.7.65.7 LE Data Length Change Event 5415 ''' 5416 5417 5418# ----------------------------------------------------------------------------- 5419@HCI_LE_Meta_Event.event( 5420 [ 5421 ('status', STATUS_SPEC), 5422 ('connection_handle', 2), 5423 ( 5424 'role', 5425 {'size': 1, 'mapper': lambda x: 'CENTRAL' if x == 0 else 'PERIPHERAL'}, 5426 ), 5427 ('peer_address_type', Address.ADDRESS_TYPE_SPEC), 5428 ('peer_address', Address.parse_address_preceded_by_type), 5429 ('local_resolvable_private_address', Address.parse_random_address), 5430 ('peer_resolvable_private_address', Address.parse_random_address), 5431 ('connection_interval', 2), 5432 ('peripheral_latency', 2), 5433 ('supervision_timeout', 2), 5434 ('central_clock_accuracy', 1), 5435 ] 5436) 5437class HCI_LE_Enhanced_Connection_Complete_Event(HCI_LE_Meta_Event): 5438 ''' 5439 See Bluetooth spec @ 7.7.65.10 LE Enhanced Connection Complete Event 5440 ''' 5441 5442 5443# ----------------------------------------------------------------------------- 5444@HCI_LE_Meta_Event.event( 5445 [ 5446 ('status', STATUS_SPEC), 5447 ('connection_handle', 2), 5448 ('tx_phy', {'size': 1, 'mapper': HCI_Constant.le_phy_name}), 5449 ('rx_phy', {'size': 1, 'mapper': HCI_Constant.le_phy_name}), 5450 ] 5451) 5452class HCI_LE_PHY_Update_Complete_Event(HCI_LE_Meta_Event): 5453 ''' 5454 See Bluetooth spec @ 7.7.65.12 LE PHY Update Complete Event 5455 ''' 5456 5457 5458# ----------------------------------------------------------------------------- 5459class HCI_LE_Extended_Advertising_Report_Event(HCI_LE_Meta_Event): 5460 ''' 5461 See Bluetooth spec @ 7.7.65.13 LE Extended Advertising Report Event 5462 ''' 5463 5464 subevent_code = HCI_LE_EXTENDED_ADVERTISING_REPORT_EVENT 5465 5466 # Event types flags 5467 CONNECTABLE_ADVERTISING = 0 5468 SCANNABLE_ADVERTISING = 1 5469 DIRECTED_ADVERTISING = 2 5470 SCAN_RESPONSE = 3 5471 LEGACY_ADVERTISING_PDU_USED = 4 5472 5473 DATA_COMPLETE = 0x00 5474 DATA_INCOMPLETE_MORE_TO_COME = 0x01 5475 DATA_INCOMPLETE_TRUNCATED_NO_MORE_TO_COME = 0x02 5476 5477 EVENT_TYPE_FLAG_NAMES = ( 5478 'CONNECTABLE_ADVERTISING', 5479 'SCANNABLE_ADVERTISING', 5480 'DIRECTED_ADVERTISING', 5481 'SCAN_RESPONSE', 5482 'LEGACY_ADVERTISING_PDU_USED', 5483 ) 5484 5485 LEGACY_PDU_TYPE_MAP = { 5486 0b0011: HCI_LE_Advertising_Report_Event.ADV_IND, 5487 0b0101: HCI_LE_Advertising_Report_Event.ADV_DIRECT_IND, 5488 0b0010: HCI_LE_Advertising_Report_Event.ADV_SCAN_IND, 5489 0b0000: HCI_LE_Advertising_Report_Event.ADV_NONCONN_IND, 5490 0b1011: HCI_LE_Advertising_Report_Event.SCAN_RSP, 5491 0b1010: HCI_LE_Advertising_Report_Event.SCAN_RSP, 5492 } 5493 5494 NO_ADI_FIELD_PROVIDED = 0xFF 5495 TX_POWER_INFORMATION_NOT_AVAILABLE = 0x7F 5496 RSSI_NOT_AVAILABLE = 0x7F 5497 ANONYMOUS_ADDRESS_TYPE = 0xFF 5498 UNRESOLVED_RESOLVABLE_ADDRESS_TYPE = 0xFE 5499 5500 class Report(HCI_Object): 5501 FIELDS = [ 5502 ('event_type', 2), 5503 ('address_type', Address.ADDRESS_TYPE_SPEC), 5504 ('address', Address.parse_address_preceded_by_type), 5505 ('primary_phy', {'size': 1, 'mapper': HCI_Constant.le_phy_name}), 5506 ('secondary_phy', {'size': 1, 'mapper': HCI_Constant.le_phy_name}), 5507 ('advertising_sid', 1), 5508 ('tx_power', 1), 5509 ('rssi', -1), 5510 ('periodic_advertising_interval', 2), 5511 ('direct_address_type', Address.ADDRESS_TYPE_SPEC), 5512 ('direct_address', Address.parse_address_preceded_by_type), 5513 ( 5514 'data', 5515 { 5516 'parser': HCI_Object.parse_length_prefixed_bytes, 5517 'serializer': HCI_Object.serialize_length_prefixed_bytes, 5518 }, 5519 ), 5520 ] 5521 5522 @classmethod 5523 def from_parameters(cls, parameters, offset): 5524 return cls.from_bytes(parameters, offset, cls.FIELDS) 5525 5526 def event_type_string(self): 5527 return HCI_LE_Extended_Advertising_Report_Event.event_type_string( 5528 self.event_type 5529 ) 5530 5531 def to_string(self, indentation='', _=None): 5532 # pylint: disable=line-too-long 5533 return super().to_string( 5534 indentation, 5535 { 5536 'event_type': HCI_LE_Extended_Advertising_Report_Event.event_type_string, 5537 'address_type': Address.address_type_name, 5538 'data': lambda x: str(AdvertisingData.from_bytes(x)), 5539 }, 5540 ) 5541 5542 @staticmethod 5543 def event_type_string(event_type): 5544 event_type_flags = bit_flags_to_strings( 5545 event_type & 0x1F, 5546 HCI_LE_Extended_Advertising_Report_Event.EVENT_TYPE_FLAG_NAMES, 5547 ) 5548 event_type_flags.append( 5549 ('COMPLETE', 'INCOMPLETE+', 'INCOMPLETE#', '?')[(event_type >> 5) & 3] 5550 ) 5551 5552 if event_type & ( 5553 1 << HCI_LE_Extended_Advertising_Report_Event.LEGACY_ADVERTISING_PDU_USED 5554 ): 5555 legacy_pdu_type = ( 5556 HCI_LE_Extended_Advertising_Report_Event.LEGACY_PDU_TYPE_MAP.get( 5557 event_type & 0x0F 5558 ) 5559 ) 5560 if legacy_pdu_type is not None: 5561 # pylint: disable=line-too-long 5562 legacy_info_string = f'({HCI_LE_Advertising_Report_Event.event_type_name(legacy_pdu_type)})' 5563 else: 5564 legacy_info_string = '' 5565 else: 5566 legacy_info_string = '' 5567 5568 return f'0x{event_type:04X} [{",".join(event_type_flags)}]{legacy_info_string}' 5569 5570 @classmethod 5571 def from_parameters(cls, parameters): 5572 num_reports = parameters[1] 5573 reports = [] 5574 offset = 2 5575 for _ in range(num_reports): 5576 report = cls.Report.from_parameters(parameters, offset) 5577 offset += 24 + len(report.data) 5578 reports.append(report) 5579 5580 return cls(reports) 5581 5582 def __init__(self, reports): 5583 self.reports = reports[:] 5584 5585 # Serialize the fields 5586 parameters = bytes( 5587 [HCI_LE_EXTENDED_ADVERTISING_REPORT_EVENT, len(reports)] 5588 ) + b''.join([bytes(report) for report in reports]) 5589 5590 super().__init__(self.subevent_code, parameters) 5591 5592 def __str__(self): 5593 reports = '\n'.join( 5594 [f'{i}:\n{report.to_string(" ")}' for i, report in enumerate(self.reports)] 5595 ) 5596 return f'{color(self.subevent_name(self.subevent_code), "magenta")}:\n{reports}' 5597 5598 5599HCI_LE_Meta_Event.subevent_classes[HCI_LE_EXTENDED_ADVERTISING_REPORT_EVENT] = ( 5600 HCI_LE_Extended_Advertising_Report_Event 5601) 5602 5603 5604# ----------------------------------------------------------------------------- 5605@HCI_LE_Meta_Event.event( 5606 [ 5607 ('status', STATUS_SPEC), 5608 ('sync_handle', 2), 5609 ('advertising_sid', 1), 5610 ('advertiser_address_type', Address.ADDRESS_TYPE_SPEC), 5611 ('advertiser_address', Address.parse_address_preceded_by_type), 5612 ('advertiser_phy', {'size': 1, 'mapper': HCI_Constant.le_phy_name}), 5613 ('periodic_advertising_interval', 2), 5614 ('advertiser_clock_accuracy', 1), 5615 ] 5616) 5617class HCI_LE_Periodic_Advertising_Sync_Established_Event(HCI_LE_Meta_Event): 5618 ''' 5619 See Bluetooth spec @ 7.7.65.14 LE Periodic Advertising Sync Established Event 5620 ''' 5621 5622 5623# ----------------------------------------------------------------------------- 5624@HCI_LE_Meta_Event.event( 5625 [ 5626 ('status', STATUS_SPEC), 5627 ('sync_handle', 2), 5628 ('advertising_sid', 1), 5629 ('advertiser_address_type', Address.ADDRESS_TYPE_SPEC), 5630 ('advertiser_address', Address.parse_address_preceded_by_type), 5631 ('advertiser_phy', {'size': 1, 'mapper': HCI_Constant.le_phy_name}), 5632 ('periodic_advertising_interval', 2), 5633 ('advertiser_clock_accuracy', 1), 5634 ('num_subevents', 1), 5635 ('subevent_interval', 1), 5636 ('response_slot_delay', 1), 5637 ('response_slot_spacing', 1), 5638 ] 5639) 5640class HCI_LE_Periodic_Advertising_Sync_Established_V2_Event(HCI_LE_Meta_Event): 5641 ''' 5642 See Bluetooth spec @ 7.7.65.14 LE Periodic Advertising Sync Established Event 5643 ''' 5644 5645 5646# ----------------------------------------------------------------------------- 5647@HCI_LE_Meta_Event.event( 5648 [ 5649 ('sync_handle', 2), 5650 ('tx_power', -1), 5651 ('rssi', -1), 5652 ( 5653 'cte_type', 5654 { 5655 'size': 1, 5656 'mapper': lambda x: HCI_LE_Periodic_Advertising_Report_Event.CteType( 5657 x 5658 ).name, 5659 }, 5660 ), 5661 ( 5662 'data_status', 5663 { 5664 'size': 1, 5665 'mapper': lambda x: HCI_LE_Periodic_Advertising_Report_Event.DataStatus( 5666 x 5667 ).name, 5668 }, 5669 ), 5670 ('data', 'v'), 5671 ] 5672) 5673class HCI_LE_Periodic_Advertising_Report_Event(HCI_LE_Meta_Event): 5674 ''' 5675 See Bluetooth spec @ 7.7.65.15 LE Periodic Advertising Report Event 5676 ''' 5677 5678 TX_POWER_INFORMATION_NOT_AVAILABLE = 0x7F 5679 RSSI_NOT_AVAILABLE = 0x7F 5680 5681 class CteType(OpenIntEnum): 5682 AOA_CONSTANT_TONE_EXTENSION = 0x00 5683 AOD_CONSTANT_TONE_EXTENSION_1US = 0x01 5684 AOD_CONSTANT_TONE_EXTENSION_2US = 0x02 5685 NO_CONSTANT_TONE_EXTENSION = 0xFF 5686 5687 class DataStatus(OpenIntEnum): 5688 DATA_COMPLETE = 0x00 5689 DATA_INCOMPLETE_MORE_TO_COME = 0x01 5690 DATA_INCOMPLETE_TRUNCATED_NO_MORE_TO_COME = 0x02 5691 5692 5693# ----------------------------------------------------------------------------- 5694@HCI_LE_Meta_Event.event( 5695 [ 5696 ('sync_handle', 2), 5697 ('tx_power', -1), 5698 ('rssi', -1), 5699 ( 5700 'cte_type', 5701 { 5702 'size': 1, 5703 'mapper': lambda x: HCI_LE_Periodic_Advertising_Report_Event.CteType( 5704 x 5705 ).name, 5706 }, 5707 ), 5708 ('periodic_event_counter', 2), 5709 ('subevent', 1), 5710 ( 5711 'data_status', 5712 { 5713 'size': 1, 5714 'mapper': lambda x: HCI_LE_Periodic_Advertising_Report_Event.DataStatus( 5715 x 5716 ).name, 5717 }, 5718 ), 5719 ('data', 'v'), 5720 ] 5721) 5722class HCI_LE_Periodic_Advertising_Report_V2_Event(HCI_LE_Meta_Event): 5723 ''' 5724 See Bluetooth spec @ 7.7.65.15 LE Periodic Advertising Report Event 5725 ''' 5726 5727 5728# ----------------------------------------------------------------------------- 5729@HCI_LE_Meta_Event.event( 5730 [ 5731 ('sync_handle', 2), 5732 ] 5733) 5734class HCI_LE_Periodic_Advertising_Sync_Lost_Event(HCI_LE_Meta_Event): 5735 ''' 5736 See Bluetooth spec @ 7.7.65.16 LE Periodic Advertising Sync Lost Event 5737 ''' 5738 5739 5740# ----------------------------------------------------------------------------- 5741@HCI_LE_Meta_Event.event( 5742 [ 5743 ('status', 1), 5744 ('advertising_handle', 1), 5745 ('connection_handle', 2), 5746 ('num_completed_extended_advertising_events', 1), 5747 ] 5748) 5749class HCI_LE_Advertising_Set_Terminated_Event(HCI_LE_Meta_Event): 5750 ''' 5751 See Bluetooth spec @ 7.7.65.18 LE Advertising Set Terminated Event 5752 ''' 5753 5754 5755# ----------------------------------------------------------------------------- 5756@HCI_LE_Meta_Event.event([('connection_handle', 2), ('channel_selection_algorithm', 1)]) 5757class HCI_LE_Channel_Selection_Algorithm_Event(HCI_LE_Meta_Event): 5758 ''' 5759 See Bluetooth spec @ 7.7.65.20 LE Channel Selection Algorithm Event 5760 ''' 5761 5762 5763# ----------------------------------------------------------------------------- 5764@HCI_LE_Meta_Event.event( 5765 [ 5766 ('status', STATUS_SPEC), 5767 ('connection_handle', 2), 5768 ('service_data', 2), 5769 ('sync_handle', 2), 5770 ('advertising_sid', 1), 5771 ('advertiser_address_type', Address.ADDRESS_TYPE_SPEC), 5772 ('advertiser_address', Address.parse_address_preceded_by_type), 5773 ('advertiser_phy', 1), 5774 ('periodic_advertising_interval', 2), 5775 ('advertiser_clock_accuracy', 1), 5776 ] 5777) 5778class HCI_LE_Periodic_Advertising_Sync_Transfer_Received_Event(HCI_LE_Meta_Event): 5779 ''' 5780 See Bluetooth spec @ 7.7.65.24 LE Periodic Advertising Sync Transfer Received Event 5781 ''' 5782 5783 5784# ----------------------------------------------------------------------------- 5785@HCI_LE_Meta_Event.event( 5786 [ 5787 ('status', STATUS_SPEC), 5788 ('connection_handle', 2), 5789 ('cig_sync_delay', 3), 5790 ('cis_sync_delay', 3), 5791 ('transport_latency_c_to_p', 3), 5792 ('transport_latency_p_to_c', 3), 5793 ('phy_c_to_p', 1), 5794 ('phy_p_to_c', 1), 5795 ('nse', 1), 5796 ('bn_c_to_p', 1), 5797 ('bn_p_to_c', 1), 5798 ('ft_c_to_p', 1), 5799 ('ft_p_to_c', 1), 5800 ('max_pdu_c_to_p', 2), 5801 ('max_pdu_p_to_c', 2), 5802 ('iso_interval', 2), 5803 ] 5804) 5805class HCI_LE_CIS_Established_Event(HCI_LE_Meta_Event): 5806 ''' 5807 See Bluetooth spec @ 7.7.65.25 LE CIS Established Event 5808 ''' 5809 5810 5811# ----------------------------------------------------------------------------- 5812@HCI_LE_Meta_Event.event( 5813 [ 5814 ('acl_connection_handle', 2), 5815 ('cis_connection_handle', 2), 5816 ('cig_id', 1), 5817 ('cis_id', 1), 5818 ] 5819) 5820class HCI_LE_CIS_Request_Event(HCI_LE_Meta_Event): 5821 ''' 5822 See Bluetooth spec @ 7.7.65.26 LE CIS Request Event 5823 ''' 5824 5825 5826# ----------------------------------------------------------------------------- 5827@HCI_LE_Meta_Event.event( 5828 [ 5829 ('sync_handle', 2), 5830 ('num_bis', 1), 5831 ('nse', 1), 5832 ('iso_interval', 2), 5833 ('bn', 1), 5834 ('pto', 1), 5835 ('irc', 1), 5836 ('max_pdu', 2), 5837 ('sdu_interval', 3), 5838 ('max_sdu', 2), 5839 ('phy', {'size': 1, 'mapper': HCI_Constant.le_phy_name}), 5840 ('framing', 1), 5841 ('encryption', 1), 5842 ] 5843) 5844class HCI_LE_BIGInfo_Advertising_Report_Event(HCI_LE_Meta_Event): 5845 ''' 5846 See Bluetooth spec @ 7.7.65.34 LE BIGInfo Advertising Report Event 5847 ''' 5848 5849 5850# ----------------------------------------------------------------------------- 5851@HCI_Event.event([('status', STATUS_SPEC)]) 5852class HCI_Inquiry_Complete_Event(HCI_Event): 5853 ''' 5854 See Bluetooth spec @ 7.7.1 Inquiry Complete Event 5855 ''' 5856 5857 5858# ----------------------------------------------------------------------------- 5859@HCI_Event.registered 5860class HCI_Inquiry_Result_Event(HCI_Event): 5861 ''' 5862 See Bluetooth spec @ 7.7.2 Inquiry Result Event 5863 ''' 5864 5865 RESPONSE_FIELDS = [ 5866 ('bd_addr', Address.parse_address), 5867 ('page_scan_repetition_mode', 1), 5868 ('reserved', 1), 5869 ('reserved', 1), 5870 ('class_of_device', {'size': 3, 'mapper': map_class_of_device}), 5871 ('clock_offset', 2), 5872 ] 5873 5874 @staticmethod 5875 def from_parameters(parameters): 5876 num_responses = parameters[0] 5877 responses = [] 5878 offset = 1 5879 for _ in range(num_responses): 5880 response = HCI_Object.from_bytes( 5881 parameters, offset, HCI_Inquiry_Result_Event.RESPONSE_FIELDS 5882 ) 5883 offset += 14 5884 responses.append(response) 5885 5886 return HCI_Inquiry_Result_Event(responses) 5887 5888 def __init__(self, responses): 5889 self.responses = responses[:] 5890 5891 # Serialize the fields 5892 parameters = bytes([HCI_INQUIRY_RESULT_EVENT, len(responses)]) + b''.join( 5893 [bytes(response) for response in responses] 5894 ) 5895 5896 super().__init__(HCI_INQUIRY_RESULT_EVENT, parameters) 5897 5898 def __str__(self): 5899 responses = '\n'.join( 5900 [response.to_string(indentation=' ') for response in self.responses] 5901 ) 5902 return f'{color("HCI_INQUIRY_RESULT_EVENT", "magenta")}:\n{responses}' 5903 5904 5905# ----------------------------------------------------------------------------- 5906@HCI_Event.event( 5907 [ 5908 ('status', STATUS_SPEC), 5909 ('connection_handle', 2), 5910 ('bd_addr', Address.parse_address), 5911 ( 5912 'link_type', 5913 { 5914 'size': 1, 5915 # pylint: disable-next=unnecessary-lambda 5916 'mapper': lambda x: HCI_Connection_Complete_Event.link_type_name(x), 5917 }, 5918 ), 5919 ('encryption_enabled', 1), 5920 ] 5921) 5922class HCI_Connection_Complete_Event(HCI_Event): 5923 ''' 5924 See Bluetooth spec @ 7.7.3 Connection Complete Event 5925 ''' 5926 5927 SCO_LINK_TYPE = 0x00 5928 ACL_LINK_TYPE = 0x01 5929 ESCO_LINK_TYPE = 0x02 5930 5931 LINK_TYPE_NAMES = { 5932 SCO_LINK_TYPE: 'SCO', 5933 ACL_LINK_TYPE: 'ACL', 5934 ESCO_LINK_TYPE: 'eSCO', 5935 } 5936 5937 @staticmethod 5938 def link_type_name(link_type): 5939 return name_or_number(HCI_Connection_Complete_Event.LINK_TYPE_NAMES, link_type) 5940 5941 5942# ----------------------------------------------------------------------------- 5943@HCI_Event.event( 5944 [ 5945 ('bd_addr', Address.parse_address), 5946 ('class_of_device', 3), 5947 ( 5948 'link_type', 5949 { 5950 'size': 1, 5951 # pylint: disable-next=unnecessary-lambda 5952 'mapper': lambda x: HCI_Connection_Complete_Event.link_type_name(x), 5953 }, 5954 ), 5955 ] 5956) 5957class HCI_Connection_Request_Event(HCI_Event): 5958 ''' 5959 See Bluetooth spec @ 7.7.4 Connection Request Event 5960 ''' 5961 5962 5963# ----------------------------------------------------------------------------- 5964@HCI_Event.event( 5965 [ 5966 ('status', STATUS_SPEC), 5967 ('connection_handle', 2), 5968 ('reason', {'size': 1, 'mapper': HCI_Constant.error_name}), 5969 ] 5970) 5971class HCI_Disconnection_Complete_Event(HCI_Event): 5972 ''' 5973 See Bluetooth spec @ 7.7.5 Disconnection Complete Event 5974 ''' 5975 5976 status: int 5977 connection_handle: int 5978 reason: int 5979 5980 5981# ----------------------------------------------------------------------------- 5982@HCI_Event.event([('status', STATUS_SPEC), ('connection_handle', 2)]) 5983class HCI_Authentication_Complete_Event(HCI_Event): 5984 ''' 5985 See Bluetooth spec @ 7.7.6 Authentication Complete Event 5986 ''' 5987 5988 5989# ----------------------------------------------------------------------------- 5990@HCI_Event.event( 5991 [ 5992 ('status', STATUS_SPEC), 5993 ('bd_addr', Address.parse_address), 5994 ('remote_name', {'size': 248, 'mapper': map_null_terminated_utf8_string}), 5995 ] 5996) 5997class HCI_Remote_Name_Request_Complete_Event(HCI_Event): 5998 ''' 5999 See Bluetooth spec @ 7.7.7 Remote Name Request Complete Event 6000 ''' 6001 6002 6003# ----------------------------------------------------------------------------- 6004@HCI_Event.event( 6005 [ 6006 ('status', STATUS_SPEC), 6007 ('connection_handle', 2), 6008 ( 6009 'encryption_enabled', 6010 { 6011 'size': 1, 6012 # pylint: disable-next=unnecessary-lambda 6013 'mapper': lambda x: HCI_Encryption_Change_Event.encryption_enabled_name( 6014 x 6015 ), 6016 }, 6017 ), 6018 ] 6019) 6020class HCI_Encryption_Change_Event(HCI_Event): 6021 ''' 6022 See Bluetooth spec @ 7.7.8 Encryption Change Event 6023 ''' 6024 6025 OFF = 0x00 6026 E0_OR_AES_CCM = 0x01 6027 AES_CCM = 0x02 6028 6029 ENCRYPTION_ENABLED_NAMES = { 6030 OFF: 'OFF', 6031 E0_OR_AES_CCM: 'E0_OR_AES_CCM', 6032 AES_CCM: 'AES_CCM', 6033 } 6034 6035 @staticmethod 6036 def encryption_enabled_name(encryption_enabled): 6037 return name_or_number( 6038 HCI_Encryption_Change_Event.ENCRYPTION_ENABLED_NAMES, encryption_enabled 6039 ) 6040 6041 6042# ----------------------------------------------------------------------------- 6043@HCI_Event.event( 6044 [('status', STATUS_SPEC), ('connection_handle', 2), ('lmp_features', 8)] 6045) 6046class HCI_Read_Remote_Supported_Features_Complete_Event(HCI_Event): 6047 ''' 6048 See Bluetooth spec @ 7.7.11 Read Remote Supported Features Complete Event 6049 ''' 6050 6051 6052# ----------------------------------------------------------------------------- 6053@HCI_Event.event( 6054 [ 6055 ('status', STATUS_SPEC), 6056 ('connection_handle', 2), 6057 ('version', 1), 6058 ('manufacturer_name', 2), 6059 ('subversion', 2), 6060 ] 6061) 6062class HCI_Read_Remote_Version_Information_Complete_Event(HCI_Event): 6063 ''' 6064 See Bluetooth spec @ 7.7.12 Read Remote Version Information Complete Event 6065 ''' 6066 6067 6068# ----------------------------------------------------------------------------- 6069@HCI_Event.event( 6070 [ 6071 ('num_hci_command_packets', 1), 6072 ('command_opcode', {'size': 2, 'mapper': HCI_Command.command_name}), 6073 ('return_parameters', '*'), 6074 ] 6075) 6076class HCI_Command_Complete_Event(HCI_Event): 6077 ''' 6078 See Bluetooth spec @ 7.7.14 Command Complete Event 6079 ''' 6080 6081 return_parameters = b'' 6082 command_opcode: int 6083 6084 def map_return_parameters(self, return_parameters): 6085 '''Map simple 'status' return parameters to their named constant form''' 6086 6087 if isinstance(return_parameters, bytes) and len(return_parameters) == 1: 6088 # Byte-array form 6089 return HCI_Constant.status_name(return_parameters[0]) 6090 6091 if isinstance(return_parameters, int): 6092 # Already converted to an integer status code 6093 return HCI_Constant.status_name(return_parameters) 6094 6095 return return_parameters 6096 6097 @staticmethod 6098 def from_parameters(parameters): 6099 self = HCI_Command_Complete_Event.__new__(HCI_Command_Complete_Event) 6100 HCI_Event.__init__(self, self.event_code, parameters) 6101 HCI_Object.init_from_bytes( 6102 self, parameters, 0, HCI_Command_Complete_Event.fields 6103 ) 6104 6105 # Parse the return parameters 6106 if ( 6107 isinstance(self.return_parameters, bytes) 6108 and len(self.return_parameters) == 1 6109 ): 6110 # All commands with 1-byte return parameters return a 'status' field, 6111 # convert it to an integer 6112 self.return_parameters = self.return_parameters[0] 6113 else: 6114 cls = HCI_Command.command_classes.get(self.command_opcode) 6115 if cls: 6116 # Try to parse the return parameters bytes into an object. 6117 return_parameters = cls.parse_return_parameters(self.return_parameters) 6118 if return_parameters is not None: 6119 self.return_parameters = return_parameters 6120 6121 return self 6122 6123 def __str__(self): 6124 return f'{color(self.name, "magenta")}:\n' + HCI_Object.format_fields( 6125 self.__dict__, 6126 self.fields, 6127 ' ', 6128 {'return_parameters': self.map_return_parameters}, 6129 ) 6130 6131 6132# ----------------------------------------------------------------------------- 6133@HCI_Event.event( 6134 [ 6135 ( 6136 'status', 6137 # pylint: disable-next=unnecessary-lambda 6138 {'size': 1, 'mapper': lambda x: HCI_Command_Status_Event.status_name(x)}, 6139 ), 6140 ('num_hci_command_packets', 1), 6141 ('command_opcode', {'size': 2, 'mapper': HCI_Command.command_name}), 6142 ] 6143) 6144class HCI_Command_Status_Event(HCI_Event): 6145 ''' 6146 See Bluetooth spec @ 7.7.15 Command Complete Event 6147 ''' 6148 6149 PENDING = 0 6150 6151 @staticmethod 6152 def status_name(status): 6153 if status == HCI_Command_Status_Event.PENDING: 6154 return 'PENDING' 6155 6156 return HCI_Constant.error_name(status) 6157 6158 6159# ----------------------------------------------------------------------------- 6160@HCI_Event.event( 6161 [ 6162 ('status', STATUS_SPEC), 6163 ('bd_addr', Address.parse_address), 6164 ('new_role', {'size': 1, 'mapper': HCI_Constant.role_name}), 6165 ] 6166) 6167class HCI_Role_Change_Event(HCI_Event): 6168 ''' 6169 See Bluetooth spec @ 7.7.18 Role Change Event 6170 ''' 6171 6172 6173# ----------------------------------------------------------------------------- 6174@HCI_Event.registered 6175class HCI_Number_Of_Completed_Packets_Event(HCI_Event): 6176 ''' 6177 See Bluetooth spec @ 7.7.19 Number Of Completed Packets Event 6178 ''' 6179 6180 @classmethod 6181 def from_parameters(cls, parameters): 6182 self = cls.__new__(cls) 6183 self.parameters = parameters 6184 num_handles = parameters[0] 6185 self.connection_handles = [] 6186 self.num_completed_packets = [] 6187 for i in range(num_handles): 6188 self.connection_handles.append( 6189 struct.unpack_from('<H', parameters, 1 + i * 4)[0] 6190 ) 6191 self.num_completed_packets.append( 6192 struct.unpack_from('<H', parameters, 1 + i * 4 + 2)[0] 6193 ) 6194 6195 return self 6196 6197 def __init__(self, connection_handle_and_completed_packets_list): 6198 self.connection_handles = [] 6199 self.num_completed_packets = [] 6200 parameters = bytes([len(connection_handle_and_completed_packets_list)]) 6201 for handle, completed_packets in connection_handle_and_completed_packets_list: 6202 self.connection_handles.append(handle) 6203 self.num_completed_packets.append(completed_packets) 6204 parameters += struct.pack('<H', handle) 6205 parameters += struct.pack('<H', completed_packets) 6206 super().__init__(HCI_NUMBER_OF_COMPLETED_PACKETS_EVENT, parameters) 6207 6208 def __str__(self): 6209 lines = [ 6210 color(self.name, 'magenta') + ':', 6211 color(' number_of_handles: ', 'cyan') 6212 + f'{len(self.connection_handles)}', 6213 ] 6214 for i, connection_handle in enumerate(self.connection_handles): 6215 lines.append( 6216 color(f' connection_handle[{i}]: ', 'cyan') 6217 + f'{connection_handle}' 6218 ) 6219 lines.append( 6220 color(f' num_completed_packets[{i}]: ', 'cyan') 6221 + f'{self.num_completed_packets[i]}' 6222 ) 6223 return '\n'.join(lines) 6224 6225 6226# ----------------------------------------------------------------------------- 6227@HCI_Event.event( 6228 [ 6229 ('status', STATUS_SPEC), 6230 ('connection_handle', 2), 6231 ( 6232 'current_mode', 6233 # pylint: disable-next=unnecessary-lambda 6234 {'size': 1, 'mapper': lambda x: HCI_Mode_Change_Event.mode_name(x)}, 6235 ), 6236 ('interval', 2), 6237 ] 6238) 6239class HCI_Mode_Change_Event(HCI_Event): 6240 ''' 6241 See Bluetooth spec @ 7.7.20 Mode Change Event 6242 ''' 6243 6244 ACTIVE_MODE = 0x00 6245 HOLD_MODE = 0x01 6246 SNIFF_MODE = 0x02 6247 6248 MODE_NAMES = { 6249 ACTIVE_MODE: 'ACTIVE_MODE', 6250 HOLD_MODE: 'HOLD_MODE', 6251 SNIFF_MODE: 'SNIFF_MODE', 6252 } 6253 6254 @staticmethod 6255 def mode_name(mode): 6256 return name_or_number(HCI_Mode_Change_Event.MODE_NAMES, mode) 6257 6258 6259# ----------------------------------------------------------------------------- 6260@HCI_Event.event([('bd_addr', Address.parse_address)]) 6261class HCI_PIN_Code_Request_Event(HCI_Event): 6262 ''' 6263 See Bluetooth spec @ 7.7.22 PIN Code Request Event 6264 ''' 6265 6266 6267# ----------------------------------------------------------------------------- 6268@HCI_Event.event([('bd_addr', Address.parse_address)]) 6269class HCI_Link_Key_Request_Event(HCI_Event): 6270 ''' 6271 See Bluetooth spec @ 7.7.24 7.7.23 Link Key Request Event 6272 ''' 6273 6274 6275# ----------------------------------------------------------------------------- 6276@HCI_Event.event( 6277 [ 6278 ('bd_addr', Address.parse_address), 6279 ('link_key', 16), 6280 ('key_type', {'size': 1, 'mapper': HCI_Constant.link_key_type_name}), 6281 ] 6282) 6283class HCI_Link_Key_Notification_Event(HCI_Event): 6284 ''' 6285 See Bluetooth spec @ 7.7.24 Link Key Notification Event 6286 ''' 6287 6288 6289# ----------------------------------------------------------------------------- 6290@HCI_Event.event([('connection_handle', 2), ('lmp_max_slots', 1)]) 6291class HCI_Max_Slots_Change_Event(HCI_Event): 6292 ''' 6293 See Bluetooth spec @ 7.7.27 Max Slots Change Event 6294 ''' 6295 6296 6297# ----------------------------------------------------------------------------- 6298@HCI_Event.event( 6299 [('status', STATUS_SPEC), ('connection_handle', 2), ('clock_offset', 2)] 6300) 6301class HCI_Read_Clock_Offset_Complete_Event(HCI_Event): 6302 ''' 6303 See Bluetooth spec @ 7.7.28 Read Clock Offset Complete Event 6304 ''' 6305 6306 6307# ----------------------------------------------------------------------------- 6308@HCI_Event.event( 6309 [('status', STATUS_SPEC), ('connection_handle', 2), ('packet_type', 2)] 6310) 6311class HCI_Connection_Packet_Type_Changed_Event(HCI_Event): 6312 ''' 6313 See Bluetooth spec @ 7.7.29 Connection Packet Type Changed Event 6314 ''' 6315 6316 6317# ----------------------------------------------------------------------------- 6318@HCI_Event.event([('bd_addr', Address.parse_address), ('page_scan_repetition_mode', 1)]) 6319class HCI_Page_Scan_Repetition_Mode_Change_Event(HCI_Event): 6320 ''' 6321 See Bluetooth spec @ 7.7.31 Page Scan Repetition Mode Change Event 6322 ''' 6323 6324 6325# ----------------------------------------------------------------------------- 6326@HCI_Event.registered 6327class HCI_Inquiry_Result_With_RSSI_Event(HCI_Event): 6328 ''' 6329 See Bluetooth spec @ 7.7.33 Inquiry Result with RSSI Event 6330 ''' 6331 6332 RESPONSE_FIELDS = [ 6333 ('bd_addr', Address.parse_address), 6334 ('page_scan_repetition_mode', 1), 6335 ('reserved', 1), 6336 ('class_of_device', {'size': 3, 'mapper': map_class_of_device}), 6337 ('clock_offset', 2), 6338 ('rssi', -1), 6339 ] 6340 6341 @staticmethod 6342 def from_parameters(parameters): 6343 num_responses = parameters[0] 6344 responses = [] 6345 offset = 1 6346 for _ in range(num_responses): 6347 response = HCI_Object.from_bytes( 6348 parameters, offset, HCI_Inquiry_Result_With_RSSI_Event.RESPONSE_FIELDS 6349 ) 6350 offset += 14 6351 responses.append(response) 6352 6353 return HCI_Inquiry_Result_With_RSSI_Event(responses) 6354 6355 def __init__(self, responses): 6356 self.responses = responses[:] 6357 6358 # Serialize the fields 6359 parameters = bytes( 6360 [HCI_INQUIRY_RESULT_WITH_RSSI_EVENT, len(responses)] 6361 ) + b''.join([bytes(response) for response in responses]) 6362 6363 super().__init__(HCI_INQUIRY_RESULT_WITH_RSSI_EVENT, parameters) 6364 6365 def __str__(self): 6366 responses = '\n'.join( 6367 [response.to_string(indentation=' ') for response in self.responses] 6368 ) 6369 return f'{color("HCI_INQUIRY_RESULT_WITH_RSSI_EVENT", "magenta")}:\n{responses}' 6370 6371 6372# ----------------------------------------------------------------------------- 6373@HCI_Event.event( 6374 [ 6375 ('status', STATUS_SPEC), 6376 ('connection_handle', 2), 6377 ('page_number', 1), 6378 ('maximum_page_number', 1), 6379 ('extended_lmp_features', 8), 6380 ] 6381) 6382class HCI_Read_Remote_Extended_Features_Complete_Event(HCI_Event): 6383 ''' 6384 See Bluetooth spec @ 7.7.34 Read Remote Extended Features Complete Event 6385 ''' 6386 6387 6388# ----------------------------------------------------------------------------- 6389@HCI_Event.event( 6390 # pylint: disable=line-too-long 6391 [ 6392 ('status', STATUS_SPEC), 6393 ('connection_handle', 2), 6394 ('bd_addr', Address.parse_address), 6395 ( 6396 'link_type', 6397 { 6398 'size': 1, 6399 # pylint: disable-next=unnecessary-lambda 6400 'mapper': lambda x: HCI_Synchronous_Connection_Complete_Event.link_type_name( 6401 x 6402 ), 6403 }, 6404 ), 6405 ('transmission_interval', 1), 6406 ('retransmission_window', 1), 6407 ('rx_packet_length', 2), 6408 ('tx_packet_length', 2), 6409 ( 6410 'air_mode', 6411 { 6412 'size': 1, 6413 # pylint: disable-next=unnecessary-lambda 6414 'mapper': lambda x: HCI_Synchronous_Connection_Complete_Event.air_mode_name( 6415 x 6416 ), 6417 }, 6418 ), 6419 ] 6420) 6421class HCI_Synchronous_Connection_Complete_Event(HCI_Event): 6422 ''' 6423 See Bluetooth spec @ 7.7.35 Synchronous Connection Complete Event 6424 ''' 6425 6426 SCO_CONNECTION_LINK_TYPE = 0x00 6427 ESCO_CONNECTION_LINK_TYPE = 0x02 6428 6429 LINK_TYPE_NAMES = { 6430 SCO_CONNECTION_LINK_TYPE: 'SCO', 6431 ESCO_CONNECTION_LINK_TYPE: 'eSCO', 6432 } 6433 6434 U_LAW_LOG_AIR_MODE = 0x00 6435 A_LAW_LOG_AIR_MORE = 0x01 6436 CVSD_AIR_MODE = 0x02 6437 TRANSPARENT_DATA_AIR_MODE = 0x03 6438 6439 AIR_MODE_NAMES = { 6440 U_LAW_LOG_AIR_MODE: 'u-law log', 6441 A_LAW_LOG_AIR_MORE: 'A-law log', 6442 CVSD_AIR_MODE: 'CVSD', 6443 TRANSPARENT_DATA_AIR_MODE: 'Transparent Data', 6444 } 6445 6446 @staticmethod 6447 def link_type_name(link_type): 6448 return name_or_number( 6449 HCI_Synchronous_Connection_Complete_Event.LINK_TYPE_NAMES, link_type 6450 ) 6451 6452 @staticmethod 6453 def air_mode_name(air_mode): 6454 return name_or_number( 6455 HCI_Synchronous_Connection_Complete_Event.AIR_MODE_NAMES, air_mode 6456 ) 6457 6458 6459# ----------------------------------------------------------------------------- 6460@HCI_Event.event( 6461 [ 6462 ('status', STATUS_SPEC), 6463 ('connection_handle', 2), 6464 ('transmission_interval', 1), 6465 ('retransmission_window', 1), 6466 ('rx_packet_length', 2), 6467 ('tx_packet_length', 2), 6468 ] 6469) 6470class HCI_Synchronous_Connection_Changed_Event(HCI_Event): 6471 ''' 6472 See Bluetooth spec @ 7.7.36 Synchronous Connection Changed Event 6473 ''' 6474 6475 6476# ----------------------------------------------------------------------------- 6477@HCI_Event.event( 6478 [ 6479 ('status', STATUS_SPEC), 6480 ('connection_handle', 2), 6481 ('max_tx_latency', 2), 6482 ('max_rx_latency', 2), 6483 ('min_remote_timeout', 2), 6484 ('min_local_timeout', 2), 6485 ] 6486) 6487class HCI_Sniff_Subrating_Event(HCI_Event): 6488 ''' 6489 See Bluetooth spec @ 7.7.37 Sniff Subrating Event 6490 ''' 6491 6492 6493# ----------------------------------------------------------------------------- 6494@HCI_Event.event( 6495 [ 6496 ('num_responses', 1), 6497 ('bd_addr', Address.parse_address), 6498 ('page_scan_repetition_mode', 1), 6499 ('reserved', 1), 6500 ('class_of_device', {'size': 3, 'mapper': map_class_of_device}), 6501 ('clock_offset', 2), 6502 ('rssi', -1), 6503 ('extended_inquiry_response', 240), 6504 ] 6505) 6506class HCI_Extended_Inquiry_Result_Event(HCI_Event): 6507 ''' 6508 See Bluetooth spec @ 7.7.38 Extended Inquiry Result Event 6509 ''' 6510 6511 6512# ----------------------------------------------------------------------------- 6513@HCI_Event.event([('status', STATUS_SPEC), ('connection_handle', 2)]) 6514class HCI_Encryption_Key_Refresh_Complete_Event(HCI_Event): 6515 ''' 6516 See Bluetooth spec @ 7.7.39 Encryption Key Refresh Complete Event 6517 ''' 6518 6519 6520# ----------------------------------------------------------------------------- 6521@HCI_Event.event([('bd_addr', Address.parse_address)]) 6522class HCI_IO_Capability_Request_Event(HCI_Event): 6523 ''' 6524 See Bluetooth spec @ 7.7.40 IO Capability Request Event 6525 ''' 6526 6527 6528# ----------------------------------------------------------------------------- 6529@HCI_Event.event( 6530 [ 6531 ('bd_addr', Address.parse_address), 6532 ('io_capability', {'size': 1, 'mapper': HCI_Constant.io_capability_name}), 6533 ('oob_data_present', 1), 6534 ( 6535 'authentication_requirements', 6536 {'size': 1, 'mapper': HCI_Constant.authentication_requirements_name}, 6537 ), 6538 ] 6539) 6540class HCI_IO_Capability_Response_Event(HCI_Event): 6541 ''' 6542 See Bluetooth spec @ 7.7.41 IO Capability Response Event 6543 ''' 6544 6545 6546# ----------------------------------------------------------------------------- 6547@HCI_Event.event([('bd_addr', Address.parse_address), ('numeric_value', 4)]) 6548class HCI_User_Confirmation_Request_Event(HCI_Event): 6549 ''' 6550 See Bluetooth spec @ 7.7.42 User Confirmation Request Event 6551 ''' 6552 6553 6554# ----------------------------------------------------------------------------- 6555@HCI_Event.event([('bd_addr', Address.parse_address)]) 6556class HCI_User_Passkey_Request_Event(HCI_Event): 6557 ''' 6558 See Bluetooth spec @ 7.7.43 User Passkey Request Event 6559 ''' 6560 6561 6562# ----------------------------------------------------------------------------- 6563@HCI_Event.event([('bd_addr', Address.parse_address)]) 6564class HCI_Remote_OOB_Data_Request_Event(HCI_Event): 6565 ''' 6566 See Bluetooth spec @ 7.7.44 Remote OOB Data Request Event 6567 ''' 6568 6569 6570# ----------------------------------------------------------------------------- 6571@HCI_Event.event([('status', STATUS_SPEC), ('bd_addr', Address.parse_address)]) 6572class HCI_Simple_Pairing_Complete_Event(HCI_Event): 6573 ''' 6574 See Bluetooth spec @ 7.7.45 Simple Pairing Complete Event 6575 ''' 6576 6577 6578# ----------------------------------------------------------------------------- 6579@HCI_Event.event([('connection_handle', 2), ('link_supervision_timeout', 2)]) 6580class HCI_Link_Supervision_Timeout_Changed_Event(HCI_Event): 6581 ''' 6582 See Bluetooth spec @ 7.7.46 Link Supervision Timeout Changed Event 6583 ''' 6584 6585 6586# ----------------------------------------------------------------------------- 6587@HCI_Event.event([('handle', 2)]) 6588class HCI_Enhanced_Flush_Complete_Event(HCI_Event): 6589 ''' 6590 See Bluetooth spec @ 7.7.47 Enhanced Flush Complete Event 6591 ''' 6592 6593 6594# ----------------------------------------------------------------------------- 6595@HCI_Event.event([('bd_addr', Address.parse_address), ('passkey', 4)]) 6596class HCI_User_Passkey_Notification_Event(HCI_Event): 6597 ''' 6598 See Bluetooth spec @ 7.7.48 User Passkey Notification Event 6599 ''' 6600 6601 6602# ----------------------------------------------------------------------------- 6603@HCI_Event.event([('bd_addr', Address.parse_address), ('notification_type', 1)]) 6604class HCI_Keypress_Notification_Event(HCI_Event): 6605 ''' 6606 See Bluetooth spec @ 7.7.49 Keypress Notification Event 6607 ''' 6608 6609 6610# ----------------------------------------------------------------------------- 6611@HCI_Event.event([('bd_addr', Address.parse_address), ('host_supported_features', 8)]) 6612class HCI_Remote_Host_Supported_Features_Notification_Event(HCI_Event): 6613 ''' 6614 See Bluetooth spec @ 7.7.50 Remote Host Supported Features Notification Event 6615 ''' 6616 6617 6618# ----------------------------------------------------------------------------- 6619class HCI_AclDataPacket(HCI_Packet): 6620 ''' 6621 See Bluetooth spec @ 5.4.2 HCI ACL Data Packets 6622 ''' 6623 6624 hci_packet_type = HCI_ACL_DATA_PACKET 6625 6626 @staticmethod 6627 def from_bytes(packet: bytes) -> HCI_AclDataPacket: 6628 # Read the header 6629 h, data_total_length = struct.unpack_from('<HH', packet, 1) 6630 connection_handle = h & 0xFFF 6631 pb_flag = (h >> 12) & 3 6632 bc_flag = (h >> 14) & 3 6633 data = packet[5:] 6634 if len(data) != data_total_length: 6635 raise InvalidPacketError('invalid packet length') 6636 return HCI_AclDataPacket( 6637 connection_handle, pb_flag, bc_flag, data_total_length, data 6638 ) 6639 6640 def to_bytes(self): 6641 h = (self.pb_flag << 12) | (self.bc_flag << 14) | self.connection_handle 6642 return ( 6643 struct.pack('<BHH', HCI_ACL_DATA_PACKET, h, self.data_total_length) 6644 + self.data 6645 ) 6646 6647 def __init__(self, connection_handle, pb_flag, bc_flag, data_total_length, data): 6648 self.connection_handle = connection_handle 6649 self.pb_flag = pb_flag 6650 self.bc_flag = bc_flag 6651 self.data_total_length = data_total_length 6652 self.data = data 6653 6654 def __bytes__(self): 6655 return self.to_bytes() 6656 6657 def __str__(self): 6658 return ( 6659 f'{color("ACL", "blue")}: ' 6660 f'handle=0x{self.connection_handle:04x}, ' 6661 f'pb={self.pb_flag}, bc={self.bc_flag}, ' 6662 f'data_total_length={self.data_total_length}, ' 6663 f'data={self.data.hex()}' 6664 ) 6665 6666 6667# ----------------------------------------------------------------------------- 6668class HCI_SynchronousDataPacket(HCI_Packet): 6669 ''' 6670 See Bluetooth spec @ 5.4.3 HCI SCO Data Packets 6671 ''' 6672 6673 hci_packet_type = HCI_SYNCHRONOUS_DATA_PACKET 6674 6675 @staticmethod 6676 def from_bytes(packet: bytes) -> HCI_SynchronousDataPacket: 6677 # Read the header 6678 h, data_total_length = struct.unpack_from('<HB', packet, 1) 6679 connection_handle = h & 0xFFF 6680 packet_status = (h >> 12) & 0b11 6681 data = packet[4:] 6682 if len(data) != data_total_length: 6683 raise InvalidPacketError( 6684 f'invalid packet length {len(data)} != {data_total_length}' 6685 ) 6686 return HCI_SynchronousDataPacket( 6687 connection_handle, packet_status, data_total_length, data 6688 ) 6689 6690 def to_bytes(self) -> bytes: 6691 h = (self.packet_status << 12) | self.connection_handle 6692 return ( 6693 struct.pack('<BHB', HCI_SYNCHRONOUS_DATA_PACKET, h, self.data_total_length) 6694 + self.data 6695 ) 6696 6697 def __init__( 6698 self, 6699 connection_handle: int, 6700 packet_status: int, 6701 data_total_length: int, 6702 data: bytes, 6703 ) -> None: 6704 self.connection_handle = connection_handle 6705 self.packet_status = packet_status 6706 self.data_total_length = data_total_length 6707 self.data = data 6708 6709 def __bytes__(self) -> bytes: 6710 return self.to_bytes() 6711 6712 def __str__(self) -> str: 6713 return ( 6714 f'{color("SCO", "blue")}: ' 6715 f'handle=0x{self.connection_handle:04x}, ' 6716 f'ps={self.packet_status}, ' 6717 f'data_total_length={self.data_total_length}, ' 6718 f'data={self.data.hex()}' 6719 ) 6720 6721 6722# ----------------------------------------------------------------------------- 6723@dataclasses.dataclass 6724class HCI_IsoDataPacket(HCI_Packet): 6725 ''' 6726 See Bluetooth spec @ 5.4.5 HCI ISO Data Packets 6727 ''' 6728 6729 hci_packet_type: ClassVar[int] = HCI_ISO_DATA_PACKET 6730 6731 connection_handle: int 6732 data_total_length: int 6733 iso_sdu_fragment: bytes 6734 pb_flag: int 6735 ts_flag: int = 0 6736 time_stamp: Optional[int] = None 6737 packet_sequence_number: Optional[int] = None 6738 iso_sdu_length: Optional[int] = None 6739 packet_status_flag: Optional[int] = None 6740 6741 @staticmethod 6742 def from_bytes(packet: bytes) -> HCI_IsoDataPacket: 6743 time_stamp: Optional[int] = None 6744 packet_sequence_number: Optional[int] = None 6745 iso_sdu_length: Optional[int] = None 6746 packet_status_flag: Optional[int] = None 6747 6748 pos = 1 6749 pdu_info, data_total_length = struct.unpack_from('<HH', packet, pos) 6750 connection_handle = pdu_info & 0xFFF 6751 pb_flag = (pdu_info >> 12) & 0b11 6752 ts_flag = (pdu_info >> 14) & 0b01 6753 pos += 4 6754 6755 # pb_flag in (0b00, 0b10) but faster 6756 should_include_sdu_info = not (pb_flag & 0b01) 6757 6758 if ts_flag: 6759 if not should_include_sdu_info: 6760 logger.warning(f'Timestamp included when pb_flag={bin(pb_flag)}') 6761 time_stamp, *_ = struct.unpack_from('<I', packet, pos) 6762 pos += 4 6763 6764 if should_include_sdu_info: 6765 packet_sequence_number, sdu_info = struct.unpack_from('<HH', packet, pos) 6766 iso_sdu_length = sdu_info & 0xFFF 6767 packet_status_flag = sdu_info >> 14 6768 pos += 4 6769 6770 iso_sdu_fragment = packet[pos:] 6771 return HCI_IsoDataPacket( 6772 connection_handle=connection_handle, 6773 pb_flag=pb_flag, 6774 ts_flag=ts_flag, 6775 data_total_length=data_total_length, 6776 time_stamp=time_stamp, 6777 packet_sequence_number=packet_sequence_number, 6778 iso_sdu_length=iso_sdu_length, 6779 packet_status_flag=packet_status_flag, 6780 iso_sdu_fragment=iso_sdu_fragment, 6781 ) 6782 6783 def __bytes__(self) -> bytes: 6784 return self.to_bytes() 6785 6786 def to_bytes(self) -> bytes: 6787 fmt = '<BHH' 6788 args = [ 6789 HCI_ISO_DATA_PACKET, 6790 self.ts_flag << 14 | self.pb_flag << 12 | self.connection_handle, 6791 self.data_total_length, 6792 ] 6793 if self.time_stamp is not None: 6794 fmt += 'I' 6795 args.append(self.time_stamp) 6796 if ( 6797 self.packet_sequence_number is not None 6798 and self.iso_sdu_length is not None 6799 and self.packet_status_flag is not None 6800 ): 6801 fmt += 'HH' 6802 args += [ 6803 self.packet_sequence_number, 6804 self.iso_sdu_length | self.packet_status_flag << 14, 6805 ] 6806 return struct.pack(fmt, *args) + self.iso_sdu_fragment 6807 6808 def __str__(self) -> str: 6809 return ( 6810 f'{color("ISO", "blue")}: ' 6811 f'handle=0x{self.connection_handle:04x}, ' 6812 f'ps={self.packet_status_flag}, ' 6813 f'data_total_length={self.data_total_length}, ' 6814 f'sdu={self.iso_sdu_fragment.hex()}' 6815 ) 6816 6817 6818# ----------------------------------------------------------------------------- 6819class HCI_AclDataPacketAssembler: 6820 current_data: Optional[bytes] 6821 6822 def __init__(self, callback: Callable[[bytes], Any]) -> None: 6823 self.callback = callback 6824 self.current_data = None 6825 self.l2cap_pdu_length = 0 6826 6827 def feed_packet(self, packet: HCI_AclDataPacket) -> None: 6828 if packet.pb_flag in ( 6829 HCI_ACL_PB_FIRST_NON_FLUSHABLE, 6830 HCI_ACL_PB_FIRST_FLUSHABLE, 6831 ): 6832 (l2cap_pdu_length,) = struct.unpack_from('<H', packet.data, 0) 6833 self.current_data = packet.data 6834 self.l2cap_pdu_length = l2cap_pdu_length 6835 elif packet.pb_flag == HCI_ACL_PB_CONTINUATION: 6836 if self.current_data is None: 6837 logger.warning('!!! ACL continuation without start') 6838 return 6839 self.current_data += packet.data 6840 6841 assert self.current_data is not None 6842 if len(self.current_data) == self.l2cap_pdu_length + 4: 6843 # The packet is complete, invoke the callback 6844 logger.debug(f'<<< ACL PDU: {self.current_data.hex()}') 6845 self.callback(self.current_data) 6846 6847 # Reset 6848 self.current_data = None 6849 self.l2cap_pdu_length = 0 6850 else: 6851 # Compliance check 6852 if len(self.current_data) > self.l2cap_pdu_length + 4: 6853 logger.warning('!!! ACL data exceeds L2CAP PDU') 6854 self.current_data = None 6855 self.l2cap_pdu_length = 0 6856