Add SERIAL_PROXY_PORT_TYPE_USB_SERIAL, derived automatically when a
port's uart_id resolves to a usb_uart channel (never set by the user),
and a SerialProxyGetUsbInfoRequest/Response pair (IDs 153/154) that
reads VID/PID/bcdDevice and the manufacturer/product/serial strings
live from the descriptors the USB host stack caches, so a client can
identify the attached device before subscribing. Ports that are not
USB_SERIAL answer NOT_SUPPORTED; an unplugged device answers with
connected=false. ZigbeeProxyRequest moves to ID 155 (expected merge
order: set_mode, USB info, zigbee).
The boot mode had no coherent job left: before any subscriber the tap
is served via tap_needs_port() regardless of mode, 1.17+ clients select
the mode explicitly after subscribing, and the only remaining effect
was arming the tap for a first-session client that never asked for it
and could not turn it off. The mode is now purely a session property
of the API: ports always boot RAW.
Also polish the tap contract per review: expose tap_is_observed(),
return false from write_from_tap() when the bytes are dropped, and
document that tap_pump() must not be called from tap callbacks.
- Refuse PROTOCOL with NOT_SUPPORTED when the port has no tap, so a
client cannot mistake a plain pipe for an active tap
- Skip tap_pump() when neither the tap nor a subscriber would receive
the bytes, instead of draining the FIFO into the void
- Rename the client-facing overload to set_mode_from_client, matching
write_from_client
- Document that PORT_IN_USE also covers callers that never subscribed,
and that the YAML mode applies only until the first session ends
Address review findings:
- Only the live subscriber may set the mode, so a mode set by a client
that never subscribes cannot persist past its session
- With a subscriber attached, the mode alone decides whether the tap is
served; tap_needs_port() bypasses it only while the port is unheld,
and write_from_tap() is gated the same way, so RAW is inert by code
- The explicit UNSUBSCRIBE path keeps the loop alive for a tap that
still needs the port, mirroring the disconnect path in loop()
- Mode values from the wire are validated; unknown values are refused
with INVALID_ARGUMENT instead of stored and acknowledged OK
- Add a test variant that defines USE_SERIAL_PROXY_TAP so the tap code
paths compile in a real build
Follow the acknowledgement pattern from #18312: set_mode now returns a
SerialProxyResult and the handler answers with SerialProxyRequestResponse
(type SET_MODE). This matters most for a client switching to RAW before
flashing firmware through the port: without an ack, a refused request
(another client holds the port) is silently dropped and the client cannot
tell that protocol bytes may still be injected.
Add SerialProxyTap, a protocol-agnostic observer interface that lets a
companion component watch the bytes flowing through a proxied port and
inject bytes of its own (protocol acknowledgements, for example) without
owning the port. The tap machinery is compiled in only when a tap
component defines USE_SERIAL_PROXY_TAP, so ports without one pay nothing.
Add a per-port mode (RAW or PROTOCOL) with a matching API message so
clients control whether the tap is active. The mode belongs to the client
session: it resets to RAW whenever the subscriber disconnects, and RAW is
guaranteed inert so a client can flash firmware through the port without
protocol bytes being injected. Bumps the API minor version to 17.
Co-Authored-By: puddly <32534428+puddly@users.noreply.github.com>
Rename SERIAL_PROXY_MODE_EZSP_ASH to SERIAL_PROXY_MODE_PROTOCOL so the
serial_proxy API surface carries no protocol-specific names. The mode now
means "the port's tap is active"; which protocol the tap speaks is a
property of the device configuration, discoverable from the tap
component's own API surface. Future protocol taps need no serial_proxy
or API changes.
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick+github@koston.org>