Code generation declares the UDP link's buffer for packets split across
buffers as a static array of max_packet_size bytes, so it is not
allocated at run time.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Enforce max_packet_size on send and receive
- Copy split packets into a buffer allocated in setup, not on the stack
- Add unit tests for the link's send and receive paths
- Explain why the broadcast socket is always enabled
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each packet is one UDP datagram, using the settings of the udp component.
The udp component now reports whether a packet was sent, and an ENOMEM
refusal from lwIP is logged at verbose level as the packet can be sent
again.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
max_packet_size was a default with a setter that code generation called
after construction, so it could be raised above the size of a link's
buffer. It is now a constructor parameter, and a link with a fixed buffer
takes the buffer as a std::span, so its size is the link's limit and the
two cannot differ.
Co-Authored-By: Claude Code <noreply@anthropic.com>
The receive buffer is sized by code generation to max_packet_size, but
set_max_packet_size() can raise the limit afterwards, and the received
bytes would then overflow the buffer. The link now takes the buffer as a
span and stops at its size too.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The test main constructs App once, and later tests and its listener use
it, so the fixture now replaces App in SetUp and constructs it again in
TearDown, instead of constructing over a live App and leaving it
destroyed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each test directory's benchmark.yaml was merged by top-level key, keeping
the first value, so when several directories added entries to one
platform component only the first directory's survived. In a combined
run the UDP link was then left out of the build and its test failed to
compile. Lists are now joined.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A fake link with a layer stacked on it checks that the bridge sends
through the top of the stack, passes a packet in one buffer to
packet_transport, and drops a packet split across buffers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
It allocated a vector for each call, which invites heap churn. Only the
tests used it; they now have a local helper.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Code generation declares the UART link's receive buffer as a static
array of max_packet_size bytes, so it is not allocated at run time
- Move the increment out of the condition in note_received_()
- Initialise the UART transmit copy buffer
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A packet interface moves packets over a channel, with a uart link and a
packet_transport platform that uses any packet interface. Later layers
stack on the same base class.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>