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

Use the negotiated mtu for read requests #31

Merged
merged 1 commit into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions bleps/src/async_attribute_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ where
{
pub(crate) ble: &'a mut Ble<T>,
pub(crate) src_handle: u16,
pub(crate) mtu: u16,
pub(crate) attributes: &'a mut [Attribute<'a>],
}

Expand All @@ -43,6 +44,7 @@ where
AttributeServer {
ble,
src_handle: 0,
mtu: crate::attribute_server::BASE_MTU,
attributes,
}
}
Expand Down
27 changes: 15 additions & 12 deletions bleps/src/attribute_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,8 @@ pub const PRIMARY_SERVICE_UUID16: Uuid = Uuid::Uuid16(0x2800);
pub const CHARACTERISTIC_UUID16: Uuid = Uuid::Uuid16(0x2803);
pub const GENERIC_ATTRIBUTE_UUID16: Uuid = Uuid::Uuid16(0x1801);

/// The base MTU that is always supported. The MTU can be upgraded
/// per-connection. In the case of multiple connections, handling this
/// correctly would involve keeping track of which connection was configured
/// with which MTU. Instead of doing this, we always use the `BASE_MTU`
/// when transmitting but in the MTU exchange we support reporting a larger MTU.
/// This allows the client to use a larger MTU when transmitting to us, even
/// though we always respond with the smaller MTU.
/// The default value of MTU, which can be upgraded through negotiation
/// with the client.
pub const BASE_MTU: u16 = 23;

#[cfg(feature = "mtu128")]
Expand Down Expand Up @@ -61,6 +56,10 @@ impl From<AttDecodeError> for AttributeServerError {

pub struct AttributeServer<'a> {
ble: &'a mut Ble<'a>,
// The MTU negotiated for this server. In principle this can be different per-client,
// but we only support one client at a time, so we only need to store one value
// (and reset it to the default when disconnecting).
mtu: u16,
src_handle: u16,
attributes: &'a mut [Attribute<'a>],
}
Expand Down Expand Up @@ -122,7 +121,7 @@ bleps_dedup::dedup! {
) -> Result<WorkResult, AttributeServerError> {
if let Some(notification_data) = notification_data {
let mut answer = notification_data.data;
answer.limit_len(BASE_MTU as usize - 3);
answer.limit_len(self.mtu as usize - 3);
let mut data = Data::new_att_value_ntf(notification_data.handle);
data.append(&answer.as_slice());
self.write_att(self.src_handle, data).await;
Expand All @@ -144,6 +143,8 @@ bleps_dedup::dedup! {
reason: _,
} = evt
{
// Reset the MTU; the next connection will need to renegotiate it.
self.mtu = BASE_MTU;
Ok(WorkResult::GotDisconnected)
} else {
Ok(WorkResult::DidWork)
Expand Down Expand Up @@ -330,7 +331,7 @@ bleps_dedup::dedup! {

let response = match err {
Ok(_) => {
data.limit_len(BASE_MTU as usize);
data.limit_len(self.mtu as usize);
data
}
Err(e) => Data::new_att_error_response(ATT_READ_REQUEST_OPCODE, handle, e),
Expand Down Expand Up @@ -373,8 +374,9 @@ bleps_dedup::dedup! {
}

async fn handle_exchange_mtu(&mut self, src_handle: u16, mtu: u16) {
log::debug!("Requested MTU {mtu}, returning {MTU}");
self.write_att(src_handle, Data::new_att_exchange_mtu_response(MTU))
self.mtu = mtu.min(MTU);
log::debug!("Requested MTU {mtu}, returning {}", self.mtu);
self.write_att(src_handle, Data::new_att_exchange_mtu_response(self.mtu))
.await;
}

Expand Down Expand Up @@ -484,7 +486,7 @@ bleps_dedup::dedup! {

let response = match err {
Ok(_) => {
data.limit_len(BASE_MTU as usize - 1);
data.limit_len(self.mtu as usize);
data
}
Err(e) => Data::new_att_error_response(ATT_READ_BLOB_REQ_OPCODE, handle, e),
Expand Down Expand Up @@ -531,6 +533,7 @@ impl<'a> AttributeServer<'a> {

AttributeServer {
ble,
mtu: BASE_MTU,
src_handle: 0,
attributes,
}
Expand Down