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

Assorted fixes to allow pairing/bonding, and working with Apple Siri Remotes #27

Merged
merged 4 commits into from
Jul 5, 2024

Conversation

retsyx
Copy link
Contributor

@retsyx retsyx commented Jun 25, 2024

See individual commit messages.

retsyx added 4 commits June 25, 2024 13:30
MTU for client and server can be different. When we negotiate MTU,
don't use the returned server's MTU for our client's MTU. Instead,
set our MTU, notify the server, and be done.
A random address may be used when pairing to a peripheral. For later reference, the public
address needs to be known. Until this change, there was no way to know the public address
from the information available when performing the pairing. The kernel returns the
public address at pair completion, and bluepy now propogates it to the caller.
Bondable/pairable controls if bonding is enabled when pairing with a device.
If it is not set when pairing, some devices will refuse to pair with an insufficient authentication
error.
Devices notify however they want, and BTLE should faithfully reflect that.
@Mausy5043
Copy link
Owner

Mausy5043 commented Jun 29, 2024

Thank you @retsyx for this PR. We will look in to it.

@Mausy5043
Copy link
Owner

Mausy5043 commented Jun 29, 2024

If you'd like, you can test your changes by installing bluepy3 v2.9.4 using

python3 -m pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ --no-deps --upgrade bluepy3

@Mausy5043
Copy link
Owner

Mausy5043 commented Jun 29, 2024

We're willing to pull the first three commits, but commit e0bf351 is unrelated to the other commits and more controversial.

I'd like to ask you to do two things:

  1. Remove commit e0bf351 from this PR.
    Feel free to offer those changes in a new PR.
  2. We can't test the functionality you added. So, please test v2.9.4 for yourself and decide if additional changes are needed.

@retsyx
Copy link
Contributor Author

retsyx commented Jun 29, 2024

All the commits are necessary for bluepy3 Siri Remote compatibility. Without e0bf351, Siri Remotes trigger the exception nearly instantly.

Perhaps I'm misunderstanding the exception. I failed to find a commit message explaining the change (relative to bluepy). On the face of it, it looks like a transport layer, bluepy3, is making determinations about what devices are allowed to do. Given you think the exception is necessary, what is the correct way to use bluepy3 so that the exception isn't raised by arbitrary device behavior?

@Mausy5043
Copy link
Owner

Mausy5043 commented Jun 30, 2024

There are/were a lot of problems like this one and this one with Xiaomi Mija LYWSD03MMC devices that would hang bluepy-helper seemingly for no reason and causing it to use 100% CPU. I have several devices of my own and had the same issues.
This led me to investigate the problem and I found that these devices would just keep sending ntfys until the bluepy-helper was killed. This prompted the code adjustments you want to revert in e0bf351.
How to move forward? Could you try to find out how many ntfys your device sends until _waitResp() returns?

Given you think the exception is necessary, what is the correct way to use bluepy3 so that the exception isn't raised by arbitrary device behavior?

As I see it now, there is a bug in the implementation of BT/BLE in some devices in the market. Notably Xiaomi devices seem infected. I can't fix those. I agree with you that the stack should allow devices to communicate however they see fit. But, the next best thing AFAICS is to fix the erroneous device behaviour at this point in the stack.
e0bf351#diff-c1a12b99c58955d386175abdf7a7890632313d993dab6c726de4c8d2700aea0cL546-L548

We could make the number of ntfy after which to raise the exception an optional parameter of the Bluepy3Helper class or as an atribute of the btle module, either with a sensible default. Alternatively, bluepy3-helper.c might be modified to handle stuff differently.

@retsyx
Copy link
Contributor Author

retsyx commented Jun 30, 2024

Ok. I looked at the code again and I think that your spam limiting change is entirely untenable. At least as it is structured at the moment. The explanation is really simple. The entire Siri Remote protocol is based on notifications. The way the Siri remote protocol works is that the client (bluepy3) connects to the server (the remote), and requests various notifications for button, touch, or audio events. When a user presses a button, or moves a finger on the remote's touchpad, the remote generates a notification. So there will be a practically infinite number of notifications.

From looking at the code, I think it is counting notifications globally over the lifetime of the helper. That obviously won't work for a remote that uses notifications for everything.

I don't know why the Xiaomi sensors generate a notification flood. Perhaps it has a similar notification protocol, and it is being misconfigured by your handshake code (not that that justifies a notification flood), or perhaps it is has not been tested by Xiaomi for long duration BT sessions (I assume the sensor is for use with phones which will naturally have only short term sessions). If it's a session duration problem than a periodic disconnect by higher level code could resolve the issue. If possible, I would try to get a BT trace to see if the Xiaomi sensor floods a Xiaomi certified compatible device.

The alternative is to change the global limit to a rate limit. But I think the problem is really elsewhere.

@Mausy5043
Copy link
Owner

I understand your point and have to agree that this needs to go. I haven't previously used the stack in this way (with paired devices). So it never came up.

I'm going to have to rethink this at some point, but will reinstate the bluepy3-helper-killer service on the RPi for the moment.
I'm also not sure if changing to a rate-limit would solve anything. Keeping a button of the remote pressed for a long time could then exceed the rate limit and we'd be no better off.

@retsyx
Copy link
Contributor Author

retsyx commented Jul 2, 2024

If you'd like, you can test your changes by installing bluepy3 v2.9.4 using

python3 -m pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ --no-deps --upgrade bluepy3

Thank you. I tested v2.9.4, and it works well for me.

@Mausy5043
Copy link
Owner

I'm giving it a few more days of testing on my system. My experience with BT/BLE is that it seems to have a bit of a random timing when problems will reproduce. If all goes well I expect to merge the coming weekend.

@Mausy5043 Mausy5043 merged commit b213ff7 into Mausy5043:devel Jul 5, 2024
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.

2 participants