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

GATT BLE Server: GATT dictionary with several services uuid can't be used by server, since an exception is thrown #84

Closed
alexmac98 opened this issue Jun 23, 2022 · 2 comments · Fixed by #91
Labels
backend: bluez Problem specific to bluez bug Something isn't working

Comments

@alexmac98
Copy link

Hello,
I'm developing a GATT BLE Server using your library. This server is supposed to advertise 4 services, so essentially the GATT configuration to be passed to the server via add_gatt() follows the pattern:

{ <service1_uuid>: {<char1_uuid>: {"Properties": ..., "Permissions": ..., "Value": ...}}, <service2_uuid>: {<char1_uuid>: {"Properties": ..., "Permissions": ..., "Value": ...}}, <service3_uuid>: {<char1_uuid>: {"Properties": ..., "Permissions": ..., "Value": ...}}, <service4_uuid>: {<char1_uuid>: {"Properties": ..., "Permissions": ..., "Value": ...}}, }

However, after I add the GATT configuration to the server and start it await server.start(), an exception occurs:
raise DBusError._from_message(msg)
dbus_next.errors.DBusError: Failed to parse advertisement.

If I try to advertise any single service, it works properly. In order to advertise the four services, I created 4 different GATT BLE servers, which is not ok, since it doesn't work as I expected (only one advertised service shows on the LightBlue app, but every characteristic advertised is displayed). I've also tried to add the 4 GATT configurations separately, and the same problem occurred.

I don't know if I'm doing something wrong, but I've checked the GATT configurations and everything seems fine.

Do you know why this might happen?

Best regards and thank you in advance

@kevincar kevincar added the bug Something isn't working label Aug 27, 2022
@kevincar kevincar added the backend: bluez Problem specific to bluez label Sep 6, 2022
@kevincar kevincar linked a pull request Sep 7, 2022 that will close this issue
@kevincar
Copy link
Owner

kevincar commented Sep 7, 2022

Thanks for bringing this up. I was able to localize the issue to Linux's BlueZ Advertisement API. The problem seemed to be that the advertisement failed to register when advertising more than one 32-bit service UUID. By restricting the advertisement to advertise only the primary service UUID, more than one service can now be broadcast.

This has been resolved an is now on the develop branch for now. Please reopen if the problem persists.

@kevincar kevincar closed this as completed Sep 7, 2022
@kosma
Copy link

kosma commented Jan 16, 2024

I think I am getting hit by this. I'm trying to register multiple services:

        gatt = {
            # Battery - public
            self.UUID_SERVICE_BATTERY: {
                self.UUID_CHARACTERISTIC_BATTERY_LEVEL: {
                    "Properties": GATTCharacteristicProperties.read,
                    "Permissions": GATTAttributePermissions.readable,
                    "Value": bytearray(b'\x69'),
                }
            },
            # Automation IO - catch-all for control - private
            self.UUID_SERVICE_AUTOMATION_IO: {
                self.UUID_CHARACTERISTIC_NUMBER_OF_DIGITALS: {
                    "Properties": GATTCharacteristicProperties.read,
                    "Permissions": GATTAttributePermissions.readable,
                    "Value": bytearray(b'\x01'),  # one digital
                },
                self.UUID_CHARACTERISTIC_CHARACTERISTIC_USER_DESCRIPTION: {
                    "Properties": GATTCharacteristicProperties.read,
                    "Permissions": GATTAttributePermissions.readable,
                    "Value": bytearray('WiFi'.encode()),
                },
                self.UUID_CHARACTERISTIC_CHARACTERISTIC_PRESENTATION_FORMAT: {
                    "Properties": GATTCharacteristicProperties.read,
                    "Permissions": GATTAttributePermissions.readable,
                    "Value": bytearray(b'\x01'),  # boolean
                },
                self.UUID_CHARACTERISTIC_DIGITAL: {
                    "Properties": GATTCharacteristicProperties.read | GATTCharacteristicProperties.encrypt_authenticated_write,
                    "Permissions": GATTAttributePermissions.readable | GATTAttributePermissions.writeable,
                    "Value": bytearray(b'\x00'),
                },
            },
            # WiFi password access - private
            self.UUID_SERVICE_WIFI: {
                self.UUID_CHARACTERISTIC_WIFI_SSID: {
                    "Properties": GATTCharacteristicProperties.encrypt_authenticated_read,
                    "Permissions": GATTAttributePermissions.readable,
                    "Value": bytearray(self.name.encode()),
                },
                self.UUID_CHARACTERISTIC_WIFI_PSK: {
                    "Properties": GATTCharacteristicProperties.encrypt_authenticated_read,
                    "Permissions": GATTAttributePermissions.readable,
                    "Value": bytearray(b'TODO'),
                },
            },
        }
        await self.server.add_gatt(gatt)

But only the first service is shown on the client side:

image

How do you suggest I proceed from here? I can slap all my characteristics into a single vendor-specific service - though I was hoping I could have multiple services for different functionalities on the device (some based on standard services, some vendor-specific).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend: bluez Problem specific to bluez bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants