mirror of
https://github.com/google/bumble.git
synced 2026-04-16 00:25:31 +00:00
8200 lines
353 KiB
Python
8200 lines
353 KiB
Python
# Copyright 2021-2022 Google LLC
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# https://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Imports
|
|
# -----------------------------------------------------------------------------
|
|
from __future__ import annotations
|
|
|
|
import collections
|
|
import dataclasses
|
|
import enum
|
|
import functools
|
|
import logging
|
|
import secrets
|
|
import struct
|
|
from collections.abc import Callable, Iterable, Sequence
|
|
from dataclasses import field
|
|
from typing import (
|
|
Any,
|
|
ClassVar,
|
|
Generic,
|
|
Literal,
|
|
SupportsBytes,
|
|
TypeVar,
|
|
cast,
|
|
)
|
|
|
|
from typing_extensions import Self
|
|
|
|
from bumble import crypto, utils
|
|
from bumble.colors import color
|
|
from bumble.core import (
|
|
DeviceClass,
|
|
InvalidArgumentError,
|
|
InvalidPacketError,
|
|
PhysicalTransport,
|
|
ProtocolError,
|
|
bit_flags_to_strings,
|
|
name_or_number,
|
|
padded_bytes,
|
|
)
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Logging
|
|
# -----------------------------------------------------------------------------
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Utils
|
|
# -----------------------------------------------------------------------------
|
|
def hci_command_op_code(ogf, ocf):
|
|
return ogf << 10 | ocf
|
|
|
|
|
|
def hci_vendor_command_op_code(ocf):
|
|
return hci_command_op_code(HCI_VENDOR_OGF, ocf)
|
|
|
|
|
|
def key_with_value(dictionary, target_value):
|
|
for key, value in dictionary.items():
|
|
if value == target_value:
|
|
return key
|
|
return None
|
|
|
|
|
|
def indent_lines(string):
|
|
return '\n'.join([' ' + line for line in string.split('\n')])
|
|
|
|
|
|
def map_null_terminated_utf8_string(utf8_bytes: bytes) -> str | bytes:
|
|
try:
|
|
terminator = utf8_bytes.find(0)
|
|
if terminator < 0:
|
|
terminator = len(utf8_bytes)
|
|
return utf8_bytes[0:terminator].decode('utf8')
|
|
except UnicodeDecodeError:
|
|
return utf8_bytes
|
|
|
|
|
|
def map_class_of_device(class_of_device: int) -> str:
|
|
(
|
|
service_classes,
|
|
major_device_class,
|
|
minor_device_class,
|
|
) = DeviceClass.split_class_of_device(class_of_device)
|
|
return (
|
|
f'[{class_of_device:06X}] Services('
|
|
f'{",".join(DeviceClass.service_class_labels(service_classes))}),'
|
|
f'Class({DeviceClass.major_device_class_name(major_device_class)}|'
|
|
f'{DeviceClass.minor_device_class_name(major_device_class, minor_device_class)}'
|
|
')'
|
|
)
|
|
|
|
|
|
def phy_list_to_bits(phys: Iterable[Phy] | None) -> int:
|
|
if phys is None:
|
|
return 0
|
|
|
|
phy_bits = 0
|
|
for phy in phys:
|
|
if phy not in HCI_LE_PHY_TYPE_TO_BIT:
|
|
raise InvalidArgumentError('invalid PHY')
|
|
phy_bits |= 1 << HCI_LE_PHY_TYPE_TO_BIT[phy]
|
|
return phy_bits
|
|
|
|
|
|
class SpecableEnum(utils.OpenIntEnum):
|
|
@classmethod
|
|
def type_spec(cls, size: int, byteorder: Literal['little', 'big'] = 'little'):
|
|
return {
|
|
'serializer': lambda x: x.to_bytes(size, byteorder),
|
|
'parser': lambda data, offset: (
|
|
offset + size,
|
|
cls(int.from_bytes(data[offset : offset + size], byteorder)),
|
|
),
|
|
'mapper': lambda x: cls(x).name,
|
|
}
|
|
|
|
@classmethod
|
|
def type_metadata(
|
|
cls,
|
|
size: int,
|
|
list_begin: bool = False,
|
|
list_end: bool = False,
|
|
byteorder: Literal['little', 'big'] = 'little',
|
|
):
|
|
return metadata(
|
|
cls.type_spec(size, byteorder),
|
|
list_begin=list_begin,
|
|
list_end=list_end,
|
|
)
|
|
|
|
|
|
class SpecableFlag(enum.IntFlag):
|
|
@classmethod
|
|
def type_spec(cls, size: int, byteorder: Literal['little', 'big'] = 'little'):
|
|
return {
|
|
'serializer': lambda x: x.to_bytes(size, byteorder),
|
|
'parser': lambda data, offset: (
|
|
offset + size,
|
|
cls(int.from_bytes(data[offset : offset + size], byteorder)),
|
|
),
|
|
'mapper': lambda x: cls(x).name,
|
|
}
|
|
|
|
@classmethod
|
|
def type_metadata(
|
|
cls,
|
|
size: int,
|
|
list_begin: bool = False,
|
|
list_end: bool = False,
|
|
byteorder: Literal['little', 'big'] = 'little',
|
|
):
|
|
return metadata(
|
|
cls.type_spec(size, byteorder),
|
|
list_begin=list_begin,
|
|
list_end=list_end,
|
|
)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Field Metadata
|
|
# -----------------------------------------------------------------------------
|
|
# Field specification can be:
|
|
# - a dict with "serializer", "parser", "size", "mapper" keys
|
|
# - a callable that takes (packet, offset) and returns (new_offset, value) (deserialize only)
|
|
# - a string of
|
|
# - ">2" and ">4" for 2-byte and 4-byte big-endian integers
|
|
# - "*" for all remaining bytes in the packet
|
|
# - "v" for variable length bytes with a leading length byte
|
|
# - an integer [1, 4] for 1-byte, 2-byte or 4-byte unsigned little-endian integers
|
|
# - an integer [-2, -1] for 1-byte, 2-byte signed little-endian integers
|
|
FieldSpec = dict[str, Any] | Callable[[bytes, int], tuple[int, Any]] | str | int
|
|
Fields = Sequence['tuple[str, FieldSpec] | Fields']
|
|
|
|
|
|
@dataclasses.dataclass
|
|
class FieldMetadata:
|
|
spec: FieldSpec
|
|
list_begin: bool = False
|
|
list_end: bool = False
|
|
|
|
|
|
def metadata(
|
|
spec: FieldSpec, list_begin: bool = False, list_end: bool = False
|
|
) -> dict[str, Any]:
|
|
return {
|
|
"bumble.hci": FieldMetadata(spec=spec, list_begin=list_begin, list_end=list_end)
|
|
}
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Constants
|
|
# -----------------------------------------------------------------------------
|
|
# fmt: off
|
|
# pylint: disable=line-too-long
|
|
|
|
HCI_VENDOR_OGF = 0x3F
|
|
|
|
# Specification Version
|
|
class SpecificationVersion(SpecableEnum):
|
|
BLUETOOTH_CORE_1_0B = 0
|
|
BLUETOOTH_CORE_1_1 = 1
|
|
BLUETOOTH_CORE_1_2 = 2
|
|
BLUETOOTH_CORE_2_0_EDR = 3
|
|
BLUETOOTH_CORE_2_1_EDR = 4
|
|
BLUETOOTH_CORE_3_0_HS = 5
|
|
BLUETOOTH_CORE_4_0 = 6
|
|
BLUETOOTH_CORE_4_1 = 7
|
|
BLUETOOTH_CORE_4_2 = 8
|
|
BLUETOOTH_CORE_5_0 = 9
|
|
BLUETOOTH_CORE_5_1 = 10
|
|
BLUETOOTH_CORE_5_2 = 11
|
|
BLUETOOTH_CORE_5_3 = 12
|
|
BLUETOOTH_CORE_5_4 = 13
|
|
BLUETOOTH_CORE_6_0 = 14
|
|
BLUETOOTH_CORE_6_1 = 15
|
|
BLUETOOTH_CORE_6_2 = 16
|
|
|
|
# For backwards compatibility only
|
|
HCI_VERSION_BLUETOOTH_CORE_1_0B = SpecificationVersion.BLUETOOTH_CORE_1_0B
|
|
HCI_VERSION_BLUETOOTH_CORE_1_1 = SpecificationVersion.BLUETOOTH_CORE_1_1
|
|
HCI_VERSION_BLUETOOTH_CORE_1_2 = SpecificationVersion.BLUETOOTH_CORE_1_2
|
|
HCI_VERSION_BLUETOOTH_CORE_2_0_EDR = SpecificationVersion.BLUETOOTH_CORE_2_0_EDR
|
|
HCI_VERSION_BLUETOOTH_CORE_2_1_EDR = SpecificationVersion.BLUETOOTH_CORE_2_1_EDR
|
|
HCI_VERSION_BLUETOOTH_CORE_3_0_HS = SpecificationVersion.BLUETOOTH_CORE_3_0_HS
|
|
HCI_VERSION_BLUETOOTH_CORE_4_0 = SpecificationVersion.BLUETOOTH_CORE_4_0
|
|
HCI_VERSION_BLUETOOTH_CORE_4_1 = SpecificationVersion.BLUETOOTH_CORE_4_1
|
|
HCI_VERSION_BLUETOOTH_CORE_4_2 = SpecificationVersion.BLUETOOTH_CORE_4_2
|
|
HCI_VERSION_BLUETOOTH_CORE_5_0 = SpecificationVersion.BLUETOOTH_CORE_5_0
|
|
HCI_VERSION_BLUETOOTH_CORE_5_1 = SpecificationVersion.BLUETOOTH_CORE_5_1
|
|
HCI_VERSION_BLUETOOTH_CORE_5_2 = SpecificationVersion.BLUETOOTH_CORE_5_2
|
|
HCI_VERSION_BLUETOOTH_CORE_5_3 = SpecificationVersion.BLUETOOTH_CORE_5_3
|
|
HCI_VERSION_BLUETOOTH_CORE_5_4 = SpecificationVersion.BLUETOOTH_CORE_5_4
|
|
HCI_VERSION_BLUETOOTH_CORE_6_0 = SpecificationVersion.BLUETOOTH_CORE_6_0
|
|
HCI_VERSION_BLUETOOTH_CORE_6_1 = SpecificationVersion.BLUETOOTH_CORE_6_1
|
|
HCI_VERSION_BLUETOOTH_CORE_6_2 = SpecificationVersion.BLUETOOTH_CORE_6_2
|
|
|
|
# HCI Packet types
|
|
HCI_COMMAND_PACKET = 0x01
|
|
HCI_ACL_DATA_PACKET = 0x02
|
|
HCI_SYNCHRONOUS_DATA_PACKET = 0x03
|
|
HCI_EVENT_PACKET = 0x04
|
|
HCI_ISO_DATA_PACKET = 0x05
|
|
|
|
# HCI Event Codes
|
|
HCI_INQUIRY_COMPLETE_EVENT = 0x01
|
|
HCI_INQUIRY_RESULT_EVENT = 0x02
|
|
HCI_CONNECTION_COMPLETE_EVENT = 0x03
|
|
HCI_CONNECTION_REQUEST_EVENT = 0x04
|
|
HCI_DISCONNECTION_COMPLETE_EVENT = 0x05
|
|
HCI_AUTHENTICATION_COMPLETE_EVENT = 0x06
|
|
HCI_REMOTE_NAME_REQUEST_COMPLETE_EVENT = 0x07
|
|
HCI_ENCRYPTION_CHANGE_EVENT = 0x08
|
|
HCI_CHANGE_CONNECTION_LINK_KEY_COMPLETE_EVENT = 0x09
|
|
HCI_LINK_KEY_TYPE_CHANGED_EVENT = 0x0A
|
|
HCI_READ_REMOTE_SUPPORTED_FEATURES_COMPLETE_EVENT = 0x0B
|
|
HCI_READ_REMOTE_VERSION_INFORMATION_COMPLETE_EVENT = 0x0C
|
|
HCI_QOS_SETUP_COMPLETE_EVENT = 0x0D
|
|
HCI_COMMAND_COMPLETE_EVENT = 0x0E
|
|
HCI_COMMAND_STATUS_EVENT = 0x0F
|
|
HCI_HARDWARE_ERROR_EVENT = 0x10
|
|
HCI_FLUSH_OCCURRED_EVENT = 0x11
|
|
HCI_ROLE_CHANGE_EVENT = 0x12
|
|
HCI_NUMBER_OF_COMPLETED_PACKETS_EVENT = 0x13
|
|
HCI_MODE_CHANGE_EVENT = 0x14
|
|
HCI_RETURN_LINK_KEYS_EVENT = 0x15
|
|
HCI_PIN_CODE_REQUEST_EVENT = 0x16
|
|
HCI_LINK_KEY_REQUEST_EVENT = 0x17
|
|
HCI_LINK_KEY_NOTIFICATION_EVENT = 0x18
|
|
HCI_LOOPBACK_COMMAND_EVENT = 0x19
|
|
HCI_DATA_BUFFER_OVERFLOW_EVENT = 0x1A
|
|
HCI_MAX_SLOTS_CHANGE_EVENT = 0x1B
|
|
HCI_READ_CLOCK_OFFSET_COMPLETE_EVENT = 0x1C
|
|
HCI_CONNECTION_PACKET_TYPE_CHANGED_EVENT = 0x1D
|
|
HCI_QOS_VIOLATION_EVENT = 0x1E
|
|
HCI_PAGE_SCAN_REPETITION_MODE_CHANGE_EVENT = 0x20
|
|
HCI_FLOW_SPECIFICATION_COMPLETE_EVENT = 0x21
|
|
HCI_INQUIRY_RESULT_WITH_RSSI_EVENT = 0x22
|
|
HCI_READ_REMOTE_EXTENDED_FEATURES_COMPLETE_EVENT = 0x23
|
|
HCI_SYNCHRONOUS_CONNECTION_COMPLETE_EVENT = 0x2C
|
|
HCI_SYNCHRONOUS_CONNECTION_CHANGED_EVENT = 0x2D
|
|
HCI_SNIFF_SUBRATING_EVENT = 0x2E
|
|
HCI_EXTENDED_INQUIRY_RESULT_EVENT = 0x2F
|
|
HCI_ENCRYPTION_KEY_REFRESH_COMPLETE_EVENT = 0x30
|
|
HCI_IO_CAPABILITY_REQUEST_EVENT = 0x31
|
|
HCI_IO_CAPABILITY_RESPONSE_EVENT = 0x32
|
|
HCI_USER_CONFIRMATION_REQUEST_EVENT = 0x33
|
|
HCI_USER_PASSKEY_REQUEST_EVENT = 0x34
|
|
HCI_REMOTE_OOB_DATA_REQUEST_EVENT = 0x35
|
|
HCI_SIMPLE_PAIRING_COMPLETE_EVENT = 0x36
|
|
HCI_LINK_SUPERVISION_TIMEOUT_CHANGED_EVENT = 0x38
|
|
HCI_ENHANCED_FLUSH_COMPLETE_EVENT = 0x39
|
|
HCI_USER_PASSKEY_NOTIFICATION_EVENT = 0x3B
|
|
HCI_KEYPRESS_NOTIFICATION_EVENT = 0x3C
|
|
HCI_REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION_EVENT = 0x3D
|
|
HCI_LE_META_EVENT = 0x3E
|
|
HCI_NUMBER_OF_COMPLETED_DATA_BLOCKS_EVENT = 0x48
|
|
HCI_TRIGGERED_CLOCK_CAPTURE_EVENT = 0X4E
|
|
HCI_SYNCHRONIZATION_TRAIN_COMPLETE_EVENT = 0X4F
|
|
HCI_SYNCHRONIZATION_TRAIN_RECEIVED_EVENT = 0X50
|
|
HCI_CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVE_EVENT = 0X51
|
|
HCI_CONNECTIONLESS_PERIPHERAL_BROADCAST_TIMEOUT_EVENT = 0X52
|
|
HCI_TRUNCATED_PAGE_COMPLETE_EVENT = 0X53
|
|
HCI_PERIPHERAL_PAGE_RESPONSE_TIMEOUT_EVENT = 0X54
|
|
HCI_CONNECTIONLESS_PERIPHERAL_BROADCAST_CHANNEL_MAP_CHANGE_EVENT = 0X55
|
|
HCI_INQUIRY_RESPONSE_NOTIFICATION_EVENT = 0X56
|
|
HCI_AUTHENTICATED_PAYLOAD_TIMEOUT_EXPIRED_EVENT = 0X57
|
|
HCI_SAM_STATUS_CHANGE_EVENT = 0X58
|
|
HCI_ENCRYPTION_CHANGE_V2_EVENT = 0x59
|
|
|
|
HCI_VENDOR_EVENT = 0xFF
|
|
|
|
|
|
# HCI Subevent Codes
|
|
HCI_LE_CONNECTION_COMPLETE_EVENT = 0x01
|
|
HCI_LE_ADVERTISING_REPORT_EVENT = 0x02
|
|
HCI_LE_CONNECTION_UPDATE_COMPLETE_EVENT = 0x03
|
|
HCI_LE_READ_REMOTE_FEATURES_COMPLETE_EVENT = 0x04
|
|
HCI_LE_LONG_TERM_KEY_REQUEST_EVENT = 0x05
|
|
HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_EVENT = 0x06
|
|
HCI_LE_DATA_LENGTH_CHANGE_EVENT = 0x07
|
|
HCI_LE_READ_LOCAL_P_256_PUBLIC_KEY_COMPLETE_EVENT = 0x08
|
|
HCI_LE_GENERATE_DHKEY_COMPLETE_EVENT = 0x09
|
|
HCI_LE_ENHANCED_CONNECTION_COMPLETE_EVENT = 0x0A
|
|
HCI_LE_DIRECTED_ADVERTISING_REPORT_EVENT = 0x0B
|
|
HCI_LE_PHY_UPDATE_COMPLETE_EVENT = 0x0C
|
|
HCI_LE_EXTENDED_ADVERTISING_REPORT_EVENT = 0x0D
|
|
HCI_LE_PERIODIC_ADVERTISING_SYNC_ESTABLISHED_EVENT = 0x0E
|
|
HCI_LE_PERIODIC_ADVERTISING_REPORT_EVENT = 0x0F
|
|
HCI_LE_PERIODIC_ADVERTISING_SYNC_LOST_EVENT = 0x10
|
|
HCI_LE_SCAN_TIMEOUT_EVENT = 0x11
|
|
HCI_LE_ADVERTISING_SET_TERMINATED_EVENT = 0x12
|
|
HCI_LE_SCAN_REQUEST_RECEIVED_EVENT = 0x13
|
|
HCI_LE_CHANNEL_SELECTION_ALGORITHM_EVENT = 0x14
|
|
HCI_LE_CONNECTIONLESS_IQ_REPORT_EVENT = 0X15
|
|
HCI_LE_CONNECTION_IQ_REPORT_EVENT = 0X16
|
|
HCI_LE_CTE_REQUEST_FAILED_EVENT = 0X17
|
|
HCI_LE_PERIODIC_ADVERTISING_SYNC_TRANSFER_RECEIVED_EVENT = 0X18
|
|
HCI_LE_CIS_ESTABLISHED_EVENT = 0X19
|
|
HCI_LE_CIS_REQUEST_EVENT = 0X1A
|
|
HCI_LE_CREATE_BIG_COMPLETE_EVENT = 0X1B
|
|
HCI_LE_TERMINATE_BIG_COMPLETE_EVENT = 0X1C
|
|
HCI_LE_BIG_SYNC_ESTABLISHED_EVENT = 0X1D
|
|
HCI_LE_BIG_SYNC_LOST_EVENT = 0X1E
|
|
HCI_LE_REQUEST_PEER_SCA_COMPLETE_EVENT = 0X1F
|
|
HCI_LE_PATH_LOSS_THRESHOLD_EVENT = 0X20
|
|
HCI_LE_TRANSMIT_POWER_REPORTING_EVENT = 0X21
|
|
HCI_LE_BIGINFO_ADVERTISING_REPORT_EVENT = 0X22
|
|
HCI_LE_SUBRATE_CHANGE_EVENT = 0X23
|
|
HCI_LE_PERIODIC_ADVERTISING_SYNC_ESTABLISHED_V2_EVENT = 0X24
|
|
HCI_LE_PERIODIC_ADVERTISING_REPORT_V2_EVENT = 0X25
|
|
HCI_LE_PERIODIC_ADVERTISING_SYNC_TRANSFER_RECEIVED_V2_EVENT = 0X26
|
|
HCI_LE_PERIODIC_ADVERTISING_SUBEVENT_DATA_REQUEST_EVENT = 0X27
|
|
HCI_LE_PERIODIC_ADVERTISING_RESPONSE_REPORT_EVENT = 0X28
|
|
HCI_LE_ENHANCED_CONNECTION_COMPLETE_V2_EVENT = 0X29
|
|
HCI_LE_CIS_ESTABLISHED_V2_EVENT = 0x2A
|
|
HCI_LE_READ_ALL_REMOTE_FEATURES_COMPLETE_EVENT = 0x2B
|
|
HCI_LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES_COMPLETE_EVENT = 0x2C
|
|
HCI_LE_CS_READ_REMOTE_FAE_TABLE_COMPLETE_EVENT = 0x2D
|
|
HCI_LE_CS_SECURITY_ENABLE_COMPLETE_EVENT = 0x2E
|
|
HCI_LE_CS_CONFIG_COMPLETE_EVENT = 0x2F
|
|
HCI_LE_CS_PROCEDURE_ENABLE_COMPLETE_EVENT = 0x30
|
|
HCI_LE_CS_SUBEVENT_RESULT_EVENT = 0x31
|
|
HCI_LE_CS_SUBEVENT_RESULT_CONTINUE_EVENT = 0x32
|
|
HCI_LE_CS_TEST_END_COMPLETE_EVENT = 0x33
|
|
HCI_LE_MONITORED_ADVERTISERS_REPORT_EVENT = 0x34
|
|
HCI_LE_FRAME_SPACE_UPDATE_COMPLETE_EVENT = 0x35
|
|
HCI_LE_UTP_RECEIVE_EVENT = 0x36
|
|
HCI_LE_CONNECTION_RATE_CHANGE_EVENT = 0x37
|
|
|
|
|
|
# HCI Command
|
|
HCI_INQUIRY_COMMAND = hci_command_op_code(0x01, 0x0001)
|
|
HCI_INQUIRY_CANCEL_COMMAND = hci_command_op_code(0x01, 0x0002)
|
|
HCI_PERIODIC_INQUIRY_MODE_COMMAND = hci_command_op_code(0x01, 0x0003)
|
|
HCI_EXIT_PERIODIC_INQUIRY_MODE_COMMAND = hci_command_op_code(0x01, 0x0004)
|
|
HCI_CREATE_CONNECTION_COMMAND = hci_command_op_code(0x01, 0x0005)
|
|
HCI_DISCONNECT_COMMAND = hci_command_op_code(0x01, 0x0006)
|
|
HCI_CREATE_CONNECTION_CANCEL_COMMAND = hci_command_op_code(0x01, 0x0008)
|
|
HCI_ACCEPT_CONNECTION_REQUEST_COMMAND = hci_command_op_code(0x01, 0x0009)
|
|
HCI_REJECT_CONNECTION_REQUEST_COMMAND = hci_command_op_code(0x01, 0x000A)
|
|
HCI_LINK_KEY_REQUEST_REPLY_COMMAND = hci_command_op_code(0x01, 0x000B)
|
|
HCI_LINK_KEY_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x01, 0x000C)
|
|
HCI_PIN_CODE_REQUEST_REPLY_COMMAND = hci_command_op_code(0x01, 0x000D)
|
|
HCI_PIN_CODE_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x01, 0x000E)
|
|
HCI_CHANGE_CONNECTION_PACKET_TYPE_COMMAND = hci_command_op_code(0x01, 0x000F)
|
|
HCI_AUTHENTICATION_REQUESTED_COMMAND = hci_command_op_code(0x01, 0x0011)
|
|
HCI_SET_CONNECTION_ENCRYPTION_COMMAND = hci_command_op_code(0x01, 0x0013)
|
|
HCI_CHANGE_CONNECTION_LINK_KEY_COMMAND = hci_command_op_code(0x01, 0x0015)
|
|
HCI_LINK_KEY_SELECTION_COMMAND = hci_command_op_code(0x01, 0x0017)
|
|
HCI_REMOTE_NAME_REQUEST_COMMAND = hci_command_op_code(0x01, 0x0019)
|
|
HCI_REMOTE_NAME_REQUEST_CANCEL_COMMAND = hci_command_op_code(0x01, 0x001A)
|
|
HCI_READ_REMOTE_SUPPORTED_FEATURES_COMMAND = hci_command_op_code(0x01, 0x001B)
|
|
HCI_READ_REMOTE_EXTENDED_FEATURES_COMMAND = hci_command_op_code(0x01, 0x001C)
|
|
HCI_READ_REMOTE_VERSION_INFORMATION_COMMAND = hci_command_op_code(0x01, 0x001D)
|
|
HCI_READ_CLOCK_OFFSET_COMMAND = hci_command_op_code(0x01, 0x001F)
|
|
HCI_READ_LMP_HANDLE_COMMAND = hci_command_op_code(0x01, 0x0020)
|
|
HCI_SETUP_SYNCHRONOUS_CONNECTION_COMMAND = hci_command_op_code(0x01, 0x0028)
|
|
HCI_ACCEPT_SYNCHRONOUS_CONNECTION_REQUEST_COMMAND = hci_command_op_code(0x01, 0x0029)
|
|
HCI_REJECT_SYNCHRONOUS_CONNECTION_REQUEST_COMMAND = hci_command_op_code(0x01, 0x002A)
|
|
HCI_IO_CAPABILITY_REQUEST_REPLY_COMMAND = hci_command_op_code(0x01, 0x002B)
|
|
HCI_USER_CONFIRMATION_REQUEST_REPLY_COMMAND = hci_command_op_code(0x01, 0x002C)
|
|
HCI_USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x01, 0x002D)
|
|
HCI_USER_PASSKEY_REQUEST_REPLY_COMMAND = hci_command_op_code(0x01, 0x002E)
|
|
HCI_USER_PASSKEY_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x01, 0x002F)
|
|
HCI_REMOTE_OOB_DATA_REQUEST_REPLY_COMMAND = hci_command_op_code(0x01, 0x0030)
|
|
HCI_REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x01, 0x0033)
|
|
HCI_IO_CAPABILITY_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x01, 0x0034)
|
|
HCI_ENHANCED_SETUP_SYNCHRONOUS_CONNECTION_COMMAND = hci_command_op_code(0x01, 0x003D)
|
|
HCI_ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION_REQUEST_COMMAND = hci_command_op_code(0x01, 0x003E)
|
|
HCI_TRUNCATED_PAGE_COMMAND = hci_command_op_code(0x01, 0x003F)
|
|
HCI_TRUNCATED_PAGE_CANCEL_COMMAND = hci_command_op_code(0x01, 0x0040)
|
|
HCI_SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_COMMAND = hci_command_op_code(0x01, 0x0041)
|
|
HCI_SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVE_COMMAND = hci_command_op_code(0x01, 0x0042)
|
|
HCI_START_SYNCHRONIZATION_TRAIN_COMMAND = hci_command_op_code(0x01, 0x0043)
|
|
HCI_RECEIVE_SYNCHRONIZATION_TRAIN_COMMAND = hci_command_op_code(0x01, 0x0044)
|
|
HCI_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_COMMAND = hci_command_op_code(0x01, 0x0045)
|
|
HCI_HOLD_MODE_COMMAND = hci_command_op_code(0x02, 0x0001)
|
|
HCI_SNIFF_MODE_COMMAND = hci_command_op_code(0x02, 0x0003)
|
|
HCI_EXIT_SNIFF_MODE_COMMAND = hci_command_op_code(0x02, 0x0004)
|
|
HCI_QOS_SETUP_COMMAND = hci_command_op_code(0x02, 0x0007)
|
|
HCI_ROLE_DISCOVERY_COMMAND = hci_command_op_code(0x02, 0x0009)
|
|
HCI_SWITCH_ROLE_COMMAND = hci_command_op_code(0x02, 0x000B)
|
|
HCI_READ_LINK_POLICY_SETTINGS_COMMAND = hci_command_op_code(0x02, 0x000C)
|
|
HCI_WRITE_LINK_POLICY_SETTINGS_COMMAND = hci_command_op_code(0x02, 0x000D)
|
|
HCI_READ_DEFAULT_LINK_POLICY_SETTINGS_COMMAND = hci_command_op_code(0x02, 0x000E)
|
|
HCI_WRITE_DEFAULT_LINK_POLICY_SETTINGS_COMMAND = hci_command_op_code(0x02, 0x000F)
|
|
HCI_FLOW_SPECIFICATION_COMMAND = hci_command_op_code(0x02, 0x0010)
|
|
HCI_SNIFF_SUBRATING_COMMAND = hci_command_op_code(0x02, 0x0011)
|
|
HCI_SET_EVENT_MASK_COMMAND = hci_command_op_code(0x03, 0x0001)
|
|
HCI_RESET_COMMAND = hci_command_op_code(0x03, 0x0003)
|
|
HCI_SET_EVENT_FILTER_COMMAND = hci_command_op_code(0x03, 0x0005)
|
|
HCI_FLUSH_COMMAND = hci_command_op_code(0x03, 0x0008)
|
|
HCI_READ_PIN_TYPE_COMMAND = hci_command_op_code(0x03, 0x0009)
|
|
HCI_WRITE_PIN_TYPE_COMMAND = hci_command_op_code(0x03, 0x000A)
|
|
HCI_READ_STORED_LINK_KEY_COMMAND = hci_command_op_code(0x03, 0x000D)
|
|
HCI_WRITE_STORED_LINK_KEY_COMMAND = hci_command_op_code(0x03, 0x0011)
|
|
HCI_DELETE_STORED_LINK_KEY_COMMAND = hci_command_op_code(0x03, 0x0012)
|
|
HCI_WRITE_LOCAL_NAME_COMMAND = hci_command_op_code(0x03, 0x0013)
|
|
HCI_READ_LOCAL_NAME_COMMAND = hci_command_op_code(0x03, 0x0014)
|
|
HCI_READ_CONNECTION_ACCEPT_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x0015)
|
|
HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x0016)
|
|
HCI_READ_PAGE_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x0017)
|
|
HCI_WRITE_PAGE_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x0018)
|
|
HCI_READ_SCAN_ENABLE_COMMAND = hci_command_op_code(0x03, 0x0019)
|
|
HCI_WRITE_SCAN_ENABLE_COMMAND = hci_command_op_code(0x03, 0x001A)
|
|
HCI_READ_PAGE_SCAN_ACTIVITY_COMMAND = hci_command_op_code(0x03, 0x001B)
|
|
HCI_WRITE_PAGE_SCAN_ACTIVITY_COMMAND = hci_command_op_code(0x03, 0x001C)
|
|
HCI_READ_INQUIRY_SCAN_ACTIVITY_COMMAND = hci_command_op_code(0x03, 0x001D)
|
|
HCI_WRITE_INQUIRY_SCAN_ACTIVITY_COMMAND = hci_command_op_code(0x03, 0x001E)
|
|
HCI_READ_AUTHENTICATION_ENABLE_COMMAND = hci_command_op_code(0x03, 0x001F)
|
|
HCI_WRITE_AUTHENTICATION_ENABLE_COMMAND = hci_command_op_code(0x03, 0x0020)
|
|
HCI_READ_CLASS_OF_DEVICE_COMMAND = hci_command_op_code(0x03, 0x0023)
|
|
HCI_WRITE_CLASS_OF_DEVICE_COMMAND = hci_command_op_code(0x03, 0x0024)
|
|
HCI_READ_VOICE_SETTING_COMMAND = hci_command_op_code(0x03, 0x0025)
|
|
HCI_WRITE_VOICE_SETTING_COMMAND = hci_command_op_code(0x03, 0x0026)
|
|
HCI_READ_AUTOMATIC_FLUSH_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x0027)
|
|
HCI_WRITE_AUTOMATIC_FLUSH_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x0028)
|
|
HCI_READ_NUM_BROADCAST_RETRANSMISSIONS_COMMAND = hci_command_op_code(0x03, 0x0029)
|
|
HCI_WRITE_NUM_BROADCAST_RETRANSMISSIONS_COMMAND = hci_command_op_code(0x03, 0x002A)
|
|
HCI_READ_HOLD_MODE_ACTIVITY_COMMAND = hci_command_op_code(0x03, 0x002B)
|
|
HCI_WRITE_HOLD_MODE_ACTIVITY_COMMAND = hci_command_op_code(0x03, 0x002C)
|
|
HCI_READ_TRANSMIT_POWER_LEVEL_COMMAND = hci_command_op_code(0x03, 0x002D)
|
|
HCI_READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE_COMMAND = hci_command_op_code(0x03, 0x002E)
|
|
HCI_WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE_COMMAND = hci_command_op_code(0x03, 0x002F)
|
|
HCI_SET_CONTROLLER_TO_HOST_FLOW_CONTROL_COMMAND = hci_command_op_code(0x03, 0x0031)
|
|
HCI_HOST_BUFFER_SIZE_COMMAND = hci_command_op_code(0x03, 0x0033)
|
|
HCI_HOST_NUMBER_OF_COMPLETED_PACKETS_COMMAND = hci_command_op_code(0x03, 0x0035)
|
|
HCI_READ_LINK_SUPERVISION_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x0036)
|
|
HCI_WRITE_LINK_SUPERVISION_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x0037)
|
|
HCI_READ_NUMBER_OF_SUPPORTED_IAC_COMMAND = hci_command_op_code(0x03, 0x0038)
|
|
HCI_READ_CURRENT_IAC_LAP_COMMAND = hci_command_op_code(0x03, 0x0039)
|
|
HCI_WRITE_CURRENT_IAC_LAP_COMMAND = hci_command_op_code(0x03, 0x003A)
|
|
HCI_SET_AFH_HOST_CHANNEL_CLASSIFICATION_COMMAND = hci_command_op_code(0x03, 0x003F)
|
|
HCI_READ_INQUIRY_SCAN_TYPE_COMMAND = hci_command_op_code(0x03, 0x0042)
|
|
HCI_WRITE_INQUIRY_SCAN_TYPE_COMMAND = hci_command_op_code(0x03, 0x0043)
|
|
HCI_READ_INQUIRY_MODE_COMMAND = hci_command_op_code(0x03, 0x0044)
|
|
HCI_WRITE_INQUIRY_MODE_COMMAND = hci_command_op_code(0x03, 0x0045)
|
|
HCI_READ_PAGE_SCAN_TYPE_COMMAND = hci_command_op_code(0x03, 0x0046)
|
|
HCI_WRITE_PAGE_SCAN_TYPE_COMMAND = hci_command_op_code(0x03, 0x0047)
|
|
HCI_READ_AFH_CHANNEL_ASSESSMENT_MODE_COMMAND = hci_command_op_code(0x03, 0x0048)
|
|
HCI_WRITE_AFH_CHANNEL_ASSESSMENT_MODE_COMMAND = hci_command_op_code(0x03, 0x0049)
|
|
HCI_READ_EXTENDED_INQUIRY_RESPONSE_COMMAND = hci_command_op_code(0x03, 0x0051)
|
|
HCI_WRITE_EXTENDED_INQUIRY_RESPONSE_COMMAND = hci_command_op_code(0x03, 0x0052)
|
|
HCI_REFRESH_ENCRYPTION_KEY_COMMAND = hci_command_op_code(0x03, 0x0053)
|
|
HCI_READ_SIMPLE_PAIRING_MODE_COMMAND = hci_command_op_code(0x03, 0x0055)
|
|
HCI_WRITE_SIMPLE_PAIRING_MODE_COMMAND = hci_command_op_code(0x03, 0x0056)
|
|
HCI_READ_LOCAL_OOB_DATA_COMMAND = hci_command_op_code(0x03, 0x0057)
|
|
HCI_READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL_COMMAND = hci_command_op_code(0x03, 0x0058)
|
|
HCI_WRITE_INQUIRY_TRANSMIT_POWER_LEVEL_COMMAND = hci_command_op_code(0x03, 0x0059)
|
|
HCI_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_COMMAND = hci_command_op_code(0x03, 0x005A)
|
|
HCI_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_COMMAND = hci_command_op_code(0x03, 0x005B)
|
|
HCI_ENHANCED_FLUSH_COMMAND = hci_command_op_code(0x03, 0x005F)
|
|
HCI_SEND_KEYPRESS_NOTIFICATION_COMMAND = hci_command_op_code(0x03, 0x0060)
|
|
HCI_SET_EVENT_MASK_PAGE_2_COMMAND = hci_command_op_code(0x03, 0x0063)
|
|
HCI_READ_FLOW_CONTROL_MODE_COMMAND = hci_command_op_code(0x03, 0x0066)
|
|
HCI_WRITE_FLOW_CONTROL_MODE_COMMAND = hci_command_op_code(0x03, 0x0067)
|
|
HCI_READ_ENHANCED_TRANSMIT_POWER_LEVEL_COMMAND = hci_command_op_code(0x03, 0x0068)
|
|
HCI_READ_LE_HOST_SUPPORT_COMMAND = hci_command_op_code(0x03, 0x006C)
|
|
HCI_WRITE_LE_HOST_SUPPORT_COMMAND = hci_command_op_code(0x03, 0x006D)
|
|
HCI_SET_MWS_CHANNEL_PARAMETERS_COMMAND = hci_command_op_code(0x03, 0x006E)
|
|
HCI_SET_EXTERNAL_FRAME_CONFIGURATION_COMMAND = hci_command_op_code(0x03, 0x006F)
|
|
HCI_SET_MWS_SIGNALING_COMMAND = hci_command_op_code(0x03, 0x0070)
|
|
HCI_SET_MWS_TRANSPORT_LAYER_COMMAND = hci_command_op_code(0x03, 0x0071)
|
|
HCI_SET_MWS_SCAN_FREQUENCY_TABLE_COMMAND = hci_command_op_code(0x03, 0x0072)
|
|
HCI_SET_MWS_PATTERN_CONFIGURATION_COMMAND = hci_command_op_code(0x03, 0x0073)
|
|
HCI_SET_RESERVED_LT_ADDR_COMMAND = hci_command_op_code(0x03, 0x0074)
|
|
HCI_DELETE_RESERVED_LT_ADDR_COMMAND = hci_command_op_code(0x03, 0x0075)
|
|
HCI_SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_DATA_COMMAND = hci_command_op_code(0x03, 0x0076)
|
|
HCI_READ_SYNCHRONIZATION_TRAIN_PARAMETERS_COMMAND = hci_command_op_code(0x03, 0x0077)
|
|
HCI_WRITE_SYNCHRONIZATION_TRAIN_PARAMETERS_COMMAND = hci_command_op_code(0x03, 0x0078)
|
|
HCI_READ_SECURE_CONNECTIONS_HOST_SUPPORT_COMMAND = hci_command_op_code(0x03, 0x0079)
|
|
HCI_WRITE_SECURE_CONNECTIONS_HOST_SUPPORT_COMMAND = hci_command_op_code(0x03, 0x007A)
|
|
HCI_READ_AUTHENTICATED_PAYLOAD_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x007B)
|
|
HCI_WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x007C)
|
|
HCI_READ_LOCAL_OOB_EXTENDED_DATA_COMMAND = hci_command_op_code(0x03, 0x007D)
|
|
HCI_READ_EXTENDED_PAGE_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x007E)
|
|
HCI_WRITE_EXTENDED_PAGE_TIMEOUT_COMMAND = hci_command_op_code(0x03, 0x007F)
|
|
HCI_READ_EXTENDED_INQUIRY_LENGTH_COMMAND = hci_command_op_code(0x03, 0x0080)
|
|
HCI_WRITE_EXTENDED_INQUIRY_LENGTH_COMMAND = hci_command_op_code(0x03, 0x0081)
|
|
HCI_SET_ECOSYSTEM_BASE_INTERVAL_COMMAND = hci_command_op_code(0x03, 0x0082)
|
|
HCI_CONFIGURE_DATA_PATH_COMMAND = hci_command_op_code(0x03, 0x0083)
|
|
HCI_SET_MIN_ENCRYPTION_KEY_SIZE_COMMAND = hci_command_op_code(0x03, 0x0084)
|
|
HCI_READ_LOCAL_VERSION_INFORMATION_COMMAND = hci_command_op_code(0x04, 0x0001)
|
|
HCI_READ_LOCAL_SUPPORTED_COMMANDS_COMMAND = hci_command_op_code(0x04, 0x0002)
|
|
HCI_READ_LOCAL_SUPPORTED_FEATURES_COMMAND = hci_command_op_code(0x04, 0x0003)
|
|
HCI_READ_LOCAL_EXTENDED_FEATURES_COMMAND = hci_command_op_code(0x04, 0x0004)
|
|
HCI_READ_BUFFER_SIZE_COMMAND = hci_command_op_code(0x04, 0x0005)
|
|
HCI_READ_BD_ADDR_COMMAND = hci_command_op_code(0x04, 0x0009)
|
|
HCI_READ_DATA_BLOCK_SIZE_COMMAND = hci_command_op_code(0x04, 0x000A)
|
|
HCI_READ_LOCAL_SUPPORTED_CODECS_COMMAND = hci_command_op_code(0x04, 0x000B)
|
|
HCI_READ_LOCAL_SIMPLE_PAIRING_OPTIONS_COMMAND = hci_command_op_code(0x04, 0x000C)
|
|
HCI_READ_LOCAL_SUPPORTED_CODECS_V2_COMMAND = hci_command_op_code(0x04, 0x000D)
|
|
HCI_READ_LOCAL_SUPPORTED_CODEC_CAPABILITIES_COMMAND = hci_command_op_code(0x04, 0x000E)
|
|
HCI_READ_LOCAL_SUPPORTED_CONTROLLER_DELAY_COMMAND = hci_command_op_code(0x04, 0x000F)
|
|
HCI_READ_FAILED_CONTACT_COUNTER_COMMAND = hci_command_op_code(0x05, 0x0001)
|
|
HCI_RESET_FAILED_CONTACT_COUNTER_COMMAND = hci_command_op_code(0x05, 0x0002)
|
|
HCI_READ_LINK_QUALITY_COMMAND = hci_command_op_code(0x05, 0x0003)
|
|
HCI_READ_RSSI_COMMAND = hci_command_op_code(0x05, 0x0005)
|
|
HCI_READ_AFH_CHANNEL_MAP_COMMAND = hci_command_op_code(0x05, 0x0006)
|
|
HCI_READ_CLOCK_COMMAND = hci_command_op_code(0x05, 0x0007)
|
|
HCI_READ_ENCRYPTION_KEY_SIZE_COMMAND = hci_command_op_code(0x05, 0x0008)
|
|
HCI_GET_MWS_TRANSPORT_LAYER_CONFIGURATION_COMMAND = hci_command_op_code(0x05, 0x000C)
|
|
HCI_SET_TRIGGERED_CLOCK_CAPTURE_COMMAND = hci_command_op_code(0x05, 0x000D)
|
|
HCI_READ_LOOPBACK_MODE_COMMAND = hci_command_op_code(0x06, 0x0001)
|
|
HCI_WRITE_LOOPBACK_MODE_COMMAND = hci_command_op_code(0x06, 0x0002)
|
|
HCI_ENABLE_DEVICE_UNDER_TEST_MODE_COMMAND = hci_command_op_code(0x06, 0x0003)
|
|
HCI_WRITE_SIMPLE_PAIRING_DEBUG_MODE_COMMAND = hci_command_op_code(0x06, 0x0004)
|
|
HCI_WRITE_SECURE_CONNECTIONS_TEST_MODE_COMMAND = hci_command_op_code(0x06, 0x000A)
|
|
HCI_LE_SET_EVENT_MASK_COMMAND = hci_command_op_code(0x08, 0x0001)
|
|
HCI_LE_READ_BUFFER_SIZE_COMMAND = hci_command_op_code(0x08, 0x0002)
|
|
HCI_LE_READ_LOCAL_SUPPORTED_FEATURES_COMMAND = hci_command_op_code(0x08, 0x0003)
|
|
HCI_LE_SET_RANDOM_ADDRESS_COMMAND = hci_command_op_code(0x08, 0x0005)
|
|
HCI_LE_SET_ADVERTISING_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0006)
|
|
HCI_LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER_COMMAND = hci_command_op_code(0x08, 0x0007)
|
|
HCI_LE_SET_ADVERTISING_DATA_COMMAND = hci_command_op_code(0x08, 0x0008)
|
|
HCI_LE_SET_SCAN_RESPONSE_DATA_COMMAND = hci_command_op_code(0x08, 0x0009)
|
|
HCI_LE_SET_ADVERTISING_ENABLE_COMMAND = hci_command_op_code(0x08, 0x000A)
|
|
HCI_LE_SET_SCAN_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x000B)
|
|
HCI_LE_SET_SCAN_ENABLE_COMMAND = hci_command_op_code(0x08, 0x000C)
|
|
HCI_LE_CREATE_CONNECTION_COMMAND = hci_command_op_code(0x08, 0x000D)
|
|
HCI_LE_CREATE_CONNECTION_CANCEL_COMMAND = hci_command_op_code(0x08, 0x000E)
|
|
HCI_LE_READ_FILTER_ACCEPT_LIST_SIZE_COMMAND = hci_command_op_code(0x08, 0x000F)
|
|
HCI_LE_CLEAR_FILTER_ACCEPT_LIST_COMMAND = hci_command_op_code(0x08, 0x0010)
|
|
HCI_LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST_COMMAND = hci_command_op_code(0x08, 0x0011)
|
|
HCI_LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST_COMMAND = hci_command_op_code(0x08, 0x0012)
|
|
HCI_LE_CONNECTION_UPDATE_COMMAND = hci_command_op_code(0x08, 0x0013)
|
|
HCI_LE_SET_HOST_CHANNEL_CLASSIFICATION_COMMAND = hci_command_op_code(0x08, 0x0014)
|
|
HCI_LE_READ_CHANNEL_MAP_COMMAND = hci_command_op_code(0x08, 0x0015)
|
|
HCI_LE_READ_REMOTE_FEATURES_COMMAND = hci_command_op_code(0x08, 0x0016)
|
|
HCI_LE_ENCRYPT_COMMAND = hci_command_op_code(0x08, 0x0017)
|
|
HCI_LE_RAND_COMMAND = hci_command_op_code(0x08, 0x0018)
|
|
HCI_LE_ENABLE_ENCRYPTION_COMMAND = hci_command_op_code(0x08, 0x0019)
|
|
HCI_LE_LONG_TERM_KEY_REQUEST_REPLY_COMMAND = hci_command_op_code(0x08, 0x001A)
|
|
HCI_LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x08, 0x001B)
|
|
HCI_LE_READ_SUPPORTED_STATES_COMMAND = hci_command_op_code(0x08, 0x001C)
|
|
HCI_LE_RECEIVER_TEST_COMMAND = hci_command_op_code(0x08, 0x001D)
|
|
HCI_LE_TRANSMITTER_TEST_COMMAND = hci_command_op_code(0x08, 0x001E)
|
|
HCI_LE_TEST_END_COMMAND = hci_command_op_code(0x08, 0x001F)
|
|
HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY_COMMAND = hci_command_op_code(0x08, 0x0020)
|
|
HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY_COMMAND = hci_command_op_code(0x08, 0x0021)
|
|
HCI_LE_SET_DATA_LENGTH_COMMAND = hci_command_op_code(0x08, 0x0022)
|
|
HCI_LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH_COMMAND = hci_command_op_code(0x08, 0x0023)
|
|
HCI_LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH_COMMAND = hci_command_op_code(0x08, 0x0024)
|
|
HCI_LE_READ_LOCAL_P_256_PUBLIC_KEY_COMMAND = hci_command_op_code(0x08, 0x0025)
|
|
HCI_LE_GENERATE_DHKEY_COMMAND = hci_command_op_code(0x08, 0x0026)
|
|
HCI_LE_ADD_DEVICE_TO_RESOLVING_LIST_COMMAND = hci_command_op_code(0x08, 0x0027)
|
|
HCI_LE_REMOVE_DEVICE_FROM_RESOLVING_LIST_COMMAND = hci_command_op_code(0x08, 0x0028)
|
|
HCI_LE_CLEAR_RESOLVING_LIST_COMMAND = hci_command_op_code(0x08, 0x0029)
|
|
HCI_LE_READ_RESOLVING_LIST_SIZE_COMMAND = hci_command_op_code(0x08, 0x002A)
|
|
HCI_LE_READ_PEER_RESOLVABLE_ADDRESS_COMMAND = hci_command_op_code(0x08, 0x002B)
|
|
HCI_LE_READ_LOCAL_RESOLVABLE_ADDRESS_COMMAND = hci_command_op_code(0x08, 0x002C)
|
|
HCI_LE_SET_ADDRESS_RESOLUTION_ENABLE_COMMAND = hci_command_op_code(0x08, 0x002D)
|
|
HCI_LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT_COMMAND = hci_command_op_code(0x08, 0x002E)
|
|
HCI_LE_READ_MAXIMUM_DATA_LENGTH_COMMAND = hci_command_op_code(0x08, 0x002F)
|
|
HCI_LE_READ_PHY_COMMAND = hci_command_op_code(0x08, 0x0030)
|
|
HCI_LE_SET_DEFAULT_PHY_COMMAND = hci_command_op_code(0x08, 0x0031)
|
|
HCI_LE_SET_PHY_COMMAND = hci_command_op_code(0x08, 0x0032)
|
|
HCI_LE_RECEIVER_TEST_V2_COMMAND = hci_command_op_code(0x08, 0x0033)
|
|
HCI_LE_TRANSMITTER_TEST_V2_COMMAND = hci_command_op_code(0x08, 0x0034)
|
|
HCI_LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_COMMAND = hci_command_op_code(0x08, 0x0035)
|
|
HCI_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0036)
|
|
HCI_LE_SET_EXTENDED_ADVERTISING_DATA_COMMAND = hci_command_op_code(0x08, 0x0037)
|
|
HCI_LE_SET_EXTENDED_SCAN_RESPONSE_DATA_COMMAND = hci_command_op_code(0x08, 0x0038)
|
|
HCI_LE_SET_EXTENDED_ADVERTISING_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0039)
|
|
HCI_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH_COMMAND = hci_command_op_code(0x08, 0x003A)
|
|
HCI_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS_COMMAND = hci_command_op_code(0x08, 0x003B)
|
|
HCI_LE_REMOVE_ADVERTISING_SET_COMMAND = hci_command_op_code(0x08, 0x003C)
|
|
HCI_LE_CLEAR_ADVERTISING_SETS_COMMAND = hci_command_op_code(0x08, 0x003D)
|
|
HCI_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x003E)
|
|
HCI_LE_SET_PERIODIC_ADVERTISING_DATA_COMMAND = hci_command_op_code(0x08, 0x003F)
|
|
HCI_LE_SET_PERIODIC_ADVERTISING_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0040)
|
|
HCI_LE_SET_EXTENDED_SCAN_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0041)
|
|
HCI_LE_SET_EXTENDED_SCAN_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0042)
|
|
HCI_LE_EXTENDED_CREATE_CONNECTION_COMMAND = hci_command_op_code(0x08, 0x0043)
|
|
HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC_COMMAND = hci_command_op_code(0x08, 0x0044)
|
|
HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL_COMMAND = hci_command_op_code(0x08, 0x0045)
|
|
HCI_LE_PERIODIC_ADVERTISING_TERMINATE_SYNC_COMMAND = hci_command_op_code(0x08, 0x0046)
|
|
HCI_LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST_COMMAND = hci_command_op_code(0x08, 0x0047)
|
|
HCI_LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST_COMMAND = hci_command_op_code(0x08, 0x0048)
|
|
HCI_LE_CLEAR_PERIODIC_ADVERTISER_LIST_COMMAND = hci_command_op_code(0x08, 0x0049)
|
|
HCI_LE_READ_PERIODIC_ADVERTISER_LIST_SIZE_COMMAND = hci_command_op_code(0x08, 0x004A)
|
|
HCI_LE_READ_TRANSMIT_POWER_COMMAND = hci_command_op_code(0x08, 0x004B)
|
|
HCI_LE_READ_RF_PATH_COMPENSATION_COMMAND = hci_command_op_code(0x08, 0x004C)
|
|
HCI_LE_WRITE_RF_PATH_COMPENSATION_COMMAND = hci_command_op_code(0x08, 0x004D)
|
|
HCI_LE_SET_PRIVACY_MODE_COMMAND = hci_command_op_code(0x08, 0x004E)
|
|
HCI_LE_RECEIVER_TEST_V3_COMMAND = hci_command_op_code(0x08, 0x004F)
|
|
HCI_LE_TRANSMITTER_TEST_V3_COMMAND = hci_command_op_code(0x08, 0x0050)
|
|
HCI_LE_SET_CONNECTIONLESS_CTE_TRANSMIT_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0051)
|
|
HCI_LE_SET_CONNECTIONLESS_CTE_TRANSMIT_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0052)
|
|
HCI_LE_SET_CONNECTIONLESS_IQ_SAMPLING_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0053)
|
|
HCI_LE_SET_CONNECTION_CTE_RECEIVE_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0054)
|
|
HCI_LE_SET_CONNECTION_CTE_TRANSMIT_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0055)
|
|
HCI_LE_CONNECTION_CTE_REQUEST_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0056)
|
|
HCI_LE_CONNECTION_CTE_RESPONSE_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0057)
|
|
HCI_LE_READ_ANTENNA_INFORMATION_COMMAND = hci_command_op_code(0x08, 0x0058)
|
|
HCI_LE_SET_PERIODIC_ADVERTISING_RECEIVE_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0059)
|
|
HCI_LE_PERIODIC_ADVERTISING_SYNC_TRANSFER_COMMAND = hci_command_op_code(0x08, 0x005A)
|
|
HCI_LE_PERIODIC_ADVERTISING_SET_INFO_TRANSFER_COMMAND = hci_command_op_code(0x08, 0x005B)
|
|
HCI_LE_SET_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x005C)
|
|
HCI_LE_SET_DEFAULT_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x005D)
|
|
HCI_LE_GENERATE_DHKEY_V2_COMMAND = hci_command_op_code(0x08, 0x005E)
|
|
HCI_LE_MODIFY_SLEEP_CLOCK_ACCURACY_COMMAND = hci_command_op_code(0x08, 0x005F)
|
|
HCI_LE_READ_BUFFER_SIZE_V2_COMMAND = hci_command_op_code(0x08, 0x0060)
|
|
HCI_LE_READ_ISO_TX_SYNC_COMMAND = hci_command_op_code(0x08, 0x0061)
|
|
HCI_LE_SET_CIG_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0062)
|
|
HCI_LE_SET_CIG_PARAMETERS_TEST_COMMAND = hci_command_op_code(0x08, 0x0063)
|
|
HCI_LE_CREATE_CIS_COMMAND = hci_command_op_code(0x08, 0x0064)
|
|
HCI_LE_REMOVE_CIG_COMMAND = hci_command_op_code(0x08, 0x0065)
|
|
HCI_LE_ACCEPT_CIS_REQUEST_COMMAND = hci_command_op_code(0x08, 0x0066)
|
|
HCI_LE_REJECT_CIS_REQUEST_COMMAND = hci_command_op_code(0x08, 0x0067)
|
|
HCI_LE_CREATE_BIG_COMMAND = hci_command_op_code(0x08, 0x0068)
|
|
HCI_LE_CREATE_BIG_TEST_COMMAND = hci_command_op_code(0x08, 0x0069)
|
|
HCI_LE_TERMINATE_BIG_COMMAND = hci_command_op_code(0x08, 0x006A)
|
|
HCI_LE_BIG_CREATE_SYNC_COMMAND = hci_command_op_code(0x08, 0x006B)
|
|
HCI_LE_BIG_TERMINATE_SYNC_COMMAND = hci_command_op_code(0x08, 0x006C)
|
|
HCI_LE_REQUEST_PEER_SCA_COMMAND = hci_command_op_code(0x08, 0x006D)
|
|
HCI_LE_SETUP_ISO_DATA_PATH_COMMAND = hci_command_op_code(0x08, 0x006E)
|
|
HCI_LE_REMOVE_ISO_DATA_PATH_COMMAND = hci_command_op_code(0x08, 0x006F)
|
|
HCI_LE_ISO_TRANSMIT_TEST_COMMAND = hci_command_op_code(0x08, 0x0070)
|
|
HCI_LE_ISO_RECEIVE_TEST_COMMAND = hci_command_op_code(0x08, 0x0071)
|
|
HCI_LE_ISO_READ_TEST_COUNTERS_COMMAND = hci_command_op_code(0x08, 0x0072)
|
|
HCI_LE_ISO_TEST_END_COMMAND = hci_command_op_code(0x08, 0x0073)
|
|
HCI_LE_SET_HOST_FEATURE_COMMAND = hci_command_op_code(0x08, 0x0074)
|
|
HCI_LE_READ_ISO_LINK_QUALITY_COMMAND = hci_command_op_code(0x08, 0x0075)
|
|
HCI_LE_ENHANCED_READ_TRANSMIT_POWER_LEVEL_COMMAND = hci_command_op_code(0x08, 0x0076)
|
|
HCI_LE_READ_REMOTE_TRANSMIT_POWER_LEVEL_COMMAND = hci_command_op_code(0x08, 0x0077)
|
|
HCI_LE_SET_PATH_LOSS_REPORTING_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0078)
|
|
HCI_LE_SET_PATH_LOSS_REPORTING_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0079)
|
|
HCI_LE_SET_TRANSMIT_POWER_REPORTING_ENABLE_COMMAND = hci_command_op_code(0x08, 0x007A)
|
|
HCI_LE_TRANSMITTER_TEST_V4_COMMAND = hci_command_op_code(0x08, 0x007B)
|
|
HCI_LE_SET_DATA_RELATED_ADDRESS_CHANGES_COMMAND = hci_command_op_code(0x08, 0x007C)
|
|
HCI_LE_SET_DEFAULT_SUBRATE_COMMAND = hci_command_op_code(0x08, 0x007D)
|
|
HCI_LE_SUBRATE_REQUEST_COMMAND = hci_command_op_code(0x08, 0x007E)
|
|
HCI_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_V2_COMMAND = hci_command_op_code(0x08, 0x007F)
|
|
HCI_LE_SET_DECISION_DATA_COMMAND = hci_command_op_code(0x08, 0x0080)
|
|
HCI_LE_SET_DECISION_INSTRUCTIONS_COMMAND = hci_command_op_code(0x08, 0x0081)
|
|
HCI_LE_SET_PERIODIC_ADVERTISING_SUBEVENT_DATA_COMMAND = hci_command_op_code(0x08, 0x0082)
|
|
HCI_LE_SET_PERIODIC_ADVERTISING_RESPONSE_DATA_COMMAND = hci_command_op_code(0x08, 0x0083)
|
|
HCI_LE_SET_PERIODIC_SYNC_SUBEVENT_COMMAND = hci_command_op_code(0x08, 0x0084)
|
|
HCI_LE_EXTENDED_CREATE_CONNECTION_V2_COMMAND = hci_command_op_code(0x08, 0x0085)
|
|
HCI_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_V2_COMMAND = hci_command_op_code(0x08, 0x0086)
|
|
HCI_LE_READ_ALL_LOCAL_SUPPORTED_FEATURES_COMMAND = hci_command_op_code(0x08, 0x0087)
|
|
HCI_LE_READ_ALL_REMOTE_FEATURES_COMMAND = hci_command_op_code(0x08, 0x0088)
|
|
HCI_LE_CS_READ_LOCAL_SUPPORTED_CAPABILITIES_COMMAND = hci_command_op_code(0x08, 0x0089)
|
|
HCI_LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES_COMMAND = hci_command_op_code(0x08, 0x008A)
|
|
HCI_LE_CS_WRITE_CACHED_REMOTE_SUPPORTED_CAPABILITIES_COMMAND = hci_command_op_code(0x08, 0x008B)
|
|
HCI_LE_CS_SECURITY_ENABLE_COMMAND = hci_command_op_code(0x08, 0x008C)
|
|
HCI_LE_CS_SET_DEFAULT_SETTINGS_COMMAND = hci_command_op_code(0x08, 0x008D)
|
|
HCI_LE_CS_READ_REMOTE_FAE_TABLE_COMMAND = hci_command_op_code(0x08, 0x008E)
|
|
HCI_LE_CS_WRITE_CACHED_REMOTE_FAE_TABLE_COMMAND = hci_command_op_code(0x08, 0x008F)
|
|
HCI_LE_CS_CREATE_CONFIG_COMMAND = hci_command_op_code(0x08, 0x0090)
|
|
HCI_LE_CS_REMOVE_CONFIG_COMMAND = hci_command_op_code(0x08, 0x0091)
|
|
HCI_LE_CS_SET_CHANNEL_CLASSIFICATION_COMMAND = hci_command_op_code(0x08, 0x0092)
|
|
HCI_LE_CS_SET_PROCEDURE_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0093)
|
|
HCI_LE_CS_PROCEDURE_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0094)
|
|
HCI_LE_CS_TEST_COMMAND = hci_command_op_code(0x08, 0x0095)
|
|
HCI_LE_CS_TEST_END_COMMAND = hci_command_op_code(0x08, 0x0096)
|
|
HCI_LE_SET_HOST_FEATURE_V2_COMMAND = hci_command_op_code(0x08, 0x0097)
|
|
HCI_LE_ADD_DEVICE_TO_MONITORED_ADVERTISERS_LIST_COMMAND = hci_command_op_code(0x08, 0x0098)
|
|
HCI_LE_REMOVE_DEVICE_FROM_MONITORED_ADVERTISERS_LIST_COMMAND = hci_command_op_code(0x08, 0x0099)
|
|
HCI_LE_CLEAR_MONITORED_ADVERTISERS_LIST_COMMAND = hci_command_op_code(0x08, 0x009A)
|
|
HCI_LE_READ_MONITORED_ADVERTISERS_LIST_SIZE_COMMAND = hci_command_op_code(0x08, 0x009B)
|
|
HCI_LE_ENABLE_MONITORING_ADVERTISERS_COMMAND = hci_command_op_code(0x08, 0x009C)
|
|
HCI_LE_FRAME_SPACE_UPDATE_COMMAND = hci_command_op_code(0x08, 0x009D)
|
|
HCI_LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT_V2_COMMAND = hci_command_op_code(0x08, 0x009E)
|
|
HCI_LE_ENABLE_UTP_OTA_MODE_COMMAND = hci_command_op_code(0x08, 0x009F)
|
|
HCI_LE_UTP_SEND_COMMAND = hci_command_op_code(0x08, 0x00A0)
|
|
HCI_LE_CONNECTION_RATE_REQUEST_COMMAND = hci_command_op_code(0x08, 0x00A1)
|
|
HCI_LE_SET_DEFAULT_RATE_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x00A2)
|
|
HCI_LE_READ_MINIMUM_SUPPORTED_CONNECTION_INTERVAL_COMMAND = hci_command_op_code(0x08, 0x00A3)
|
|
|
|
|
|
# HCI Error Codes
|
|
# See Bluetooth spec Vol 2, Part D - 1.3 LIST OF ERROR CODES
|
|
class HCI_ErrorCode(SpecableEnum):
|
|
SUCCESS = 0x00
|
|
UNKNOWN_HCI_COMMAND_ERROR = 0x01
|
|
UNKNOWN_CONNECTION_IDENTIFIER_ERROR = 0x02
|
|
HARDWARE_FAILURE_ERROR = 0x03
|
|
PAGE_TIMEOUT_ERROR = 0x04
|
|
AUTHENTICATION_FAILURE_ERROR = 0x05
|
|
PIN_OR_KEY_MISSING_ERROR = 0x06
|
|
MEMORY_CAPACITY_EXCEEDED_ERROR = 0x07
|
|
CONNECTION_TIMEOUT_ERROR = 0x08
|
|
CONNECTION_LIMIT_EXCEEDED_ERROR = 0x09
|
|
SYNCHRONOUS_CONNECTION_LIMIT_TO_A_DEVICE_EXCEEDED_ERROR = 0x0A
|
|
CONNECTION_ALREADY_EXISTS_ERROR = 0x0B
|
|
COMMAND_DISALLOWED_ERROR = 0x0C
|
|
CONNECTION_REJECTED_DUE_TO_LIMITED_RESOURCES_ERROR = 0x0D
|
|
CONNECTION_REJECTED_DUE_TO_SECURITY_REASONS_ERROR = 0x0E
|
|
CONNECTION_REJECTED_DUE_TO_UNACCEPTABLE_BD_ADDR_ERROR = 0x0F
|
|
CONNECTION_ACCEPT_TIMEOUT_ERROR = 0x10
|
|
UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE_ERROR = 0x11
|
|
INVALID_COMMAND_PARAMETERS_ERROR = 0x12
|
|
REMOTE_USER_TERMINATED_CONNECTION_ERROR = 0x13
|
|
REMOTE_DEVICE_TERMINATED_CONNECTION_DUE_TO_LOW_RESOURCES_ERROR = 0x14
|
|
REMOTE_DEVICE_TERMINATED_CONNECTION_DUE_TO_POWER_OFF_ERROR = 0x15
|
|
CONNECTION_TERMINATED_BY_LOCAL_HOST_ERROR = 0x16
|
|
REPEATED_ATTEMPTS_ERROR = 0X17
|
|
PAIRING_NOT_ALLOWED_ERROR = 0X18
|
|
UNKNOWN_LMP_PDU_ERROR = 0X19
|
|
UNSUPPORTED_REMOTE_FEATURE_ERROR = 0X1A
|
|
SCO_OFFSET_REJECTED_ERROR = 0X1B
|
|
SCO_INTERVAL_REJECTED_ERROR = 0X1C
|
|
SCO_AIR_MODE_REJECTED_ERROR = 0X1D
|
|
INVALID_LMP_OR_LL_PARAMETERS_ERROR = 0X1E
|
|
UNSPECIFIED_ERROR_ERROR = 0X1F
|
|
UNSUPPORTED_LMP_OR_LL_PARAMETER_VALUE_ERROR = 0X20
|
|
ROLE_CHANGE_NOT_ALLOWED_ERROR = 0X21
|
|
LMP_OR_LL_RESPONSE_TIMEOUT_ERROR = 0X22
|
|
LMP_ERROR_TRANSACTION_COLLISION_OR_LL_PROCEDURE_COLLISION_ERROR = 0X23
|
|
LMP_PDU_NOT_ALLOWED_ERROR = 0X24
|
|
ENCRYPTION_MODE_NOT_ACCEPTABLE_ERROR = 0X25
|
|
LINK_KEY_CANNOT_BE_CHANGED_ERROR = 0X26
|
|
REQUESTED_QOS_NOT_SUPPORTED_ERROR = 0X27
|
|
INSTANT_PASSED_ERROR = 0X28
|
|
PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED_ERROR = 0X29
|
|
DIFFERENT_TRANSACTION_COLLISION_ERROR = 0X2A
|
|
RESERVED_FOR_FUTURE_USE = 0X2B
|
|
QOS_UNACCEPTABLE_PARAMETER_ERROR = 0X2C
|
|
QOS_REJECTED_ERROR = 0X2D
|
|
CHANNEL_CLASSIFICATION_NOT_SUPPORTED_ERROR = 0X2E
|
|
INSUFFICIENT_SECURITY_ERROR = 0X2F
|
|
PARAMETER_OUT_OF_MANDATORY_RANGE_ERROR = 0X30
|
|
ROLE_SWITCH_PENDING_ERROR = 0X32
|
|
RESERVED_SLOT_VIOLATION_ERROR = 0X34
|
|
ROLE_SWITCH_FAILED_ERROR = 0X35
|
|
EXTENDED_INQUIRY_RESPONSE_TOO_LARGE_ERROR = 0X36
|
|
SECURE_SIMPLE_PAIRING_NOT_SUPPORTED_BY_HOST_ERROR = 0X37
|
|
HOST_BUSY_PAIRING_ERROR = 0X38
|
|
CONNECTION_REJECTED_DUE_TO_NO_SUITABLE_CHANNEL_FOUND_ERROR = 0X39
|
|
CONTROLLER_BUSY_ERROR = 0X3A
|
|
UNACCEPTABLE_CONNECTION_PARAMETERS_ERROR = 0X3B
|
|
ADVERTISING_TIMEOUT_ERROR = 0X3C
|
|
CONNECTION_TERMINATED_DUE_TO_MIC_FAILURE_ERROR = 0X3D
|
|
CONNECTION_FAILED_TO_BE_ESTABLISHED_ERROR = 0X3E
|
|
COARSE_CLOCK_ADJUSTMENT_REJECTED_BUT_WILL_TRY_TO_ADJUST_USING_CLOCK_DRAGGING_ERROR = 0X40
|
|
TYPE0_SUBMAP_NOT_DEFINED_ERROR = 0X41
|
|
UNKNOWN_ADVERTISING_IDENTIFIER_ERROR = 0X42
|
|
LIMIT_REACHED_ERROR = 0X43
|
|
OPERATION_CANCELLED_BY_HOST_ERROR = 0X44
|
|
PACKET_TOO_LONG_ERROR = 0X45
|
|
|
|
# For backwards compatibility.
|
|
HCI_SUCCESS = 0x00
|
|
HCI_UNKNOWN_HCI_COMMAND_ERROR = 0x01
|
|
HCI_UNKNOWN_CONNECTION_IDENTIFIER_ERROR = 0x02
|
|
HCI_HARDWARE_FAILURE_ERROR = 0x03
|
|
HCI_PAGE_TIMEOUT_ERROR = 0x04
|
|
HCI_AUTHENTICATION_FAILURE_ERROR = 0x05
|
|
HCI_PIN_OR_KEY_MISSING_ERROR = 0x06
|
|
HCI_MEMORY_CAPACITY_EXCEEDED_ERROR = 0x07
|
|
HCI_CONNECTION_TIMEOUT_ERROR = 0x08
|
|
HCI_CONNECTION_LIMIT_EXCEEDED_ERROR = 0x09
|
|
HCI_SYNCHRONOUS_CONNECTION_LIMIT_TO_A_DEVICE_EXCEEDED_ERROR = 0x0A
|
|
HCI_CONNECTION_ALREADY_EXISTS_ERROR = 0x0B
|
|
HCI_COMMAND_DISALLOWED_ERROR = 0x0C
|
|
HCI_CONNECTION_REJECTED_DUE_TO_LIMITED_RESOURCES_ERROR = 0x0D
|
|
HCI_CONNECTION_REJECTED_DUE_TO_SECURITY_REASONS_ERROR = 0x0E
|
|
HCI_CONNECTION_REJECTED_DUE_TO_UNACCEPTABLE_BD_ADDR_ERROR = 0x0F
|
|
HCI_CONNECTION_ACCEPT_TIMEOUT_ERROR = 0x10
|
|
HCI_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE_ERROR = 0x11
|
|
HCI_INVALID_HCI_COMMAND_PARAMETERS_ERROR = 0x12
|
|
HCI_REMOTE_USER_TERMINATED_CONNECTION_ERROR = 0x13
|
|
HCI_REMOTE_DEVICE_TERMINATED_CONNECTION_DUE_TO_LOW_RESOURCES_ERROR = 0x14
|
|
HCI_REMOTE_DEVICE_TERMINATED_CONNECTION_DUE_TO_POWER_OFF_ERROR = 0x15
|
|
HCI_CONNECTION_TERMINATED_BY_LOCAL_HOST_ERROR = 0x16
|
|
HCI_REPEATED_ATTEMPTS_ERROR = 0X17
|
|
HCI_PAIRING_NOT_ALLOWED_ERROR = 0X18
|
|
HCI_UNKNOWN_LMP_PDU_ERROR = 0X19
|
|
HCI_UNSUPPORTED_REMOTE_FEATURE_ERROR = 0X1A
|
|
HCI_SCO_OFFSET_REJECTED_ERROR = 0X1B
|
|
HCI_SCO_INTERVAL_REJECTED_ERROR = 0X1C
|
|
HCI_SCO_AIR_MODE_REJECTED_ERROR = 0X1D
|
|
HCI_INVALID_LMP_OR_LL_PARAMETERS_ERROR = 0X1E
|
|
HCI_UNSPECIFIED_ERROR_ERROR = 0X1F
|
|
HCI_UNSUPPORTED_LMP_OR_LL_PARAMETER_VALUE_ERROR = 0X20
|
|
HCI_ROLE_CHANGE_NOT_ALLOWED_ERROR = 0X21
|
|
HCI_LMP_OR_LL_RESPONSE_TIMEOUT_ERROR = 0X22
|
|
HCI_LMP_ERROR_TRANSACTION_COLLISION_OR_LL_PROCEDURE_COLLISION_ERROR = 0X23
|
|
HCI_LMP_PDU_NOT_ALLOWED_ERROR = 0X24
|
|
HCI_ENCRYPTION_MODE_NOT_ACCEPTABLE_ERROR = 0X25
|
|
HCI_LINK_KEY_CANNOT_BE_CHANGED_ERROR = 0X26
|
|
HCI_REQUESTED_QOS_NOT_SUPPORTED_ERROR = 0X27
|
|
HCI_INSTANT_PASSED_ERROR = 0X28
|
|
HCI_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED_ERROR = 0X29
|
|
HCI_DIFFERENT_TRANSACTION_COLLISION_ERROR = 0X2A
|
|
HCI_RESERVED_FOR_FUTURE_USE = 0X2B
|
|
HCI_QOS_UNACCEPTABLE_PARAMETER_ERROR = 0X2C
|
|
HCI_QOS_REJECTED_ERROR = 0X2D
|
|
HCI_CHANNEL_CLASSIFICATION_NOT_SUPPORTED_ERROR = 0X2E
|
|
HCI_INSUFFICIENT_SECURITY_ERROR = 0X2F
|
|
HCI_PARAMETER_OUT_OF_MANDATORY_RANGE_ERROR = 0X30
|
|
HCI_ROLE_SWITCH_PENDING_ERROR = 0X32
|
|
HCI_RESERVED_SLOT_VIOLATION_ERROR = 0X34
|
|
HCI_ROLE_SWITCH_FAILED_ERROR = 0X35
|
|
HCI_EXTENDED_INQUIRY_RESPONSE_TOO_LARGE_ERROR = 0X36
|
|
HCI_SECURE_SIMPLE_PAIRING_NOT_SUPPORTED_BY_HOST_ERROR = 0X37
|
|
HCI_HOST_BUSY_PAIRING_ERROR = 0X38
|
|
HCI_CONNECTION_REJECTED_DUE_TO_NO_SUITABLE_CHANNEL_FOUND_ERROR = 0X39
|
|
HCI_CONTROLLER_BUSY_ERROR = 0X3A
|
|
HCI_UNACCEPTABLE_CONNECTION_PARAMETERS_ERROR = 0X3B
|
|
HCI_ADVERTISING_TIMEOUT_ERROR = 0X3C
|
|
HCI_CONNECTION_TERMINATED_DUE_TO_MIC_FAILURE_ERROR = 0X3D
|
|
HCI_CONNECTION_FAILED_TO_BE_ESTABLISHED_ERROR = 0X3E
|
|
HCI_COARSE_CLOCK_ADJUSTMENT_REJECTED_BUT_WILL_TRY_TO_ADJUST_USING_CLOCK_DRAGGING_ERROR = 0X40
|
|
HCI_TYPE0_SUBMAP_NOT_DEFINED_ERROR = 0X41
|
|
HCI_UNKNOWN_ADVERTISING_IDENTIFIER_ERROR = 0X42
|
|
HCI_LIMIT_REACHED_ERROR = 0X43
|
|
HCI_OPERATION_CANCELLED_BY_HOST_ERROR = 0X44
|
|
HCI_PACKET_TOO_LONG_ERROR = 0X45
|
|
|
|
HCI_ERROR_NAMES = {
|
|
error_code: error_code.name for error_code in HCI_ErrorCode
|
|
}
|
|
|
|
# Command Status codes
|
|
class HCI_CommandStatus(SpecableEnum):
|
|
PENDING = 0x00
|
|
|
|
# For backward compatibility
|
|
HCI_COMMAND_STATUS_PENDING = HCI_CommandStatus.PENDING
|
|
|
|
|
|
class Phy(SpecableEnum):
|
|
LE_1M = 1
|
|
LE_2M = 2
|
|
LE_CODED = 3
|
|
|
|
|
|
# ACL
|
|
HCI_ACL_PB_FIRST_NON_FLUSHABLE = 0
|
|
HCI_ACL_PB_CONTINUATION = 1
|
|
HCI_ACL_PB_FIRST_FLUSHABLE = 2
|
|
HCI_ACK_PB_COMPLETE_L2CAP = 3
|
|
|
|
HCI_LE_PHY_NAMES: dict[int,str] = {
|
|
Phy.LE_1M: 'LE 1M',
|
|
Phy.LE_2M: 'LE 2M',
|
|
Phy.LE_CODED: 'LE Coded'
|
|
}
|
|
|
|
HCI_LE_1M_PHY_BIT = 0
|
|
HCI_LE_2M_PHY_BIT = 1
|
|
HCI_LE_CODED_PHY_BIT = 2
|
|
|
|
HCI_LE_PHY_BIT_NAMES = ['LE_1M_PHY', 'LE_2M_PHY', 'LE_CODED_PHY']
|
|
|
|
HCI_LE_PHY_TYPE_TO_BIT: dict[Phy, int] = {
|
|
Phy.LE_1M: HCI_LE_1M_PHY_BIT,
|
|
Phy.LE_2M: HCI_LE_2M_PHY_BIT,
|
|
Phy.LE_CODED: HCI_LE_CODED_PHY_BIT,
|
|
}
|
|
|
|
|
|
class PhyBit(SpecableFlag):
|
|
LE_1M = 1 << HCI_LE_1M_PHY_BIT
|
|
LE_2M = 1 << HCI_LE_2M_PHY_BIT
|
|
LE_CODED = 1 << HCI_LE_CODED_PHY_BIT
|
|
|
|
|
|
class CsRole(SpecableEnum):
|
|
INITIATOR = 0x00
|
|
REFLECTOR = 0x01
|
|
|
|
|
|
class CsRoleMask(enum.IntFlag):
|
|
INITIATOR = 0x01
|
|
REFLECTOR = 0x02
|
|
|
|
|
|
class CsSyncPhy(SpecableEnum):
|
|
LE_1M = 1
|
|
LE_2M = 2
|
|
LE_2M_2BT = 3
|
|
|
|
|
|
class CsSyncPhySupported(enum.IntFlag):
|
|
LE_2M = 0x01
|
|
LE_2M_2BT = 0x02
|
|
|
|
|
|
class RttType(SpecableEnum):
|
|
AA_ONLY = 0x00
|
|
SOUNDING_SEQUENCE_32_BIT = 0x01
|
|
SOUNDING_SEQUENCE_96_BIT = 0x02
|
|
RANDOM_SEQUENCE_32_BIT = 0x03
|
|
RANDOM_SEQUENCE_64_BIT = 0x04
|
|
RANDOM_SEQUENCE_96_BIT = 0x05
|
|
RANDOM_SEQUENCE_128_BIT = 0x06
|
|
|
|
|
|
class CsSnr(SpecableEnum):
|
|
SNR_18_DB = 0x00
|
|
SNR_21_DB = 0x01
|
|
SNR_24_DB = 0x02
|
|
SNR_27_DB = 0x03
|
|
SNR_30_DB = 0x04
|
|
NOT_APPLIED = 0xFF
|
|
|
|
|
|
class CsDoneStatus(SpecableEnum):
|
|
ALL_RESULTS_COMPLETED = 0x00
|
|
PARTIAL = 0x01
|
|
ABORTED = 0x0F
|
|
|
|
|
|
class CsProcedureAbortReason(SpecableEnum):
|
|
NO_ABORT = 0x00
|
|
LOCAL_HOST_OR_REMOTE_REQUEST = 0x01
|
|
CHANNEL_MAP_UPDATE_INSTANT_PASSED = 0x02
|
|
UNSPECIFIED = 0x0F
|
|
|
|
|
|
class CsSubeventAbortReason(SpecableEnum):
|
|
NO_ABORT = 0x00
|
|
LOCAL_HOST_OR_REMOTE_REQUEST = 0x01
|
|
NO_CS_SYNC_RECEIVED = 0x02
|
|
SCHEDULING_CONFLICT_OR_LIMITED_RESOURCES = 0x03
|
|
UNSPECIFIED = 0x0F
|
|
|
|
class Role(SpecableEnum):
|
|
CENTRAL = 0
|
|
PERIPHERAL = 1
|
|
|
|
# For Backward Compatibility.
|
|
HCI_CENTRAL_ROLE = Role.CENTRAL
|
|
HCI_PERIPHERAL_ROLE = Role.PERIPHERAL
|
|
|
|
|
|
HCI_LE_1M_PHY = Phy.LE_1M
|
|
HCI_LE_2M_PHY = Phy.LE_2M
|
|
HCI_LE_CODED_PHY = Phy.LE_CODED
|
|
|
|
|
|
# Connection Parameters
|
|
HCI_CONNECTION_INTERVAL_MS_PER_UNIT = 1.25
|
|
HCI_CONNECTION_LATENCY_MS_PER_UNIT = 1.25
|
|
HCI_SUPERVISION_TIMEOUT_MS_PER_UNIT = 10
|
|
|
|
# Inquiry LAP
|
|
HCI_LIMITED_DEDICATED_INQUIRY_LAP = 0x9E8B00
|
|
HCI_GENERAL_INQUIRY_LAP = 0x9E8B33
|
|
HCI_INQUIRY_LAP_NAMES = {
|
|
HCI_LIMITED_DEDICATED_INQUIRY_LAP: 'Limited Dedicated Inquiry',
|
|
HCI_GENERAL_INQUIRY_LAP: 'General Inquiry'
|
|
}
|
|
|
|
# Inquiry Mode
|
|
HCI_STANDARD_INQUIRY_MODE = 0x00
|
|
HCI_INQUIRY_WITH_RSSI_MODE = 0x01
|
|
HCI_EXTENDED_INQUIRY_MODE = 0x02
|
|
|
|
# Page Scan Repetition Mode
|
|
HCI_R0_PAGE_SCAN_REPETITION_MODE = 0x00
|
|
HCI_R1_PAGE_SCAN_REPETITION_MODE = 0x01
|
|
HCI_R2_PAGE_SCAN_REPETITION_MODE = 0x02
|
|
|
|
# IO Capability
|
|
class IoCapability(SpecableEnum):
|
|
DISPLAY_ONLY = 0x00
|
|
DISPLAY_YES_NO = 0x01
|
|
KEYBOARD_ONLY = 0x02
|
|
NO_INPUT_NO_OUTPUT = 0x03
|
|
|
|
# Authentication Requirements
|
|
class AuthenticationRequirements(SpecableEnum):
|
|
MITM_NOT_REQUIRED_NO_BONDING = 0x00
|
|
MITM_REQUIRED_NO_BONDING = 0x01
|
|
MITM_NOT_REQUIRED_DEDICATED_BONDING = 0x02
|
|
MITM_REQUIRED_DEDICATED_BONDING = 0x03
|
|
MITM_NOT_REQUIRED_GENERAL_BONDING = 0x04
|
|
MITM_REQUIRED_GENERAL_BONDING = 0x05
|
|
|
|
# Link Key Types
|
|
class LinkKeyType(SpecableEnum):
|
|
COMBINATION_KEY = 0X00
|
|
LOCAL_UNIT_KEY = 0X01
|
|
REMOTE_UNIT_KEY = 0X02
|
|
DEBUG_COMBINATION_KEY = 0X03
|
|
UNAUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_192 = 0X04
|
|
AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_192 = 0X05
|
|
CHANGED_COMBINATION_KEY = 0X06
|
|
UNAUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_256 = 0X07
|
|
AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P_256 = 0X08
|
|
|
|
# Address types
|
|
class AddressType(SpecableEnum):
|
|
PUBLIC_DEVICE = 0x00
|
|
RANDOM_DEVICE = 0x01
|
|
PUBLIC_IDENTITY = 0x02
|
|
RANDOM_IDENTITY = 0x03
|
|
# (Directed Only) Address is RPA, but controller cannot resolve.
|
|
UNABLE_TO_RESOLVE = 0xFE
|
|
# (Extended Only) No address.
|
|
ANONYMOUS = 0xFF
|
|
|
|
# Supported Commands Masks
|
|
# See Bluetooth spec @ 6.27 SUPPORTED COMMANDS
|
|
HCI_SUPPORTED_COMMANDS_MASKS = {
|
|
HCI_INQUIRY_COMMAND : 1 << (0*8+0),
|
|
HCI_INQUIRY_CANCEL_COMMAND : 1 << (0*8+1),
|
|
HCI_PERIODIC_INQUIRY_MODE_COMMAND : 1 << (0*8+2),
|
|
HCI_EXIT_PERIODIC_INQUIRY_MODE_COMMAND : 1 << (0*8+3),
|
|
HCI_CREATE_CONNECTION_COMMAND : 1 << (0*8+4),
|
|
HCI_DISCONNECT_COMMAND : 1 << (0*8+5),
|
|
HCI_CREATE_CONNECTION_CANCEL_COMMAND : 1 << (0*8+7),
|
|
HCI_ACCEPT_CONNECTION_REQUEST_COMMAND : 1 << (1*8+0),
|
|
HCI_REJECT_CONNECTION_REQUEST_COMMAND : 1 << (1*8+1),
|
|
HCI_LINK_KEY_REQUEST_REPLY_COMMAND : 1 << (1*8+2),
|
|
HCI_LINK_KEY_REQUEST_NEGATIVE_REPLY_COMMAND : 1 << (1*8+3),
|
|
HCI_PIN_CODE_REQUEST_REPLY_COMMAND : 1 << (1*8+4),
|
|
HCI_PIN_CODE_REQUEST_NEGATIVE_REPLY_COMMAND : 1 << (1*8+5),
|
|
HCI_CHANGE_CONNECTION_PACKET_TYPE_COMMAND : 1 << (1*8+6),
|
|
HCI_AUTHENTICATION_REQUESTED_COMMAND : 1 << (1*8+7),
|
|
HCI_SET_CONNECTION_ENCRYPTION_COMMAND : 1 << (2*8+0),
|
|
HCI_CHANGE_CONNECTION_LINK_KEY_COMMAND : 1 << (2*8+1),
|
|
HCI_LINK_KEY_SELECTION_COMMAND : 1 << (2*8+2),
|
|
HCI_REMOTE_NAME_REQUEST_COMMAND : 1 << (2*8+3),
|
|
HCI_REMOTE_NAME_REQUEST_CANCEL_COMMAND : 1 << (2*8+4),
|
|
HCI_READ_REMOTE_SUPPORTED_FEATURES_COMMAND : 1 << (2*8+5),
|
|
HCI_READ_REMOTE_EXTENDED_FEATURES_COMMAND : 1 << (2*8+6),
|
|
HCI_READ_REMOTE_VERSION_INFORMATION_COMMAND : 1 << (2*8+7),
|
|
HCI_READ_CLOCK_OFFSET_COMMAND : 1 << (3*8+0),
|
|
HCI_READ_LMP_HANDLE_COMMAND : 1 << (3*8+1),
|
|
HCI_HOLD_MODE_COMMAND : 1 << (4*8+1),
|
|
HCI_SNIFF_MODE_COMMAND : 1 << (4*8+2),
|
|
HCI_EXIT_SNIFF_MODE_COMMAND : 1 << (4*8+3),
|
|
HCI_QOS_SETUP_COMMAND : 1 << (4*8+6),
|
|
HCI_ROLE_DISCOVERY_COMMAND : 1 << (4*8+7),
|
|
HCI_SWITCH_ROLE_COMMAND : 1 << (5*8+0),
|
|
HCI_READ_LINK_POLICY_SETTINGS_COMMAND : 1 << (5*8+1),
|
|
HCI_WRITE_LINK_POLICY_SETTINGS_COMMAND : 1 << (5*8+2),
|
|
HCI_READ_DEFAULT_LINK_POLICY_SETTINGS_COMMAND : 1 << (5*8+3),
|
|
HCI_WRITE_DEFAULT_LINK_POLICY_SETTINGS_COMMAND : 1 << (5*8+4),
|
|
HCI_FLOW_SPECIFICATION_COMMAND : 1 << (5*8+5),
|
|
HCI_SET_EVENT_MASK_COMMAND : 1 << (5*8+6),
|
|
HCI_RESET_COMMAND : 1 << (5*8+7),
|
|
HCI_SET_EVENT_FILTER_COMMAND : 1 << (6*8+0),
|
|
HCI_FLUSH_COMMAND : 1 << (6*8+1),
|
|
HCI_READ_PIN_TYPE_COMMAND : 1 << (6*8+2),
|
|
HCI_WRITE_PIN_TYPE_COMMAND : 1 << (6*8+3),
|
|
HCI_READ_STORED_LINK_KEY_COMMAND : 1 << (6*8+5),
|
|
HCI_WRITE_STORED_LINK_KEY_COMMAND : 1 << (6*8+6),
|
|
HCI_DELETE_STORED_LINK_KEY_COMMAND : 1 << (6*8+7),
|
|
HCI_WRITE_LOCAL_NAME_COMMAND : 1 << (7*8+0),
|
|
HCI_READ_LOCAL_NAME_COMMAND : 1 << (7*8+1),
|
|
HCI_READ_CONNECTION_ACCEPT_TIMEOUT_COMMAND : 1 << (7*8+2),
|
|
HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT_COMMAND : 1 << (7*8+3),
|
|
HCI_READ_PAGE_TIMEOUT_COMMAND : 1 << (7*8+4),
|
|
HCI_WRITE_PAGE_TIMEOUT_COMMAND : 1 << (7*8+5),
|
|
HCI_READ_SCAN_ENABLE_COMMAND : 1 << (7*8+6),
|
|
HCI_WRITE_SCAN_ENABLE_COMMAND : 1 << (7*8+7),
|
|
HCI_READ_PAGE_SCAN_ACTIVITY_COMMAND : 1 << (8*8+0),
|
|
HCI_WRITE_PAGE_SCAN_ACTIVITY_COMMAND : 1 << (8*8+1),
|
|
HCI_READ_INQUIRY_SCAN_ACTIVITY_COMMAND : 1 << (8*8+2),
|
|
HCI_WRITE_INQUIRY_SCAN_ACTIVITY_COMMAND : 1 << (8*8+3),
|
|
HCI_READ_AUTHENTICATION_ENABLE_COMMAND : 1 << (8*8+4),
|
|
HCI_WRITE_AUTHENTICATION_ENABLE_COMMAND : 1 << (8*8+5),
|
|
HCI_READ_CLASS_OF_DEVICE_COMMAND : 1 << (9*8+0),
|
|
HCI_WRITE_CLASS_OF_DEVICE_COMMAND : 1 << (9*8+1),
|
|
HCI_READ_VOICE_SETTING_COMMAND : 1 << (9*8+2),
|
|
HCI_WRITE_VOICE_SETTING_COMMAND : 1 << (9*8+3),
|
|
HCI_READ_AUTOMATIC_FLUSH_TIMEOUT_COMMAND : 1 << (9*8+4),
|
|
HCI_WRITE_AUTOMATIC_FLUSH_TIMEOUT_COMMAND : 1 << (9*8+5),
|
|
HCI_READ_NUM_BROADCAST_RETRANSMISSIONS_COMMAND : 1 << (9*8+6),
|
|
HCI_WRITE_NUM_BROADCAST_RETRANSMISSIONS_COMMAND : 1 << (9*8+7),
|
|
HCI_READ_HOLD_MODE_ACTIVITY_COMMAND : 1 << (10*8+0),
|
|
HCI_WRITE_HOLD_MODE_ACTIVITY_COMMAND : 1 << (10*8+1),
|
|
HCI_READ_TRANSMIT_POWER_LEVEL_COMMAND : 1 << (10*8+2),
|
|
HCI_READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE_COMMAND : 1 << (10*8+3),
|
|
HCI_WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE_COMMAND : 1 << (10*8+4),
|
|
HCI_SET_CONTROLLER_TO_HOST_FLOW_CONTROL_COMMAND : 1 << (10*8+5),
|
|
HCI_HOST_BUFFER_SIZE_COMMAND : 1 << (10*8+6),
|
|
HCI_HOST_NUMBER_OF_COMPLETED_PACKETS_COMMAND : 1 << (10*8+7),
|
|
HCI_READ_LINK_SUPERVISION_TIMEOUT_COMMAND : 1 << (11*8+0),
|
|
HCI_WRITE_LINK_SUPERVISION_TIMEOUT_COMMAND : 1 << (11*8+1),
|
|
HCI_READ_NUMBER_OF_SUPPORTED_IAC_COMMAND : 1 << (11*8+2),
|
|
HCI_READ_CURRENT_IAC_LAP_COMMAND : 1 << (11*8+3),
|
|
HCI_WRITE_CURRENT_IAC_LAP_COMMAND : 1 << (11*8+4),
|
|
HCI_SET_AFH_HOST_CHANNEL_CLASSIFICATION_COMMAND : 1 << (12*8+1),
|
|
HCI_LE_CS_READ_REMOTE_FAE_TABLE_COMMAND : 1 << (12*8+2),
|
|
HCI_LE_CS_WRITE_CACHED_REMOTE_FAE_TABLE_COMMAND : 1 << (12*8+3),
|
|
HCI_READ_INQUIRY_SCAN_TYPE_COMMAND : 1 << (12*8+4),
|
|
HCI_WRITE_INQUIRY_SCAN_TYPE_COMMAND : 1 << (12*8+5),
|
|
HCI_READ_INQUIRY_MODE_COMMAND : 1 << (12*8+6),
|
|
HCI_WRITE_INQUIRY_MODE_COMMAND : 1 << (12*8+7),
|
|
HCI_READ_PAGE_SCAN_TYPE_COMMAND : 1 << (13*8+0),
|
|
HCI_WRITE_PAGE_SCAN_TYPE_COMMAND : 1 << (13*8+1),
|
|
HCI_READ_AFH_CHANNEL_ASSESSMENT_MODE_COMMAND : 1 << (13*8+2),
|
|
HCI_WRITE_AFH_CHANNEL_ASSESSMENT_MODE_COMMAND : 1 << (13*8+3),
|
|
HCI_READ_LOCAL_VERSION_INFORMATION_COMMAND : 1 << (14*8+3),
|
|
HCI_READ_LOCAL_SUPPORTED_FEATURES_COMMAND : 1 << (14*8+5),
|
|
HCI_READ_LOCAL_EXTENDED_FEATURES_COMMAND : 1 << (14*8+6),
|
|
HCI_READ_BUFFER_SIZE_COMMAND : 1 << (14*8+7),
|
|
HCI_READ_BD_ADDR_COMMAND : 1 << (15*8+1),
|
|
HCI_READ_FAILED_CONTACT_COUNTER_COMMAND : 1 << (15*8+2),
|
|
HCI_RESET_FAILED_CONTACT_COUNTER_COMMAND : 1 << (15*8+3),
|
|
HCI_READ_LINK_QUALITY_COMMAND : 1 << (15*8+4),
|
|
HCI_READ_RSSI_COMMAND : 1 << (15*8+5),
|
|
HCI_READ_AFH_CHANNEL_MAP_COMMAND : 1 << (15*8+6),
|
|
HCI_READ_CLOCK_COMMAND : 1 << (15*8+7),
|
|
HCI_READ_LOOPBACK_MODE_COMMAND : 1 << (16*8+0),
|
|
HCI_WRITE_LOOPBACK_MODE_COMMAND : 1 << (16*8+1),
|
|
HCI_ENABLE_DEVICE_UNDER_TEST_MODE_COMMAND : 1 << (16*8+2),
|
|
HCI_SETUP_SYNCHRONOUS_CONNECTION_COMMAND : 1 << (16*8+3),
|
|
HCI_ACCEPT_SYNCHRONOUS_CONNECTION_REQUEST_COMMAND : 1 << (16*8+4),
|
|
HCI_REJECT_SYNCHRONOUS_CONNECTION_REQUEST_COMMAND : 1 << (16*8+5),
|
|
HCI_LE_CS_CREATE_CONFIG_COMMAND : 1 << (16*8+6),
|
|
HCI_LE_CS_REMOVE_CONFIG_COMMAND : 1 << (16*8+7),
|
|
HCI_READ_EXTENDED_INQUIRY_RESPONSE_COMMAND : 1 << (17*8+0),
|
|
HCI_WRITE_EXTENDED_INQUIRY_RESPONSE_COMMAND : 1 << (17*8+1),
|
|
HCI_REFRESH_ENCRYPTION_KEY_COMMAND : 1 << (17*8+2),
|
|
HCI_SNIFF_SUBRATING_COMMAND : 1 << (17*8+4),
|
|
HCI_READ_SIMPLE_PAIRING_MODE_COMMAND : 1 << (17*8+5),
|
|
HCI_WRITE_SIMPLE_PAIRING_MODE_COMMAND : 1 << (17*8+6),
|
|
HCI_READ_LOCAL_OOB_DATA_COMMAND : 1 << (17*8+7),
|
|
HCI_READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL_COMMAND : 1 << (18*8+0),
|
|
HCI_WRITE_INQUIRY_TRANSMIT_POWER_LEVEL_COMMAND : 1 << (18*8+1),
|
|
HCI_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_COMMAND : 1 << (18*8+2),
|
|
HCI_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_COMMAND : 1 << (18*8+3),
|
|
HCI_IO_CAPABILITY_REQUEST_REPLY_COMMAND : 1 << (18*8+7),
|
|
HCI_USER_CONFIRMATION_REQUEST_REPLY_COMMAND : 1 << (19*8+0),
|
|
HCI_USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY_COMMAND : 1 << (19*8+1),
|
|
HCI_USER_PASSKEY_REQUEST_REPLY_COMMAND : 1 << (19*8+2),
|
|
HCI_USER_PASSKEY_REQUEST_NEGATIVE_REPLY_COMMAND : 1 << (19*8+3),
|
|
HCI_REMOTE_OOB_DATA_REQUEST_REPLY_COMMAND : 1 << (19*8+4),
|
|
HCI_WRITE_SIMPLE_PAIRING_DEBUG_MODE_COMMAND : 1 << (19*8+5),
|
|
HCI_ENHANCED_FLUSH_COMMAND : 1 << (19*8+6),
|
|
HCI_REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY_COMMAND : 1 << (19*8+7),
|
|
HCI_SEND_KEYPRESS_NOTIFICATION_COMMAND : 1 << (20*8+2),
|
|
HCI_IO_CAPABILITY_REQUEST_NEGATIVE_REPLY_COMMAND : 1 << (20*8+3),
|
|
HCI_READ_ENCRYPTION_KEY_SIZE_COMMAND : 1 << (20*8+4),
|
|
HCI_LE_CS_READ_LOCAL_SUPPORTED_CAPABILITIES_COMMAND : 1 << (20*8+5),
|
|
HCI_LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES_COMMAND : 1 << (20*8+6),
|
|
HCI_LE_CS_WRITE_CACHED_REMOTE_SUPPORTED_CAPABILITIES_COMMAND : 1 << (20*8+7),
|
|
HCI_SET_EVENT_MASK_PAGE_2_COMMAND : 1 << (22*8+2),
|
|
HCI_READ_FLOW_CONTROL_MODE_COMMAND : 1 << (23*8+0),
|
|
HCI_WRITE_FLOW_CONTROL_MODE_COMMAND : 1 << (23*8+1),
|
|
HCI_READ_DATA_BLOCK_SIZE_COMMAND : 1 << (23*8+2),
|
|
HCI_LE_CS_TEST_COMMAND : 1 << (23*8+3),
|
|
HCI_LE_CS_TEST_END_COMMAND : 1 << (23*8+4),
|
|
HCI_READ_ENHANCED_TRANSMIT_POWER_LEVEL_COMMAND : 1 << (24*8+0),
|
|
HCI_LE_CS_SECURITY_ENABLE_COMMAND : 1 << (24*8+1),
|
|
HCI_READ_LE_HOST_SUPPORT_COMMAND : 1 << (24*8+5),
|
|
HCI_WRITE_LE_HOST_SUPPORT_COMMAND : 1 << (24*8+6),
|
|
HCI_LE_CS_SET_DEFAULT_SETTINGS_COMMAND : 1 << (24*8+7),
|
|
HCI_LE_SET_EVENT_MASK_COMMAND : 1 << (25*8+0),
|
|
HCI_LE_READ_BUFFER_SIZE_COMMAND : 1 << (25*8+1),
|
|
HCI_LE_READ_LOCAL_SUPPORTED_FEATURES_COMMAND : 1 << (25*8+2),
|
|
HCI_LE_SET_RANDOM_ADDRESS_COMMAND : 1 << (25*8+4),
|
|
HCI_LE_SET_ADVERTISING_PARAMETERS_COMMAND : 1 << (25*8+5),
|
|
HCI_LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER_COMMAND : 1 << (25*8+6),
|
|
HCI_LE_SET_ADVERTISING_DATA_COMMAND : 1 << (25*8+7),
|
|
HCI_LE_SET_SCAN_RESPONSE_DATA_COMMAND : 1 << (26*8+0),
|
|
HCI_LE_SET_ADVERTISING_ENABLE_COMMAND : 1 << (26*8+1),
|
|
HCI_LE_SET_SCAN_PARAMETERS_COMMAND : 1 << (26*8+2),
|
|
HCI_LE_SET_SCAN_ENABLE_COMMAND : 1 << (26*8+3),
|
|
HCI_LE_CREATE_CONNECTION_COMMAND : 1 << (26*8+4),
|
|
HCI_LE_CREATE_CONNECTION_CANCEL_COMMAND : 1 << (26*8+5),
|
|
HCI_LE_READ_FILTER_ACCEPT_LIST_SIZE_COMMAND : 1 << (26*8+6),
|
|
HCI_LE_CLEAR_FILTER_ACCEPT_LIST_COMMAND : 1 << (26*8+7),
|
|
HCI_LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST_COMMAND : 1 << (27*8+0),
|
|
HCI_LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST_COMMAND : 1 << (27*8+1),
|
|
HCI_LE_CONNECTION_UPDATE_COMMAND : 1 << (27*8+2),
|
|
HCI_LE_SET_HOST_CHANNEL_CLASSIFICATION_COMMAND : 1 << (27*8+3),
|
|
HCI_LE_READ_CHANNEL_MAP_COMMAND : 1 << (27*8+4),
|
|
HCI_LE_READ_REMOTE_FEATURES_COMMAND : 1 << (27*8+5),
|
|
HCI_LE_ENCRYPT_COMMAND : 1 << (27*8+6),
|
|
HCI_LE_RAND_COMMAND : 1 << (27*8+7),
|
|
HCI_LE_ENABLE_ENCRYPTION_COMMAND : 1 << (28*8+0),
|
|
HCI_LE_LONG_TERM_KEY_REQUEST_REPLY_COMMAND : 1 << (28*8+1),
|
|
HCI_LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY_COMMAND : 1 << (28*8+2),
|
|
HCI_LE_READ_SUPPORTED_STATES_COMMAND : 1 << (28*8+3),
|
|
HCI_LE_RECEIVER_TEST_COMMAND : 1 << (28*8+4),
|
|
HCI_LE_TRANSMITTER_TEST_COMMAND : 1 << (28*8+5),
|
|
HCI_LE_TEST_END_COMMAND : 1 << (28*8+6),
|
|
HCI_LE_ENABLE_MONITORING_ADVERTISERS_COMMAND : 1 << (28*8+7),
|
|
HCI_LE_CS_SET_CHANNEL_CLASSIFICATION_COMMAND : 1 << (29*8+0),
|
|
HCI_LE_CS_SET_PROCEDURE_PARAMETERS_COMMAND : 1 << (29*8+1),
|
|
HCI_LE_CS_PROCEDURE_ENABLE_COMMAND : 1 << (29*8+2),
|
|
HCI_ENHANCED_SETUP_SYNCHRONOUS_CONNECTION_COMMAND : 1 << (29*8+3),
|
|
HCI_ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION_REQUEST_COMMAND : 1 << (29*8+4),
|
|
HCI_READ_LOCAL_SUPPORTED_CODECS_COMMAND : 1 << (29*8+5),
|
|
HCI_SET_MWS_CHANNEL_PARAMETERS_COMMAND : 1 << (29*8+6),
|
|
HCI_SET_EXTERNAL_FRAME_CONFIGURATION_COMMAND : 1 << (29*8+7),
|
|
HCI_SET_MWS_SIGNALING_COMMAND : 1 << (30*8+0),
|
|
HCI_SET_MWS_TRANSPORT_LAYER_COMMAND : 1 << (30*8+1),
|
|
HCI_SET_MWS_SCAN_FREQUENCY_TABLE_COMMAND : 1 << (30*8+2),
|
|
HCI_GET_MWS_TRANSPORT_LAYER_CONFIGURATION_COMMAND : 1 << (30*8+3),
|
|
HCI_SET_MWS_PATTERN_CONFIGURATION_COMMAND : 1 << (30*8+4),
|
|
HCI_SET_TRIGGERED_CLOCK_CAPTURE_COMMAND : 1 << (30*8+5),
|
|
HCI_TRUNCATED_PAGE_COMMAND : 1 << (30*8+6),
|
|
HCI_TRUNCATED_PAGE_CANCEL_COMMAND : 1 << (30*8+7),
|
|
HCI_SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_COMMAND : 1 << (31*8+0),
|
|
HCI_SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVE_COMMAND : 1 << (31*8+1),
|
|
HCI_START_SYNCHRONIZATION_TRAIN_COMMAND : 1 << (31*8+2),
|
|
HCI_RECEIVE_SYNCHRONIZATION_TRAIN_COMMAND : 1 << (31*8+3),
|
|
HCI_SET_RESERVED_LT_ADDR_COMMAND : 1 << (31*8+4),
|
|
HCI_DELETE_RESERVED_LT_ADDR_COMMAND : 1 << (31*8+5),
|
|
HCI_SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_DATA_COMMAND : 1 << (31*8+6),
|
|
HCI_READ_SYNCHRONIZATION_TRAIN_PARAMETERS_COMMAND : 1 << (31*8+7),
|
|
HCI_WRITE_SYNCHRONIZATION_TRAIN_PARAMETERS_COMMAND : 1 << (32*8+0),
|
|
HCI_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_COMMAND : 1 << (32*8+1),
|
|
HCI_READ_SECURE_CONNECTIONS_HOST_SUPPORT_COMMAND : 1 << (32*8+2),
|
|
HCI_WRITE_SECURE_CONNECTIONS_HOST_SUPPORT_COMMAND : 1 << (32*8+3),
|
|
HCI_READ_AUTHENTICATED_PAYLOAD_TIMEOUT_COMMAND : 1 << (32*8+4),
|
|
HCI_WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT_COMMAND : 1 << (32*8+5),
|
|
HCI_READ_LOCAL_OOB_EXTENDED_DATA_COMMAND : 1 << (32*8+6),
|
|
HCI_WRITE_SECURE_CONNECTIONS_TEST_MODE_COMMAND : 1 << (32*8+7),
|
|
HCI_READ_EXTENDED_PAGE_TIMEOUT_COMMAND : 1 << (33*8+0),
|
|
HCI_WRITE_EXTENDED_PAGE_TIMEOUT_COMMAND : 1 << (33*8+1),
|
|
HCI_READ_EXTENDED_INQUIRY_LENGTH_COMMAND : 1 << (33*8+2),
|
|
HCI_WRITE_EXTENDED_INQUIRY_LENGTH_COMMAND : 1 << (33*8+3),
|
|
HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY_COMMAND : 1 << (33*8+4),
|
|
HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY_COMMAND : 1 << (33*8+5),
|
|
HCI_LE_SET_DATA_LENGTH_COMMAND : 1 << (33*8+6),
|
|
HCI_LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH_COMMAND : 1 << (33*8+7),
|
|
HCI_LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH_COMMAND : 1 << (34*8+0),
|
|
HCI_LE_READ_LOCAL_P_256_PUBLIC_KEY_COMMAND : 1 << (34*8+1),
|
|
HCI_LE_GENERATE_DHKEY_COMMAND : 1 << (34*8+2),
|
|
HCI_LE_ADD_DEVICE_TO_RESOLVING_LIST_COMMAND : 1 << (34*8+3),
|
|
HCI_LE_REMOVE_DEVICE_FROM_RESOLVING_LIST_COMMAND : 1 << (34*8+4),
|
|
HCI_LE_CLEAR_RESOLVING_LIST_COMMAND : 1 << (34*8+5),
|
|
HCI_LE_READ_RESOLVING_LIST_SIZE_COMMAND : 1 << (34*8+6),
|
|
HCI_LE_READ_PEER_RESOLVABLE_ADDRESS_COMMAND : 1 << (34*8+7),
|
|
HCI_LE_READ_LOCAL_RESOLVABLE_ADDRESS_COMMAND : 1 << (35*8+0),
|
|
HCI_LE_SET_ADDRESS_RESOLUTION_ENABLE_COMMAND : 1 << (35*8+1),
|
|
HCI_LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT_COMMAND : 1 << (35*8+2),
|
|
HCI_LE_READ_MAXIMUM_DATA_LENGTH_COMMAND : 1 << (35*8+3),
|
|
HCI_LE_READ_PHY_COMMAND : 1 << (35*8+4),
|
|
HCI_LE_SET_DEFAULT_PHY_COMMAND : 1 << (35*8+5),
|
|
HCI_LE_SET_PHY_COMMAND : 1 << (35*8+6),
|
|
HCI_LE_RECEIVER_TEST_V2_COMMAND : 1 << (35*8+7),
|
|
HCI_LE_TRANSMITTER_TEST_V2_COMMAND : 1 << (36*8+0),
|
|
HCI_LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_COMMAND : 1 << (36*8+1),
|
|
HCI_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_COMMAND : 1 << (36*8+2),
|
|
HCI_LE_SET_EXTENDED_ADVERTISING_DATA_COMMAND : 1 << (36*8+3),
|
|
HCI_LE_SET_EXTENDED_SCAN_RESPONSE_DATA_COMMAND : 1 << (36*8+4),
|
|
HCI_LE_SET_EXTENDED_ADVERTISING_ENABLE_COMMAND : 1 << (36*8+5),
|
|
HCI_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH_COMMAND : 1 << (36*8+6),
|
|
HCI_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS_COMMAND : 1 << (36*8+7),
|
|
HCI_LE_REMOVE_ADVERTISING_SET_COMMAND : 1 << (37*8+0),
|
|
HCI_LE_CLEAR_ADVERTISING_SETS_COMMAND : 1 << (37*8+1),
|
|
HCI_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_COMMAND : 1 << (37*8+2),
|
|
HCI_LE_SET_PERIODIC_ADVERTISING_DATA_COMMAND : 1 << (37*8+3),
|
|
HCI_LE_SET_PERIODIC_ADVERTISING_ENABLE_COMMAND : 1 << (37*8+4),
|
|
HCI_LE_SET_EXTENDED_SCAN_PARAMETERS_COMMAND : 1 << (37*8+5),
|
|
HCI_LE_SET_EXTENDED_SCAN_ENABLE_COMMAND : 1 << (37*8+6),
|
|
HCI_LE_EXTENDED_CREATE_CONNECTION_COMMAND : 1 << (37*8+7),
|
|
HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC_COMMAND : 1 << (38*8+0),
|
|
HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL_COMMAND : 1 << (38*8+1),
|
|
HCI_LE_PERIODIC_ADVERTISING_TERMINATE_SYNC_COMMAND : 1 << (38*8+2),
|
|
HCI_LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST_COMMAND : 1 << (38*8+3),
|
|
HCI_LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST_COMMAND : 1 << (38*8+4),
|
|
HCI_LE_CLEAR_PERIODIC_ADVERTISER_LIST_COMMAND : 1 << (38*8+5),
|
|
HCI_LE_READ_PERIODIC_ADVERTISER_LIST_SIZE_COMMAND : 1 << (38*8+6),
|
|
HCI_LE_READ_TRANSMIT_POWER_COMMAND : 1 << (38*8+7),
|
|
HCI_LE_READ_RF_PATH_COMPENSATION_COMMAND : 1 << (39*8+0),
|
|
HCI_LE_WRITE_RF_PATH_COMPENSATION_COMMAND : 1 << (39*8+1),
|
|
HCI_LE_SET_PRIVACY_MODE_COMMAND : 1 << (39*8+2),
|
|
HCI_LE_RECEIVER_TEST_V3_COMMAND : 1 << (39*8+3),
|
|
HCI_LE_TRANSMITTER_TEST_V3_COMMAND : 1 << (39*8+4),
|
|
HCI_LE_SET_CONNECTIONLESS_CTE_TRANSMIT_PARAMETERS_COMMAND : 1 << (39*8+5),
|
|
HCI_LE_SET_CONNECTIONLESS_CTE_TRANSMIT_ENABLE_COMMAND : 1 << (39*8+6),
|
|
HCI_LE_SET_CONNECTIONLESS_IQ_SAMPLING_ENABLE_COMMAND : 1 << (39*8+7),
|
|
HCI_LE_SET_CONNECTION_CTE_RECEIVE_PARAMETERS_COMMAND : 1 << (40*8+0),
|
|
HCI_LE_SET_CONNECTION_CTE_TRANSMIT_PARAMETERS_COMMAND : 1 << (40*8+1),
|
|
HCI_LE_CONNECTION_CTE_REQUEST_ENABLE_COMMAND : 1 << (40*8+2),
|
|
HCI_LE_CONNECTION_CTE_RESPONSE_ENABLE_COMMAND : 1 << (40*8+3),
|
|
HCI_LE_READ_ANTENNA_INFORMATION_COMMAND : 1 << (40*8+4),
|
|
HCI_LE_SET_PERIODIC_ADVERTISING_RECEIVE_ENABLE_COMMAND : 1 << (40*8+5),
|
|
HCI_LE_PERIODIC_ADVERTISING_SYNC_TRANSFER_COMMAND : 1 << (40*8+6),
|
|
HCI_LE_PERIODIC_ADVERTISING_SET_INFO_TRANSFER_COMMAND : 1 << (40*8+7),
|
|
HCI_LE_SET_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS_COMMAND : 1 << (41*8+0),
|
|
HCI_LE_SET_DEFAULT_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS_COMMAND : 1 << (41*8+1),
|
|
HCI_LE_GENERATE_DHKEY_V2_COMMAND : 1 << (41*8+2),
|
|
HCI_READ_LOCAL_SIMPLE_PAIRING_OPTIONS_COMMAND : 1 << (41*8+3),
|
|
HCI_LE_MODIFY_SLEEP_CLOCK_ACCURACY_COMMAND : 1 << (41*8+4),
|
|
HCI_LE_READ_BUFFER_SIZE_V2_COMMAND : 1 << (41*8+5),
|
|
HCI_LE_READ_ISO_TX_SYNC_COMMAND : 1 << (41*8+6),
|
|
HCI_LE_SET_CIG_PARAMETERS_COMMAND : 1 << (41*8+7),
|
|
HCI_LE_SET_CIG_PARAMETERS_TEST_COMMAND : 1 << (42*8+0),
|
|
HCI_LE_CREATE_CIS_COMMAND : 1 << (42*8+1),
|
|
HCI_LE_REMOVE_CIG_COMMAND : 1 << (42*8+2),
|
|
HCI_LE_ACCEPT_CIS_REQUEST_COMMAND : 1 << (42*8+3),
|
|
HCI_LE_REJECT_CIS_REQUEST_COMMAND : 1 << (42*8+4),
|
|
HCI_LE_CREATE_BIG_COMMAND : 1 << (42*8+5),
|
|
HCI_LE_CREATE_BIG_TEST_COMMAND : 1 << (42*8+6),
|
|
HCI_LE_TERMINATE_BIG_COMMAND : 1 << (42*8+7),
|
|
HCI_LE_BIG_CREATE_SYNC_COMMAND : 1 << (43*8+0),
|
|
HCI_LE_BIG_TERMINATE_SYNC_COMMAND : 1 << (43*8+1),
|
|
HCI_LE_REQUEST_PEER_SCA_COMMAND : 1 << (43*8+2),
|
|
HCI_LE_SETUP_ISO_DATA_PATH_COMMAND : 1 << (43*8+3),
|
|
HCI_LE_REMOVE_ISO_DATA_PATH_COMMAND : 1 << (43*8+4),
|
|
HCI_LE_ISO_TRANSMIT_TEST_COMMAND : 1 << (43*8+5),
|
|
HCI_LE_ISO_RECEIVE_TEST_COMMAND : 1 << (43*8+6),
|
|
HCI_LE_ISO_READ_TEST_COUNTERS_COMMAND : 1 << (43*8+7),
|
|
HCI_LE_ISO_TEST_END_COMMAND : 1 << (44*8+0),
|
|
HCI_LE_SET_HOST_FEATURE_COMMAND : 1 << (44*8+1),
|
|
HCI_LE_READ_ISO_LINK_QUALITY_COMMAND : 1 << (44*8+2),
|
|
HCI_LE_ENHANCED_READ_TRANSMIT_POWER_LEVEL_COMMAND : 1 << (44*8+3),
|
|
HCI_LE_READ_REMOTE_TRANSMIT_POWER_LEVEL_COMMAND : 1 << (44*8+4),
|
|
HCI_LE_SET_PATH_LOSS_REPORTING_PARAMETERS_COMMAND : 1 << (44*8+5),
|
|
HCI_LE_SET_PATH_LOSS_REPORTING_ENABLE_COMMAND : 1 << (44*8+6),
|
|
HCI_LE_SET_TRANSMIT_POWER_REPORTING_ENABLE_COMMAND : 1 << (44*8+7),
|
|
HCI_LE_TRANSMITTER_TEST_V4_COMMAND : 1 << (45*8+0),
|
|
HCI_SET_ECOSYSTEM_BASE_INTERVAL_COMMAND : 1 << (45*8+1),
|
|
HCI_READ_LOCAL_SUPPORTED_CODECS_V2_COMMAND : 1 << (45*8+2),
|
|
HCI_READ_LOCAL_SUPPORTED_CODEC_CAPABILITIES_COMMAND : 1 << (45*8+3),
|
|
HCI_READ_LOCAL_SUPPORTED_CONTROLLER_DELAY_COMMAND : 1 << (45*8+4),
|
|
HCI_CONFIGURE_DATA_PATH_COMMAND : 1 << (45*8+5),
|
|
HCI_LE_SET_DATA_RELATED_ADDRESS_CHANGES_COMMAND : 1 << (45*8+6),
|
|
HCI_SET_MIN_ENCRYPTION_KEY_SIZE_COMMAND : 1 << (45*8+7),
|
|
HCI_LE_SET_DEFAULT_SUBRATE_COMMAND : 1 << (46*8+0),
|
|
HCI_LE_SUBRATE_REQUEST_COMMAND : 1 << (46*8+1),
|
|
HCI_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_V2_COMMAND : 1 << (46*8+2),
|
|
HCI_LE_SET_DECISION_DATA_COMMAND : 1 << (46*8+3),
|
|
HCI_LE_SET_DECISION_INSTRUCTIONS_COMMAND : 1 << (46*8+4),
|
|
HCI_LE_SET_PERIODIC_ADVERTISING_SUBEVENT_DATA_COMMAND : 1 << (46*8+5),
|
|
HCI_LE_SET_PERIODIC_ADVERTISING_RESPONSE_DATA_COMMAND : 1 << (46*8+6),
|
|
HCI_LE_SET_PERIODIC_SYNC_SUBEVENT_COMMAND : 1 << (46*8+7),
|
|
HCI_LE_EXTENDED_CREATE_CONNECTION_V2_COMMAND : 1 << (47*8+0),
|
|
HCI_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_V2_COMMAND : 1 << (47*8+1),
|
|
HCI_LE_READ_ALL_LOCAL_SUPPORTED_FEATURES_COMMAND : 1 << (47*8+2),
|
|
HCI_LE_READ_ALL_REMOTE_FEATURES_COMMAND : 1 << (47*8+3),
|
|
HCI_LE_SET_HOST_FEATURE_V2_COMMAND : 1 << (47*8+4),
|
|
HCI_LE_ADD_DEVICE_TO_MONITORED_ADVERTISERS_LIST_COMMAND : 1 << (47*8+5),
|
|
HCI_LE_REMOVE_DEVICE_FROM_MONITORED_ADVERTISERS_LIST_COMMAND : 1 << (47*8+6),
|
|
HCI_LE_CLEAR_MONITORED_ADVERTISERS_LIST_COMMAND : 1 << (47*8+7),
|
|
HCI_LE_READ_MONITORED_ADVERTISERS_LIST_SIZE_COMMAND : 1 << (48*8+0),
|
|
HCI_LE_FRAME_SPACE_UPDATE_COMMAND : 1 << (48*8+1),
|
|
HCI_LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT_V2_COMMAND : 1 << (48*8+2),
|
|
HCI_LE_ENABLE_UTP_OTA_MODE_COMMAND : 1 << (48*8+3),
|
|
HCI_LE_UTP_SEND_COMMAND : 1 << (48*8+4),
|
|
HCI_LE_CONNECTION_RATE_REQUEST_COMMAND : 1 << (48*8+5),
|
|
HCI_LE_SET_DEFAULT_RATE_PARAMETERS_COMMAND : 1 << (48*8+6),
|
|
HCI_LE_READ_MINIMUM_SUPPORTED_CONNECTION_INTERVAL_COMMAND : 1 << (48*8+7)
|
|
}
|
|
|
|
# LE Supported Features
|
|
# See Bluetooth spec @ Vol 6, Part B, 4.6 FEATURE SUPPORT
|
|
class LeFeature(SpecableEnum):
|
|
LE_ENCRYPTION = 0
|
|
CONNECTION_PARAMETERS_REQUEST_PROCEDURE = 1
|
|
EXTENDED_REJECT_INDICATION = 2
|
|
PERIPHERAL_INITIATED_FEATURE_EXCHANGE = 3
|
|
LE_PING = 4
|
|
LE_DATA_PACKET_LENGTH_EXTENSION = 5
|
|
LL_PRIVACY = 6
|
|
EXTENDED_SCANNER_FILTER_POLICIES = 7
|
|
LE_2M_PHY = 8
|
|
STABLE_MODULATION_INDEX_TRANSMITTER = 9
|
|
STABLE_MODULATION_INDEX_RECEIVER = 10
|
|
LE_CODED_PHY = 11
|
|
LE_EXTENDED_ADVERTISING = 12
|
|
LE_PERIODIC_ADVERTISING = 13
|
|
CHANNEL_SELECTION_ALGORITHM_2 = 14
|
|
LE_POWER_CLASS_1 = 15
|
|
MINIMUM_NUMBER_OF_USED_CHANNELS_PROCEDURE = 16
|
|
CONNECTION_CTE_REQUEST = 17
|
|
CONNECTION_CTE_RESPONSE = 18
|
|
CONNECTIONLESS_CTE_TRANSMITTER = 19
|
|
CONNECTIONLESS_CTR_RECEIVER = 20
|
|
ANTENNA_SWITCHING_DURING_CTE_TRANSMISSION = 21
|
|
ANTENNA_SWITCHING_DURING_CTE_RECEPTION = 22
|
|
RECEIVING_CONSTANT_TONE_EXTENSIONS = 23
|
|
PERIODIC_ADVERTISING_SYNC_TRANSFER_SENDER = 24
|
|
PERIODIC_ADVERTISING_SYNC_TRANSFER_RECIPIENT = 25
|
|
SLEEP_CLOCK_ACCURACY_UPDATES = 26
|
|
REMOTE_PUBLIC_KEY_VALIDATION = 27
|
|
CONNECTED_ISOCHRONOUS_STREAM_CENTRAL = 28
|
|
CONNECTED_ISOCHRONOUS_STREAM_PERIPHERAL = 29
|
|
ISOCHRONOUS_BROADCASTER = 30
|
|
SYNCHRONIZED_RECEIVER = 31
|
|
CONNECTED_ISOCHRONOUS_STREAM = 32
|
|
LE_POWER_CONTROL_REQUEST = 33
|
|
LE_POWER_CONTROL_REQUEST_DUP = 34
|
|
LE_PATH_LOSS_MONITORING = 35
|
|
PERIODIC_ADVERTISING_ADI_SUPPORT = 36
|
|
CONNECTION_SUBRATING = 37
|
|
CONNECTION_SUBRATING_HOST_SUPPORT = 38
|
|
CHANNEL_CLASSIFICATION = 39
|
|
ADVERTISING_CODING_SELECTION = 40
|
|
ADVERTISING_CODING_SELECTION_HOST_SUPPORT = 41
|
|
DECISION_BASED_ADVERTISING_FILTERING = 42
|
|
PERIODIC_ADVERTISING_WITH_RESPONSES_ADVERTISER = 43
|
|
PERIODIC_ADVERTISING_WITH_RESPONSES_SCANNER = 44
|
|
UNSEGMENTED_FRAMED_MODE = 45
|
|
CHANNEL_SOUNDING = 46
|
|
CHANNEL_SOUNDING_HOST_SUPPORT = 47
|
|
CHANNEL_SOUNDING_TONE_QUALITY_INDICATION = 48
|
|
LL_EXTENDED_FEATURE_SET = 63
|
|
MONITORING_ADVERTISERS = 64
|
|
FRAME_SPACE_UPDATE = 65
|
|
UTP_OTA_MODE = 66
|
|
UTP_HCI_MODE = 67
|
|
LL_OTA_UTP_IND_MAXIMUM_LENGTH_0 = 68
|
|
LL_OTA_UTP_IND_MAXIMUM_LENGTH_1 = 69
|
|
SHORTER_CONNECTION_INTERVALS = 72
|
|
SHORTER_CONNECTION_INTERVALS_HOST_SUPPORT = 73
|
|
LE_FLUSHABLE_ACL_DATA = 74
|
|
|
|
|
|
class LeFeatureMask(utils.CompatibleIntFlag):
|
|
LE_ENCRYPTION = 1 << LeFeature.LE_ENCRYPTION
|
|
CONNECTION_PARAMETERS_REQUEST_PROCEDURE = 1 << LeFeature.CONNECTION_PARAMETERS_REQUEST_PROCEDURE
|
|
EXTENDED_REJECT_INDICATION = 1 << LeFeature.EXTENDED_REJECT_INDICATION
|
|
PERIPHERAL_INITIATED_FEATURE_EXCHANGE = 1 << LeFeature.PERIPHERAL_INITIATED_FEATURE_EXCHANGE
|
|
LE_PING = 1 << LeFeature.LE_PING
|
|
LE_DATA_PACKET_LENGTH_EXTENSION = 1 << LeFeature.LE_DATA_PACKET_LENGTH_EXTENSION
|
|
LL_PRIVACY = 1 << LeFeature.LL_PRIVACY
|
|
EXTENDED_SCANNER_FILTER_POLICIES = 1 << LeFeature.EXTENDED_SCANNER_FILTER_POLICIES
|
|
LE_2M_PHY = 1 << LeFeature.LE_2M_PHY
|
|
STABLE_MODULATION_INDEX_TRANSMITTER = 1 << LeFeature.STABLE_MODULATION_INDEX_TRANSMITTER
|
|
STABLE_MODULATION_INDEX_RECEIVER = 1 << LeFeature.STABLE_MODULATION_INDEX_RECEIVER
|
|
LE_CODED_PHY = 1 << LeFeature.LE_CODED_PHY
|
|
LE_EXTENDED_ADVERTISING = 1 << LeFeature.LE_EXTENDED_ADVERTISING
|
|
LE_PERIODIC_ADVERTISING = 1 << LeFeature.LE_PERIODIC_ADVERTISING
|
|
CHANNEL_SELECTION_ALGORITHM_2 = 1 << LeFeature.CHANNEL_SELECTION_ALGORITHM_2
|
|
LE_POWER_CLASS_1 = 1 << LeFeature.LE_POWER_CLASS_1
|
|
MINIMUM_NUMBER_OF_USED_CHANNELS_PROCEDURE = 1 << LeFeature.MINIMUM_NUMBER_OF_USED_CHANNELS_PROCEDURE
|
|
CONNECTION_CTE_REQUEST = 1 << LeFeature.CONNECTION_CTE_REQUEST
|
|
CONNECTION_CTE_RESPONSE = 1 << LeFeature.CONNECTION_CTE_RESPONSE
|
|
CONNECTIONLESS_CTE_TRANSMITTER = 1 << LeFeature.CONNECTIONLESS_CTE_TRANSMITTER
|
|
CONNECTIONLESS_CTR_RECEIVER = 1 << LeFeature.CONNECTIONLESS_CTR_RECEIVER
|
|
ANTENNA_SWITCHING_DURING_CTE_TRANSMISSION = 1 << LeFeature.ANTENNA_SWITCHING_DURING_CTE_TRANSMISSION
|
|
ANTENNA_SWITCHING_DURING_CTE_RECEPTION = 1 << LeFeature.ANTENNA_SWITCHING_DURING_CTE_RECEPTION
|
|
RECEIVING_CONSTANT_TONE_EXTENSIONS = 1 << LeFeature.RECEIVING_CONSTANT_TONE_EXTENSIONS
|
|
PERIODIC_ADVERTISING_SYNC_TRANSFER_SENDER = 1 << LeFeature.PERIODIC_ADVERTISING_SYNC_TRANSFER_SENDER
|
|
PERIODIC_ADVERTISING_SYNC_TRANSFER_RECIPIENT = 1 << LeFeature.PERIODIC_ADVERTISING_SYNC_TRANSFER_RECIPIENT
|
|
SLEEP_CLOCK_ACCURACY_UPDATES = 1 << LeFeature.SLEEP_CLOCK_ACCURACY_UPDATES
|
|
REMOTE_PUBLIC_KEY_VALIDATION = 1 << LeFeature.REMOTE_PUBLIC_KEY_VALIDATION
|
|
CONNECTED_ISOCHRONOUS_STREAM_CENTRAL = 1 << LeFeature.CONNECTED_ISOCHRONOUS_STREAM_CENTRAL
|
|
CONNECTED_ISOCHRONOUS_STREAM_PERIPHERAL = 1 << LeFeature.CONNECTED_ISOCHRONOUS_STREAM_PERIPHERAL
|
|
ISOCHRONOUS_BROADCASTER = 1 << LeFeature.ISOCHRONOUS_BROADCASTER
|
|
SYNCHRONIZED_RECEIVER = 1 << LeFeature.SYNCHRONIZED_RECEIVER
|
|
CONNECTED_ISOCHRONOUS_STREAM = 1 << LeFeature.CONNECTED_ISOCHRONOUS_STREAM
|
|
LE_POWER_CONTROL_REQUEST = 1 << LeFeature.LE_POWER_CONTROL_REQUEST
|
|
LE_POWER_CONTROL_REQUEST_DUP = 1 << LeFeature.LE_POWER_CONTROL_REQUEST_DUP
|
|
LE_PATH_LOSS_MONITORING = 1 << LeFeature.LE_PATH_LOSS_MONITORING
|
|
PERIODIC_ADVERTISING_ADI_SUPPORT = 1 << LeFeature.PERIODIC_ADVERTISING_ADI_SUPPORT
|
|
CONNECTION_SUBRATING = 1 << LeFeature.CONNECTION_SUBRATING
|
|
CONNECTION_SUBRATING_HOST_SUPPORT = 1 << LeFeature.CONNECTION_SUBRATING_HOST_SUPPORT
|
|
CHANNEL_CLASSIFICATION = 1 << LeFeature.CHANNEL_CLASSIFICATION
|
|
ADVERTISING_CODING_SELECTION = 1 << LeFeature.ADVERTISING_CODING_SELECTION
|
|
ADVERTISING_CODING_SELECTION_HOST_SUPPORT = 1 << LeFeature.ADVERTISING_CODING_SELECTION_HOST_SUPPORT
|
|
DECISION_BASED_ADVERTISING_FILTERING = 1 << LeFeature.DECISION_BASED_ADVERTISING_FILTERING
|
|
PERIODIC_ADVERTISING_WITH_RESPONSES_ADVERTISER = 1 << LeFeature.PERIODIC_ADVERTISING_WITH_RESPONSES_ADVERTISER
|
|
PERIODIC_ADVERTISING_WITH_RESPONSES_SCANNER = 1 << LeFeature.PERIODIC_ADVERTISING_WITH_RESPONSES_SCANNER
|
|
UNSEGMENTED_FRAMED_MODE = 1 << LeFeature.UNSEGMENTED_FRAMED_MODE
|
|
CHANNEL_SOUNDING = 1 << LeFeature.CHANNEL_SOUNDING
|
|
CHANNEL_SOUNDING_HOST_SUPPORT = 1 << LeFeature.CHANNEL_SOUNDING_HOST_SUPPORT
|
|
CHANNEL_SOUNDING_TONE_QUALITY_INDICATION = 1 << LeFeature.CHANNEL_SOUNDING_TONE_QUALITY_INDICATION
|
|
LL_EXTENDED_FEATURE_SET = 1 << LeFeature.LL_EXTENDED_FEATURE_SET
|
|
MONITORING_ADVERTISERS = 1 << LeFeature.MONITORING_ADVERTISERS
|
|
FRAME_SPACE_UPDATE = 1 << LeFeature.FRAME_SPACE_UPDATE
|
|
UTP_OTA_MODE = 1 << LeFeature.UTP_OTA_MODE
|
|
UTP_HCI_MODE = 1 << LeFeature.UTP_HCI_MODE
|
|
LL_OTA_UTP_IND_MAXIMUM_LENGTH_0 = 1 << LeFeature.LL_OTA_UTP_IND_MAXIMUM_LENGTH_0
|
|
LL_OTA_UTP_IND_MAXIMUM_LENGTH_1 = 1 << LeFeature.LL_OTA_UTP_IND_MAXIMUM_LENGTH_1
|
|
SHORTER_CONNECTION_INTERVALS = 1 << LeFeature.SHORTER_CONNECTION_INTERVALS
|
|
SHORTER_CONNECTION_INTERVALS_HOST_SUPPORT = 1 << LeFeature.SHORTER_CONNECTION_INTERVALS_HOST_SUPPORT
|
|
LE_FLUSHABLE_ACL_DATA = 1 << LeFeature.LE_FLUSHABLE_ACL_DATA
|
|
|
|
class LmpFeature(SpecableEnum):
|
|
# Page 0 (Legacy LMP features)
|
|
LMP_3_SLOT_PACKETS = 0
|
|
LMP_5_SLOT_PACKETS = 1
|
|
ENCRYPTION = 2
|
|
SLOT_OFFSET = 3
|
|
TIMING_ACCURACY = 4
|
|
ROLE_SWITCH = 5
|
|
HOLD_MODE = 6
|
|
SNIFF_MODE = 7
|
|
# PREVIOUSLY_USED = 8
|
|
POWER_CONTROL_REQUESTS = 9
|
|
CHANNEL_QUALITY_DRIVEN_DATA_RATE_CQDDR = 10
|
|
SCO_LINK = 11
|
|
HV2_PACKETS = 12
|
|
HV3_PACKETS = 13
|
|
U_LAW_LOG_SYNCHRONOUS_DATA = 14
|
|
A_LAW_LOG_SYNCHRONOUS_DATA = 15
|
|
CVSD_SYNCHRONOUS_DATA = 16
|
|
PAGING_PARAMETER_NEGOTIATION = 17
|
|
POWER_CONTROL = 18
|
|
TRANSPARENT_SYNCHRONOUS_DATA = 19
|
|
FLOW_CONTROL_LAG_LEAST_SIGNIFICANT_BIT = 20
|
|
FLOW_CONTROL_LAG_MIDDLE_BIT = 21
|
|
FLOW_CONTROL_LAG_MOST_SIGNIFICANT_BIT = 22
|
|
BROADCAST_ENCRYPTION = 23
|
|
# RESERVED_FOR_FUTURE_USE = 24
|
|
ENHANCED_DATA_RATE_ACL_2_MBPS_MODE = 25
|
|
ENHANCED_DATA_RATE_ACL_3_MBPS_MODE = 26
|
|
ENHANCED_INQUIRY_SCAN = 27
|
|
INTERLACED_INQUIRY_SCAN = 28
|
|
INTERLACED_PAGE_SCAN = 29
|
|
RSSI_WITH_INQUIRY_RESULTS = 30
|
|
EXTENDED_SCO_LINK_EV3_PACKETS = 31
|
|
EV4_PACKETS = 32
|
|
EV5_PACKETS = 33
|
|
# RESERVED_FOR_FUTURE_USE = 34
|
|
AFH_CAPABLE_PERIPHERAL = 35
|
|
AFH_CLASSIFICATION_PERIPHERAL = 36
|
|
BR_EDR_NOT_SUPPORTED = 37
|
|
LE_SUPPORTED_CONTROLLER = 38
|
|
LMP_3_SLOT_ENHANCED_DATA_RATE_ACL_PACKETS = 39
|
|
LMP_5_SLOT_ENHANCED_DATA_RATE_ACL_PACKETS = 40
|
|
SNIFF_SUBRATING = 41
|
|
PAUSE_ENCRYPTION = 42
|
|
AFH_CAPABLE_CENTRAL = 43
|
|
AFH_CLASSIFICATION_CENTRAL = 44
|
|
ENHANCED_DATA_RATE_ESCO_2_MBPS_MODE = 45
|
|
ENHANCED_DATA_RATE_ESCO_3_MBPS_MODE = 46
|
|
LMP_3_SLOT_ENHANCED_DATA_RATE_ESCO_PACKETS = 47
|
|
EXTENDED_INQUIRY_RESPONSE = 48
|
|
SIMULTANEOUS_LE_AND_BR_EDR_TO_SAME_DEVICE_CAPABLE_CONTROLLER = 49
|
|
# RESERVED_FOR_FUTURE_USE = 50
|
|
SECURE_SIMPLE_PAIRING_CONTROLLER_SUPPORT = 51
|
|
ENCAPSULATED_PDU = 52
|
|
ERRONEOUS_DATA_REPORTING = 53
|
|
NON_FLUSHABLE_PACKET_BOUNDARY_FLAG = 54
|
|
# RESERVED_FOR_FUTURE_USE = 55
|
|
HCI_LINK_SUPERVISION_TIMEOUT_CHANGED_EVENT = 56
|
|
VARIABLE_INQUIRY_TX_POWER_LEVEL = 57
|
|
ENHANCED_POWER_CONTROL = 58
|
|
# RESERVED_FOR_FUTURE_USE = 59
|
|
# RESERVED_FOR_FUTURE_USE = 60
|
|
# RESERVED_FOR_FUTURE_USE = 61
|
|
# RESERVED_FOR_FUTURE_USE = 62
|
|
EXTENDED_FEATURES = 63
|
|
|
|
# Page 1
|
|
SECURE_SIMPLE_PAIRING_HOST_SUPPORT = 64
|
|
LE_SUPPORTED_HOST = 65
|
|
# PREVIOUSLY_USED = 66
|
|
SECURE_CONNECTIONS_HOST_SUPPORT = 67
|
|
|
|
# Page 2
|
|
CONNECTIONLESS_PERIPHERAL_BROADCAST_TRANSMITTER_OPERATION = 128
|
|
CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVER_OPERATION = 129
|
|
SYNCHRONIZATION_TRAIN = 130
|
|
SYNCHRONIZATION_SCAN = 131
|
|
HCI_INQUIRY_RESPONSE_NOTIFICATION_EVENT = 132
|
|
GENERALIZED_INTERLACED_SCAN = 133
|
|
COARSE_CLOCK_ADJUSTMENT = 134
|
|
RESERVED_FOR_FUTURE_USE = 135
|
|
SECURE_CONNECTIONS_CONTROLLER_SUPPORT = 136
|
|
PING = 137
|
|
SLOT_AVAILABILITY_MASK = 138
|
|
TRAIN_NUDGING = 139
|
|
|
|
class LmpFeatureMask(utils.CompatibleIntFlag):
|
|
# Page 0 (Legacy LMP features)
|
|
LMP_3_SLOT_PACKETS = (1 << LmpFeature.LMP_3_SLOT_PACKETS)
|
|
LMP_5_SLOT_PACKETS = (1 << LmpFeature.LMP_5_SLOT_PACKETS)
|
|
ENCRYPTION = (1 << LmpFeature.ENCRYPTION)
|
|
SLOT_OFFSET = (1 << LmpFeature.SLOT_OFFSET)
|
|
TIMING_ACCURACY = (1 << LmpFeature.TIMING_ACCURACY)
|
|
ROLE_SWITCH = (1 << LmpFeature.ROLE_SWITCH)
|
|
HOLD_MODE = (1 << LmpFeature.HOLD_MODE)
|
|
SNIFF_MODE = (1 << LmpFeature.SNIFF_MODE)
|
|
# PREVIOUSLY_USED = (1 << LmpFeature.PREVIOUSLY_USED)
|
|
POWER_CONTROL_REQUESTS = (1 << LmpFeature.POWER_CONTROL_REQUESTS)
|
|
CHANNEL_QUALITY_DRIVEN_DATA_RATE_CQDDR = (1 << LmpFeature.CHANNEL_QUALITY_DRIVEN_DATA_RATE_CQDDR)
|
|
SCO_LINK = (1 << LmpFeature.SCO_LINK)
|
|
HV2_PACKETS = (1 << LmpFeature.HV2_PACKETS)
|
|
HV3_PACKETS = (1 << LmpFeature.HV3_PACKETS)
|
|
U_LAW_LOG_SYNCHRONOUS_DATA = (1 << LmpFeature.U_LAW_LOG_SYNCHRONOUS_DATA)
|
|
A_LAW_LOG_SYNCHRONOUS_DATA = (1 << LmpFeature.A_LAW_LOG_SYNCHRONOUS_DATA)
|
|
CVSD_SYNCHRONOUS_DATA = (1 << LmpFeature.CVSD_SYNCHRONOUS_DATA)
|
|
PAGING_PARAMETER_NEGOTIATION = (1 << LmpFeature.PAGING_PARAMETER_NEGOTIATION)
|
|
POWER_CONTROL = (1 << LmpFeature.POWER_CONTROL)
|
|
TRANSPARENT_SYNCHRONOUS_DATA = (1 << LmpFeature.TRANSPARENT_SYNCHRONOUS_DATA)
|
|
FLOW_CONTROL_LAG_LEAST_SIGNIFICANT_BIT = (1 << LmpFeature.FLOW_CONTROL_LAG_LEAST_SIGNIFICANT_BIT)
|
|
FLOW_CONTROL_LAG_MIDDLE_BIT = (1 << LmpFeature.FLOW_CONTROL_LAG_MIDDLE_BIT)
|
|
FLOW_CONTROL_LAG_MOST_SIGNIFICANT_BIT = (1 << LmpFeature.FLOW_CONTROL_LAG_MOST_SIGNIFICANT_BIT)
|
|
BROADCAST_ENCRYPTION = (1 << LmpFeature.BROADCAST_ENCRYPTION)
|
|
# RESERVED_FOR_FUTURE_USE = (1 << LmpFeature.RESERVED_FOR_FUTURE_USE)
|
|
ENHANCED_DATA_RATE_ACL_2_MBPS_MODE = (1 << LmpFeature.ENHANCED_DATA_RATE_ACL_2_MBPS_MODE)
|
|
ENHANCED_DATA_RATE_ACL_3_MBPS_MODE = (1 << LmpFeature.ENHANCED_DATA_RATE_ACL_3_MBPS_MODE)
|
|
ENHANCED_INQUIRY_SCAN = (1 << LmpFeature.ENHANCED_INQUIRY_SCAN)
|
|
INTERLACED_INQUIRY_SCAN = (1 << LmpFeature.INTERLACED_INQUIRY_SCAN)
|
|
INTERLACED_PAGE_SCAN = (1 << LmpFeature.INTERLACED_PAGE_SCAN)
|
|
RSSI_WITH_INQUIRY_RESULTS = (1 << LmpFeature.RSSI_WITH_INQUIRY_RESULTS)
|
|
EXTENDED_SCO_LINK_EV3_PACKETS = (1 << LmpFeature.EXTENDED_SCO_LINK_EV3_PACKETS)
|
|
EV4_PACKETS = (1 << LmpFeature.EV4_PACKETS)
|
|
EV5_PACKETS = (1 << LmpFeature.EV5_PACKETS)
|
|
# RESERVED_FOR_FUTURE_USE = (1 << LmpFeature.RESERVED_FOR_FUTURE_USE)
|
|
AFH_CAPABLE_PERIPHERAL = (1 << LmpFeature.AFH_CAPABLE_PERIPHERAL)
|
|
AFH_CLASSIFICATION_PERIPHERAL = (1 << LmpFeature.AFH_CLASSIFICATION_PERIPHERAL)
|
|
BR_EDR_NOT_SUPPORTED = (1 << LmpFeature.BR_EDR_NOT_SUPPORTED)
|
|
LE_SUPPORTED_CONTROLLER = (1 << LmpFeature.LE_SUPPORTED_CONTROLLER)
|
|
LMP_3_SLOT_ENHANCED_DATA_RATE_ACL_PACKETS = (1 << LmpFeature.LMP_3_SLOT_ENHANCED_DATA_RATE_ACL_PACKETS)
|
|
LMP_5_SLOT_ENHANCED_DATA_RATE_ACL_PACKETS = (1 << LmpFeature.LMP_5_SLOT_ENHANCED_DATA_RATE_ACL_PACKETS)
|
|
SNIFF_SUBRATING = (1 << LmpFeature.SNIFF_SUBRATING)
|
|
PAUSE_ENCRYPTION = (1 << LmpFeature.PAUSE_ENCRYPTION)
|
|
AFH_CAPABLE_CENTRAL = (1 << LmpFeature.AFH_CAPABLE_CENTRAL)
|
|
AFH_CLASSIFICATION_CENTRAL = (1 << LmpFeature.AFH_CLASSIFICATION_CENTRAL)
|
|
ENHANCED_DATA_RATE_ESCO_2_MBPS_MODE = (1 << LmpFeature.ENHANCED_DATA_RATE_ESCO_2_MBPS_MODE)
|
|
ENHANCED_DATA_RATE_ESCO_3_MBPS_MODE = (1 << LmpFeature.ENHANCED_DATA_RATE_ESCO_3_MBPS_MODE)
|
|
LMP_3_SLOT_ENHANCED_DATA_RATE_ESCO_PACKETS = (1 << LmpFeature.LMP_3_SLOT_ENHANCED_DATA_RATE_ESCO_PACKETS)
|
|
EXTENDED_INQUIRY_RESPONSE = (1 << LmpFeature.EXTENDED_INQUIRY_RESPONSE)
|
|
SIMULTANEOUS_LE_AND_BR_EDR_TO_SAME_DEVICE_CAPABLE_CONTROLLER = (1 << LmpFeature.SIMULTANEOUS_LE_AND_BR_EDR_TO_SAME_DEVICE_CAPABLE_CONTROLLER)
|
|
# RESERVED_FOR_FUTURE_USE = (1 << LmpFeature.RESERVED_FOR_FUTURE_USE)
|
|
SECURE_SIMPLE_PAIRING_CONTROLLER_SUPPORT = (1 << LmpFeature.SECURE_SIMPLE_PAIRING_CONTROLLER_SUPPORT)
|
|
ENCAPSULATED_PDU = (1 << LmpFeature.ENCAPSULATED_PDU)
|
|
ERRONEOUS_DATA_REPORTING = (1 << LmpFeature.ERRONEOUS_DATA_REPORTING)
|
|
NON_FLUSHABLE_PACKET_BOUNDARY_FLAG = (1 << LmpFeature.NON_FLUSHABLE_PACKET_BOUNDARY_FLAG)
|
|
# RESERVED_FOR_FUTURE_USE = (1 << LmpFeature.RESERVED_FOR_FUTURE_USE)
|
|
HCI_LINK_SUPERVISION_TIMEOUT_CHANGED_EVENT = (1 << LmpFeature.HCI_LINK_SUPERVISION_TIMEOUT_CHANGED_EVENT)
|
|
VARIABLE_INQUIRY_TX_POWER_LEVEL = (1 << LmpFeature.VARIABLE_INQUIRY_TX_POWER_LEVEL)
|
|
ENHANCED_POWER_CONTROL = (1 << LmpFeature.ENHANCED_POWER_CONTROL)
|
|
# RESERVED_FOR_FUTURE_USE = (1 << LmpFeature.RESERVED_FOR_FUTURE_USE)
|
|
# RESERVED_FOR_FUTURE_USE = (1 << LmpFeature.RESERVED_FOR_FUTURE_USE)
|
|
# RESERVED_FOR_FUTURE_USE = (1 << LmpFeature.RESERVED_FOR_FUTURE_USE)
|
|
# RESERVED_FOR_FUTURE_USE = (1 << LmpFeature.RESERVED_FOR_FUTURE_USE)
|
|
EXTENDED_FEATURES = (1 << LmpFeature.EXTENDED_FEATURES)
|
|
|
|
# Page 1
|
|
SECURE_SIMPLE_PAIRING_HOST_SUPPORT = (1 << LmpFeature.SECURE_SIMPLE_PAIRING_HOST_SUPPORT)
|
|
LE_SUPPORTED_HOST = (1 << LmpFeature.LE_SUPPORTED_HOST)
|
|
# PREVIOUSLY_USED = (1 << LmpFeature.PREVIOUSLY_USED)
|
|
SECURE_CONNECTIONS_HOST_SUPPORT = (1 << LmpFeature.SECURE_CONNECTIONS_HOST_SUPPORT)
|
|
|
|
# Page 2
|
|
CONNECTIONLESS_PERIPHERAL_BROADCAST_TRANSMITTER_OPERATION = (1 << LmpFeature.CONNECTIONLESS_PERIPHERAL_BROADCAST_TRANSMITTER_OPERATION)
|
|
CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVER_OPERATION = (1 << LmpFeature.CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVER_OPERATION)
|
|
SYNCHRONIZATION_TRAIN = (1 << LmpFeature.SYNCHRONIZATION_TRAIN)
|
|
SYNCHRONIZATION_SCAN = (1 << LmpFeature.SYNCHRONIZATION_SCAN)
|
|
HCI_INQUIRY_RESPONSE_NOTIFICATION_EVENT = (1 << LmpFeature.HCI_INQUIRY_RESPONSE_NOTIFICATION_EVENT)
|
|
GENERALIZED_INTERLACED_SCAN = (1 << LmpFeature.GENERALIZED_INTERLACED_SCAN)
|
|
COARSE_CLOCK_ADJUSTMENT = (1 << LmpFeature.COARSE_CLOCK_ADJUSTMENT)
|
|
RESERVED_FOR_FUTURE_USE = (1 << LmpFeature.RESERVED_FOR_FUTURE_USE)
|
|
SECURE_CONNECTIONS_CONTROLLER_SUPPORT = (1 << LmpFeature.SECURE_CONNECTIONS_CONTROLLER_SUPPORT)
|
|
PING = (1 << LmpFeature.PING)
|
|
SLOT_AVAILABILITY_MASK = (1 << LmpFeature.SLOT_AVAILABILITY_MASK)
|
|
TRAIN_NUDGING = (1 << LmpFeature.TRAIN_NUDGING)
|
|
|
|
|
|
# fmt: on
|
|
# pylint: enable=line-too-long
|
|
# pylint: disable=invalid-name
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# pylint: disable-next=unnecessary-lambda
|
|
STATUS_SPEC = {'size': 1, 'mapper': lambda x: HCI_Constant.status_name(x)}
|
|
CS_ROLE_SPEC = {'size': 1, 'mapper': lambda x: CsRole(x).name}
|
|
CS_ROLE_MASK_SPEC = {'size': 1, 'mapper': lambda x: CsRoleMask(x).name}
|
|
CS_SYNC_PHY_SPEC = {'size': 1, 'mapper': lambda x: CsSyncPhy(x).name}
|
|
CS_SYNC_PHY_SUPPORTED_SPEC = {'size': 1, 'mapper': lambda x: CsSyncPhySupported(x).name}
|
|
RTT_TYPE_SPEC = {'size': 1, 'mapper': lambda x: RttType(x).name}
|
|
CS_SNR_SPEC = {'size': 1, 'mapper': lambda x: CsSnr(x).name}
|
|
COD_SPEC = {'size': 3, 'mapper': map_class_of_device}
|
|
|
|
|
|
class CodecID(SpecableEnum):
|
|
# fmt: off
|
|
U_LOG = 0x00
|
|
A_LOG = 0x01
|
|
CVSD = 0x02
|
|
TRANSPARENT = 0x03
|
|
LINEAR_PCM = 0x04
|
|
MSBC = 0x05
|
|
LC3 = 0x06
|
|
G729A = 0x07
|
|
VENDOR_SPECIFIC = 0xFF
|
|
|
|
|
|
@dataclasses.dataclass(frozen=True)
|
|
class CodingFormat:
|
|
codec_id: CodecID
|
|
company_id: int = 0
|
|
vendor_specific_codec_id: int = 0
|
|
|
|
@classmethod
|
|
def parse_from_bytes(cls, data: bytes, offset: int) -> tuple[int, CodingFormat]:
|
|
(codec_id, company_id, vendor_specific_codec_id) = struct.unpack_from(
|
|
'<BHH', data, offset
|
|
)
|
|
return offset + 5, cls(
|
|
codec_id=CodecID(codec_id),
|
|
company_id=company_id,
|
|
vendor_specific_codec_id=vendor_specific_codec_id,
|
|
)
|
|
|
|
@classmethod
|
|
def from_bytes(cls, data: bytes) -> CodingFormat:
|
|
return cls.parse_from_bytes(data, 0)[1]
|
|
|
|
def __bytes__(self) -> bytes:
|
|
return struct.pack(
|
|
'<BHH', self.codec_id, self.company_id, self.vendor_specific_codec_id
|
|
)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
class HCI_Constant:
|
|
@staticmethod
|
|
def status_name(status):
|
|
return HCI_ERROR_NAMES.get(status, f'0x{status:02X}')
|
|
|
|
@staticmethod
|
|
def error_name(status):
|
|
return HCI_ERROR_NAMES.get(status, f'0x{status:02X}')
|
|
|
|
@staticmethod
|
|
def role_name(role: int) -> str:
|
|
return Role(role).name
|
|
|
|
@staticmethod
|
|
def le_phy_name(phy):
|
|
return HCI_LE_PHY_NAMES.get(phy, str(phy))
|
|
|
|
@staticmethod
|
|
def inquiry_lap_name(lap):
|
|
return HCI_INQUIRY_LAP_NAMES.get(lap, f'0x{lap:06X}')
|
|
|
|
@staticmethod
|
|
def io_capability_name(io_capability: int) -> str:
|
|
return IoCapability(io_capability).name
|
|
|
|
@staticmethod
|
|
def authentication_requirements_name(authentication_requirements: int) -> str:
|
|
return AuthenticationRequirements(authentication_requirements).name
|
|
|
|
@staticmethod
|
|
def link_key_type_name(link_key_type: int) -> str:
|
|
return LinkKeyType(link_key_type).name
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
class HCI_Error(ProtocolError):
|
|
def __init__(self, error_code):
|
|
super().__init__(
|
|
error_code,
|
|
error_namespace='hci',
|
|
error_name=HCI_Constant.error_name(error_code),
|
|
)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
class HCI_StatusError(ProtocolError):
|
|
def __init__(self, response):
|
|
super().__init__(
|
|
response.status,
|
|
error_namespace=HCI_Command.command_name(response.command_opcode),
|
|
error_name=HCI_Constant.status_name(response.status),
|
|
)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Generic HCI object
|
|
# -----------------------------------------------------------------------------
|
|
class HCI_Object:
|
|
fields: Fields
|
|
|
|
@staticmethod
|
|
def init_from_fields(hci_object, fields, values):
|
|
if isinstance(values, dict):
|
|
for field in fields:
|
|
if isinstance(field, list):
|
|
# The field is an array, up-level the array field names
|
|
for sub_field_name, _ in field:
|
|
setattr(hci_object, sub_field_name, values[sub_field_name])
|
|
else:
|
|
field_name = field[0]
|
|
setattr(hci_object, field_name, values[field_name])
|
|
else:
|
|
for field_name, field_value in zip(fields, values):
|
|
setattr(hci_object, field_name, field_value)
|
|
|
|
@staticmethod
|
|
def init_from_bytes(hci_object, data, offset, fields):
|
|
parsed = HCI_Object.dict_from_bytes(data, offset, fields)
|
|
HCI_Object.init_from_fields(hci_object, parsed.keys(), parsed.values())
|
|
|
|
@staticmethod
|
|
def parse_field(data: bytes, offset: int, field_type: FieldSpec):
|
|
# The field_type may be a dictionary with a mapper, parser, and/or size
|
|
if isinstance(field_type, dict):
|
|
if 'size' in field_type:
|
|
field_type = field_type['size']
|
|
elif 'parser' in field_type:
|
|
field_type = field_type['parser']
|
|
|
|
# Parse the field
|
|
match field_type:
|
|
case '*':
|
|
# The rest of the bytes
|
|
field_value = data[offset:]
|
|
return (field_value, len(field_value))
|
|
case 'v':
|
|
# Variable-length bytes field, with 1-byte length at the beginning
|
|
field_length = data[offset]
|
|
offset += 1
|
|
field_value = data[offset : offset + field_length]
|
|
return (field_value, field_length + 1)
|
|
case 1:
|
|
# 8-bit unsigned
|
|
return (data[offset], 1)
|
|
case -1:
|
|
# 8-bit signed
|
|
return (struct.unpack_from('b', data, offset)[0], 1)
|
|
case 2:
|
|
# 16-bit unsigned
|
|
return (struct.unpack_from('<H', data, offset)[0], 2)
|
|
case '>2':
|
|
# 16-bit unsigned big-endian
|
|
return (struct.unpack_from('>H', data, offset)[0], 2)
|
|
case -2:
|
|
# 16-bit signed
|
|
return (struct.unpack_from('<h', data, offset)[0], 2)
|
|
case 3:
|
|
# 24-bit unsigned
|
|
padded = data[offset : offset + 3] + bytes([0])
|
|
return (struct.unpack('<I', padded)[0], 3)
|
|
case 4:
|
|
# 32-bit unsigned
|
|
return (struct.unpack_from('<I', data, offset)[0], 4)
|
|
case '>4':
|
|
# 32-bit unsigned big-endian
|
|
return (struct.unpack_from('>I', data, offset)[0], 4)
|
|
case int() if 4 < field_type <= 256:
|
|
# Byte array (from 5 up to 256 bytes)
|
|
return (data[offset : offset + field_type], field_type)
|
|
|
|
if callable(field_type):
|
|
new_offset, field_value = field_type(data, offset)
|
|
return (field_value, new_offset - offset)
|
|
|
|
raise InvalidArgumentError(f'unknown field type {field_type}')
|
|
|
|
@classmethod
|
|
def dict_and_offset_from_bytes(
|
|
cls, data: bytes, offset: int, object_fields: Fields
|
|
) -> tuple[int, collections.OrderedDict[str, Any]]:
|
|
result = collections.OrderedDict[str, Any]()
|
|
for object_field in object_fields:
|
|
if isinstance(object_field, list):
|
|
# This is an array field, starting with a 1-byte item count.
|
|
item_count = data[offset]
|
|
offset += 1
|
|
# Set fields first, because item_count might be 0.
|
|
for sub_field_name, _ in object_field:
|
|
result[sub_field_name] = []
|
|
|
|
for _ in range(item_count):
|
|
for sub_field_name, sub_field_type in object_field:
|
|
value, size = HCI_Object.parse_field(
|
|
data, offset, sub_field_type
|
|
)
|
|
result[sub_field_name].append(value)
|
|
offset += size
|
|
continue
|
|
|
|
field_name, field_type = object_field
|
|
assert isinstance(field_name, str)
|
|
field_value, field_size = HCI_Object.parse_field(
|
|
data, offset, cast(FieldSpec, field_type)
|
|
)
|
|
result[field_name] = field_value
|
|
offset += field_size
|
|
|
|
return (offset, result)
|
|
|
|
@staticmethod
|
|
def dict_from_bytes(data, offset, fields):
|
|
return HCI_Object.dict_and_offset_from_bytes(data, offset, fields)[1]
|
|
|
|
@staticmethod
|
|
def serialize_field(field_value: Any, field_type: FieldSpec) -> bytes:
|
|
# The field_type may be a dictionary with a mapper, parser, serializer,
|
|
# and/or size
|
|
serializer = None
|
|
if isinstance(field_type, dict):
|
|
if 'serializer' in field_type:
|
|
serializer = field_type['serializer']
|
|
if 'size' in field_type:
|
|
field_type = field_type['size']
|
|
|
|
# Serialize the field
|
|
if serializer:
|
|
return serializer(field_value)
|
|
match field_type:
|
|
case 1:
|
|
# 8-bit unsigned
|
|
return bytes([field_value])
|
|
case -1:
|
|
# 8-bit signed
|
|
return struct.pack('b', field_value)
|
|
case 2:
|
|
# 16-bit unsigned
|
|
return struct.pack('<H', field_value)
|
|
case '>2':
|
|
# 16-bit unsigned big-endian
|
|
return struct.pack('>H', field_value)
|
|
case -2:
|
|
# 16-bit signed
|
|
return struct.pack('<h', field_value)
|
|
case 3:
|
|
# 24-bit unsigned
|
|
return struct.pack('<I', field_value)[0:3]
|
|
case 4:
|
|
# 32-bit unsigned
|
|
return struct.pack('<I', field_value)
|
|
case '>4':
|
|
# 32-bit unsigned big-endian
|
|
return struct.pack('>I', field_value)
|
|
case '*':
|
|
if isinstance(field_value, int):
|
|
if 0 <= field_value <= 255:
|
|
return bytes([field_value])
|
|
else:
|
|
raise InvalidArgumentError('value too large for *-typed field')
|
|
else:
|
|
return bytes(field_value)
|
|
case 'v':
|
|
# Variable-length bytes field, with 1-byte length at the beginning
|
|
field_bytes = bytes(field_value)
|
|
field_length = len(field_bytes)
|
|
return bytes([field_length]) + field_bytes
|
|
if isinstance(field_value, (bytes, bytearray, SupportsBytes)):
|
|
field_bytes = bytes(field_value)
|
|
if isinstance(field_type, int) and 4 < field_type <= 256:
|
|
# Truncate or pad with zeros if the field is too long or too short
|
|
if len(field_bytes) < field_type:
|
|
return field_bytes + bytes(field_type - len(field_bytes))
|
|
elif len(field_bytes) > field_type:
|
|
return field_bytes[:field_type]
|
|
return field_bytes
|
|
|
|
raise InvalidArgumentError(
|
|
f"don't know how to serialize type {type(field_value)}"
|
|
)
|
|
|
|
@staticmethod
|
|
def dict_to_bytes(hci_object, object_fields):
|
|
result = bytearray()
|
|
for object_field in object_fields:
|
|
if isinstance(object_field, list):
|
|
# The field is an array. The serialized form starts with a 1-byte
|
|
# item count. We use the length of the first array field as the
|
|
# array count, since all array fields have the same number of items.
|
|
item_count = len(hci_object[object_field[0][0]])
|
|
result += bytes([item_count]) + b''.join(
|
|
b''.join(
|
|
HCI_Object.serialize_field(
|
|
hci_object[sub_field_name][i], sub_field_type
|
|
)
|
|
for sub_field_name, sub_field_type in object_field
|
|
)
|
|
for i in range(item_count)
|
|
)
|
|
continue
|
|
|
|
(field_name, field_type) = object_field
|
|
result += HCI_Object.serialize_field(hci_object[field_name], field_type)
|
|
|
|
return bytes(result)
|
|
|
|
@classmethod
|
|
def from_bytes(cls, data, offset, fields):
|
|
return cls(fields, **cls.dict_from_bytes(data, offset, fields))
|
|
|
|
def __bytes__(self):
|
|
return HCI_Object.dict_to_bytes(self.__dict__, self.fields)
|
|
|
|
@staticmethod
|
|
def parse_length_prefixed_bytes(data, offset):
|
|
length = data[offset]
|
|
return offset + 1 + length, data[offset + 1 : offset + 1 + length]
|
|
|
|
@staticmethod
|
|
def serialize_length_prefixed_bytes(data, padded_size=0):
|
|
prefixed_size = 1 + len(data)
|
|
padding = (
|
|
bytes(padded_size - prefixed_size) if prefixed_size < padded_size else b''
|
|
)
|
|
return bytes([len(data)]) + data + padding
|
|
|
|
@staticmethod
|
|
def format_field_value(value, indentation):
|
|
if isinstance(value, bytes):
|
|
return value.hex()
|
|
|
|
if isinstance(value, HCI_Object):
|
|
return '\n' + value.to_string(indentation)
|
|
|
|
return str(value)
|
|
|
|
@staticmethod
|
|
def stringify_field(
|
|
field_name, field_type, field_value, indentation, value_mappers
|
|
):
|
|
value_mapper = None
|
|
if isinstance(field_type, dict):
|
|
# Get the value mapper from the specifier
|
|
value_mapper = field_type.get('mapper')
|
|
|
|
# Check if there's a matching mapper passed
|
|
if value_mappers:
|
|
value_mapper = value_mappers.get(field_name, value_mapper)
|
|
|
|
# Map the value if we have a mapper
|
|
if value_mapper is not None:
|
|
field_value = value_mapper(field_value)
|
|
|
|
# Get the string representation of the value
|
|
return HCI_Object.format_field_value(
|
|
field_value, indentation=indentation + ' '
|
|
)
|
|
|
|
@staticmethod
|
|
def format_fields(hci_object, object_fields, indentation='', value_mappers=None):
|
|
if not object_fields:
|
|
return ''
|
|
|
|
# Build array of formatted key:value pairs
|
|
field_strings = []
|
|
for object_field in object_fields:
|
|
if isinstance(object_field, list):
|
|
for sub_field in object_field:
|
|
sub_field_name, sub_field_type = sub_field
|
|
item_count = len(hci_object[sub_field_name])
|
|
for i in range(item_count):
|
|
field_strings.append(
|
|
(
|
|
f'{sub_field_name}[{i}]',
|
|
HCI_Object.stringify_field(
|
|
sub_field_name,
|
|
sub_field_type,
|
|
hci_object[sub_field_name][i],
|
|
indentation,
|
|
value_mappers,
|
|
),
|
|
),
|
|
)
|
|
continue
|
|
|
|
field_name, field_type = object_field
|
|
field_value = hci_object[field_name]
|
|
field_strings.append(
|
|
(
|
|
field_name,
|
|
HCI_Object.stringify_field(
|
|
field_name, field_type, field_value, indentation, value_mappers
|
|
),
|
|
),
|
|
)
|
|
|
|
# Measure the widest field name
|
|
max_field_name_length = max(len(s[0]) for s in field_strings)
|
|
sep = ':'
|
|
return '\n'.join(
|
|
f'{indentation}'
|
|
f'{color(f"{field_name + sep:{1 + max_field_name_length}}", "cyan")} {field_value}'
|
|
for field_name, field_value in field_strings
|
|
)
|
|
|
|
@classmethod
|
|
def fields_from_dataclass(cls, obj: Any) -> list[Any]:
|
|
stack: list[list[Any]] = [[]]
|
|
for object_field in dataclasses.fields(obj):
|
|
# Fields without metadata should be ignored.
|
|
if not isinstance(
|
|
(metadata := object_field.metadata.get("bumble.hci")), FieldMetadata
|
|
):
|
|
continue
|
|
if metadata.list_begin:
|
|
stack.append([])
|
|
if metadata.spec:
|
|
stack[-1].append((object_field.name, metadata.spec))
|
|
if metadata.list_end:
|
|
top = stack.pop()
|
|
stack[-1].append(top)
|
|
return stack[0]
|
|
|
|
def __init__(self, fields, **kwargs):
|
|
self.fields = fields
|
|
self.init_from_fields(self, fields, kwargs)
|
|
|
|
def to_string(self, indentation='', value_mappers=None):
|
|
return HCI_Object.format_fields(
|
|
self.__dict__, self.fields, indentation, value_mappers
|
|
)
|
|
|
|
def __str__(self):
|
|
return self.to_string()
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Dataclass_Object(HCI_Object):
|
|
def __post_init__(self) -> None:
|
|
self.fields = HCI_Object.fields_from_dataclass(self)
|
|
|
|
@classmethod
|
|
def parse_from_bytes(cls, data: bytes, offset: int) -> tuple[int, Self]:
|
|
fields = HCI_Object.fields_from_dataclass(cls)
|
|
offset, kwargs = HCI_Object.dict_and_offset_from_bytes(data, offset, fields)
|
|
return offset, cls(**kwargs)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Bluetooth Address
|
|
# -----------------------------------------------------------------------------
|
|
class Address:
|
|
'''
|
|
Bluetooth Address (see Bluetooth spec Vol 6, Part B - 1.3 DEVICE ADDRESS)
|
|
NOTE: the address bytes are stored in little-endian byte order here, so
|
|
address[0] is the LSB of the address, address[5] is the MSB.
|
|
'''
|
|
|
|
PUBLIC_DEVICE_ADDRESS = AddressType.PUBLIC_DEVICE
|
|
RANDOM_DEVICE_ADDRESS = AddressType.RANDOM_DEVICE
|
|
PUBLIC_IDENTITY_ADDRESS = AddressType.PUBLIC_IDENTITY
|
|
RANDOM_IDENTITY_ADDRESS = AddressType.RANDOM_IDENTITY
|
|
|
|
# Type declarations
|
|
NIL: ClassVar[Address]
|
|
ANY: ClassVar[Address]
|
|
ANY_RANDOM: ClassVar[Address]
|
|
|
|
# pylint: disable-next=unnecessary-lambda
|
|
ADDRESS_TYPE_SPEC = {'size': 1, 'mapper': lambda x: Address.address_type_name(x)}
|
|
|
|
@classmethod
|
|
def address_type_name(cls: type[Self], address_type: int) -> str:
|
|
return AddressType(address_type).name
|
|
|
|
@classmethod
|
|
def from_string_for_transport(
|
|
cls: type[Self], string: str, transport: PhysicalTransport
|
|
) -> Self:
|
|
if transport == PhysicalTransport.BR_EDR:
|
|
address_type = Address.PUBLIC_DEVICE_ADDRESS
|
|
else:
|
|
address_type = Address.RANDOM_DEVICE_ADDRESS
|
|
return cls(string, address_type)
|
|
|
|
@classmethod
|
|
def parse_address(cls: type[Self], data: bytes, offset: int) -> tuple[int, Self]:
|
|
# Fix the type to a default value. This is used for parsing type-less Classic
|
|
# addresses
|
|
return cls.parse_address_with_type(data, offset, Address.PUBLIC_DEVICE_ADDRESS)
|
|
|
|
@classmethod
|
|
def parse_random_address(
|
|
cls: type[Self], data: bytes, offset: int
|
|
) -> tuple[int, Self]:
|
|
return cls.parse_address_with_type(data, offset, Address.RANDOM_DEVICE_ADDRESS)
|
|
|
|
@classmethod
|
|
def parse_address_with_type(
|
|
cls: type[Self], data: bytes, offset: int, address_type: AddressType
|
|
) -> tuple[int, Self]:
|
|
return offset + 6, cls(data[offset : offset + 6], address_type)
|
|
|
|
@classmethod
|
|
def parse_address_preceded_by_type(
|
|
cls: type[Self], data: bytes, offset: int
|
|
) -> tuple[int, Self]:
|
|
address_type = AddressType(data[offset - 1])
|
|
return cls.parse_address_with_type(data, offset, address_type)
|
|
|
|
@classmethod
|
|
def generate_static_address(cls) -> Address:
|
|
'''Generates Random Static Address, with the 2 most significant bits of 0b11.
|
|
|
|
See Bluetooth spec, Vol 6, Part B - Table 1.2.
|
|
'''
|
|
address_bytes = secrets.token_bytes(6)
|
|
address_bytes = address_bytes[:5] + bytes([address_bytes[5] | 0b11000000])
|
|
return Address(
|
|
address=address_bytes, address_type=Address.RANDOM_DEVICE_ADDRESS
|
|
)
|
|
|
|
@classmethod
|
|
def generate_private_address(cls, irk: bytes = b'') -> Address:
|
|
'''Generates Random Private MAC Address.
|
|
|
|
If IRK is present, a Resolvable Private Address, with the 2 most significant
|
|
bits of 0b01 will be generated. Otherwise, a Non-resolvable Private Address,
|
|
with the 2 most significant bits of 0b00 will be generated.
|
|
|
|
See Bluetooth spec, Vol 6, Part B - Table 1.2.
|
|
|
|
Args:
|
|
irk: Local Identity Resolving Key(IRK), in little-endian. If not set, a
|
|
non-resolvable address will be generated.
|
|
'''
|
|
if irk:
|
|
prand = crypto.generate_prand()
|
|
address_bytes = crypto.ah(irk, prand) + prand
|
|
else:
|
|
address_bytes = secrets.token_bytes(6)
|
|
address_bytes = address_bytes[:5] + bytes([address_bytes[5] & 0b00111111])
|
|
|
|
return Address(
|
|
address=address_bytes, address_type=Address.RANDOM_DEVICE_ADDRESS
|
|
)
|
|
|
|
def __init__(
|
|
self,
|
|
address: bytes | str,
|
|
address_type: AddressType = RANDOM_DEVICE_ADDRESS,
|
|
) -> None:
|
|
'''
|
|
Initialize an instance. `address` may be a byte array in little-endian
|
|
format, or a hex string in big-endian format (with optional ':'
|
|
separators between the bytes).
|
|
If the address is a string suffixed with '/P', `address_type` is ignored and
|
|
the type is set to PUBLIC_DEVICE_ADDRESS.
|
|
'''
|
|
if isinstance(address, bytes):
|
|
self.address_bytes = address
|
|
else:
|
|
# Check if there's a '/P' type specifier
|
|
if address.endswith('P'):
|
|
address_type = Address.PUBLIC_DEVICE_ADDRESS
|
|
address = address[:-2]
|
|
|
|
if len(address) == 12 + 5:
|
|
# Form with ':' separators
|
|
address = address.replace(':', '')
|
|
|
|
self.address_bytes = bytes(reversed(bytes.fromhex(address)))
|
|
|
|
if len(self.address_bytes) != 6:
|
|
raise InvalidArgumentError('invalid address length')
|
|
|
|
self.address_type = address_type
|
|
|
|
def clone(self) -> Address:
|
|
return Address(self.address_bytes, self.address_type)
|
|
|
|
@property
|
|
def is_public(self) -> bool:
|
|
return self.address_type in (
|
|
self.PUBLIC_DEVICE_ADDRESS,
|
|
self.PUBLIC_IDENTITY_ADDRESS,
|
|
)
|
|
|
|
@property
|
|
def is_random(self) -> bool:
|
|
return not self.is_public
|
|
|
|
@property
|
|
def is_resolved(self) -> bool:
|
|
return self.address_type in (
|
|
self.PUBLIC_IDENTITY_ADDRESS,
|
|
self.RANDOM_IDENTITY_ADDRESS,
|
|
)
|
|
|
|
@property
|
|
def is_resolvable(self) -> bool:
|
|
return self.address_type == self.RANDOM_DEVICE_ADDRESS and (
|
|
self.address_bytes[5] >> 6 == 1
|
|
)
|
|
|
|
@property
|
|
def is_static(self) -> bool:
|
|
return self.is_random and (self.address_bytes[5] >> 6 == 3)
|
|
|
|
def to_string(self, with_type_qualifier: bool = True) -> str:
|
|
'''
|
|
String representation of the address, MSB first, with an optional type
|
|
qualifier.
|
|
'''
|
|
result = ':'.join([f'{x:02X}' for x in reversed(self.address_bytes)])
|
|
if not with_type_qualifier or not self.is_public:
|
|
return result
|
|
return result + '/P'
|
|
|
|
def __bytes__(self) -> bytes:
|
|
return self.address_bytes
|
|
|
|
def __hash__(self) -> int:
|
|
return hash(self.address_bytes)
|
|
|
|
def __eq__(self, other: Any) -> bool:
|
|
return (
|
|
isinstance(other, Address)
|
|
and self.address_bytes == other.address_bytes
|
|
and self.is_public == other.is_public
|
|
)
|
|
|
|
def __str__(self) -> str:
|
|
return self.to_string()
|
|
|
|
def __repr__(self) -> str:
|
|
return f'Address({self.to_string(False)}/{self.address_type_name(self.address_type)})'
|
|
|
|
|
|
# Predefined address values
|
|
Address.NIL = Address(b"\xff\xff\xff\xff\xff\xff", Address.PUBLIC_DEVICE_ADDRESS)
|
|
Address.ANY = Address(b"\x00\x00\x00\x00\x00\x00", Address.PUBLIC_DEVICE_ADDRESS)
|
|
Address.ANY_RANDOM = Address(b"\x00\x00\x00\x00\x00\x00", Address.RANDOM_DEVICE_ADDRESS)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
class OwnAddressType(SpecableEnum):
|
|
PUBLIC = 0
|
|
RANDOM = 1
|
|
RESOLVABLE_OR_PUBLIC = 2
|
|
RESOLVABLE_OR_RANDOM = 3
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
class LoopbackMode(SpecableEnum):
|
|
DISABLED = 0
|
|
LOCAL = 1
|
|
REMOTE = 2
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
class CteType(SpecableEnum):
|
|
AOA_CONSTANT_TONE_EXTENSION = 0x00
|
|
AOD_CONSTANT_TONE_EXTENSION_1US = 0x01
|
|
AOD_CONSTANT_TONE_EXTENSION_2US = 0x02
|
|
NO_CONSTANT_TONE_EXTENSION = 0xFF
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
class HCI_Packet:
|
|
'''
|
|
Abstract Base class for HCI packets
|
|
'''
|
|
|
|
hci_packet_type: int
|
|
|
|
@classmethod
|
|
def from_bytes(cls, packet: bytes) -> HCI_Packet:
|
|
try:
|
|
packet_type = packet[0]
|
|
|
|
if packet_type == HCI_COMMAND_PACKET:
|
|
return HCI_Command.from_bytes(packet)
|
|
|
|
if packet_type == HCI_ACL_DATA_PACKET:
|
|
return HCI_AclDataPacket.from_bytes(packet)
|
|
|
|
if packet_type == HCI_SYNCHRONOUS_DATA_PACKET:
|
|
return HCI_SynchronousDataPacket.from_bytes(packet)
|
|
|
|
if packet_type == HCI_EVENT_PACKET:
|
|
return HCI_Event.from_bytes(packet)
|
|
|
|
if packet_type == HCI_ISO_DATA_PACKET:
|
|
return HCI_IsoDataPacket.from_bytes(packet)
|
|
|
|
return HCI_CustomPacket(packet)
|
|
except Exception as e:
|
|
logger.error(f'error parsing HCI packet [{packet.hex()}]: {e}')
|
|
raise
|
|
|
|
def __init__(self, name: str) -> None:
|
|
self.name = name
|
|
|
|
def __bytes__(self) -> bytes:
|
|
raise NotImplementedError
|
|
|
|
def __repr__(self) -> str:
|
|
return self.name
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
class HCI_CustomPacket(HCI_Packet):
|
|
def __init__(self, payload: bytes) -> None:
|
|
super().__init__('HCI_CUSTOM_PACKET')
|
|
self.hci_packet_type = payload[0]
|
|
self.payload = payload
|
|
|
|
def __bytes__(self) -> bytes:
|
|
return self.payload
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
class HCI_Command(HCI_Packet):
|
|
'''
|
|
See Bluetooth spec @ Vol 2, Part E - 5.4.1 HCI Command Packet
|
|
'''
|
|
|
|
hci_packet_type = HCI_COMMAND_PACKET
|
|
command_names: dict[int, str] = {}
|
|
command_classes: dict[int, type[HCI_Command]] = {}
|
|
op_code: int
|
|
fields: Fields = ()
|
|
_parameters: bytes = b''
|
|
|
|
_Command = TypeVar("_Command", bound="HCI_Command")
|
|
|
|
@classmethod
|
|
def command(cls, subclass: type[_Command]) -> type[_Command]:
|
|
'''
|
|
Decorator used to declare and register subclasses
|
|
'''
|
|
|
|
# Subclasses may set parameters as ClassVar, or inferred from class name.
|
|
if not hasattr(subclass, 'name'):
|
|
subclass.name = subclass.__name__.upper()
|
|
if not hasattr(subclass, 'op_code'):
|
|
op_code = key_with_value(subclass.command_names, subclass.name)
|
|
if op_code is None:
|
|
raise KeyError(f'command {subclass.name} not found in command_names')
|
|
subclass.op_code = op_code
|
|
|
|
if dataclasses.is_dataclass(subclass):
|
|
subclass.fields = HCI_Object.fields_from_dataclass(subclass)
|
|
|
|
# Register a factory for this class
|
|
cls.command_classes[subclass.op_code] = subclass
|
|
|
|
return subclass
|
|
|
|
@staticmethod
|
|
def command_map(symbols: dict[str, Any]) -> dict[int, str]:
|
|
return {
|
|
command_code: command_name
|
|
for (command_name, command_code) in symbols.items()
|
|
if command_name.startswith('HCI_') and command_name.endswith('_COMMAND')
|
|
}
|
|
|
|
@classmethod
|
|
def register_commands(cls, symbols: dict[str, Any]) -> None:
|
|
cls.command_names.update(cls.command_map(symbols))
|
|
|
|
@staticmethod
|
|
def from_bytes(packet: bytes) -> HCI_Command:
|
|
op_code, length = struct.unpack_from('<HB', packet, 1)
|
|
parameters = packet[4:]
|
|
if len(parameters) != length:
|
|
raise InvalidPacketError('invalid packet length')
|
|
|
|
# Look for a registered class
|
|
cls = HCI_Command.command_classes.get(op_code)
|
|
if cls is None:
|
|
# No class registered, just use a generic instance
|
|
return HCI_Command(parameters, op_code=op_code)
|
|
|
|
return cls.from_parameters(parameters)
|
|
|
|
@classmethod
|
|
def from_parameters(cls, parameters: bytes) -> HCI_Command:
|
|
command = cls(**HCI_Object.dict_from_bytes(parameters, 0, cls.fields))
|
|
command.parameters = parameters
|
|
return command
|
|
|
|
@classmethod
|
|
def command_name(cls, op_code: int) -> str:
|
|
if name := cls.command_names.get(op_code):
|
|
return name
|
|
if (subclass := cls.command_classes.get(op_code)) and subclass.name:
|
|
return subclass.name
|
|
return f'[OGF=0x{op_code >> 10:02x}, OCF=0x{op_code & 0x3FF:04x}]'
|
|
|
|
def __init__(
|
|
self,
|
|
parameters: bytes | None = None,
|
|
*,
|
|
op_code: int | None = None,
|
|
**kwargs,
|
|
) -> None:
|
|
# op_code should be set in cls.
|
|
if op_code is not None:
|
|
self.op_code = op_code
|
|
super().__init__(HCI_Command.command_name(self.op_code))
|
|
if self.fields and kwargs:
|
|
HCI_Object.init_from_fields(self, self.fields, kwargs)
|
|
if parameters is None:
|
|
parameters = HCI_Object.dict_to_bytes(kwargs, self.fields)
|
|
self.parameters = parameters or b''
|
|
|
|
@property
|
|
def parameters(self) -> bytes:
|
|
if not self._parameters:
|
|
self._parameters = HCI_Object.dict_to_bytes(self.__dict__, self.fields)
|
|
return self._parameters
|
|
|
|
@parameters.setter
|
|
def parameters(self, parameters: bytes):
|
|
self._parameters = parameters
|
|
|
|
def __bytes__(self) -> bytes:
|
|
parameters = b'' if self.parameters is None else self.parameters
|
|
return (
|
|
struct.pack('<BHB', HCI_COMMAND_PACKET, self.op_code, len(parameters))
|
|
+ parameters
|
|
)
|
|
|
|
def __str__(self):
|
|
result = color(self.name, 'green')
|
|
if self.fields:
|
|
result += ':\n' + HCI_Object.format_fields(self.__dict__, self.fields, ' ')
|
|
else:
|
|
if self.parameters:
|
|
result += f': {self.parameters.hex()}'
|
|
return result
|
|
|
|
|
|
HCI_Command.register_commands(globals())
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
class HCI_AsyncCommand(HCI_Command):
|
|
'''
|
|
HCI Commands for which the expected response is an HCI_Command_Status_Event.
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
class HCI_ReturnParameters(HCI_Object):
|
|
@classmethod
|
|
def from_parameters(cls, parameters: bytes) -> Self:
|
|
return cls(**HCI_Object.dict_from_bytes(parameters, 0, cls.fields))
|
|
|
|
|
|
@dataclasses.dataclass
|
|
class HCI_GenericReturnParameters(HCI_ReturnParameters):
|
|
fields = [('data', '*')]
|
|
data: bytes = field(metadata=metadata('*'))
|
|
|
|
|
|
@dataclasses.dataclass
|
|
class HCI_StatusReturnParameters(HCI_ReturnParameters):
|
|
status: HCI_ErrorCode = field(metadata=HCI_ErrorCode.type_metadata(1))
|
|
|
|
@classmethod
|
|
def from_parameters(cls, parameters: bytes) -> Self | HCI_StatusReturnParameters:
|
|
status = HCI_ErrorCode(parameters[0])
|
|
|
|
if status != HCI_ErrorCode.SUCCESS:
|
|
# Don't parse further, just return the status.
|
|
return HCI_StatusReturnParameters(status=status)
|
|
|
|
return cls(**HCI_Object.dict_from_bytes(parameters, 0, cls.fields))
|
|
|
|
|
|
@dataclasses.dataclass
|
|
class HCI_GenericStatusReturnParameters(HCI_StatusReturnParameters):
|
|
data: bytes = field(metadata=metadata('*'))
|
|
|
|
|
|
@dataclasses.dataclass
|
|
class HCI_StatusAndAddressReturnParameters(HCI_StatusReturnParameters):
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
|
|
|
|
@dataclasses.dataclass
|
|
class HCI_StatusAndConnectionHandleReturnParameters(HCI_StatusReturnParameters):
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
|
|
|
|
_RP = TypeVar('_RP', bound=HCI_ReturnParameters)
|
|
|
|
|
|
class HCI_SyncCommand(HCI_Command, Generic[_RP]):
|
|
'''
|
|
HCI Commands for which the expected response is an HCI_Command_Complete_Event.
|
|
'''
|
|
|
|
return_parameters_class: type[_RP]
|
|
|
|
_SyncCommand = TypeVar("_SyncCommand", bound="HCI_SyncCommand")
|
|
|
|
@classmethod
|
|
def sync_command(
|
|
cls: type[_SyncCommand], return_parameters_class: type[_RP]
|
|
) -> Callable[[type[_SyncCommand]], type[_SyncCommand]]:
|
|
'''
|
|
Decorator used to declare and register subclasses and setup their
|
|
`return_parameters_class` attribute.
|
|
'''
|
|
|
|
_SyncCommand = TypeVar("_SyncCommand", bound="HCI_SyncCommand")
|
|
|
|
def inner(cls: type[_SyncCommand]) -> type[_SyncCommand]:
|
|
cls = HCI_Command.command(cls)
|
|
cls.return_parameters_class = return_parameters_class
|
|
return_parameters_class.fields = HCI_Object.fields_from_dataclass(
|
|
cls.return_parameters_class
|
|
)
|
|
return cls
|
|
|
|
return inner
|
|
|
|
@classmethod
|
|
def parse_return_parameters(cls, parameters: bytes) -> _RP:
|
|
return cls.return_parameters_class.from_parameters(parameters)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_Inquiry_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.1.1 Inquiry Command
|
|
'''
|
|
|
|
lap: int = field(
|
|
metadata=metadata({'size': 3, 'mapper': HCI_Constant.inquiry_lap_name})
|
|
)
|
|
inquiry_length: int = field(metadata=metadata(1))
|
|
num_responses: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Inquiry_Cancel_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.1.2 Inquiry Cancel Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_Create_Connection_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.1.5 Create Connection Command
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
packet_type: int = field(metadata=metadata(2))
|
|
page_scan_repetition_mode: int = field(metadata=metadata(1))
|
|
reserved: int = field(metadata=metadata(1))
|
|
clock_offset: int = field(metadata=metadata(2))
|
|
allow_role_switch: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_Disconnect_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.1.6 Disconnect Command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
reason: int = field(metadata=metadata(STATUS_SPEC))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndAddressReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Create_Connection_Cancel_Command(
|
|
HCI_SyncCommand[HCI_StatusAndAddressReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.1.7 Create Connection Cancel Command
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_Accept_Connection_Request_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.1.8 Accept Connection Request Command
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
role: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_Reject_Connection_Request_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.1.9 Reject Connection Request Command
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
reason: int = field(metadata=metadata(STATUS_SPEC))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndAddressReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Link_Key_Request_Reply_Command(
|
|
HCI_SyncCommand[HCI_StatusAndAddressReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.1.10 Link Key Request Reply Command
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
link_key: bytes = field(metadata=metadata(16))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndAddressReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Link_Key_Request_Negative_Reply_Command(
|
|
HCI_SyncCommand[HCI_StatusAndAddressReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.1.11 Link Key Request Negative Reply Command
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndAddressReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_PIN_Code_Request_Reply_Command(
|
|
HCI_SyncCommand[HCI_StatusAndAddressReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.1.12 PIN Code Request Reply Command
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
pin_code_length: int = field(metadata=metadata(1))
|
|
pin_code: bytes = field(metadata=metadata(16))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndAddressReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_PIN_Code_Request_Negative_Reply_Command(
|
|
HCI_SyncCommand[HCI_StatusAndAddressReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.1.13 PIN Code Request Negative Reply Command
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_Change_Connection_Packet_Type_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.1.14 Change Connection Packet Type Command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
packet_type: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_Authentication_Requested_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.1.15 Authentication Requested Command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_Set_Connection_Encryption_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.1.16 Set Connection Encryption Command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
encryption_enable: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_Remote_Name_Request_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.1.19 Remote Name Request Command
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
page_scan_repetition_mode: int = field(metadata=metadata(1))
|
|
reserved: int = field(metadata=metadata(1))
|
|
clock_offset: int = field(metadata=metadata(2))
|
|
|
|
R0 = 0x00
|
|
R1 = 0x01
|
|
R2 = 0x02
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Remote_Supported_Features_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.1.21 Read Remote Supported Features Command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Remote_Extended_Features_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.1.22 Read Remote Extended Features Command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
page_number: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Remote_Version_Information_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.1.23 Read Remote Version Information Command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Clock_Offset_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.1.24 Read Clock Offset Command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_Reject_Synchronous_Connection_Request_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.1.28 Reject Synchronous Connection Request Command
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
reason: int = field(metadata=metadata(STATUS_SPEC))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndAddressReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_IO_Capability_Request_Reply_Command(
|
|
HCI_SyncCommand[HCI_StatusAndAddressReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.1.29 IO Capability Request Reply Command
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
io_capability: int = field(metadata=IoCapability.type_metadata(1))
|
|
oob_data_present: int = field(metadata=metadata(1))
|
|
authentication_requirements: int = field(
|
|
metadata=AuthenticationRequirements.type_metadata(1)
|
|
)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndAddressReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_User_Confirmation_Request_Reply_Command(
|
|
HCI_SyncCommand[HCI_StatusAndAddressReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.1.30 User Confirmation Request Reply Command
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndAddressReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_User_Confirmation_Request_Negative_Reply_Command(
|
|
HCI_SyncCommand[HCI_StatusAndAddressReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.1.31 User Confirmation Request Negative Reply Command
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndAddressReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_User_Passkey_Request_Reply_Command(
|
|
HCI_SyncCommand[HCI_StatusAndAddressReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.1.32 User Passkey Request Reply Command
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
numeric_value: int = field(metadata=metadata(4))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndAddressReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_User_Passkey_Request_Negative_Reply_Command(
|
|
HCI_SyncCommand[HCI_StatusAndAddressReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.1.33 User Passkey Request Negative Reply Command
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndAddressReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Remote_OOB_Data_Request_Reply_Command(
|
|
HCI_SyncCommand[HCI_StatusAndAddressReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.1.34 Remote OOB Data Request Reply Command
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
c: bytes = field(metadata=metadata(16))
|
|
r: bytes = field(metadata=metadata(16))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndAddressReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Remote_OOB_Data_Request_Negative_Reply_Command(
|
|
HCI_SyncCommand[HCI_StatusAndAddressReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.1.35 Remote OOB Data Request Negative Reply Command
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndAddressReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_IO_Capability_Request_Negative_Reply_Command(
|
|
HCI_SyncCommand[HCI_StatusAndAddressReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.1.36 IO Capability Request Negative Reply Command
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
reason: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_Enhanced_Setup_Synchronous_Connection_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.1.45 Enhanced Setup Synchronous Connection Command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
transmit_bandwidth: int = field(metadata=metadata(4))
|
|
receive_bandwidth: int = field(metadata=metadata(4))
|
|
transmit_coding_format: int = field(
|
|
metadata=metadata(CodingFormat.parse_from_bytes)
|
|
)
|
|
receive_coding_format: int = field(metadata=metadata(CodingFormat.parse_from_bytes))
|
|
transmit_codec_frame_size: int = field(metadata=metadata(2))
|
|
receive_codec_frame_size: int = field(metadata=metadata(2))
|
|
input_bandwidth: int = field(metadata=metadata(4))
|
|
output_bandwidth: int = field(metadata=metadata(4))
|
|
input_coding_format: int = field(metadata=metadata(CodingFormat.parse_from_bytes))
|
|
output_coding_format: int = field(metadata=metadata(CodingFormat.parse_from_bytes))
|
|
input_coded_data_size: int = field(metadata=metadata(2))
|
|
output_coded_data_size: int = field(metadata=metadata(2))
|
|
input_pcm_data_format: int = field(metadata=metadata(1))
|
|
output_pcm_data_format: int = field(metadata=metadata(1))
|
|
input_pcm_sample_payload_msb_position: int = field(metadata=metadata(1))
|
|
output_pcm_sample_payload_msb_position: int = field(metadata=metadata(1))
|
|
input_data_path: int = field(metadata=metadata(1))
|
|
output_data_path: int = field(metadata=metadata(1))
|
|
input_transport_unit_size: int = field(metadata=metadata(1))
|
|
output_transport_unit_size: int = field(metadata=metadata(1))
|
|
max_latency: int = field(metadata=metadata(2))
|
|
packet_type: int = field(metadata=metadata(2))
|
|
retransmission_effort: int = field(metadata=metadata(1))
|
|
|
|
class PcmDataFormat(SpecableEnum):
|
|
NA = 0x00
|
|
ONES_COMPLEMENT = 0x01
|
|
TWOS_COMPLEMENT = 0x02
|
|
SIGN_MAGNITUDE = 0x03
|
|
UNSIGNED = 0x04
|
|
|
|
class DataPath(SpecableEnum):
|
|
HCI = 0x00
|
|
PCM = 0x01
|
|
|
|
class RetransmissionEffort(SpecableEnum):
|
|
NO_RETRANSMISSION = 0x00
|
|
OPTIMIZE_FOR_POWER = 0x01
|
|
OPTIMIZE_FOR_QUALITY = 0x02
|
|
DONT_CARE = 0xFF
|
|
|
|
class PacketType(SpecableFlag):
|
|
HV1 = 0x0001
|
|
HV2 = 0x0002
|
|
HV3 = 0x0004
|
|
EV3 = 0x0008
|
|
EV4 = 0x0010
|
|
EV5 = 0x0020
|
|
NO_2_EV3 = 0x0040
|
|
NO_3_EV3 = 0x0080
|
|
NO_2_EV5 = 0x0100
|
|
NO_3_EV5 = 0x0200
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_Enhanced_Accept_Synchronous_Connection_Request_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.1.46 Enhanced Accept Synchronous Connection Request Command
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
transmit_bandwidth: int = field(metadata=metadata(4))
|
|
receive_bandwidth: int = field(metadata=metadata(4))
|
|
transmit_coding_format: int = field(
|
|
metadata=metadata(CodingFormat.parse_from_bytes)
|
|
)
|
|
receive_coding_format: int = field(metadata=metadata(CodingFormat.parse_from_bytes))
|
|
transmit_codec_frame_size: int = field(metadata=metadata(2))
|
|
receive_codec_frame_size: int = field(metadata=metadata(2))
|
|
input_bandwidth: int = field(metadata=metadata(4))
|
|
output_bandwidth: int = field(metadata=metadata(4))
|
|
input_coding_format: int = field(metadata=metadata(CodingFormat.parse_from_bytes))
|
|
output_coding_format: int = field(metadata=metadata(CodingFormat.parse_from_bytes))
|
|
input_coded_data_size: int = field(metadata=metadata(2))
|
|
output_coded_data_size: int = field(metadata=metadata(2))
|
|
input_pcm_data_format: int = field(metadata=metadata(1))
|
|
output_pcm_data_format: int = field(metadata=metadata(1))
|
|
input_pcm_sample_payload_msb_position: int = field(metadata=metadata(1))
|
|
output_pcm_sample_payload_msb_position: int = field(metadata=metadata(1))
|
|
input_data_path: int = field(metadata=metadata(1))
|
|
output_data_path: int = field(metadata=metadata(1))
|
|
input_transport_unit_size: int = field(metadata=metadata(1))
|
|
output_transport_unit_size: int = field(metadata=metadata(1))
|
|
max_latency: int = field(metadata=metadata(2))
|
|
packet_type: int = field(metadata=metadata(2))
|
|
retransmission_effort: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_Truncated_Page_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.1.47 Truncated Page Command
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
page_scan_repetition_mode: int = field(metadata=metadata(1))
|
|
clock_offset: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndAddressReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Truncated_Page_Cancel_Command(
|
|
HCI_SyncCommand[HCI_StatusAndAddressReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.1.48 Truncated Page Cancel Command
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Set_Connectionless_Peripheral_Broadcast_ReturnParameters(
|
|
HCI_StatusReturnParameters
|
|
):
|
|
lt_addr: int = field(metadata=metadata(1))
|
|
interval: int = field(metadata=metadata(2))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(
|
|
HCI_Set_Connectionless_Peripheral_Broadcast_ReturnParameters
|
|
)
|
|
@dataclasses.dataclass
|
|
class HCI_Set_Connectionless_Peripheral_Broadcast_Command(
|
|
HCI_SyncCommand[HCI_Set_Connectionless_Peripheral_Broadcast_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.1.49 Set Connectionless Peripheral Broadcast Command
|
|
'''
|
|
|
|
enable: int = field(metadata=metadata(1))
|
|
lt_addr: Address = field(metadata=metadata(1))
|
|
lpo_allowed: int = field(metadata=metadata(1))
|
|
packet_type: int = field(metadata=metadata(2))
|
|
interval_min: int = field(metadata=metadata(2))
|
|
interval_max: int = field(metadata=metadata(2))
|
|
supervision_timeout: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Set_Connectionless_Peripheral_Broadcast_Receive_ReturnParameters(
|
|
HCI_StatusReturnParameters
|
|
):
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
lt_addr: int = field(metadata=metadata(1))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(
|
|
HCI_Set_Connectionless_Peripheral_Broadcast_Receive_ReturnParameters
|
|
)
|
|
@dataclasses.dataclass
|
|
class HCI_Set_Connectionless_Peripheral_Broadcast_Receive_Command(
|
|
HCI_SyncCommand[
|
|
HCI_Set_Connectionless_Peripheral_Broadcast_Receive_ReturnParameters
|
|
]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.1.50 Set Connectionless Peripheral Broadcast Receive Command
|
|
'''
|
|
|
|
enable: int = field(metadata=metadata(1))
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
lt_addr: Address = field(metadata=metadata(1))
|
|
interval: int = field(metadata=metadata(2))
|
|
clock_offset: int = field(metadata=metadata(4))
|
|
next_connectionless_peripheral_broadcast_clock: int = field(metadata=metadata(4))
|
|
supervision_timeout: int = field(metadata=metadata(2))
|
|
remote_timing_accuracy: int = field(metadata=metadata(1))
|
|
skip: int = field(metadata=metadata(1))
|
|
packet_type: int = field(metadata=metadata(2))
|
|
afh_channel_map: bytes = field(metadata=metadata(10))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_Start_Synchronization_Train_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.1.51 Start Synchronization Train Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_Receive_Synchronization_Train_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.1.52 Receive Synchronization Train Command
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
sync_scan_timeout: int = field(metadata=metadata(2))
|
|
sync_scan_window: int = field(metadata=metadata(2))
|
|
sync_scan_interval: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Remote_OOB_Extended_Data_Request_Reply_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.1.53 Remote OOB Extended Data Request Reply Command
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
c_192: bytes = field(metadata=metadata(16))
|
|
r_192: bytes = field(metadata=metadata(16))
|
|
c_256: bytes = field(metadata=metadata(16))
|
|
r_256: bytes = field(metadata=metadata(16))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_Sniff_Mode_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.2.2 Sniff Mode Command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
sniff_max_interval: int = field(metadata=metadata(2))
|
|
sniff_min_interval: int = field(metadata=metadata(2))
|
|
sniff_attempt: int = field(metadata=metadata(2))
|
|
sniff_timeout: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_Exit_Sniff_Mode_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.2.3 Exit Sniff Mode Command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_Switch_Role_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.2.8 Switch Role Command
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
role: int = field(metadata=Role.type_metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndConnectionHandleReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Write_Link_Policy_Settings_Command(
|
|
HCI_SyncCommand[HCI_StatusAndConnectionHandleReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.2.10 Write Link Policy Settings Command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
link_policy_settings: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Write_Default_Link_Policy_Settings_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.2.12 Write Default Link Policy Settings Command
|
|
'''
|
|
|
|
default_link_policy_settings: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndConnectionHandleReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Sniff_Subrating_Command(
|
|
HCI_SyncCommand[HCI_StatusAndConnectionHandleReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.2.14 Sniff Subrating Command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
maximum_latency: int = field(metadata=metadata(2))
|
|
minimum_remote_timeout: int = field(metadata=metadata(2))
|
|
minimum_local_timeout: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Set_Event_Mask_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.3.1 Set Event Mask Command
|
|
'''
|
|
|
|
event_mask: bytes = field(metadata=metadata(8))
|
|
|
|
@staticmethod
|
|
def mask(event_codes: Iterable[int]) -> bytes:
|
|
'''
|
|
Compute the event mask value for a list of events.
|
|
'''
|
|
# NOTE: this implementation takes advantage of the fact that as of version 5.4
|
|
# of the core specification, the bit number for each event code is equal to one
|
|
# less than the event code.
|
|
# If future versions of the specification deviate from that, a different
|
|
# implementation would be needed.
|
|
return sum((1 << event_code - 1) for event_code in event_codes).to_bytes(
|
|
8, 'little'
|
|
)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Reset_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.3.2 Reset Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Set_Event_Filter_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.3.3 Set Event Filter Command
|
|
'''
|
|
|
|
filter_type: int = field(metadata=metadata(1))
|
|
filter_condition: bytes = field(metadata=metadata("*"))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Stored_Link_Key_ReturnParameters(HCI_StatusReturnParameters):
|
|
max_num_keys: int = field(metadata=metadata(2))
|
|
num_keys_read: int = field(metadata=metadata(2))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_Read_Stored_Link_Key_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Stored_Link_Key_Command(
|
|
HCI_SyncCommand[HCI_Read_Stored_Link_Key_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.3.8 Read Stored Link Key Command
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
read_all_flag: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Delete_Stored_Link_Key_ReturnParameters(HCI_StatusReturnParameters):
|
|
num_keys_deleted: int = field(metadata=metadata(2))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_Delete_Stored_Link_Key_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Delete_Stored_Link_Key_Command(
|
|
HCI_SyncCommand[HCI_Delete_Stored_Link_Key_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.3.10 Delete Stored Link Key Command
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
delete_all_flag: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Write_Local_Name_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.3.11 Write Local Name Command
|
|
'''
|
|
|
|
local_name: bytes = field(
|
|
metadata=metadata({'size': 248, 'mapper': map_null_terminated_utf8_string})
|
|
)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Local_Name_ReturnParameters(HCI_StatusReturnParameters):
|
|
local_name: bytes = field(
|
|
metadata=metadata({'size': 248, 'mapper': map_null_terminated_utf8_string})
|
|
)
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_Read_Local_Name_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Local_Name_Command(
|
|
HCI_SyncCommand[HCI_Read_Local_Name_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.3.12 Read Local Name Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Write_Connection_Accept_Timeout_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.3.14 Write Connection Accept Timeout Command
|
|
'''
|
|
|
|
connection_accept_timeout: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Write_Page_Timeout_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.3.16 Write Page Timeout Command
|
|
'''
|
|
|
|
page_timeout: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Write_Scan_Enable_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.3.18 Write Scan Enable Command
|
|
'''
|
|
|
|
scan_enable: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Page_Scan_Activity_ReturnParameters(HCI_StatusReturnParameters):
|
|
page_scan_interval: int = field(metadata=metadata(2))
|
|
page_scan_window: int = field(metadata=metadata(2))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_Read_Page_Scan_Activity_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Page_Scan_Activity_Command(
|
|
HCI_SyncCommand[HCI_Read_Page_Scan_Activity_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.3.19 Read Page Scan Activity Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Write_Page_Scan_Activity_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.3.20 Write Page Scan Activity Command
|
|
'''
|
|
|
|
page_scan_interval: int = field(metadata=metadata(2))
|
|
page_scan_window: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Write_Inquiry_Scan_Activity_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.3.22 Write Inquiry Scan Activity Command
|
|
'''
|
|
|
|
inquiry_scan_interval: int = field(metadata=metadata(2))
|
|
inquiry_scan_window: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Authentication_Enable_ReturnParameters(HCI_StatusReturnParameters):
|
|
authentication_enable: int = field(metadata=metadata(1))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_Read_Authentication_Enable_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Authentication_Enable_Command(
|
|
HCI_SyncCommand[HCI_Read_Authentication_Enable_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.3.23 Read Authentication Enable Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Write_Authentication_Enable_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.3.24 Write Authentication Enable Command
|
|
'''
|
|
|
|
authentication_enable: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Class_Of_Device_ReturnParameters(HCI_StatusReturnParameters):
|
|
class_of_device: int = field(
|
|
metadata=metadata({'size': 3, 'mapper': map_class_of_device})
|
|
)
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_Read_Class_Of_Device_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Class_Of_Device_Command(
|
|
HCI_SyncCommand[HCI_Read_Class_Of_Device_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.3.25 Read Class of Device Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Write_Class_Of_Device_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.3.26 Write Class of Device Command
|
|
'''
|
|
|
|
class_of_device: int = field(metadata=metadata(COD_SPEC))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Voice_Setting_ReturnParameters(HCI_StatusReturnParameters):
|
|
voice_setting: int = field(metadata=metadata(2))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_Read_Voice_Setting_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Voice_Setting_Command(
|
|
HCI_SyncCommand[HCI_Read_Voice_Setting_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.3.27 Read Voice Setting Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Write_Voice_Setting_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.3.28 Write Voice Setting Command
|
|
'''
|
|
|
|
voice_setting: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Synchronous_Flow_Control_Enable_ReturnParameters(
|
|
HCI_StatusReturnParameters
|
|
):
|
|
synchronous_flow_control_enable: int = field(metadata=metadata(1))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_Read_Synchronous_Flow_Control_Enable_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Synchronous_Flow_Control_Enable_Command(
|
|
HCI_SyncCommand[HCI_Read_Synchronous_Flow_Control_Enable_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.3.36 Read Synchronous Flow Control Enable Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Write_Synchronous_Flow_Control_Enable_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.3.37 Write Synchronous Flow Control Enable Command
|
|
'''
|
|
|
|
synchronous_flow_control_enable: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Set_Controller_To_Host_Flow_Control_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.3.38 Set Controller To Host Flow Control command
|
|
'''
|
|
|
|
flow_control_enable: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Host_Buffer_Size_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.3.39 Host Buffer Size Command
|
|
'''
|
|
|
|
host_acl_data_packet_length: int = field(metadata=metadata(2))
|
|
host_synchronous_data_packet_length: int = field(metadata=metadata(1))
|
|
host_total_num_acl_data_packets: int = field(metadata=metadata(2))
|
|
host_total_num_synchronous_data_packets: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Write_Link_Supervision_Timeout_ReturnParameters(HCI_StatusReturnParameters):
|
|
handle: int = field(metadata=metadata(2))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_Write_Link_Supervision_Timeout_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Write_Link_Supervision_Timeout_Command(
|
|
HCI_SyncCommand[HCI_Write_Link_Supervision_Timeout_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.3.42 Write Link Supervision Timeout Command
|
|
'''
|
|
|
|
handle: int = field(metadata=metadata(2))
|
|
link_supervision_timeout: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Number_Of_Supported_IAC_ReturnParameters(HCI_StatusReturnParameters):
|
|
num_support_iac: int = field(metadata=metadata(1))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_Read_Number_Of_Supported_IAC_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Number_Of_Supported_IAC_Command(
|
|
HCI_SyncCommand[HCI_Read_Number_Of_Supported_IAC_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.3.43 Read Number Of Supported IAC Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Current_IAC_LAP_ReturnParameters(HCI_StatusReturnParameters):
|
|
num_support_iac: int = field(metadata=metadata(1))
|
|
iac_lap: bytes = field(metadata=metadata('*')) # TODO: should be parsed as an array
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_Read_Current_IAC_LAP_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Current_IAC_LAP_Command(
|
|
HCI_SyncCommand[HCI_Read_Current_IAC_LAP_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.3.44 Read Current IAC LAP Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Write_Inquiry_Scan_Type_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.3.48 Write Inquiry Scan Type Command
|
|
'''
|
|
|
|
scan_type: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Write_Inquiry_Mode_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.3.50 Write Inquiry Mode Command
|
|
'''
|
|
|
|
inquiry_mode: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Page_Scan_Type_ReturnParameters(HCI_StatusReturnParameters):
|
|
page_scan_type: int = field(metadata=metadata(1))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_Read_Page_Scan_Type_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Page_Scan_Type_Command(
|
|
HCI_SyncCommand[HCI_Read_Page_Scan_Type_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.3.51 Read Page Scan Type Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Write_Page_Scan_Type_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.3.52 Write Page Scan Type Command
|
|
'''
|
|
|
|
page_scan_type: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Write_Extended_Inquiry_Response_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.3.56 Write Extended Inquiry Response Command
|
|
'''
|
|
|
|
fec_required: int = field(metadata=metadata(1))
|
|
extended_inquiry_response: bytes = field(
|
|
metadata=metadata({'size': 240, 'serializer': lambda x: padded_bytes(x, 240)})
|
|
)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Write_Simple_Pairing_Mode_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.3.59 Write Simple Pairing Mode Command
|
|
'''
|
|
|
|
simple_pairing_mode: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Local_OOB_Data_ReturnParameters(HCI_StatusReturnParameters):
|
|
c: bytes = field(metadata=metadata(16))
|
|
r: bytes = field(metadata=metadata(16))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_Read_Local_OOB_Data_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Local_OOB_Data_Command(
|
|
HCI_SyncCommand[HCI_Read_Local_OOB_Data_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.3.60 Read Local OOB Data Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Inquiry_Response_Transmit_Power_Level_ReturnParameters(
|
|
HCI_StatusReturnParameters
|
|
):
|
|
tx_power: int = field(metadata=metadata(-1))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(
|
|
HCI_Read_Inquiry_Response_Transmit_Power_Level_ReturnParameters
|
|
)
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Inquiry_Response_Transmit_Power_Level_Command(
|
|
HCI_SyncCommand[HCI_Read_Inquiry_Response_Transmit_Power_Level_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.3.61 Read Inquiry Response Transmit Power Level Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Default_Erroneous_Data_ReturnParameters(HCI_StatusReturnParameters):
|
|
erroneous_data_reporting: int = field(metadata=metadata(1))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_Read_Default_Erroneous_Data_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Default_Erroneous_Data_Reporting_Command(
|
|
HCI_SyncCommand[HCI_Read_Default_Erroneous_Data_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.3.64 Read Default Erroneous Data Reporting Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Set_Event_Mask_Page_2_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.3.69 Set Event Mask Page 2 Command
|
|
'''
|
|
|
|
event_mask_page_2: bytes = field(metadata=metadata(8))
|
|
|
|
@staticmethod
|
|
def mask(event_codes: Iterable[int]) -> bytes:
|
|
'''
|
|
Compute the event mask value for a list of events.
|
|
'''
|
|
# NOTE: this implementation takes advantage of the fact that as of version 6.0
|
|
# of the core specification, the bit number for each event code is equal to 64
|
|
# less than the event code.
|
|
# If future versions of the specification deviate from that, a different
|
|
# implementation would be needed.
|
|
return sum((1 << event_code - 64) for event_code in event_codes).to_bytes(
|
|
8, 'little'
|
|
)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Read_LE_Host_Support_ReturnParameters(HCI_StatusReturnParameters):
|
|
le_supported_host: int = field(metadata=metadata(1))
|
|
unused: int = field(metadata=metadata(1))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_Read_LE_Host_Support_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Read_LE_Host_Support_Command(
|
|
HCI_SyncCommand[HCI_Read_LE_Host_Support_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.3.78 Read LE Host Support Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Write_LE_Host_Support_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.3.79 Write LE Host Support Command
|
|
'''
|
|
|
|
le_supported_host: int = field(metadata=metadata(1))
|
|
simultaneous_le_host: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Write_Secure_Connections_Host_Support_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.3.92 Write Secure Connections Host Support Command
|
|
'''
|
|
|
|
secure_connections_host_support: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Write_Authenticated_Payload_Timeout_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.3.94 Write Authenticated Payload Timeout Command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
authenticated_payload_timeout: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Local_OOB_Extended_Data_ReturnParameters(HCI_StatusReturnParameters):
|
|
le_supported_host: int = field(metadata=metadata(1))
|
|
c_192: bytes = field(metadata=metadata(16))
|
|
r_192: bytes = field(metadata=metadata(16))
|
|
c_256: bytes = field(metadata=metadata(16))
|
|
r_256: bytes = field(metadata=metadata(16))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_Read_Local_OOB_Extended_Data_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Local_OOB_Extended_Data_Command(
|
|
HCI_SyncCommand[HCI_Read_Local_OOB_Extended_Data_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.3.95 Read Local OOB Extended Data Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Local_Version_Information_ReturnParameters(HCI_StatusReturnParameters):
|
|
hci_version: int = field(metadata=SpecificationVersion.type_metadata(1))
|
|
hci_subversion: int = field(metadata=metadata(2))
|
|
lmp_version: int = field(metadata=SpecificationVersion.type_metadata(1))
|
|
company_identifier: int = field(metadata=metadata(2))
|
|
lmp_subversion: int = field(metadata=metadata(2))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_Read_Local_Version_Information_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Local_Version_Information_Command(
|
|
HCI_SyncCommand[HCI_Read_Local_Version_Information_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.4.1 Read Local Version Information Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Local_Supported_Commands_ReturnParameters(HCI_StatusReturnParameters):
|
|
supported_commands: bytes = field(metadata=metadata(64))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_Read_Local_Supported_Commands_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Local_Supported_Commands_Command(
|
|
HCI_SyncCommand[HCI_Read_Local_Supported_Commands_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.4.2 Read Local Supported Commands Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Local_Supported_Features_ReturnParameters(HCI_StatusReturnParameters):
|
|
lmp_features: bytes = field(metadata=metadata(8))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_Read_Local_Supported_Features_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Local_Supported_Features_Command(
|
|
HCI_SyncCommand[HCI_Read_Local_Supported_Features_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.4.3 Read Local Supported Features Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Local_Extended_Features_ReturnParameters(HCI_StatusReturnParameters):
|
|
page_number: int = field(metadata=metadata(1))
|
|
maximum_page_number: int = field(metadata=metadata(1))
|
|
extended_lmp_features: bytes = field(metadata=metadata(8))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_Read_Local_Extended_Features_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Local_Extended_Features_Command(
|
|
HCI_SyncCommand[HCI_Read_Local_Extended_Features_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.4.4 Read Local Extended Features Command
|
|
'''
|
|
|
|
page_number: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Buffer_Size_ReturnParameters(HCI_StatusReturnParameters):
|
|
hc_acl_data_packet_length: int = field(metadata=metadata(2))
|
|
hc_synchronous_data_packet_length: int = field(metadata=metadata(1))
|
|
hc_total_num_acl_data_packets: int = field(metadata=metadata(2))
|
|
hc_total_num_synchronous_data_packets: int = field(metadata=metadata(2))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_Read_Buffer_Size_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Buffer_Size_Command(
|
|
HCI_SyncCommand[HCI_Read_Buffer_Size_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.4.5 Read Buffer Size Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Read_BD_ADDR_ReturnParameters(HCI_StatusReturnParameters):
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_Read_BD_ADDR_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Read_BD_ADDR_Command(HCI_SyncCommand[HCI_Read_BD_ADDR_ReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.4.6 Read BD_ADDR Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Local_Supported_Codecs_ReturnParameters(HCI_StatusReturnParameters):
|
|
standard_codec_ids: Sequence[CodecID] = field(
|
|
metadata=CodecID.type_metadata(1, list_begin=True, list_end=True)
|
|
)
|
|
vendor_specific_codec_ids: Sequence[int] = field(
|
|
metadata=metadata(4, list_begin=True, list_end=True)
|
|
)
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_Read_Local_Supported_Codecs_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Local_Supported_Codecs_Command(
|
|
HCI_SyncCommand[HCI_Read_Local_Supported_Codecs_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.4.8 Read Local Supported Codecs Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Local_Supported_Codecs_V2_ReturnParameters(HCI_StatusReturnParameters):
|
|
class Transport(SpecableFlag):
|
|
BR_EDR_ACL = 1 << 0
|
|
BR_EDR_SCO = 1 << 1
|
|
LE_CIS = 1 << 2
|
|
LE_BIS = 1 << 3
|
|
|
|
standard_codec_ids: Sequence[CodecID] = field(
|
|
metadata=CodecID.type_metadata(1, list_begin=True)
|
|
)
|
|
standard_codec_transports: Sequence[Transport] = field(
|
|
metadata=Transport.type_metadata(1, list_end=True)
|
|
)
|
|
vendor_specific_codec_ids: Sequence[int] = field(
|
|
metadata=metadata(4, list_begin=True)
|
|
)
|
|
vendor_specific_codec_transports: Sequence[Transport] = field(
|
|
metadata=Transport.type_metadata(1, list_end=True)
|
|
)
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_Read_Local_Supported_Codecs_V2_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Local_Supported_Codecs_V2_Command(
|
|
HCI_SyncCommand[HCI_Read_Local_Supported_Codecs_V2_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.4.8 Read Local Supported Codecs Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Read_RSSI_ReturnParameters(HCI_StatusReturnParameters):
|
|
handle: int = field(metadata=metadata(2))
|
|
rssi: int = field(metadata=metadata(-1))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_Read_RSSI_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Read_RSSI_Command(HCI_SyncCommand[HCI_Read_RSSI_ReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.5.4 Read RSSI Command
|
|
'''
|
|
|
|
handle: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Encryption_Key_Size_ReturnParameters(HCI_StatusReturnParameters):
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
key_size: int = field(metadata=metadata(1))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_Read_Encryption_Key_Size_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Encryption_Key_Size_Command(
|
|
HCI_SyncCommand[HCI_Read_Encryption_Key_Size_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.5.7 Read Encryption Key Size Command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Loopback_Mode_ReturnParameters(HCI_StatusReturnParameters):
|
|
loopback_mode: LoopbackMode = field(metadata=LoopbackMode.type_metadata(1))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_Read_Loopback_Mode_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Loopback_Mode_Command(
|
|
HCI_SyncCommand[HCI_Read_Loopback_Mode_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.6.1 Read Loopback Mode Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_Write_Loopback_Mode_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.6.2 Write Loopback Mode Command
|
|
'''
|
|
|
|
loopback_mode: LoopbackMode = field(metadata=LoopbackMode.type_metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Event_Mask_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.8.1 LE Set Event Mask Command
|
|
'''
|
|
|
|
le_event_mask: bytes = field(metadata=metadata(8))
|
|
|
|
@staticmethod
|
|
def mask(event_codes: Iterable[int]) -> bytes:
|
|
'''
|
|
Compute the event mask value for a list of events.
|
|
'''
|
|
# NOTE: this implementation takes advantage of the fact that as of version 5.4
|
|
# of the core specification, the bit number for each event code is equal to one
|
|
# less than the event code.
|
|
# If future versions of the specification deviate from that, a different
|
|
# implementation would be needed.
|
|
return sum((1 << event_code - 1) for event_code in event_codes).to_bytes(
|
|
8, 'little'
|
|
)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Buffer_Size_ReturnParameters(HCI_StatusReturnParameters):
|
|
le_acl_data_packet_length: int = field(metadata=metadata(2))
|
|
total_num_le_acl_data_packets: int = field(metadata=metadata(1))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_LE_Read_Buffer_Size_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Buffer_Size_Command(
|
|
HCI_SyncCommand[HCI_LE_Read_Buffer_Size_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.2 LE Read Buffer Size Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Buffer_Size_V2_ReturnParameters(HCI_StatusReturnParameters):
|
|
le_acl_data_packet_length: int = field(metadata=metadata(2))
|
|
total_num_le_acl_data_packets: int = field(metadata=metadata(1))
|
|
iso_data_packet_length: int = field(metadata=metadata(2))
|
|
total_num_iso_data_packets: int = field(metadata=metadata(1))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_LE_Read_Buffer_Size_V2_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Buffer_Size_V2_Command(
|
|
HCI_SyncCommand[HCI_LE_Read_Buffer_Size_V2_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.2 LE Read Buffer Size V2 Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Local_Supported_Features_ReturnParameters(HCI_StatusReturnParameters):
|
|
le_features: bytes = field(metadata=metadata(8))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_LE_Read_Local_Supported_Features_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Local_Supported_Features_Command(
|
|
HCI_SyncCommand[HCI_LE_Read_Local_Supported_Features_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.3 LE Read Local Supported Features Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Random_Address_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.8.4 LE Set Random Address Command
|
|
'''
|
|
|
|
random_address: Address = field(
|
|
metadata=metadata(
|
|
lambda data, offset: Address.parse_address_with_type(
|
|
data, offset, Address.RANDOM_DEVICE_ADDRESS
|
|
)
|
|
)
|
|
)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Advertising_Parameters_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.5 LE Set Advertising Parameters Command
|
|
'''
|
|
|
|
class AdvertisingType(SpecableEnum):
|
|
ADV_IND = 0x00
|
|
ADV_DIRECT_IND = 0x01
|
|
ADV_SCAN_IND = 0x02
|
|
ADV_NONCONN_IND = 0x03
|
|
ADV_DIRECT_IND_LOW_DUTY = 0x04
|
|
|
|
advertising_interval_min: int = field(metadata=metadata(2))
|
|
advertising_interval_max: int = field(metadata=metadata(2))
|
|
advertising_type: int = field(metadata=AdvertisingType.type_metadata(1))
|
|
own_address_type: int = field(metadata=OwnAddressType.type_metadata(1))
|
|
peer_address_type: int = field(metadata=metadata(Address.ADDRESS_TYPE_SPEC))
|
|
peer_address: Address = field(
|
|
metadata=metadata(Address.parse_address_preceded_by_type)
|
|
)
|
|
advertising_channel_map: int = field(metadata=metadata(1))
|
|
advertising_filter_policy: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Advertising_Physical_Channel_Tx_Power_ReturnParameters(
|
|
HCI_StatusReturnParameters
|
|
):
|
|
tx_power_level: int = field(metadata=metadata(-1))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(
|
|
HCI_LE_Read_Advertising_Physical_Channel_Tx_Power_ReturnParameters
|
|
)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Advertising_Physical_Channel_Tx_Power_Command(
|
|
HCI_SyncCommand[HCI_LE_Read_Advertising_Physical_Channel_Tx_Power_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.6 LE Read Advertising Physical Channel Tx Power Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Advertising_Data_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.8.7 LE Set Advertising Data Command
|
|
'''
|
|
|
|
advertising_data: bytes = field(
|
|
metadata=metadata(
|
|
{
|
|
'parser': HCI_Object.parse_length_prefixed_bytes,
|
|
'serializer': functools.partial(
|
|
HCI_Object.serialize_length_prefixed_bytes, padded_size=32
|
|
),
|
|
}
|
|
)
|
|
)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Scan_Response_Data_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.8 LE Set Scan Response Data Command
|
|
'''
|
|
|
|
scan_response_data: bytes = field(
|
|
metadata=metadata(
|
|
{
|
|
'parser': HCI_Object.parse_length_prefixed_bytes,
|
|
'serializer': functools.partial(
|
|
HCI_Object.serialize_length_prefixed_bytes, padded_size=32
|
|
),
|
|
}
|
|
)
|
|
)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Advertising_Enable_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.9 LE Set Advertising Enable Command
|
|
'''
|
|
|
|
advertising_enable: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Scan_Parameters_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.8.10 LE Set Scan Parameters Command
|
|
'''
|
|
|
|
le_scan_type: int = field(metadata=metadata(1))
|
|
le_scan_interval: int = field(metadata=metadata(2))
|
|
le_scan_window: int = field(metadata=metadata(2))
|
|
own_address_type: int = field(metadata=OwnAddressType.type_metadata(1))
|
|
scanning_filter_policy: int = field(metadata=metadata(1))
|
|
|
|
PASSIVE_SCANNING = 0
|
|
ACTIVE_SCANNING = 1
|
|
|
|
BASIC_UNFILTERED_POLICY = 0x00
|
|
BASIC_FILTERED_POLICY = 0x01
|
|
EXTENDED_UNFILTERED_POLICY = 0x02
|
|
EXTENDED_FILTERED_POLICY = 0x03
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Scan_Enable_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.8.11 LE Set Scan Enable Command
|
|
'''
|
|
|
|
le_scan_enable: int = field(metadata=metadata(1))
|
|
filter_duplicates: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Create_Connection_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.8.12 LE Create Connection Command
|
|
'''
|
|
|
|
le_scan_interval: int = field(metadata=metadata(2))
|
|
le_scan_window: int = field(metadata=metadata(2))
|
|
initiator_filter_policy: int = field(metadata=metadata(1))
|
|
peer_address_type: int = field(metadata=metadata(Address.ADDRESS_TYPE_SPEC))
|
|
peer_address: Address = field(
|
|
metadata=metadata(Address.parse_address_preceded_by_type)
|
|
)
|
|
own_address_type: int = field(metadata=OwnAddressType.type_metadata(1))
|
|
connection_interval_min: int = field(metadata=metadata(2))
|
|
connection_interval_max: int = field(metadata=metadata(2))
|
|
max_latency: int = field(metadata=metadata(2))
|
|
supervision_timeout: int = field(metadata=metadata(2))
|
|
min_ce_length: int = field(metadata=metadata(2))
|
|
max_ce_length: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Create_Connection_Cancel_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.13 LE Create Connection Cancel Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Filter_Accept_List_Size_ReturnParameters(HCI_StatusReturnParameters):
|
|
filter_accept_list_size: int = field(metadata=metadata(1))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_LE_Read_Filter_Accept_List_Size_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Filter_Accept_List_Size_Command(
|
|
HCI_SyncCommand[HCI_LE_Read_Filter_Accept_List_Size_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.14 LE Read Filter Accept List Size Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Clear_Filter_Accept_List_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.15 LE Clear Filter Accept List Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Add_Device_To_Filter_Accept_List_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.16 LE Add Device To Filter Accept List Command
|
|
'''
|
|
|
|
address_type: int = field(metadata=metadata(Address.ADDRESS_TYPE_SPEC))
|
|
address: Address = field(metadata=metadata(Address.parse_address_preceded_by_type))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Remove_Device_From_Filter_Accept_List_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.17 LE Remove Device From Filter Accept List Command
|
|
'''
|
|
|
|
address_type: int = field(metadata=metadata(Address.ADDRESS_TYPE_SPEC))
|
|
address: Address = field(metadata=metadata(Address.parse_address_preceded_by_type))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Connection_Update_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.8.18 LE Connection Update Command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
connection_interval_min: int = field(metadata=metadata(2))
|
|
connection_interval_max: int = field(metadata=metadata(2))
|
|
max_latency: int = field(metadata=metadata(2))
|
|
supervision_timeout: int = field(metadata=metadata(2))
|
|
min_ce_length: int = field(metadata=metadata(2))
|
|
max_ce_length: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Remote_Features_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.8.21 LE Read Remote Features Command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Rand_ReturnParameters(HCI_StatusReturnParameters):
|
|
random_number: bytes = field(metadata=metadata(8))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_LE_Rand_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Rand_Command(HCI_SyncCommand[HCI_LE_Rand_ReturnParameters]):
|
|
"""
|
|
See Bluetooth spec @ 7.8.23 LE Rand Command
|
|
"""
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Enable_Encryption_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.8.24 LE Enable Encryption Command
|
|
(renamed from "LE Start Encryption Command" in version prior to 5.2 of the
|
|
specification)
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
random_number: bytes = field(metadata=metadata(8))
|
|
encrypted_diversifier: int = field(metadata=metadata(2))
|
|
long_term_key: bytes = field(metadata=metadata(16))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndConnectionHandleReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Long_Term_Key_Request_Reply_Command(
|
|
HCI_SyncCommand[HCI_StatusAndConnectionHandleReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.25 LE Long Term Key Request Reply Command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
long_term_key: bytes = field(metadata=metadata(16))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndConnectionHandleReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Long_Term_Key_Request_Negative_Reply_Command(
|
|
HCI_SyncCommand[HCI_StatusAndConnectionHandleReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.26 LE Long Term Key Request Negative Reply Command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Supported_States_ReturnParameters(HCI_StatusReturnParameters):
|
|
le_states: bytes = field(metadata=metadata(8))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_LE_Read_Supported_States_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Supported_States_Command(
|
|
HCI_SyncCommand[HCI_LE_Read_Supported_States_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.27 LE Read Supported States Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndConnectionHandleReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Remote_Connection_Parameter_Request_Reply_Command(
|
|
HCI_SyncCommand[HCI_StatusAndConnectionHandleReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.31 LE Remote Connection Parameter Request Reply Command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
interval_min: int = field(metadata=metadata(2))
|
|
interval_max: int = field(metadata=metadata(2))
|
|
max_latency: int = field(metadata=metadata(2))
|
|
timeout: int = field(metadata=metadata(2))
|
|
min_ce_length: int = field(metadata=metadata(2))
|
|
max_ce_length: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndConnectionHandleReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Remote_Connection_Parameter_Request_Negative_Reply_Command(
|
|
HCI_SyncCommand[HCI_StatusAndConnectionHandleReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.32 LE Remote Connection Parameter Request Negative Reply
|
|
Command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
reason: int = field(metadata=metadata(STATUS_SPEC))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndConnectionHandleReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Data_Length_Command(
|
|
HCI_SyncCommand[HCI_StatusAndConnectionHandleReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.33 LE Set Data Length Command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
tx_octets: int = field(metadata=metadata(2))
|
|
tx_time: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Suggested_Default_Data_Length_ReturnParameters(
|
|
HCI_StatusReturnParameters
|
|
):
|
|
suggested_max_tx_octets: int = field(metadata=metadata(2))
|
|
suggested_max_tx_time: int = field(metadata=metadata(2))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(
|
|
HCI_LE_Read_Suggested_Default_Data_Length_ReturnParameters
|
|
)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Suggested_Default_Data_Length_Command(
|
|
HCI_SyncCommand[HCI_LE_Read_Suggested_Default_Data_Length_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.34 LE Read Suggested Default Data Length Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Write_Suggested_Default_Data_Length_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.35 LE Write Suggested Default Data Length Command
|
|
'''
|
|
|
|
suggested_max_tx_octets: int = field(metadata=metadata(2))
|
|
suggested_max_tx_time: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Local_P_256_Public_Key_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.8.36 LE Read Local P-256 Public Key command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Add_Device_To_Resolving_List_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.38 LE Add Device To Resolving List Command
|
|
'''
|
|
|
|
peer_identity_address_type: int = field(
|
|
metadata=metadata(Address.ADDRESS_TYPE_SPEC)
|
|
)
|
|
peer_identity_address: Address = field(
|
|
metadata=metadata(Address.parse_address_preceded_by_type)
|
|
)
|
|
peer_irk: bytes = field(metadata=metadata(16))
|
|
local_irk: bytes = field(metadata=metadata(16))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Clear_Resolving_List_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.8.40 LE Clear Resolving List Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Resolving_List_Size_ReturnParameters(HCI_StatusReturnParameters):
|
|
resolving_list_size: int = field(metadata=metadata(1))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_LE_Read_Resolving_List_Size_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Resolving_List_Size_Command(
|
|
HCI_SyncCommand[HCI_LE_Read_Resolving_List_Size_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.41 LE Read Resolving List Size command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Address_Resolution_Enable_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.44 LE Set Address Resolution Enable Command
|
|
'''
|
|
|
|
address_resolution_enable: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Resolvable_Private_Address_Timeout_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.45 LE Set Resolvable Private Address Timeout Command
|
|
'''
|
|
|
|
rpa_timeout: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Maximum_Data_Length_ReturnParameters(HCI_StatusReturnParameters):
|
|
supported_max_tx_octets: int = field(metadata=metadata(2))
|
|
supported_max_tx_time: int = field(metadata=metadata(2))
|
|
supported_max_rx_octets: int = field(metadata=metadata(2))
|
|
supported_max_rx_time: int = field(metadata=metadata(2))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_LE_Read_Maximum_Data_Length_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Maximum_Data_Length_Command(
|
|
HCI_SyncCommand[HCI_LE_Read_Maximum_Data_Length_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.46 LE Read Maximum Data Length Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_PHY_ReturnParameters(HCI_StatusAndConnectionHandleReturnParameters):
|
|
tx_phy: Phy = field(metadata=Phy.type_metadata(1))
|
|
rx_phy: Phy = field(metadata=Phy.type_metadata(1))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_LE_Read_PHY_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_PHY_Command(HCI_SyncCommand[HCI_LE_Read_PHY_ReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.8.47 LE Read PHY Command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Default_PHY_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.8.48 LE Set Default PHY Command
|
|
'''
|
|
|
|
class AnyPhy(SpecableFlag):
|
|
ANY_TX = 0
|
|
ANY_RX = 1
|
|
|
|
all_phys: int = field(metadata=AnyPhy.type_metadata(1))
|
|
tx_phys: int = field(metadata=PhyBit.type_metadata(1))
|
|
rx_phys: int = field(metadata=PhyBit.type_metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_PHY_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.8.49 LE Set PHY Command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
all_phys: int = field(
|
|
metadata=HCI_LE_Set_Default_PHY_Command.AnyPhy.type_metadata(1)
|
|
)
|
|
tx_phys: int = field(metadata=PhyBit.type_metadata(1))
|
|
rx_phys: int = field(metadata=PhyBit.type_metadata(1))
|
|
phy_options: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Advertising_Set_Random_Address_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.52 LE Set Advertising Set Random Address Command
|
|
'''
|
|
|
|
advertising_handle: int = field(metadata=metadata(1))
|
|
random_address: Address = field(
|
|
metadata=metadata(
|
|
lambda data, offset: Address.parse_address_with_type(
|
|
data, offset, Address.RANDOM_DEVICE_ADDRESS
|
|
)
|
|
)
|
|
)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Extended_Advertising_Parameters_ReturnParameters(
|
|
HCI_StatusReturnParameters
|
|
):
|
|
selected_tx_power: int = field(metadata=metadata(-1))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(
|
|
HCI_LE_Set_Extended_Advertising_Parameters_ReturnParameters
|
|
)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Extended_Advertising_Parameters_Command(
|
|
HCI_SyncCommand[HCI_LE_Set_Extended_Advertising_Parameters_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.53 LE Set Extended Advertising Parameters Command
|
|
'''
|
|
|
|
TX_POWER_NO_PREFERENCE = 0x7F
|
|
SHOULD_NOT_FRAGMENT = 0x01
|
|
|
|
class AdvertisingProperties(SpecableFlag):
|
|
CONNECTABLE_ADVERTISING = 1 << 0
|
|
SCANNABLE_ADVERTISING = 1 << 1
|
|
DIRECTED_ADVERTISING = 1 << 2
|
|
HIGH_DUTY_CYCLE_DIRECTED_CONNECTABLE_ADVERTISING = 1 << 3
|
|
USE_LEGACY_ADVERTISING_PDUS = 1 << 4
|
|
ANONYMOUS_ADVERTISING = 1 << 5
|
|
INCLUDE_TX_POWER = 1 << 6
|
|
|
|
def __str__(self) -> str:
|
|
return '|'.join(
|
|
flag.name
|
|
for flag in HCI_LE_Set_Extended_Advertising_Parameters_Command.AdvertisingProperties
|
|
if self.value & flag.value and flag.name is not None
|
|
)
|
|
|
|
class ChannelMap(SpecableFlag):
|
|
CHANNEL_37 = 1 << 0
|
|
CHANNEL_38 = 1 << 1
|
|
CHANNEL_39 = 1 << 2
|
|
|
|
def __str__(self) -> str:
|
|
return '|'.join(
|
|
flag.name
|
|
for flag in HCI_LE_Set_Extended_Advertising_Parameters_Command.ChannelMap
|
|
if self.value & flag.value and flag.name is not None
|
|
)
|
|
|
|
advertising_handle: int = field(metadata=metadata(1))
|
|
advertising_event_properties: int = field(
|
|
metadata=AdvertisingProperties.type_metadata(2)
|
|
)
|
|
primary_advertising_interval_min: int = field(metadata=metadata(3))
|
|
primary_advertising_interval_max: int = field(metadata=metadata(3))
|
|
primary_advertising_channel_map: int = field(metadata=ChannelMap.type_metadata(1))
|
|
own_address_type: int = field(metadata=OwnAddressType.type_metadata(1))
|
|
peer_address_type: int = field(metadata=metadata(Address.ADDRESS_TYPE_SPEC))
|
|
peer_address: Address = field(
|
|
metadata=metadata(Address.parse_address_preceded_by_type)
|
|
)
|
|
advertising_filter_policy: int = field(metadata=metadata(1))
|
|
advertising_tx_power: int = field(metadata=metadata(1))
|
|
primary_advertising_phy: int = field(metadata=Phy.type_metadata(1))
|
|
secondary_advertising_max_skip: int = field(metadata=metadata(1))
|
|
secondary_advertising_phy: int = field(metadata=Phy.type_metadata(1))
|
|
advertising_sid: int = field(metadata=metadata(1))
|
|
scan_request_notification_enable: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Extended_Advertising_Data_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.54 LE Set Extended Advertising Data Command
|
|
'''
|
|
|
|
class Operation(SpecableEnum):
|
|
INTERMEDIATE_FRAGMENT = 0x00
|
|
FIRST_FRAGMENT = 0x01
|
|
LAST_FRAGMENT = 0x02
|
|
COMPLETE_DATA = 0x03
|
|
UNCHANGED_DATA = 0x04
|
|
|
|
advertising_handle: int = field(metadata=metadata(1))
|
|
operation: int = field(metadata=Operation.type_metadata(1))
|
|
fragment_preference: int = field(metadata=metadata(1))
|
|
advertising_data: bytes = field(metadata=metadata("v"))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Extended_Scan_Response_Data_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.55 LE Set Extended Scan Response Data Command
|
|
'''
|
|
|
|
advertising_handle: int = field(metadata=metadata(1))
|
|
operation: int = field(
|
|
metadata=HCI_LE_Set_Extended_Advertising_Data_Command.Operation.type_metadata(1)
|
|
)
|
|
fragment_preference: int = field(metadata=metadata(1))
|
|
scan_response_data: bytes = field(metadata=metadata("v"))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Extended_Advertising_Enable_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.56 LE Set Extended Advertising Enable Command
|
|
'''
|
|
|
|
enable: int = field(metadata=metadata(1))
|
|
advertising_handles: Sequence[int] = field(metadata=metadata(1, list_begin=True))
|
|
durations: Sequence[int] = field(metadata=metadata(2))
|
|
max_extended_advertising_events: Sequence[int] = field(
|
|
metadata=metadata(1, list_end=True)
|
|
)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Maximum_Advertising_Data_Length_ReturnParameters(
|
|
HCI_StatusReturnParameters
|
|
):
|
|
max_advertising_data_length: int = field(metadata=metadata(2))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(
|
|
HCI_LE_Read_Maximum_Advertising_Data_Length_ReturnParameters
|
|
)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Maximum_Advertising_Data_Length_Command(
|
|
HCI_SyncCommand[HCI_LE_Read_Maximum_Advertising_Data_Length_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.57 LE Read Maximum Advertising Data Length Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Number_Of_Supported_Advertising_Sets_ReturnParameters(
|
|
HCI_StatusReturnParameters
|
|
):
|
|
num_supported_advertising_sets: int = field(metadata=metadata(1))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(
|
|
HCI_LE_Read_Number_Of_Supported_Advertising_Sets_ReturnParameters
|
|
)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Number_Of_Supported_Advertising_Sets_Command(
|
|
HCI_SyncCommand[HCI_LE_Read_Number_Of_Supported_Advertising_Sets_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.58 LE Read Number of Supported Advertising Sets Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Remove_Advertising_Set_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.59 LE Remove Advertising Set Command
|
|
'''
|
|
|
|
advertising_handle: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Clear_Advertising_Sets_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.60 LE Clear Advertising Sets Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Periodic_Advertising_Parameters_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.61 LE Set Periodic Advertising Parameters command
|
|
'''
|
|
|
|
advertising_handle: int = field(metadata=metadata(1))
|
|
periodic_advertising_interval_min: int = field(metadata=metadata(2))
|
|
periodic_advertising_interval_max: int = field(metadata=metadata(2))
|
|
periodic_advertising_properties: int = field(metadata=metadata(2))
|
|
|
|
class Properties(SpecableFlag):
|
|
INCLUDE_TX_POWER = 1 << 6
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Periodic_Advertising_Data_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.62 LE Set Periodic Advertising Data command
|
|
'''
|
|
|
|
advertising_handle: int = field(metadata=metadata(1))
|
|
operation: int = field(
|
|
metadata=HCI_LE_Set_Extended_Advertising_Data_Command.Operation.type_metadata(1)
|
|
)
|
|
advertising_data: bytes = field(metadata=metadata("v"))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Periodic_Advertising_Enable_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.63 LE Set Periodic Advertising Enable Command
|
|
'''
|
|
|
|
enable: int = field(metadata=metadata(1))
|
|
advertising_handle: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
class HCI_LE_Set_Extended_Scan_Parameters_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.64 LE Set Extended Scan Parameters Command
|
|
'''
|
|
|
|
PASSIVE_SCANNING = 0
|
|
ACTIVE_SCANNING = 1
|
|
|
|
BASIC_UNFILTERED_POLICY = 0x00
|
|
BASIC_FILTERED_POLICY = 0x01
|
|
EXTENDED_UNFILTERED_POLICY = 0x02
|
|
EXTENDED_FILTERED_POLICY = 0x03
|
|
|
|
op_code = HCI_LE_SET_EXTENDED_SCAN_PARAMETERS_COMMAND
|
|
|
|
@classmethod
|
|
def from_parameters(cls, parameters: bytes) -> Self:
|
|
own_address_type = parameters[0]
|
|
scanning_filter_policy = parameters[1]
|
|
scanning_phys = parameters[2]
|
|
|
|
phy_bits_set = bin(scanning_phys).count('1')
|
|
scan_types = []
|
|
scan_intervals = []
|
|
scan_windows = []
|
|
for i in range(phy_bits_set):
|
|
scan_types.append(parameters[3 + (5 * i)])
|
|
scan_intervals.append(
|
|
struct.unpack_from('<H', parameters, 3 + (5 * i) + 1)[0]
|
|
)
|
|
scan_windows.append(
|
|
struct.unpack_from('<H', parameters, 3 + (5 * i) + 3)[0]
|
|
)
|
|
|
|
return cls(
|
|
own_address_type=own_address_type,
|
|
scanning_filter_policy=scanning_filter_policy,
|
|
scanning_phys=scanning_phys,
|
|
scan_types=scan_types,
|
|
scan_intervals=scan_intervals,
|
|
scan_windows=scan_windows,
|
|
)
|
|
|
|
def __init__(
|
|
self,
|
|
own_address_type: int,
|
|
scanning_filter_policy: int,
|
|
scanning_phys: int,
|
|
scan_types: Sequence[int],
|
|
scan_intervals: Sequence[int],
|
|
scan_windows: Sequence[int],
|
|
) -> None:
|
|
super().__init__()
|
|
self.own_address_type = own_address_type
|
|
self.scanning_filter_policy = scanning_filter_policy
|
|
self.scanning_phys = scanning_phys
|
|
self.scan_types = list(scan_types)
|
|
self.scan_intervals = list(scan_intervals)
|
|
self.scan_windows = list(scan_windows)
|
|
|
|
self.parameters = bytes(
|
|
[own_address_type, scanning_filter_policy, scanning_phys]
|
|
)
|
|
phy_bits_set = bin(scanning_phys).count('1')
|
|
for i in range(phy_bits_set):
|
|
self.parameters += struct.pack(
|
|
'<BHH', scan_types[i], scan_intervals[i], scan_windows[i]
|
|
)
|
|
|
|
def __str__(self):
|
|
scanning_phys_strs = bit_flags_to_strings(
|
|
self.scanning_phys, HCI_LE_PHY_BIT_NAMES
|
|
)
|
|
fields = [
|
|
(
|
|
'own_address_type: ',
|
|
Address.address_type_name(self.own_address_type),
|
|
),
|
|
('scanning_filter_policy:', self.scanning_filter_policy),
|
|
('scanning_phys: ', ','.join(scanning_phys_strs)),
|
|
]
|
|
for i, scanning_phy_str in enumerate(scanning_phys_strs):
|
|
fields.append(
|
|
(
|
|
f'{scanning_phy_str}.scan_type: ',
|
|
(
|
|
'PASSIVE'
|
|
if self.scan_types[i] == self.PASSIVE_SCANNING
|
|
else 'ACTIVE'
|
|
),
|
|
)
|
|
)
|
|
fields.append(
|
|
(f'{scanning_phy_str}.scan_interval:', self.scan_intervals[i])
|
|
)
|
|
fields.append((f'{scanning_phy_str}.scan_window: ', self.scan_windows[i]))
|
|
|
|
return (
|
|
color(self.name, 'green')
|
|
+ ':\n'
|
|
+ '\n'.join(
|
|
[
|
|
color(' ' + field[0], 'cyan') + ' ' + str(field[1])
|
|
for field in fields
|
|
]
|
|
)
|
|
)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Extended_Scan_Enable_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.65 LE Set Extended Scan Enable Command
|
|
'''
|
|
|
|
enable: int = field(metadata=metadata(1))
|
|
filter_duplicates: int = field(metadata=metadata(1))
|
|
duration: int = field(metadata=metadata(2))
|
|
period: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
class HCI_LE_Extended_Create_Connection_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.8.66 LE Extended Create Connection Command
|
|
'''
|
|
|
|
op_code = HCI_LE_EXTENDED_CREATE_CONNECTION_COMMAND
|
|
|
|
@classmethod
|
|
def from_parameters(cls, parameters: bytes) -> Self:
|
|
initiator_filter_policy = parameters[0]
|
|
own_address_type = parameters[1]
|
|
peer_address_type = parameters[2]
|
|
peer_address = Address.parse_address_preceded_by_type(parameters, 3)[1]
|
|
initiating_phys = parameters[9]
|
|
|
|
phy_bits_set = bin(initiating_phys).count('1')
|
|
|
|
def read_parameter_list(offset):
|
|
return [
|
|
struct.unpack_from('<H', parameters, offset + 16 * i)[0]
|
|
for i in range(phy_bits_set)
|
|
]
|
|
|
|
return cls(
|
|
initiator_filter_policy=initiator_filter_policy,
|
|
own_address_type=own_address_type,
|
|
peer_address_type=peer_address_type,
|
|
peer_address=peer_address,
|
|
initiating_phys=initiating_phys,
|
|
scan_intervals=read_parameter_list(10),
|
|
scan_windows=read_parameter_list(12),
|
|
connection_interval_mins=read_parameter_list(14),
|
|
connection_interval_maxs=read_parameter_list(16),
|
|
max_latencies=read_parameter_list(18),
|
|
supervision_timeouts=read_parameter_list(20),
|
|
min_ce_lengths=read_parameter_list(22),
|
|
max_ce_lengths=read_parameter_list(24),
|
|
)
|
|
|
|
def __init__(
|
|
self,
|
|
initiator_filter_policy: int,
|
|
own_address_type: int,
|
|
peer_address_type: int,
|
|
peer_address: Address,
|
|
initiating_phys: int,
|
|
scan_intervals: Sequence[int],
|
|
scan_windows: Sequence[int],
|
|
connection_interval_mins: Sequence[int],
|
|
connection_interval_maxs: Sequence[int],
|
|
max_latencies: Sequence[int],
|
|
supervision_timeouts: Sequence[int],
|
|
min_ce_lengths: Sequence[int],
|
|
max_ce_lengths: Sequence[int],
|
|
):
|
|
super().__init__()
|
|
self.initiator_filter_policy = initiator_filter_policy
|
|
self.own_address_type = own_address_type
|
|
self.peer_address_type = peer_address_type
|
|
self.peer_address = peer_address
|
|
self.initiating_phys = initiating_phys
|
|
self.scan_intervals = list(scan_intervals)
|
|
self.scan_windows = list(scan_windows)
|
|
self.connection_interval_mins = list(connection_interval_mins)
|
|
self.connection_interval_maxs = list(connection_interval_maxs)
|
|
self.max_latencies = list(max_latencies)
|
|
self.supervision_timeouts = list(supervision_timeouts)
|
|
self.min_ce_lengths = list(min_ce_lengths)
|
|
self.max_ce_lengths = list(max_ce_lengths)
|
|
|
|
self.parameters = (
|
|
bytes([initiator_filter_policy, own_address_type, peer_address_type])
|
|
+ bytes(peer_address)
|
|
+ bytes([initiating_phys])
|
|
)
|
|
|
|
phy_bits_set = bin(initiating_phys).count('1')
|
|
for i in range(phy_bits_set):
|
|
self.parameters += struct.pack(
|
|
'<HHHHHHHH',
|
|
scan_intervals[i],
|
|
scan_windows[i],
|
|
connection_interval_mins[i],
|
|
connection_interval_maxs[i],
|
|
max_latencies[i],
|
|
supervision_timeouts[i],
|
|
min_ce_lengths[i],
|
|
max_ce_lengths[i],
|
|
)
|
|
|
|
def __str__(self):
|
|
initiating_phys_strs = bit_flags_to_strings(
|
|
self.initiating_phys, HCI_LE_PHY_BIT_NAMES
|
|
)
|
|
fields = [
|
|
('initiator_filter_policy:', self.initiator_filter_policy),
|
|
(
|
|
'own_address_type: ',
|
|
OwnAddressType(self.own_address_type).name,
|
|
),
|
|
(
|
|
'peer_address_type: ',
|
|
Address.address_type_name(self.peer_address_type),
|
|
),
|
|
('peer_address: ', str(self.peer_address)),
|
|
('initiating_phys: ', ','.join(initiating_phys_strs)),
|
|
]
|
|
for i, initiating_phys_str in enumerate(initiating_phys_strs):
|
|
fields.append(
|
|
(
|
|
f'{initiating_phys_str}.scan_interval: ',
|
|
self.scan_intervals[i],
|
|
)
|
|
)
|
|
fields.append(
|
|
(
|
|
f'{initiating_phys_str}.scan_window: ',
|
|
self.scan_windows[i],
|
|
)
|
|
)
|
|
fields.append(
|
|
(
|
|
f'{initiating_phys_str}.connection_interval_min:',
|
|
self.connection_interval_mins[i],
|
|
)
|
|
)
|
|
fields.append(
|
|
(
|
|
f'{initiating_phys_str}.connection_interval_max:',
|
|
self.connection_interval_maxs[i],
|
|
)
|
|
)
|
|
fields.append(
|
|
(
|
|
f'{initiating_phys_str}.max_latency: ',
|
|
self.max_latencies[i],
|
|
)
|
|
)
|
|
fields.append(
|
|
(
|
|
f'{initiating_phys_str}.supervision_timeout: ',
|
|
self.supervision_timeouts[i],
|
|
)
|
|
)
|
|
fields.append(
|
|
(
|
|
f'{initiating_phys_str}.min_ce_length: ',
|
|
self.min_ce_lengths[i],
|
|
)
|
|
)
|
|
fields.append(
|
|
(
|
|
f'{initiating_phys_str}.max_ce_length: ',
|
|
self.max_ce_lengths[i],
|
|
)
|
|
)
|
|
|
|
return (
|
|
color(self.name, 'green')
|
|
+ ':\n'
|
|
+ '\n'.join(
|
|
[
|
|
color(' ' + field[0], 'cyan') + ' ' + str(field[1])
|
|
for field in fields
|
|
]
|
|
)
|
|
)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Periodic_Advertising_Create_Sync_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.8.67 LE Periodic Advertising Create Sync command
|
|
'''
|
|
|
|
class Options(SpecableFlag):
|
|
USE_PERIODIC_ADVERTISER_LIST = 1 << 0
|
|
REPORTING_INITIALLY_DISABLED = 1 << 1
|
|
DUPLICATE_FILTERING_INITIALLY_ENABLED = 1 << 2
|
|
|
|
class CteType(SpecableFlag):
|
|
DO_NOT_SYNC_TO_PACKETS_WITH_AN_AOA_CONSTANT_TONE_EXTENSION = 1 << 0
|
|
DO_NOT_SYNC_TO_PACKETS_WITH_AN_AOD_CONSTANT_TONE_EXTENSION_1US = 1 << 1
|
|
DO_NOT_SYNC_TO_PACKETS_WITH_AN_AOD_CONSTANT_TONE_EXTENSION_2US = 1 << 2
|
|
DO_NOT_SYNC_TO_PACKETS_WITH_A_TYPE_3_CONSTANT_TONE_EXTENSION = 1 << 3
|
|
DO_NOT_SYNC_TO_PACKETS_WITHOUT_A_CONSTANT_TONE_EXTENSION = 1 << 4
|
|
|
|
options: int = field(metadata=Options.type_metadata(1))
|
|
advertising_sid: int = field(metadata=metadata(1))
|
|
advertiser_address_type: int = field(metadata=metadata(Address.ADDRESS_TYPE_SPEC))
|
|
advertiser_address: Address = field(
|
|
metadata=metadata(Address.parse_address_preceded_by_type)
|
|
)
|
|
skip: int = field(metadata=metadata(2))
|
|
sync_timeout: int = field(metadata=metadata(2))
|
|
sync_cte_type: int = field(metadata=CteType.type_metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Periodic_Advertising_Create_Sync_Cancel_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.68 LE Periodic Advertising Create Sync Cancel Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Periodic_Advertising_Terminate_Sync_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.69 LE Periodic Advertising Terminate Sync Command
|
|
'''
|
|
|
|
sync_handle: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Transmit_Power_ReturnParameters(HCI_StatusReturnParameters):
|
|
min_tx_power: int = field(metadata=metadata(1))
|
|
max_tx_power: int = field(metadata=metadata(1))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_LE_Read_Transmit_Power_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Transmit_Power_Command(
|
|
HCI_SyncCommand[HCI_LE_Read_Transmit_Power_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.74 LE Read Transmit Power command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Privacy_Mode_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.8.77 LE Set Privacy Mode Command
|
|
'''
|
|
|
|
class PrivacyMode(SpecableEnum):
|
|
NETWORK_PRIVACY_MODE = 0x00
|
|
DEVICE_PRIVACY_MODE = 0x01
|
|
|
|
peer_identity_address_type: int = field(
|
|
metadata=metadata(Address.ADDRESS_TYPE_SPEC)
|
|
)
|
|
peer_identity_address: Address = field(
|
|
metadata=metadata(Address.parse_address_preceded_by_type)
|
|
)
|
|
privacy_mode: int = field(metadata=PrivacyMode.type_metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Periodic_Advertising_Receive_Enable_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.88 LE Set Periodic Advertising Receive Enable Command
|
|
'''
|
|
|
|
sync_handle: int = field(metadata=metadata(2))
|
|
enable: int = field(metadata=metadata(1))
|
|
|
|
class Enable(SpecableFlag):
|
|
REPORTING_ENABLED = 1 << 0
|
|
DUPLICATE_FILTERING_ENABLED = 1 << 1
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndConnectionHandleReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Periodic_Advertising_Sync_Transfer_Command(
|
|
HCI_SyncCommand[HCI_StatusAndConnectionHandleReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.89 LE Periodic Advertising Sync Transfer Command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
service_data: int = field(metadata=metadata(2))
|
|
sync_handle: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndConnectionHandleReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Periodic_Advertising_Set_Info_Transfer_Command(
|
|
HCI_SyncCommand[HCI_StatusAndConnectionHandleReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.90 LE Periodic Advertising Set Info Transfer Command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
service_data: int = field(metadata=metadata(2))
|
|
advertising_handle: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndConnectionHandleReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Periodic_Advertising_Sync_Transfer_Parameters_Command(
|
|
HCI_SyncCommand[HCI_StatusAndConnectionHandleReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.91 LE Set Periodic Advertising Sync Transfer Parameters command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
mode: int = field(metadata=metadata(1))
|
|
skip: int = field(metadata=metadata(2))
|
|
sync_timeout: int = field(metadata=metadata(2))
|
|
cte_type: int = field(metadata=CteType.type_metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Default_Periodic_Advertising_Sync_Transfer_Parameters_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.92 LE Set Default Periodic Advertising Sync Transfer Parameters command
|
|
'''
|
|
|
|
mode: int = field(metadata=metadata(1))
|
|
skip: int = field(metadata=metadata(2))
|
|
sync_timeout: int = field(metadata=metadata(2))
|
|
cte_type: int = field(metadata=CteType.type_metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_ISO_TX_Sync_ReturnParameters(
|
|
HCI_StatusAndConnectionHandleReturnParameters
|
|
):
|
|
packet_sequence_number: int = field(metadata=metadata(2))
|
|
tx_time_stamp: int = field(metadata=metadata(4))
|
|
time_offset: int = field(metadata=metadata(4))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_LE_Read_ISO_TX_Sync_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_ISO_TX_Sync_Command(
|
|
HCI_SyncCommand[HCI_LE_Read_ISO_TX_Sync_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.96 LE Read ISO TX Sync command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_CIG_Parameters_ReturnParameters(HCI_StatusReturnParameters):
|
|
cig_id: int = field(metadata=metadata(1))
|
|
connection_handle: Sequence[int] = field(
|
|
metadata=metadata(2, list_begin=True, list_end=True)
|
|
)
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_LE_Set_CIG_Parameters_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_CIG_Parameters_Command(
|
|
HCI_SyncCommand[HCI_LE_Set_CIG_Parameters_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.97 LE Set CIG Parameters Command
|
|
'''
|
|
|
|
cig_id: int = field(metadata=metadata(1))
|
|
sdu_interval_c_to_p: int = field(metadata=metadata(3))
|
|
sdu_interval_p_to_c: int = field(metadata=metadata(3))
|
|
worst_case_sca: int = field(metadata=metadata(1))
|
|
packing: int = field(metadata=metadata(1))
|
|
framing: int = field(metadata=metadata(1))
|
|
max_transport_latency_c_to_p: int = field(metadata=metadata(2))
|
|
max_transport_latency_p_to_c: int = field(metadata=metadata(2))
|
|
cis_id: Sequence[int] = field(metadata=metadata(1, list_begin=True))
|
|
max_sdu_c_to_p: Sequence[int] = field(metadata=metadata(2))
|
|
max_sdu_p_to_c: Sequence[int] = field(metadata=metadata(2))
|
|
phy_c_to_p: Sequence[int] = field(metadata=metadata(1))
|
|
phy_p_to_c: Sequence[int] = field(metadata=metadata(1))
|
|
rtn_c_to_p: Sequence[int] = field(metadata=metadata(1))
|
|
rtn_p_to_c: Sequence[int] = field(metadata=metadata(1, list_end=True))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Create_CIS_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.8.99 LE Create CIS command
|
|
'''
|
|
|
|
cis_connection_handle: Sequence[int] = field(metadata=metadata(2, list_begin=True))
|
|
acl_connection_handle: Sequence[int] = field(metadata=metadata(2, list_end=True))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Remove_CIG_ReturnParameters(HCI_StatusReturnParameters):
|
|
cig_id: int = field(metadata=metadata(1))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_LE_Remove_CIG_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Remove_CIG_Command(HCI_SyncCommand[HCI_LE_Remove_CIG_ReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.8.100 LE Remove CIG command
|
|
'''
|
|
|
|
cig_id: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Accept_CIS_Request_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.8.101 LE Accept CIS Request command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndConnectionHandleReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Reject_CIS_Request_Command(
|
|
HCI_SyncCommand[HCI_StatusAndConnectionHandleReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.102 LE Reject CIS Request command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
reason: int = field(metadata=metadata(STATUS_SPEC))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Create_BIG_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.8.103 LE Create BIG command
|
|
'''
|
|
|
|
big_handle: int = field(metadata=metadata(1))
|
|
advertising_handle: int = field(metadata=metadata(1))
|
|
num_bis: int = field(metadata=metadata(1))
|
|
sdu_interval: int = field(metadata=metadata(3))
|
|
max_sdu: int = field(metadata=metadata(2))
|
|
max_transport_latency: int = field(metadata=metadata(2))
|
|
rtn: int = field(metadata=metadata(1))
|
|
phy: int = field(metadata=metadata(1))
|
|
packing: int = field(metadata=metadata(1))
|
|
framing: int = field(metadata=metadata(1))
|
|
encryption: int = field(metadata=metadata(1))
|
|
broadcast_code: bytes = field(metadata=metadata(16))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Terminate_BIG_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.8.105 LE Terminate BIG command
|
|
'''
|
|
|
|
big_handle: int = field(metadata=metadata(1))
|
|
reason: int = field(metadata=metadata(STATUS_SPEC))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_LE_BIG_Create_Sync_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.8.106 LE BIG Create Sync command
|
|
'''
|
|
|
|
big_handle: int = field(metadata=metadata(1))
|
|
sync_handle: int = field(metadata=metadata(2))
|
|
encryption: int = field(metadata=metadata(1))
|
|
broadcast_code: bytes = field(metadata=metadata(16))
|
|
mse: int = field(metadata=metadata(1))
|
|
big_sync_timeout: int = field(metadata=metadata(2))
|
|
bis: Sequence[int] = field(metadata=metadata(1, list_begin=True, list_end=True))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_LE_BIG_Terminate_Sync_ReturnParameters(HCI_StatusReturnParameters):
|
|
big_handle: int = field(metadata=metadata(1))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_LE_BIG_Terminate_Sync_ReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_BIG_Terminate_Sync_Command(
|
|
HCI_SyncCommand[HCI_LE_BIG_Terminate_Sync_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.107. LE BIG Terminate Sync command
|
|
'''
|
|
|
|
big_handle: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndConnectionHandleReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Setup_ISO_Data_Path_Command(
|
|
HCI_SyncCommand[HCI_StatusAndConnectionHandleReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.109 LE Setup ISO Data Path command
|
|
'''
|
|
|
|
class Direction(SpecableEnum):
|
|
HOST_TO_CONTROLLER = 0x00
|
|
CONTROLLER_TO_HOST = 0x01
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
data_path_direction: int = field(metadata=Direction.type_metadata(1))
|
|
data_path_id: int = field(metadata=metadata(1))
|
|
codec_id: CodingFormat = field(metadata=metadata(CodingFormat.parse_from_bytes))
|
|
controller_delay: int = field(metadata=metadata(3))
|
|
codec_configuration: bytes = field(metadata=metadata("v"))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndConnectionHandleReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Remove_ISO_Data_Path_Command(
|
|
HCI_SyncCommand[HCI_StatusAndConnectionHandleReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.110 LE Remove ISO Data Path command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
data_path_direction: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Host_Feature_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.8.115 LE Set Host Feature Command
|
|
'''
|
|
|
|
bit_number: int = field(metadata=metadata(1))
|
|
bit_value: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Default_Subrate_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.8.123 LE Set Default Subrate command
|
|
'''
|
|
|
|
subrate_min: int = field(metadata=metadata(2))
|
|
subrate_max: int = field(metadata=metadata(2))
|
|
max_latency: int = field(metadata=metadata(2))
|
|
continuation_number: int = field(metadata=metadata(2))
|
|
supervision_timeout: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Subrate_Request_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.8.124 LE Subrate Request command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
subrate_min: int = field(metadata=metadata(2))
|
|
subrate_max: int = field(metadata=metadata(2))
|
|
max_latency: int = field(metadata=metadata(2))
|
|
continuation_number: int = field(metadata=metadata(2))
|
|
supervision_timeout: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_All_Local_Supported_Features_ReturnParameters(
|
|
HCI_StatusReturnParameters
|
|
):
|
|
max_page: int = field(metadata=metadata(1))
|
|
le_features: bytes = field(metadata=metadata(248))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(HCI_LE_Read_All_Local_Supported_Features_ReturnParameters)
|
|
class HCI_LE_Read_All_Local_Supported_Features_Command(
|
|
HCI_SyncCommand[HCI_LE_Read_All_Local_Supported_Features_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.128 LE Read All Local Supported Features Command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_LE_CS_Read_Local_Supported_Capabilities_ReturnParameters(
|
|
HCI_StatusReturnParameters
|
|
):
|
|
num_config_supported: int = field(metadata=metadata(1))
|
|
max_consecutive_procedures_supported: int = field(metadata=metadata(2))
|
|
num_antennas_supported: int = field(metadata=metadata(1))
|
|
max_antenna_paths_supported: int = field(metadata=metadata(1))
|
|
roles_supported: int = field(metadata=metadata(1))
|
|
modes_supported: int = field(metadata=metadata(1))
|
|
rtt_capability: int = field(metadata=metadata(1))
|
|
rtt_aa_only_n: int = field(metadata=metadata(1))
|
|
rtt_sounding_n: int = field(metadata=metadata(1))
|
|
rtt_random_sequence_n: int = field(metadata=metadata(1))
|
|
nadm_sounding_capability: int = field(metadata=metadata(2))
|
|
nadm_random_capability: int = field(metadata=metadata(2))
|
|
cs_sync_phys_supported: int = field(metadata=metadata(CS_SYNC_PHY_SUPPORTED_SPEC))
|
|
subfeatures_supported: int = field(metadata=metadata(2))
|
|
t_ip1_times_supported: int = field(metadata=metadata(2))
|
|
t_ip2_times_supported: int = field(metadata=metadata(2))
|
|
t_fcs_times_supported: int = field(metadata=metadata(2))
|
|
t_pm_times_supported: int = field(metadata=metadata(2))
|
|
t_sw_time_supported: int = field(metadata=metadata(1))
|
|
tx_snr_capability: int = field(metadata=metadata(CS_SNR_SPEC))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(
|
|
HCI_LE_CS_Read_Local_Supported_Capabilities_ReturnParameters
|
|
)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_CS_Read_Local_Supported_Capabilities_Command(
|
|
HCI_SyncCommand[HCI_LE_CS_Read_Local_Supported_Capabilities_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.130 LE CS Read Local Supported Capabilities command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_LE_CS_Read_Remote_Supported_Capabilities_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.8.131 LE CS Read Remote Supported Capabilities command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndConnectionHandleReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_CS_Write_Cached_Remote_Supported_Capabilities_Command(
|
|
HCI_SyncCommand[HCI_StatusAndConnectionHandleReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.132 LE CS Write Cached Remote Supported Capabilities command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
num_config_supported: int = field(metadata=metadata(1))
|
|
max_consecutive_procedures_supported: int = field(metadata=metadata(2))
|
|
num_antennas_supported: int = field(metadata=metadata(1))
|
|
max_antenna_paths_supported: int = field(metadata=metadata(1))
|
|
roles_supported: int = field(metadata=metadata(1))
|
|
modes_supported: int = field(metadata=metadata(1))
|
|
rtt_capability: int = field(metadata=metadata(1))
|
|
rtt_aa_only_n: int = field(metadata=metadata(1))
|
|
rtt_sounding_n: int = field(metadata=metadata(1))
|
|
rtt_random_sequence_n: int = field(metadata=metadata(1))
|
|
nadm_sounding_capability: int = field(metadata=metadata(2))
|
|
nadm_random_capability: int = field(metadata=metadata(2))
|
|
cs_sync_phys_supported: int = field(metadata=metadata(CS_SYNC_PHY_SUPPORTED_SPEC))
|
|
subfeatures_supported: int = field(metadata=metadata(2))
|
|
t_ip1_times_supported: int = field(metadata=metadata(2))
|
|
t_ip2_times_supported: int = field(metadata=metadata(2))
|
|
t_fcs_times_supported: int = field(metadata=metadata(2))
|
|
t_pm_times_supported: int = field(metadata=metadata(2))
|
|
t_sw_time_supported: int = field(metadata=metadata(1))
|
|
tx_snr_capability: int = field(metadata=metadata(CS_SNR_SPEC))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_LE_CS_Security_Enable_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.8.133 LE CS Security Enable command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndConnectionHandleReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_CS_Set_Default_Settings_Command(
|
|
HCI_SyncCommand[HCI_StatusAndConnectionHandleReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.134 LE CS Security Enable command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
role_enable: int = field(metadata=metadata(CS_ROLE_MASK_SPEC))
|
|
cs_sync_antenna_selection: int = field(metadata=metadata(1))
|
|
max_tx_power: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_LE_CS_Read_Remote_FAE_Table_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.8.135 LE CS Read Remote FAE Table command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndConnectionHandleReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_CS_Write_Cached_Remote_FAE_Table_Command(
|
|
HCI_SyncCommand[HCI_StatusAndConnectionHandleReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.136 LE CS Write Cached Remote FAE Table command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
remote_fae_table: bytes = field(metadata=metadata(72))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_LE_CS_Create_Config_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.8.137 LE CS Create Config command
|
|
'''
|
|
|
|
class ChannelSelectionType(SpecableEnum):
|
|
ALGO_3B = 0
|
|
ALGO_3C = 1
|
|
|
|
class Ch3cShape(SpecableEnum):
|
|
HAT = 0x00
|
|
X = 0x01
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
config_id: int = field(metadata=metadata(1))
|
|
create_context: int = field(metadata=metadata(1))
|
|
main_mode_type: int = field(metadata=metadata(1))
|
|
sub_mode_type: int = field(metadata=metadata(1))
|
|
min_main_mode_steps: int = field(metadata=metadata(1))
|
|
max_main_mode_steps: int = field(metadata=metadata(1))
|
|
main_mode_repetition: int = field(metadata=metadata(1))
|
|
mode_0_steps: int = field(metadata=metadata(1))
|
|
role: int = field(metadata=metadata(CS_ROLE_SPEC))
|
|
rtt_type: int = field(metadata=metadata(RTT_TYPE_SPEC))
|
|
cs_sync_phy: int = field(metadata=metadata(CS_SYNC_PHY_SPEC))
|
|
channel_map: bytes = field(metadata=metadata(10))
|
|
channel_map_repetition: int = field(metadata=metadata(1))
|
|
channel_selection_type: int = field(metadata=ChannelSelectionType.type_metadata(1))
|
|
ch3c_shape: int = field(metadata=Ch3cShape.type_metadata(1))
|
|
ch3c_jump: int = field(metadata=metadata(1))
|
|
reserved: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_LE_CS_Remove_Config_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.8.138 LE CS Remove Config command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
config_id: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_CS_Set_Channel_Classification_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.139 LE CS Set Channel Classification command
|
|
'''
|
|
|
|
channel_classification: bytes = field(metadata=metadata(10))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusAndConnectionHandleReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_CS_Set_Procedure_Parameters_Command(
|
|
HCI_SyncCommand[HCI_StatusAndConnectionHandleReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.140 LE CS Set Procedure Parameters command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
config_id: int = field(metadata=metadata(1))
|
|
max_procedure_len: int = field(metadata=metadata(2))
|
|
min_procedure_interval: int = field(metadata=metadata(2))
|
|
max_procedure_interval: int = field(metadata=metadata(2))
|
|
max_procedure_count: int = field(metadata=metadata(2))
|
|
min_subevent_len: int = field(metadata=metadata(3))
|
|
max_subevent_len: int = field(metadata=metadata(3))
|
|
tone_antenna_config_selection: int = field(metadata=metadata(1))
|
|
phy: int = field(metadata=metadata(1))
|
|
tx_power_delta: int = field(metadata=metadata(1))
|
|
preferred_peer_antenna: int = field(metadata=metadata(1))
|
|
snr_control_initiator: int = field(metadata=metadata(CS_SNR_SPEC))
|
|
snr_control_reflector: int = field(metadata=metadata(CS_SNR_SPEC))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_LE_CS_Procedure_Enable_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.8.141 LE CS Procedure Enable command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
config_id: int = field(metadata=metadata(1))
|
|
enable: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_CS_Test_Command(HCI_SyncCommand[HCI_StatusReturnParameters]):
|
|
'''
|
|
See Bluetooth spec @ 7.8.142 LE CS Test command
|
|
'''
|
|
|
|
main_mode_type: int = field(metadata=metadata(1))
|
|
sub_mode_type: int = field(metadata=metadata(1))
|
|
main_mode_repetition: int = field(metadata=metadata(1))
|
|
mode_0_steps: int = field(metadata=metadata(1))
|
|
role: int = field(metadata=metadata(CS_ROLE_SPEC))
|
|
rtt_type: int = field(metadata=metadata(RTT_TYPE_SPEC))
|
|
cs_sync_phy: int = field(metadata=metadata(CS_SYNC_PHY_SPEC))
|
|
cs_sync_antenna_selection: int = field(metadata=metadata(1))
|
|
subevent_len: int = field(metadata=metadata(3))
|
|
subevent_interval: int = field(metadata=metadata(2))
|
|
max_num_subevents: int = field(metadata=metadata(1))
|
|
transmit_power_level: int = field(metadata=metadata(1))
|
|
t_ip1_time: int = field(metadata=metadata(1))
|
|
t_ip2_time: int = field(metadata=metadata(1))
|
|
t_fcs_time: int = field(metadata=metadata(1))
|
|
t_pm_time: int = field(metadata=metadata(1))
|
|
t_sw_time: int = field(metadata=metadata(1))
|
|
tone_antenna_config_selection: int = field(metadata=metadata(1))
|
|
reserved: int = field(metadata=metadata(1))
|
|
snr_control_initiator: int = field(metadata=metadata(CS_SNR_SPEC))
|
|
snr_control_reflector: int = field(metadata=metadata(CS_SNR_SPEC))
|
|
drbg_nonce: int = field(metadata=metadata(2))
|
|
channel_map_repetition: int = field(metadata=metadata(1))
|
|
override_config: int = field(metadata=metadata(2))
|
|
override_parameters_data: bytes = field(metadata=metadata("v"))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_LE_CS_Test_End_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.8.143 LE CS Test End command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Frame_Space_Update_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.8.151 LE Frame Space Update command
|
|
'''
|
|
|
|
class SpacingType(SpecableFlag):
|
|
T_IFS_ACL_CP = 1 << 0
|
|
T_IFS_ACL_PC = 1 << 1
|
|
T_MCES = 1 << 2
|
|
T_IFS_CIS = 1 << 3
|
|
T_MSS_CIS = 1 << 4
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
frame_space_min: int = field(metadata=metadata(2))
|
|
frame_space_max: int = field(metadata=metadata(2))
|
|
phys: int = field(metadata=PhyBit.type_metadata(1))
|
|
spacing_types: int = field(metadata=SpacingType.type_metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Command.command
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Connection_Rate_Request_Command(HCI_AsyncCommand):
|
|
'''
|
|
See Bluetooth spec @ 7.8.154 LE Connection Rate Request command
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
connection_interval_min: int = field(metadata=metadata(2))
|
|
connection_interval_max: int = field(metadata=metadata(2))
|
|
subrate_min: int = field(metadata=metadata(2))
|
|
subrate_max: int = field(metadata=metadata(2))
|
|
max_latency: int = field(metadata=metadata(2))
|
|
continuation_number: int = field(metadata=metadata(2))
|
|
supervision_timeout: int = field(metadata=metadata(2))
|
|
min_ce_length: int = field(metadata=metadata(2))
|
|
max_ce_length: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_SyncCommand.sync_command(HCI_StatusReturnParameters)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Set_Default_Rate_Parameters_Command(
|
|
HCI_SyncCommand[HCI_StatusReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.155 LE Set Default Rate Parameters command
|
|
'''
|
|
|
|
connection_interval_min: int = field(metadata=metadata(2))
|
|
connection_interval_max: int = field(metadata=metadata(2))
|
|
subrate_min: int = field(metadata=metadata(2))
|
|
subrate_max: int = field(metadata=metadata(2))
|
|
max_latency: int = field(metadata=metadata(2))
|
|
continuation_number: int = field(metadata=metadata(2))
|
|
supervision_timeout: int = field(metadata=metadata(2))
|
|
min_ce_length: int = field(metadata=metadata(2))
|
|
max_ce_length: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Minimum_Supported_Connection_Interval_ReturnParameters(
|
|
HCI_StatusReturnParameters
|
|
):
|
|
minimum_supported_connection_interval: int = field(metadata=metadata(1))
|
|
group_min: Sequence[int] = field(metadata=metadata(2, list_begin=True))
|
|
group_max: Sequence[int] = field(metadata=metadata(2))
|
|
group_stride: Sequence[int] = field(metadata=metadata(2, list_end=True))
|
|
|
|
|
|
@HCI_SyncCommand.sync_command(
|
|
HCI_LE_Read_Minimum_Supported_Connection_Interval_ReturnParameters
|
|
)
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Minimum_Supported_Connection_Interval_Command(
|
|
HCI_SyncCommand[HCI_LE_Read_Minimum_Supported_Connection_Interval_ReturnParameters]
|
|
):
|
|
'''
|
|
See Bluetooth spec @ 7.8.156 LE Read Minimum Supported Connection Interval command
|
|
'''
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# HCI Events
|
|
# -----------------------------------------------------------------------------
|
|
class HCI_Event(HCI_Packet):
|
|
'''
|
|
See Bluetooth spec @ Vol 2, Part E - 5.4.4 HCI Event Packet
|
|
'''
|
|
|
|
hci_packet_type = HCI_EVENT_PACKET
|
|
event_names: dict[int, str] = {}
|
|
event_classes: dict[int, type[HCI_Event]] = {}
|
|
vendor_factories: list[Callable[[bytes], HCI_Event | None]] = []
|
|
event_code: int
|
|
fields: Fields = ()
|
|
_parameters: bytes = b''
|
|
|
|
_Event = TypeVar("_Event", bound="HCI_Event")
|
|
|
|
@classmethod
|
|
def event(cls, subclass: type[_Event]) -> type[_Event]:
|
|
'''
|
|
Decorator used to declare and register subclasses
|
|
'''
|
|
# Subclasses may set parameters as ClassVar, or inferred from class name.
|
|
if not hasattr(subclass, 'name'):
|
|
subclass.name = subclass.__name__.upper()
|
|
if not hasattr(subclass, 'event_code'):
|
|
event_code = key_with_value(subclass.event_names, subclass.name)
|
|
if event_code is None:
|
|
raise KeyError(f'event {subclass.name} not found in event_names')
|
|
subclass.event_code = event_code
|
|
|
|
if dataclasses.is_dataclass(subclass):
|
|
subclass.fields = HCI_Object.fields_from_dataclass(subclass)
|
|
|
|
# Register a factory for this class
|
|
cls.event_classes[subclass.event_code] = subclass
|
|
return subclass
|
|
|
|
@staticmethod
|
|
def event_map(symbols: dict[str, Any]) -> dict[int, str]:
|
|
return {
|
|
event_code: event_name
|
|
for (event_name, event_code) in symbols.items()
|
|
if event_name.startswith('HCI_')
|
|
and not event_name.startswith('HCI_LE_')
|
|
and event_name.endswith('_EVENT')
|
|
}
|
|
|
|
@classmethod
|
|
def event_name(cls, event_code: int) -> str:
|
|
if (subclass := cls.event_classes.get(event_code)) and subclass.name:
|
|
return subclass.name
|
|
return name_or_number(cls.event_names, event_code)
|
|
|
|
@staticmethod
|
|
def register_events(symbols: dict[str, Any]) -> None:
|
|
HCI_Event.event_names.update(HCI_Event.event_map(symbols))
|
|
|
|
@staticmethod
|
|
def registered(event_class):
|
|
event_class.name = event_class.__name__.upper()
|
|
event_class.event_code = key_with_value(HCI_Event.event_names, event_class.name)
|
|
if event_class.event_code is None:
|
|
raise KeyError(f'event {event_class.name} not found in event_names')
|
|
|
|
# Register a factory for this class
|
|
HCI_Event.event_classes[event_class.event_code] = event_class
|
|
|
|
return event_class
|
|
|
|
@classmethod
|
|
def add_vendor_factory(cls, factory: Callable[[bytes], HCI_Event | None]) -> None:
|
|
cls.vendor_factories.append(factory)
|
|
|
|
@classmethod
|
|
def remove_vendor_factory(
|
|
cls, factory: Callable[[bytes], HCI_Event | None]
|
|
) -> None:
|
|
if factory in cls.vendor_factories:
|
|
cls.vendor_factories.remove(factory)
|
|
|
|
@classmethod
|
|
def from_bytes(cls, packet: bytes) -> HCI_Event:
|
|
event_code = packet[1]
|
|
parameters_length = packet[2]
|
|
if len(packet) < 3 + parameters_length:
|
|
raise InvalidPacketError(
|
|
f'invalid parameters length (packet={packet.hex()}): '
|
|
f'expected {parameters_length}, got {len(packet) - 3})'
|
|
)
|
|
if len(packet) > 3 + parameters_length:
|
|
logger.warning(
|
|
f'truncating parameters (packet={packet.hex()}): '
|
|
f'from {len(packet) - 3} to {parameters_length}'
|
|
)
|
|
|
|
parameters = packet[3 : 3 + parameters_length]
|
|
|
|
subclass: type[HCI_Event] | None
|
|
if event_code == HCI_LE_META_EVENT:
|
|
# We do this dispatch here and not in the subclass in order to avoid call
|
|
# loops
|
|
subevent_code = parameters[0]
|
|
subclass = HCI_LE_Meta_Event.subevent_classes.get(subevent_code)
|
|
if subclass is None:
|
|
# No class registered, just use a generic class instance
|
|
return HCI_LE_Meta_Event(
|
|
subevent_code=subevent_code, parameters=parameters
|
|
)
|
|
elif event_code == HCI_VENDOR_EVENT:
|
|
# Invoke all the registered factories to see if any of them can handle
|
|
# the event
|
|
for vendor_factory in cls.vendor_factories:
|
|
if event := vendor_factory(parameters):
|
|
return event
|
|
|
|
# No factory, or the factory could not create an instance,
|
|
# return a generic vendor event
|
|
return HCI_Vendor_Event(data=parameters)
|
|
else:
|
|
subclass = HCI_Event.event_classes.get(event_code)
|
|
if subclass is None:
|
|
# No class registered, just use a generic class instance
|
|
return HCI_Event(event_code=event_code, parameters=parameters)
|
|
|
|
# Invoke the factory to create a new instance
|
|
return subclass.from_parameters(parameters)
|
|
|
|
@classmethod
|
|
def from_parameters(cls, parameters: bytes) -> Self:
|
|
event = cls(**HCI_Object.dict_from_bytes(parameters, 0, cls.fields))
|
|
event.parameters = parameters
|
|
return event
|
|
|
|
def __init__(
|
|
self,
|
|
parameters: bytes | None = None,
|
|
*,
|
|
event_code: int | None = None,
|
|
**kwargs,
|
|
):
|
|
if event_code is not None:
|
|
self.event_code = event_code
|
|
super().__init__(HCI_Event.event_name(self.event_code))
|
|
if self.fields and kwargs:
|
|
HCI_Object.init_from_fields(self, self.fields, kwargs)
|
|
if parameters is None:
|
|
parameters = HCI_Object.dict_to_bytes(kwargs, self.fields)
|
|
self.parameters = parameters or b''
|
|
|
|
@property
|
|
def parameters(self) -> bytes:
|
|
if not self._parameters:
|
|
self._parameters = HCI_Object.dict_to_bytes(self.__dict__, self.fields)
|
|
return self._parameters
|
|
|
|
@parameters.setter
|
|
def parameters(self, parameters: bytes):
|
|
self._parameters = parameters
|
|
|
|
def __bytes__(self) -> bytes:
|
|
parameters = self.parameters
|
|
return bytes([HCI_EVENT_PACKET, self.event_code, len(parameters)]) + parameters
|
|
|
|
def __str__(self):
|
|
result = color(self.name, 'magenta')
|
|
if self.fields:
|
|
result += ':\n' + HCI_Object.format_fields(self.__dict__, self.fields, ' ')
|
|
else:
|
|
if self.parameters:
|
|
result += f': {self.parameters.hex()}'
|
|
return result
|
|
|
|
|
|
HCI_Event.register_events(globals())
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
class HCI_Extended_Event(HCI_Event):
|
|
'''
|
|
HCI_Event subclass for events that have a subevent code.
|
|
'''
|
|
|
|
subevent_names: dict[int, str] = {}
|
|
subevent_classes: dict[int, type[HCI_Extended_Event]] = {}
|
|
subevent_code: int
|
|
_parameters: bytes = b''
|
|
|
|
_ExtendedEvent = TypeVar("_ExtendedEvent", bound="HCI_Extended_Event")
|
|
|
|
# TODO: Remove type ignore after migrating HCI_Event.
|
|
@classmethod
|
|
def event(cls, subclass: type[_ExtendedEvent]) -> type[_ExtendedEvent]: # type: ignore[override]
|
|
'''
|
|
Decorator used to declare and register subclasses
|
|
'''
|
|
# Subclasses may set parameters as ClassVar, or inferred from class name.
|
|
if not hasattr(subclass, 'name'):
|
|
subclass.name = subclass.__name__.upper()
|
|
if not hasattr(subclass, 'subevent_code'):
|
|
subevent_code = key_with_value(subclass.subevent_names, subclass.name)
|
|
if subevent_code is None:
|
|
raise KeyError(f'subevent {subclass.name} not found in subevent_names')
|
|
subclass.subevent_code = subevent_code
|
|
|
|
if dataclasses.is_dataclass(subclass):
|
|
subclass.fields = HCI_Object.fields_from_dataclass(subclass)
|
|
|
|
# Register a factory for this class
|
|
cls.subevent_classes[subclass.subevent_code] = subclass
|
|
|
|
return subclass
|
|
|
|
@property
|
|
def parameters(self) -> bytes:
|
|
if not self._parameters:
|
|
self._parameters = bytes([self.subevent_code]) + HCI_Object.dict_to_bytes(
|
|
self.__dict__, self.fields
|
|
)
|
|
return self._parameters
|
|
|
|
@parameters.setter
|
|
def parameters(self, parameters: bytes):
|
|
self._parameters = parameters
|
|
|
|
@classmethod
|
|
def subevent_name(cls, subevent_code: int) -> str:
|
|
if subevent_name := cls.subevent_names.get(subevent_code):
|
|
return subevent_name
|
|
if (subclass := cls.subevent_classes.get(subevent_code)) and subclass.name:
|
|
return subclass.name
|
|
|
|
return f'{cls.__name__.upper()}[0x{subevent_code:02X}]'
|
|
|
|
@staticmethod
|
|
def subevent_map(symbols: dict[str, Any]) -> dict[int, str]:
|
|
return {
|
|
subevent_code: subevent_name
|
|
for (subevent_name, subevent_code) in symbols.items()
|
|
if subevent_name.startswith('HCI_') and subevent_name.endswith('_EVENT')
|
|
}
|
|
|
|
@classmethod
|
|
def register_subevents(cls, symbols: dict[str, Any]) -> None:
|
|
cls.subevent_names.update(cls.subevent_map(symbols))
|
|
|
|
@classmethod
|
|
def subclass_from_parameters(cls, parameters: bytes) -> HCI_Extended_Event | None:
|
|
"""
|
|
Factory method that parses the subevent code, finds a registered subclass,
|
|
and creates an instance if found.
|
|
"""
|
|
subevent_code = parameters[0]
|
|
if subclass := cls.subevent_classes.get(subevent_code):
|
|
return subclass.from_parameters(parameters)
|
|
|
|
return None
|
|
|
|
@classmethod
|
|
def from_parameters(cls, parameters: bytes) -> Self:
|
|
"""Factory method for subclasses (the subevent code has already been parsed)"""
|
|
event = cls(**HCI_Object.dict_from_bytes(parameters, 1, cls.fields))
|
|
event.parameters = parameters
|
|
return event
|
|
|
|
def __init__(
|
|
self,
|
|
parameters: bytes | None = None,
|
|
*,
|
|
subevent_code: int | None = None,
|
|
**kwargs,
|
|
) -> None:
|
|
if subevent_code is not None:
|
|
self.subevent_code = subevent_code
|
|
if parameters is None and self.fields and kwargs:
|
|
parameters = bytes([self.subevent_code]) + HCI_Object.dict_to_bytes(
|
|
kwargs, self.fields
|
|
)
|
|
super().__init__(parameters, **kwargs)
|
|
|
|
# Override the name in order to adopt the subevent name instead
|
|
self.name = self.subevent_name(self.subevent_code)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
class HCI_LE_Meta_Event(HCI_Extended_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65 LE Meta Event
|
|
'''
|
|
|
|
event_code: int = HCI_LE_META_EVENT
|
|
subevent_classes = {}
|
|
|
|
@staticmethod
|
|
def subevent_map(symbols: dict[str, Any]) -> dict[int, str]:
|
|
return {
|
|
subevent_code: subevent_name
|
|
for (subevent_name, subevent_code) in symbols.items()
|
|
if subevent_name.startswith('HCI_LE_') and subevent_name.endswith('_EVENT')
|
|
}
|
|
|
|
|
|
HCI_LE_Meta_Event.register_subevents(globals())
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Connection_Complete_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.1 LE Connection Complete Event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
role: int = field(metadata=Role.type_metadata(1))
|
|
peer_address_type: int = field(metadata=AddressType.type_metadata(1))
|
|
peer_address: Address = field(
|
|
metadata=metadata(Address.parse_address_preceded_by_type)
|
|
)
|
|
connection_interval: int = field(metadata=metadata(2))
|
|
peripheral_latency: int = field(metadata=metadata(2))
|
|
supervision_timeout: int = field(metadata=metadata(2))
|
|
central_clock_accuracy: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Advertising_Report_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.2 LE Advertising Report Event
|
|
'''
|
|
|
|
class EventType(SpecableEnum):
|
|
ADV_IND = 0x00
|
|
ADV_DIRECT_IND = 0x01
|
|
ADV_SCAN_IND = 0x02
|
|
ADV_NONCONN_IND = 0x03
|
|
SCAN_RSP = 0x04
|
|
|
|
@dataclasses.dataclass
|
|
class Report(HCI_Dataclass_Object):
|
|
event_type: int = field(
|
|
metadata=metadata(
|
|
{
|
|
'size': 1,
|
|
'mapper': lambda x: HCI_LE_Advertising_Report_Event.EventType(
|
|
x
|
|
).name,
|
|
}
|
|
)
|
|
)
|
|
address_type: int = field(metadata=metadata(Address.ADDRESS_TYPE_SPEC))
|
|
address: Address = field(
|
|
metadata=metadata(Address.parse_address_preceded_by_type)
|
|
)
|
|
data: bytes = field(metadata=metadata('v'))
|
|
rssi: int = field(metadata=metadata(-1))
|
|
|
|
reports: Sequence[Report] = field(
|
|
metadata=metadata(Report.parse_from_bytes, list_begin=True, list_end=True)
|
|
)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Connection_Update_Complete_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.3 LE Connection Update Complete Event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
connection_interval: int = field(metadata=metadata(2))
|
|
peripheral_latency: int = field(metadata=metadata(2))
|
|
supervision_timeout: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Read_Remote_Features_Complete_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.4 LE Read Remote Features Complete Event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
le_features: bytes = field(metadata=metadata(8))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Long_Term_Key_Request_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.5 LE Long Term Key Request Event
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
random_number: bytes = field(metadata=metadata(8))
|
|
encryption_diversifier: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Remote_Connection_Parameter_Request_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.6 LE Remote Connection Parameter Request Event
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
interval_min: int = field(metadata=metadata(2))
|
|
interval_max: int = field(metadata=metadata(2))
|
|
max_latency: int = field(metadata=metadata(2))
|
|
timeout: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Data_Length_Change_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.7 LE Data Length Change Event
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
max_tx_octets: int = field(metadata=metadata(2))
|
|
max_tx_time: int = field(metadata=metadata(2))
|
|
max_rx_octets: int = field(metadata=metadata(2))
|
|
max_rx_time: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Enhanced_Connection_Complete_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.10 LE Enhanced Connection Complete Event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
role: int = field(metadata=Role.type_metadata(1))
|
|
peer_address_type: int = field(metadata=AddressType.type_metadata(1))
|
|
peer_address: Address = field(
|
|
metadata=metadata(Address.parse_address_preceded_by_type)
|
|
)
|
|
local_resolvable_private_address: Address = field(
|
|
metadata=metadata(Address.parse_random_address)
|
|
)
|
|
peer_resolvable_private_address: Address = field(
|
|
metadata=metadata(Address.parse_random_address)
|
|
)
|
|
connection_interval: int = field(metadata=metadata(2))
|
|
peripheral_latency: int = field(metadata=metadata(2))
|
|
supervision_timeout: int = field(metadata=metadata(2))
|
|
central_clock_accuracy: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Enhanced_Connection_Complete_V2_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.10 LE Enhanced Connection Complete Event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
role: int = field(metadata=Role.type_metadata(1))
|
|
peer_address_type: int = field(metadata=AddressType.type_metadata(1))
|
|
peer_address: Address = field(
|
|
metadata=metadata(Address.parse_address_preceded_by_type)
|
|
)
|
|
local_resolvable_private_address: Address = field(
|
|
metadata=metadata(Address.parse_random_address)
|
|
)
|
|
peer_resolvable_private_address: Address = field(
|
|
metadata=metadata(Address.parse_random_address)
|
|
)
|
|
connection_interval: int = field(metadata=metadata(2))
|
|
peripheral_latency: int = field(metadata=metadata(2))
|
|
supervision_timeout: int = field(metadata=metadata(2))
|
|
central_clock_accuracy: int = field(metadata=metadata(1))
|
|
advertising_handle: int = field(metadata=metadata(1))
|
|
sync_handle: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_PHY_Update_Complete_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.12 LE PHY Update Complete Event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
tx_phy: int = field(metadata=Phy.type_metadata(1))
|
|
rx_phy: int = field(metadata=Phy.type_metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Extended_Advertising_Report_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.13 LE Extended Advertising Report Event
|
|
'''
|
|
|
|
class EventType(enum.IntFlag):
|
|
CONNECTABLE_ADVERTISING = 1 << 0
|
|
SCANNABLE_ADVERTISING = 1 << 1
|
|
DIRECTED_ADVERTISING = 1 << 2
|
|
SCAN_RESPONSE = 1 << 3
|
|
LEGACY_ADVERTISING_PDU_USED = 1 << 4
|
|
|
|
DATA_COMPLETE = 0x00
|
|
DATA_INCOMPLETE_MORE_TO_COME = 0x01
|
|
DATA_INCOMPLETE_TRUNCATED_NO_MORE_TO_COME = 0x02
|
|
|
|
LEGACY_PDU_TYPE_MAP = {
|
|
0b0011: HCI_LE_Advertising_Report_Event.EventType.ADV_IND,
|
|
0b0101: HCI_LE_Advertising_Report_Event.EventType.ADV_DIRECT_IND,
|
|
0b0010: HCI_LE_Advertising_Report_Event.EventType.ADV_SCAN_IND,
|
|
0b0000: HCI_LE_Advertising_Report_Event.EventType.ADV_NONCONN_IND,
|
|
0b1011: HCI_LE_Advertising_Report_Event.EventType.SCAN_RSP,
|
|
0b1010: HCI_LE_Advertising_Report_Event.EventType.SCAN_RSP,
|
|
}
|
|
|
|
NO_ADI_FIELD_PROVIDED = 0xFF
|
|
TX_POWER_INFORMATION_NOT_AVAILABLE = 0x7F
|
|
RSSI_NOT_AVAILABLE = 0x7F
|
|
ANONYMOUS_ADDRESS_TYPE = 0xFF
|
|
UNRESOLVED_RESOLVABLE_ADDRESS_TYPE = 0xFE
|
|
|
|
@dataclasses.dataclass
|
|
class Report(HCI_Dataclass_Object):
|
|
event_type: int = field(
|
|
metadata=metadata(
|
|
{
|
|
'size': 2,
|
|
'mapper': lambda x: HCI_LE_Extended_Advertising_Report_Event.EventType(
|
|
x
|
|
).name,
|
|
}
|
|
)
|
|
)
|
|
address_type: int = field(metadata=metadata(Address.ADDRESS_TYPE_SPEC))
|
|
address: Address = field(
|
|
metadata=metadata(Address.parse_address_preceded_by_type)
|
|
)
|
|
primary_phy: int = field(metadata=metadata(Phy.type_spec(1)))
|
|
secondary_phy: int = field(metadata=metadata(Phy.type_spec(1)))
|
|
advertising_sid: int = field(metadata=metadata(1))
|
|
tx_power: int = field(metadata=metadata(1))
|
|
rssi: int = field(metadata=metadata(-1))
|
|
periodic_advertising_interval: int = field(metadata=metadata(2))
|
|
direct_address_type: int = field(metadata=metadata(Address.ADDRESS_TYPE_SPEC))
|
|
direct_address: Address = field(
|
|
metadata=metadata(Address.parse_address_preceded_by_type)
|
|
)
|
|
data: bytes = field(metadata=metadata('v'))
|
|
|
|
reports: Sequence[Report] = field(
|
|
metadata=metadata(Report.parse_from_bytes, list_begin=True, list_end=True)
|
|
)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Periodic_Advertising_Sync_Established_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.14 LE Periodic Advertising Sync Established Event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
sync_handle: int = field(metadata=metadata(2))
|
|
advertising_sid: int = field(metadata=metadata(1))
|
|
advertiser_address_type: int = field(metadata=AddressType.type_metadata(1))
|
|
advertiser_address: Address = field(
|
|
metadata=metadata(Address.parse_address_preceded_by_type)
|
|
)
|
|
advertiser_phy: int = field(metadata=Phy.type_metadata(1))
|
|
periodic_advertising_interval: int = field(metadata=metadata(2))
|
|
advertiser_clock_accuracy: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Periodic_Advertising_Sync_Established_V2_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.14 LE Periodic Advertising Sync Established Event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
sync_handle: int = field(metadata=metadata(2))
|
|
advertising_sid: int = field(metadata=metadata(1))
|
|
advertiser_address_type: int = field(metadata=AddressType.type_metadata(1))
|
|
advertiser_address: Address = field(
|
|
metadata=metadata(Address.parse_address_preceded_by_type)
|
|
)
|
|
advertiser_phy: int = field(metadata=Phy.type_metadata(1))
|
|
periodic_advertising_interval: int = field(metadata=metadata(2))
|
|
advertiser_clock_accuracy: int = field(metadata=metadata(1))
|
|
num_subevents: int = field(metadata=metadata(1))
|
|
subevent_interval: int = field(metadata=metadata(1))
|
|
response_slot_delay: int = field(metadata=metadata(1))
|
|
response_slot_spacing: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Periodic_Advertising_Report_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.15 LE Periodic Advertising Report Event
|
|
'''
|
|
|
|
class DataStatus(SpecableEnum):
|
|
DATA_COMPLETE = 0x00
|
|
DATA_INCOMPLETE_MORE_TO_COME = 0x01
|
|
DATA_INCOMPLETE_TRUNCATED_NO_MORE_TO_COME = 0x02
|
|
|
|
TX_POWER_INFORMATION_NOT_AVAILABLE = 0x7F
|
|
RSSI_NOT_AVAILABLE = 0x7F
|
|
|
|
sync_handle: int = field(metadata=metadata(2))
|
|
tx_power: int = field(metadata=metadata(-1))
|
|
rssi: int = field(metadata=metadata(-1))
|
|
cte_type: int = field(metadata=CteType.type_metadata(1))
|
|
data_status: int = field(metadata=DataStatus.type_metadata(1))
|
|
data: bytes = field(metadata=metadata("v"))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Periodic_Advertising_Report_V2_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.15 LE Periodic Advertising Report Event
|
|
'''
|
|
|
|
sync_handle: int = field(metadata=metadata(2))
|
|
tx_power: int = field(metadata=metadata(-1))
|
|
rssi: int = field(metadata=metadata(-1))
|
|
cte_type: int = field(metadata=CteType.type_metadata(1))
|
|
periodic_event_counter: int = field(metadata=metadata(2))
|
|
subevent: int = field(metadata=metadata(1))
|
|
data_status: int = field(metadata=CteType.type_metadata(1))
|
|
data: bytes = field(metadata=metadata("v"))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Periodic_Advertising_Sync_Lost_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.16 LE Periodic Advertising Sync Lost Event
|
|
'''
|
|
|
|
sync_handle: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Advertising_Set_Terminated_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.18 LE Advertising Set Terminated Event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
advertising_handle: int = field(metadata=metadata(1))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
num_completed_extended_advertising_events: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Channel_Selection_Algorithm_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.20 LE Channel Selection Algorithm Event
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
channel_selection_algorithm: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Periodic_Advertising_Sync_Transfer_Received_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.24 LE Periodic Advertising Sync Transfer Received Event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
service_data: int = field(metadata=metadata(2))
|
|
sync_handle: int = field(metadata=metadata(2))
|
|
advertising_sid: int = field(metadata=metadata(1))
|
|
advertiser_address_type: int = field(metadata=AddressType.type_metadata(1))
|
|
advertiser_address: Address = field(
|
|
metadata=metadata(Address.parse_address_preceded_by_type)
|
|
)
|
|
advertiser_phy: int = field(metadata=metadata(1))
|
|
periodic_advertising_interval: int = field(metadata=metadata(2))
|
|
advertiser_clock_accuracy: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Periodic_Advertising_Sync_Transfer_Received_V2_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.24 LE Periodic Advertising Sync Transfer Received Event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
service_data: int = field(metadata=metadata(2))
|
|
sync_handle: int = field(metadata=metadata(2))
|
|
advertising_sid: int = field(metadata=metadata(1))
|
|
advertiser_address_type: int = field(metadata=AddressType.type_metadata(1))
|
|
advertiser_address: Address = field(
|
|
metadata=metadata(Address.parse_address_preceded_by_type)
|
|
)
|
|
advertiser_phy: int = field(metadata=metadata(1))
|
|
periodic_advertising_interval: int = field(metadata=metadata(2))
|
|
advertiser_clock_accuracy: int = field(metadata=metadata(1))
|
|
num_subevents: int = field(metadata=metadata(1))
|
|
subevent_interval: int = field(metadata=metadata(1))
|
|
response_slot_delay: int = field(metadata=metadata(1))
|
|
response_slot_spacing: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_CIS_Established_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.25 LE CIS Established Event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
cig_sync_delay: int = field(metadata=metadata(3))
|
|
cis_sync_delay: int = field(metadata=metadata(3))
|
|
transport_latency_c_to_p: int = field(metadata=metadata(3))
|
|
transport_latency_p_to_c: int = field(metadata=metadata(3))
|
|
phy_c_to_p: int = field(metadata=metadata(1))
|
|
phy_p_to_c: int = field(metadata=metadata(1))
|
|
nse: int = field(metadata=metadata(1))
|
|
bn_c_to_p: int = field(metadata=metadata(1))
|
|
bn_p_to_c: int = field(metadata=metadata(1))
|
|
ft_c_to_p: int = field(metadata=metadata(1))
|
|
ft_p_to_c: int = field(metadata=metadata(1))
|
|
max_pdu_c_to_p: int = field(metadata=metadata(2))
|
|
max_pdu_p_to_c: int = field(metadata=metadata(2))
|
|
iso_interval: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_CIS_Request_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.26 LE CIS Request Event
|
|
'''
|
|
|
|
acl_connection_handle: int = field(metadata=metadata(2))
|
|
cis_connection_handle: int = field(metadata=metadata(2))
|
|
cig_id: int = field(metadata=metadata(1))
|
|
cis_id: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Create_BIG_Complete_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.27 LE Create BIG Complete Event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
big_handle: int = field(metadata=metadata(1))
|
|
big_sync_delay: int = field(metadata=metadata(3))
|
|
transport_latency_big: int = field(metadata=metadata(3))
|
|
phy: int = field(metadata=metadata(1))
|
|
nse: int = field(metadata=metadata(1))
|
|
bn: int = field(metadata=metadata(1))
|
|
pto: int = field(metadata=metadata(1))
|
|
irc: int = field(metadata=metadata(1))
|
|
max_pdu: int = field(metadata=metadata(2))
|
|
iso_interval: int = field(metadata=metadata(2))
|
|
connection_handle: Sequence[int] = field(
|
|
metadata=metadata(2, list_begin=True, list_end=True)
|
|
)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Terminate_BIG_Complete_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.28 LE Terminate BIG Complete Event
|
|
'''
|
|
|
|
big_handle: int = field(metadata=metadata(1))
|
|
reason: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_BIG_Sync_Established_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.29 LE BIG Sync Established event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
big_handle: int = field(metadata=metadata(1))
|
|
transport_latency_big: int = field(metadata=metadata(3))
|
|
nse: int = field(metadata=metadata(1))
|
|
bn: int = field(metadata=metadata(1))
|
|
pto: int = field(metadata=metadata(1))
|
|
irc: int = field(metadata=metadata(1))
|
|
max_pdu: int = field(metadata=metadata(2))
|
|
iso_interval: int = field(metadata=metadata(2))
|
|
connection_handle: Sequence[int] = field(
|
|
metadata=metadata(2, list_begin=True, list_end=True)
|
|
)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_BIG_Sync_Lost_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.30 LE BIG Sync Lost event
|
|
'''
|
|
|
|
big_handle: int = field(metadata=metadata(1))
|
|
reason: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_BIGInfo_Advertising_Report_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.34 LE BIGInfo Advertising Report Event
|
|
'''
|
|
|
|
sync_handle: int = field(metadata=metadata(2))
|
|
num_bis: int = field(metadata=metadata(1))
|
|
nse: int = field(metadata=metadata(1))
|
|
iso_interval: int = field(metadata=metadata(2))
|
|
bn: int = field(metadata=metadata(1))
|
|
pto: int = field(metadata=metadata(1))
|
|
irc: int = field(metadata=metadata(1))
|
|
max_pdu: int = field(metadata=metadata(2))
|
|
sdu_interval: int = field(metadata=metadata(3))
|
|
max_sdu: int = field(metadata=metadata(2))
|
|
phy: int = field(metadata=Phy.type_metadata(1))
|
|
framing: int = field(metadata=metadata(1))
|
|
encryption: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Subrate_Change_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.35 LE Subrate Change event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
subrate_factor: int = field(metadata=metadata(2))
|
|
peripheral_latency: int = field(metadata=metadata(2))
|
|
continuation_number: int = field(metadata=metadata(2))
|
|
supervision_timeout: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_CS_Read_Remote_Supported_Capabilities_Complete_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.39 LE CS Read Remote Supported Capabilities Complete event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
num_config_supported: int = field(metadata=metadata(1))
|
|
max_consecutive_procedures_supported: int = field(metadata=metadata(2))
|
|
num_antennas_supported: int = field(metadata=metadata(1))
|
|
max_antenna_paths_supported: int = field(metadata=metadata(1))
|
|
roles_supported: int = field(metadata=metadata(1))
|
|
modes_supported: int = field(metadata=metadata(1))
|
|
rtt_capability: int = field(metadata=metadata(1))
|
|
rtt_aa_only_n: int = field(metadata=metadata(1))
|
|
rtt_sounding_n: int = field(metadata=metadata(1))
|
|
rtt_random_sequence_n: int = field(metadata=metadata(1))
|
|
nadm_sounding_capability: int = field(metadata=metadata(2))
|
|
nadm_random_capability: int = field(metadata=metadata(2))
|
|
cs_sync_phys_supported: int = field(metadata=metadata(CS_SYNC_PHY_SUPPORTED_SPEC))
|
|
subfeatures_supported: int = field(metadata=metadata(2))
|
|
t_ip1_times_supported: int = field(metadata=metadata(2))
|
|
t_ip2_times_supported: int = field(metadata=metadata(2))
|
|
t_fcs_times_supported: int = field(metadata=metadata(2))
|
|
t_pm_times_supported: int = field(metadata=metadata(2))
|
|
t_sw_time_supported: int = field(metadata=metadata(1))
|
|
tx_snr_capability: int = field(metadata=metadata(CS_SNR_SPEC))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_CS_Read_Remote_FAE_Table_Complete_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.40 LE CS Read Remote FAE Table Complete event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
remote_fae_table: bytes = field(metadata=metadata(72))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_CS_Security_Enable_Complete_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.41 LE CS Security Enable Complete event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_CS_Config_Complete_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.42 LE CS Config Complete event
|
|
'''
|
|
|
|
class Action(SpecableEnum):
|
|
REMOVED = 0
|
|
CREATED = 1
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
config_id: int = field(metadata=metadata(1))
|
|
action: int = field(metadata=Action.type_metadata(1))
|
|
main_mode_type: int = field(metadata=metadata(1))
|
|
sub_mode_type: int = field(metadata=metadata(1))
|
|
min_main_mode_steps: int = field(metadata=metadata(1))
|
|
max_main_mode_steps: int = field(metadata=metadata(1))
|
|
main_mode_repetition: int = field(metadata=metadata(1))
|
|
mode_0_steps: int = field(metadata=metadata(1))
|
|
role: int = field(metadata=metadata(CS_ROLE_SPEC))
|
|
rtt_type: int = field(metadata=metadata(RTT_TYPE_SPEC))
|
|
cs_sync_phy: int = field(metadata=metadata(CS_SYNC_PHY_SPEC))
|
|
channel_map: bytes = field(metadata=metadata(10))
|
|
channel_map_repetition: int = field(metadata=metadata(1))
|
|
channel_selection_type: int = field(metadata=metadata(1))
|
|
ch3c_shape: int = field(metadata=metadata(1))
|
|
ch3c_jump: int = field(metadata=metadata(1))
|
|
reserved: int = field(metadata=metadata(1))
|
|
t_ip1_time: int = field(metadata=metadata(1))
|
|
t_ip2_time: int = field(metadata=metadata(1))
|
|
t_fcs_time: int = field(metadata=metadata(1))
|
|
t_pm_time: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_CS_Procedure_Enable_Complete_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.43 LE CS Procedure Enable Complete event
|
|
'''
|
|
|
|
class State(SpecableEnum):
|
|
DISABLED = 0
|
|
ENABLED = 1
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
config_id: int = field(metadata=metadata(1))
|
|
state: int = field(metadata=State.type_metadata(1))
|
|
tone_antenna_config_selection: int = field(metadata=metadata(1))
|
|
selected_tx_power: int = field(metadata=metadata(-1))
|
|
subevent_len: int = field(metadata=metadata(3))
|
|
subevents_per_event: int = field(metadata=metadata(1))
|
|
subevent_interval: int = field(metadata=metadata(2))
|
|
event_interval: int = field(metadata=metadata(2))
|
|
procedure_interval: int = field(metadata=metadata(2))
|
|
procedure_count: int = field(metadata=metadata(2))
|
|
max_procedure_len: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_CS_Subevent_Result_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.44 LE CS Subevent Result event
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
config_id: int = field(metadata=metadata(1))
|
|
start_acl_conn_event_counter: int = field(metadata=metadata(2))
|
|
procedure_counter: int = field(metadata=metadata(2))
|
|
frequency_compensation: int = field(metadata=metadata(2))
|
|
reference_power_level: int = field(metadata=metadata(-1))
|
|
procedure_done_status: int = field(metadata=metadata(1))
|
|
subevent_done_status: int = field(metadata=metadata(1))
|
|
abort_reason: int = field(metadata=metadata(1))
|
|
num_antenna_paths: int = field(metadata=metadata(1))
|
|
step_mode: Sequence[int] = field(metadata=metadata(1, list_begin=True))
|
|
step_channel: Sequence[int] = field(metadata=metadata(1))
|
|
step_data: Sequence[bytes] = field(metadata=metadata("v", list_end=True))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_CS_Subevent_Result_Continue_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.45 LE CS Subevent Result Continue event
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
config_id: int = field(metadata=metadata(1))
|
|
procedure_done_status: int = field(metadata=metadata(1))
|
|
subevent_done_status: int = field(metadata=metadata(1))
|
|
abort_reason: int = field(metadata=metadata(1))
|
|
num_antenna_paths: int = field(metadata=metadata(1))
|
|
step_mode: Sequence[int] = field(metadata=metadata(1, list_begin=True))
|
|
step_channel: Sequence[int] = field(metadata=metadata(1))
|
|
step_data: Sequence[bytes] = field(metadata=metadata("v", list_end=True))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_CS_Test_End_Complete_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.46 LE CS Test End Complete event
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_LE_Meta_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_LE_Connection_Rate_Change_Event(HCI_LE_Meta_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.65.50 LE Connection Rate Change event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
connection_interval: int = field(metadata=metadata(2))
|
|
subrate_factor: int = field(metadata=metadata(2))
|
|
peripheral_latency: int = field(metadata=metadata(2))
|
|
continuation_number: int = field(metadata=metadata(2))
|
|
supervision_timeout: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Inquiry_Complete_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.1 Inquiry Complete Event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Inquiry_Result_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.2 Inquiry Result Event
|
|
'''
|
|
|
|
bd_addr: Sequence[Address] = field(
|
|
metadata=metadata(Address.parse_address, list_begin=True)
|
|
)
|
|
page_scan_repetition_mode: Sequence[int] = field(metadata=metadata(1))
|
|
reserved_0: Sequence[int] = field(metadata=metadata(1))
|
|
reserved_1: Sequence[int] = field(metadata=metadata(1))
|
|
class_of_device: Sequence[int] = field(metadata=metadata(COD_SPEC))
|
|
clock_offset: Sequence[int] = field(metadata=metadata(2, list_end=True))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Connection_Complete_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.3 Connection Complete Event
|
|
'''
|
|
|
|
class LinkType(SpecableEnum):
|
|
SCO = 0x00
|
|
ACL = 0x01
|
|
ESCO = 0x02
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
link_type: int = field(metadata=LinkType.type_metadata(1))
|
|
encryption_enabled: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Connection_Request_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.4 Connection Request Event
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
class_of_device: int = field(metadata=metadata(3))
|
|
link_type: int = field(
|
|
metadata=HCI_Connection_Complete_Event.LinkType.type_metadata(1)
|
|
)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Disconnection_Complete_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.5 Disconnection Complete Event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
reason: int = field(metadata=metadata(STATUS_SPEC))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Authentication_Complete_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.6 Authentication Complete Event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Remote_Name_Request_Complete_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.7 Remote Name Request Complete Event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
remote_name: bytes = field(
|
|
metadata=metadata({'size': 248, 'mapper': map_null_terminated_utf8_string})
|
|
)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Encryption_Change_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.8 Encryption Change Event
|
|
'''
|
|
|
|
class Enabled(SpecableEnum):
|
|
OFF = 0x00
|
|
E0_OR_AES_CCM = 0x01
|
|
AES_CCM = 0x02
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
encryption_enabled: int = field(metadata=Enabled.type_metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Encryption_Change_V2_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.8 Encryption Change Event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
encryption_enabled: int = field(
|
|
metadata=HCI_Encryption_Change_Event.Enabled.type_metadata(1)
|
|
)
|
|
encryption_key_size: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Remote_Supported_Features_Complete_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.11 Read Remote Supported Features Complete Event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
lmp_features: bytes = field(metadata=metadata(8))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Remote_Version_Information_Complete_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.12 Read Remote Version Information Complete Event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
version: int = field(metadata=metadata(1))
|
|
manufacturer_name: int = field(metadata=metadata(2))
|
|
subversion: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_QOS_Setup_Complete_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.13 QoS Setup Complete Event
|
|
'''
|
|
|
|
class ServiceType(SpecableEnum):
|
|
NO_TRAFFIC_AVAILABLE = 0x00
|
|
BEST_EFFORT_AVAILABLE = 0x01
|
|
GUARANTEED_AVAILABLE = 0x02
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
unused: int = field(metadata=metadata(1))
|
|
service_type: int = field(metadata=ServiceType.type_metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Command_Complete_Event(HCI_Event, Generic[_RP]):
|
|
'''
|
|
See Bluetooth spec @ 7.7.14 Command Complete Event
|
|
'''
|
|
|
|
num_hci_command_packets: int = field(metadata=metadata(1))
|
|
command_opcode: int = field(
|
|
metadata=metadata({'size': 2, 'mapper': HCI_Command.command_name})
|
|
)
|
|
return_parameters: _RP = field(metadata=metadata("*"))
|
|
|
|
@classmethod
|
|
def from_parameters(cls, parameters: bytes) -> Self:
|
|
event = cls(**HCI_Object.dict_from_bytes(parameters, 0, cls.fields))
|
|
event.parameters = parameters
|
|
return_parameters_bytes = parameters[3:]
|
|
|
|
# Find the class for the matching command.
|
|
subclass = HCI_Command.command_classes.get(event.command_opcode)
|
|
|
|
# Deal with unknown commands.
|
|
if subclass is None or not issubclass(subclass, HCI_SyncCommand):
|
|
if subclass is not None:
|
|
# Check that the subclass is one that has return parameters.
|
|
logger.warning(
|
|
'HCI Command Complete event with opcode for a class that is not'
|
|
' an HCI_SyncCommand subclass: '
|
|
f'opcode={event.command_opcode:#04x}, '
|
|
f'type={subclass.__name__}'
|
|
)
|
|
event.return_parameters = HCI_GenericReturnParameters(
|
|
data=return_parameters_bytes
|
|
) # type: ignore[assignment]
|
|
return event
|
|
|
|
# Parse the return parameters bytes into an object.
|
|
event.return_parameters = subclass.parse_return_parameters(
|
|
return_parameters_bytes
|
|
) # type: ignore[assignment]
|
|
|
|
return event
|
|
|
|
def __str__(self):
|
|
return f'{color(self.name, "magenta")}:\n' + HCI_Object.format_fields(
|
|
self.__dict__,
|
|
self.fields,
|
|
' ',
|
|
{'return_parameters': lambda x: "\n" + x.to_string(indentation=' ')},
|
|
)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Command_Status_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.15 Command Complete Event
|
|
'''
|
|
|
|
PENDING = 0
|
|
|
|
@staticmethod
|
|
def status_name(status):
|
|
if status == HCI_Command_Status_Event.PENDING:
|
|
return 'PENDING'
|
|
|
|
return HCI_Constant.error_name(status)
|
|
|
|
status: int = field(
|
|
metadata=metadata(
|
|
{'size': 1, 'mapper': lambda x: HCI_Command_Status_Event.status_name(x)}
|
|
)
|
|
)
|
|
num_hci_command_packets: int = field(metadata=metadata(1))
|
|
command_opcode: int = field(
|
|
metadata=metadata({'size': 2, 'mapper': HCI_Command.command_name})
|
|
)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Role_Change_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.18 Role Change Event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
new_role: int = field(metadata=Role.type_metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Number_Of_Completed_Packets_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.19 Number Of Completed Packets Event
|
|
'''
|
|
|
|
connection_handles: Sequence[int] = field(metadata=metadata(2, list_begin=True))
|
|
num_completed_packets: Sequence[int] = field(metadata=metadata(2, list_end=True))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Mode_Change_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.20 Mode Change Event
|
|
'''
|
|
|
|
class Mode(SpecableEnum):
|
|
ACTIVE = 0x00
|
|
HOLD = 0x01
|
|
SNIFF = 0x02
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
current_mode: int = field(metadata=Mode.type_metadata(1))
|
|
interval: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_PIN_Code_Request_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.22 PIN Code Request Event
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Link_Key_Request_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.24 7.7.23 Link Key Request Event
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Link_Key_Notification_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.24 Link Key Notification Event
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
link_key: bytes = field(metadata=metadata(16))
|
|
key_type: int = field(metadata=LinkKeyType.type_metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Max_Slots_Change_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.27 Max Slots Change Event
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
lmp_max_slots: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Clock_Offset_Complete_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.28 Read Clock Offset Complete Event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
clock_offset: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Connection_Packet_Type_Changed_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.29 Connection Packet Type Changed Event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
packet_type: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Page_Scan_Repetition_Mode_Change_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.31 Page Scan Repetition Mode Change Event
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
page_scan_repetition_mode: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Inquiry_Result_With_RSSI_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.33 Inquiry Result with RSSI Event
|
|
'''
|
|
|
|
bd_addr: Sequence[Address] = field(
|
|
metadata=metadata(Address.parse_address, list_begin=True)
|
|
)
|
|
page_scan_repetition_mode: Sequence[int] = field(metadata=metadata(1))
|
|
reserved: Sequence[int] = field(metadata=metadata(1))
|
|
class_of_device: Sequence[int] = field(metadata=metadata(COD_SPEC))
|
|
clock_offset: Sequence[int] = field(metadata=metadata(2))
|
|
rssi: Sequence[int] = field(metadata=metadata(-1, list_end=True))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Read_Remote_Extended_Features_Complete_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.34 Read Remote Extended Features Complete Event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
page_number: int = field(metadata=metadata(1))
|
|
maximum_page_number: int = field(metadata=metadata(1))
|
|
extended_lmp_features: bytes = field(metadata=metadata(8))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Synchronous_Connection_Complete_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.35 Synchronous Connection Complete Event
|
|
'''
|
|
|
|
class LinkType(SpecableEnum):
|
|
SCO = 0x00
|
|
ESCO = 0x02
|
|
|
|
class AirMode(SpecableEnum):
|
|
U_LAW_LOG = 0x00
|
|
A_LAW_LOG_AIR_MORE = 0x01
|
|
CVSD = 0x02
|
|
TRANSPARENT_DATA = 0x03
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
link_type: int = field(metadata=LinkType.type_metadata(1))
|
|
transmission_interval: int = field(metadata=metadata(1))
|
|
retransmission_window: int = field(metadata=metadata(1))
|
|
rx_packet_length: int = field(metadata=metadata(2))
|
|
tx_packet_length: int = field(metadata=metadata(2))
|
|
air_mode: int = field(metadata=AirMode.type_metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Synchronous_Connection_Changed_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.36 Synchronous Connection Changed Event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
transmission_interval: int = field(metadata=metadata(1))
|
|
retransmission_window: int = field(metadata=metadata(1))
|
|
rx_packet_length: int = field(metadata=metadata(2))
|
|
tx_packet_length: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Sniff_Subrating_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.37 Sniff Subrating Event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
max_tx_latency: int = field(metadata=metadata(2))
|
|
max_rx_latency: int = field(metadata=metadata(2))
|
|
min_remote_timeout: int = field(metadata=metadata(2))
|
|
min_local_timeout: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Extended_Inquiry_Result_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.38 Extended Inquiry Result Event
|
|
'''
|
|
|
|
num_responses: int = field(metadata=metadata(1))
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
page_scan_repetition_mode: int = field(metadata=metadata(1))
|
|
reserved: int = field(metadata=metadata(1))
|
|
class_of_device: int = field(metadata=metadata(COD_SPEC))
|
|
clock_offset: int = field(metadata=metadata(2))
|
|
rssi: int = field(metadata=metadata(-1))
|
|
extended_inquiry_response: bytes = field(metadata=metadata(240))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Encryption_Key_Refresh_Complete_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.39 Encryption Key Refresh Complete Event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_IO_Capability_Request_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.40 IO Capability Request Event
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_IO_Capability_Response_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.41 IO Capability Response Event
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
io_capability: int = field(metadata=IoCapability.type_metadata(1))
|
|
oob_data_present: int = field(metadata=metadata(1))
|
|
authentication_requirements: int = field(
|
|
metadata=AuthenticationRequirements.type_metadata(1)
|
|
)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_User_Confirmation_Request_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.42 User Confirmation Request Event
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
numeric_value: int = field(metadata=metadata(4))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_User_Passkey_Request_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.43 User Passkey Request Event
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Remote_OOB_Data_Request_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.44 Remote OOB Data Request Event
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Simple_Pairing_Complete_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.45 Simple Pairing Complete Event
|
|
'''
|
|
|
|
status: int = field(metadata=metadata(STATUS_SPEC))
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Link_Supervision_Timeout_Changed_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.46 Link Supervision Timeout Changed Event
|
|
'''
|
|
|
|
connection_handle: int = field(metadata=metadata(2))
|
|
link_supervision_timeout: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Enhanced_Flush_Complete_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.47 Enhanced Flush Complete Event
|
|
'''
|
|
|
|
handle: int = field(metadata=metadata(2))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_User_Passkey_Notification_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.48 User Passkey Notification Event
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
passkey: int = field(metadata=metadata(4))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Keypress_Notification_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.49 Keypress Notification Event
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
notification_type: int = field(metadata=metadata(1))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Remote_Host_Supported_Features_Notification_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 7.7.50 Remote Host Supported Features Notification Event
|
|
'''
|
|
|
|
bd_addr: Address = field(metadata=metadata(Address.parse_address))
|
|
host_supported_features: bytes = field(metadata=metadata(8))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@HCI_Event.event
|
|
@dataclasses.dataclass
|
|
class HCI_Vendor_Event(HCI_Event):
|
|
'''
|
|
See Bluetooth spec @ 5.4.4 HCI Event packet
|
|
'''
|
|
|
|
data: bytes = field(metadata=metadata("*"))
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_AclDataPacket(HCI_Packet):
|
|
'''
|
|
See Bluetooth spec @ 5.4.2 HCI ACL Data Packets
|
|
'''
|
|
|
|
hci_packet_type = HCI_ACL_DATA_PACKET
|
|
|
|
connection_handle: int
|
|
pb_flag: int
|
|
bc_flag: int
|
|
data_total_length: int
|
|
data: bytes
|
|
|
|
@classmethod
|
|
def from_bytes(cls, packet: bytes) -> HCI_AclDataPacket:
|
|
# Read the header
|
|
h, data_total_length = struct.unpack_from('<HH', packet, 1)
|
|
connection_handle = h & 0xFFF
|
|
pb_flag = (h >> 12) & 3
|
|
bc_flag = (h >> 14) & 3
|
|
data = packet[5:]
|
|
if len(data) != data_total_length:
|
|
raise InvalidPacketError('invalid packet length')
|
|
return cls(
|
|
connection_handle=connection_handle,
|
|
pb_flag=pb_flag,
|
|
bc_flag=bc_flag,
|
|
data_total_length=data_total_length,
|
|
data=data,
|
|
)
|
|
|
|
def __bytes__(self) -> bytes:
|
|
h = (self.pb_flag << 12) | (self.bc_flag << 14) | self.connection_handle
|
|
return (
|
|
struct.pack('<BHH', HCI_ACL_DATA_PACKET, h, self.data_total_length)
|
|
+ self.data
|
|
)
|
|
|
|
def __str__(self) -> str:
|
|
return (
|
|
f'{color("ACL", "blue")}: '
|
|
f'handle=0x{self.connection_handle:04x}, '
|
|
f'pb={self.pb_flag}, bc={self.bc_flag}, '
|
|
f'data_total_length={self.data_total_length}, '
|
|
f'data={self.data.hex()}'
|
|
)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_SynchronousDataPacket(HCI_Packet):
|
|
'''
|
|
See Bluetooth spec @ 5.4.3 HCI SCO Data Packets
|
|
'''
|
|
|
|
hci_packet_type = HCI_SYNCHRONOUS_DATA_PACKET
|
|
|
|
connection_handle: int
|
|
packet_status: int
|
|
data_total_length: int
|
|
data: bytes
|
|
|
|
@classmethod
|
|
def from_bytes(cls, packet: bytes) -> HCI_SynchronousDataPacket:
|
|
# Read the header
|
|
h, data_total_length = struct.unpack_from('<HB', packet, 1)
|
|
connection_handle = h & 0xFFF
|
|
packet_status = (h >> 12) & 0b11
|
|
data = packet[4:]
|
|
if len(data) != data_total_length:
|
|
raise InvalidPacketError(
|
|
f'invalid packet length {len(data)} != {data_total_length}'
|
|
)
|
|
return cls(
|
|
connection_handle=connection_handle,
|
|
packet_status=packet_status,
|
|
data_total_length=data_total_length,
|
|
data=data,
|
|
)
|
|
|
|
def __bytes__(self) -> bytes:
|
|
h = (self.packet_status << 12) | self.connection_handle
|
|
return (
|
|
struct.pack('<BHB', HCI_SYNCHRONOUS_DATA_PACKET, h, self.data_total_length)
|
|
+ self.data
|
|
)
|
|
|
|
def __str__(self) -> str:
|
|
return (
|
|
f'{color("SCO", "blue")}: '
|
|
f'handle=0x{self.connection_handle:04x}, '
|
|
f'ps={self.packet_status}, '
|
|
f'data_total_length={self.data_total_length}, '
|
|
f'data={self.data.hex()}'
|
|
)
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
@dataclasses.dataclass
|
|
class HCI_IsoDataPacket(HCI_Packet):
|
|
'''
|
|
See Bluetooth spec @ 5.4.5 HCI ISO Data Packets
|
|
'''
|
|
|
|
hci_packet_type = HCI_ISO_DATA_PACKET
|
|
|
|
connection_handle: int
|
|
data_total_length: int
|
|
iso_sdu_fragment: bytes
|
|
pb_flag: int
|
|
ts_flag: int = 0
|
|
time_stamp: int | None = None
|
|
packet_sequence_number: int | None = None
|
|
iso_sdu_length: int | None = None
|
|
packet_status_flag: int | None = None
|
|
|
|
def __post_init__(self) -> None:
|
|
self.ts_flag = self.time_stamp is not None
|
|
|
|
@staticmethod
|
|
def from_bytes(packet: bytes) -> HCI_IsoDataPacket:
|
|
time_stamp: int | None = None
|
|
packet_sequence_number: int | None = None
|
|
iso_sdu_length: int | None = None
|
|
packet_status_flag: int | None = None
|
|
|
|
pos = 1
|
|
pdu_info, data_total_length = struct.unpack_from('<HH', packet, pos)
|
|
connection_handle = pdu_info & 0xFFF
|
|
pb_flag = (pdu_info >> 12) & 0b11
|
|
ts_flag = (pdu_info >> 14) & 0b01
|
|
pos += 4
|
|
|
|
# pb_flag in (0b00, 0b10) but faster
|
|
should_include_sdu_info = not (pb_flag & 0b01)
|
|
|
|
if ts_flag:
|
|
if not should_include_sdu_info:
|
|
logger.warning(f'Timestamp included when pb_flag={bin(pb_flag)}')
|
|
time_stamp, *_ = struct.unpack_from('<I', packet, pos)
|
|
pos += 4
|
|
|
|
if should_include_sdu_info:
|
|
packet_sequence_number, sdu_info = struct.unpack_from('<HH', packet, pos)
|
|
iso_sdu_length = sdu_info & 0xFFF
|
|
packet_status_flag = (sdu_info >> 15) & 1
|
|
pos += 4
|
|
|
|
iso_sdu_fragment = packet[pos:]
|
|
return HCI_IsoDataPacket(
|
|
connection_handle=connection_handle,
|
|
pb_flag=pb_flag,
|
|
ts_flag=ts_flag,
|
|
data_total_length=data_total_length,
|
|
time_stamp=time_stamp,
|
|
packet_sequence_number=packet_sequence_number,
|
|
iso_sdu_length=iso_sdu_length,
|
|
packet_status_flag=packet_status_flag,
|
|
iso_sdu_fragment=iso_sdu_fragment,
|
|
)
|
|
|
|
def __bytes__(self) -> bytes:
|
|
fmt = '<BHH'
|
|
args = [
|
|
HCI_ISO_DATA_PACKET,
|
|
self.ts_flag << 14 | self.pb_flag << 12 | self.connection_handle,
|
|
self.data_total_length,
|
|
]
|
|
if self.time_stamp is not None:
|
|
fmt += 'I'
|
|
args.append(self.time_stamp)
|
|
if (
|
|
self.packet_sequence_number is not None
|
|
and self.iso_sdu_length is not None
|
|
and self.packet_status_flag is not None
|
|
):
|
|
fmt += 'HH'
|
|
args += [
|
|
self.packet_sequence_number,
|
|
self.iso_sdu_length | self.packet_status_flag << 15,
|
|
]
|
|
return struct.pack(fmt, *args) + self.iso_sdu_fragment
|
|
|
|
def __str__(self) -> str:
|
|
result = (
|
|
f'{color("ISO", "blue")}: '
|
|
f'handle=0x{self.connection_handle:04x}, '
|
|
f'pb={self.pb_flag}, '
|
|
f'data_total_length={self.data_total_length}'
|
|
)
|
|
|
|
if self.ts_flag:
|
|
result += f', time_stamp={self.time_stamp}'
|
|
|
|
if self.pb_flag in (0b00, 0b10):
|
|
result += (
|
|
', '
|
|
f'packet_sequence_number={self.packet_sequence_number}, '
|
|
f'ps={self.packet_status_flag}, '
|
|
f'sdu_fragment={self.iso_sdu_fragment.hex()}'
|
|
)
|
|
|
|
return result
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
class HCI_AclDataPacketAssembler:
|
|
current_data: bytes | None
|
|
|
|
def __init__(self, callback: Callable[[bytes], Any]) -> None:
|
|
self.callback = callback
|
|
self.current_data = None
|
|
self.l2cap_pdu_length = 0
|
|
|
|
def feed_packet(self, packet: HCI_AclDataPacket) -> None:
|
|
if packet.pb_flag in (
|
|
HCI_ACL_PB_FIRST_NON_FLUSHABLE,
|
|
HCI_ACL_PB_FIRST_FLUSHABLE,
|
|
):
|
|
(l2cap_pdu_length,) = struct.unpack_from('<H', packet.data, 0)
|
|
self.current_data = packet.data
|
|
self.l2cap_pdu_length = l2cap_pdu_length
|
|
elif packet.pb_flag == HCI_ACL_PB_CONTINUATION:
|
|
if self.current_data is None:
|
|
logger.warning('!!! ACL continuation without start')
|
|
return
|
|
self.current_data += packet.data
|
|
|
|
assert self.current_data is not None
|
|
if len(self.current_data) == self.l2cap_pdu_length + 4:
|
|
# The packet is complete, invoke the callback
|
|
logger.debug(f'<<< ACL PDU: {self.current_data.hex()}')
|
|
self.callback(self.current_data)
|
|
|
|
# Reset
|
|
self.current_data = None
|
|
self.l2cap_pdu_length = 0
|
|
else:
|
|
# Compliance check
|
|
if len(self.current_data) > self.l2cap_pdu_length + 4:
|
|
logger.warning('!!! ACL data exceeds L2CAP PDU')
|
|
self.current_data = None
|
|
self.l2cap_pdu_length = 0
|