# TCPStreamer source kind A new source kind `tcps` ("TCPStreamer") that receives a MARTe2 `TCPStreamer` DataSource, either standalone or through a shared `TCPStreamService`. ## Wire and scope - Both transports are plain UDPS framing over TCP. A standalone `TCPStreamer` (TCPSServer) sends CONFIG then DATA on connect. A `TCPStreamService` additionally requires a first client frame, `SUBSCRIBE` (type 5, payload = stream name, 1..255 bytes). - A plain server ignores `SUBSCRIBE`, so the client sends it only when a stream name is set. - One connection carries one stream. Multiplexed lists (`"a,b,c"`, stream index in `fragmentIdx`) are out of scope: a udpscope source is single-timebase. Several streams are merged server-side with `TCPStreamJoin`, which publishes an ordinary named stream. ## `deps/udpsclient`: a TCP transport mode - `udps_client_config_t` gains `use_tcp` and `stream_name`. - New `connect_tcp()`: open the TCP socket, send `SUBSCRIBE` if a stream name is set, send no `CONNECT`. No UDP socket, no keepalive ACK. - `udps_client_poll` reuses `read_tcp_frame` / `handle_packet`. - `reorder_window_s` is forced to 0 in TCP mode: TCP is ordered, so a counter gap is a server-side drop and is reported at once. - Silence timeout and reconnect delay behave as in UDP (dead server, or a stalled client the server evicted, reconnects). - The datagram tap does not fire; the packet capture stays UDP-only (`has_datagrams()` false). - Additive. Recorded in `docs/claude/build-and-run.md` as a sixth intentional upstream change. ## Source adapter and kind - `UdpsSource` takes a transport argument (`UdpsSource(cfg, Transport::Tcp)`) instead of being copied: its callbacks are identical. The TCP variant reads `server`, `port` (default 44500) and `stream`. - `src/source/tcps_kind.cpp`: kind `tcps`, display name "TCPStreamer". Form rows: Server, Port, Stream name (optional). Description: "Leave empty for a standalone TCPStreamer; name the stream for a TCPStreamService". - Identity: `host:port` or `host:port/stream`. Session naming follows the existing non-UDPS rule (`tcps-`, port 1, `source_kind=tcps`, `source_opt_*`). - Registered in `register_builtin_sources()` and `CMakeLists.txt`. ## Verification No unit suite. Extend the self-check in `src/ui_probe.cpp` with an in-process fake TCP server that sends CONFIG then DATA, and requires `SUBSCRIBE` in one mode. Probe lines assert the signals, the frame count, and the reconnect after the server closes. Baselines: exactly one build warning, no `Gtk-CRITICAL`. A smoke test against a real MARTe `TCPStreamer` if one is runnable. ## Docs README and `docs/claude/architecture.md` (Sources) describe the kind; `docs/claude/probe-readings.md` gets the new probe lines.