Compare commits

...

4 Commits

Author SHA1 Message Date
Gilles Boccon-Gibod
a6ead0147e fix #722 2025-07-28 13:36:55 -07:00
Gilles Boccon-Gibod
0665e9ca5c Merge pull request #731 from google/gbg/common-logger
use common logger
2025-07-28 10:22:30 -07:00
Gilles Boccon-Gibod
b8b78ca1ee add missing file 2025-07-27 15:02:42 -07:00
Gilles Boccon-Gibod
d611d25802 resolve merge conflicts 2025-07-26 21:20:52 -07:00
71 changed files with 331 additions and 385 deletions

View File

@@ -102,5 +102,7 @@
"."
],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true
"python.testing.pytestEnabled": true,
"python-envs.defaultEnvManager": "ms-python.python:system",
"python-envs.pythonProjects": []
}

View File

@@ -23,7 +23,6 @@ import contextlib
import dataclasses
import functools
import logging
import os
import struct
from typing import (
Any,
@@ -54,6 +53,8 @@ from bumble.profiles import bass
import bumble.device
import bumble.transport
import bumble.utils
import bumble.logging
# -----------------------------------------------------------------------------
# Logging
@@ -1235,7 +1236,7 @@ def transmit(
def main():
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'INFO').upper())
bumble.logging.setup_basic_logging()
auracast()

View File

@@ -19,7 +19,6 @@ import asyncio
import dataclasses
import enum
import logging
import os
import statistics
import struct
import time
@@ -70,6 +69,7 @@ import bumble.rfcomm
import bumble.core
from bumble.utils import AsyncRunner
from bumble.pairing import PairingConfig
import bumble.logging
# -----------------------------------------------------------------------------
@@ -2321,11 +2321,7 @@ def peripheral(ctx, transport):
def main():
logging.basicConfig(
level=os.environ.get('BUMBLE_LOGLEVEL', 'INFO').upper(),
format="[%(asctime)s.%(msecs)03d] %(levelname)s:%(name)s:%(message)s",
datefmt="%H:%M:%S",
)
bumble.logging.setup_basic_logging('INFO')
bench()

View File

@@ -16,8 +16,6 @@
# Imports
# -----------------------------------------------------------------------------
import asyncio
import os
import logging
import time
import click
@@ -59,6 +57,7 @@ from bumble.hci import (
)
from bumble.host import Host
from bumble.transport import open_transport
import bumble.logging
# -----------------------------------------------------------------------------
@@ -342,11 +341,7 @@ async def async_main(
)
@click.argument('transport')
def main(latency_probes, latency_probe_interval, latency_probe_command, transport):
logging.basicConfig(
level=os.environ.get('BUMBLE_LOGLEVEL', 'INFO').upper(),
format="[%(asctime)s.%(msecs)03d] %(levelname)s:%(name)s:%(message)s",
datefmt="%H:%M:%S",
)
bumble.logging.setup_basic_logging()
asyncio.run(
async_main(
latency_probes, latency_probe_interval, latency_probe_command, transport

View File

@@ -16,10 +16,11 @@
# Imports
# -----------------------------------------------------------------------------
import asyncio
import logging
import os
import time
from typing import Optional
import click
from bumble.colors import color
from bumble.hci import (
HCI_READ_LOOPBACK_MODE_COMMAND,
@@ -30,7 +31,7 @@ from bumble.hci import (
)
from bumble.host import Host
from bumble.transport import open_transport
import click
import bumble.logging
class Loopback:
@@ -194,12 +195,7 @@ class Loopback:
)
@click.argument('transport')
def main(packet_size, packet_count, transport):
logging.basicConfig(
level=os.environ.get('BUMBLE_LOGLEVEL', 'INFO').upper(),
format="[%(asctime)s.%(msecs)03d] %(levelname)s:%(name)s:%(message)s",
datefmt="%H:%M:%S",
)
bumble.logging.setup_basic_logging()
loopback = Loopback(packet_size, packet_count, transport)
asyncio.run(loopback.run())

View File

@@ -15,14 +15,13 @@
# -----------------------------------------------------------------------------
# Imports
# -----------------------------------------------------------------------------
import logging
import asyncio
import sys
import os
from bumble.controller import Controller
from bumble.link import LocalLink
from bumble.transport import open_transport
import bumble.logging
# -----------------------------------------------------------------------------
@@ -62,7 +61,7 @@ async def async_main():
# -----------------------------------------------------------------------------
def main():
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'INFO').upper())
bumble.logging.setup_basic_logging()
asyncio.run(async_main())

View File

@@ -16,8 +16,6 @@
# Imports
# -----------------------------------------------------------------------------
import asyncio
import os
import logging
from typing import Callable, Iterable, Optional
import click
@@ -33,6 +31,7 @@ from bumble.profiles.pacs import PublishedAudioCapabilitiesServiceProxy
from bumble.profiles.tmap import TelephonyAndMediaAudioServiceProxy
from bumble.profiles.vcs import VolumeControlServiceProxy
from bumble.transport import open_transport
import bumble.logging
# -----------------------------------------------------------------------------
@@ -267,7 +266,7 @@ def main(device_config, encrypt, transport, address_or_name):
Dump the GATT database on a remote device. If ADDRESS_OR_NAME is not specified,
wait for an incoming connection.
"""
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'INFO').upper())
bumble.logging.setup_basic_logging()
asyncio.run(async_main(device_config, encrypt, transport, address_or_name))

View File

@@ -16,8 +16,7 @@
# Imports
# -----------------------------------------------------------------------------
import asyncio
import os
import logging
import click
import bumble.core
@@ -25,6 +24,7 @@ from bumble.colors import color
from bumble.device import Device, Peer
from bumble.gatt import show_services
from bumble.transport import open_transport
import bumble.logging
# -----------------------------------------------------------------------------
@@ -112,7 +112,7 @@ def main(device_config, encrypt, transport, address_or_name):
Dump the GATT database on a remote device. If ADDRESS_OR_NAME is not specified,
wait for an incoming connection.
"""
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'INFO').upper())
bumble.logging.setup_basic_logging()
asyncio.run(async_main(device_config, encrypt, transport, address_or_name))

View File

@@ -16,9 +16,8 @@
# Imports
# -----------------------------------------------------------------------------
import asyncio
import os
import struct
import logging
import click
from bumble import l2cap
@@ -29,6 +28,7 @@ from bumble.gatt import Service, Characteristic, CharacteristicValue
from bumble.utils import AsyncRunner
from bumble.transport import open_transport
from bumble.hci import HCI_Constant
import bumble.logging
# -----------------------------------------------------------------------------
@@ -383,6 +383,7 @@ def main(
receive_host,
receive_port,
):
bumble.logging.setup_basic_logging('WARNING')
asyncio.run(
run(
hci_transport,
@@ -397,6 +398,5 @@ def main(
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'WARNING').upper())
if __name__ == '__main__':
main()

View File

@@ -17,11 +17,12 @@
# -----------------------------------------------------------------------------
import logging
import asyncio
import os
import sys
from bumble import hci, transport
from bumble.bridge import HCI_Bridge
import bumble.logging
# -----------------------------------------------------------------------------
# Logging
@@ -100,7 +101,7 @@ async def async_main():
# -----------------------------------------------------------------------------
def main():
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'INFO').upper())
bumble.logging.setup_basic_logging()
asyncio.run(async_main())

View File

@@ -16,8 +16,7 @@
# Imports
# -----------------------------------------------------------------------------
import asyncio
import logging
import os
import click
from bumble import l2cap
@@ -26,6 +25,7 @@ from bumble.transport import open_transport
from bumble.device import Device
from bumble.utils import FlowControlAsyncPipe
from bumble.hci import HCI_Constant
import bumble.logging
# -----------------------------------------------------------------------------
@@ -356,6 +356,6 @@ def client(context, bluetooth_address, tcp_host, tcp_port):
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'WARNING').upper())
if __name__ == '__main__':
bumble.logging.setup_basic_logging('WARNING')
cli(obj={}) # pylint: disable=no-value-for-parameter

View File

@@ -22,7 +22,6 @@ import datetime
import functools
from importlib import resources
import json
import os
import logging
import pathlib
import weakref
@@ -44,6 +43,7 @@ from bumble.device import Device, DeviceConfiguration, AdvertisingParameters, Ci
from bumble.transport import open_transport
from bumble.profiles import ascs, bap, pacs
from bumble.hci import Address, CodecID, CodingFormat, HCI_IsoDataPacket
import bumble.logging
# -----------------------------------------------------------------------------
@@ -454,7 +454,7 @@ def speaker(ui_port: int, device_config: str, transport: str, lc3_file: str) ->
# -----------------------------------------------------------------------------
def main():
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'INFO').upper())
bumble.logging.setup_basic_logging()
speaker()

View File

@@ -17,8 +17,6 @@
# -----------------------------------------------------------------------------
from __future__ import annotations
import asyncio
import asyncio.subprocess
import os
import logging
from typing import Optional, Union
@@ -63,6 +61,7 @@ from bumble.hci import Address, HCI_CONNECTION_ALREADY_EXISTS_ERROR, HCI_Constan
from bumble.pairing import PairingConfig
from bumble.transport import open_transport
from bumble.utils import AsyncRunner
import bumble.logging
# -----------------------------------------------------------------------------
@@ -599,7 +598,7 @@ def play(context, address, audio_format, audio_file):
# -----------------------------------------------------------------------------
def main():
logging.basicConfig(level=os.environ.get("BUMBLE_LOGLEVEL", "WARNING").upper())
bumble.logging.setup_basic_logging("WARNING")
player_cli()

View File

@@ -16,8 +16,6 @@
# Imports
# -----------------------------------------------------------------------------
import asyncio
import logging
import os
import time
from typing import Optional
@@ -30,6 +28,7 @@ from bumble import hci
from bumble import rfcomm
from bumble import transport
from bumble import utils
import bumble.logging
# -----------------------------------------------------------------------------
@@ -515,6 +514,6 @@ def client(context, bluetooth_address, tcp_host, tcp_port, authenticate, encrypt
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get("BUMBLE_LOGLEVEL", "WARNING").upper())
if __name__ == "__main__":
bumble.logging.setup_basic_logging("WARNING")
cli(obj={}) # pylint: disable=no-value-for-parameter

View File

@@ -16,8 +16,6 @@
# Imports
# -----------------------------------------------------------------------------
import asyncio
import os
import logging
import click
from bumble.colors import color
@@ -27,6 +25,7 @@ from bumble.keys import JsonKeyStore
from bumble.smp import AddressResolver
from bumble.device import Advertisement
from bumble.hci import Address, HCI_Constant, HCI_LE_1M_PHY, HCI_LE_CODED_PHY
import bumble.logging
# -----------------------------------------------------------------------------
@@ -237,7 +236,7 @@ def main(
device_config,
transport,
):
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'WARNING').upper())
bumble.logging.setup_basic_logging('WARNING')
asyncio.run(
scan(
min_rssi,

View File

@@ -18,7 +18,6 @@
import datetime
import importlib
import logging
import os
import struct
import click
@@ -27,6 +26,7 @@ from bumble.colors import color
from bumble import hci
from bumble.transport.common import PacketReader
from bumble.helpers import PacketTracer
import bumble.logging
# -----------------------------------------------------------------------------
@@ -188,5 +188,5 @@ def main(format, vendor, filename):
# -----------------------------------------------------------------------------
if __name__ == '__main__':
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'WARNING').upper())
bumble.logging.setup_basic_logging('WARNING')
main() # pylint: disable=no-value-for-parameter

View File

@@ -21,7 +21,6 @@ import asyncio.subprocess
from importlib import resources
import enum
import json
import os
import logging
import pathlib
import subprocess
@@ -58,6 +57,7 @@ from bumble.a2dp import (
from bumble.utils import AsyncRunner
from bumble.codecs import AacAudioRtpPacket
from bumble.rtp import MediaPacket
import bumble.logging
# -----------------------------------------------------------------------------
@@ -833,11 +833,7 @@ def speaker(
# -----------------------------------------------------------------------------
def main():
logging.basicConfig(
level=os.environ.get('BUMBLE_LOGLEVEL', 'WARNING').upper(),
format="[%(asctime)s.%(msecs)03d] %(levelname)s:%(name)s:%(message)s",
datefmt="%H:%M:%S",
)
bumble.logging.setup_basic_logging('WARNING')
speaker()

View File

@@ -16,13 +16,12 @@
# Imports
# -----------------------------------------------------------------------------
import asyncio
import os
import logging
import click
from bumble.device import Device
from bumble.keys import JsonKeyStore
from bumble.transport import open_transport
import bumble.logging
# -----------------------------------------------------------------------------
@@ -68,7 +67,7 @@ def main(keystore_file, hci_transport, device_config, address):
instantiated.
If no address is passed, the existing pairing keys for all addresses are printed.
"""
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'INFO').upper())
bumble.logging.setup_basic_logging()
if not keystore_file and not hci_transport:
print('either --keystore-file or --hci-transport must be specified.')

View File

@@ -26,13 +26,12 @@
# -----------------------------------------------------------------------------
# Imports
# -----------------------------------------------------------------------------
import os
import logging
import click
import usb1
from bumble.colors import color
from bumble.transport.usb import load_libusb
import bumble.logging
# -----------------------------------------------------------------------------
@@ -169,7 +168,7 @@ def is_bluetooth_hci(device):
@click.command()
@click.option('--verbose', is_flag=True, default=False, help='Print more details')
def main(verbose):
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'WARNING').upper())
bumble.logging.setup_basic_logging('WARNING')
load_libusb()
with usb1.USBContext() as context:

View File

@@ -370,6 +370,12 @@ class Controller:
return connection
return None
def find_peripheral_connection_by_handle(self, handle):
for connection in self.peripheral_connections.values():
if connection.handle == handle:
return connection
return None
def find_classic_connection_by_handle(self, handle):
for connection in self.classic_connections.values():
if connection.handle == handle:
@@ -414,7 +420,7 @@ class Controller:
)
)
def on_link_central_disconnected(self, peer_address, reason):
def on_link_disconnected(self, peer_address, reason):
'''
Called when an active disconnection occurs from a peer
'''
@@ -431,6 +437,17 @@ class Controller:
# Remove the connection
del self.peripheral_connections[peer_address]
elif connection := self.central_connections.get(peer_address):
self.send_hci_packet(
HCI_Disconnection_Complete_Event(
status=HCI_SUCCESS,
connection_handle=connection.handle,
reason=reason,
)
)
# Remove the connection
del self.central_connections[peer_address]
else:
logger.warning(f'!!! No peripheral connection found for {peer_address}')
@@ -479,7 +496,7 @@ class Controller:
)
)
def on_link_peripheral_disconnection_complete(self, disconnection_command, status):
def on_link_disconnection_complete(self, disconnection_command, status):
'''
Called when a disconnection has been completed
'''
@@ -499,26 +516,11 @@ class Controller:
):
logger.debug(f'CENTRAL Connection removed: {connection}')
del self.central_connections[connection.peer_address]
def on_link_peripheral_disconnected(self, peer_address):
'''
Called when a connection to a peripheral is broken
'''
# Send a disconnection complete event
if connection := self.central_connections.get(peer_address):
self.send_hci_packet(
HCI_Disconnection_Complete_Event(
status=HCI_SUCCESS,
connection_handle=connection.handle,
reason=HCI_CONNECTION_TIMEOUT_ERROR,
)
)
# Remove the connection
del self.central_connections[peer_address]
else:
logger.warning(f'!!! No central connection found for {peer_address}')
elif connection := self.find_peripheral_connection_by_handle(
disconnection_command.connection_handle
):
logger.debug(f'PERIPHERAL Connection removed: {connection}')
del self.peripheral_connections[connection.peer_address]
def on_link_encrypted(self, peer_address, _rand, _ediv, _ltk):
# For now, just setup the encryption without asking the host
@@ -877,6 +879,14 @@ class Controller:
else:
# Remove the connection
del self.central_connections[connection.peer_address]
elif connection := self.find_peripheral_connection_by_handle(handle):
if self.link:
self.link.disconnect(
self.random_address, connection.peer_address, command
)
else:
# Remove the connection
del self.peripheral_connections[connection.peer_address]
elif connection := self.find_classic_connection_by_handle(handle):
if self.link:
self.link.classic_disconnect(

View File

@@ -159,29 +159,29 @@ class LocalLink:
asyncio.get_running_loop().call_soon(self.on_connection_complete)
def on_disconnection_complete(
self, central_address, peripheral_address, disconnect_command
self, initiating_address, target_address, disconnect_command
):
# Find the controller that initiated the disconnection
if not (central_controller := self.find_controller(central_address)):
if not (initiating_controller := self.find_controller(initiating_address)):
logger.warning('!!! Initiating controller not found')
return
# Disconnect from the first controller with a matching address
if peripheral_controller := self.find_controller(peripheral_address):
peripheral_controller.on_link_central_disconnected(
central_address, disconnect_command.reason
if target_controller := self.find_controller(target_address):
target_controller.on_link_disconnected(
initiating_address, disconnect_command.reason
)
central_controller.on_link_peripheral_disconnection_complete(
initiating_controller.on_link_disconnection_complete(
disconnect_command, HCI_SUCCESS
)
def disconnect(self, central_address, peripheral_address, disconnect_command):
def disconnect(self, initiating_address, target_address, disconnect_command):
logger.debug(
f'$$$ DISCONNECTION {central_address} -> '
f'{peripheral_address}: reason = {disconnect_command.reason}'
f'$$$ DISCONNECTION {initiating_address} -> '
f'{target_address}: reason = {disconnect_command.reason}'
)
args = [central_address, peripheral_address, disconnect_command]
args = [initiating_address, target_address, disconnect_command]
asyncio.get_running_loop().call_soon(self.on_disconnection_complete, *args)
# pylint: disable=too-many-arguments

65
bumble/logging.py Normal file
View File

@@ -0,0 +1,65 @@
# Copyright 2025 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 functools
import logging
import os
from bumble import colors
# -----------------------------------------------------------------------------
class ColorFormatter(logging.Formatter):
_colorizers = {
logging.DEBUG: functools.partial(colors.color, fg="white"),
logging.INFO: functools.partial(colors.color, fg="green"),
logging.WARNING: functools.partial(colors.color, fg="yellow"),
logging.ERROR: functools.partial(colors.color, fg="red"),
logging.CRITICAL: functools.partial(colors.color, fg="black", bg="red"),
}
_formatters = {
level: logging.Formatter(
fmt=colorizer("{asctime}.{msecs:03.0f} {levelname:.1} {name}: ")
+ "{message}",
datefmt="%H:%M:%S",
style="{",
)
for level, colorizer in _colorizers.items()
}
def format(self, record: logging.LogRecord) -> str:
return self._formatters[record.levelno].format(record)
def setup_basic_logging(default_level: str = "INFO") -> None:
"""
Set up basic logging with logging.basicConfig, configured with a simple formatter
that prints out the date and log level in color.
If the BUMBLE_LOGLEVEL environment variable is set to the name of a log level, it
is used. Otherwise the default_level argument is used.
Args:
default_level: default logging level
"""
handler = logging.StreamHandler()
handler.setFormatter(ColorFormatter())
logging.basicConfig(
level=os.environ.get("BUMBLE_LOGLEVEL", default_level).upper(),
handlers=[handler],
)

View File

@@ -15,11 +15,10 @@
# -----------------------------------------------------------------------------
# Imports
# -----------------------------------------------------------------------------
import logging
import asyncio
import os
from bumble.utils import AsyncRunner
import bumble.logging
# -----------------------------------------------------------------------------
my_work_queue1 = AsyncRunner.WorkQueue()
@@ -83,5 +82,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -17,13 +17,12 @@
# -----------------------------------------------------------------------------
import asyncio
import sys
import os
import logging
from bumble.colors import color
from bumble.device import Device
from bumble.hci import Address
from bumble.transport import open_transport
from bumble.profiles.battery_service import BatteryServiceProxy
import bumble.logging
# -----------------------------------------------------------------------------
@@ -72,5 +71,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -17,8 +17,6 @@
# -----------------------------------------------------------------------------
import asyncio
import sys
import os
import logging
import random
import struct
@@ -26,6 +24,7 @@ from bumble.core import AdvertisingData
from bumble.device import Device
from bumble.transport import open_transport
from bumble.profiles.battery_service import BatteryService
import bumble.logging
# -----------------------------------------------------------------------------
@@ -74,5 +73,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -17,13 +17,13 @@
# -----------------------------------------------------------------------------
import asyncio
import sys
import os
import logging
from bumble.colors import color
from bumble.device import Device, Peer
from bumble.hci import Address
from bumble.profiles.device_information_service import DeviceInformationServiceProxy
from bumble.transport import open_transport
import bumble.logging
# -----------------------------------------------------------------------------
@@ -116,5 +116,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -17,14 +17,13 @@
# -----------------------------------------------------------------------------
import asyncio
import sys
import os
import logging
import struct
from bumble.core import AdvertisingData
from bumble.device import Device
from bumble.transport import open_transport
from bumble.profiles.device_information_service import DeviceInformationService
import bumble.logging
# -----------------------------------------------------------------------------
@@ -70,5 +69,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -17,13 +17,13 @@
# -----------------------------------------------------------------------------
import asyncio
import sys
import os
import logging
from bumble.colors import color
from bumble.device import Device
from bumble.hci import Address
from bumble.transport import open_transport
from bumble.profiles.heart_rate_service import HeartRateServiceProxy
import bumble.logging
# -----------------------------------------------------------------------------
@@ -76,5 +76,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -20,9 +20,7 @@ import time
import math
import random
import struct
import logging
import asyncio
import os
from bumble.core import AdvertisingData
from bumble.device import Device
@@ -30,6 +28,7 @@ from bumble.transport import open_transport
from bumble.profiles.device_information_service import DeviceInformationService
from bumble.profiles.heart_rate_service import HeartRateService
from bumble.utils import AsyncRunner
import bumble.logging
# -----------------------------------------------------------------------------
@@ -128,5 +127,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -17,13 +17,12 @@
# -----------------------------------------------------------------------------
import asyncio
import sys
import os
import logging
import struct
import json
import websockets
from bumble.colors import color
import websockets
from bumble.colors import color
from bumble.core import AdvertisingData
from bumble.device import Device, Connection, Peer
from bumble.utils import AsyncRunner
@@ -45,6 +44,8 @@ from bumble.gatt import (
GATT_HID_CONTROL_POINT_CHARACTERISTIC,
GATT_REPORT_REFERENCE_DESCRIPTOR,
)
import bumble.logging
# -----------------------------------------------------------------------------
@@ -450,5 +451,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -17,8 +17,6 @@
# -----------------------------------------------------------------------------
import asyncio
import sys
import os
import logging
from bumble.colors import color
from bumble.device import Device
@@ -39,6 +37,7 @@ from bumble.sdp import (
SDP_BLUETOOTH_PROFILE_DESCRIPTOR_LIST_ATTRIBUTE_ID,
SDP_SERVICE_CLASS_ID_LIST_ATTRIBUTE_ID,
)
import bumble.logging
# -----------------------------------------------------------------------------
@@ -198,5 +197,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -17,8 +17,6 @@
# -----------------------------------------------------------------------------
import asyncio
import sys
import os
import logging
from typing import Any
from bumble.device import Device
@@ -35,6 +33,8 @@ from bumble.a2dp import (
A2DP_SBC_CODEC_TYPE,
SbcMediaCodecInformation,
)
import bumble.logging
Context: dict[Any, Any] = {'output': None}
@@ -166,5 +166,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -17,8 +17,6 @@
# -----------------------------------------------------------------------------
import asyncio
import sys
import os
import logging
from bumble.colors import color
from bumble.device import Device
@@ -38,6 +36,7 @@ from bumble.a2dp import (
SbcMediaCodecInformation,
SbcPacketSource,
)
import bumble.logging
# -----------------------------------------------------------------------------
@@ -186,5 +185,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -16,15 +16,14 @@
# Imports
# -----------------------------------------------------------------------------
import asyncio
import logging
import sys
import os
import struct
from bumble.core import AdvertisingData
from bumble.device import AdvertisingType, Device
from bumble.hci import Address
from bumble.transport import open_transport
import bumble.logging
# -----------------------------------------------------------------------------
@@ -72,5 +71,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -17,10 +17,8 @@
# -----------------------------------------------------------------------------
import asyncio
import sys
import os
import logging
from bumble.colors import color
from bumble.colors import color
from bumble.device import Device, Peer
from bumble.transport import open_transport
from bumble.profiles.ancs import (
@@ -31,6 +29,7 @@ from bumble.profiles.ancs import (
Notification,
NotificationAttributeId,
)
import bumble.logging
# -----------------------------------------------------------------------------
@@ -210,5 +209,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'INFO').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -17,18 +17,19 @@
# -----------------------------------------------------------------------------
import asyncio
import sys
import os
import logging
import websockets
from typing import Optional
import websockets
from bumble import decoder
from bumble import gatt
from bumble.core import AdvertisingData
from bumble.device import Device, AdvertisingParameters
from bumble.transport import open_transport
from bumble.profiles import asha
import bumble.logging
ws_connection: Optional[websockets.WebSocketServerProtocol] = None
g722_decoder = decoder.G722Decoder()
@@ -111,9 +112,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(
level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper(),
format='%(asctime)s.%(msecs)03d %(levelname)s %(module)s - %(funcName)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
)
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -19,8 +19,8 @@ from __future__ import annotations
import asyncio
import json
import sys
import os
import logging
import websockets
from bumble.device import Device
@@ -31,6 +31,7 @@ from bumble import avrcp
from bumble import avdtp
from bumble import a2dp
from bumble import utils
import bumble.logging
logger = logging.getLogger(__name__)
@@ -409,5 +410,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -18,15 +18,15 @@
from __future__ import annotations
import asyncio
import logging
import sys
import os
import functools
from bumble import core
from bumble import hci
from bumble.device import Connection, Device, ChannelSoundingCapabilities
from bumble.transport import open_transport
import bumble.logging
# From https://cs.android.com/android/platform/superproject/main/+/main:packages/modules/Bluetooth/system/gd/hci/distance_measurement_manager.cc.
CS_TONE_ANTENNA_CONFIG_MAPPING_TABLE = [
@@ -150,5 +150,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -16,16 +16,14 @@
# Imports
# -----------------------------------------------------------------------------
import asyncio
import logging
import sys
import os
from bumble import utils
from bumble.device import Device, CigParameters, CisLink, Connection
from bumble.hci import (
OwnAddressType,
)
from bumble.transport import open_transport
import bumble.logging
# -----------------------------------------------------------------------------
@@ -104,5 +102,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -17,10 +17,8 @@
# -----------------------------------------------------------------------------
import asyncio
import sys
import os
import logging
from bumble.colors import color
from bumble.colors import color
from bumble.device import Device
from bumble.transport import open_transport
from bumble.core import PhysicalTransport, BT_L2CAP_PROTOCOL_ID, CommandTimeoutError
@@ -29,6 +27,7 @@ from bumble.sdp import (
SDP_PUBLIC_BROWSE_ROOT,
SDP_ALL_ATTRIBUTES_RANGE,
)
import bumble.logging
# -----------------------------------------------------------------------------
@@ -117,5 +116,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -17,8 +17,6 @@
# -----------------------------------------------------------------------------
import asyncio
import sys
import os
import logging
from bumble.device import Device
from bumble.transport import open_transport
@@ -38,6 +36,8 @@ from bumble.core import (
BT_AVDTP_PROTOCOL_ID,
BT_ADVANCED_AUDIO_DISTRIBUTION_SERVICE,
)
import bumble.logging
# -----------------------------------------------------------------------------
SDP_SERVICE_RECORDS = {
@@ -117,5 +117,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -17,13 +17,13 @@
# -----------------------------------------------------------------------------
import asyncio
import sys
import os
import logging
from bumble.colors import color
from bumble.device import Device
from bumble.hci import Address
from bumble.transport import open_transport
from bumble.core import DeviceClass
import bumble.logging
# -----------------------------------------------------------------------------
@@ -77,5 +77,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -17,11 +17,10 @@
# -----------------------------------------------------------------------------
import asyncio
import sys
import os
import logging
from bumble.device import Device
from bumble.transport import open_transport
import bumble.logging
# -----------------------------------------------------------------------------
@@ -62,5 +61,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -15,10 +15,8 @@
# -----------------------------------------------------------------------------
# Imports
# -----------------------------------------------------------------------------
import logging
import asyncio
import sys
import os
from bumble.gatt import (
GATT_CHARACTERISTIC_USER_DESCRIPTION_DESCRIPTOR,
@@ -33,6 +31,7 @@ from bumble.host import Host
from bumble.controller import Controller
from bumble.link import LocalLink
from bumble.transport import open_transport
import bumble.logging
# -----------------------------------------------------------------------------
@@ -105,5 +104,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -15,16 +15,16 @@
# -----------------------------------------------------------------------------
# Imports
# -----------------------------------------------------------------------------
import logging
import asyncio
import sys
import os
from bumble.colors import color
from bumble.device import Device
from bumble.controller import Controller
from bumble.hci import Address
from bumble.link import LocalLink
from bumble.transport import open_transport
import bumble.logging
# -----------------------------------------------------------------------------
@@ -82,5 +82,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -16,9 +16,7 @@
# Imports
# -----------------------------------------------------------------------------
import asyncio
import logging
import sys
import os
import secrets
from bumble.core import AdvertisingData
@@ -28,8 +26,8 @@ from bumble.hci import (
)
from bumble.profiles.cap import CommonAudioServiceService
from bumble.profiles.csip import CoordinatedSetIdentificationService, SirkType
from bumble.transport import open_transport
import bumble.logging
# -----------------------------------------------------------------------------
@@ -101,5 +99,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -17,12 +17,12 @@
# -----------------------------------------------------------------------------
import asyncio
import sys
import os
import logging
from bumble.hci import Address
from bumble.device import Device
from bumble.transport import open_transport
from bumble.snoop import BtSnooper
import bumble.logging
# -----------------------------------------------------------------------------
@@ -52,5 +52,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -16,15 +16,14 @@
# Imports
# -----------------------------------------------------------------------------
import asyncio
import logging
import sys
import os
from bumble.core import PhysicalTransport
from bumble.device import Device, ScoLink
from bumble.hci import HCI_Enhanced_Setup_Synchronous_Connection_Command
from bumble.hfp import DefaultCodecParameters, ESCO_PARAMETERS
from bumble.transport import open_transport
import bumble.logging
# -----------------------------------------------------------------------------
@@ -83,5 +82,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -16,9 +16,8 @@
# Imports
# -----------------------------------------------------------------------------
import asyncio
import logging
import sys
import os
from bumble.device import (
AdvertisingParameters,
AdvertisingEventProperties,
@@ -26,8 +25,8 @@ from bumble.device import (
Device,
)
from bumble.hci import Address
from bumble.transport import open_transport
import bumble.logging
# -----------------------------------------------------------------------------
@@ -69,5 +68,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -16,13 +16,13 @@
# Imports
# -----------------------------------------------------------------------------
import asyncio
import logging
import sys
import os
from bumble.device import AdvertisingParameters, AdvertisingEventProperties, Device
from bumble.hci import Address
from bumble.core import AdvertisingData
from bumble.transport import open_transport
import bumble.logging
# -----------------------------------------------------------------------------
@@ -96,5 +96,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -17,8 +17,6 @@
# -----------------------------------------------------------------------------
import asyncio
import sys
import os
import logging
from bumble.colors import color
from bumble.core import ProtocolError
@@ -26,6 +24,7 @@ from bumble.device import Device, Peer
from bumble.gatt import show_services
from bumble.transport import open_transport
from bumble.utils import AsyncRunner
import bumble.logging
# -----------------------------------------------------------------------------
@@ -101,5 +100,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -16,8 +16,7 @@
# Imports
# -----------------------------------------------------------------------------
import asyncio
import os
import logging
from bumble.colors import color
from bumble.core import ProtocolError
from bumble.controller import Controller
@@ -34,6 +33,7 @@ from bumble.gatt import (
GATT_DEVICE_INFORMATION_SERVICE,
)
from bumble.gatt_client import show_services
import bumble.logging
# -----------------------------------------------------------------------------
@@ -119,5 +119,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -17,8 +17,6 @@
# -----------------------------------------------------------------------------
import asyncio
import sys
import os
import logging
from bumble.device import Device, Connection
from bumble.transport import open_transport
@@ -32,6 +30,7 @@ from bumble.gatt import (
GATT_MANUFACTURER_NAME_STRING_CHARACTERISTIC,
GATT_DEVICE_INFORMATION_SERVICE,
)
import bumble.logging
# -----------------------------------------------------------------------------
@@ -152,5 +151,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -17,8 +17,6 @@
# -----------------------------------------------------------------------------
import asyncio
import sys
import os
import logging
from bumble.device import Device
from bumble.transport import open_transport
@@ -27,6 +25,7 @@ from bumble.gatt import (
Characteristic,
)
from bumble.pairing import PairingConfig, PairingDelegate
import bumble.logging
# -----------------------------------------------------------------------------
@@ -107,5 +106,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -20,8 +20,6 @@ import asyncio
import dataclasses
import functools
import enum
import logging
import os
import random
import struct
import sys
@@ -34,6 +32,7 @@ from bumble import gatt_adapters
from bumble import gatt_client
from bumble import hci
from bumble import core
import bumble.logging
# -----------------------------------------------------------------------------
@@ -432,5 +431,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'INFO').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -16,9 +16,7 @@
# Imports
# -----------------------------------------------------------------------------
import asyncio
import logging
import sys
import os
from bumble.core import AdvertisingData
from bumble.device import Device
@@ -32,8 +30,9 @@ from bumble.profiles.hap import (
WritablePresetsSupport,
PresetRecord,
)
from bumble.transport import open_transport
import bumble.logging
server_features = HearingAidFeatures(
HearingAidType.MONAURAL_HEARING_AID,
@@ -102,5 +101,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -18,7 +18,6 @@
import asyncio
import json
import sys
import os
import io
import logging
from typing import Iterable, Optional
@@ -30,6 +29,7 @@ from bumble.device import Device, ScoLink
from bumble.transport import open_transport
from bumble.core import PhysicalTransport
from bumble import hci, rfcomm, hfp
import bumble.logging
logger = logging.getLogger(__name__)
@@ -286,5 +286,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -18,20 +18,20 @@
import asyncio
import contextlib
import sys
import os
import logging
import json
import websockets
import functools
from typing import Optional
from bumble import utils
import websockets
from bumble import rfcomm
from bumble import hci
from bumble.device import Device, Connection
from bumble.transport import open_transport
from bumble import hfp
from bumble.hfp import HfProtocol
import bumble.logging
ws: Optional[websockets.WebSocketServerProtocol] = None
hf_protocol: Optional[HfProtocol] = None
@@ -175,5 +175,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -17,12 +17,11 @@
# -----------------------------------------------------------------------------
import asyncio
import sys
import os
import logging
import json
import websockets
import struct
import websockets
from bumble.device import Device
from bumble.transport import open_transport
from bumble.core import (
@@ -49,6 +48,8 @@ from bumble.sdp import (
SDP_SERVICE_RECORD_HANDLE_ATTRIBUTE_ID,
SDP_BROWSE_GROUP_LIST_ATTRIBUTE_ID,
)
import bumble.logging
# -----------------------------------------------------------------------------
# SDP attributes for Bluetooth HID devices
@@ -744,5 +745,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -17,8 +17,6 @@
# -----------------------------------------------------------------------------
import asyncio
import sys
import os
import logging
from bumble.colors import color
@@ -41,6 +39,7 @@ from bumble.sdp import (
SDP_SERVICE_RECORD_HANDLE_ATTRIBUTE_ID,
SDP_BROWSE_GROUP_LIST_ATTRIBUTE_ID,
)
import bumble.logging
from hid_report_parser import ReportParser
# -----------------------------------------------------------------------------
@@ -565,6 +564,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -16,13 +16,12 @@
# Imports
# -----------------------------------------------------------------------------
import asyncio
import logging
import sys
import os
import websockets
import json
from typing import Optional
import websockets
from bumble import utils
from bumble.core import AdvertisingData
from bumble.device import (
Device,
@@ -53,8 +52,7 @@ from bumble.profiles.mcp import (
)
from bumble.profiles.pacs import PacRecord, PublishedAudioCapabilitiesService
from bumble.transport import open_transport
from typing import Optional
import bumble.logging
# -----------------------------------------------------------------------------
@@ -191,5 +189,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -17,13 +17,12 @@
# -----------------------------------------------------------------------------
import asyncio
import sys
import os
import random
import logging
from bumble.device import Device, Connection
from bumble.transport import open_transport
from bumble.gatt import Service, Characteristic
import bumble.logging
# -----------------------------------------------------------------------------
@@ -128,5 +127,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -17,8 +17,6 @@
# -----------------------------------------------------------------------------
import asyncio
import sys
import os
import logging
from bumble.colors import color
@@ -39,6 +37,7 @@ from bumble.sdp import (
SDP_SERVICE_CLASS_ID_LIST_ATTRIBUTE_ID,
SDP_BLUETOOTH_PROFILE_DESCRIPTOR_LIST_ATTRIBUTE_ID,
)
import bumble.logging
# -----------------------------------------------------------------------------
@@ -237,5 +236,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -17,8 +17,6 @@
# -----------------------------------------------------------------------------
import asyncio
import sys
import os
import logging
from bumble.core import UUID
from bumble.device import Device
@@ -26,6 +24,7 @@ from bumble.transport import open_transport
from bumble.rfcomm import Server
from bumble.utils import AsyncRunner
from bumble.rfcomm import make_service_sdp_records
import bumble.logging
# -----------------------------------------------------------------------------
@@ -159,5 +158,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -17,12 +17,11 @@
# -----------------------------------------------------------------------------
import asyncio
import sys
import os
import logging
from bumble.colors import color
from bumble.hci import Address
from bumble.device import Device
from bumble.transport import open_transport
from bumble import logging
# -----------------------------------------------------------------------------
@@ -79,5 +78,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -18,9 +18,7 @@
import asyncio
import datetime
import functools
import logging
import sys
import os
import io
import struct
import secrets
@@ -46,6 +44,7 @@ from bumble.profiles.cap import CommonAudioServiceService
from bumble.profiles.csip import CoordinatedSetIdentificationService, SirkType
from bumble.profiles.pacs import PacRecord, PublishedAudioCapabilitiesService
from bumble.transport import open_transport
import bumble.logging
def _sink_pac_record() -> PacRecord:
@@ -200,5 +199,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -16,12 +16,12 @@
# Imports
# -----------------------------------------------------------------------------
import asyncio
import logging
import sys
import os
import secrets
import websockets
import json
from typing import Optional
import websockets
from bumble.core import AdvertisingData
from bumble.device import Device, AdvertisingParameters, AdvertisingEventProperties
@@ -43,10 +43,8 @@ from bumble.profiles.pacs import PacRecord, PublishedAudioCapabilitiesService
from bumble.profiles.cap import CommonAudioServiceService
from bumble.profiles.csip import CoordinatedSetIdentificationService, SirkType
from bumble.profiles.vcs import VolumeControlService
from bumble.transport import open_transport
from typing import Optional
import bumble.logging
def dumps_volume_state(volume_setting: int, muted: int, change_counter: int) -> str:
@@ -186,5 +184,5 @@ async def main() -> None:
# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
bumble.logging.setup_basic_logging('DEBUG')
asyncio.run(main())

View File

@@ -23,13 +23,9 @@ import pytest
from unittest.mock import AsyncMock, MagicMock, patch
from bumble.controller import Controller
from bumble.core import PhysicalTransport
from bumble.link import LocalLink
from bumble.device import Device, Peer
from bumble.host import Host
from bumble.device import Peer
from bumble.gatt import Service, Characteristic
from bumble.transport.common import AsyncPipeSink
from bumble.pairing import PairingConfig, PairingDelegate
from bumble.smp import (
SMP_PAIRING_NOT_SUPPORTED_ERROR,
@@ -38,9 +34,10 @@ from bumble.smp import (
OobLegacyContext,
)
from bumble.core import ProtocolError
from bumble.keys import PairingKeys
from bumble.hci import Role
from .test_utils import TwoDevices
# -----------------------------------------------------------------------------
# Logging
@@ -49,63 +46,26 @@ logger = logging.getLogger(__name__)
# -----------------------------------------------------------------------------
class TwoDevices:
def __init__(self):
self.connections = [None, None]
addresses = ['F0:F1:F2:F3:F4:F5', 'F5:F4:F3:F2:F1:F0']
self.link = LocalLink()
self.controllers = [
Controller('C1', link=self.link, public_address=addresses[0]),
Controller('C2', link=self.link, public_address=addresses[1]),
]
self.devices = [
Device(
address=addresses[0],
host=Host(self.controllers[0], AsyncPipeSink(self.controllers[0])),
),
Device(
address=addresses[1],
host=Host(self.controllers[1], AsyncPipeSink(self.controllers[1])),
),
]
self.paired = [
asyncio.get_event_loop().create_future(),
asyncio.get_event_loop().create_future(),
]
def on_connection(self, which, connection):
self.connections[which] = connection
def on_paired(self, which: int, keys: PairingKeys):
self.paired[which].set_result(keys)
@pytest.mark.asyncio
async def test_self_connection():
two_devices = TwoDevices()
await two_devices.setup_connection()
# -----------------------------------------------------------------------------
@pytest.mark.asyncio
async def test_self_connection():
# Create two devices, each with a controller, attached to the same link
async def test_self_disconnection():
two_devices = TwoDevices()
await two_devices.setup_connection()
await two_devices.connections[0].disconnect()
assert two_devices.connections[0] is None
assert two_devices.connections[1] is None
# Attach listeners
two_devices.devices[0].on(
'connection', lambda connection: two_devices.on_connection(0, connection)
)
two_devices.devices[1].on(
'connection', lambda connection: two_devices.on_connection(1, connection)
)
# Start
await two_devices.devices[0].power_on()
await two_devices.devices[1].power_on()
# Connect the two devices
await two_devices.devices[0].connect(two_devices.devices[1].random_address)
# Check the post conditions
assert two_devices.connections[0] is not None
assert two_devices.connections[1] is not None
two_devices = TwoDevices()
await two_devices.setup_connection()
await two_devices.connections[1].disconnect()
assert two_devices.connections[0] is None
assert two_devices.connections[1] is None
# -----------------------------------------------------------------------------
@@ -115,24 +75,14 @@ async def test_self_connection():
(Role.CENTRAL, Role.PERIPHERAL),
)
async def test_self_classic_connection(responder_role):
# Create two devices, each with a controller, attached to the same link
two_devices = TwoDevices()
# Attach listeners
two_devices.devices[0].on(
'connection', lambda connection: two_devices.on_connection(0, connection)
)
two_devices.devices[1].on(
'connection', lambda connection: two_devices.on_connection(1, connection)
)
# Enable Classic connections
two_devices.devices[0].classic_enabled = True
two_devices.devices[1].classic_enabled = True
# Start
await two_devices.devices[0].power_on()
await two_devices.devices[1].power_on()
await two_devices.setup_connection()
# Connect the two devices
await asyncio.gather(
@@ -203,15 +153,9 @@ async def test_self_gatt():
s4 = Service('3A12C182-14E2-4FE0-8C5B-65D7C569F9DB', [], included_services=[s2, s3])
two_devices.devices[1].add_services([s1, s2, s4])
# Start
await two_devices.devices[0].power_on()
await two_devices.devices[1].power_on()
# Connect the two devices
connection = await two_devices.devices[0].connect(
two_devices.devices[1].random_address
)
peer = Peer(connection)
await two_devices.setup_connection()
peer = Peer(two_devices.connections[0])
bogus_uuid = 'A0AA6007-0B48-4BBE-80AC-0DE9AAF541EA'
result = await peer.discover_services([bogus_uuid])
@@ -264,15 +208,9 @@ async def test_self_gatt_long_read():
service = Service('8140E247-04F0-42C1-BC34-534C344DAFCA', characteristics)
two_devices.devices[1].add_service(service)
# Start
await two_devices.devices[0].power_on()
await two_devices.devices[1].power_on()
# Connect the two devices
connection = await two_devices.devices[0].connect(
two_devices.devices[1].random_address
)
peer = Peer(connection)
await two_devices.setup_connection()
peer = Peer(two_devices.connections[0])
result = await peer.discover_service(service.uuid)
assert len(result) == 1
@@ -289,25 +227,12 @@ async def _test_self_smp_with_configs(pairing_config1, pairing_config2):
# Create two devices, each with a controller, attached to the same link
two_devices = TwoDevices()
# Start
await two_devices.devices[0].power_on()
await two_devices.devices[1].power_on()
# Attach listeners
two_devices.devices[0].on(
'connection', lambda connection: two_devices.on_connection(0, connection)
)
two_devices.devices[1].on(
'connection', lambda connection: two_devices.on_connection(1, connection)
)
# Connect the two devices
connection = await two_devices.devices[0].connect(
two_devices.devices[1].random_address
)
await two_devices.setup_connection()
connection = two_devices.connections[0]
assert not connection.is_encrypted
# Attach connection listeners
# Attach pairing listeners
two_devices.connections[0].on(
'pairing', lambda keys: two_devices.on_paired(0, keys)
)
@@ -488,23 +413,13 @@ async def test_self_smp_over_classic():
# Create two devices, each with a controller, attached to the same link
two_devices = TwoDevices()
# Attach listeners
two_devices.devices[0].on(
'connection', lambda connection: two_devices.on_connection(0, connection)
)
two_devices.devices[1].on(
'connection', lambda connection: two_devices.on_connection(1, connection)
)
# Enable Classic connections
two_devices.devices[0].classic_enabled = True
two_devices.devices[1].classic_enabled = True
# Start
# Connect the two devices
await two_devices.devices[0].power_on()
await two_devices.devices[1].power_on()
# Connect the two devices
await asyncio.gather(
two_devices.devices[0].connect(
two_devices.devices[1].public_address, transport=PhysicalTransport.BR_EDR
@@ -650,6 +565,7 @@ async def test_self_smp_oob_legacy():
# -----------------------------------------------------------------------------
async def run_test_self():
await test_self_connection()
await test_self_disconnection()
await test_self_gatt()
await test_self_gatt_long_read()
await test_self_smp()

View File

@@ -25,6 +25,7 @@ from bumble.device import Device, Connection
from bumble.host import Host
from bumble.transport.common import AsyncPipeSink
from bumble.hci import Address
from bumble.keys import PairingKeys
# -----------------------------------------------------------------------------
@@ -51,16 +52,6 @@ class TwoDevices:
),
]
self.paired = [None, None]
def on_connection(self, which, connection):
self.connections[which] = connection
def on_paired(self, which, keys):
self.paired[which] = keys
async def setup_connection(self) -> None:
# Attach listeners
self.devices[0].on(
'connection', lambda connection: self.on_connection(0, connection)
)
@@ -68,6 +59,22 @@ class TwoDevices:
'connection', lambda connection: self.on_connection(1, connection)
)
self.paired = [
asyncio.get_event_loop().create_future(),
asyncio.get_event_loop().create_future(),
]
def on_connection(self, which, connection):
self.connections[which] = connection
connection.on('disconnection', lambda code: self.on_disconnection(which))
def on_disconnection(self, which):
self.connections[which] = None
def on_paired(self, which: int, keys: PairingKeys) -> None:
self.paired[which].set_result(keys)
async def setup_connection(self) -> None:
# Start
await self.devices[0].power_on()
await self.devices[1].power_on()

View File

@@ -17,7 +17,6 @@
# -----------------------------------------------------------------------------
import logging
import asyncio
import os
from typing import Any, Optional
import click
@@ -26,6 +25,8 @@ from bumble.colors import color
from bumble import transport
from bumble.drivers import intel
from bumble.host import Host
import bumble.logging
# -----------------------------------------------------------------------------
# Logging
@@ -107,7 +108,7 @@ async def do_bootloader(usb_transport: str, force: bool) -> None:
# -----------------------------------------------------------------------------
@click.group()
def main():
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'INFO').upper())
bumble.logging.setup_basic_logging()
@main.command

View File

@@ -15,15 +15,16 @@
# -----------------------------------------------------------------------------
# Imports
# -----------------------------------------------------------------------------
import logging
import asyncio
import os
import logging
import click
from bumble import transport
from bumble.host import Host
from bumble.drivers import rtk
import bumble.logging
# -----------------------------------------------------------------------------
# Logging
@@ -112,7 +113,7 @@ async def do_info(usb_transport, force):
# -----------------------------------------------------------------------------
@click.group()
def main():
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'INFO').upper())
bumble.logging.setup_basic_logging()
@main.command