bumble 0.0.208__py3-none-any.whl → 0.0.210__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. bumble/_version.py +2 -2
  2. bumble/a2dp.py +7 -7
  3. bumble/apps/auracast.py +37 -29
  4. bumble/apps/bench.py +9 -7
  5. bumble/apps/console.py +1 -1
  6. bumble/apps/lea_unicast/app.py +6 -2
  7. bumble/apps/pair.py +4 -3
  8. bumble/apps/player/player.py +3 -3
  9. bumble/apps/rfcomm_bridge.py +1 -1
  10. bumble/apps/speaker/speaker.py +4 -2
  11. bumble/att.py +12 -5
  12. bumble/avc.py +5 -5
  13. bumble/avdtp.py +9 -10
  14. bumble/avrcp.py +18 -19
  15. bumble/bridge.py +2 -2
  16. bumble/controller.py +13 -15
  17. bumble/core.py +61 -60
  18. bumble/device.py +193 -162
  19. bumble/drivers/__init__.py +2 -2
  20. bumble/gap.py +1 -1
  21. bumble/gatt.py +16 -0
  22. bumble/gatt_adapters.py +3 -3
  23. bumble/gatt_client.py +27 -21
  24. bumble/gatt_server.py +9 -10
  25. bumble/hci.py +109 -90
  26. bumble/hfp.py +3 -3
  27. bumble/hid.py +4 -3
  28. bumble/host.py +30 -19
  29. bumble/keys.py +3 -3
  30. bumble/l2cap.py +21 -19
  31. bumble/link.py +5 -6
  32. bumble/pairing.py +3 -3
  33. bumble/pandora/__init__.py +5 -5
  34. bumble/pandora/host.py +30 -23
  35. bumble/pandora/l2cap.py +2 -2
  36. bumble/pandora/security.py +17 -19
  37. bumble/pandora/utils.py +2 -2
  38. bumble/profiles/aics.py +6 -6
  39. bumble/profiles/ancs.py +513 -0
  40. bumble/profiles/ascs.py +17 -10
  41. bumble/profiles/asha.py +5 -5
  42. bumble/profiles/bass.py +1 -1
  43. bumble/profiles/csip.py +10 -10
  44. bumble/profiles/gatt_service.py +12 -12
  45. bumble/profiles/hap.py +16 -16
  46. bumble/profiles/mcp.py +26 -24
  47. bumble/profiles/pacs.py +6 -6
  48. bumble/profiles/pbp.py +1 -1
  49. bumble/profiles/vcs.py +6 -4
  50. bumble/profiles/vocs.py +3 -3
  51. bumble/rfcomm.py +8 -8
  52. bumble/sdp.py +1 -1
  53. bumble/smp.py +39 -33
  54. bumble/transport/__init__.py +24 -19
  55. bumble/transport/android_emulator.py +8 -4
  56. bumble/transport/android_netsim.py +8 -5
  57. bumble/transport/common.py +5 -1
  58. bumble/transport/file.py +1 -1
  59. bumble/transport/hci_socket.py +1 -1
  60. bumble/transport/pty.py +1 -1
  61. bumble/transport/pyusb.py +3 -3
  62. bumble/transport/serial.py +1 -1
  63. bumble/transport/tcp_client.py +1 -1
  64. bumble/transport/tcp_server.py +1 -1
  65. bumble/transport/udp.py +1 -1
  66. bumble/transport/unix.py +1 -1
  67. bumble/transport/usb.py +1 -3
  68. bumble/transport/vhci.py +2 -2
  69. bumble/transport/ws_client.py +6 -1
  70. bumble/transport/ws_server.py +1 -1
  71. bumble/utils.py +89 -76
  72. {bumble-0.0.208.dist-info → bumble-0.0.210.dist-info}/METADATA +3 -2
  73. {bumble-0.0.208.dist-info → bumble-0.0.210.dist-info}/RECORD +77 -76
  74. {bumble-0.0.208.dist-info → bumble-0.0.210.dist-info}/WHEEL +1 -1
  75. {bumble-0.0.208.dist-info → bumble-0.0.210.dist-info}/entry_points.txt +0 -0
  76. {bumble-0.0.208.dist-info → bumble-0.0.210.dist-info/licenses}/LICENSE +0 -0
  77. {bumble-0.0.208.dist-info → bumble-0.0.210.dist-info}/top_level.txt +0 -0
bumble/l2cap.py CHANGED
@@ -23,7 +23,6 @@ import logging
23
23
  import struct
24
24
 
25
25
  from collections import deque
26
- from pyee import EventEmitter
27
26
  from typing import (
28
27
  Dict,
29
28
  Type,
@@ -39,19 +38,19 @@ from typing import (
39
38
  TYPE_CHECKING,
40
39
  )
41
40
 
42
- from .utils import deprecated
43
- from .colors import color
44
- from .core import (
45
- BT_CENTRAL_ROLE,
41
+ from bumble import utils
42
+ from bumble.colors import color
43
+ from bumble.core import (
46
44
  InvalidStateError,
47
45
  InvalidArgumentError,
48
46
  InvalidPacketError,
49
47
  OutOfResourcesError,
50
48
  ProtocolError,
51
49
  )
52
- from .hci import (
50
+ from bumble.hci import (
53
51
  HCI_LE_Connection_Update_Command,
54
52
  HCI_Object,
53
+ Role,
55
54
  key_with_value,
56
55
  name_or_number,
57
56
  )
@@ -720,7 +719,7 @@ class L2CAP_LE_Flow_Control_Credit(L2CAP_Control_Frame):
720
719
 
721
720
 
722
721
  # -----------------------------------------------------------------------------
723
- class ClassicChannel(EventEmitter):
722
+ class ClassicChannel(utils.EventEmitter):
724
723
  class State(enum.IntEnum):
725
724
  # States
726
725
  CLOSED = 0x00
@@ -821,8 +820,8 @@ class ClassicChannel(EventEmitter):
821
820
 
822
821
  # Wait for the connection to succeed or fail
823
822
  try:
824
- return await self.connection.abort_on(
825
- 'disconnection', self.connection_result
823
+ return await utils.cancel_on_event(
824
+ self.connection, 'disconnection', self.connection_result
826
825
  )
827
826
  finally:
828
827
  self.connection_result = None
@@ -1026,7 +1025,7 @@ class ClassicChannel(EventEmitter):
1026
1025
 
1027
1026
 
1028
1027
  # -----------------------------------------------------------------------------
1029
- class LeCreditBasedChannel(EventEmitter):
1028
+ class LeCreditBasedChannel(utils.EventEmitter):
1030
1029
  """
1031
1030
  LE Credit-based Connection Oriented Channel
1032
1031
  """
@@ -1381,7 +1380,7 @@ class LeCreditBasedChannel(EventEmitter):
1381
1380
 
1382
1381
 
1383
1382
  # -----------------------------------------------------------------------------
1384
- class ClassicChannelServer(EventEmitter):
1383
+ class ClassicChannelServer(utils.EventEmitter):
1385
1384
  def __init__(
1386
1385
  self,
1387
1386
  manager: ChannelManager,
@@ -1406,7 +1405,7 @@ class ClassicChannelServer(EventEmitter):
1406
1405
 
1407
1406
 
1408
1407
  # -----------------------------------------------------------------------------
1409
- class LeCreditBasedChannelServer(EventEmitter):
1408
+ class LeCreditBasedChannelServer(utils.EventEmitter):
1410
1409
  def __init__(
1411
1410
  self,
1412
1411
  manager: ChannelManager,
@@ -1521,6 +1520,9 @@ class ChannelManager:
1521
1520
 
1522
1521
  def next_identifier(self, connection: Connection) -> int:
1523
1522
  identifier = (self.identifiers.setdefault(connection.handle, 0) + 1) % 256
1523
+ # 0x00 is an invalid ID (BT Core Spec, Vol 3, Part A, Sect 4
1524
+ if identifier == 0:
1525
+ identifier = 1
1524
1526
  self.identifiers[connection.handle] = identifier
1525
1527
  return identifier
1526
1528
 
@@ -1533,7 +1535,7 @@ class ChannelManager:
1533
1535
  if cid in self.fixed_channels:
1534
1536
  del self.fixed_channels[cid]
1535
1537
 
1536
- @deprecated("Please use create_classic_server")
1538
+ @utils.deprecated("Please use create_classic_server")
1537
1539
  def register_server(
1538
1540
  self,
1539
1541
  psm: int,
@@ -1579,7 +1581,7 @@ class ChannelManager:
1579
1581
 
1580
1582
  return self.servers[spec.psm]
1581
1583
 
1582
- @deprecated("Please use create_le_credit_based_server()")
1584
+ @utils.deprecated("Please use create_le_credit_based_server()")
1583
1585
  def register_le_coc_server(
1584
1586
  self,
1585
1587
  psm: int,
@@ -1908,7 +1910,7 @@ class ChannelManager:
1908
1910
  def on_l2cap_connection_parameter_update_request(
1909
1911
  self, connection: Connection, cid: int, request
1910
1912
  ):
1911
- if connection.role == BT_CENTRAL_ROLE:
1913
+ if connection.role == Role.CENTRAL:
1912
1914
  self.send_control_frame(
1913
1915
  connection,
1914
1916
  cid,
@@ -2123,7 +2125,7 @@ class ChannelManager:
2123
2125
  if channel.source_cid in connection_channels:
2124
2126
  del connection_channels[channel.source_cid]
2125
2127
 
2126
- @deprecated("Please use create_le_credit_based_channel()")
2128
+ @utils.deprecated("Please use create_le_credit_based_channel()")
2127
2129
  async def open_le_coc(
2128
2130
  self, connection: Connection, psm: int, max_credits: int, mtu: int, mps: int
2129
2131
  ) -> LeCreditBasedChannel:
@@ -2180,7 +2182,7 @@ class ChannelManager:
2180
2182
 
2181
2183
  return channel
2182
2184
 
2183
- @deprecated("Please use create_classic_channel()")
2185
+ @utils.deprecated("Please use create_classic_channel()")
2184
2186
  async def connect(self, connection: Connection, psm: int) -> ClassicChannel:
2185
2187
  return await self.create_classic_channel(
2186
2188
  connection=connection, spec=ClassicChannelSpec(psm=psm)
@@ -2230,12 +2232,12 @@ class ChannelManager:
2230
2232
 
2231
2233
 
2232
2234
  class Channel(ClassicChannel):
2233
- @deprecated("Please use ClassicChannel")
2235
+ @utils.deprecated("Please use ClassicChannel")
2234
2236
  def __init__(self, *args, **kwargs) -> None:
2235
2237
  super().__init__(*args, **kwargs)
2236
2238
 
2237
2239
 
2238
2240
  class LeConnectionOrientedChannel(LeCreditBasedChannel):
2239
- @deprecated("Please use LeCreditBasedChannel")
2241
+ @utils.deprecated("Please use LeCreditBasedChannel")
2240
2242
  def __init__(self, *args, **kwargs) -> None:
2241
2243
  super().__init__(*args, **kwargs)
bumble/link.py CHANGED
@@ -20,14 +20,13 @@ import asyncio
20
20
  from functools import partial
21
21
 
22
22
  from bumble.core import (
23
- BT_PERIPHERAL_ROLE,
24
- BT_BR_EDR_TRANSPORT,
25
- BT_LE_TRANSPORT,
23
+ PhysicalTransport,
26
24
  InvalidStateError,
27
25
  )
28
26
  from bumble.colors import color
29
27
  from bumble.hci import (
30
28
  Address,
29
+ Role,
31
30
  HCI_SUCCESS,
32
31
  HCI_CONNECTION_ACCEPT_TIMEOUT_ERROR,
33
32
  HCI_CONNECTION_TIMEOUT_ERROR,
@@ -116,10 +115,10 @@ class LocalLink:
116
115
 
117
116
  def send_acl_data(self, sender_controller, destination_address, transport, data):
118
117
  # Send the data to the first controller with a matching address
119
- if transport == BT_LE_TRANSPORT:
118
+ if transport == PhysicalTransport.LE:
120
119
  destination_controller = self.find_controller(destination_address)
121
120
  source_address = sender_controller.random_address
122
- elif transport == BT_BR_EDR_TRANSPORT:
121
+ elif transport == PhysicalTransport.BR_EDR:
123
122
  destination_controller = self.find_classic_controller(destination_address)
124
123
  source_address = sender_controller.public_address
125
124
  else:
@@ -292,7 +291,7 @@ class LocalLink:
292
291
  return
293
292
 
294
293
  async def task():
295
- if responder_role != BT_PERIPHERAL_ROLE:
294
+ if responder_role != Role.PERIPHERAL:
296
295
  initiator_controller.on_classic_role_change(
297
296
  responder_controller.public_address, int(not (responder_role))
298
297
  )
bumble/pairing.py CHANGED
@@ -20,14 +20,14 @@ import enum
20
20
  from dataclasses import dataclass
21
21
  from typing import Optional, Tuple
22
22
 
23
- from .hci import (
23
+ from bumble.hci import (
24
24
  Address,
25
25
  HCI_NO_INPUT_NO_OUTPUT_IO_CAPABILITY,
26
26
  HCI_DISPLAY_ONLY_IO_CAPABILITY,
27
27
  HCI_DISPLAY_YES_NO_IO_CAPABILITY,
28
28
  HCI_KEYBOARD_ONLY_IO_CAPABILITY,
29
29
  )
30
- from .smp import (
30
+ from bumble.smp import (
31
31
  SMP_NO_INPUT_NO_OUTPUT_IO_CAPABILITY,
32
32
  SMP_KEYBOARD_ONLY_IO_CAPABILITY,
33
33
  SMP_DISPLAY_ONLY_IO_CAPABILITY,
@@ -41,7 +41,7 @@ from .smp import (
41
41
  OobLegacyContext,
42
42
  OobSharedData,
43
43
  )
44
- from .core import AdvertisingData, LeRole
44
+ from bumble.core import AdvertisingData, LeRole
45
45
 
46
46
 
47
47
  # -----------------------------------------------------------------------------
@@ -22,11 +22,11 @@ __version__ = "0.0.1"
22
22
  import grpc
23
23
  import grpc.aio
24
24
 
25
- from .config import Config
26
- from .device import PandoraDevice
27
- from .host import HostService
28
- from .l2cap import L2CAPService
29
- from .security import SecurityService, SecurityStorageService
25
+ from bumble.pandora.config import Config
26
+ from bumble.pandora.device import PandoraDevice
27
+ from bumble.pandora.host import HostService
28
+ from bumble.pandora.l2cap import L2CAPService
29
+ from bumble.pandora.security import SecurityService, SecurityStorageService
30
30
  from pandora.host_grpc_aio import add_HostServicer_to_server
31
31
  from pandora.l2cap_grpc_aio import add_L2CAPServicer_to_server
32
32
  from pandora.security_grpc_aio import (
bumble/pandora/host.py CHANGED
@@ -20,12 +20,11 @@ import grpc.aio
20
20
  import logging
21
21
  import struct
22
22
 
23
- from . import utils
24
- from .config import Config
23
+ import bumble.utils
24
+ from bumble.pandora import utils
25
+ from bumble.pandora.config import Config
25
26
  from bumble.core import (
26
- BT_BR_EDR_TRANSPORT,
27
- BT_LE_TRANSPORT,
28
- BT_PERIPHERAL_ROLE,
27
+ PhysicalTransport,
29
28
  UUID,
30
29
  AdvertisingData,
31
30
  Appearance,
@@ -47,6 +46,8 @@ from bumble.hci import (
47
46
  HCI_REMOTE_USER_TERMINATED_CONNECTION_ERROR,
48
47
  Address,
49
48
  Phy,
49
+ Role,
50
+ OwnAddressType,
50
51
  )
51
52
  from google.protobuf import any_pb2 # pytype: disable=pyi-error
52
53
  from google.protobuf import empty_pb2 # pytype: disable=pyi-error
@@ -114,11 +115,11 @@ SECONDARY_PHY_TO_BUMBLE_PHY_MAP: Dict[SecondaryPhy, Phy] = {
114
115
  SECONDARY_CODED: Phy.LE_CODED,
115
116
  }
116
117
 
117
- OWN_ADDRESS_MAP: Dict[host_pb2.OwnAddressType, bumble.hci.OwnAddressType] = {
118
- host_pb2.PUBLIC: bumble.hci.OwnAddressType.PUBLIC,
119
- host_pb2.RANDOM: bumble.hci.OwnAddressType.RANDOM,
120
- host_pb2.RESOLVABLE_OR_PUBLIC: bumble.hci.OwnAddressType.RESOLVABLE_OR_PUBLIC,
121
- host_pb2.RESOLVABLE_OR_RANDOM: bumble.hci.OwnAddressType.RESOLVABLE_OR_RANDOM,
118
+ OWN_ADDRESS_MAP: Dict[host_pb2.OwnAddressType, OwnAddressType] = {
119
+ host_pb2.PUBLIC: OwnAddressType.PUBLIC,
120
+ host_pb2.RANDOM: OwnAddressType.RANDOM,
121
+ host_pb2.RESOLVABLE_OR_PUBLIC: OwnAddressType.RESOLVABLE_OR_PUBLIC,
122
+ host_pb2.RESOLVABLE_OR_RANDOM: OwnAddressType.RESOLVABLE_OR_RANDOM,
122
123
  }
123
124
 
124
125
 
@@ -184,7 +185,7 @@ class HostService(HostServicer):
184
185
 
185
186
  try:
186
187
  connection = await self.device.connect(
187
- address, transport=BT_BR_EDR_TRANSPORT
188
+ address, transport=PhysicalTransport.BR_EDR
188
189
  )
189
190
  except ConnectionError as e:
190
191
  if e.error_code == HCI_PAGE_TIMEOUT_ERROR:
@@ -217,7 +218,7 @@ class HostService(HostServicer):
217
218
  self.log.debug(f"WaitConnection from {address}...")
218
219
 
219
220
  connection = self.device.find_connection_by_bd_addr(
220
- address, transport=BT_BR_EDR_TRANSPORT
221
+ address, transport=PhysicalTransport.BR_EDR
221
222
  )
222
223
  if connection and id(connection) in self.waited_connections:
223
224
  # this connection was already returned: wait for a new one.
@@ -249,8 +250,8 @@ class HostService(HostServicer):
249
250
  try:
250
251
  connection = await self.device.connect(
251
252
  address,
252
- transport=BT_LE_TRANSPORT,
253
- own_address_type=request.own_address_type,
253
+ transport=PhysicalTransport.LE,
254
+ own_address_type=OwnAddressType(request.own_address_type),
254
255
  )
255
256
  except ConnectionError as e:
256
257
  if e.error_code == HCI_PAGE_TIMEOUT_ERROR:
@@ -377,8 +378,8 @@ class HostService(HostServicer):
377
378
 
378
379
  def on_connection(connection: bumble.device.Connection) -> None:
379
380
  if (
380
- connection.transport == BT_LE_TRANSPORT
381
- and connection.role == BT_PERIPHERAL_ROLE
381
+ connection.transport == PhysicalTransport.LE
382
+ and connection.role == Role.PERIPHERAL
382
383
  ):
383
384
  connections.put_nowait(connection)
384
385
 
@@ -495,8 +496,8 @@ class HostService(HostServicer):
495
496
 
496
497
  def on_connection(connection: bumble.device.Connection) -> None:
497
498
  if (
498
- connection.transport == BT_LE_TRANSPORT
499
- and connection.role == BT_PERIPHERAL_ROLE
499
+ connection.transport == PhysicalTransport.LE
500
+ and connection.role == Role.PERIPHERAL
500
501
  ):
501
502
  connections.put_nowait(connection)
502
503
 
@@ -509,7 +510,7 @@ class HostService(HostServicer):
509
510
  await self.device.start_advertising(
510
511
  target=target,
511
512
  advertising_type=advertising_type,
512
- own_address_type=request.own_address_type,
513
+ own_address_type=OwnAddressType(request.own_address_type),
513
514
  )
514
515
 
515
516
  if not request.connectable:
@@ -534,7 +535,9 @@ class HostService(HostServicer):
534
535
 
535
536
  try:
536
537
  self.log.debug('Stop advertising')
537
- await self.device.abort_on('flush', self.device.stop_advertising())
538
+ await bumble.utils.cancel_on_event(
539
+ self.device, 'flush', self.device.stop_advertising()
540
+ )
538
541
  except:
539
542
  pass
540
543
 
@@ -558,7 +561,7 @@ class HostService(HostServicer):
558
561
  await self.device.start_scanning(
559
562
  legacy=request.legacy,
560
563
  active=not request.passive,
561
- own_address_type=request.own_address_type,
564
+ own_address_type=OwnAddressType(request.own_address_type),
562
565
  scan_interval=(
563
566
  int(request.interval)
564
567
  if request.interval
@@ -602,7 +605,9 @@ class HostService(HostServicer):
602
605
  self.device.remove_listener('advertisement', handler) # type: ignore
603
606
  try:
604
607
  self.log.debug('Stop scanning')
605
- await self.device.abort_on('flush', self.device.stop_scanning())
608
+ await bumble.utils.cancel_on_event(
609
+ self.device, 'flush', self.device.stop_scanning()
610
+ )
606
611
  except:
607
612
  pass
608
613
 
@@ -642,7 +647,9 @@ class HostService(HostServicer):
642
647
  self.device.remove_listener('inquiry_result', result_handler) # type: ignore
643
648
  try:
644
649
  self.log.debug('Stop inquiry')
645
- await self.device.abort_on('flush', self.device.stop_discovery())
650
+ await bumble.utils.cancel_on_event(
651
+ self.device, 'flush', self.device.stop_discovery()
652
+ )
646
653
  except:
647
654
  pass
648
655
 
bumble/pandora/l2cap.py CHANGED
@@ -19,8 +19,8 @@ import logging
19
19
 
20
20
  from asyncio import Queue as AsyncQueue, Future
21
21
 
22
- from . import utils
23
- from .config import Config
22
+ from bumble.pandora import utils
23
+ from bumble.pandora.config import Config
24
24
  from bumble.core import OutOfResourcesError, InvalidArgumentError
25
25
  from bumble.device import Device
26
26
  from bumble.l2cap import (
@@ -18,18 +18,16 @@ import contextlib
18
18
  import grpc
19
19
  import logging
20
20
 
21
- from . import utils
22
- from .config import Config
21
+ from bumble.pandora import utils
22
+ from bumble.pandora.config import Config
23
23
  from bumble import hci
24
24
  from bumble.core import (
25
- BT_BR_EDR_TRANSPORT,
26
- BT_LE_TRANSPORT,
27
- BT_PERIPHERAL_ROLE,
25
+ PhysicalTransport,
28
26
  ProtocolError,
29
27
  )
28
+ import bumble.utils
30
29
  from bumble.device import Connection as BumbleConnection, Device
31
- from bumble.hci import HCI_Error
32
- from bumble.utils import EventWatcher
30
+ from bumble.hci import HCI_Error, Role
33
31
  from bumble.pairing import PairingConfig, PairingDelegate as BasePairingDelegate
34
32
  from google.protobuf import any_pb2 # pytype: disable=pyi-error
35
33
  from google.protobuf import empty_pb2 # pytype: disable=pyi-error
@@ -95,7 +93,7 @@ class PairingDelegate(BasePairingDelegate):
95
93
  else:
96
94
  # In BR/EDR, connection may not be complete,
97
95
  # use address instead
98
- assert self.connection.transport == BT_BR_EDR_TRANSPORT
96
+ assert self.connection.transport == PhysicalTransport.BR_EDR
99
97
  ev.address = bytes(reversed(bytes(self.connection.peer_address)))
100
98
 
101
99
  return ev
@@ -174,7 +172,7 @@ class PairingDelegate(BasePairingDelegate):
174
172
 
175
173
  async def display_number(self, number: int, digits: int = 6) -> None:
176
174
  if (
177
- self.connection.transport == BT_BR_EDR_TRANSPORT
175
+ self.connection.transport == PhysicalTransport.BR_EDR
178
176
  and self.io_capability == BasePairingDelegate.DISPLAY_OUTPUT_ONLY
179
177
  ):
180
178
  return
@@ -287,7 +285,7 @@ class SecurityService(SecurityServicer):
287
285
 
288
286
  oneof = request.WhichOneof('level')
289
287
  level = getattr(request, oneof)
290
- assert {BT_BR_EDR_TRANSPORT: 'classic', BT_LE_TRANSPORT: 'le'}[
288
+ assert {PhysicalTransport.BR_EDR: 'classic', PhysicalTransport.LE: 'le'}[
291
289
  connection.transport
292
290
  ] == oneof
293
291
 
@@ -302,7 +300,7 @@ class SecurityService(SecurityServicer):
302
300
 
303
301
  security_result = asyncio.get_running_loop().create_future()
304
302
 
305
- with contextlib.closing(EventWatcher()) as watcher:
303
+ with contextlib.closing(bumble.utils.EventWatcher()) as watcher:
306
304
 
307
305
  @watcher.on(connection, 'pairing')
308
306
  def on_pairing(*_: Any) -> None:
@@ -317,8 +315,8 @@ class SecurityService(SecurityServicer):
317
315
  security_result.set_result('connection_died')
318
316
 
319
317
  if (
320
- connection.transport == BT_LE_TRANSPORT
321
- and connection.role == BT_PERIPHERAL_ROLE
318
+ connection.transport == PhysicalTransport.LE
319
+ and connection.role == Role.PERIPHERAL
322
320
  ):
323
321
  connection.request_pairing()
324
322
  else:
@@ -379,7 +377,7 @@ class SecurityService(SecurityServicer):
379
377
 
380
378
  assert request.level
381
379
  level = request.level
382
- assert {BT_BR_EDR_TRANSPORT: 'classic', BT_LE_TRANSPORT: 'le'}[
380
+ assert {PhysicalTransport.BR_EDR: 'classic', PhysicalTransport.LE: 'le'}[
383
381
  connection.transport
384
382
  ] == request.level_variant()
385
383
 
@@ -427,7 +425,7 @@ class SecurityService(SecurityServicer):
427
425
  self.log.debug('Wait for security: done')
428
426
  wait_for_security.set_result('success')
429
427
  elif (
430
- connection.transport == BT_BR_EDR_TRANSPORT
428
+ connection.transport == PhysicalTransport.BR_EDR
431
429
  and self.need_authentication(connection, level)
432
430
  ):
433
431
  nonlocal authenticate_task
@@ -451,7 +449,7 @@ class SecurityService(SecurityServicer):
451
449
  'security_request': pair,
452
450
  }
453
451
 
454
- with contextlib.closing(EventWatcher()) as watcher:
452
+ with contextlib.closing(bumble.utils.EventWatcher()) as watcher:
455
453
  # register event handlers
456
454
  for event, listener in listeners.items():
457
455
  watcher.on(connection, event, listener)
@@ -505,12 +503,12 @@ class SecurityService(SecurityServicer):
505
503
  return BR_LEVEL_REACHED[level](connection)
506
504
 
507
505
  def need_pairing(self, connection: BumbleConnection, level: int) -> bool:
508
- if connection.transport == BT_LE_TRANSPORT:
506
+ if connection.transport == PhysicalTransport.LE:
509
507
  return level >= LE_LEVEL3 and not connection.authenticated
510
508
  return False
511
509
 
512
510
  def need_authentication(self, connection: BumbleConnection, level: int) -> bool:
513
- if connection.transport == BT_LE_TRANSPORT:
511
+ if connection.transport == PhysicalTransport.LE:
514
512
  return False
515
513
  if level == LEVEL2 and connection.encryption != 0:
516
514
  return not connection.authenticated
@@ -518,7 +516,7 @@ class SecurityService(SecurityServicer):
518
516
 
519
517
  def need_encryption(self, connection: BumbleConnection, level: int) -> bool:
520
518
  # TODO(abel): need to support MITM
521
- if connection.transport == BT_LE_TRANSPORT:
519
+ if connection.transport == PhysicalTransport.LE:
522
520
  return level == LE_LEVEL2 and not connection.encryption
523
521
  return level >= LEVEL2 and not connection.encryption
524
522
 
bumble/pandora/utils.py CHANGED
@@ -20,11 +20,11 @@ import inspect
20
20
  import logging
21
21
 
22
22
  from bumble.device import Device
23
- from bumble.hci import Address
23
+ from bumble.hci import Address, AddressType
24
24
  from google.protobuf.message import Message # pytype: disable=pyi-error
25
25
  from typing import Any, Dict, Generator, MutableMapping, Optional, Tuple
26
26
 
27
- ADDRESS_TYPES: Dict[str, int] = {
27
+ ADDRESS_TYPES: Dict[str, AddressType] = {
28
28
  "public": Address.PUBLIC_DEVICE_ADDRESS,
29
29
  "random": Address.RANDOM_DEVICE_ADDRESS,
30
30
  "public_identity": Address.PUBLIC_IDENTITY_ADDRESS,
bumble/profiles/aics.py CHANGED
@@ -48,7 +48,7 @@ from bumble.gatt_adapters import (
48
48
  UTF8CharacteristicProxyAdapter,
49
49
  )
50
50
  from bumble.gatt_client import ProfileServiceProxy, ServiceProxy
51
- from bumble.utils import OpenIntEnum
51
+ from bumble import utils
52
52
 
53
53
  # -----------------------------------------------------------------------------
54
54
  # Logging
@@ -64,7 +64,7 @@ GAIN_SETTINGS_MIN_VALUE = 0
64
64
  GAIN_SETTINGS_MAX_VALUE = 255
65
65
 
66
66
 
67
- class ErrorCode(OpenIntEnum):
67
+ class ErrorCode(utils.OpenIntEnum):
68
68
  '''
69
69
  Cf. 1.6 Application error codes
70
70
  '''
@@ -76,7 +76,7 @@ class ErrorCode(OpenIntEnum):
76
76
  GAIN_MODE_CHANGE_NOT_ALLOWED = 0x84
77
77
 
78
78
 
79
- class Mute(OpenIntEnum):
79
+ class Mute(utils.OpenIntEnum):
80
80
  '''
81
81
  Cf. 2.2.1.2 Mute Field
82
82
  '''
@@ -86,7 +86,7 @@ class Mute(OpenIntEnum):
86
86
  DISABLED = 0x02
87
87
 
88
88
 
89
- class GainMode(OpenIntEnum):
89
+ class GainMode(utils.OpenIntEnum):
90
90
  '''
91
91
  Cf. 2.2.1.3 Gain Mode
92
92
  '''
@@ -97,7 +97,7 @@ class GainMode(OpenIntEnum):
97
97
  AUTOMATIC = 0x03
98
98
 
99
99
 
100
- class AudioInputStatus(OpenIntEnum):
100
+ class AudioInputStatus(utils.OpenIntEnum):
101
101
  '''
102
102
  Cf. 3.4 Audio Input Status
103
103
  '''
@@ -106,7 +106,7 @@ class AudioInputStatus(OpenIntEnum):
106
106
  ACTIVE = 0x01
107
107
 
108
108
 
109
- class AudioInputControlPointOpCode(OpenIntEnum):
109
+ class AudioInputControlPointOpCode(utils.OpenIntEnum):
110
110
  '''
111
111
  Cf. 3.5.1 Audio Input Control Point procedure requirements
112
112
  '''