forked from auracaster/bumble_mirror
Compare commits
20 Commits
gbg/bench-
...
v0.0.187
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4a60df108a | ||
|
|
ad48109748 | ||
|
|
44c51c13ac | ||
|
|
7507be1eab | ||
|
|
cbe9446dcf | ||
|
|
174930399a | ||
|
|
1f3aee5566 | ||
|
|
256044a789 | ||
|
|
e554bd1033 | ||
|
|
38981cefa1 | ||
|
|
f2d601f411 | ||
|
|
6e7c64c1de | ||
|
|
565d51f4db | ||
|
|
de8f3d9c1e | ||
|
|
cde6d48690 | ||
|
|
02180088b3 | ||
|
|
90f49267d1 | ||
|
|
0e6d69cd7b | ||
|
|
9eccc583d5 | ||
|
|
f4aeaa6eb3 |
2
.github/workflows/python-build-test.yml
vendored
2
.github/workflows/python-build-test.yml
vendored
@@ -47,7 +47,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [ "3.8", "3.9", "3.10", "3.11" ]
|
||||
rust-version: [ "1.70.0", "stable" ]
|
||||
rust-version: [ "1.76.0", "stable" ]
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Check out from Git
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -9,6 +9,9 @@ __pycache__
|
||||
# generated by setuptools_scm
|
||||
bumble/_version.py
|
||||
.vscode/launch.json
|
||||
.vscode/settings.json
|
||||
/.idea
|
||||
venv/
|
||||
.venv/
|
||||
# snoop logs
|
||||
out/
|
||||
|
||||
75
apps/show.py
75
apps/show.py
@@ -15,7 +15,11 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# Imports
|
||||
# -----------------------------------------------------------------------------
|
||||
import datetime
|
||||
import logging
|
||||
import os
|
||||
import struct
|
||||
|
||||
import click
|
||||
|
||||
from bumble.colors import color
|
||||
@@ -24,6 +28,14 @@ from bumble.transport.common import PacketReader
|
||||
from bumble.helpers import PacketTracer
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Logging
|
||||
# -----------------------------------------------------------------------------
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Classes
|
||||
# -----------------------------------------------------------------------------
|
||||
class SnoopPacketReader:
|
||||
'''
|
||||
@@ -36,12 +48,18 @@ class SnoopPacketReader:
|
||||
DATALINK_BSCP = 1003
|
||||
DATALINK_H5 = 1004
|
||||
|
||||
IDENTIFICATION_PATTERN = b'btsnoop\0'
|
||||
TIMESTAMP_ANCHOR = datetime.datetime(2000, 1, 1)
|
||||
TIMESTAMP_DELTA = 0x00E03AB44A676000
|
||||
ONE_MICROSECOND = datetime.timedelta(microseconds=1)
|
||||
|
||||
def __init__(self, source):
|
||||
self.source = source
|
||||
self.at_end = False
|
||||
|
||||
# Read the header
|
||||
identification_pattern = source.read(8)
|
||||
if identification_pattern.hex().lower() != '6274736e6f6f7000':
|
||||
if identification_pattern != self.IDENTIFICATION_PATTERN:
|
||||
raise ValueError(
|
||||
'not a valid snoop file, unexpected identification pattern'
|
||||
)
|
||||
@@ -55,19 +73,32 @@ class SnoopPacketReader:
|
||||
# Read the record header
|
||||
header = self.source.read(24)
|
||||
if len(header) < 24:
|
||||
return (0, None)
|
||||
self.at_end = True
|
||||
return (None, 0, None)
|
||||
|
||||
# Parse the header
|
||||
(
|
||||
original_length,
|
||||
included_length,
|
||||
packet_flags,
|
||||
_cumulative_drops,
|
||||
_timestamp_seconds,
|
||||
_timestamp_microsecond,
|
||||
) = struct.unpack('>IIIIII', header)
|
||||
timestamp,
|
||||
) = struct.unpack('>IIIIQ', header)
|
||||
|
||||
# Abort on truncated packets
|
||||
# Skip truncated packets
|
||||
if original_length != included_length:
|
||||
return (0, None)
|
||||
print(
|
||||
color(
|
||||
f"!!! truncated packet ({included_length}/{original_length})", "red"
|
||||
)
|
||||
)
|
||||
self.source.read(included_length)
|
||||
return (None, 0, None)
|
||||
|
||||
# Convert the timestamp to a datetime object.
|
||||
ts_dt = self.TIMESTAMP_ANCHOR + datetime.timedelta(
|
||||
microseconds=timestamp - self.TIMESTAMP_DELTA
|
||||
)
|
||||
|
||||
if self.data_link_type == self.DATALINK_H1:
|
||||
# The packet is un-encapsulated, look at the flags to figure out its type
|
||||
@@ -89,7 +120,17 @@ class SnoopPacketReader:
|
||||
bytes([packet_type]) + self.source.read(included_length),
|
||||
)
|
||||
|
||||
return (packet_flags & 1, self.source.read(included_length))
|
||||
return (ts_dt, packet_flags & 1, self.source.read(included_length))
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
class Printer:
|
||||
def __init__(self):
|
||||
self.index = 0
|
||||
|
||||
def print(self, message: str) -> None:
|
||||
self.index += 1
|
||||
print(f"[{self.index:8}]{message}")
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
@@ -122,24 +163,28 @@ def main(format, vendors, filename):
|
||||
packet_reader = PacketReader(input)
|
||||
|
||||
def read_next_packet():
|
||||
return (0, packet_reader.next_packet())
|
||||
return (None, 0, packet_reader.next_packet())
|
||||
|
||||
else:
|
||||
packet_reader = SnoopPacketReader(input)
|
||||
read_next_packet = packet_reader.next_packet
|
||||
|
||||
tracer = PacketTracer(emit_message=print)
|
||||
printer = Printer()
|
||||
tracer = PacketTracer(emit_message=printer.print)
|
||||
|
||||
while True:
|
||||
while not packet_reader.at_end:
|
||||
try:
|
||||
(direction, packet) = read_next_packet()
|
||||
if packet is None:
|
||||
break
|
||||
tracer.trace(hci.HCI_Packet.from_bytes(packet), direction)
|
||||
(timestamp, direction, packet) = read_next_packet()
|
||||
if packet:
|
||||
tracer.trace(hci.HCI_Packet.from_bytes(packet), direction, timestamp)
|
||||
else:
|
||||
printer.print(color("[TRUNCATED]", "red"))
|
||||
except Exception as error:
|
||||
logger.exception()
|
||||
print(color(f'!!! {error}', 'red'))
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
if __name__ == '__main__':
|
||||
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'WARNING').upper())
|
||||
main() # pylint: disable=no-value-for-parameter
|
||||
|
||||
@@ -2065,7 +2065,9 @@ class Device(CompositeEventEmitter):
|
||||
"""Stop legacy advertising."""
|
||||
# Disable advertising
|
||||
if self.legacy_advertising_set:
|
||||
await self.legacy_advertising_set.stop()
|
||||
if self.legacy_advertising_set.enabled:
|
||||
await self.legacy_advertising_set.stop()
|
||||
await self.legacy_advertising_set.remove()
|
||||
self.legacy_advertising_set = None
|
||||
elif self.legacy_advertiser:
|
||||
await self.legacy_advertiser.stop()
|
||||
@@ -2110,6 +2112,20 @@ class Device(CompositeEventEmitter):
|
||||
Returns:
|
||||
An AdvertisingSet instance.
|
||||
"""
|
||||
# Instantiate default values
|
||||
if advertising_parameters is None:
|
||||
advertising_parameters = AdvertisingParameters()
|
||||
|
||||
if (
|
||||
not advertising_parameters.advertising_event_properties.is_legacy
|
||||
and advertising_data
|
||||
and scan_response_data
|
||||
):
|
||||
raise ValueError(
|
||||
"Extended advertisements can't have both data and scan \
|
||||
response data"
|
||||
)
|
||||
|
||||
# Allocate a new handle
|
||||
try:
|
||||
advertising_handle = next(
|
||||
@@ -2123,10 +2139,6 @@ class Device(CompositeEventEmitter):
|
||||
except StopIteration as exc:
|
||||
raise RuntimeError("all valid advertising handles already in use") from exc
|
||||
|
||||
# Instantiate default values
|
||||
if advertising_parameters is None:
|
||||
advertising_parameters = AdvertisingParameters()
|
||||
|
||||
# Use the device's random address if a random address is needed but none was
|
||||
# provided.
|
||||
if (
|
||||
@@ -2207,9 +2219,6 @@ class Device(CompositeEventEmitter):
|
||||
if self.legacy_advertiser:
|
||||
return True
|
||||
|
||||
if self.legacy_advertising_set and self.legacy_advertising_set.enabled:
|
||||
return True
|
||||
|
||||
return any(
|
||||
advertising_set.enabled
|
||||
for advertising_set in self.extended_advertising_sets.values()
|
||||
@@ -2223,7 +2232,7 @@ class Device(CompositeEventEmitter):
|
||||
scan_window: int = DEVICE_DEFAULT_SCAN_WINDOW, # Scan window in ms
|
||||
own_address_type: int = OwnAddressType.RANDOM,
|
||||
filter_duplicates: bool = False,
|
||||
scanning_phys: Tuple[int, int] = (HCI_LE_1M_PHY, HCI_LE_CODED_PHY),
|
||||
scanning_phys: List[int] = [HCI_LE_1M_PHY, HCI_LE_CODED_PHY],
|
||||
) -> None:
|
||||
# Check that the arguments are legal
|
||||
if scan_interval < scan_window:
|
||||
@@ -3541,11 +3550,9 @@ class Device(CompositeEventEmitter):
|
||||
connection_handle,
|
||||
number_of_completed_extended_advertising_events,
|
||||
):
|
||||
# Legacy advertising set is also one of extended advertising sets.
|
||||
if not (
|
||||
advertising_set := (
|
||||
self.extended_advertising_sets.get(advertising_handle)
|
||||
or self.legacy_advertising_set
|
||||
)
|
||||
advertising_set := self.extended_advertising_sets.get(advertising_handle)
|
||||
):
|
||||
logger.warning(f'advertising set {advertising_handle} not found')
|
||||
return
|
||||
|
||||
@@ -25,7 +25,7 @@ import pathlib
|
||||
import platform
|
||||
from typing import Dict, Iterable, Optional, Type, TYPE_CHECKING
|
||||
|
||||
from . import rtk
|
||||
from . import rtk, intel
|
||||
from .common import Driver
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -45,7 +45,7 @@ async def get_driver_for_host(host: Host) -> Optional[Driver]:
|
||||
found.
|
||||
If a "driver" HCI metadata entry is present, only that driver class will be probed.
|
||||
"""
|
||||
driver_classes: Dict[str, Type[Driver]] = {"rtk": rtk.Driver}
|
||||
driver_classes: Dict[str, Type[Driver]] = {"rtk": rtk.Driver, "intel": intel.Driver}
|
||||
probe_list: Iterable[str]
|
||||
if driver_name := host.hci_metadata.get("driver"):
|
||||
# Only probe a single driver
|
||||
|
||||
70
bumble/drivers/intel.py
Normal file
70
bumble/drivers/intel.py
Normal file
@@ -0,0 +1,70 @@
|
||||
# Copyright 2024 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
|
||||
# -----------------------------------------------------------------------------
|
||||
import logging
|
||||
|
||||
from bumble.drivers import common
|
||||
from bumble.hci import (
|
||||
hci_vendor_command_op_code, # type: ignore
|
||||
HCI_Command,
|
||||
HCI_Reset_Command,
|
||||
)
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Logging
|
||||
# -----------------------------------------------------------------------------
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# HCI Commands
|
||||
# -----------------------------------------------------------------------------
|
||||
HCI_INTEL_DDC_CONFIG_WRITE_COMMAND = hci_vendor_command_op_code(0xFC8B) # type: ignore
|
||||
HCI_INTEL_DDC_CONFIG_WRITE_PAYLOAD = [0x03, 0xE4, 0x02, 0x00]
|
||||
|
||||
HCI_Command.register_commands(globals())
|
||||
|
||||
|
||||
@HCI_Command.command( # type: ignore
|
||||
fields=[("params", "*")],
|
||||
return_parameters_fields=[
|
||||
("params", "*"),
|
||||
],
|
||||
)
|
||||
class Hci_Intel_DDC_Config_Write_Command(HCI_Command):
|
||||
pass
|
||||
|
||||
|
||||
class Driver(common.Driver):
|
||||
def __init__(self, host):
|
||||
self.host = host
|
||||
|
||||
@classmethod
|
||||
async def for_host(cls, host): # type: ignore
|
||||
# Only instantiate this driver if explicitly selected
|
||||
if host.hci_metadata.get("driver") == "intel":
|
||||
return cls(host)
|
||||
|
||||
return None
|
||||
|
||||
async def init_controller(self):
|
||||
self.host.ready = True
|
||||
await self.host.send_command(HCI_Reset_Command(), check_result=True)
|
||||
await self.host.send_command(
|
||||
Hci_Intel_DDC_Config_Write_Command(
|
||||
params=HCI_INTEL_DDC_CONFIG_WRITE_PAYLOAD
|
||||
)
|
||||
)
|
||||
841
bumble/hci.py
841
bumble/hci.py
@@ -790,538 +790,317 @@ HCI_RANDOM_DEVICE_ADDRESS_TYPE = 0x01
|
||||
HCI_PUBLIC_IDENTITY_ADDRESS_TYPE = 0x02
|
||||
HCI_RANDOM_IDENTITY_ADDRESS_TYPE = 0x03
|
||||
|
||||
# Supported Commands Flags
|
||||
# Supported Commands Masks
|
||||
# See Bluetooth spec @ 6.27 SUPPORTED COMMANDS
|
||||
HCI_SUPPORTED_COMMANDS_FLAGS = (
|
||||
# Octet 0
|
||||
(
|
||||
HCI_INQUIRY_COMMAND,
|
||||
HCI_INQUIRY_CANCEL_COMMAND,
|
||||
HCI_PERIODIC_INQUIRY_MODE_COMMAND,
|
||||
HCI_EXIT_PERIODIC_INQUIRY_MODE_COMMAND,
|
||||
HCI_CREATE_CONNECTION_COMMAND,
|
||||
HCI_DISCONNECT_COMMAND,
|
||||
None,
|
||||
HCI_CREATE_CONNECTION_CANCEL_COMMAND
|
||||
),
|
||||
# Octet 1
|
||||
(
|
||||
HCI_ACCEPT_CONNECTION_REQUEST_COMMAND,
|
||||
HCI_REJECT_CONNECTION_REQUEST_COMMAND,
|
||||
HCI_LINK_KEY_REQUEST_REPLY_COMMAND,
|
||||
HCI_LINK_KEY_REQUEST_NEGATIVE_REPLY_COMMAND,
|
||||
HCI_PIN_CODE_REQUEST_REPLY_COMMAND,
|
||||
HCI_PIN_CODE_REQUEST_NEGATIVE_REPLY_COMMAND,
|
||||
HCI_CHANGE_CONNECTION_PACKET_TYPE_COMMAND,
|
||||
HCI_AUTHENTICATION_REQUESTED_COMMAND
|
||||
),
|
||||
# Octet 2
|
||||
(
|
||||
HCI_SET_CONNECTION_ENCRYPTION_COMMAND,
|
||||
HCI_CHANGE_CONNECTION_LINK_KEY_COMMAND,
|
||||
HCI_LINK_KEY_SELECTION_COMMAND,
|
||||
HCI_REMOTE_NAME_REQUEST_COMMAND,
|
||||
HCI_REMOTE_NAME_REQUEST_CANCEL_COMMAND,
|
||||
HCI_READ_REMOTE_SUPPORTED_FEATURES_COMMAND,
|
||||
HCI_READ_REMOTE_EXTENDED_FEATURES_COMMAND,
|
||||
HCI_READ_REMOTE_VERSION_INFORMATION_COMMAND
|
||||
),
|
||||
# Octet 3
|
||||
(
|
||||
HCI_READ_CLOCK_OFFSET_COMMAND,
|
||||
HCI_READ_LMP_HANDLE_COMMAND,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None
|
||||
),
|
||||
# Octet 4
|
||||
(
|
||||
None,
|
||||
HCI_HOLD_MODE_COMMAND,
|
||||
HCI_SNIFF_MODE_COMMAND,
|
||||
HCI_EXIT_SNIFF_MODE_COMMAND,
|
||||
None,
|
||||
None,
|
||||
HCI_QOS_SETUP_COMMAND,
|
||||
HCI_ROLE_DISCOVERY_COMMAND
|
||||
),
|
||||
# Octet 5
|
||||
(
|
||||
HCI_SWITCH_ROLE_COMMAND,
|
||||
HCI_READ_LINK_POLICY_SETTINGS_COMMAND,
|
||||
HCI_WRITE_LINK_POLICY_SETTINGS_COMMAND,
|
||||
HCI_READ_DEFAULT_LINK_POLICY_SETTINGS_COMMAND,
|
||||
HCI_WRITE_DEFAULT_LINK_POLICY_SETTINGS_COMMAND,
|
||||
HCI_FLOW_SPECIFICATION_COMMAND,
|
||||
HCI_SET_EVENT_MASK_COMMAND,
|
||||
HCI_RESET_COMMAND
|
||||
),
|
||||
# Octet 6
|
||||
(
|
||||
HCI_SET_EVENT_FILTER_COMMAND,
|
||||
HCI_FLUSH_COMMAND,
|
||||
HCI_READ_PIN_TYPE_COMMAND,
|
||||
HCI_WRITE_PIN_TYPE_COMMAND,
|
||||
None,
|
||||
HCI_READ_STORED_LINK_KEY_COMMAND,
|
||||
HCI_WRITE_STORED_LINK_KEY_COMMAND,
|
||||
HCI_DELETE_STORED_LINK_KEY_COMMAND
|
||||
),
|
||||
# Octet 7
|
||||
(
|
||||
HCI_WRITE_LOCAL_NAME_COMMAND,
|
||||
HCI_READ_LOCAL_NAME_COMMAND,
|
||||
HCI_READ_CONNECTION_ACCEPT_TIMEOUT_COMMAND,
|
||||
HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT_COMMAND,
|
||||
HCI_READ_PAGE_TIMEOUT_COMMAND,
|
||||
HCI_WRITE_PAGE_TIMEOUT_COMMAND,
|
||||
HCI_READ_SCAN_ENABLE_COMMAND,
|
||||
HCI_WRITE_SCAN_ENABLE_COMMAND
|
||||
),
|
||||
# Octet 8
|
||||
(
|
||||
HCI_READ_PAGE_SCAN_ACTIVITY_COMMAND,
|
||||
HCI_WRITE_PAGE_SCAN_ACTIVITY_COMMAND,
|
||||
HCI_READ_INQUIRY_SCAN_ACTIVITY_COMMAND,
|
||||
HCI_WRITE_INQUIRY_SCAN_ACTIVITY_COMMAND,
|
||||
HCI_READ_AUTHENTICATION_ENABLE_COMMAND,
|
||||
HCI_WRITE_AUTHENTICATION_ENABLE_COMMAND,
|
||||
None,
|
||||
None
|
||||
),
|
||||
# Octet 9
|
||||
(
|
||||
HCI_READ_CLASS_OF_DEVICE_COMMAND,
|
||||
HCI_WRITE_CLASS_OF_DEVICE_COMMAND,
|
||||
HCI_READ_VOICE_SETTING_COMMAND,
|
||||
HCI_WRITE_VOICE_SETTING_COMMAND,
|
||||
HCI_READ_AUTOMATIC_FLUSH_TIMEOUT_COMMAND,
|
||||
HCI_WRITE_AUTOMATIC_FLUSH_TIMEOUT_COMMAND,
|
||||
HCI_READ_NUM_BROADCAST_RETRANSMISSIONS_COMMAND,
|
||||
HCI_WRITE_NUM_BROADCAST_RETRANSMISSIONS_COMMAND
|
||||
),
|
||||
# Octet 10
|
||||
(
|
||||
HCI_READ_HOLD_MODE_ACTIVITY_COMMAND,
|
||||
HCI_WRITE_HOLD_MODE_ACTIVITY_COMMAND,
|
||||
HCI_READ_TRANSMIT_POWER_LEVEL_COMMAND,
|
||||
HCI_READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE_COMMAND,
|
||||
HCI_WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE_COMMAND,
|
||||
HCI_SET_CONTROLLER_TO_HOST_FLOW_CONTROL_COMMAND,
|
||||
HCI_HOST_BUFFER_SIZE_COMMAND,
|
||||
HCI_HOST_NUMBER_OF_COMPLETED_PACKETS_COMMAND
|
||||
),
|
||||
# Octet 11
|
||||
(
|
||||
HCI_READ_LINK_SUPERVISION_TIMEOUT_COMMAND,
|
||||
HCI_WRITE_LINK_SUPERVISION_TIMEOUT_COMMAND,
|
||||
HCI_READ_NUMBER_OF_SUPPORTED_IAC_COMMAND,
|
||||
HCI_READ_CURRENT_IAC_LAP_COMMAND,
|
||||
HCI_WRITE_CURRENT_IAC_LAP_COMMAND,
|
||||
None,
|
||||
None,
|
||||
None
|
||||
),
|
||||
# Octet 12
|
||||
(
|
||||
None,
|
||||
HCI_SET_AFH_HOST_CHANNEL_CLASSIFICATION_COMMAND,
|
||||
None,
|
||||
None,
|
||||
HCI_READ_INQUIRY_SCAN_TYPE_COMMAND,
|
||||
HCI_WRITE_INQUIRY_SCAN_TYPE_COMMAND,
|
||||
HCI_READ_INQUIRY_MODE_COMMAND,
|
||||
HCI_WRITE_INQUIRY_MODE_COMMAND
|
||||
),
|
||||
# Octet 13
|
||||
(
|
||||
HCI_READ_PAGE_SCAN_TYPE_COMMAND,
|
||||
HCI_WRITE_PAGE_SCAN_TYPE_COMMAND,
|
||||
HCI_READ_AFH_CHANNEL_ASSESSMENT_MODE_COMMAND,
|
||||
HCI_WRITE_AFH_CHANNEL_ASSESSMENT_MODE_COMMAND,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
),
|
||||
# Octet 14
|
||||
(
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
HCI_READ_LOCAL_VERSION_INFORMATION_COMMAND,
|
||||
None,
|
||||
HCI_READ_LOCAL_SUPPORTED_FEATURES_COMMAND,
|
||||
HCI_READ_LOCAL_EXTENDED_FEATURES_COMMAND,
|
||||
HCI_READ_BUFFER_SIZE_COMMAND
|
||||
),
|
||||
# Octet 15
|
||||
(
|
||||
None,
|
||||
HCI_READ_BD_ADDR_COMMAND,
|
||||
HCI_READ_FAILED_CONTACT_COUNTER_COMMAND,
|
||||
HCI_RESET_FAILED_CONTACT_COUNTER_COMMAND,
|
||||
HCI_READ_LINK_QUALITY_COMMAND,
|
||||
HCI_READ_RSSI_COMMAND,
|
||||
HCI_READ_AFH_CHANNEL_MAP_COMMAND,
|
||||
HCI_READ_CLOCK_COMMAND
|
||||
),
|
||||
# Octet 16
|
||||
(
|
||||
HCI_READ_LOOPBACK_MODE_COMMAND,
|
||||
HCI_WRITE_LOOPBACK_MODE_COMMAND,
|
||||
HCI_ENABLE_DEVICE_UNDER_TEST_MODE_COMMAND,
|
||||
HCI_SETUP_SYNCHRONOUS_CONNECTION_COMMAND,
|
||||
HCI_ACCEPT_SYNCHRONOUS_CONNECTION_REQUEST_COMMAND,
|
||||
HCI_REJECT_SYNCHRONOUS_CONNECTION_REQUEST_COMMAND,
|
||||
None,
|
||||
None,
|
||||
),
|
||||
# Octet 17
|
||||
(
|
||||
HCI_READ_EXTENDED_INQUIRY_RESPONSE_COMMAND,
|
||||
HCI_WRITE_EXTENDED_INQUIRY_RESPONSE_COMMAND,
|
||||
HCI_REFRESH_ENCRYPTION_KEY_COMMAND,
|
||||
None,
|
||||
HCI_SNIFF_SUBRATING_COMMAND,
|
||||
HCI_READ_SIMPLE_PAIRING_MODE_COMMAND,
|
||||
HCI_WRITE_SIMPLE_PAIRING_MODE_COMMAND,
|
||||
HCI_READ_LOCAL_OOB_DATA_COMMAND
|
||||
),
|
||||
# Octet 18
|
||||
(
|
||||
HCI_READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL_COMMAND,
|
||||
HCI_WRITE_INQUIRY_TRANSMIT_POWER_LEVEL_COMMAND,
|
||||
HCI_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_COMMAND,
|
||||
HCI_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_COMMAND,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
HCI_IO_CAPABILITY_REQUEST_REPLY_COMMAND
|
||||
),
|
||||
# Octet 19
|
||||
(
|
||||
HCI_USER_CONFIRMATION_REQUEST_REPLY_COMMAND,
|
||||
HCI_USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY_COMMAND,
|
||||
HCI_USER_PASSKEY_REQUEST_REPLY_COMMAND,
|
||||
HCI_USER_PASSKEY_REQUEST_NEGATIVE_REPLY_COMMAND,
|
||||
HCI_REMOTE_OOB_DATA_REQUEST_REPLY_COMMAND,
|
||||
HCI_WRITE_SIMPLE_PAIRING_DEBUG_MODE_COMMAND,
|
||||
HCI_ENHANCED_FLUSH_COMMAND,
|
||||
HCI_REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY_COMMAND
|
||||
),
|
||||
# Octet 20
|
||||
(
|
||||
None,
|
||||
None,
|
||||
HCI_SEND_KEYPRESS_NOTIFICATION_COMMAND,
|
||||
HCI_IO_CAPABILITY_REQUEST_NEGATIVE_REPLY_COMMAND,
|
||||
HCI_READ_ENCRYPTION_KEY_SIZE_COMMAND,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
),
|
||||
# Octet 21
|
||||
(
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
),
|
||||
# Octet 22
|
||||
(
|
||||
None,
|
||||
None,
|
||||
HCI_SET_EVENT_MASK_PAGE_2_COMMAND,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
),
|
||||
# Octet 23
|
||||
(
|
||||
HCI_READ_FLOW_CONTROL_MODE_COMMAND,
|
||||
HCI_WRITE_FLOW_CONTROL_MODE_COMMAND,
|
||||
HCI_READ_DATA_BLOCK_SIZE_COMMAND,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
),
|
||||
# Octet 24
|
||||
(
|
||||
HCI_READ_ENHANCED_TRANSMIT_POWER_LEVEL_COMMAND,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
HCI_READ_LE_HOST_SUPPORT_COMMAND,
|
||||
HCI_WRITE_LE_HOST_SUPPORT_COMMAND,
|
||||
None,
|
||||
),
|
||||
# Octet 25
|
||||
(
|
||||
HCI_LE_SET_EVENT_MASK_COMMAND,
|
||||
HCI_LE_READ_BUFFER_SIZE_COMMAND,
|
||||
HCI_LE_READ_LOCAL_SUPPORTED_FEATURES_COMMAND,
|
||||
None,
|
||||
HCI_LE_SET_RANDOM_ADDRESS_COMMAND,
|
||||
HCI_LE_SET_ADVERTISING_PARAMETERS_COMMAND,
|
||||
HCI_LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER_COMMAND,
|
||||
HCI_LE_SET_ADVERTISING_DATA_COMMAND,
|
||||
),
|
||||
# Octet 26
|
||||
(
|
||||
HCI_LE_SET_SCAN_RESPONSE_DATA_COMMAND,
|
||||
HCI_LE_SET_ADVERTISING_ENABLE_COMMAND,
|
||||
HCI_LE_SET_SCAN_PARAMETERS_COMMAND,
|
||||
HCI_LE_SET_SCAN_ENABLE_COMMAND,
|
||||
HCI_LE_CREATE_CONNECTION_COMMAND,
|
||||
HCI_LE_CREATE_CONNECTION_CANCEL_COMMAND,
|
||||
HCI_LE_READ_FILTER_ACCEPT_LIST_SIZE_COMMAND,
|
||||
HCI_LE_CLEAR_FILTER_ACCEPT_LIST_COMMAND
|
||||
),
|
||||
# Octet 27
|
||||
(
|
||||
HCI_LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST_COMMAND,
|
||||
HCI_LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST_COMMAND,
|
||||
HCI_LE_CONNECTION_UPDATE_COMMAND,
|
||||
HCI_LE_SET_HOST_CHANNEL_CLASSIFICATION_COMMAND,
|
||||
HCI_LE_READ_CHANNEL_MAP_COMMAND,
|
||||
HCI_LE_READ_REMOTE_FEATURES_COMMAND,
|
||||
HCI_LE_ENCRYPT_COMMAND,
|
||||
HCI_LE_RAND_COMMAND
|
||||
),
|
||||
# Octet 28
|
||||
(
|
||||
HCI_LE_ENABLE_ENCRYPTION_COMMAND,
|
||||
HCI_LE_LONG_TERM_KEY_REQUEST_REPLY_COMMAND,
|
||||
HCI_LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY_COMMAND,
|
||||
HCI_LE_READ_SUPPORTED_STATES_COMMAND,
|
||||
HCI_LE_RECEIVER_TEST_COMMAND,
|
||||
HCI_LE_TRANSMITTER_TEST_COMMAND,
|
||||
HCI_LE_TEST_END_COMMAND,
|
||||
None,
|
||||
),
|
||||
# Octet 29
|
||||
(
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
HCI_ENHANCED_SETUP_SYNCHRONOUS_CONNECTION_COMMAND,
|
||||
HCI_ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION_REQUEST_COMMAND,
|
||||
HCI_READ_LOCAL_SUPPORTED_CODECS_COMMAND,
|
||||
HCI_SET_MWS_CHANNEL_PARAMETERS_COMMAND,
|
||||
HCI_SET_EXTERNAL_FRAME_CONFIGURATION_COMMAND
|
||||
),
|
||||
# Octet 30
|
||||
(
|
||||
HCI_SET_MWS_SIGNALING_COMMAND,
|
||||
HCI_SET_MWS_TRANSPORT_LAYER_COMMAND,
|
||||
HCI_SET_MWS_SCAN_FREQUENCY_TABLE_COMMAND,
|
||||
HCI_GET_MWS_TRANSPORT_LAYER_CONFIGURATION_COMMAND,
|
||||
HCI_SET_MWS_PATTERN_CONFIGURATION_COMMAND,
|
||||
HCI_SET_TRIGGERED_CLOCK_CAPTURE_COMMAND,
|
||||
HCI_TRUNCATED_PAGE_COMMAND,
|
||||
HCI_TRUNCATED_PAGE_CANCEL_COMMAND
|
||||
),
|
||||
# Octet 31
|
||||
(
|
||||
HCI_SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_COMMAND,
|
||||
HCI_SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVE_COMMAND,
|
||||
HCI_START_SYNCHRONIZATION_TRAIN_COMMAND,
|
||||
HCI_RECEIVE_SYNCHRONIZATION_TRAIN_COMMAND,
|
||||
HCI_SET_RESERVED_LT_ADDR_COMMAND,
|
||||
HCI_DELETE_RESERVED_LT_ADDR_COMMAND,
|
||||
HCI_SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_DATA_COMMAND,
|
||||
HCI_READ_SYNCHRONIZATION_TRAIN_PARAMETERS_COMMAND
|
||||
),
|
||||
# Octet 32
|
||||
(
|
||||
HCI_WRITE_SYNCHRONIZATION_TRAIN_PARAMETERS_COMMAND,
|
||||
HCI_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_COMMAND,
|
||||
HCI_READ_SECURE_CONNECTIONS_HOST_SUPPORT_COMMAND,
|
||||
HCI_WRITE_SECURE_CONNECTIONS_HOST_SUPPORT_COMMAND,
|
||||
HCI_READ_AUTHENTICATED_PAYLOAD_TIMEOUT_COMMAND,
|
||||
HCI_WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT_COMMAND,
|
||||
HCI_READ_LOCAL_OOB_EXTENDED_DATA_COMMAND,
|
||||
HCI_WRITE_SECURE_CONNECTIONS_TEST_MODE_COMMAND
|
||||
),
|
||||
# Octet 33
|
||||
(
|
||||
HCI_READ_EXTENDED_PAGE_TIMEOUT_COMMAND,
|
||||
HCI_WRITE_EXTENDED_PAGE_TIMEOUT_COMMAND,
|
||||
HCI_READ_EXTENDED_INQUIRY_LENGTH_COMMAND,
|
||||
HCI_WRITE_EXTENDED_INQUIRY_LENGTH_COMMAND,
|
||||
HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY_COMMAND,
|
||||
HCI_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY_COMMAND,
|
||||
HCI_LE_SET_DATA_LENGTH_COMMAND,
|
||||
HCI_LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH_COMMAND
|
||||
),
|
||||
# Octet 34
|
||||
(
|
||||
HCI_LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH_COMMAND,
|
||||
HCI_LE_READ_LOCAL_P_256_PUBLIC_KEY_COMMAND,
|
||||
HCI_LE_GENERATE_DHKEY_COMMAND,
|
||||
HCI_LE_ADD_DEVICE_TO_RESOLVING_LIST_COMMAND,
|
||||
HCI_LE_REMOVE_DEVICE_FROM_RESOLVING_LIST_COMMAND,
|
||||
HCI_LE_CLEAR_RESOLVING_LIST_COMMAND,
|
||||
HCI_LE_READ_RESOLVING_LIST_SIZE_COMMAND,
|
||||
HCI_LE_READ_PEER_RESOLVABLE_ADDRESS_COMMAND
|
||||
),
|
||||
# Octet 35
|
||||
(
|
||||
HCI_LE_READ_LOCAL_RESOLVABLE_ADDRESS_COMMAND,
|
||||
HCI_LE_SET_ADDRESS_RESOLUTION_ENABLE_COMMAND,
|
||||
HCI_LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT_COMMAND,
|
||||
HCI_LE_READ_MAXIMUM_DATA_LENGTH_COMMAND,
|
||||
HCI_LE_READ_PHY_COMMAND,
|
||||
HCI_LE_SET_DEFAULT_PHY_COMMAND,
|
||||
HCI_LE_SET_PHY_COMMAND,
|
||||
HCI_LE_RECEIVER_TEST_V2_COMMAND
|
||||
),
|
||||
# Octet 36
|
||||
(
|
||||
HCI_LE_TRANSMITTER_TEST_V2_COMMAND,
|
||||
HCI_LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_COMMAND,
|
||||
HCI_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_COMMAND,
|
||||
HCI_LE_SET_EXTENDED_ADVERTISING_DATA_COMMAND,
|
||||
HCI_LE_SET_EXTENDED_SCAN_RESPONSE_DATA_COMMAND,
|
||||
HCI_LE_SET_EXTENDED_ADVERTISING_ENABLE_COMMAND,
|
||||
HCI_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH_COMMAND,
|
||||
HCI_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS_COMMAND,
|
||||
),
|
||||
# Octet 37
|
||||
(
|
||||
HCI_LE_REMOVE_ADVERTISING_SET_COMMAND,
|
||||
HCI_LE_CLEAR_ADVERTISING_SETS_COMMAND,
|
||||
HCI_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_COMMAND,
|
||||
HCI_LE_SET_PERIODIC_ADVERTISING_DATA_COMMAND,
|
||||
HCI_LE_SET_PERIODIC_ADVERTISING_ENABLE_COMMAND,
|
||||
HCI_LE_SET_EXTENDED_SCAN_PARAMETERS_COMMAND,
|
||||
HCI_LE_SET_EXTENDED_SCAN_ENABLE_COMMAND,
|
||||
HCI_LE_EXTENDED_CREATE_CONNECTION_COMMAND
|
||||
),
|
||||
# Octet 38
|
||||
(
|
||||
HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC_COMMAND,
|
||||
HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL_COMMAND,
|
||||
HCI_LE_PERIODIC_ADVERTISING_TERMINATE_SYNC_COMMAND,
|
||||
HCI_LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST_COMMAND,
|
||||
HCI_LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST_COMMAND,
|
||||
HCI_LE_CLEAR_PERIODIC_ADVERTISER_LIST_COMMAND,
|
||||
HCI_LE_READ_PERIODIC_ADVERTISER_LIST_SIZE_COMMAND,
|
||||
HCI_LE_READ_TRANSMIT_POWER_COMMAND
|
||||
),
|
||||
# Octet 39
|
||||
(
|
||||
HCI_LE_READ_RF_PATH_COMPENSATION_COMMAND,
|
||||
HCI_LE_WRITE_RF_PATH_COMPENSATION_COMMAND,
|
||||
HCI_LE_SET_PRIVACY_MODE_COMMAND,
|
||||
HCI_LE_RECEIVER_TEST_V3_COMMAND,
|
||||
HCI_LE_TRANSMITTER_TEST_V3_COMMAND,
|
||||
HCI_LE_SET_CONNECTIONLESS_CTE_TRANSMIT_PARAMETERS_COMMAND,
|
||||
HCI_LE_SET_CONNECTIONLESS_CTE_TRANSMIT_ENABLE_COMMAND,
|
||||
HCI_LE_SET_CONNECTIONLESS_IQ_SAMPLING_ENABLE_COMMAND,
|
||||
),
|
||||
# Octet 40
|
||||
(
|
||||
HCI_LE_SET_CONNECTION_CTE_RECEIVE_PARAMETERS_COMMAND,
|
||||
HCI_LE_SET_CONNECTION_CTE_TRANSMIT_PARAMETERS_COMMAND,
|
||||
HCI_LE_CONNECTION_CTE_REQUEST_ENABLE_COMMAND,
|
||||
HCI_LE_CONNECTION_CTE_RESPONSE_ENABLE_COMMAND,
|
||||
HCI_LE_READ_ANTENNA_INFORMATION_COMMAND,
|
||||
HCI_LE_SET_PERIODIC_ADVERTISING_RECEIVE_ENABLE_COMMAND,
|
||||
HCI_LE_PERIODIC_ADVERTISING_SYNC_TRANSFER_COMMAND,
|
||||
HCI_LE_PERIODIC_ADVERTISING_SET_INFO_TRANSFER_COMMAND
|
||||
),
|
||||
# Octet 41
|
||||
(
|
||||
HCI_LE_SET_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS_COMMAND,
|
||||
HCI_LE_SET_DEFAULT_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS_COMMAND,
|
||||
HCI_LE_GENERATE_DHKEY_V2_COMMAND,
|
||||
HCI_READ_LOCAL_SIMPLE_PAIRING_OPTIONS_COMMAND,
|
||||
HCI_LE_MODIFY_SLEEP_CLOCK_ACCURACY_COMMAND,
|
||||
HCI_LE_READ_BUFFER_SIZE_V2_COMMAND,
|
||||
HCI_LE_READ_ISO_TX_SYNC_COMMAND,
|
||||
HCI_LE_SET_CIG_PARAMETERS_COMMAND
|
||||
),
|
||||
# Octet 42
|
||||
(
|
||||
HCI_LE_SET_CIG_PARAMETERS_TEST_COMMAND,
|
||||
HCI_LE_CREATE_CIS_COMMAND,
|
||||
HCI_LE_REMOVE_CIG_COMMAND,
|
||||
HCI_LE_ACCEPT_CIS_REQUEST_COMMAND,
|
||||
HCI_LE_REJECT_CIS_REQUEST_COMMAND,
|
||||
HCI_LE_CREATE_BIG_COMMAND,
|
||||
HCI_LE_CREATE_BIG_TEST_COMMAND,
|
||||
HCI_LE_TERMINATE_BIG_COMMAND,
|
||||
),
|
||||
# Octet 43
|
||||
(
|
||||
HCI_LE_BIG_CREATE_SYNC_COMMAND,
|
||||
HCI_LE_BIG_TERMINATE_SYNC_COMMAND,
|
||||
HCI_LE_REQUEST_PEER_SCA_COMMAND,
|
||||
HCI_LE_SETUP_ISO_DATA_PATH_COMMAND,
|
||||
HCI_LE_REMOVE_ISO_DATA_PATH_COMMAND,
|
||||
HCI_LE_ISO_TRANSMIT_TEST_COMMAND,
|
||||
HCI_LE_ISO_RECEIVE_TEST_COMMAND,
|
||||
HCI_LE_ISO_READ_TEST_COUNTERS_COMMAND
|
||||
),
|
||||
# Octet 44
|
||||
(
|
||||
HCI_LE_ISO_TEST_END_COMMAND,
|
||||
HCI_LE_SET_HOST_FEATURE_COMMAND,
|
||||
HCI_LE_READ_ISO_LINK_QUALITY_COMMAND,
|
||||
HCI_LE_ENHANCED_READ_TRANSMIT_POWER_LEVEL_COMMAND,
|
||||
HCI_LE_READ_REMOTE_TRANSMIT_POWER_LEVEL_COMMAND,
|
||||
HCI_LE_SET_PATH_LOSS_REPORTING_PARAMETERS_COMMAND,
|
||||
HCI_LE_SET_PATH_LOSS_REPORTING_ENABLE_COMMAND,
|
||||
HCI_LE_SET_TRANSMIT_POWER_REPORTING_ENABLE_COMMAND
|
||||
),
|
||||
# Octet 45
|
||||
(
|
||||
HCI_LE_TRANSMITTER_TEST_V4_COMMAND,
|
||||
HCI_SET_ECOSYSTEM_BASE_INTERVAL_COMMAND,
|
||||
HCI_READ_LOCAL_SUPPORTED_CODECS_V2_COMMAND,
|
||||
HCI_READ_LOCAL_SUPPORTED_CODEC_CAPABILITIES_COMMAND,
|
||||
HCI_READ_LOCAL_SUPPORTED_CONTROLLER_DELAY_COMMAND,
|
||||
HCI_CONFIGURE_DATA_PATH_COMMAND,
|
||||
HCI_LE_SET_DATA_RELATED_ADDRESS_CHANGES_COMMAND,
|
||||
HCI_SET_MIN_ENCRYPTION_KEY_SIZE_COMMAND
|
||||
),
|
||||
# Octet 46
|
||||
(
|
||||
HCI_LE_SET_DEFAULT_SUBRATE_COMMAND,
|
||||
HCI_LE_SUBRATE_REQUEST_COMMAND,
|
||||
HCI_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_V2_COMMAND,
|
||||
None,
|
||||
None,
|
||||
HCI_LE_SET_PERIODIC_ADVERTISING_SUBEVENT_DATA_COMMAND,
|
||||
HCI_LE_SET_PERIODIC_ADVERTISING_RESPONSE_DATA_COMMAND,
|
||||
HCI_LE_SET_PERIODIC_SYNC_SUBEVENT_COMMAND
|
||||
),
|
||||
# Octet 47
|
||||
(
|
||||
HCI_LE_EXTENDED_CREATE_CONNECTION_V2_COMMAND,
|
||||
HCI_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_V2_COMMAND,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
)
|
||||
)
|
||||
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_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_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_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_READ_ENHANCED_TRANSMIT_POWER_LEVEL_COMMAND : 1 << (24*8+0),
|
||||
HCI_READ_LE_HOST_SUPPORT_COMMAND : 1 << (24*8+5),
|
||||
HCI_WRITE_LE_HOST_SUPPORT_COMMAND : 1 << (24*8+6),
|
||||
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_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_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),
|
||||
}
|
||||
|
||||
# LE Supported Features
|
||||
# See Bluetooth spec @ Vol 6, Part B, 4.6 FEATURE SUPPORT
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable, MutableMapping
|
||||
import datetime
|
||||
from typing import cast, Any, Optional
|
||||
import logging
|
||||
|
||||
@@ -66,12 +67,13 @@ PSM_NAMES = {
|
||||
rfcomm.RFCOMM_PSM: 'RFCOMM',
|
||||
sdp.SDP_PSM: 'SDP',
|
||||
avdtp.AVDTP_PSM: 'AVDTP',
|
||||
avctp.AVCTP_PSM: 'AVCTP'
|
||||
avctp.AVCTP_PSM: 'AVCTP',
|
||||
# TODO: add more PSM values
|
||||
}
|
||||
|
||||
AVCTP_PID_NAMES = {avrcp.AVRCP_PID: 'AVRCP'}
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
class PacketTracer:
|
||||
class AclStream:
|
||||
@@ -207,6 +209,7 @@ class PacketTracer:
|
||||
self.label = label
|
||||
self.emit_message = emit_message
|
||||
self.acl_streams = {} # ACL streams, by connection handle
|
||||
self.packet_timestamp: Optional[datetime.datetime] = None
|
||||
|
||||
def start_acl_stream(self, connection_handle: int) -> PacketTracer.AclStream:
|
||||
logger.info(
|
||||
@@ -234,7 +237,10 @@ class PacketTracer:
|
||||
# Let the other forwarder know so it can cleanup its stream as well
|
||||
self.peer.end_acl_stream(connection_handle)
|
||||
|
||||
def on_packet(self, packet: HCI_Packet) -> None:
|
||||
def on_packet(
|
||||
self, timestamp: Optional[datetime.datetime], packet: HCI_Packet
|
||||
) -> None:
|
||||
self.packet_timestamp = timestamp
|
||||
self.emit(packet)
|
||||
|
||||
if packet.hci_packet_type == HCI_ACL_DATA_PACKET:
|
||||
@@ -254,13 +260,22 @@ class PacketTracer:
|
||||
)
|
||||
|
||||
def emit(self, message: Any) -> None:
|
||||
self.emit_message(f'[{self.label}] {message}')
|
||||
if self.packet_timestamp:
|
||||
prefix = f"[{self.packet_timestamp.strftime('%Y-%m-%d %H:%M:%S.%f')}]"
|
||||
else:
|
||||
prefix = ""
|
||||
self.emit_message(f'{prefix}[{self.label}] {message}')
|
||||
|
||||
def trace(self, packet: HCI_Packet, direction: int = 0) -> None:
|
||||
def trace(
|
||||
self,
|
||||
packet: HCI_Packet,
|
||||
direction: int = 0,
|
||||
timestamp: Optional[datetime.datetime] = None,
|
||||
) -> None:
|
||||
if direction == 0:
|
||||
self.host_to_controller_analyzer.on_packet(packet)
|
||||
self.host_to_controller_analyzer.on_packet(timestamp, packet)
|
||||
else:
|
||||
self.controller_to_host_analyzer.on_packet(packet)
|
||||
self.controller_to_host_analyzer.on_packet(timestamp, packet)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
|
||||
@@ -22,7 +22,17 @@ import dataclasses
|
||||
import logging
|
||||
import struct
|
||||
|
||||
from typing import Any, Awaitable, Callable, Deque, Dict, Optional, cast, TYPE_CHECKING
|
||||
from typing import (
|
||||
Any,
|
||||
Awaitable,
|
||||
Callable,
|
||||
Deque,
|
||||
Dict,
|
||||
Optional,
|
||||
Set,
|
||||
cast,
|
||||
TYPE_CHECKING,
|
||||
)
|
||||
|
||||
from bumble.colors import color
|
||||
from bumble.l2cap import L2CAP_PDU
|
||||
@@ -165,7 +175,7 @@ class Host(AbortableEventEmitter):
|
||||
self.number_of_supported_advertising_sets = 0
|
||||
self.maximum_advertising_data_length = 31
|
||||
self.local_version = None
|
||||
self.local_supported_commands = bytes(64)
|
||||
self.local_supported_commands = 0
|
||||
self.local_le_features = 0
|
||||
self.local_lmp_features = hci.LmpFeatureMask(0) # Classic LMP features
|
||||
self.suggested_max_tx_octets = 251 # Max allowed
|
||||
@@ -232,7 +242,9 @@ class Host(AbortableEventEmitter):
|
||||
response = await self.send_command(
|
||||
hci.HCI_Read_Local_Supported_Commands_Command(), check_result=True
|
||||
)
|
||||
self.local_supported_commands = response.return_parameters.supported_commands
|
||||
self.local_supported_commands = int.from_bytes(
|
||||
response.return_parameters.supported_commands, 'little'
|
||||
)
|
||||
|
||||
if self.supports_command(hci.HCI_LE_READ_LOCAL_SUPPORTED_FEATURES_COMMAND):
|
||||
response = await self.send_command(
|
||||
@@ -486,7 +498,7 @@ class Host(AbortableEventEmitter):
|
||||
def controller(self, controller) -> None:
|
||||
self.set_packet_sink(controller)
|
||||
if controller:
|
||||
controller.set_packet_sink(self)
|
||||
self.set_packet_source(controller)
|
||||
|
||||
def set_packet_sink(self, sink: Optional[TransportSink]) -> None:
|
||||
self.hci_sink = sink
|
||||
@@ -583,31 +595,19 @@ class Host(AbortableEventEmitter):
|
||||
offset += data_total_length
|
||||
bytes_remaining -= data_total_length
|
||||
|
||||
def supports_command(self, command):
|
||||
# Find the support flag position for this command
|
||||
for octet, flags in enumerate(hci.HCI_SUPPORTED_COMMANDS_FLAGS):
|
||||
for flag_position, value in enumerate(flags):
|
||||
if value == command:
|
||||
# Check if the flag is set
|
||||
if octet < len(self.local_supported_commands) and flag_position < 8:
|
||||
return (
|
||||
self.local_supported_commands[octet] & (1 << flag_position)
|
||||
) != 0
|
||||
|
||||
return False
|
||||
def supports_command(self, op_code: int) -> bool:
|
||||
return (
|
||||
self.local_supported_commands
|
||||
& hci.HCI_SUPPORTED_COMMANDS_MASKS.get(op_code, 0)
|
||||
) != 0
|
||||
|
||||
@property
|
||||
def supported_commands(self):
|
||||
commands = []
|
||||
for octet, flags in enumerate(self.local_supported_commands):
|
||||
if octet < len(hci.HCI_SUPPORTED_COMMANDS_FLAGS):
|
||||
for flag in range(8):
|
||||
if flags & (1 << flag) != 0:
|
||||
command = hci.HCI_SUPPORTED_COMMANDS_FLAGS[octet][flag]
|
||||
if command is not None:
|
||||
commands.append(command)
|
||||
|
||||
return commands
|
||||
def supported_commands(self) -> Set[int]:
|
||||
return set(
|
||||
op_code
|
||||
for op_code, mask in hci.HCI_SUPPORTED_COMMANDS_MASKS.items()
|
||||
if self.local_supported_commands & mask
|
||||
)
|
||||
|
||||
def supports_le_features(self, feature: hci.LeFeatureMask) -> bool:
|
||||
return (self.local_le_features & feature) == feature
|
||||
|
||||
@@ -34,8 +34,11 @@ from bumble.device import (
|
||||
DEVICE_DEFAULT_SCAN_INTERVAL,
|
||||
DEVICE_DEFAULT_SCAN_WINDOW,
|
||||
Advertisement,
|
||||
AdvertisingParameters,
|
||||
AdvertisingEventProperties,
|
||||
AdvertisingType,
|
||||
Device,
|
||||
Phy,
|
||||
)
|
||||
from bumble.gatt import Service
|
||||
from bumble.hci import (
|
||||
@@ -47,6 +50,7 @@ from bumble.hci import (
|
||||
from google.protobuf import any_pb2 # pytype: disable=pyi-error
|
||||
from google.protobuf import empty_pb2 # pytype: disable=pyi-error
|
||||
from pandora.host_grpc_aio import HostServicer
|
||||
from pandora import host_pb2
|
||||
from pandora.host_pb2 import (
|
||||
NOT_CONNECTABLE,
|
||||
NOT_DISCOVERABLE,
|
||||
@@ -94,6 +98,25 @@ SECONDARY_PHY_MAP: Dict[int, SecondaryPhy] = {
|
||||
3: SECONDARY_CODED,
|
||||
}
|
||||
|
||||
PRIMARY_PHY_TO_BUMBLE_PHY_MAP: Dict[PrimaryPhy, Phy] = {
|
||||
PRIMARY_1M: Phy.LE_1M,
|
||||
PRIMARY_CODED: Phy.LE_CODED,
|
||||
}
|
||||
|
||||
SECONDARY_PHY_TO_BUMBLE_PHY_MAP: Dict[SecondaryPhy, Phy] = {
|
||||
SECONDARY_NONE: Phy.LE_1M,
|
||||
SECONDARY_1M: Phy.LE_1M,
|
||||
SECONDARY_2M: Phy.LE_2M,
|
||||
SECONDARY_CODED: Phy.LE_CODED,
|
||||
}
|
||||
|
||||
OWN_ADDRESS_MAP: Dict[host_pb2.OwnAddressType, bumble.hci.OwnAddressType] = {
|
||||
host_pb2.PUBLIC: bumble.hci.OwnAddressType.PUBLIC,
|
||||
host_pb2.RANDOM: bumble.hci.OwnAddressType.RANDOM,
|
||||
host_pb2.RESOLVABLE_OR_PUBLIC: bumble.hci.OwnAddressType.RESOLVABLE_OR_PUBLIC,
|
||||
host_pb2.RESOLVABLE_OR_RANDOM: bumble.hci.OwnAddressType.RESOLVABLE_OR_RANDOM,
|
||||
}
|
||||
|
||||
|
||||
class HostService(HostServicer):
|
||||
waited_connections: Set[int]
|
||||
@@ -281,10 +304,113 @@ class HostService(HostServicer):
|
||||
async def Advertise(
|
||||
self, request: AdvertiseRequest, context: grpc.ServicerContext
|
||||
) -> AsyncGenerator[AdvertiseResponse, None]:
|
||||
if not request.legacy:
|
||||
raise NotImplementedError(
|
||||
"TODO: add support for extended advertising in Bumble"
|
||||
try:
|
||||
if request.legacy:
|
||||
async for rsp in self.legacy_advertise(request, context):
|
||||
yield rsp
|
||||
else:
|
||||
async for rsp in self.extended_advertise(request, context):
|
||||
yield rsp
|
||||
finally:
|
||||
pass
|
||||
|
||||
async def extended_advertise(
|
||||
self, request: AdvertiseRequest, context: grpc.ServicerContext
|
||||
) -> AsyncGenerator[AdvertiseResponse, None]:
|
||||
advertising_data = bytes(self.unpack_data_types(request.data))
|
||||
scan_response_data = bytes(self.unpack_data_types(request.scan_response_data))
|
||||
scannable = len(scan_response_data) != 0
|
||||
|
||||
advertising_event_properties = AdvertisingEventProperties(
|
||||
is_connectable=request.connectable,
|
||||
is_scannable=scannable,
|
||||
is_directed=request.target is not None,
|
||||
is_high_duty_cycle_directed_connectable=False,
|
||||
is_legacy=False,
|
||||
is_anonymous=False,
|
||||
include_tx_power=False,
|
||||
)
|
||||
|
||||
peer_address = Address.ANY
|
||||
if request.target:
|
||||
# Need to reverse bytes order since Bumble Address is using MSB.
|
||||
target_bytes = bytes(reversed(request.target))
|
||||
if request.target_variant() == "public":
|
||||
peer_address = Address(target_bytes, Address.PUBLIC_DEVICE_ADDRESS)
|
||||
else:
|
||||
peer_address = Address(target_bytes, Address.RANDOM_DEVICE_ADDRESS)
|
||||
|
||||
advertising_parameters = AdvertisingParameters(
|
||||
advertising_event_properties=advertising_event_properties,
|
||||
own_address_type=OWN_ADDRESS_MAP[request.own_address_type],
|
||||
peer_address=peer_address,
|
||||
primary_advertising_phy=PRIMARY_PHY_TO_BUMBLE_PHY_MAP[request.primary_phy],
|
||||
secondary_advertising_phy=SECONDARY_PHY_TO_BUMBLE_PHY_MAP[
|
||||
request.secondary_phy
|
||||
],
|
||||
)
|
||||
if advertising_interval := request.interval:
|
||||
advertising_parameters.primary_advertising_interval_min = int(
|
||||
advertising_interval
|
||||
)
|
||||
advertising_parameters.primary_advertising_interval_max = int(
|
||||
advertising_interval
|
||||
)
|
||||
if interval_range := request.interval_range:
|
||||
advertising_parameters.primary_advertising_interval_max += int(
|
||||
interval_range
|
||||
)
|
||||
|
||||
advertising_set = await self.device.create_advertising_set(
|
||||
advertising_parameters=advertising_parameters,
|
||||
advertising_data=advertising_data,
|
||||
scan_response_data=scan_response_data,
|
||||
)
|
||||
|
||||
pending_connection: asyncio.Future[
|
||||
bumble.device.Connection
|
||||
] = asyncio.get_running_loop().create_future()
|
||||
|
||||
if request.connectable:
|
||||
|
||||
def on_connection(connection: bumble.device.Connection) -> None:
|
||||
if (
|
||||
connection.transport == BT_LE_TRANSPORT
|
||||
and connection.role == BT_PERIPHERAL_ROLE
|
||||
):
|
||||
pending_connection.set_result(connection)
|
||||
|
||||
self.device.on('connection', on_connection)
|
||||
|
||||
try:
|
||||
# Advertise until RPC is canceled
|
||||
while True:
|
||||
if not advertising_set.enabled:
|
||||
self.log.debug('Advertise (extended)')
|
||||
await advertising_set.start()
|
||||
|
||||
if not request.connectable:
|
||||
await asyncio.sleep(1)
|
||||
continue
|
||||
|
||||
connection = await pending_connection
|
||||
pending_connection = asyncio.get_running_loop().create_future()
|
||||
|
||||
cookie = any_pb2.Any(value=connection.handle.to_bytes(4, 'big'))
|
||||
yield AdvertiseResponse(connection=Connection(cookie=cookie))
|
||||
|
||||
await asyncio.sleep(1)
|
||||
finally:
|
||||
try:
|
||||
self.log.debug('Stop Advertise (extended)')
|
||||
await advertising_set.stop()
|
||||
await advertising_set.remove()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
async def legacy_advertise(
|
||||
self, request: AdvertiseRequest, context: grpc.ServicerContext
|
||||
) -> AsyncGenerator[AdvertiseResponse, None]:
|
||||
if advertising_interval := request.interval:
|
||||
self.device.config.advertising_interval_min = int(advertising_interval)
|
||||
self.device.config.advertising_interval_max = int(advertising_interval)
|
||||
@@ -422,11 +548,16 @@ class HostService(HostServicer):
|
||||
self, request: ScanRequest, context: grpc.ServicerContext
|
||||
) -> AsyncGenerator[ScanningResponse, None]:
|
||||
# TODO: modify `start_scanning` to accept floats instead of int for ms values
|
||||
if request.phys:
|
||||
raise NotImplementedError("TODO: add support for `request.phys`")
|
||||
|
||||
self.log.debug('Scan')
|
||||
|
||||
scanning_phys = []
|
||||
if PRIMARY_1M in request.phys:
|
||||
scanning_phys.append(int(Phy.LE_1M))
|
||||
if PRIMARY_CODED in request.phys:
|
||||
scanning_phys.append(int(Phy.LE_CODED))
|
||||
if not scanning_phys:
|
||||
scanning_phys = [int(Phy.LE_1M), int(Phy.LE_CODED)]
|
||||
|
||||
scan_queue: asyncio.Queue[Advertisement] = asyncio.Queue()
|
||||
handler = self.device.on('advertisement', scan_queue.put_nowait)
|
||||
await self.device.start_scanning(
|
||||
@@ -439,6 +570,7 @@ class HostService(HostServicer):
|
||||
scan_window=int(request.window)
|
||||
if request.window
|
||||
else DEVICE_DEFAULT_SCAN_WINDOW,
|
||||
scanning_phys=scanning_phys,
|
||||
)
|
||||
|
||||
try:
|
||||
|
||||
@@ -168,11 +168,13 @@ class PacketReader:
|
||||
|
||||
def __init__(self, source: io.BufferedReader) -> None:
|
||||
self.source = source
|
||||
self.at_end = False
|
||||
|
||||
def next_packet(self) -> Optional[bytes]:
|
||||
# Get the packet type
|
||||
packet_type = self.source.read(1)
|
||||
if len(packet_type) != 1:
|
||||
self.at_end = True
|
||||
return None
|
||||
|
||||
# Get the packet info based on its type
|
||||
|
||||
@@ -12,12 +12,25 @@ a host that send custom HCI commands that the controller may not understand.
|
||||
```
|
||||
python hci_bridge.py <host-transport-spec> <controller-transport-spec> [command-short-circuit-list]
|
||||
```
|
||||
The command-short-circuit-list field is specified by a series of comma separated Opcode Group
|
||||
Field (OGF) : OpCode Command Field (OCF) pairs. The OGF/OCF values are specified in the Blutooth
|
||||
core specification.
|
||||
|
||||
For the commands that are listed in the short-circuit-list, the HCI bridge will always generate
|
||||
a Command Complete Event for the specified op code. The return parameter will be HCI_SUCCESS.
|
||||
|
||||
This feature can only be used for commands that return Command Complete. Other events will not be
|
||||
generated by the HCI bridge tool.
|
||||
|
||||
!!! example "UDP to Serial"
|
||||
```
|
||||
python hci_bridge.py udp:0.0.0.0:9000,127.0.0.1:9001 serial:/dev/tty.usbmodem0006839912171,1000000 0x3f:0x0070,0x3f:0x0074,0x3f:0x0077,0x3f:0x0078
|
||||
```
|
||||
|
||||
In this example, the short circuit list is specified to respond to the Vendor-specific Opcode Group
|
||||
Field (0x3f) commands 0x70, 0x74, 0x77, 0x78 with Command Complete. The short circuit list can be
|
||||
used where the Host uses some HCI commands that are not supported/implemented by the Controller.
|
||||
|
||||
!!! example "PTY to Link Relay"
|
||||
```
|
||||
python hci_bridge.py serial:emulated_uart_pty,1000000 link-relay:ws://127.0.0.1:10723/test
|
||||
@@ -28,3 +41,4 @@ a host that send custom HCI commands that the controller may not understand.
|
||||
(through which the communication with other virtual controllers will be mediated).
|
||||
|
||||
NOTE: this assumes you're running a Link Relay on port `10723`.
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ used with particular HCI controller.
|
||||
When the transport for an HCI controller is instantiated from a transport name,
|
||||
a driver may also be forced by specifying ``driver=<driver-name>`` in the optional
|
||||
metadata portion of the transport name. For example,
|
||||
``usb:[driver=-rtk]0`` indicates that the ``rtk`` driver should be used with the
|
||||
``usb:[driver=rtk]0`` indicates that the ``rtk`` driver should be used with the
|
||||
first USB device, even if a normal probe would not have selected it based on the
|
||||
USB vendor ID and product ID.
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ documentation = "https://docs.rs/crate/bumble"
|
||||
authors = ["Marshall Pierce <marshallpierce@google.com>"]
|
||||
keywords = ["bluetooth", "ble"]
|
||||
categories = ["api-bindings", "network-programming"]
|
||||
rust-version = "1.70.0"
|
||||
rust-version = "1.76.0"
|
||||
|
||||
# https://github.com/frewsxcv/cargo-all-features#options
|
||||
[package.metadata.cargo-all-features]
|
||||
|
||||
Reference in New Issue
Block a user