bless does not advertise more then one service
The problem I made a script that need to advertise more than one service. I tried accessing it's content's by using the android app "nRF Connect" and it shows me only the first service I configured
Reproduction For the creation of the services I used a script very similar to this one:
from bless import BlessServer, GATTCharacteristicProperties, GATTAttributePermissions, BlessGATTService, BlessGATTCharacteristic
from .base_service import BaseService
SERVICE_UUID = "bfc2bc5c-39b5-41fc-be0d-e577272563e6"
CHARACTERISTIC_UUID = "698eb415-817e-41c2-a20b-6b4764d79276"
class VersionService(BaseService):
def __init__(self, server: BlessServer):
super().__init__(server)
self.service: BlessGATTService = None
async def setup(self):
self.logger.debug(f"Setting up {self.__class__.__name__}")
await self.server.add_new_service(SERVICE_UUID)
char_flags = (
GATTCharacteristicProperties.read
| GATTCharacteristicProperties.indicate
)
permissions = GATTAttributePermissions.readable
# Add the characteristic to the server
await self.server.add_new_characteristic(
SERVICE_UUID,
CHARACTERISTIC_UUID,
char_flags,
self.__get_version(),
permissions
)
self.service = self.server.get_service(SERVICE_UUID)
async def main():
server = BlessServer(name="My-Server")
services = [
VersionService(),
ServiceX(),
ServiceY()
]
for i in services:
i.setup()
await server.start()
All the additional services are identical to the example class I put above, if I print on screen server.services all the services seem to be present
Expected behavior That all services are displayed in the app
Screenshots
Services from server.services:
services from nRF Connect
Desktop (please complete the following information):
- OS: Debian Bookworm
It is really hard to give advice, if it is not easily to reproduce a problem, do you mind sharing your actual code?
- the constructor calls of the services are missing server
- in the loop i.setup() is not awaited
- main* is never called
- missing import - from .base_service import BaseService
- missing code for ServiceX and ServiceY
Sorry, I wrote the example a little quickly.
Anyway I tested also with the gattserver example by adding a service and the result is always the same: only the first service is advertised
"""
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, Union
from bless import ( # type: ignore
BlessServer,
BlessGATTCharacteristic,
GATTCharacteristicProperties,
GATTAttributePermissions,
)
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(name=__name__)
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:
logger.debug(f"Reading {characteristic.value}")
return characteristic.value
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":
logger.debug("Nice")
trigger.set()
async def run(loop):
trigger.clear()
# 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-16F1FBE7E8CC": {
"51FF12BB-3ED8-46E5-B4F9-D64E2FEC021C": {
"Properties": (
GATTCharacteristicProperties.read
| GATTCharacteristicProperties.write
| GATTCharacteristicProperties.indicate
),
"Permissions": (
GATTAttributePermissions.readable
| GATTAttributePermissions.writeable
),
"Value": None,
}
},
"5c339364-c7be-4f23-b666-a8ff73a6a86d": {
"bfc0c92f-317d-4ba9-976b-cc11ce77b4cd": {
"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("Advertising")
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.update_value(
"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))
I am having the same issue. I tested adding an additional service and characteristic in both examples and it only advertises the first one 🥲