Skip to content

[POTENTIAL BUG] Discovering a second Characteristic Breaks IsNotifying Updates #6

@Jcambass

Description

@Jcambass

Hi there, Thanks for the great library!

EDIT: It turns out peripheral.discoverCharacteristics works while peripheral.discoverCharacteristic does not. I did not read the docs properly but honestly, having read parts of them now, it's not super clear that one would break in hard to notice ways like this. Ideally we could either fix this behavior, make the failure more more explicit or at least improve the docs.


Warning

I'm relatively new to Swift, its concurrency primitives and (Core) Bluetooth. So I might be doing something obvious wrong (even thought I've tried to confirm my assumptions as much as possible :)).

I've ran into the problem that I would not receive any data after using SetNotify with my real device. I have verified that my device specific protocol is correct since it's highly inspired by an existing python application.

At that point, I tried to mimic what the Example app in this repository does and support toggling the notification status via the UI. When doing this I did notice that sometimes some call inside SetNotify would not work as expected. I honestly got lost a bit in the details so I can't share exact call stacks or proper function names.

However, I did see that we compare the new state with the current state on the characteristic and for some reason the characteristic had the old state still (the first update never reached it). With that in mind, I came up with a somewhat black box approach to test this:

  • Check the notification state of the characteristic whenever the UI state value changes and log out if the old UI state is not identical with the current (before calling setNotify) state on the characteristic.

Now, this feels kinda unsafe to me in terms of concurrency. The interesting thing was that doing the same in the Example app worked 100% of the time while in my app it triggered the failure condition 100% of the time. After a good amount of time I was able to isolate the problem down to the following:

  • Discovering a single characteristic on a service and using SetNotify works.
  • Discovering two characteristic on a serviceand using SetNotify on only one of them, does not work. Even if only one of them supports .notify.

I created a PR in my own repo to demonstrate this, commenting out the discovery of the heartRateControlCharacteristic causes the problem to go away.

I've been able to verify the problem and the above assumption about cause (one vs two characteristics discovered for the same service) with the mock but also my real device.

However, I will be unable to verify if I actually get data since the other characteristic is needed to trigger the device side sends.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions