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

Requesting MTU #407

Draft
wants to merge 6 commits into
base: dev
Choose a base branch
from
Draft

Requesting MTU #407

wants to merge 6 commits into from

Conversation

robbym
Copy link

@robbym robbym commented Nov 12, 2024

This PR will include a method to retrieve the negotiated MTU size on each platform.

Info grabbed from: #246

Windows - GattSession.MaxPduSize
Negotiation happens on user's behalf, and a GattSession.MaxPduSizeChanged event is emitted when MTU is updated.

macOS / iOS - CBPeripheral.maximumWriteValueLength
Negotiation happens on user's behalf, have used peripheral.maximumWriteValueLength(for: .withoutResponse) reliably in the past. .withResponse has some issues. See here.

Linux
Instead of a dedicated MTU property, BlueZ has decided to adopt the newer Bluetooth 5.2 standard. Example here: Link

Android - BluetoothGatt.requestMtu
The way I understand it and have used it in the past, you call requestMtu with the largest you can support (e.g. 512), and it will negotiate the min(host.maxMtu, periph.maxMtu) and call onMtuChanged with the new mtu size.

TODO:

  • Windows
  • Linux
  • Android
  • macOS/iOS

@qwandor qwandor changed the base branch from master to dev November 12, 2024 16:31
@@ -93,6 +94,7 @@ impl Peripheral {
adapter,
device: tokio::sync::Mutex::new(None),
address,
mtu: AtomicU16::new(23),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Where does this 23 come from?

Copy link
Author

Choose a reason for hiding this comment

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

It's the default size of the MTU prior to negotiation. It includes the L2CAP header (4 bytes), so usable size would be 19.

Copy link
Author

Choose a reason for hiding this comment

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

I think I'll add an initial assignment from MaxPduSize prior to the event handler registration.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Please add a constant for it, with a comment explaining this.

@laxian
Copy link

laxian commented Dec 11, 2024

@robbym Hi, have you finish it on bluez?

@robbym
Copy link
Author

robbym commented Dec 20, 2024

@laxian I just pushed a working bluez implementation. I tested it on one of my BLE devices and it works, but let me know if there is any issues.

@qwandor I added the constant and now moved it to the api namespace so that each implementation can use it. Not really happy with where it currently lives. Maybe move it to common?

let services = self.services.lock().unwrap();
for (_, service) in services.iter() {
for (_, characteristic) in service.characteristics.iter() {
return characteristic.info.mtu.unwrap();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can this be different for different characteristics?

Copy link
Author

Choose a reason for hiding this comment

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

In Bluetooth 5.2 and forward, yes. The reason they implemented it as a per-characteristic MTU is because of the enhanced ATT (EATT) bearer feature.

They mention it here: bluez/bluez#199
I mention it here: #246 (comment)

The majority of devices on the market are going to be using the unenhanced version (single MTU per connection), so I don't understand why bluez didn't add support for that first.

In any case, the implementation was based on how SimpleBle did it: https://github.com/OpenBluetoothToolbox/SimpleBLE/blob/614a5af35cdd22ba08318cb776795ecd2da8c389/simpleble/src/backends/linux/PeripheralBase.cpp#L57

Copy link
Collaborator

Choose a reason for hiding this comment

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

Okay, seems reasonable given the API limitations.

@qwandor qwandor requested a review from qdot December 20, 2024 23:25
@qwandor qwandor added enhancement New feature or request bluez (linux) Issues related to the dbus/bluez core uwp (windows) Issues related to the UWP/Win10 core labels Dec 20, 2024
@qdot
Copy link
Contributor

qdot commented Dec 21, 2024

Windows parts of this are looking good so far. Would like to get all platforms in before we land it (otherwise I will have people on unsupported platforms yelling) but I'm fine to also do a point release whenever we get all the parts in.

@qdot qdot marked this pull request as draft December 21, 2024 22:01
@qdot
Copy link
Contributor

qdot commented Dec 21, 2024

Converted this to a draft until we get all the platforms in. Just makes my life easier for the little amount of time I actually get to do triage on this project.

@qdot
Copy link
Contributor

qdot commented Dec 21, 2024

One more quick update here: I brought us up to bluez-async 0.8.0 in v0.11.7, so mtu() is available now and we can drop that change here (it'll probably just skip the commit on rebase).

Copy link
Collaborator

@qwandor qwandor left a comment

Choose a reason for hiding this comment

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

BlueZ implementation seems fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bluez (linux) Issues related to the dbus/bluez core enhancement New feature or request uwp (windows) Issues related to the UWP/Win10 core
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants