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

MTU handshake results in default size #232

Open
pperanich opened this issue Jan 11, 2025 · 3 comments
Open

MTU handshake results in default size #232

pperanich opened this issue Jan 11, 2025 · 3 comments

Comments

@pperanich
Copy link
Contributor

When running the ble_bas_peripheral example on the Microbit, the agreed upon MTU results in the BLE default of 23 bytes, instead of the requested 247 that is specified L2CAP_MTU - 4. When running a similar application with nrf-softdevice (with the same devices for gatt server/client), the MTU handshake results in the upper limit being selected, i.e. whatever ATT_MTU sets.

@pperanich
Copy link
Contributor Author

Looking through the code base, it appears that neither the Connection nor ConnectionManager's set_att_mtu method is called anywhere. When I change the visibility of this method to pub and add the following snippet to the ble_bas_peripheral example, the agreed MTU is larger, though still not the requested ATT_MTU. I.e it ends up being 185, instead of 247:

    info!("[adv] advertising");
    let conn = advertiser.accept().await?;
    conn.set_att_mtu(ATT_MTU as u16);  // <-- Add here.
    info!("[adv] connection established");
    Ok(conn)

If I add the following log to exchange_att_mtu:

    pub(crate) fn exchange_att_mtu(&self, conn: ConnHandle, mtu: u16) -> u16 {
        let mut state = self.state.borrow_mut();
        for storage in state.connections.iter_mut() {
            match storage.state {
                ConnectionState::Connected if storage.handle.unwrap() == conn => {
                    info!("storage.att_mtu = {:?}, mtu = {:?}", storage.att_mtu, mtu);  // <-- Added log
                    storage.att_mtu = storage.att_mtu.min(mtu);
                    return storage.att_mtu;
                }
                _ => {}
            }
        }
        mtu
    }

I get:

0.007110 INFO  [adv] advertising
└─ trouble_example_apps::ble_bas_peripheral::advertise::{async_fn#0} @ /Users/peranpl1/Documents/repos/oss/trouble/examples/apps/src/fmt.rs:143
11.909423 TRACE [host] connection with handle ConnHandle(0) established to BdAddr([b2, cf, 56, d5, 2c, 59])
└─ trouble_host::host::{impl#1}::handle_connection @ /Users/peranpl1/Documents/repos/oss/trouble/host/src/fmt.rs:117
11.910186 TRACE [link][poll_accept] connection handle ConnHandle(0) in role Peripheral accepted
└─ trouble_host::connection_manager::{impl#1}::poll_accept @ /Users/peranpl1/Documents/repos/oss/trouble/host/src/fmt.rs:117
11.910888 INFO  [adv] notifying connection of tick 1
└─ trouble_example_apps::ble_bas_peripheral::counter_task::{async_fn#0} @ /Users/peranpl1/Documents/repos/oss/trouble/examples/apps/src/fmt.rs:143
12.046569 WARN  [host] unsupported l2cap channel id 58
└─ trouble_host::host::{impl#1}::handle_acl @ /Users/peranpl1/Documents/repos/oss/trouble/host/src/fmt.rs:156
12.046844 WARN  [host] encountered error processing ACL data for ConnHandle(0): NotSupported
└─ trouble_host::host::{impl#3}::run_with_handler::{async_fn#0} @ /Users/peranpl1/Documents/repos/oss/trouble/host/src/fmt.rs:156
12.076995 INFO  storage.att_mtu = 247, mtu = 185
└─ trouble_host::connection_manager::{impl#1}::exchange_att_mtu @ /Users/peranpl1/Documents/repos/oss/trouble/host/src/fmt.rs:143
12.077453 INFO  [host] agreed att MTU of 185
└─ trouble_host::host::{impl#1}::handle_acl @ /Users/peranpl1/Documents/repos/oss/trouble/host/src/fmt.rs:143

Note: I seem to always get the above warning about unsupported l2cap channel id. Curious if anyone else has noticed this.

lulf added a commit that referenced this issue Jan 13, 2025
Rather than setting default att mtu to the smallest value,
set it to the max possible based on l2cap mtu - 4.

Issue #232
@lulf
Copy link
Member

lulf commented Jan 13, 2025

I think #237 should fix using the l2cap - 4 as the default rather than 23. Wrt. set_att_mtu, it was used earlier when att mtu was explicitly set from the no longer existing gatt server. We could remove the method, or expose it.

In either case, if the other end chooses a lower value, it will pick the lowest (it looks like in your case the other end has a max of 185?)

lulf added a commit that referenced this issue Jan 13, 2025
Rather than setting default att mtu to the smallest value,
set it to the max possible based on l2cap mtu - 4.

Issue #232
lulf added a commit that referenced this issue Jan 13, 2025
Rather than setting default att mtu to the smallest value,
set it to the max possible based on l2cap mtu - 4.

Issue #232
@pperanich
Copy link
Contributor Author

I would be in favor of removing the set_att_mtu methods if they are no longer in use.

It's interesting because when I run the ble_bas_peripheral example of the nrf-softdevice repo on the Microbit and use the same client-side device, the att mtu is negotiated to be 247.

lulf added a commit that referenced this issue Jan 14, 2025
Rather than setting default att mtu to the smallest value,
set it to the max possible based on l2cap mtu - 4.

Issue #232
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

No branches or pull requests

2 participants