Create Characteristic.Property
Move all Characteristic properties into its own `enum.IntFlag` class
diff --git a/apps/bench.py b/apps/bench.py
index 19cdcfa..4708403 100644
--- a/apps/bench.py
+++ b/apps/bench.py
@@ -558,11 +558,13 @@
# Setup the GATT service
self.speed_tx = Characteristic(
SPEED_TX_UUID,
- Characteristic.WRITE,
+ Characteristic.Properties.WRITE,
Characteristic.WRITEABLE,
CharacteristicValue(write=self.on_tx_write),
)
- self.speed_rx = Characteristic(SPEED_RX_UUID, Characteristic.NOTIFY, 0)
+ self.speed_rx = Characteristic(
+ SPEED_RX_UUID, Characteristic.Properties.NOTIFY, 0
+ )
speed_service = Service(
SPEED_SERVICE_UUID,
diff --git a/apps/console.py b/apps/console.py
index 498e224..1522f08 100644
--- a/apps/console.py
+++ b/apps/console.py
@@ -873,7 +873,7 @@
return
# use write with response if supported
- with_response = characteristic.properties & Characteristic.WRITE
+ with_response = characteristic.properties & Characteristic.Properties.WRITE
await characteristic.write_value(value, with_response=with_response)
async def do_local_write(self, params):
diff --git a/apps/gg_bridge.py b/apps/gg_bridge.py
index 17c1662..6506f7b 100644
--- a/apps/gg_bridge.py
+++ b/apps/gg_bridge.py
@@ -230,13 +230,13 @@
)
self.tx_characteristic = Characteristic(
GG_GATTLINK_TX_CHARACTERISTIC_UUID,
- Characteristic.NOTIFY,
+ Characteristic.Properties.NOTIFY,
Characteristic.READABLE,
)
self.tx_characteristic.on('subscription', self.on_tx_subscription)
self.psm_characteristic = Characteristic(
GG_GATTLINK_L2CAP_CHANNEL_PSM_CHARACTERISTIC_UUID,
- Characteristic.READ | Characteristic.NOTIFY,
+ Characteristic.Properties.READ | Characteristic.Properties.NOTIFY,
Characteristic.READABLE,
bytes([psm, 0]),
)
diff --git a/apps/pair.py b/apps/pair.py
index 3729143..541e5b5 100644
--- a/apps/pair.py
+++ b/apps/pair.py
@@ -302,7 +302,8 @@
[
Characteristic(
'552957FB-CF1F-4A31-9535-E78847E1A714',
- Characteristic.READ | Characteristic.WRITE,
+ Characteristic.Properties.READ
+ | Characteristic.Properties.WRITE,
Characteristic.READABLE | Characteristic.WRITEABLE,
CharacteristicValue(
read=read_with_error, write=write_with_error
diff --git a/bumble/device.py b/bumble/device.py
index 25fa099..0fa8f16 100644
--- a/bumble/device.py
+++ b/bumble/device.py
@@ -1018,7 +1018,9 @@
descriptors.append(new_descriptor)
new_characteristic = Characteristic(
uuid=characteristic["uuid"],
- properties=characteristic["properties"],
+ properties=Characteristic.Properties.from_string(
+ characteristic["properties"]
+ ),
permissions=characteristic["permissions"],
descriptors=descriptors,
)
diff --git a/bumble/gap.py b/bumble/gap.py
index a4d5077..29df89f 100644
--- a/bumble/gap.py
+++ b/bumble/gap.py
@@ -41,14 +41,14 @@
def __init__(self, device_name, appearance=(0, 0)):
device_name_characteristic = Characteristic(
GATT_DEVICE_NAME_CHARACTERISTIC,
- Characteristic.READ,
+ Characteristic.Properties.READ,
Characteristic.READABLE,
device_name.encode('utf-8')[:248],
)
appearance_characteristic = Characteristic(
GATT_APPEARANCE_CHARACTERISTIC,
- Characteristic.READ,
+ Characteristic.Properties.READ,
Characteristic.READABLE,
struct.pack('<H', (appearance[0] << 6) | appearance[1]),
)
diff --git a/bumble/gatt.py b/bumble/gatt.py
index 74ba6f0..88b7417 100644
--- a/bumble/gatt.py
+++ b/bumble/gatt.py
@@ -28,7 +28,7 @@
import functools
import logging
import struct
-from typing import Optional, Sequence, List, Any, Iterable
+from typing import Optional, Sequence, List
from .colors import color
from .core import UUID, get_dict_key_by_value
@@ -260,64 +260,67 @@
'''
uuid: UUID
+ properties: Characteristic.Properties
- # Property flags
- BROADCAST = 0x01
- READ = 0x02
- WRITE_WITHOUT_RESPONSE = 0x04
- WRITE = 0x08
- NOTIFY = 0x10
- INDICATE = 0x20
- AUTHENTICATED_SIGNED_WRITES = 0x40
- EXTENDED_PROPERTIES = 0x80
+ class Properties(enum.IntFlag):
+ """Property flags"""
- PROPERTY_NAMES = {
- BROADCAST: 'BROADCAST',
- READ: 'READ',
- WRITE_WITHOUT_RESPONSE: 'WRITE_WITHOUT_RESPONSE',
- WRITE: 'WRITE',
- NOTIFY: 'NOTIFY',
- INDICATE: 'INDICATE',
- AUTHENTICATED_SIGNED_WRITES: 'AUTHENTICATED_SIGNED_WRITES',
- EXTENDED_PROPERTIES: 'EXTENDED_PROPERTIES',
- }
+ BROADCAST = 0x01
+ READ = 0x02
+ WRITE_WITHOUT_RESPONSE = 0x04
+ WRITE = 0x08
+ NOTIFY = 0x10
+ INDICATE = 0x20
+ AUTHENTICATED_SIGNED_WRITES = 0x40
+ EXTENDED_PROPERTIES = 0x80
- @staticmethod
- def property_name(property_int):
- return Characteristic.PROPERTY_NAMES.get(property_int, '')
+ @staticmethod
+ def from_string(properties_str: str) -> Characteristic.Properties:
+ property_names: List[str] = []
+ for property in Characteristic.Properties:
+ if property.name is None:
+ raise TypeError()
+ property_names.append(property.name)
- @staticmethod
- def properties_as_string(properties):
- return ','.join(
- [
- Characteristic.property_name(p)
- for p in Characteristic.PROPERTY_NAMES
- if properties & p
- ]
- )
+ def string_to_property(property_string) -> Characteristic.Properties:
+ for property in zip(Characteristic.Properties, property_names):
+ if property_string == property[1]:
+ return property[0]
+ raise TypeError(f"Unable to convert {property_string} to Property")
- @staticmethod
- def string_to_properties(properties_str: str):
- return functools.reduce(
- lambda x, y: x | get_dict_key_by_value(Characteristic.PROPERTY_NAMES, y),
- properties_str.split(","),
- 0,
- )
+ try:
+ return functools.reduce(
+ lambda x, y: x | string_to_property(y),
+ properties_str.split(","),
+ Characteristic.Properties(0),
+ )
+ except TypeError:
+ raise TypeError(
+ f"Characteristic.Properties::from_string() error:\nExpected a string containing any of the keys, separated by commas: {','.join(property_names)}\nGot: {properties_str}"
+ )
+
+ # For backwards compatibility these are defined here
+ # For new code, please use Characteristic.Properties.X
+ BROADCAST = Properties.BROADCAST
+ READ = Properties.READ
+ WRITE_WITHOUT_RESPONSE = Properties.WRITE_WITHOUT_RESPONSE
+ WRITE = Properties.WRITE
+ NOTIFY = Properties.NOTIFY
+ INDICATE = Properties.INDICATE
+ AUTHENTICATED_SIGNED_WRITES = Properties.AUTHENTICATED_SIGNED_WRITES
+ EXTENDED_PROPERTIES = Properties.EXTENDED_PROPERTIES
def __init__(
self,
uuid,
- properties,
+ properties: Characteristic.Properties,
permissions,
value=b'',
descriptors: Sequence[Descriptor] = (),
):
super().__init__(uuid, permissions, value)
self.uuid = self.type
- if isinstance(properties, str):
- self.properties = Characteristic.string_to_properties(properties)
- else:
- self.properties = properties
+ self.properties = properties
self.descriptors = descriptors
def get_descriptor(self, descriptor_type):
@@ -327,18 +330,15 @@
return None
- def has_properties(self, properties: Iterable[int]):
- for prop in properties:
- if self.properties & prop == 0:
- return False
- return True
+ def has_properties(self, properties: Characteristic.Properties) -> bool:
+ return self.properties & properties == properties
def __str__(self):
return (
f'Characteristic(handle=0x{self.handle:04X}, '
f'end=0x{self.end_group_handle:04X}, '
f'uuid={self.uuid}, '
- f'properties={Characteristic.properties_as_string(self.properties)})'
+ f'{self.properties!s})'
)
@@ -365,8 +365,8 @@
return (
f'CharacteristicDeclaration(handle=0x{self.handle:04X}, '
f'value_handle=0x{self.value_handle:04X}, '
- f'uuid={self.characteristic.uuid}, properties='
- f'{Characteristic.properties_as_string(self.characteristic.properties)})'
+ f'uuid={self.characteristic.uuid}, '
+ f'{self.characteristic.properties!s})'
)
diff --git a/bumble/gatt_client.py b/bumble/gatt_client.py
index 17f622b..d7a0666 100644
--- a/bumble/gatt_client.py
+++ b/bumble/gatt_client.py
@@ -27,7 +27,7 @@
import asyncio
import logging
import struct
-from typing import List, Optional
+from typing import List, Optional, Dict, Any, Callable
from pyee import EventEmitter
@@ -138,9 +138,18 @@
class CharacteristicProxy(AttributeProxy):
+ properties: Characteristic.Properties
descriptors: List[DescriptorProxy]
+ subscribers: Dict[Any, Callable]
- def __init__(self, client, handle, end_group_handle, uuid, properties):
+ def __init__(
+ self,
+ client,
+ handle,
+ end_group_handle,
+ uuid,
+ properties: Characteristic.Properties,
+ ):
super().__init__(client, handle, end_group_handle, uuid)
self.uuid = uuid
self.properties = properties
@@ -185,7 +194,7 @@
return (
f'Characteristic(handle=0x{self.handle:04X}, '
f'uuid={self.uuid}, '
- f'properties={Characteristic.properties_as_string(self.properties)})'
+ f'properties={self.properties!s})'
)
@@ -677,8 +686,8 @@
return
if (
- characteristic.properties & Characteristic.NOTIFY
- and characteristic.properties & Characteristic.INDICATE
+ characteristic.properties & Characteristic.Properties.NOTIFY
+ and characteristic.properties & Characteristic.Properties.INDICATE
):
if prefer_notify:
bits = ClientCharacteristicConfigurationBits.NOTIFICATION
@@ -686,10 +695,10 @@
else:
bits = ClientCharacteristicConfigurationBits.INDICATION
subscribers = self.indication_subscribers
- elif characteristic.properties & Characteristic.NOTIFY:
+ elif characteristic.properties & Characteristic.Properties.NOTIFY:
bits = ClientCharacteristicConfigurationBits.NOTIFICATION
subscribers = self.notification_subscribers
- elif characteristic.properties & Characteristic.INDICATE:
+ elif characteristic.properties & Characteristic.Properties.INDICATE:
bits = ClientCharacteristicConfigurationBits.INDICATION
subscribers = self.indication_subscribers
else:
diff --git a/bumble/gatt_server.py b/bumble/gatt_server.py
index e3529c8..51f3ec0 100644
--- a/bumble/gatt_server.py
+++ b/bumble/gatt_server.py
@@ -243,7 +243,10 @@
# unless there is one already
if (
characteristic.properties
- & (Characteristic.NOTIFY | Characteristic.INDICATE)
+ & (
+ Characteristic.Properties.NOTIFY
+ | Characteristic.Properties.INDICATE
+ )
and characteristic.get_descriptor(
GATT_CLIENT_CHARACTERISTIC_CONFIGURATION_DESCRIPTOR
)
diff --git a/bumble/profiles/asha_service.py b/bumble/profiles/asha_service.py
index 1b1e93a..6898397 100644
--- a/bumble/profiles/asha_service.py
+++ b/bumble/profiles/asha_service.py
@@ -103,7 +103,7 @@
self.read_only_properties_characteristic = Characteristic(
GATT_ASHA_READ_ONLY_PROPERTIES_CHARACTERISTIC,
- Characteristic.READ,
+ Characteristic.Properties.READ,
Characteristic.READABLE,
bytes(
[
@@ -120,19 +120,20 @@
self.audio_control_point_characteristic = Characteristic(
GATT_ASHA_AUDIO_CONTROL_POINT_CHARACTERISTIC,
- Characteristic.WRITE | Characteristic.WRITE_WITHOUT_RESPONSE,
+ Characteristic.Properties.WRITE
+ | Characteristic.Properties.WRITE_WITHOUT_RESPONSE,
Characteristic.WRITEABLE,
CharacteristicValue(write=on_audio_control_point_write),
)
self.audio_status_characteristic = Characteristic(
GATT_ASHA_AUDIO_STATUS_CHARACTERISTIC,
- Characteristic.READ | Characteristic.NOTIFY,
+ Characteristic.Properties.READ | Characteristic.Properties.NOTIFY,
Characteristic.READABLE,
bytes([0]),
)
self.volume_characteristic = Characteristic(
GATT_ASHA_VOLUME_CHARACTERISTIC,
- Characteristic.WRITE_WITHOUT_RESPONSE,
+ Characteristic.Properties.WRITE_WITHOUT_RESPONSE,
Characteristic.WRITEABLE,
CharacteristicValue(write=on_volume_write),
)
@@ -151,7 +152,7 @@
self.psm = self.device.register_l2cap_channel_server(self.psm, on_coc, 8)
self.le_psm_out_characteristic = Characteristic(
GATT_ASHA_LE_PSM_OUT_CHARACTERISTIC,
- Characteristic.READ,
+ Characteristic.Properties.READ,
Characteristic.READABLE,
struct.pack('<H', self.psm),
)
diff --git a/bumble/profiles/battery_service.py b/bumble/profiles/battery_service.py
index f6ccc10..211fee0 100644
--- a/bumble/profiles/battery_service.py
+++ b/bumble/profiles/battery_service.py
@@ -36,7 +36,7 @@
self.battery_level_characteristic = PackedCharacteristicAdapter(
Characteristic(
GATT_BATTERY_LEVEL_CHARACTERISTIC,
- Characteristic.READ | Characteristic.NOTIFY,
+ Characteristic.Properties.READ | Characteristic.Properties.NOTIFY,
Characteristic.READABLE,
CharacteristicValue(read=read_battery_level),
),
diff --git a/bumble/profiles/device_information_service.py b/bumble/profiles/device_information_service.py
index 2ad9cae..09bfd6c 100644
--- a/bumble/profiles/device_information_service.py
+++ b/bumble/profiles/device_information_service.py
@@ -63,7 +63,9 @@
# TODO: pnp_id
):
characteristics = [
- Characteristic(uuid, Characteristic.READ, Characteristic.READABLE, field)
+ Characteristic(
+ uuid, Characteristic.Properties.READ, Characteristic.READABLE, field
+ )
for (field, uuid) in (
(manufacturer_name, GATT_MANUFACTURER_NAME_STRING_CHARACTERISTIC),
(model_number, GATT_MODEL_NUMBER_STRING_CHARACTERISTIC),
@@ -79,7 +81,7 @@
characteristics.append(
Characteristic(
GATT_SYSTEM_ID_CHARACTERISTIC,
- Characteristic.READ,
+ Characteristic.Properties.READ,
Characteristic.READABLE,
self.pack_system_id(*system_id),
)
@@ -89,7 +91,7 @@
characteristics.append(
Characteristic(
GATT_REGULATORY_CERTIFICATION_DATA_LIST_CHARACTERISTIC,
- Characteristic.READ,
+ Characteristic.Properties.READ,
Characteristic.READABLE,
ieee_regulatory_certification_data_list,
)
diff --git a/bumble/profiles/heart_rate_service.py b/bumble/profiles/heart_rate_service.py
index 5755535..c7d3018 100644
--- a/bumble/profiles/heart_rate_service.py
+++ b/bumble/profiles/heart_rate_service.py
@@ -152,7 +152,7 @@
self.heart_rate_measurement_characteristic = DelegatedCharacteristicAdapter(
Characteristic(
GATT_HEART_RATE_MEASUREMENT_CHARACTERISTIC,
- Characteristic.NOTIFY,
+ Characteristic.Properties.NOTIFY,
0,
CharacteristicValue(read=read_heart_rate_measurement),
),
@@ -164,7 +164,7 @@
if body_sensor_location is not None:
self.body_sensor_location_characteristic = Characteristic(
GATT_BODY_SENSOR_LOCATION_CHARACTERISTIC,
- Characteristic.READ,
+ Characteristic.Properties.READ,
Characteristic.READABLE,
bytes([int(body_sensor_location)]),
)
@@ -182,7 +182,7 @@
self.heart_rate_control_point_characteristic = PackedCharacteristicAdapter(
Characteristic(
GATT_HEART_RATE_CONTROL_POINT_CHARACTERISTIC,
- Characteristic.WRITE,
+ Characteristic.Properties.WRITE,
Characteristic.WRITEABLE,
CharacteristicValue(write=write_heart_rate_control_point_value),
),
diff --git a/examples/keyboard.py b/examples/keyboard.py
index 16dbeb6..314a805 100644
--- a/examples/keyboard.py
+++ b/examples/keyboard.py
@@ -209,7 +209,7 @@
return
for i, characteristic in enumerate(report_characteristics):
print(color('REPORT:', 'yellow'), characteristic)
- if characteristic.properties & Characteristic.NOTIFY:
+ if characteristic.properties & Characteristic.Properties.NOTIFY:
await peer.discover_descriptors(characteristic)
report_reference_descriptor = characteristic.get_descriptor(
GATT_REPORT_REFERENCE_DESCRIPTOR
@@ -241,7 +241,9 @@
# Create an 'input report' characteristic to send keyboard reports to the host
input_report_characteristic = Characteristic(
GATT_REPORT_CHARACTERISTIC,
- Characteristic.READ | Characteristic.WRITE | Characteristic.NOTIFY,
+ Characteristic.Properties.READ
+ | Characteristic.Properties.WRITE
+ | Characteristic.Properties.NOTIFY,
Characteristic.READABLE | Characteristic.WRITEABLE,
bytes([0, 0, 0, 0, 0, 0, 0, 0]),
[
@@ -256,8 +258,8 @@
# Create an 'output report' characteristic to receive keyboard reports from the host
output_report_characteristic = Characteristic(
GATT_REPORT_CHARACTERISTIC,
- Characteristic.READ
- | Characteristic.WRITE
+ Characteristic.Properties.READ
+ | Characteristic.Properties.WRITE
| Characteristic.WRITE_WITHOUT_RESPONSE,
Characteristic.READABLE | Characteristic.WRITEABLE,
bytes([0]),
@@ -278,7 +280,7 @@
[
Characteristic(
GATT_MANUFACTURER_NAME_STRING_CHARACTERISTIC,
- Characteristic.READ,
+ Characteristic.Properties.READ,
Characteristic.READABLE,
'Bumble',
)
@@ -289,13 +291,13 @@
[
Characteristic(
GATT_PROTOCOL_MODE_CHARACTERISTIC,
- Characteristic.READ,
+ Characteristic.Properties.READ,
Characteristic.READABLE,
bytes([HID_REPORT_PROTOCOL]),
),
Characteristic(
GATT_HID_INFORMATION_CHARACTERISTIC,
- Characteristic.READ,
+ Characteristic.Properties.READ,
Characteristic.READABLE,
# bcdHID=1.1, bCountryCode=0x00,
# Flags=RemoteWake|NormallyConnectable
@@ -309,7 +311,7 @@
),
Characteristic(
GATT_REPORT_MAP_CHARACTERISTIC,
- Characteristic.READ,
+ Characteristic.Properties.READ,
Characteristic.READABLE,
HID_KEYBOARD_REPORT_MAP,
),
@@ -322,7 +324,7 @@
[
Characteristic(
GATT_BATTERY_LEVEL_CHARACTERISTIC,
- Characteristic.READ,
+ Characteristic.Properties.READ,
Characteristic.READABLE,
bytes([100]),
)
diff --git a/examples/run_asha_sink.py b/examples/run_asha_sink.py
index 3b8083c..3e4955d 100644
--- a/examples/run_asha_sink.py
+++ b/examples/run_asha_sink.py
@@ -101,7 +101,7 @@
# Add the ASHA service to the GATT server
read_only_properties_characteristic = Characteristic(
ASHA_READ_ONLY_PROPERTIES_CHARACTERISTIC,
- Characteristic.READ,
+ Characteristic.Properties.READ,
Characteristic.READABLE,
bytes(
[
@@ -127,13 +127,13 @@
)
audio_control_point_characteristic = Characteristic(
ASHA_AUDIO_CONTROL_POINT_CHARACTERISTIC,
- Characteristic.WRITE | Characteristic.WRITE_WITHOUT_RESPONSE,
+ Characteristic.Properties.WRITE | Characteristic.WRITE_WITHOUT_RESPONSE,
Characteristic.WRITEABLE,
CharacteristicValue(write=on_audio_control_point_write),
)
audio_status_characteristic = Characteristic(
ASHA_AUDIO_STATUS_CHARACTERISTIC,
- Characteristic.READ | Characteristic.NOTIFY,
+ Characteristic.Properties.READ | Characteristic.Properties.NOTIFY,
Characteristic.READABLE,
bytes([0]),
)
@@ -145,7 +145,7 @@
)
le_psm_out_characteristic = Characteristic(
ASHA_LE_PSM_OUT_CHARACTERISTIC,
- Characteristic.READ,
+ Characteristic.Properties.READ,
Characteristic.READABLE,
struct.pack('<H', psm),
)
diff --git a/examples/run_controller.py b/examples/run_controller.py
index 885b96d..596ac8b 100644
--- a/examples/run_controller.py
+++ b/examples/run_controller.py
@@ -80,7 +80,7 @@
)
manufacturer_name_characteristic = Characteristic(
GATT_MANUFACTURER_NAME_STRING_CHARACTERISTIC,
- Characteristic.READ,
+ Characteristic.Properties.READ,
Characteristic.READABLE,
"Fitbit",
[descriptor],
diff --git a/examples/run_gatt_client_and_server.py b/examples/run_gatt_client_and_server.py
index f3df733..609fe18 100644
--- a/examples/run_gatt_client_and_server.py
+++ b/examples/run_gatt_client_and_server.py
@@ -70,7 +70,7 @@
)
manufacturer_name_characteristic = Characteristic(
GATT_MANUFACTURER_NAME_STRING_CHARACTERISTIC,
- Characteristic.READ,
+ Characteristic.Properties.READ,
Characteristic.READABLE,
"Fitbit",
[descriptor],
diff --git a/examples/run_gatt_server.py b/examples/run_gatt_server.py
index 041b440..46d42a2 100644
--- a/examples/run_gatt_server.py
+++ b/examples/run_gatt_server.py
@@ -96,7 +96,7 @@
)
manufacturer_name_characteristic = Characteristic(
GATT_MANUFACTURER_NAME_STRING_CHARACTERISTIC,
- Characteristic.READ,
+ Characteristic.Properties.READ,
Characteristic.READABLE,
'Fitbit',
[descriptor],
@@ -109,13 +109,13 @@
[
Characteristic(
'D901B45B-4916-412E-ACCA-376ECB603B2C',
- Characteristic.READ | Characteristic.WRITE,
+ Characteristic.Properties.READ | Characteristic.Properties.WRITE,
Characteristic.READABLE | Characteristic.WRITEABLE,
CharacteristicValue(read=my_custom_read, write=my_custom_write),
),
Characteristic(
'552957FB-CF1F-4A31-9535-E78847E1A714',
- Characteristic.READ | Characteristic.WRITE,
+ Characteristic.Properties.READ | Characteristic.Properties.WRITE,
Characteristic.READABLE | Characteristic.WRITEABLE,
CharacteristicValue(
read=my_custom_read_with_error, write=my_custom_write_with_error
@@ -123,7 +123,7 @@
),
Characteristic(
'486F64C6-4B5F-4B3B-8AFF-EDE134A8446A',
- Characteristic.READ | Characteristic.NOTIFY,
+ Characteristic.Properties.READ | Characteristic.Properties.NOTIFY,
Characteristic.READABLE,
'hello',
),
diff --git a/examples/run_notifier.py b/examples/run_notifier.py
index 673286b..5f6def3 100644
--- a/examples/run_notifier.py
+++ b/examples/run_notifier.py
@@ -74,19 +74,21 @@
# Add a few entries to the device's GATT server
characteristic1 = Characteristic(
'486F64C6-4B5F-4B3B-8AFF-EDE134A8446A',
- Characteristic.READ | Characteristic.NOTIFY,
+ Characteristic.Properties.READ | Characteristic.Properties.NOTIFY,
Characteristic.READABLE,
bytes([0x40]),
)
characteristic2 = Characteristic(
'8EBDEBAE-0017-418E-8D3B-3A3809492165',
- Characteristic.READ | Characteristic.INDICATE,
+ Characteristic.Properties.READ | Characteristic.Properties.INDICATE,
Characteristic.READABLE,
bytes([0x41]),
)
characteristic3 = Characteristic(
'8EBDEBAE-0017-418E-8D3B-3A3809492165',
- Characteristic.READ | Characteristic.NOTIFY | Characteristic.INDICATE,
+ Characteristic.Properties.READ
+ | Characteristic.Properties.NOTIFY
+ | Characteristic.Properties.INDICATE,
Characteristic.READABLE,
bytes([0x42]),
)
diff --git a/tests/gatt_test.py b/tests/gatt_test.py
index 3dc0f5f..0652197 100644
--- a/tests/gatt_test.py
+++ b/tests/gatt_test.py
@@ -115,7 +115,7 @@
c = Foo(
GATT_BATTERY_LEVEL_CHARACTERISTIC,
- Characteristic.READ,
+ Characteristic.Properties.READ,
Characteristic.READABLE,
123,
)
@@ -144,7 +144,9 @@
characteristic = Characteristic(
'FDB159DB-036C-49E3-B3DB-6325AC750806',
- Characteristic.READ | Characteristic.WRITE | Characteristic.NOTIFY,
+ Characteristic.Properties.READ
+ | Characteristic.Properties.WRITE
+ | Characteristic.Properties.NOTIFY,
Characteristic.READABLE | Characteristic.WRITEABLE,
bytes([123]),
)
@@ -240,7 +242,9 @@
characteristic_uuid = UUID('FDB159DB-036C-49E3-B3DB-6325AC750806')
characteristic = Characteristic(
characteristic_uuid,
- Characteristic.READ | Characteristic.WRITE | Characteristic.NOTIFY,
+ Characteristic.Properties.READ
+ | Characteristic.Properties.WRITE
+ | Characteristic.Properties.NOTIFY,
Characteristic.READABLE | Characteristic.WRITEABLE,
bytes([123]),
)
@@ -285,7 +289,7 @@
v = bytes([1, 2, 3])
c = Characteristic(
GATT_BATTERY_LEVEL_CHARACTERISTIC,
- Characteristic.READ,
+ Characteristic.Properties.READ,
Characteristic.READABLE,
v,
)
@@ -421,7 +425,7 @@
characteristic1 = Characteristic(
'FDB159DB-036C-49E3-B3DB-6325AC750806',
- Characteristic.READ | Characteristic.WRITE,
+ Characteristic.Properties.READ | Characteristic.Properties.WRITE,
Characteristic.READABLE | Characteristic.WRITEABLE,
)
@@ -438,7 +442,7 @@
characteristic2 = Characteristic(
'66DE9057-C848-4ACA-B993-D675644EBB85',
- Characteristic.READ | Characteristic.WRITE,
+ Characteristic.Properties.READ | Characteristic.Properties.WRITE,
Characteristic.READABLE | Characteristic.WRITEABLE,
CharacteristicValue(
read=on_characteristic2_read, write=on_characteristic2_write
@@ -501,7 +505,7 @@
v = bytes([0x11, 0x22, 0x33, 0x44])
characteristic1 = Characteristic(
'FDB159DB-036C-49E3-B3DB-6325AC750806',
- Characteristic.READ | Characteristic.WRITE,
+ Characteristic.Properties.READ | Characteristic.Properties.WRITE,
Characteristic.READABLE | Characteristic.WRITEABLE,
value=v,
)
@@ -545,7 +549,7 @@
characteristic1 = Characteristic(
'FDB159DB-036C-49E3-B3DB-6325AC750806',
- Characteristic.READ | Characteristic.NOTIFY,
+ Characteristic.Properties.READ | Characteristic.Properties.NOTIFY,
Characteristic.READABLE,
bytes([1, 2, 3]),
)
@@ -561,7 +565,7 @@
characteristic2 = Characteristic(
'66DE9057-C848-4ACA-B993-D675644EBB85',
- Characteristic.READ | Characteristic.INDICATE,
+ Characteristic.Properties.READ | Characteristic.Properties.INDICATE,
Characteristic.READABLE,
bytes([4, 5, 6]),
)
@@ -577,7 +581,9 @@
characteristic3 = Characteristic(
'AB5E639C-40C1-4238-B9CB-AF41F8B806E4',
- Characteristic.READ | Characteristic.NOTIFY | Characteristic.INDICATE,
+ Characteristic.Properties.READ
+ | Characteristic.Properties.NOTIFY
+ | Characteristic.Properties.INDICATE,
Characteristic.READABLE,
bytes([7, 8, 9]),
)
@@ -797,32 +803,46 @@
# -----------------------------------------------------------------------------
def test_char_property_to_string():
# single
- assert Characteristic.property_name(0x01) == "BROADCAST"
- assert Characteristic.property_name(Characteristic.BROADCAST) == "BROADCAST"
+ assert str(Characteristic.Properties(0x01)) == "Properties.BROADCAST"
+ assert str(Characteristic.Properties.BROADCAST) == "Properties.BROADCAST"
# double
- assert Characteristic.properties_as_string(0x03) == "BROADCAST,READ"
+ assert str(Characteristic.Properties(0x03)) == "Properties.READ|BROADCAST"
assert (
- Characteristic.properties_as_string(
- Characteristic.BROADCAST | Characteristic.READ
- )
- == "BROADCAST,READ"
+ str(Characteristic.Properties.BROADCAST | Characteristic.Properties.READ)
+ == "Properties.READ|BROADCAST"
)
# -----------------------------------------------------------------------------
-def test_char_property_string_to_type():
+def test_characteristic_property_from_string():
# single
- assert Characteristic.string_to_properties("BROADCAST") == Characteristic.BROADCAST
+ assert (
+ Characteristic.Properties.from_string("BROADCAST")
+ == Characteristic.Properties.BROADCAST
+ )
# double
assert (
- Characteristic.string_to_properties("BROADCAST,READ")
- == Characteristic.BROADCAST | Characteristic.READ
+ Characteristic.Properties.from_string("BROADCAST,READ")
+ == Characteristic.Properties.BROADCAST | Characteristic.Properties.READ
)
assert (
- Characteristic.string_to_properties("READ,BROADCAST")
- == Characteristic.BROADCAST | Characteristic.READ
+ Characteristic.Properties.from_string("READ,BROADCAST")
+ == Characteristic.Properties.BROADCAST | Characteristic.Properties.READ
+ )
+
+
+# -----------------------------------------------------------------------------
+def test_characteristic_property_from_string_assert():
+ with pytest.raises(TypeError) as e_info:
+ Characteristic.Properties.from_string("BROADCAST,HELLO")
+
+ assert (
+ str(e_info.value)
+ == """Characteristic.Properties::from_string() error:
+Expected a string containing any of the keys, separated by commas: BROADCAST,READ,WRITE_WITHOUT_RESPONSE,WRITE,NOTIFY,INDICATE,AUTHENTICATED_SIGNED_WRITES,EXTENDED_PROPERTIES
+Got: BROADCAST,HELLO"""
)
@@ -833,7 +853,9 @@
characteristic = Characteristic(
'FDB159DB-036C-49E3-B3DB-6325AC750806',
- Characteristic.READ | Characteristic.WRITE | Characteristic.NOTIFY,
+ Characteristic.Properties.READ
+ | Characteristic.Properties.WRITE
+ | Characteristic.Properties.NOTIFY,
Characteristic.READABLE | Characteristic.WRITEABLE,
bytes([123]),
)
@@ -844,13 +866,13 @@
assert (
str(server.gatt_server)
== """Service(handle=0x0001, end=0x0005, uuid=UUID-16:1800 (Generic Access))
-CharacteristicDeclaration(handle=0x0002, value_handle=0x0003, uuid=UUID-16:2A00 (Device Name), properties=READ)
-Characteristic(handle=0x0003, end=0x0003, uuid=UUID-16:2A00 (Device Name), properties=READ)
-CharacteristicDeclaration(handle=0x0004, value_handle=0x0005, uuid=UUID-16:2A01 (Appearance), properties=READ)
-Characteristic(handle=0x0005, end=0x0005, uuid=UUID-16:2A01 (Appearance), properties=READ)
+CharacteristicDeclaration(handle=0x0002, value_handle=0x0003, uuid=UUID-16:2A00 (Device Name), Properties.READ)
+Characteristic(handle=0x0003, end=0x0003, uuid=UUID-16:2A00 (Device Name), Properties.READ)
+CharacteristicDeclaration(handle=0x0004, value_handle=0x0005, uuid=UUID-16:2A01 (Appearance), Properties.READ)
+Characteristic(handle=0x0005, end=0x0005, uuid=UUID-16:2A01 (Appearance), Properties.READ)
Service(handle=0x0006, end=0x0009, uuid=3A657F47-D34F-46B3-B1EC-698E29B6B829)
-CharacteristicDeclaration(handle=0x0007, value_handle=0x0008, uuid=FDB159DB-036C-49E3-B3DB-6325AC750806, properties=READ,WRITE,NOTIFY)
-Characteristic(handle=0x0008, end=0x0009, uuid=FDB159DB-036C-49E3-B3DB-6325AC750806, properties=READ,WRITE,NOTIFY)
+CharacteristicDeclaration(handle=0x0007, value_handle=0x0008, uuid=FDB159DB-036C-49E3-B3DB-6325AC750806, Properties.NOTIFY|WRITE|READ)
+Characteristic(handle=0x0008, end=0x0009, uuid=FDB159DB-036C-49E3-B3DB-6325AC750806, Properties.NOTIFY|WRITE|READ)
Descriptor(handle=0x0009, type=UUID-16:2902 (Client Characteristic Configuration), value=0000)"""
)
@@ -875,7 +897,9 @@
def test_characteristic_permissions():
characteristic = Characteristic(
'FDB159DB-036C-49E3-B3DB-6325AC750806',
- Characteristic.READ | Characteristic.WRITE | Characteristic.NOTIFY,
+ Characteristic.Properties.READ
+ | Characteristic.Properties.WRITE
+ | Characteristic.Properties.NOTIFY,
'READABLE,WRITEABLE',
)
assert characteristic.permissions == 3
@@ -885,15 +909,21 @@
def test_characteristic_has_properties():
characteristic = Characteristic(
'FDB159DB-036C-49E3-B3DB-6325AC750806',
- Characteristic.READ | Characteristic.WRITE | Characteristic.NOTIFY,
+ Characteristic.Properties.READ
+ | Characteristic.Properties.WRITE
+ | Characteristic.Properties.NOTIFY,
'READABLE,WRITEABLE',
)
- assert characteristic.has_properties([Characteristic.READ])
- assert characteristic.has_properties([Characteristic.READ, Characteristic.WRITE])
- assert not characteristic.has_properties(
- [Characteristic.READ, Characteristic.WRITE, Characteristic.INDICATE]
+ assert characteristic.has_properties(Characteristic.Properties.READ)
+ assert characteristic.has_properties(
+ Characteristic.Properties.READ | Characteristic.Properties.WRITE
)
- assert not characteristic.has_properties([Characteristic.INDICATE])
+ assert not characteristic.has_properties(
+ Characteristic.Properties.READ
+ | Characteristic.Properties.WRITE
+ | Characteristic.Properties.INDICATE
+ )
+ assert not characteristic.has_properties(Characteristic.Properties.INDICATE)
# -----------------------------------------------------------------------------
diff --git a/tests/self_test.py b/tests/self_test.py
index d6b16ec..5f7f4b8 100644
--- a/tests/self_test.py
+++ b/tests/self_test.py
@@ -163,25 +163,28 @@
# Add some GATT characteristics to device 1
c1 = Characteristic(
'3A143AD7-D4A7-436B-97D6-5B62C315E833',
- Characteristic.READ,
+ Characteristic.Properties.READ,
Characteristic.READABLE,
bytes([1, 2, 3]),
)
c2 = Characteristic(
'9557CCE2-DB37-46EB-94C4-50AE5B9CB0F8',
- Characteristic.READ | Characteristic.WRITE,
+ Characteristic.Properties.READ | Characteristic.Properties.WRITE,
Characteristic.READABLE | Characteristic.WRITEABLE,
bytes([4, 5, 6]),
)
c3 = Characteristic(
'84FC1A2E-C52D-4A2D-B8C3-8855BAB86638',
- Characteristic.READ | Characteristic.WRITE_WITHOUT_RESPONSE,
+ Characteristic.Properties.READ
+ | Characteristic.Properties.WRITE_WITHOUT_RESPONSE,
Characteristic.READABLE | Characteristic.WRITEABLE,
bytes([7, 8, 9]),
)
c4 = Characteristic(
'84FC1A2E-C52D-4A2D-B8C3-8855BAB86638',
- Characteristic.READ | Characteristic.NOTIFY | Characteristic.INDICATE,
+ Characteristic.Properties.READ
+ | Characteristic.Properties.NOTIFY
+ | Characteristic.Properties.INDICATE,
Characteristic.READABLE,
bytes([1, 1, 1]),
)
@@ -234,7 +237,7 @@
characteristics = [
Characteristic(
f'3A143AD7-D4A7-436B-97D6-5B62C315{i:04X}',
- Characteristic.READ,
+ Characteristic.Properties.READ,
Characteristic.READABLE,
bytes([x & 255 for x in range(i)]),
)