Skip to content

Conversation

@andrewdavidmackenzie
Copy link
Contributor

Fixes #75

Summary
Handle the case when server DuplexChannel is closed upon disconnecting stream, which causes the server.read() to return a length of 0 bytes. In that case do not call write_to_radio() with zero length.

Related Issues
Fixes #75

Proposed Changes

  • test if length is zero from server.read()

Checklist

  • Tests pass locally

    • I wanted to add a failing test, but don't see any existing tests on COnnectedStreamAPI, and wasn't sure how to go about adding one, when an attached radio (or a mock!) is needed
  • Documentation updated if needed - N/A

},
// Data from user, forward it to the device
from_server = server.read(&mut buf) => {
let len = from_server.map_err(duplex_write_error_fn)?;
Copy link
Contributor Author

@andrewdavidmackenzie andrewdavidmackenzie Nov 7, 2025

Choose a reason for hiding this comment

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

Unrelated, but I notice on this read error you map_err using a write error fn, and the same at line 308

Copy link
Collaborator

Choose a reason for hiding this comment

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

Right, the name is wrong, I can change it later.

self.radio
// TODO: remove the skipping of the first 4 bytes
.write(&self.toradio_char, &buffer[4..], WriteType::WithResponse)
.write(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added this:

  • to check how ConnectedStreamAPI would handle it, which it does fine and avoids the panic also (tested removing the len != 0 check first)
  • for consideration as additional protection from panics due to any caller providing an invalid length buffer. Up to you to decide to include or something similar. I imagine there will be a very small runtime overhead with the check, but maybe negligible for the number of packets being sent?

let len = from_server.map_err(duplex_write_error_fn)?;
ble_handler.write_to_radio(&buf[..len]).await?;
if len != 0 {
ble_handler.write_to_radio(&buf[..len]).await?;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we can also return Err(InternalStreamError::ConnectionLost) in case len == 0.

I can look into this later, you can merge this PR as it is an improvement.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You will have to merge it I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If the result of an explicit disconnect call, strictly speaking not an error - but will let you decide.

},
// Data from user, forward it to the device
from_server = server.read(&mut buf) => {
let len = from_server.map_err(duplex_write_error_fn)?;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Right, the name is wrong, I can change it later.

@lukipuki
Copy link
Collaborator

Re testing: I want to add tests for BLE using mocking later, this will be longer effort.

@lukipuki lukipuki merged commit 0a3a9da into meshtastic:main Nov 12, 2025
6 checks passed
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.

Panic reported on disconnect

2 participants