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