spacecheese / bluez_peripheral

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

128 UUID Characteristic not working #12

Closed sroebert closed 1 year ago

sroebert commented 1 year ago

I am trying to create a characteristic with a 128 bit UUID, instead of 16 bit. If I use "2A37" from your example everything works correctly. When I change the characteristic to use a 128 bit UUID instead, I get the following error:

dbus_next.errors.DBusError: Failed to create entry in database

  File "/usr/lib/python3.9/site-packages/bluez_peripheral/gatt/service.py", line 126, in register
    await self._collection.register(bus, path, adapter)
  File "/usr/lib/python3.9/site-packages/bluez_peripheral/gatt/service.py", line 248, in register
    await manager.call_register_application(self._path, {})
  File "/usr/lib/python3.9/site-packages/dbus_next/aio/proxy_object.py", line 92, in method_fn
    BaseProxyInterface._check_method_return(msg, intr_method.out_signature)
  File "/usr/lib/python3.9/site-packages/dbus_next/proxy_object.py", line 62, in _check_method_return
    raise DBusError._from_message(msg)

Am I doing something wrong and is this suppose to work with this library? I know it should be possible as I am already using the same characteristic UUID on an iPhone and Android app.

spacecheese commented 1 year ago

Hello, Unfortunatly I'm not going to be able to look into this thoroughly for a couple of days. In the mean time could you post your modified version of the characteristic decorator.

sroebert commented 1 year ago

No worries, I'll be debugging a bit more, hopefully figuring it out by myself.

This is the code I am using, I'm passing a random UUID (e.g. 51E4D20E-23A1-409E-BCBE-16FDAECF4BD4).

async def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--uuid", type=UUID, required=True)
    parser.add_argument("--data", type=base64.b64decode, required=True)
    parser.add_argument("--duration", type=int, required=True)
    args = parser.parse_args()

    service_uuid: UUID = args.uuid
    data: bytes = args.data
    duration: int = args.duration

    @characteristic(service_uuid.hex)
    def read_characteristic(
        service, options: CharacteristicReadOptions  # pylint: disable=unused-argument
    ) -> bytes:
        return data

    bus = await bluez_peripheral_util.get_message_bus()

    service = Service(uuid=service_uuid.hex)
    service.add_characteristic(read_characteristic)
    await service.register(bus=bus)

    adapter = await bluez_peripheral_util.Adapter.get_first(bus)

    advertisement = Advertisement(
        localName="SecureIdSim",
        serviceUUIDs=[service_uuid.hex],
        appearance=0x0010,
        timeout=duration,
    )
    await advertisement.register(bus, adapter)

    await asyncio.sleep(duration)

    await service.unregister()
    bus.disconnect()

It works perfectly fine (I tested reading the characteristic), using @characteristic("2A37").

sroebert commented 1 year ago

Ok, it does seem to work if I use an instance of BTUUID directly, instead of using the UUID hex property.

There seems to be a bug in the init of characteristic, it has if uuid is str, instead of if type(uuid) is str. If fixed it in #13