Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disconnect on peripheral should clear all outstanding events #16

Open
Apollon77 opened this issue Jan 2, 2025 · 4 comments
Open

Disconnect on peripheral should clear all outstanding events #16

Apollon77 opened this issue Jan 2, 2025 · 4 comments
Labels
bug Something isn't working

Comments

@Apollon77
Copy link

I got an issue with duplicate code execution when a disconnect happens while being in "connect logic".
Here is what happens

  • Connect 1 is send and "connected " event is emitted
  • Then we send discoverServicesAsync which registers a "once" event handler to get the result ... this now does not return ... BUT a disconnect happens. means "disconnect" event is emitted. But in fact the expected command is never errored or such and so also this promise is not resolved!
  • the disconnect event leads to a retry now in my code, means we get the newest peripheral (ok in this case it was not replaced btw) and connect. Connect is emitted
  • We send the discoverServicesAsync again ... which leads to a second "once" event listener.
  • And NOW it works and the event is emitted to both handlers and response resolves BOTH promises - the initial one and also the new one ... and so the code in "connected" runs further twice

So a disconnect should clear all outstanding events on the peripheral that might be and ideally also fail all promises

@dwimberger
Copy link

We have observed the same issue with disconnects during discoverSomeServicesAndCharacteristicsAsync().
const { characteristics } = await this.device.discoverSomeServicesAndCharacteristicsAsync(services, characteristicsIdentifiers);

If a device disconnect happens during this procedure, it does never return/waits forever.
This can be reproduced with 1.18.2, 1.18.3 and 1.19.0. All versions are pinned to a 1.4.x hci-socket version:
"overrides": {
"@stoprocent/bluetooth-hci-socket": "1.4.x"
}

One thing that we have seen is, that there are no callbacks if not all services where found:
if (numDiscovered === services.length) { if (callback) { callback(null, services, allCharacteristics); } }

However in some instances the disconnect does not receive a callback because the event servicesDiscover seems not to be issued, but no other is handled:
this.once('servicesDiscover', services => { callback(null, services); });
Still trying to analyse this one better and will follow up if I find out more.

@stoprocent
Copy link
Owner

Are you calling disconnect while discoverSomeServicesAndCharacteristicsAsync or is it happening for some other reason?
I understand, and yes, looking at the code, it could be the case. There is even a comment done by the original author // TODO: handle error?

This is something that is easy to fix

@stoprocent stoprocent added bug Something isn't working and removed incomplete labels Feb 26, 2025
@dwimberger
Copy link

No, the disconnect happens for other reasons and while talking to a real device.

We have found some rather ugly workarounds to get the events handled. But I am still cleaning up. It would maybe be good to discuss it, before proposing it as a patch.

@dwimberger
Copy link

@stoprocent+noble+1.19.1.patch

This is a shot against the last version. If you think it makes sense I can open a PR as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants