deviceplug / btleplug

Rust Cross-Platform Host-Side Bluetooth LE Access Library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

(dev branch - async) Connection unstable and notifications not firing correctly on Linux Bluez when using adapter events

qdot opened this issue · comments

commented

Describe the bug

  1. Get the adapter events stream (THIS STR DOES NOT WORK OTHERWISE)
  2. Connect to a device with a notify endpoint
  3. Subscribe to endpoint notifications
  4. Trigger notification

Expected behavior
Device connects, notification event is fired

Actual behavior
First off, the device may not connect, because of "Service discovery timed out" issues during connect.

Stopping and restarting the program (assuming the program doesn't disconnect the device on exit) seems to fix that, but then, even if connect is successful, the device will not receive any device events.

We're at least getting PropertiesChanged updates, as I'm seeing this in the logs:

Jun 05 23:50:36.502 TRACE bluez_async::events: PropertiesChanged for /org/bluez/hci0/dev_C1_E0_E9_13_05_7C/service000b/char000e: PropertiesPropertiesChanged { interface_name: "org.bluez.GattCharacteristic1", changed_properties: {"Value": Variant([80, 58, 50, 48, 52, 58, 67, 49, 69, 48, 69, 57, 49, 51, 48, 53, 55, 67, 59])}, invalidated_properties: [] }

However, we're not getting any device events sent back through the streams.

Additional context

The best way to test this is to add the logic from subscribe_notify_characteristics to the event_driven_discovery example. This seems to also cause issues with finding services on connect, and just general stability issues all over. With adapter events turned off, everything works fine.

Also, this is only on bluez. Win/MacOS work fine for either example.

commented

If I watch the main event_stream (which gets all events off the central), we do get characteristic updates in btleplug there. However, using the device_event_stream filter, we get nothing at the device level.

@qwandor this might be an issue back in bluez-async? Do you have any devices with notify/indicate characteristics to test with?

I just tried to reproduce this, but it seems to work fine for me. Using the notification example from #157 (but with a different device), I'm able to subscribe to notifications and get them as expected on Linux. I tried several times and it seemed to work fairly reliably too.

commented

@qwandor Ok, thanks for trying. This could very well be something weird up in Buttplug, so I'll adapt the notification example to my needs and see if I can repro.

I've used that #157 with one of 'old neuro device' and it works fine.
But when I use the same code for 'newer neuro device' (using updated UUIDs/name) that example doesn't work for me too on Linux. Subscribing to notification just 'hangs and stuck'.
I will try one work around with not working device. may be that is kind of 'feature' of hardware. I'll write my research result then.

Ok, I tried work around for my ble device.
I found that approach in C++ code for device: from silicanlabs forum - write 0x0001 to enable notifications
So I tried to write data first as mentioned

       if characteristic.uuid == WRITE_TO_CHARACTERISTIC_UUID
              && characteristic.properties.contains(CharPropFlags::WRITE)
       {
           let data:[u8;2] = [00, 01]; // I tried  [01, 00] too
           println!("Sending command {:?} to characteristic {:?}", &data, characteristic.uuid);
           peripheral.write(&characteristic, &data, WriteType::WithResponse).await?;
        }
      // Subscribe to notifications from the characteristic with the selected UUID.
        if characteristic.uuid == NOTIFY_CHARACTERISTIC_UUID
               && characteristic.properties.contains(CharPropFlags::NOTIFY)
        {
           println!("Subscribing to characteristic {:?}", characteristic.uuid);

but that didn't help. Example stucks on Subscribing to characteristic xxxx message and hangs at that point.

May be there is something odd with subscribing on notification. I would like to help track the problem if library has ability to write full internal logs while running example with my device on linux. I also has one INDICATE characteristic on that not working device.

Try adding pretty_env_logger::init() to the start of the main function (we should have added this in the first place), and then set RUST_LOG=trace and you should get more logs.

trace.log
Here is a trace log for example.

working_trace.log
Here is a trace for similar device (but older hardware) that works fine with example code.

As I can assume, two logs are not quite verbose and informative at interested code part, aren't they? If someone prepares different branch with more correct logging, I will run both examples again to gather data.

commented

@qwandor Just updated this with the relevant info that we were discussing on discord.

Is there any update on this? I'm running into the same issue.

commented

Is there any update on this? I'm running into the same issue.

Nope. Right now I'm just using the "event detect on mac/win, polling on linux" workaround. :(

I can try to look at this, but it won't be for a few weeks probably. Does someone have a minimal example to reproduce it yet? Last time I looked I wasn't able to reproduce the issue.

commented

I can try to look at this, but it won't be for a few weeks probably. Does someone have a minimal example to reproduce it yet? Last time I looked I wasn't able to reproduce the issue.

Did you try with the event discovery example? That does it for me with pretty much any device.

The underlying bug is diwic/dbus-rs#346, which should be fixed by diwic/dbus-rs#347.

Just checked on my HW, it still doesn't work on btleplug=0.8.1 with dbus = "0.9.3"
I see some changes were merged into 0.9.3
diwic/dbus-rs#351

Is there something I can try to fix on local dbus fork to check and probably make it work ? Where can I look at in dbus code?

I'm waiting for the next release of the dbus crate with the fix in it, then I'll update bluez-async and btleplug to use it. We need to call the new set_all_signal_matches method to enable the mode that works properly.

Fixed in 0.9.0.

It works but....
Data sampling is very sloooow from device. I know my device has a sampling rate about 50 data chunks per second.
Now example code receives data one sample per second,