weliem / bluez_inc

A C library for Bluez (BLE) that hides all DBus communication. It doesn't get easier than this. This library can also be used in C++.
MIT License
84 stars 19 forks source link

Reconnect to a previous device causes strange behavior #47

Closed bojennett closed 3 months ago

bojennett commented 3 months ago

As a central, I'm seeing a weird behavior, as if either binc (or more likely bluetoothctl) is "remembering" something about a previous device.

A device will disconnect, but the scanner is still running, and so as soon as the device comes back into range, it will connect again. However, when this happens, before I've done any configuring of the device, I will get a few notifications (two from the battery, two from one of my custom characteristics). I can see from btmon that these get produced from bluetooth, but I also see that these die NOT come from my device. Separate logging on my device shows no activity there.

Then, when I go to configure my newly connected device, I go to turn on the battery level characteristic to send notifications, but (1) the library is telling me this characteristic already has notifications enabled (binc_characteristic_is_notifying saying true), and then when I try to enable it anyway via binc_characteristic_start_notify, the command goes out, but there is no log saying it returned (no notifying true <uuid>) probably because it's already true so it didn't "change"?

bojennett commented 3 months ago

My workaround for this at the moment is that I check to see the state before I do an action. If I want to turn notifications on, but it's already on, I say "hey that's weird" (because I know in my application I never want to turn it off). I will then force it off, and when I see that it was off I know that since I never tried to turn it off, I should try to turn it on. It's a hack because there is the possibility I could get into a loop here maybe, but it suffices.

But I'm curious if you are keeping objects around in your library based upon the UUID of the characteristic, and they are staying even if a device disconnects? And then the internal state of that is "notifications were enabled". Or, as I said, most likely it's a bluetoothctl thing

weliem commented 3 months ago

This is probably expected behavior. Bluez retains notification state for as long as the object is on the DBus. For paired devices this is the correct behavior and in line with the bluetooth standard. But for non-paired devices this should not be done. What I do in my apps is to remove non-paired devices from Dbus upon disconnecting. That way Bluez will 'forget' the notification state...

bojennett commented 3 months ago

Boom! That did the trick.

I'm wondering... since this is DBUS related, would there be any benefit to also "hiding" this? i.e. if we sense a device is disconnected, and it isn't a paired device, could adapter/device just internally call the remove?

Totally get why you might be reluctant to do that.

weliem commented 3 months ago

Well, if you remove it always, then you always need to discover it again before you can connect again. This might not be desirable in all use cases...e.g. if you want to connect to known devices quickly

bojennett commented 3 months ago

Fair enough. Makes sense. Thanks

Srikor commented 1 week ago

So, how do I connect to already paired devices? I'm a newbie and I can't see the paired devices in discovery and I'm not getting any connection change event when the paired device is powered on.

weliem commented 1 week ago

If your peripheral is advertising, then you should be able to find it during a discovery. However, if a device is powered on, it is not necessarily advertising....