muka / go-bluetooth

Golang bluetooth client based on bluez DBus interfaces
Apache License 2.0
652 stars 125 forks source link

GATT device disappears once connected #116

Closed basilfx closed 4 years ago

basilfx commented 4 years ago

I'm trying to implement a Go-version of BerryLan per this specification. They have a iOS app that I use to test.

I run into this problem, when I connect to my GATT device. The first time it works fine (using that app), but if I restart the app, the GATT device doesn't show up in the list of discovered devices anymore. Also, I use Bluesee on macOS to do some testing as well, and once it is connected to my phone, it does not show up there as well. The problem works the other way around as well, so I can assume this happens once the GATT device is connected to another device.

To rule out my own implementation, I also tried _examples/. I can reproduce this connection issue with running ./_examples service server, so it doesn't seem to be caused by my code.

The GATT device appears again once I actively remove the connection from the Bluetooth settings on my phone. But I would expect, with BLE, that both device can connect at the same time. How can I achieve this behavior?

It is worth noting that using their implementation of the BerryLan GATT device works as I would expect.

Using:

basilfx commented 4 years ago

This is the logging of ./examples service server:

# ./examples service server
TRAC[0000] Exec: btmgmt [--index hci0 power off]
TRAC[0000] Exec: btmgmt [--index hci0 le on]
TRAC[0000] Exec: btmgmt [--index hci0 bredr off]
TRAC[0000] Exec: btmgmt [--index hci0 power on]
INFO[0000] HW address B8:27:EB:D1:57:50
TRAC[0000] Expose /hci0/apps/0/service12342233 (org.bluez.GattService1)
TRAC[0000] Expose Properties interface (/hci0/apps/0/service12342233)
TRAC[0000] ObjectManager.AddObject: /hci0/apps/0/service12342233
TRAC[0000] Added GATT Service UUID=12342233-0000-1000-8000-00805F9B34FB /hci0/apps/0/service12342233
TRAC[0000] Expose /hci0/apps/0/service12342233/char0 (org.bluez.GattCharacteristic1)
TRAC[0000] Expose Properties interface (/hci0/apps/0/service12342233/char0)
TRAC[0000] ObjectManager.AddObject: /hci0/apps/0/service12342233/char0
TRAC[0000] Added GATT Characteristic UUID=12343344-0000-1000-8000-00805F9B34FB /hci0/apps/0/service12342233/char0
TRAC[0000] Expose /hci0/apps/0/service12342233/char0/descriptor0 (org.bluez.GattDescriptor1)
TRAC[0000] Expose Properties interface (/hci0/apps/0/service12342233/char0/descriptor0)
TRAC[0000] ObjectManager.AddObject: /hci0/apps/0/service12342233/char0/descriptor0
TRAC[0000] Added GATT Descriptor UUID=12344455-0000-1000-8000-00805F9B34FB /hci0/apps/0/service12342233/char0/descriptor0

TRAC[0000] Expose /hci0/apps/0 (org.freedesktop.DBus.ObjectManager)
TRAC[0000] Exposing Agent1 at /agent/simple0
INFO[0000] Exposed service 2233
INFO[0000] Advertising for 21600s...
TRAC[0000] Retrieving adapter instance hci0
TRAC[0000] Expose /go_bluetooth/hci0/advertisement/0 (org.bluez.LEAdvertisement1)
TRAC[0000] Expose Properties interface (/go_bluetooth/hci0/advertisement/0)
DEBU[0000] Setup adapter
TRAC[0000] Registering LEAdvertisement1 instance
TRAC[0011] Descr.ReadValue
WARN[0011] GOT READ REQUEST
TRAC[0011] Descr.ReadValue
WARN[0011] GOT READ REQUEST

Once I run bluetoothctl, It immediately show that it is connected to another device:

# bluetoothctl
Agent registered
[MacBook Pro van Bas]#

This is btmgmt -i hci0 info:

# btmgmt -i 0 info
hci0:   Primary controller
    addr B8:27:EB:D1:57:50 version 7 manufacturer 15 class 0x000000
    supported settings: powered connectable fast-connectable discoverable bondable link-security ssp br/edr hs le advertising secure-conn debug-keys privacy configuration static-addr
    current settings: powered connectable discoverable bondable le advertising secure-conn
    name Something
    short name
hci0:   Configuration options
    supported options: public-address
    missing options: public-address
muka commented 4 years ago

Hello, first of all Great to know you are implementing the berrylan specs. Will your code be open source?

I admit I do not know exactly, I suspect that the app has to explicitly disconnect from the device or it will be not discoverable. We should check in the ble specs and eventually dig into the documentation of bluez

basilfx commented 4 years ago

I'm not (yet) able to release it, since it is for a commercial project. However, it's not that hard to implement ;-)

I found this link, which describes my problem: https://stackoverflow.com/questions/56236749/continue-advertising-after-connection-bluez

Using hciconfig hci0 leadv 0, I'm able to get the advertisements going again. But I don't know the equivalent using btmgmt. I tried to see if there is an event to subscribe to, when the connection closes. But haven't found that one yet. Then I could just start advertising again.

muka commented 4 years ago

There is a hciconfig wrapper in the library, maybe a good point for extension to handle your case?

https://github.com/muka/go-bluetooth/blob/master/hw/linux/hciconfig/hciconfig.go

Maybe also this is equivalent?

btmgmt := hw.NewBtMgmt("hciX")
btmgmt.SetAdvertising(true)
basilfx commented 4 years ago

I've decided to use https://github.com/go-ble/ble instead, which does advertise again once disconnected.

I'll close this issue for now.

Thanks for thinking along with me!