Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 16 additions & 10 deletions Bdd/Targets/FreeRtos/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@ QEMU's stdio UART.

SolidSyslog runs here with the portable `SolidSyslogCircularBuffer` +
`SolidSyslogFreeRtosMutex` drained by a dedicated FreeRTOS Service task,
UdpSender over FreeRTOS-Plus-TCP, the `SolidSyslogFreeRtosStaticResolver`
pinned to the QEMU slirp gateway (`10.0.2.2`), and the
`Bdd/Targets/Common/BddTargetInteractive` runner. Drive identity /
endpoint / PRIVAL fields over the UART command channel with
`set NAME VALUE`, emit N RFC 5424 datagrams with `send N`, exit cleanly
with `quit`. See [`Bdd/README.md`](../../Bdd/README.md) for how Behave
pipes these commands through `qemu-system-arm`'s stdio UART.
a `SolidSyslogSwitchingSender` wrapping a UDP sender (over
`SolidSyslogFreeRtosDatagram`) and a TCP sender (over
`SolidSyslogFreeRtosTcpStream` + `SolidSyslogStreamSender`), the
`SolidSyslogFreeRtosStaticResolver` pinned to the QEMU slirp gateway
(`10.0.2.2`), and the `Bdd/Targets/Common/BddTargetInteractive` runner.
Drive identity / endpoint / PRIVAL fields over the UART command channel
with `set NAME VALUE`, flip the active transport at runtime with
`switch udp` / `switch tcp` (routed through `BddTargetSwitchConfig`),
emit N RFC 5424 messages with `send N`, exit cleanly with `quit`. See
[`Bdd/README.md`](../../Bdd/README.md) for how Behave pipes these
commands through `qemu-system-arm`'s stdio UART.

`Common/` carries the shared infrastructure (CMSDK UART driver, newlib
syscalls, mps2-an385 linker script, startup) and `cmake/` the
Expand Down Expand Up @@ -122,9 +126,11 @@ polled `_read` / `_write` via newlib retargeting
static IPv4 of `10.0.2.15` on the QEMU slirp network, and starts the
scheduler. On link-up the IP-task event hook spawns the interactive task
(running `BddTargetInteractive_Run`) and the Service task (draining the
`SolidSyslogCircularBuffer` and pushing through the UDP sender). Each
`send N` line over the UART emits N RFC 5424 datagrams to
`{10.0.2.2, port=g_port}`.
`SolidSyslogCircularBuffer` and pushing through the
`SolidSyslogSwitchingSender`'s active inner — UDP by default, TCP after
`switch tcp`). Each `send N` line over the UART emits N RFC 5424
messages to `{10.0.2.2, port=g_port}` over whichever transport is
currently selected.

The FreeRTOS GCC ARM_CM3 port supplies `vPortSVCHandler`,
`xPortPendSVHandler`, and `xPortSysTickHandler`.
Expand Down
2 changes: 1 addition & 1 deletion Bdd/Targets/FreeRtos/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ static void InteractiveTask(void* argument)
SolidSyslog_SetErrorHandler(ErrorHandler, NULL);
SolidSyslog_Create(&config);

BddTargetInteractive_Run(&g_message, stdin, NULL, OnSet);
BddTargetInteractive_Run(&g_message, stdin, BddTargetSwitchConfig_SetByName, OnSet);

SolidSyslog_Destroy();
SolidSyslogOriginSd_Destroy();
Expand Down
1 change: 1 addition & 0 deletions Bdd/features/switching_transport.feature
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Feature: Switch transport at runtime
SwitchingSender. The --transport CLI flag sets the initial selector
value, and the interactive `switch` command updates it at runtime.

@udp @tcp
Scenario: Switch from UDP to TCP mid-run delivers via both
Given the syslog oracle is running
And the BDD target is running with default transport udp
Expand Down
3 changes: 2 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -329,8 +329,9 @@ live under `Core/Interface/`; platform-specific helpers (the `SolidSyslogPosix*`
| `SolidSyslogFreeRtosDatagram.h` | System setup code on FreeRTOS targets using FreeRTOS-Plus-TCP for UDP | `SolidSyslogFreeRtosDatagramStorage`, `SOLIDSYSLOG_FREERTOSDATAGRAM_SIZE`, `SolidSyslogFreeRtosDatagram_Create(storage)`, `_Destroy(datagram)` (wraps `FreeRTOS_socket` / `FreeRTOS_sendto` / `FreeRTOS_closesocket`) |
| `SolidSyslogStream.h` | Sender implementors using stream transport | `SolidSyslogStream_Open`, `_Send`, `_Read`, `_Close`, `SolidSyslogSsize` |
| `SolidSyslogStreamDefinition.h` | Stream implementors (extension point) | `SolidSyslogStream` vtable struct (`Open`, `Send`, `Read`, `Close`) |
| `SolidSyslogFreeRtosTcpStream.h` | System setup code on FreeRTOS targets using FreeRTOS-Plus-TCP for TCP | `SolidSyslogFreeRtosTcpStreamStorage`, `SOLIDSYSLOG_FREERTOSTCPSTREAM_SIZE`, `SolidSyslogFreeRtosTcpStream_Create(storage)`, `_Destroy(stream)` (wraps `FreeRTOS_socket` / `FreeRTOS_connect` / `FreeRTOS_send` / `FreeRTOS_recv` / `FreeRTOS_closesocket`; bounded blocking connect via `SO_SNDTIMEO=200ms`, cleared post-connect so Send/Read are non-blocking) |
| `SolidSyslogUdpSender.h` | System setup code using UDP transport | `SolidSyslogUdpSenderConfig` (resolver, datagram, endpoint, endpointVersion), `SolidSyslogUdpSender_Create`, `_Destroy` |
| `SolidSyslogStreamSender.h` | System setup code using octet-framed transport (RFC 6587) over any Stream — `SolidSyslogPosixTcpStream` (POSIX TCP), `SolidSyslogWinsockTcpStream` (Windows TCP), `SolidSyslogTlsStream` (TLS; OpenSSL reference integration), or a caller-supplied Stream backend | `SolidSyslogStreamSenderConfig` (resolver, stream, endpoint, endpointVersion), `SolidSyslogStreamSender_Create`, `_Destroy` |
| `SolidSyslogStreamSender.h` | System setup code using octet-framed transport (RFC 6587) over any Stream — `SolidSyslogPosixTcpStream` (POSIX TCP), `SolidSyslogWinsockTcpStream` (Windows TCP), `SolidSyslogFreeRtosTcpStream` (FreeRTOS-Plus-TCP), `SolidSyslogTlsStream` (TLS; OpenSSL reference integration), or a caller-supplied Stream backend | `SolidSyslogStreamSenderConfig` (resolver, stream, endpoint, endpointVersion), `SolidSyslogStreamSender_Create`, `_Destroy` |
| `SolidSyslogSwitchingSender.h` | System setup code composing multiple inner senders | `SolidSyslogSwitchingSenderConfig` (senders, senderCount, selector), `SolidSyslogSwitchingSenderSelector`, `SolidSyslogSwitchingSender_Create`, `_Destroy` |
| `SolidSyslogBuffer.h` | Library internals consuming a buffer (Service algorithm) | `SolidSyslogBuffer_Write`, `_Read` |
| `SolidSyslogBufferDefinition.h` | Buffer implementors (extension point) | `SolidSyslogBuffer` vtable struct |
Expand Down
56 changes: 56 additions & 0 deletions DEVLOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,61 @@
# Dev Log

## 2026-05-11 — S08.11 switching_transport BDD scenario (UDP↔TCP) on QEMU (#340)

Third and final slice of S08.06. With the TCP stream (S08.09) and TCP
reconnect verification (S08.10) in place, this slice lights up the
runtime `switch` command in the FreeRTOS BDD target and admits the
non-`@tls` `switching_transport.feature` scenario to the QEMU runner.

### Decisions

- **Wire `BddTargetSwitchConfig_SetByName` as the `onSwitch` callback,
not just `set transport`.** S08.09 already routed `set transport
<udp|tcp>` through `BddTargetSwitchConfig`, so the harness could
flip the initial transport via `--transport tcp` translated to a
`set transport tcp` UART line. The runtime `switch tcp` command
path is a separate dispatch in `BddTargetInteractive.c` — guarded
on `onSwitch != NULL`, so leaving `onSwitch = NULL` meant `switch
tcp` from the BDD step `the client switches to transport tcp`
silently no-op'd. Passing `BddTargetSwitchConfig_SetByName` lines
the FreeRTOS target up with Linux (`Bdd/Targets/Linux/main.c:286`)
and Windows (`Bdd/Targets/Windows/BddTargetWindows.c:357`), which
already pass it.
- **Tag the non-`@tls` scenario `@udp @tcp` at the scenario level,
not the feature level.** The feature is feature-level `@buffered`
only — invisible to the FreeRTOS `(@udp or @tcp)` admission clause.
The `@tls` sibling must stay excluded until S08.07 lands TLS on
FreeRTOS, so feature-level `@tcp` would over-admit. Scenario-level
`@udp @tcp` on the first scenario keeps the second one out without
restructuring the docker-compose filter.
- **No new unit tests.** Pure wiring: the only code change is the
callback argument at the `BddTargetInteractive_Run` call site, and
`BddTargetSwitchConfig_SetByName` is the same function the existing
`set transport` path in `OnSet` already calls. The end-to-end
`switching_transport.feature` scenario is the test for the dispatch.

### Deferred

- **TLS switching scenario (`@tls`-tagged second scenario of
`switching_transport.feature`)** — S08.07 (#272).
- **Unit test for the `BddTargetInteractive` `switch` dispatch.** The
`onSwitch` slot was added in the S20.x SwitchingSender stories
without a paired unit test in `BddTargetInteractiveTest`; the
existing tests cover the `set` path only. Out of scope here (pure
wiring story) but worth a hygiene follow-up — every other dispatch
in this file is pinned, so `switch`'s absence is the odd one out.
- **CMake-driven memory scaling** still open from S08.09 — memory
`project_freertos_stack_budget`. The S08.09 `INTERACTIVE_TASK_
STACK_DEPTH = configMINIMAL_STACK_SIZE * 48U` already carries the
SwitchingSender + TCP path overhead, so no further bump here.

### Open questions

- None new. The S08.10 question about the 200ms SO_SNDTIMEO cap
potentially starving the Service task during outage is unrelated
to switching; CI is the arbiter and the answer is "raise the
deadline if it flakes" per `feedback_no_flaky_ci`.

## 2026-05-11 — S08.10 tcp_reconnect BDD scenario on QEMU (#339)

Second slice of S08.06. The reconnect-on-the-wire is already a property
Expand Down
3 changes: 3 additions & 0 deletions ci/docker-compose.bdd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ services:
# marks features that need a file-backed store (no FreeRTOS file
# abstraction yet), while plain @buffered just means "uses the long-lived
# interactive process" and is supported on FreeRTOS via QEMU's UART.
# S08.11 tags the non-@tls switching_transport scenario @udp @tcp so the
# existing (@udp or @tcp) clause admits it; the @tls sibling stays
# excluded until S08.07 lights up TLS on FreeRTOS.
# @windows_wip excludes the Windows-only TCP singletask variant.
command: behave --junit --junit-directory Bdd/junit --tags='not @wip and not @freertoswip and not @rtc and not @store and not @windows_wip and (@udp or @tcp)' Bdd/features/

Expand Down
Loading