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