Skip to content

feat: S08.07 FreeRTOS BDD target — TLS via mbedTLS#421

Merged
DavidCozens merged 15 commits into
mainfrom
feat/s08.07-bdd-mbedtls
May 22, 2026
Merged

feat: S08.07 FreeRTOS BDD target — TLS via mbedTLS#421
DavidCozens merged 15 commits into
mainfrom
feat/s08.07-bdd-mbedtls

Conversation

@DavidCozens

@DavidCozens DavidCozens commented May 21, 2026

Copy link
Copy Markdown
Owner

Purpose

Closes #272. Lights up the TLS slot on the FreeRTOS QEMU BDD target via SolidSyslogMbedTlsStream over SolidSyslogFreeRtosTcpStream, and registers the Mbed TLS reference adapter across the documentation set (CLAUDE.md row, IEC 62443 SL4 section, RFC 5425 compliance matrix, new docs/integrating-mbedtls.md integrator guide).

Change Description

Slice 6a + 6b (already on branch from earlier work): mbedTLS as a cross-compile subproject; integrator overrides in mbedtls_user_config.h; demo CA + client cert + client key PEMs baked into the ELF via xxd -i; weak demo-entropy callback + CTR_DRBG seed; PEM-to-handle parsing; full FreeRtosTcpStream → MbedTlsStream → StreamSender composition.

Slice 6c — TLS bring-up (this session):

  • mbedTLS allocations routed to the FreeRTOS heap via MBEDTLS_PLATFORM_MEMORY + mbedtls_platform_set_calloc_free(pvPortMalloc, vPortFree). mbedTLS's default libc calloc was funnelling through newlib's 4 KiB syscall heap and failing every mbedtls_ssl_setup with MBEDTLS_ERR_SSL_ALLOC_FAILED.
  • PSA crypto's randomness wired via MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG + an mbedtls_psa_external_get_random hook that wraps the same CTR_DRBG the classic API uses. mbedTLS 3.6's TLS 1.3 path needs psa_crypto_init() to succeed, and PSA's built-in entropy collector returns PSA_ERROR_INSUFFICIENT_ENTROPY on MBEDTLS_NO_PLATFORM_ENTROPY targets. psa_crypto_init() is now called after the DRBG is seeded.
  • MBEDTLS_SSL_IN_CONTENT_LEN shrunk to 4096, OUT to 2048 (from the 16 KiB default) to keep the per-context working set tight on the FreeRTOS heap.

Slice 6c — dual-mode TLS/mTLS dispatch:

  • BddTargetSwitchConfig gains IsMtlsMode(); set transport tls|mtls over UART sets a shared bool. Both modes route through BDD_TARGET_SWITCH_TLS.
  • BddTargetTlsSender_MbedTls_FreeRtosTcp wires the client cert + key unconditionally and dispatches the Endpoint callback at Connect time — port 6514 for TLS, 6515 for mTLS. One TLS sender / one TLS stream / one TCP socket serve both modes.
  • ci/docker-compose.bdd.yml admits @mtls in the freertos behave filter.

Slice 6c — capacity_threshold.feature admitted on FreeRTOS:

  • OnThresholdCrossed prints a line-anchored [THRESHOLD-CROSSED] token to UART; _threshold_marker_present(context) in syslog_steps.py accepts either the host marker file (POSIX / Windows binaries) or the token in the captured stdout buffer (FreeRTOS). Single cross-target assertion.
  • set capacity-threshold N handler added to FreeRTOS OnSet; --capacity-threshold translation entry added to the FreeRTOS UART flag table.
  • @freertoswip dropped from the feature.

CodeRabbit review fixes:

  • Error-checked the five fail-able mbedTLS init calls (ctr_drbg_seed, psa_crypto_init, two x509_crt_parse, pk_parse_key) and surfaced each failure as a one-line [mbedtls] … FAILED rc=… diagnostic with early return — replaces the silent (void) casts.
  • Adding the error check revealed a latent bug — DemoEntropySource was registered as MBEDTLS_ENTROPY_SOURCE_WEAK, so mbedtls_entropy_func never satisfied its strong_size >= MBEDTLS_ENTROPY_BLOCK_SIZE check and ctr_drbg_seed had always been returning ENTROPY_SOURCE_FAILED (-0x0034). Earlier handshakes "worked" because mbedtls_ctr_drbg_random against the half-seeded context produced deterministic-but-consistent bytes that syslog-ng accepted from its end of the handshake. Fixed by relabeling the demo source MBEDTLS_ENTROPY_SOURCE_STRONG; the audit-trail "demo-only entropy" printf at the end of EnsureMbedTlsInitialised is the real quality assertion.
  • BddTargetTlsSender_Destroy() + tlsSender = NULL added to TeardownAll — the inner pool slots were leaking on shutdown.
  • Stale comments around the TLS sender setup refreshed to describe the dispatcher that shipped.

Slice 7 — documentation sweep:

  • New docs/integrating-mbedtls.md — practical integrator guide structured around two scenarios ("you already have Mbed TLS in your image" / "you don't have Mbed TLS yet"). Covers the byte-transport choice, the config struct, the coexistence contract (auditable not-touched list), and the FreeRTOS-specific gotchas as a labelled integrator checklist.
  • CLAUDE.mdSolidSyslogMbedTlsStream.h row added to the Public-Header-Audiences table; StreamSender row enumerates the Mbed TLS adapter as a TLS-capable Stream backend.
  • docs/iec62443.md — new ### Embedded SL4 subsection mapping the Mbed TLS adapter to the same CR 1.5 / CR 1.8 / CR 2.12 / CR 3.9 controls as the OpenSSL substrate. SL4 setup-recipe lists both adapters as alternatives.
  • docs/rfc-compliance.md — RFC 5425 section table widened from OpenSSL-only to per-row "OpenSSL: … / Mbed TLS: …" coverage.

Long-form narrative of the bring-up is in DEVLOG.md.

Test Evidence

Local — FreeRTOS QEMU BDD suite (full):

  • 42 scenarios pass / 0 fail / 7 skipped (only remaining @freertoswip is the oversize-UTF-8 MTU scenario, unreachable because FreeRTOS SOLIDSYSLOG_MAX_MESSAGE_SIZE = 512 is below the path MTU)
  • Includes tls_transport.feature (both @tls and @tls13 scenarios), mtls_transport.feature, switching_transport.feature (TCP → TLS mid-run), capacity_threshold.feature (both threshold-fired and threshold-not-fired scenarios), tcp_reconnect.feature, store_*.feature, power_cycle_replay.feature.

Local — Linux: capacity_threshold.feature still passes via the host marker-file path.

CI: see the latest run on this PR.

Areas Affected

  • Bdd/Targets/Common/BddTargetTlsSender_MbedTls_FreeRtosTcp.c — error-checked init, STRONG entropy label, FreeRTOS heap-routed calloc, PSA external RNG hook, dispatcher endpoint callbacks.
  • Bdd/Targets/Common/BddTargetSwitchConfig.{c,h}IsMtlsMode() accessor.
  • Bdd/Targets/FreeRtos/main.ctlsSender destroy in TeardownAll, OnThresholdCrossed callback (UART marker), set capacity-threshold OnSet handler, refreshed comment block.
  • Bdd/Targets/FreeRtos/mbedtls_user_config.h — PLATFORM_MEMORY, PSA_CRYPTO_EXTERNAL_RNG, SSL_IN/OUT_CONTENT_LEN.
  • Bdd/features/capacity_threshold.feature@freertoswip removed; comment block describes the dual-channel marker.
  • Bdd/features/steps/syslog_steps.py_threshold_marker_present(context) helper; both threshold steps route through it.
  • Bdd/features/steps/target_driver.py--capacity-threshold UART translation entry.
  • ci/docker-compose.bdd.yml@mtls admitted in the freertos filter; capacity_threshold scope comment updated.
  • CLAUDE.md, docs/integrating-mbedtls.md (new), docs/iec62443.md, docs/rfc-compliance.md, DEVLOG.md.

No changes to Platform/MbedTls/Source/ — the coexistence contract (no process-global Mbed TLS calls in the adapter) is intact and auditable by grep.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added TLS and mTLS transport support for FreeRTOS target
    • Added capacity threshold callback functionality for FreeRTOS
  • Documentation

    • Added integration guide for embedded TLS implementation
    • Updated RFC 5425 and IEC 62443 compliance documentation
  • Tests

    • Extended FreeRTOS test scenarios to include TLS and mTLS transports
    • Improved FreeRTOS test timeout configuration
  • Infrastructure

    • Updated Docker container images across development and CI environments
    • Updated devcontainer configuration

Review Change Stack

Compile and link mbedTLS into the FreeRTOS QEMU BDD ELF. No behaviour yet
beyond proving the build stack is healthy — the new TlsSender wrapper
returns a no-op SolidSyslogSender so the linker has something to satisfy
its eventual call site in slice 6b without yet pulling mbedTLS into the
reachable graph (--gc-sections drops all of mbedTLS for now).

- Add Platform/MbedTls sources to the FreeRTOS executable so future
  MbedTlsStream_Create from main.c will reach them.
- Pull mbedTLS upstream into the cross build via add_subdirectory with
  the same EXCLUDE_FROM_ALL + -w + tidy/cppcheck-disabled pattern used
  by Tests/MbedTlsIntegration/CMakeLists.txt. Three new file-scope
  variables in the new CMake section (ENABLE_PROGRAMS, ENABLE_TESTING,
  MBEDTLS_FATAL_WARNINGS) force-OFF the upstream demo binaries and
  tests we never want in our build.
- Bdd/Targets/FreeRtos/mbedtls_user_config.h: integrator overrides
  wired via MBEDTLS_USER_CONFIG_FILE. Disable the upstream code paths
  that assume a Unix/Windows host — platform entropy (Cortex-M3 has
  no /dev/urandom; slice 6b will register a weak entropy callback),
  filesystem IO (PEMs are baked into the ELF), BSD sockets (our own
  transport via mbedtls_ssl_set_bio), system clock (no RTC, baked
  certs carry 2024–2099 validity), threading hooks (per the customer-
  coexistence contract), PSA on-filesystem storage, and the timing
  helpers (the adapter manages its own bounded handshake retry).
- Add BddTargetTlsSender_MbedTls_FreeRtosTcp.c as a same-shape
  parallel to BddTargetTlsSender_OpenSsl_PosixTcp.c. Slice 6a
  placeholder returns a no-op sender; slice 6b composes the real
  FreeRtosTcpStream + MbedTlsStream + StreamSender stack.
- Commit the .devcontainer/devcontainer.json swap to freertos-target
  (ARM cross + QEMU + GDB + Behave), the container that this slice
  and the rest of slice 6 are developed in.

The container image's xxd dependency for slice 6b's PEM baking is
already pushed to ghcr; the in-repo SHA bump lands as part of 6b.
Adds xxd to the host + cross images (CppUTestFreertosDocker commit
d364407 → 1cb0f34 after merge). xxd is consumed by slice 6b's CMake to
bake demo CA / client cert / client key PEMs into the FreeRTOS BDD ELF
via `xxd -i` — there's no filesystem path from the host into QEMU, so
the PEMs travel as static const arrays in rodata and feed straight into
mbedtls_x509_crt_parse / _pk_parse_key.

Both cpputest-freertos (host TDD) and cpputest-freertos-cross (cross
build, QEMU, behave) get bumped together per docs/containers.md
("always update both rows together").
…target

The FreeRTOS QEMU BDD target now has a working TLS path. mbedTLS pulls
into the reachable graph (--gc-sections no longer drops it: text 125 KB
→ 642 KB) and the switching sender's slot 2 is wired to the new mbedTLS
stack instead of falling through to NullSender.

- CMake bakes Bdd/syslog-ng/tls/{ca,client}.pem + client.key into
  generated headers via xxd -i (cat-then-NUL trick deliberately not
  used; the wrapper TU does the NUL-terminate copy at parse time
  instead).
- BddTargetTlsSender_MbedTls_FreeRtosTcp.c owns the full TLS stack
  composition: entropy + CTR_DRBG seed (one-shot, idempotent),
  baked-PEM parse to mbedtls_x509_crt + mbedtls_pk_context handles,
  and the FreeRtosTcpStream + MbedTlsStream + StreamSender chain.
  Diagnostic printfs and vTaskDelay(1) yields surround each major
  init step — QEMU emulates Cortex-M3 at host speed, but cert/key
  parses can still take seconds, and the yields keep lower-priority
  tasks alive instead of starving them through a multi-second
  monopoly of the service-thread.
- Boot diagnostics use printf rather than SolidSyslog_Error because
  main installs the error handler AFTER BddTargetTlsSender_Create
  runs; the default no-op handler would otherwise swallow the WARNING
  that documents the demo-only entropy.
- Slice 6b ships TLS-only (mtls=false) in main.c. The FreeRTOS
  BDD-harness command flow has the tls/mtls choice arrive over the
  UART AFTER boot, so mTLS support either needs a fourth switching-
  sender slot, a runtime endpoint-dispatch shim, or boot-time
  configuration. Picked up in slice 6c.

Smoke-tested under QEMU mps2-an385: target boots cleanly, mbedTLS
init prints emit in <3s, interactive prompt appears, no regression
on the existing UDP/TCP slots.
…imeout

- ci/docker-compose.bdd.yml: behave-freertos tag filter now admits @tls
  (was excluded with a "until S08.07 lights up TLS on FreeRTOS" note).
  @Mtls is excluded by virtue of not matching the (@udp or @tcp or @tls)
  clause — its dual-mode dispatch over the switching sender is still
  outstanding under slice 6c.
- Bdd/features/steps/syslog_steps.py: wait_for_prompt default bumped
  30s -> 120s. Linux + Windows native still complete in under a second
  so the change is invisible there; FreeRTOS QEMU first-boot has to
  parse the baked mbedTLS RSA client key plus bring up Plus-TCP's IP
  task, and the local smoke test measured ~60s to reach the prompt.
  Recorded in [[feedback-qemu-bdd-timeouts-generous]] so future QEMU
  deadline choices default to "budget for QEMU first" rather than
  reusing host integration numbers.

CI's bdd-freertos-qemu now drives the real end-to-end TLS handshake
against the syslog-ng oracle (port 6514, demo CA / server cert from
Bdd/syslog-ng/tls/, baked into the ELF via xxd -i in slice 6b).
@DavidCozens

Copy link
Copy Markdown
Owner Author

@coderabbitai pause

@coderabbitai

coderabbitai Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@DavidCozens has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 29 minutes and 25 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fe692aae-50ed-49aa-b009-dd7fe3125514

📥 Commits

Reviewing files that changed from the base of the PR and between 4b0f67d and b8e3113.

📒 Files selected for processing (4)
  • Bdd/Targets/Common/BddTargetTlsSender_MbedTls_FreeRtosTcp.c
  • Bdd/Targets/FreeRtos/main.c
  • ci/docker-compose.bdd.yml
  • docs/integrating-mbedtls.md
📝 Walkthrough

Walkthrough

This PR completes FreeRTOS TLS/mTLS support via mbedTLS by adding the transport sender implementation, FreeRTOS build system integration with certificate baking, runtime switching infrastructure, capacity threshold callback signaling, and comprehensive documentation. Container images, CI jobs, and devcontainer references are updated to reflect new build tooling.

Changes

FreeRTOS mbedTLS Integration

Layer / File(s) Summary
TLS vs mTLS Mode Configuration
Bdd/Targets/Common/BddTargetSwitchConfig.c, Bdd/Targets/Common/BddTargetSwitchConfig.h
New mtlsMode flag tracks whether selected transport operates as TLS or mTLS. BddTargetSwitchConfig_SetByName sets the flag for each transport, and public accessor BddTargetSwitchConfig_IsMtlsMode() enables endpoint dispatch branching at send time.
mbedTLS Build System and FreeRTOS Configuration
Bdd/Targets/FreeRtos/CMakeLists.txt, Bdd/Targets/FreeRtos/mbedtls_user_config.h
Validates MBEDTLS_SOURCE_DIR, integrates mbedTLS as CMake subproject, disables platform entropy/filesystem/sockets/threading, enables integrator-provided calloc/free and external RNG, defines PEM baking via xxd -i at build time, and links executable against mbedTLS libraries with reduced TLS record buffer sizes.
FreeRTOS TLS Sender with mbedTLS Stack
Bdd/Targets/Common/BddTargetTlsSender_MbedTls_FreeRtosTcp.c
Implements complete TLS sender with FreeRTOS allocation hooks, PSA external RNG callback, demo entropy source, idempotent one-time mbedTLS initialization with parsed baked CA/cert/key, endpoint selection helpers, sender creation/destruction with persistent state across reconnects.
Runtime Transport Switching
Bdd/Targets/FreeRtos/main.c
Includes TLS sender header, creates file-scope TLS sender handle, extends switching array to BDD_TARGET_SWITCH_COUNT elements with TLS assigned to appropriate slot, and ensures TLS sender is destroyed before TCP resources during teardown.

Capacity Threshold Callback Feature

Layer / File(s) Summary
Capacity Threshold Runtime Configuration
Bdd/Targets/FreeRtos/main.c
Extends interactive command parser to accept set capacity-threshold <n>, implements OnThresholdCrossed callback that emits [THRESHOLD-CROSSED] UART marker, and wires callback into file-backed block store config.
Capacity Threshold BDD Testing
Bdd/features/capacity_threshold.feature, Bdd/features/steps/syslog_steps.py, Bdd/features/steps/target_driver.py
Removes @freertoswip exclusion to enable FreeRTOS testing, introduces _threshold_marker_present helper that detects threshold via marker file or captured UART token, and maps --capacity-threshold CLI flag to FreeRTOS UART command.

Infrastructure and Documentation

Layer / File(s) Summary
Container Image and CI Workflow Updates
.devcontainer/devcontainer.json, .devcontainer/docker-compose.yml, .github/workflows/ci.yml, ci/docker-compose.bdd.yml, docs/containers.md
Updates container image SHAs to sha-1cb0f34 across devcontainer, docker-compose, and CI workflows; switches active devcontainer service to freertos-target; extends BDD test harness to include @tls and @mtls scenario tags for FreeRTOS.
BDD Harness Timeout Configuration
Bdd/features/steps/syslog_steps.py
Increases wait_for_prompt default timeout from 30s to 120s to accommodate slower FreeRTOS QEMU boot; docstring reflects different performance characteristics between native and QEMU targets.
mbedTLS Integration Documentation
docs/integrating-mbedtls.md
Comprehensive guide covering adapter positioning, coexistence contract with existing mbedTLS integrations, handle-based configuration model, integrator setup sequencing, FreeRTOS-specific heap/entropy/allocation concerns, failure-mode troubleshooting, and out-of-scope responsibilities.
Compliance and API Reference
docs/iec62443.md, docs/rfc-compliance.md, CLAUDE.md, DEVLOG.md
Adds SolidSyslogMbedTlsStream to IEC 62443 SL4 compliance guide and RFC 5425 TLS compliance documentation; updates CLAUDE.md public header index; documents S08.07 closure and TLS/mTLS dispatch design in DEVLOG.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

  • DavidCozens/solid-syslog#10: This PR directly implements Story S08.07 (TLS via mbedTLS on FreeRTOS) of the parent FreeRTOS demo epic, completing the full TLS/mTLS integration architecture with certificate handling, entropy seeding, and runtime switching.

Possibly related PRs

  • DavidCozens/solid-syslog#344: Both PRs extend BddTargetSwitchConfig_SetByName transport selection logic; this PR adds the mtlsMode flag and dispatch branching, while the related PR wires that config into runtime command handling.
  • DavidCozens/solid-syslog#341: Both PRs modify FreeRTOS main.c switching sender wiring; this PR adds TLS sender integration and BDD_TARGET_SWITCH_COUNT array expansion, while the related PR establishes the base switching config infrastructure.
  • DavidCozens/solid-syslog#351: Both PRs bump pinned ghcr.io/davidcozens/cpputest-freertos(-cross) container image SHAs in devcontainer and CI workflows to sha-1cb0f34.

Poem

🐰 A rabbit hops through FreeRTOS now,
With TLS certs all baked and bow,
mbedTLS threads that entropy weave,
QEMU capacity—mark when we grieve,
Syslog sings encrypted and free!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.91% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title correctly identifies the primary change: enabling TLS on FreeRTOS QEMU BDD target via mbedTLS, matching the main objective of issue #272.
Description check ✅ Passed The PR description comprehensively covers Purpose (closing #272), Change Description (detailed slices 6a-6c with specific fixes), Test Evidence (42 scenarios pass), and Areas Affected.
Linked Issues check ✅ Passed The PR fulfills all coding objectives from issue #272: mbedTLS adapter implementation, coexistence contract, FreeRTOS target wiring with demo PEMs, dual-mode TLS/mTLS dispatch, error-checked initialization, external RNG hook, capacity_threshold.feature admission, and complete documentation updates.
Out of Scope Changes check ✅ Passed All changes directly support the stated objective of implementing TLS via mbedTLS on FreeRTOS QEMU BDD target. Docker image SHA updates, CI workflow updates, and documentation additions are all in-scope for this feature implementation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/s08.07-bdd-mbedtls

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai

coderabbitai Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Reviews paused.

@github-actions

Copy link
Copy Markdown
Contributor

☀️   Quality Summary

   🚦   build-linux-gcc: 100% successful (✔️ 1286 passed, 🙈 2 skipped)
   🚦   build-freertos-host-tdd: 100% successful (✔️ 1508 passed, 🙈 2 skipped)
   🚦   build-linux-clang: 100% successful (✔️ 1238 passed, 🙈 2 skipped)
   🚦   sanitize-linux-gcc: 100% successful (✔️ 1238 passed, 🙈 2 skipped)
   🚦   integration-linux-openssl: 100% successful (✔️ 9 passed)
   🚦   integration-linux-mbedtls: 100% successful (✔️ 7 passed)
   🚦   integration-windows-openssl: 100% successful (✔️ 9 passed)
   🚦   bdd-linux-syslog-ng: 94% successful (✔️ 46 passed, 🙈 3 skipped)
   🚦   bdd-windows-otel: 90% successful (✔️ 44 passed, 🙈 5 skipped)
   🚦   bdd-freertos-qemu: 73% successful (❌ 3 failed, ✔️ 36 passed, 🙈 10 skipped)
   🚦   build-windows-msvc: 100% successful (✔️ 1127 passed, 🙈 1 skipped)
   🚦   build-linux-tunable-override: 100% successful (✔️ 1238 passed, 🙈 2 skipped)
   ⚠️   Clang-Tidy: 1 warning (normal: 1)
   ⚠️   CPPCheck: No warnings


Created by Quality Monitor v1.14.0 (#f3859fd). More details are shown in the GitHub Checks Result.

…eds on FreeRTOS

Two missing integrator-side init steps were sinking every TLS handshake on
the QEMU mps2-an385 BDD target. Both surface as opaque mbedTLS errors:

1. mbedtls_ssl_setup returned MBEDTLS_ERR_SSL_ALLOC_FAILED (-0x7F00).
   mbedTLS calls libc calloc, which on newlib routes through _sbrk into the
   4 KiB syscall heap in Bdd/Targets/FreeRtos/Common/Syscalls.c — far too
   small for a single TLS context. Defined MBEDTLS_PLATFORM_MEMORY in the
   user config and added mbedtls_platform_set_calloc_free wired to
   pvPortMalloc / vPortFree so allocations land in the 96 KiB FreeRTOS
   heap_4 region — the standard FreeRTOS+mbedTLS integration.

2. mbedtls_ssl_handshake then returned MBEDTLS_ERR_ERROR_GENERIC_ERROR
   (-0x0001) at the first state transition with no BIO traffic. mbedTLS
   3.6's TLS 1.3 path drives PSA crypto, and PSA's built-in entropy
   collector returns PSA_ERROR_INSUFFICIENT_ENTROPY (-148) on
   MBEDTLS_NO_PLATFORM_ENTROPY targets. Defined
   MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG, provided
   mbedtls_psa_external_get_random that feeds PSA from the same CTR_DRBG
   the classic API uses, and call psa_crypto_init() AFTER seeding the DRBG
   so the first PSA op has a working source.

Also shrunk MBEDTLS_SSL_IN_CONTENT_LEN to 4096 and OUT to 2048 (from the
16 KiB default) — comfortable for the BDD oracle's cert chain + the
messages we send, and frees ~28 KiB per context for FreeRTOS-Plus-TCP
socket buffers and the SolidSyslog tasks.

Local: 39/39 freertos BDD scenarios pass, including both @tls and the
@tls13 scenario. No changes under Platform/MbedTls/, so the customer
coexistence contract is intact.
@github-actions

Copy link
Copy Markdown
Contributor

☀️   Quality Summary

   🚦   build-linux-gcc: 100% successful (✔️ 1286 passed, 🙈 2 skipped)
   🚦   build-freertos-host-tdd: 100% successful (✔️ 1508 passed, 🙈 2 skipped)
   🚦   build-linux-clang: 100% successful (✔️ 1238 passed, 🙈 2 skipped)
   🚦   sanitize-linux-gcc: 100% successful (✔️ 1238 passed, 🙈 2 skipped)
   🚦   integration-linux-openssl: 100% successful (✔️ 9 passed)
   🚦   integration-linux-mbedtls: 100% successful (✔️ 7 passed)
   🚦   integration-windows-openssl: 100% successful (✔️ 9 passed)
   🚦   bdd-linux-syslog-ng: 94% successful (✔️ 46 passed, 🙈 3 skipped)
   🚦   bdd-windows-otel: 90% successful (✔️ 44 passed, 🙈 5 skipped)
   🚦   bdd-freertos-qemu: 80% successful (✔️ 39 passed, 🙈 10 skipped)
   🚦   build-windows-msvc: 100% successful (✔️ 1127 passed, 🙈 1 skipped)
   🚦   build-linux-tunable-override: 100% successful (✔️ 1238 passed, 🙈 2 skipped)
   ⚠️   Clang-Tidy: 1 warning (normal: 1)
   ⚠️   CPPCheck: No warnings


Created by Quality Monitor v1.14.0 (#f3859fd). More details are shown in the GitHub Checks Result.



The FreeRTOS BDD target spawns the TLS sender once at boot — before the
behave harness has sent `set transport tls` / `set transport mtls` over
the UART — so the per-startup `mtls` flag that the POSIX and Windows
targets read from argv can't reach this Create call in time. Resolve by
sharing one TLS sender / TLS stream / TCP socket across both modes and
dispatching the destination port at Connect time:

  - BddTargetSwitchConfig gains an mtlsMode bool tracked by SetByName and
    exposed via BddTargetSwitchConfig_IsMtlsMode(). `tls` clears it, `mtls`
    sets it, both route through BDD_TARGET_SWITCH_TLS.
  - BddTargetTlsSender_MbedTls_FreeRtosTcp wires the client cert+key
    unconditionally (syslog-ng's plain-TLS listener accepts an optional
    client cert harmlessly, and its mTLS listener requires one), then
    plumbs DispatchEndpoint / DispatchEndpointVersion as the StreamSender
    Endpoint pair. Those read IsMtlsMode at each Connect call and pick
    between BddTargetTlsConfig (port 6514) and BddTargetMtlsConfig (port
    6515). The `mtls` parameter on the wrapper's Create signature is
    retained for cross-platform contract uniformity but ignored.
  - ci/docker-compose.bdd.yml admits @Mtls in the freertos behave filter:
    `(@udp or @tcp or @tls or @Mtls)`.

Local full freertos suite: 40 scenarios pass / 0 fail / 9 skipped
(intentional @freertoswip / @windows_wip). The new @Mtls scenario from
mtls_transport.feature passes in ~3s.
@github-actions

Copy link
Copy Markdown
Contributor

☀️   Quality Summary

   🚦   build-linux-gcc: 100% successful (✔️ 1286 passed, 🙈 2 skipped)
   🚦   build-freertos-host-tdd: 100% successful (✔️ 1508 passed, 🙈 2 skipped)
   🚦   build-linux-clang: 100% successful (✔️ 1238 passed, 🙈 2 skipped)
   🚦   sanitize-linux-gcc: 100% successful (✔️ 1238 passed, 🙈 2 skipped)
   🚦   integration-linux-openssl: 100% successful (✔️ 9 passed)
   🚦   integration-linux-mbedtls: 100% successful (✔️ 7 passed)
   🚦   integration-windows-openssl: 100% successful (✔️ 9 passed)
   🚦   bdd-linux-syslog-ng: 94% successful (✔️ 46 passed, 🙈 3 skipped)
   🚦   bdd-windows-otel: 90% successful (✔️ 44 passed, 🙈 5 skipped)
   🚦   bdd-freertos-qemu: 82% successful (✔️ 40 passed, 🙈 9 skipped)
   🚦   build-windows-msvc: 100% successful (✔️ 1127 passed, 🙈 1 skipped)
   🚦   build-linux-tunable-override: 100% successful (✔️ 1238 passed, 🙈 2 skipped)
   ⚠️   Clang-Tidy: 1 warning (normal: 1)
   ⚠️   CPPCheck: No warnings


Created by Quality Monitor v1.14.0 (#f3859fd). More details are shown in the GitHub Checks Result.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Bdd/Targets/Common/BddTargetTlsSender_MbedTls_FreeRtosTcp.c`:
- Around line 209-254: The five mbedTLS calls mbedtls_ctr_drbg_seed,
psa_crypto_init, mbedtls_x509_crt_parse (for CA and client cert) and
mbedtls_pk_parse_key currently discard their return codes; change each to
capture its int return value, on non-zero log a one-line diagnostic (matching
the existing "[mbedtls]…" style) including the error code, clear/latch
mbedTlsInitialised = false (or call configASSERT for fatal), and abort the init
flow (return/cleanup) so you only set mbedTlsInitialised = true after all five
succeed; update the code paths around mbedtls_x509_crt_parse,
mbedtls_pk_parse_key, mbedtls_ctr_drbg_seed and psa_crypto_init to implement
this error-check-and-early-exit behavior.

In `@Bdd/Targets/FreeRtos/main.c`:
- Line 243: tlsSender (static struct SolidSyslogSender* tlsSender) is allocated
but never freed; update TeardownAll() to properly destroy the TLS sender by
invoking the SolidSyslogSender cleanup/destructor (e.g., call the existing
SolidSyslogSender_Destroy or equivalent cleanup function used in this codebase)
on tlsSender, close any underlying sockets/mbedtls contexts as part of that
call, and then set tlsSender = NULL to avoid dangling pointers and leaked
transport resources.
- Around line 798-809: Update the stale comment around
tlsSender/BddTargetTlsSender_Create and the SwitchingSender block to reflect
that mTLS is now supported and can be selected at runtime via the `set
transport` command (include `mtls`/`tls+mtls` option in the documented transport
list), and remove the “future work” phrasing about mTLS; specifically edit the
comment that references tlsSender = BddTargetTlsSender_Create(resolver, false)
and the SwitchingSender explanation so it documents current runtime behavior
(that `set transport` can choose udp, tcp, tls and mtls and that the system
dispatches accordingly).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9a11e43c-23a2-493f-91aa-f8dd307a0d81

📥 Commits

Reviewing files that changed from the base of the PR and between 04fc5cd and 6051ef7.

📒 Files selected for processing (12)
  • .devcontainer/devcontainer.json
  • .devcontainer/docker-compose.yml
  • .github/workflows/ci.yml
  • Bdd/Targets/Common/BddTargetSwitchConfig.c
  • Bdd/Targets/Common/BddTargetSwitchConfig.h
  • Bdd/Targets/Common/BddTargetTlsSender_MbedTls_FreeRtosTcp.c
  • Bdd/Targets/FreeRtos/CMakeLists.txt
  • Bdd/Targets/FreeRtos/main.c
  • Bdd/Targets/FreeRtos/mbedtls_user_config.h
  • Bdd/features/steps/syslog_steps.py
  • ci/docker-compose.bdd.yml
  • docs/containers.md

Comment thread Bdd/Targets/Common/BddTargetTlsSender_MbedTls_FreeRtosTcp.c
Comment thread Bdd/Targets/FreeRtos/main.c
Comment thread Bdd/Targets/FreeRtos/main.c Outdated
…a UART marker

The threshold-crossed callback was deferred from S08.05 on the grounds
that the behave step inspects a host-side marker file (/tmp/...) which a
QEMU guest can't write directly. The actual gap is smaller — semihosting
fopen against a relative path would have worked, but a UART-based marker
is cleaner because it reuses the captured-stdout reader the harness
already runs for the prompt protocol.

Changes:

  - Bdd/Targets/FreeRtos/main.c — OnThresholdCrossed callback prints a
    line-anchored `[THRESHOLD-CROSSED]` token to the UART, wired into the
    BlockStoreConfig (previously NULL). Added `set capacity-threshold N`
    to OnSet so the harness's --capacity-threshold flag plumbs through.
  - Bdd/features/steps/syslog_steps.py — _threshold_marker_present helper
    accepts either the host marker file (Linux/Windows binaries write to
    /tmp/solidsyslog_threshold_marker.log unchanged) or the
    [THRESHOLD-CROSSED] token in the captured stdout buffer (FreeRTOS).
    Both `was invoked` / `was not invoked` steps route through it.
  - Bdd/features/steps/target_driver.py — --capacity-threshold added to
    the FreeRTOS UART translation table.
  - Bdd/features/capacity_threshold.feature — drops @freertoswip; the
    feature header documents the dual-channel marker contract.
  - ci/docker-compose.bdd.yml — comment refresh; the freertos behave
    filter is unchanged (the feature is admitted via @tcp @Buffered @store
    which the existing `(@udp or @tcp or @tls or @Mtls)` clause covers).

Local: FreeRTOS suite goes from 40/0 to 42/0 (+2 capacity_threshold);
Linux capacity_threshold still passes via the file path.
New docs/integrating-mbedtls.md walks integrators through wiring
SolidSyslogMbedTlsStream. Covers:

  - When to use mbedTLS vs the OpenSSL-backed SolidSyslogTlsStream — the
    two adapters share the SolidSyslogStream vtable so callers swap at
    link time.
  - The coexistence contract — Platform/MbedTls/Source/ never calls
    process-global mbedTLS APIs; the integrator owns init.
  - The config struct fields and their ownership.
  - The process-wide setup ordering (allocator hook → entropy + DRBG seed
    → psa_crypto_init → cert parsing → adapter Create).
  - FreeRTOS specifics — heap budget, newlib's syscall heap trap, PSA
    external RNG on no-platform-entropy targets, bounded handshake retry.
  - Pointers to the reference integration (BDD target).
  - A common-failures table that maps the cryptic mbedTLS error codes
    surfaced during slice-6c diagnosis back to their root causes.

No code change, no API surface change.
@github-actions

Copy link
Copy Markdown
Contributor

☀️   Quality Summary

   🚦   build-linux-gcc: 100% successful (✔️ 1286 passed, 🙈 2 skipped)
   🚦   build-freertos-host-tdd: 100% successful (✔️ 1508 passed, 🙈 2 skipped)
   🚦   build-linux-clang: 100% successful (✔️ 1238 passed, 🙈 2 skipped)
   🚦   sanitize-linux-gcc: 100% successful (✔️ 1238 passed, 🙈 2 skipped)
   🚦   integration-linux-openssl: 100% successful (✔️ 9 passed)
   🚦   integration-linux-mbedtls: 100% successful (✔️ 7 passed)
   🚦   integration-windows-openssl: 100% successful (✔️ 9 passed)
   🚦   bdd-linux-syslog-ng: 94% successful (✔️ 46 passed, 🙈 3 skipped)
   🚦   bdd-windows-otel: 90% successful (✔️ 44 passed, 🙈 5 skipped)
   🚦   bdd-freertos-qemu: 86% successful (✔️ 42 passed, 🙈 7 skipped)
   🚦   build-windows-msvc: 100% successful (✔️ 1127 passed, 🙈 1 skipped)
   🚦   build-linux-tunable-override: 100% successful (✔️ 1238 passed, 🙈 2 skipped)
   ⚠️   Clang-Tidy: 1 warning (normal: 1)
   ⚠️   CPPCheck: No warnings


Created by Quality Monitor v1.14.0 (#f3859fd). More details are shown in the GitHub Checks Result.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
ci/docker-compose.bdd.yml (1)

116-118: 💤 Low value

Comment phrasing may cause confusion.

The comment says "slice 6c (this commit)" but according to the PR objectives, slice 6c is marked as "in progress" with outstanding items. In a PR with multiple commits, "this commit" is ambiguous. Consider rephrasing to "slice 6c" or "S08.07 slice 6c" to avoid implying this is a single atomic commit.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ci/docker-compose.bdd.yml` around lines 116 - 118, Update the ambiguous
inline comment in ci/docker-compose.bdd.yml that currently references "slice 6c
(this commit)" to a clearer label; replace the phrase with either "slice 6c" or
the explicit project identifier "S08.07 slice 6c" so the comment doesn’t imply a
single atomic commit and accurately reflects the PR status.
Bdd/Targets/FreeRtos/main.c (1)

569-581: ⚡ Quick win

Move OnThresholdCrossed below its first caller.

OnThresholdCrossed is defined before its first use (Line 623). Keep the forward declaration at the top, and place the definition immediately beneath RebuildWithFileStore to match file ordering rules.

As per coding guidelines: “Within a source file, forward-declare helper functions at top after constants/types, then define immediately beneath the function that first calls them.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Bdd/Targets/FreeRtos/main.c` around lines 569 - 581, Move the definition of
OnThresholdCrossed so it appears immediately after the function that first calls
it (RebuildWithFileStore) while keeping its forward declaration at the top;
locate the forward declaration for OnThresholdCrossed near the constants/types,
remove or cut the current definition block starting with "static void
OnThresholdCrossed(void* context)" from its current place, and paste that
definition directly beneath RebuildWithFileStore so file ordering follows:
forward declarations → RebuildWithFileStore → OnThresholdCrossed definition.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@Bdd/Targets/FreeRtos/main.c`:
- Around line 569-581: Move the definition of OnThresholdCrossed so it appears
immediately after the function that first calls it (RebuildWithFileStore) while
keeping its forward declaration at the top; locate the forward declaration for
OnThresholdCrossed near the constants/types, remove or cut the current
definition block starting with "static void OnThresholdCrossed(void* context)"
from its current place, and paste that definition directly beneath
RebuildWithFileStore so file ordering follows: forward declarations →
RebuildWithFileStore → OnThresholdCrossed definition.

In `@ci/docker-compose.bdd.yml`:
- Around line 116-118: Update the ambiguous inline comment in
ci/docker-compose.bdd.yml that currently references "slice 6c (this commit)" to
a clearer label; replace the phrase with either "slice 6c" or the explicit
project identifier "S08.07 slice 6c" so the comment doesn’t imply a single
atomic commit and accurately reflects the PR status.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 67f8b331-1239-440e-8f44-f456c394e86e

📥 Commits

Reviewing files that changed from the base of the PR and between 6051ef7 and 935cfe9.

📒 Files selected for processing (6)
  • Bdd/Targets/FreeRtos/main.c
  • Bdd/features/capacity_threshold.feature
  • Bdd/features/steps/syslog_steps.py
  • Bdd/features/steps/target_driver.py
  • ci/docker-compose.bdd.yml
  • docs/integrating-mbedtls.md
✅ Files skipped from review due to trivial changes (1)
  • Bdd/features/steps/target_driver.py

…g-up

Three findings on PR #421 — all valid, all in the BDD target rather than
production library code:

1. **Silent `(void)`-discard on mbedTLS init returns.** The five fail-able
   calls (`mbedtls_ctr_drbg_seed`, `psa_crypto_init`, two `mbedtls_x509_crt_parse`
   and `mbedtls_pk_parse_key`) had their rcs discarded. Now each captures the
   rc, prints a one-line `[mbedtls] ... FAILED rc=...` diagnostic on
   non-zero, and returns before flipping `mbedTlsInitialised = true`.
   Surfacing the seed rc exposed a latent bug: DemoEntropySource was
   registered as `MBEDTLS_ENTROPY_SOURCE_WEAK`, so `mbedtls_entropy_func`
   never satisfied its `strong_size >= MBEDTLS_ENTROPY_BLOCK_SIZE` check
   and the seed call always returned ENTROPY_SOURCE_FAILED (-0x0034).
   `mbedtls_ctr_drbg_random` against the half-seeded context still
   produced deterministic-but-consistent bytes, which is why earlier
   handshakes appeared to succeed. Switched the source label to
   `MBEDTLS_ENTROPY_SOURCE_STRONG` (the audit-trail "demo-only entropy"
   printf at the end of `EnsureMbedTlsInitialised` is the real quality
   assertion — the STRONG/WEAK label is structural, not a quality claim).

2. **`tlsSender` not destroyed in TeardownAll.** Added
   `BddTargetTlsSender_Destroy()` + `tlsSender = NULL` after the existing
   `SolidSyslogSwitchingSender_Destroy` so the inner MbedTlsStream +
   FreeRtosTcpStream pool slots release on shutdown paths.

3. **Stale TLS/mTLS comments around tlsSender setup.** The block still
   said "mTLS support is slice 6c work and may require an extra
   BDD_TARGET_SWITCH_MTLS slot" — now reflects the dual-port dispatcher
   that already shipped. The `set transport` command-list comment
   includes `mtls` alongside the other transports.

Local: 42/42 freertos BDD scenarios pass, Linux capacity_threshold
unaffected.
…udience

The first draft of this file was structured like a generic mbedTLS
tutorial — a flat init checklist plus a footprint discussion. That left
the actual integration question unanswered: "I'm here because I want
SolidSyslog on top of mbedTLS — what do *I* plug in?"

This rewrite restructures the document around two concrete integrator
scenarios:

  - **Scenario A — you already have Mbed TLS in your image.** Three steps:
    pick a `SolidSyslogStream` byte transport, fill in
    `SolidSyslogMbedTlsStreamConfig` with your existing handles, wire
    `tlsStream` into a `SolidSyslogStreamSender`. The coexistence contract
    documents the auditable not-touched list so an integrator with an
    existing Mbed TLS deployment can be confident the adapter won't fight
    their setup.
  - **Scenario B — you don't have Mbed TLS yet.** Defers to upstream Mbed
    TLS porting docs for the bring-up itself, then gives the integrator a
    SolidSyslog-specific checklist of what we actually consume (seeded
    CTR_DRBG with at least one STRONG entropy source, psa_crypto_init
    after the DRBG seed, parsed CA chain, optional client cert + key, byte
    transport).

The FreeRTOS-specific gotchas (newlib syscall heap, PSA external RNG,
record-buffer sizing) move to a dedicated section labelled as integrator
checklist items rather than baked into the body — they only apply on
that family of targets.

The "what this adapter does not own" footer makes the dependency-injection
contract explicit so integrators know which problems remain theirs (PEM
parsing, rotation, HSM, per-connection config).

No code change.
…62443.md, rfc-compliance.md

The mbedTLS reference adapter (SolidSyslogMbedTlsStream) shipped in
slices 1–5 (host) and slices 6a–6c (FreeRTOS BDD target) but was only
ever described in the parent issue, not in the existing reference docs.
This sweep registers it alongside the OpenSSL-backed reference:

  - CLAUDE.md — new `SolidSyslogMbedTlsStream.h` row in the
    Public-Header-Audiences table (alongside the existing
    `SolidSyslogTlsStream.h` row). Updates the StreamSender row to
    enumerate `SolidSyslogMbedTlsStream` alongside `SolidSyslogTlsStream`
    as a TLS-capable Stream backend. Points readers at the integrator
    guide for the full coexistence-contract write-up.
  - docs/iec62443.md — new `### Embedded SL4` subsection mapping
    `SolidSyslogMbedTlsStream` to the same CR 1.5 / CR 1.8 / CR 2.12 /
    CR 3.9 controls the OpenSSL substrate satisfies, with a
    coexistence-contract bullet aimed at integrators who already wire
    mbedTLS for another subsystem. The SL4 setup-recipe at the bottom of
    the page mentions both adapters as alternatives.
  - docs/rfc-compliance.md — RFC 5425 section table widens from
    OpenSSL-only language to per-row "OpenSSL: … / Mbed TLS: …" coverage,
    with an intro paragraph noting the two adapters share the
    SolidSyslogStream vtable so the requirement matrix is per-section,
    not per-adapter.

No code change; all references are to existing code paths.
Long-form narrative of the slice-6c bring-up: three-layer mbedTLS init
diagnosis (heap routing → PSA / TLS-1.3 → STRONG-entropy label),
dual-mode TLS/mTLS dispatcher, capacity_threshold marker over UART, the
CodeRabbit-driven discovery that ctr_drbg_seed had been failing silently
(producing deterministic-but-consistent pseudo-random for the
client-side handshake nonce — a happy accident that masked the real bug),
and the slice-7 documentation sweep that registers SolidSyslogMbedTlsStream
across CLAUDE.md, iec62443.md, rfc-compliance.md, and the new
integrating-mbedtls.md.
@DavidCozens DavidCozens changed the title feat: S08.07 FreeRTOS BDD target — TLS via mbedTLS (slice 6, WIP) feat: S08.07 FreeRTOS BDD target — TLS via mbedTLS May 21, 2026
@github-actions

Copy link
Copy Markdown
Contributor

☀️   Quality Summary

   🚦   build-linux-gcc: 100% successful (✔️ 1286 passed, 🙈 2 skipped)
   🚦   build-freertos-host-tdd: 100% successful (✔️ 1508 passed, 🙈 2 skipped)
   🚦   build-linux-clang: 100% successful (✔️ 1238 passed, 🙈 2 skipped)
   🚦   sanitize-linux-gcc: 100% successful (✔️ 1238 passed, 🙈 2 skipped)
   🚦   integration-linux-openssl: 100% successful (✔️ 9 passed)
   🚦   integration-linux-mbedtls: 100% successful (✔️ 7 passed)
   🚦   integration-windows-openssl: 100% successful (✔️ 9 passed)
   🚦   bdd-linux-syslog-ng: 94% successful (✔️ 46 passed, 🙈 3 skipped)
   🚦   bdd-windows-otel: 90% successful (✔️ 44 passed, 🙈 5 skipped)
   🚦   bdd-freertos-qemu: 86% successful (✔️ 42 passed, 🙈 7 skipped)
   🚦   build-windows-msvc: 100% successful (✔️ 1127 passed, 🙈 1 skipped)
   🚦   build-linux-tunable-override: 100% successful (✔️ 1238 passed, 🙈 2 skipped)
   ⚠️   Clang-Tidy: 1 warning (normal: 1)
   ⚠️   CPPCheck: No warnings


Created by Quality Monitor v1.14.0 (#f3859fd). More details are shown in the GitHub Checks Result.

Reflow the printf arg lists and ctr_drbg_seed call to match clang-format's
preferred layout — picked up by analyze-format on the prior push. No
behaviour change.
@github-actions

Copy link
Copy Markdown
Contributor

☀️   Quality Summary

   🚦   build-linux-gcc: 100% successful (✔️ 1286 passed, 🙈 2 skipped)
   🚦   build-freertos-host-tdd: 100% successful (✔️ 1508 passed, 🙈 2 skipped)
   🚦   build-linux-clang: 100% successful (✔️ 1238 passed, 🙈 2 skipped)
   🚦   sanitize-linux-gcc: 100% successful (✔️ 1238 passed, 🙈 2 skipped)
   🚦   integration-linux-openssl: 100% successful (✔️ 9 passed)
   🚦   integration-linux-mbedtls: 100% successful (✔️ 7 passed)
   🚦   integration-windows-openssl: 100% successful (✔️ 9 passed)
   🚦   bdd-linux-syslog-ng: 94% successful (✔️ 46 passed, 🙈 3 skipped)
   🚦   bdd-windows-otel: 90% successful (✔️ 44 passed, 🙈 5 skipped)
   🚦   bdd-freertos-qemu: 86% successful (✔️ 42 passed, 🙈 7 skipped)
   🚦   build-windows-msvc: 100% successful (✔️ 1127 passed, 🙈 1 skipped)
   🚦   build-linux-tunable-override: 100% successful (✔️ 1238 passed, 🙈 2 skipped)
   ⚠️   Clang-Tidy: 1 warning (normal: 1)
   ⚠️   CPPCheck: No warnings


Created by Quality Monitor v1.14.0 (#f3859fd). More details are shown in the GitHub Checks Result.

@DavidCozens DavidCozens marked this pull request as ready for review May 22, 2026 05:30

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
docs/integrating-mbedtls.md (1)

19-30: 💤 Low value

Consider adding language specifier to fenced code block.

The ASCII diagram at line 19 triggers a markdownlint warning for missing language specification. While ASCII art doesn't have a natural language tag, you can add text to satisfy the linter:

```text
SolidSyslog_Log ─▶ Buffer ─▶ Sender ─▶ SolidSyslogStreamSender
...
```
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/integrating-mbedtls.md` around lines 19 - 30, The fenced ASCII diagram
containing SolidSyslog_Log, SolidSyslogMbedTlsStream and SolidSyslogStream
should include a Markdown language specifier to satisfy markdownlint; update the
diagram's triple-backtick fence to use ```text (i.e., change the opening fence
for the ASCII art block to ```text) so the linter recognizes it as plain text
while preserving the diagram content.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Bdd/Targets/Common/BddTargetTlsSender_MbedTls_FreeRtosTcp.c`:
- Around line 224-229: The TLS initialization branches (e.g., failures from
ctr_drbg_seed, mbedtls_x509_crt_parse, mbedtls_pk_parse_key,
mbedtls_ctr_drbg_random, mbedtls_ssl_config_defaults, mbedtls_ssl_conf_rng) must
not just log-and-return from the helper — they need to propagate failure to
BddTargetTlsSender_Create so the TLS slot is disabled early; modify each failing
branch in BddTargetTlsSender_MbedTls_FreeRtosTcp.c to return an error status (or
set a clear failure flag/NULL out the partially-initialized BddTargetTlsSender
object) instead of only printing and returning void, ensure the caller
BddTargetTlsSender_Create checks that return value/flag and aborts creation
(cleaning up drbg / cert / key via existing cleanup functions) so no partial
state is used later (apply same change for the branches around ctr_drbg_seed,
x509 cert parse, pk parse, ssl config/rng setup and the other noted blocks).

---

Nitpick comments:
In `@docs/integrating-mbedtls.md`:
- Around line 19-30: The fenced ASCII diagram containing SolidSyslog_Log,
SolidSyslogMbedTlsStream and SolidSyslogStream should include a Markdown
language specifier to satisfy markdownlint; update the diagram's triple-backtick
fence to use ```text (i.e., change the opening fence for the ASCII art block to
```text) so the linter recognizes it as plain text while preserving the diagram
content.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0d7831da-6dc6-4083-80ae-189650fb643d

📥 Commits

Reviewing files that changed from the base of the PR and between 935cfe9 and 4b0f67d.

📒 Files selected for processing (7)
  • Bdd/Targets/Common/BddTargetTlsSender_MbedTls_FreeRtosTcp.c
  • Bdd/Targets/FreeRtos/main.c
  • CLAUDE.md
  • DEVLOG.md
  • docs/iec62443.md
  • docs/integrating-mbedtls.md
  • docs/rfc-compliance.md
✅ Files skipped from review due to trivial changes (3)
  • docs/rfc-compliance.md
  • CLAUDE.md
  • DEVLOG.md

Comment thread Bdd/Targets/Common/BddTargetTlsSender_MbedTls_FreeRtosTcp.c
…ailure

CodeRabbit's follow-up review on the slice-6c CR-fix push pointed out
that EnsureMbedTlsInitialised's new early-return branches log and bail
but BddTargetTlsSender_Create still builds a TLS sender around whatever
partial state was left in drbg / certs / key — pushing the failure into
later opaque handshake / send errors rather than disabling the TLS slot
cleanly at the point of init failure.

Closes that loop:

  - BddTargetTlsSender_Create checks mbedTlsInitialised after
    EnsureMbedTlsInitialised. On failure it returns the shared
    SolidSyslogNullSender, matching the bad-setup-contract pattern
    used elsewhere in the library — the SwitchingSender's tls slot
    drops messages cleanly and the file-scope sender / tlsStream /
    underlyingStream statics stay NULL.
  - BddTargetTlsSender_Destroy now short-circuits when sender is NULL,
    so the early-return-from-Create path doesn't try to release pool
    slots that were never acquired.

No behaviour change on the happy path: 42/42 freertos BDD scenarios
still pass locally.

Refs CodeRabbit comment 3286071197 on PR #421.
Three small CodeRabbit nitpicks on PR #421:

  - ci/docker-compose.bdd.yml — drop the ambiguous "(this commit)"
    phrasing; "S08.07 slice 6c" survives squash-merge correctly.
  - Bdd/Targets/FreeRtos/main.c — move OnStoreFull, GetCapacityThreshold,
    and OnThresholdCrossed below RebuildWithFileStore, their first
    caller. Matches the file-ordering rule in CLAUDE.md ("Helper functions
    are forward-declared at the top of the file ... and defined
    immediately beneath the function that first calls them"). The
    forward declarations near the top of the file are unchanged.
  - docs/integrating-mbedtls.md — add `text` language specifier to the
    pipeline-shape ASCII diagram's fenced code block so markdownlint
    stops warning about the missing tag.

No code behaviour change.
@github-actions

Copy link
Copy Markdown
Contributor

☀️   Quality Summary

   🚦   build-linux-gcc: 100% successful (✔️ 1286 passed, 🙈 2 skipped)
   🚦   build-freertos-host-tdd: 100% successful (✔️ 1508 passed, 🙈 2 skipped)
   🚦   build-linux-clang: 100% successful (✔️ 1238 passed, 🙈 2 skipped)
   🚦   sanitize-linux-gcc: 100% successful (✔️ 1238 passed, 🙈 2 skipped)
   🚦   integration-linux-openssl: 100% successful (✔️ 9 passed)
   🚦   integration-linux-mbedtls: 100% successful (✔️ 7 passed)
   🚦   integration-windows-openssl: 100% successful (✔️ 9 passed)
   🚦   bdd-linux-syslog-ng: 94% successful (✔️ 46 passed, 🙈 3 skipped)
   🚦   bdd-windows-otel: 90% successful (✔️ 44 passed, 🙈 5 skipped)
   🚦   bdd-freertos-qemu: 86% successful (✔️ 42 passed, 🙈 7 skipped)
   🚦   build-windows-msvc: 100% successful (✔️ 1127 passed, 🙈 1 skipped)
   🚦   build-linux-tunable-override: 100% successful (✔️ 1238 passed, 🙈 2 skipped)
   ⚠️   Clang-Tidy: 1 warning (normal: 1)
   ⚠️   CPPCheck: No warnings


Created by Quality Monitor v1.14.0 (#f3859fd). More details are shown in the GitHub Checks Result.

@DavidCozens

Copy link
Copy Markdown
Owner Author

Nitpick acknowledgements for the two CodeRabbit review summaries that don't have an inline thread to reply to —

Review 4341024920 (2026-05-21 21:56Z) — two nitpicks, both addressed in b8e3113:

  • ci/docker-compose.bdd.yml:116-118 — "(this commit)" replaced with "S08.07 slice 6c" so the phrasing survives squash-merge cleanly.
  • Bdd/Targets/FreeRtos/main.c:569-581OnThresholdCrossed (plus the two pre-existing siblings OnStoreFull and GetCapacityThreshold, for consistency) moved below RebuildWithFileStore, matching the file-ordering rule in CLAUDE.md.

Review 4342764730 (2026-05-22 05:37Z) — one nitpick, addressed in b8e3113:

  • docs/integrating-mbedtls.md:19-30 — pipeline-shape diagram fence now ```text so markdownlint stops warning.

The Major finding in that same review (BddTargetTlsSender_Create not propagating init failure) is addressed in 37d1ebb — replied inline on the original thread.

All inline CR threads resolved; CI run 26271306716 green.

@DavidCozens DavidCozens merged commit a52183a into main May 22, 2026
21 checks passed
@DavidCozens DavidCozens deleted the feat/s08.07-bdd-mbedtls branch May 22, 2026 06:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

S08.07: TLS via mbedTLS on FreeRTOS

1 participant