The example server and client provided at the BlueZ github do not work (I tested them both on two raspberry PIs, one with client and one with server). I tried first the server with the nRF Connect app on my phone and could not detect any services advertised by it. So, I used another server/peripheral code provided by:
https://punchthrough.com/creating-a-ble-peripheral-with-bluez/
This server works perfectly and I can find all my created services and characterisitics in the nRF connect application. However, now I have no idea how to get the client to work.
I tried the client files from here:
https://github.com/bluez/bluez/blob/master/test/example-gatt-client
I added my own service and characteristic UUIDs that I confirmed to be correctly advertised using the nRF Connect app. However, this code does not work at all. The main from the code I used is given as below, the rest of the functions are the same as the example code from BlueZ but with my own service and characteritics with their UUID.
def main():
# Set up the main loop.
DBusGMainLoop(set_as_default=True)
global bus
bus = dbus.SystemBus()
global mainloop
mainloop = GObject.MainLoop()
om = dbus.Interface(bus.get_object(BLUEZ_SERVICE_NAME, '/'), DBUS_OM_IFACE)
om.connect_to_signal('InterfacesRemoved', interfaces_removed_cb)
print(om)
print('Getting objects...')
objects = om.GetManagedObjects()
adapter = 0
for o, props in objects.items():
if GATT_MANAGER_IFACE in props.keys():
adapter = o
if not adapter:
logger.critical("GattManager1 interface not found")
return
print(adapter)
adapter_obj = bus.get_object(BLUEZ_SERVICE_NAME, adapter)
adapter_props = dbus.Interface(adapter_obj, "org.freedesktop.DBus.Properties")
# powered property on the controller to on
adapter_props.Set("org.bluez.Adapter1", "Powered", dbus.Boolean(1))
print(objects)
chrcs = []
# List characteristics found
for path, interfaces in objects.items():
if GATT_CHRC_IFACE not in interfaces.keys():
continue
chrcs.append(path)
print(chrcs)
# List sevices found
for path, interfaces in objects.items():
if GATT_SERVICE_IFACE not in interfaces.keys():
continue
chrc_paths = [d for d in chrcs if d.startswith(path + "/")]
if process_thispi_service(path, chrc_paths):
break
if not thispi_service:
print('This Pi Service not found')
sys.exit(1)
else:
print('This Pi Service found')
start_client()
mainloop.run()
if __name__ == '__main__':
main()
The output I got by using print statements at different points were:
<Interface <ProxyObject wrapping <dbus._dbus.SystemBus (system) at 0x7fb26f0b30> :1.18 / at 0x7fb26cedd0> implementing 'org.freedesktop.DBus.ObjectManager' at 0x7fb26e1fd0>
Getting objects...
/org/bluez/hci0
[dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service0082/char0083')]
[dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service0082/char0083'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char007c')]
[dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service0082/char0083'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char007c'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0079')]
[dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service0082/char0083'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char007c'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0079'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0076')]
[dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service0082/char0083'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char007c'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0079'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0076'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0074')]
[dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service0082/char0083'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char007c'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0079'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0076'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0074'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0071')]
[dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service0082/char0083'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char007c'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0079'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0076'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0074'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0071'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char006e')]
[dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service0082/char0083'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char007c'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0079'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0076'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0074'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0071'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char006e'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char006b')]
[dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service0082/char0083'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char007c'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0079'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0076'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0074'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0071'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char006e'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char006b'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0069')]
[dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service0082/char0083'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char007c'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0079'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0076'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0074'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0071'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char006e'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char006b'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0069'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0066')]
[dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service0082/char0083'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char007c'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0079'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0076'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0074'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0071'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char006e'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char006b'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0069'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0066'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0063')]
[dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service0082/char0083'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char007c'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0079'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0076'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0074'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0071'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char006e'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char006b'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0069'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0066'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0063'), dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A/service005a/char0060')]
dbus.Dictionary({dbus.String('UUID'): dbus.String('00001855-0000-1000-8000-00805f9b34fb', variant_level=1), dbus.String('Device'): dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A', variant_level=1), dbus.String('Primary'): dbus.Boolean(True, variant_level=1), dbus.String('Includes'): dbus.Array([], signature=dbus.Signature('o'), variant_level=1)}, signature=dbus.Signature('sv'))
dbus.Dictionary({dbus.String('UUID'): dbus.String('0000184c-0000-1000-8000-00805f9b34fb', variant_level=1), dbus.String('Device'): dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A', variant_level=1), dbus.String('Primary'): dbus.Boolean(True, variant_level=1), dbus.String('Includes'): dbus.Array([], signature=dbus.Signature('o'), variant_level=1)}, signature=dbus.Signature('sv'))
dbus.Dictionary({dbus.String('UUID'): dbus.String('00001849-0000-1000-8000-00805f9b34fb', variant_level=1), dbus.String('Device'): dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A', variant_level=1), dbus.String('Primary'): dbus.Boolean(True, variant_level=1), dbus.String('Includes'): dbus.Array([], signature=dbus.Signature('o'), variant_level=1)}, signature=dbus.Signature('sv'))
dbus.Dictionary({dbus.String('UUID'): dbus.String('00001801-0000-1000-8000-00805f9b34fb', variant_level=1), dbus.String('Device'): dbus.ObjectPath('/org/bluez/hci0/dev_24_95_2F_D3_5C_6A', variant_level=1), dbus.String('Primary'): dbus.Boolean(True, variant_level=1), dbus.String('Includes'): dbus.Array([], signature=dbus.Signature('o'), variant_level=1)}, signature=dbus.Signature('sv'))
This Pi Service not found
Process ended with exit code 1.