Skip to content

Commit

Permalink
Merge pull request #108 from kevincar/87-write_request-get-executed-o…
Browse files Browse the repository at this point in the history
…nly-after-i-kill-the-server

87 write request get executed only after i kill the server
  • Loading branch information
kevincar authored Jul 1, 2023
2 parents 623a56d + 3594d25 commit 10e318d
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 91 deletions.
99 changes: 52 additions & 47 deletions examples/gattserver.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,40 @@

"""
Example for a BLE 4.0 Server using a GATT dictionary of services and
characteristics
"""

import sys
import logging
import asyncio
import threading

from typing import Any, Dict
from typing import Any, Dict, Union

from bless import ( # type: ignore
BlessServer,
BlessGATTCharacteristic,
GATTCharacteristicProperties,
GATTAttributePermissions
)
BlessServer,
BlessGATTCharacteristic,
GATTCharacteristicProperties,
GATTAttributePermissions,
)

logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(name=__name__)
trigger: threading.Event = threading.Event()

trigger: Union[asyncio.Event, threading.Event]
if sys.platform in ["darwin", "win32"]:
trigger = threading.Event()
else:
trigger = asyncio.Event()


def read_request(
characteristic: BlessGATTCharacteristic,
**kwargs
) -> bytearray:
def read_request(characteristic: BlessGATTCharacteristic, **kwargs) -> bytearray:
logger.debug(f"Reading {characteristic.value}")
return characteristic.value


def write_request(
characteristic: BlessGATTCharacteristic,
value: Any,
**kwargs
):
def write_request(characteristic: BlessGATTCharacteristic, value: Any, **kwargs):
characteristic.value = value
logger.debug(f"Char value set to {characteristic.value}")
if characteristic.value == b'\x0f':
if characteristic.value == b"\x0f":
logger.debug("Nice")
trigger.set()

Expand All @@ -47,48 +44,56 @@ async def run(loop):

# Instantiate the server
gatt: Dict = {
"A07498CA-AD5B-474E-940D-16F1FBE7E8CD": {
"51FF12BB-3ED8-46E5-B4F9-D64E2FEC021B": {
"Properties": (GATTCharacteristicProperties.read |
GATTCharacteristicProperties.write |
GATTCharacteristicProperties.indicate),
"Permissions": (GATTAttributePermissions.readable |
GATTAttributePermissions.writeable),
"Value": None
}
},
"5c339364-c7be-4f23-b666-a8ff73a6a86a": {
"bfc0c92f-317d-4ba9-976b-cc11ce77b4ca": {
"Properties": GATTCharacteristicProperties.read,
"Permissions": GATTAttributePermissions.readable,
"Value": bytearray(b'\x69')
}
"A07498CA-AD5B-474E-940D-16F1FBE7E8CD": {
"51FF12BB-3ED8-46E5-B4F9-D64E2FEC021B": {
"Properties": (
GATTCharacteristicProperties.read
| GATTCharacteristicProperties.write
| GATTCharacteristicProperties.indicate
),
"Permissions": (
GATTAttributePermissions.readable
| GATTAttributePermissions.writeable
),
"Value": None,
}
}
},
"5c339364-c7be-4f23-b666-a8ff73a6a86a": {
"bfc0c92f-317d-4ba9-976b-cc11ce77b4ca": {
"Properties": GATTCharacteristicProperties.read,
"Permissions": GATTAttributePermissions.readable,
"Value": bytearray(b"\x69"),
}
},
}
my_service_name = "Test Service"
server = BlessServer(name=my_service_name, loop=loop)
server.read_request_func = read_request
server.write_request_func = write_request

await server.add_gatt(gatt)
await server.start()
logger.debug(server.get_characteristic(
"51FF12BB-3ED8-46E5-B4F9-D64E2FEC021B"))
logger.debug(server.get_characteristic("51FF12BB-3ED8-46E5-B4F9-D64E2FEC021B"))
logger.debug("Advertising")
logger.info("Write '0xF' to the advertised characteristic: " +
"51FF12BB-3ED8-46E5-B4F9-D64E2FEC021B")
trigger.wait()
logger.info(
"Write '0xF' to the advertised characteristic: "
+ "51FF12BB-3ED8-46E5-B4F9-D64E2FEC021B"
)
if trigger.__module__ == "threading":
trigger.wait()
else:
await trigger.wait()
await asyncio.sleep(2)
logger.debug("Updating")
server.get_characteristic("51FF12BB-3ED8-46E5-B4F9-D64E2FEC021B").value = (
bytearray(b"i")
)
server.get_characteristic("51FF12BB-3ED8-46E5-B4F9-D64E2FEC021B").value = bytearray(
b"i"
)
server.update_value(
"A07498CA-AD5B-474E-940D-16F1FBE7E8CD",
"51FF12BB-3ED8-46E5-B4F9-D64E2FEC021B"
)
"A07498CA-AD5B-474E-940D-16F1FBE7E8CD", "51FF12BB-3ED8-46E5-B4F9-D64E2FEC021B"
)
await asyncio.sleep(5)
await server.stop()


loop = asyncio.get_event_loop()
loop.run_until_complete(run(loop))
75 changes: 33 additions & 42 deletions examples/server.py
Original file line number Diff line number Diff line change
@@ -1,42 +1,40 @@

"""
Example for a BLE 4.0 Server
"""

import sys
import logging
import asyncio
import threading

from typing import Any
from typing import Any, Union

from bless import ( # type: ignore
BlessServer,
BlessGATTCharacteristic,
GATTCharacteristicProperties,
GATTAttributePermissions
)
BlessServer,
BlessGATTCharacteristic,
GATTCharacteristicProperties,
GATTAttributePermissions,
)

logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(name=__name__)
trigger: threading.Event = threading.Event()

# NOTE: Some systems require different synchronization methods.
trigger: Union[asyncio.Event, threading.Event]
if sys.platform in ["darwin", "win32"]:
trigger = threading.Event()
else:
trigger = asyncio.Event()


def read_request(
characteristic: BlessGATTCharacteristic,
**kwargs
) -> bytearray:
def read_request(characteristic: BlessGATTCharacteristic, **kwargs) -> bytearray:
logger.debug(f"Reading {characteristic.value}")
return characteristic.value


def write_request(
characteristic: BlessGATTCharacteristic,
value: Any,
**kwargs
):
def write_request(characteristic: BlessGATTCharacteristic, value: Any, **kwargs):
characteristic.value = value
logger.debug(f"Char value set to {characteristic.value}")
if characteristic.value == b'\x0f':
if characteristic.value == b"\x0f":
logger.debug("NICE")
trigger.set()

Expand All @@ -56,38 +54,31 @@ async def run(loop):
# Add a Characteristic to the service
my_char_uuid = "51FF12BB-3ED8-46E5-B4F9-D64E2FEC021B"
char_flags = (
GATTCharacteristicProperties.read |
GATTCharacteristicProperties.write |
GATTCharacteristicProperties.indicate
)
permissions = (
GATTAttributePermissions.readable |
GATTAttributePermissions.writeable
)
GATTCharacteristicProperties.read
| GATTCharacteristicProperties.write
| GATTCharacteristicProperties.indicate
)
permissions = GATTAttributePermissions.readable | GATTAttributePermissions.writeable
await server.add_new_characteristic(
my_service_uuid,
my_char_uuid,
char_flags,
None,
permissions)

logger.debug(
server.get_characteristic(
my_char_uuid
)
)
my_service_uuid, my_char_uuid, char_flags, None, permissions
)

logger.debug(server.get_characteristic(my_char_uuid))
await server.start()
logger.debug("Advertising")
logger.info(f"Write '0xF' to the advertised characteristic: {my_char_uuid}")
trigger.wait()
if trigger.__module__ == "threading":
trigger.wait()
else:
await trigger.wait()

await asyncio.sleep(2)
logger.debug("Updating")
server.get_characteristic(my_char_uuid)
server.update_value(
my_service_uuid, "51FF12BB-3ED8-46E5-B4F9-D64E2FEC021B"
)
server.update_value(my_service_uuid, "51FF12BB-3ED8-46E5-B4F9-D64E2FEC021B")
await asyncio.sleep(5)
await server.stop()


loop = asyncio.get_event_loop()
loop.run_until_complete(run(loop))
5 changes: 3 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@
install_requires=[
"bleak",
"pywin32;platform_system=='Windows'",
"pysetupdi @ git+https://github.com/gwangyi/pysetupdi#egg=pysetupdi;platform_system=='Windows'" # noqa: E501
"dbus_next;platform_system=='Linux'",
"pysetupdi @ git+https://github.com/gwangyi/pysetupdi#egg=pysetupdi;platform_system=='Windows'", # noqa: E501
],
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires='>=3.7',
python_requires=">=3.7",
)

1 comment on commit 10e318d

@ksando240
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the BLE server example, is there any way to send data frames? I'm working on a specific case: when a client connects, the information sent by the client to the server is received, but I can't find a way to send a data frame back to that client in response. In fact, on the client side, it shows that a 0-byte frame is being received. Could you help me figure out how to solve this or find a way to send data frames?

Please sign in to comment.