spacecheese / bluez_peripheral

A library for building BLE peripherals using GATT and bluez
MIT License
38 stars 8 forks source link

DBUS error when setting ManufacturerData #2

Closed dimbledup closed 2 years ago

dimbledup commented 2 years ago

When I try to set manufacturerData in the advertisement a dbus error is returned. With dbus-monitor the problem was found: the array of bytes should be in a variant.

I found a solution, but don't have the skills to make a pull request. All changes are in advert.py. This is the diff:

4a5
> from dbus_next.signature import Variant
86c87,89
<         self._manufacturerData = manufacturerData
---
>         self._manufacturerData = {}
>         for key in manufacturerData:
>             self._manufacturerData[key] = Variant('ay', manufacturerData[key])
156c159
<     def ManufacturerData(self) -> "a{qay}":  # type: ignore
---
>     def ManufacturerData(self) -> "a{qv}":  # type: ignore

In __init__ it loops through the dict and changes the manufacturerData value to a Variant. In ManufacturerData the type has to be changed from "a{qay}" to "a{qv}" where the variant "v" has type "ay".

This is a minimized script that gives an error with the original advert.py, but does work with the changed one:

from bluez_peripheral.util import *
from bluez_peripheral.advert import Advertisement
import asyncio

async def main():
    bus = await get_message_bus()
    advert = Advertisement("BT-test", [], 0, 60, manufacturerData = {0x0010: b'data'})
    adapter = await Adapter.get_first(bus)
    await advert.register(bus, adapter)
    await bus.wait_for_disconnect()

asyncio.run(main())
spacecheese commented 2 years ago

Thanks for the issue and code. I suspect there might be a similar issue with serviceData but I'll have to look at that later.