Skip to content

Add MTU discovery with typed ProtocolError enum#200

Merged
okhsunrog merged 6 commits intojamesmunns:mainfrom
okhsunrog:mtu-discovery
Mar 28, 2026
Merged

Add MTU discovery with typed ProtocolError enum#200
okhsunrog merged 6 commits intojamesmunns:mainfrom
okhsunrog:mtu-discovery

Conversation

@okhsunrog
Copy link
Copy Markdown
Collaborator

Add MTU discovery so routers can detect and report oversized frames. InterfaceSink gains an mtu() method, EdgePort::send_raw checks frame size before sending, and the router replies with a PacketTooBig error carrying the bottleneck MTU value. To make this work cleanly on the wire, ProtocolError is changed from a struct(u16) newtype to a proper enum — each variant can now carry its own typed payload (e.g. IsePacketTooBig { mtu: u16 }), serialized natively by postcard.

  • Add mtu() to InterfaceSink trait; implement in cobs_stream::Sink, framed_stream::Sink, and multi_interface! macro
  • Add InterfaceSendError::PacketTooBig { mtu } variant with MTU check in EdgePort::send_raw
  • Router process_frame catches PacketTooBig and sends error back to source with the MTU value
  • Replace ProtocolError(u16) + associated constants with enum ProtocolError — variants carry typed data
  • Remove the separate PacketTooBig struct and encode_frame_err_with_payload (enum handles this natively)
  • Add ErgotPathMtuEndpoint well-known endpoint (types only, no server yet)
  • Add 5 tests: wire round-trip (simple error, PacketTooBig with MTU, max MTU), router PacketTooBig e2e, send-within-MTU success

Breaking changes:

  • ProtocolError is now an enum — all code matching on ProtocolError::SSE_NO_SPACE etc. must use ProtocolError::SseNoSpace style variants
  • InterfaceSink implementations must add fn mtu(&self) -> u16

Cherry-picked from feature/mtu-discovery and adapted for unified Router:

- Add mtu() to InterfaceSink trait (cobs_stream, framed_stream, multi_interface)
- Add ISE_PACKET_TOO_BIG protocol error (18) and PacketTooBig payload struct
- Add MTU check in EdgePort::send_raw before forwarding
- Send PROTOCOL_ERROR back to source when forwarded frame exceeds outgoing MTU
- Add ErgotPathMtuEndpoint well-known endpoint with PathMtuQuery/PathMtuResult
Replace ProtocolError(u16) with a proper enum where each variant can
carry its own data. This allows IsePacketTooBig { mtu: u16 } to
natively encode the bottleneck MTU in the wire frame, eliminating the
need for a separate query round-trip.

Remove the now-unnecessary PacketTooBig struct and
encode_frame_err_with_payload helper. Add e2e tests for wire format
round-trip and router MTU enforcement.
Add PacketReceiver/PacketSender traits and a combined RX/TX worker
that handles the frame processing loop, optional liveness timeout,
and interface state management. New transports (BLE, CAN FD, ESP-NOW,
SPI) only need to implement the two traits (~10 lines each) instead
of duplicating the full worker loop.
The std feature was unconditionally enabling embassy-time via
"embassy-time/std", which pulls in embassy-executor-timer-queue
and its unresolved __embassy_time_queue_item_from_waker symbol.
This caused MSVC linker failures on Windows for tokio-based demos
that don't provide an embassy executor. Changed to "embassy-time?/std"
so the std sub-feature only activates if embassy-time is already
enabled by another feature.
run() already sets InterfaceState::Down on exit. The Drop impl now
checks whether the interface is already Down before setting it again.
@okhsunrog okhsunrog marked this pull request as ready for review March 28, 2026 16:54
@okhsunrog okhsunrog merged commit 8bb2c3f into jamesmunns:main Mar 28, 2026
13 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.

1 participant