muka / go-bluetooth

Golang bluetooth client based on bluez DBus interfaces

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

"org.bluez.Error.AlreadyExists" faulire when adding second GATT Server

MykolaRodin opened this issue · comments

Hi,

My OS is Ubuntu 20.04 with default Bluez 5.53. My laptop is HP with Realtek Bluetooth chip. I am trying to create an application with 2 GATT servers with different UUIDs and fail.

When I prepare the first GATT Server and call app.Run(), it succeeds. When I prepare the second GATT Server with different UUID and call app.Run(), it fails with "org.bluez.Error.AlreadyExists" at "muka/go-bluetooth/bluez/profile/agent/agent.go". The error is returned here:

err = am.RegisterAgent(ag.Path(), caps)

I believe the error occurs because ag.Path() for the second GATT Server is the same - "/agent/simple1" as for the first app.Run() call for the first GATT Server.

On the other hand, I was able to add the second GATT Server successfully, when skipped calling

err = app.ExposeAgent(app.Options.AgentCaps, app.Options.AgentSetAsDefault)

for the second app.Run(). But for this approach I see no other way when modifying the library source code. I cannot just create a modified implementation of app.Run() inside my application. Because app.Run() refers to private fields like app.conn and app.objectManager which getters are absent and assigns the value to app.gm which setter is absent as well.

I believe it must be some more correct way to add the second GATT Server. I have checked previously created issues and have not found any similar one. Please clarify what I am missing. Thank you in advance.

Hi, I do not have an answer but if you see room for improvemnt on the library please provide a PR . Thank you!

Hi,

Thank you for the response. Despite the fact, I have managed to run 2 "applications" created by service.NewApp() (with some modification of source code that prevented exposing an agent for the second application) to use 2 services with different UUIDs per a single binary, I still have some doubts if I have chosen the right way.

Before making any changes, could you please clarify whether an application created by service.NewApp() can have the only service with some UUID? Or this application can have several services with different UUIDs?

On the one hand, there is services map[dbus.ObjectPath]*Service inside App struct. It looks like an application can have several services and services.AddService() adds a service to this map. On the other hand, service.NewService() calls NewGattService1Properties() and directly sets Primary: true. It does not look like it is possible to add a secondary service then because every service is supposed to be created by service.NewService() and only then be added by services.AddService().

Please let me know what I am missing. Thank you for the clarification in advance.

To be honest I am not sure, I assume you can have more services with different UUID. But the only truth is in how bluez handles it underneath. I would suggest to explore a bit the bluez codebase. Try also reaching them via slack, you could have some hints from the author's. Let me know thanks!

Hi,

From what I have read, BlueZ seems to be just some high level implementation that sets up objects and prepares some messages for D-Bus. D-Bus itself does not care about applications and just sends messages between objects. Particularly, every application might have several objects.

When it comes to difference between primary and secondary Bluetooth services, it looks like it is used on BlueZ level and does not relate to D-Bus:
- Primary Service: represents the primary functionality of a device.
- Secondary Service: provides the auxiliary functionality of a device and is referenced (included) by at least one other primary service on the device (it is rarely used).

For me application with several primary services works fine. I just created a new application, added 2 services (they both were considered to be primary ones by current implementation in NewGattService1Properties()) and then called app.Run(). And there is no more necessity to use 2 'applications' with a single service inside each application.

Thanks a lot for for the clarification.

I believe this issue could be closed.