bumble 0.0.204__py3-none-any.whl → 0.0.207__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.
bumble/gatt.py CHANGED
@@ -42,13 +42,12 @@ from typing import (
42
42
  )
43
43
 
44
44
  from bumble.colors import color
45
- from bumble.core import BaseBumbleError, UUID
45
+ from bumble.core import BaseBumbleError, InvalidOperationError, UUID
46
46
  from bumble.att import Attribute, AttributeValue
47
47
  from bumble.utils import ByteSerializable
48
48
 
49
49
  if TYPE_CHECKING:
50
50
  from bumble.gatt_client import AttributeProxy
51
- from bumble.device import Connection
52
51
 
53
52
 
54
53
  # -----------------------------------------------------------------------------
@@ -279,6 +278,13 @@ GATT_SOURCE_AUDIO_LOCATION_CHARACTERISTIC = UUID.from_16_bits(0x2BCC, 'Sou
279
278
  GATT_AVAILABLE_AUDIO_CONTEXTS_CHARACTERISTIC = UUID.from_16_bits(0x2BCD, 'Available Audio Contexts')
280
279
  GATT_SUPPORTED_AUDIO_CONTEXTS_CHARACTERISTIC = UUID.from_16_bits(0x2BCE, 'Supported Audio Contexts')
281
280
 
281
+ # Gaming Audio Service (GMAS)
282
+ GATT_GMAP_ROLE_CHARACTERISTIC = UUID.from_16_bits(0x2C00, 'GMAP Role')
283
+ GATT_UGG_FEATURES_CHARACTERISTIC = UUID.from_16_bits(0x2C01, 'UGG Features')
284
+ GATT_UGT_FEATURES_CHARACTERISTIC = UUID.from_16_bits(0x2C02, 'UGT Features')
285
+ GATT_BGS_FEATURES_CHARACTERISTIC = UUID.from_16_bits(0x2C03, 'BGS Features')
286
+ GATT_BGR_FEATURES_CHARACTERISTIC = UUID.from_16_bits(0x2C04, 'BGR Features')
287
+
282
288
  # Hearing Access Service
283
289
  GATT_HEARING_AID_FEATURES_CHARACTERISTIC = UUID.from_16_bits(0x2BDA, 'Hearing Aid Features')
284
290
  GATT_HEARING_AID_PRESET_CONTROL_POINT_CHARACTERISTIC = UUID.from_16_bits(0x2BDB, 'Hearing Aid Preset Control Point')
@@ -308,6 +314,7 @@ GATT_CENTRAL_ADDRESS_RESOLUTION__CHARACTERISTIC = UUID.from_16_bi
308
314
  GATT_CLIENT_SUPPORTED_FEATURES_CHARACTERISTIC = UUID.from_16_bits(0x2B29, 'Client Supported Features')
309
315
  GATT_DATABASE_HASH_CHARACTERISTIC = UUID.from_16_bits(0x2B2A, 'Database Hash')
310
316
  GATT_SERVER_SUPPORTED_FEATURES_CHARACTERISTIC = UUID.from_16_bits(0x2B3A, 'Server Supported Features')
317
+ GATT_LE_GATT_SECURITY_LEVELS_CHARACTERISTIC = UUID.from_16_bits(0x2BF5, 'E GATT Security Levels')
311
318
 
312
319
  # fmt: on
313
320
  # pylint: enable=line-too-long
@@ -316,8 +323,6 @@ GATT_SERVER_SUPPORTED_FEATURES_CHARACTERISTIC = UUID.from_16_bi
316
323
  # -----------------------------------------------------------------------------
317
324
  # Utils
318
325
  # -----------------------------------------------------------------------------
319
-
320
-
321
326
  def show_services(services: Iterable[Service]) -> None:
322
327
  for service in services:
323
328
  print(color(str(service), 'cyan'))
@@ -673,10 +678,14 @@ class DelegatedCharacteristicAdapter(CharacteristicAdapter):
673
678
  self.decode = decode
674
679
 
675
680
  def encode_value(self, value):
676
- return self.encode(value) if self.encode else value
681
+ if self.encode is None:
682
+ raise InvalidOperationError('delegated adapter does not have an encoder')
683
+ return self.encode(value)
677
684
 
678
685
  def decode_value(self, value):
679
- return self.decode(value) if self.decode else value
686
+ if self.decode is None:
687
+ raise InvalidOperationError('delegate adapter does not have a decoder')
688
+ return self.decode(value)
680
689
 
681
690
 
682
691
  # -----------------------------------------------------------------------------
@@ -795,3 +804,23 @@ class ClientCharacteristicConfigurationBits(enum.IntFlag):
795
804
  DEFAULT = 0x0000
796
805
  NOTIFICATION = 0x0001
797
806
  INDICATION = 0x0002
807
+
808
+
809
+ # -----------------------------------------------------------------------------
810
+ class ClientSupportedFeatures(enum.IntFlag):
811
+ '''
812
+ See Vol 3, Part G - 7.2 - Table 7.6: Client Supported Features bit assignments.
813
+ '''
814
+
815
+ ROBUST_CACHING = 0x01
816
+ ENHANCED_ATT_BEARER = 0x02
817
+ MULTIPLE_HANDLE_VALUE_NOTIFICATIONS = 0x04
818
+
819
+
820
+ # -----------------------------------------------------------------------------
821
+ class ServerSupportedFeatures(enum.IntFlag):
822
+ '''
823
+ See Vol 3, Part G - 7.4 - Table 7.11: Server Supported Features bit assignments.
824
+ '''
825
+
826
+ EATT_SUPPORTED = 0x01
bumble/gatt_client.py CHANGED
@@ -78,6 +78,7 @@ from .gatt import (
78
78
  GATT_INCLUDE_ATTRIBUTE_TYPE,
79
79
  Characteristic,
80
80
  ClientCharacteristicConfigurationBits,
81
+ InvalidServiceError,
81
82
  TemplateService,
82
83
  )
83
84
 
@@ -162,12 +163,23 @@ class ServiceProxy(AttributeProxy):
162
163
  self.uuid = uuid
163
164
  self.characteristics = []
164
165
 
165
- async def discover_characteristics(self, uuids=()):
166
+ async def discover_characteristics(self, uuids=()) -> list[CharacteristicProxy]:
166
167
  return await self.client.discover_characteristics(uuids, self)
167
168
 
168
- def get_characteristics_by_uuid(self, uuid):
169
+ def get_characteristics_by_uuid(self, uuid: UUID) -> list[CharacteristicProxy]:
170
+ """Get all the characteristics with a specified UUID."""
169
171
  return self.client.get_characteristics_by_uuid(uuid, self)
170
172
 
173
+ def get_required_characteristic_by_uuid(self, uuid: UUID) -> CharacteristicProxy:
174
+ """
175
+ Get the first characteristic with a specified UUID.
176
+
177
+ If no characteristic with that UUID is found, an InvalidServiceError is raised.
178
+ """
179
+ if not (characteristics := self.get_characteristics_by_uuid(uuid)):
180
+ raise InvalidServiceError(f'{uuid} characteristic not found')
181
+ return characteristics[0]
182
+
171
183
  def __str__(self) -> str:
172
184
  return f'Service(handle=0x{self.handle:04X}, uuid={self.uuid})'
173
185