Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bless does not advertise more then one service #142

Open
ch3p4ll3 opened this issue Nov 8, 2024 · 2 comments
Open

bless does not advertise more then one service #142

ch3p4ll3 opened this issue Nov 8, 2024 · 2 comments

Comments

@ch3p4ll3
Copy link

ch3p4ll3 commented Nov 8, 2024

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:
image

services from nRF Connect
image

Desktop (please complete the following information):

  • OS: Debian Bookworm
@kratz00
Copy link

kratz00 commented Nov 26, 2024

It is really hard to give advice, if it is not easily to reproduce a problem, do you mind sharing your actual code?

  1. the constructor calls of the services are missing server
  2. in the loop i.setup() is not awaited
  3. main* is never called
  4. missing import - from .base_service import BaseService
  5. missing code for ServiceX and ServiceY

@ch3p4ll3
Copy link
Author

ch3p4ll3 commented Nov 27, 2024

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))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants