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