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

fix: Duplicate Characteristic UUID overwrite each other #365

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from

Conversation

blackspherefollower
Copy link
Contributor

If a device (like the LOOB) declares multiple characteristics on a service with the same UUID, the last declared characteristic is used not the first (which is what the LOOB requires us to control).

Ideally we'd have access to them all, but since we can't tell them apart at the higher levels first wins seems better than last wins.

This has been tested on Windows, macOS, Android and Linux

};
// Only consider the first characteristic of each UUID
// This "should" be unique, but of course it's not enforced
if !characteristics.contains(&char) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if there is another characteristic which has the same UUID but is different in some other way?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's dropped. Ideally, this should never happen, but the reality turns out that there are devices out there that do this.

Right now, the first characteristic is overridden, so in that respect its no worse (this change just picks the first one rather than the last).

I did consider changing the characteristic structures to Map<Uuid, Vec> (please excuse the pseudocode), but given that all the other methods use the Uuid as the key for performing characteristic operations, that'd mean that they'd all have to be able to take a UUID and an index (99.9% of the time, there's only going to be 1 item in the array). The trade-off between being able to address all characteristics (even with duplicate keys) vs the overhead of the interface changes to support 1 device felt way off to me.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How? This code seems to be comparing the characteristic as a whole, not just the UUID, unlike the other platform implementations.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good question... Sorry, I was answering for the change as a whole, not the Android diff specifically.

Hmm... the comparator does look like it applies to all members of the struct, so the contains check probably never returns true. I guess the properties and then descriptors would define the order that btleplug presents the characteristics, and I'm guessing that at a higher level they'll get uniqued by UUID. I see the UUID is the only identifier passed across the JNI boundary, and the characteristics are held in an ArrayList on that side, so I think making this set UUID unique (first characteristic wins) will mean that the presented properties match up the the characteristic being addressed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@qwandor I've re-written and re-tested the Android portion of the change

This meant that if a device (like the LOOB) declares multiple characteristics
on a service with the same UUID, the later is used not the first. Ideally we'd
have access to them all, but since we can't tell them apart at the higher levels
first wins seems better than last wins.
@blackspherefollower
Copy link
Contributor Author

Rebased and building, but still testing: please don't merge (I swear there was a button for making PR's draft/WIP...)

@qdot qdot marked this pull request as draft October 6, 2024 17:39
@qdot
Copy link
Contributor

qdot commented Oct 6, 2024

I converted it to draft (It's in the "reviewers" section for some reason)

@blackspherefollower
Copy link
Contributor Author

I converted it to draft (It's in the "reviewers" section for some reason)

Apparently I don't have the required memberships to see the option...

I've tested on Windows/Linux/Android and we're all good.
My attempts to build for macOS have not been so successful - I'm bouncing around either ruby(cocoapods) issues or cert issues in CI

@blackspherefollower blackspherefollower marked this pull request as ready for review October 10, 2024 09:26
@blackspherefollower
Copy link
Contributor Author

@qdot Apparently the "not a draft any more" button was right at the bottom of the page...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants