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.
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
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>
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>