Skip to content

Commit

Permalink
handle the case were granted credits were not used
Browse files Browse the repository at this point in the history
  • Loading branch information
lulf committed Apr 24, 2024
1 parent d89752e commit c7c764f
Showing 1 changed file with 73 additions and 33 deletions.
106 changes: 73 additions & 33 deletions host/src/channel_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,19 +208,21 @@ impl<
mps,
dcid: cid,
mtu,
credits: 0,
credits,
result: LeCreditConnResultCode::Success,
},
&mut tx[..],
)
.await?;

// NOTE: This code is disabled as we send the credits in the response request. For some reason the nrf-softdevice doesn't do that,
// so lets keep this around in case we need it.
// Send initial credits
let next_req_id = self.next_request_id();
controller
.signal(conn, next_req_id, &LeCreditFlowInd { cid, credits }, &mut tx[..])
.await?;

// let next_req_id = self.next_request_id();
// controller
// .signal(conn, next_req_id, &LeCreditFlowInd { cid, credits }, &mut tx[..])
// .await?;
//
Ok(cid)
}

Expand Down Expand Up @@ -256,7 +258,7 @@ impl<
mps,
scid: cid,
mtu,
credits: 0,
credits,
};
controller.signal(conn, req_id, &command, &mut tx[..]).await?;

Expand All @@ -281,11 +283,13 @@ impl<
})
.await?;

// NOTE: This code is disabled as we send the credits in the response request. For some reason the nrf-softdevice doesn't do that,
// so lets keep this around in case we need it.
// Send initial credits
let next_req_id = self.next_request_id();
let req = controller
.signal(conn, next_req_id, &LeCreditFlowInd { cid, credits }, &mut tx[..])
.await?;
// let next_req_id = self.next_request_id();
// let req = controller
// .signal(conn, next_req_id, &LeCreditFlowInd { cid, credits }, &mut tx[..])
// .await?;
Ok(cid)
}

Expand Down Expand Up @@ -540,21 +544,31 @@ impl<

poll_fn(|cx| self.poll_request_to_send(cid, n_packets, Some(cx))).await?;

// Segment using mps
let (first, remaining) = buf.split_at(buf.len().min(mps as usize - 2));
let mut unsent = n_packets;
let result: Result<(), AdapterError<T::Error>> = async {
// Segment using mps
let (first, remaining) = buf.split_at(buf.len().min(mps as usize - 2));

let len = encode(first, &mut p_buf[..], peer_cid, Some(buf.len() as u16))?;
hci.send(conn, &p_buf[..len]).await?;
let len = encode(first, &mut p_buf[..], peer_cid, Some(buf.len() as u16))?;
hci.send(conn, &p_buf[..len]).await?;
unsent -= 1;

let chunks = remaining.chunks(mps as usize);
let num_chunks = chunks.len();
let chunks = remaining.chunks(mps as usize);
let num_chunks = chunks.len();

for (i, chunk) in chunks.enumerate() {
let len = encode(chunk, &mut p_buf[..], peer_cid, None)?;
hci.send(conn, &p_buf[..len]).await?;
for (i, chunk) in chunks.enumerate() {
let len = encode(chunk, &mut p_buf[..], peer_cid, None)?;
hci.send(conn, &p_buf[..len]).await?;
unsent -= 1;
}
Ok(())
}

Ok(())
.await;
if unsent > 0 {
warn!("Replenishing credits for {} unsent packets", unsent);
self.abort_send(cid, unsent)?;
}
result
}

/// Send the provided buffer over a given l2cap channel.
Expand Down Expand Up @@ -582,21 +596,31 @@ impl<
}
}

// Segment using mps
let (first, remaining) = buf.split_at(buf.len().min(mps as usize - 2));
let mut unsent = n_packets;
let result: Result<(), AdapterError<T::Error>> = {
// Segment using mps
let (first, remaining) = buf.split_at(buf.len().min(mps as usize - 2));

let len = encode(first, &mut p_buf[..], peer_cid, Some(buf.len() as u16))?;
hci.try_send(conn, &p_buf[..len])?;
let len = encode(first, &mut p_buf[..], peer_cid, Some(buf.len() as u16))?;
hci.try_send(conn, &p_buf[..len])?;
unsent -= 1;

let chunks = remaining.chunks(mps as usize);
let num_chunks = chunks.len();
let chunks = remaining.chunks(mps as usize);
let num_chunks = chunks.len();

for (i, chunk) in chunks.enumerate() {
let len = encode(chunk, &mut p_buf[..], peer_cid, None)?;
hci.try_send(conn, &p_buf[..len])?;
}
for (i, chunk) in chunks.enumerate() {
let len = encode(chunk, &mut p_buf[..], peer_cid, None)?;
hci.try_send(conn, &p_buf[..len])?;
unsent -= 1;
}
Ok(())
};

Ok(())
if unsent > 0 {
warn!("Replenishing credits for {} unsent packets", unsent);
self.abort_send(cid, unsent)?;
}
result
}

fn connected_channel_params(&self, cid: u16) -> Result<(ConnHandle, u16, u16), Error> {
Expand Down Expand Up @@ -683,6 +707,22 @@ impl<
Ok(())
}

fn abort_send(&self, cid: u16, credits: u16) -> Result<(), Error> {
self.state.lock(|state| {
let mut state = state.borrow_mut();
for (idx, storage) in state.channels.iter_mut().enumerate() {
match storage.state {
ChannelState::Connected if cid == storage.cid => {
storage.peer_credits += credits;
return Ok(());
}
_ => {}
}
}
Err(Error::NotFound)
})
}

fn poll_request_to_send(&self, cid: u16, credits: u16, cx: Option<&mut Context<'_>>) -> Poll<Result<(), Error>> {
self.state.lock(|state| {
let mut state = state.borrow_mut();
Expand Down

0 comments on commit c7c764f

Please sign in to comment.