Skip to content
Open
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
6 changes: 3 additions & 3 deletions .fusa-reqs.json
Original file line number Diff line number Diff line change
Expand Up @@ -852,7 +852,7 @@
{
"id": "REQ-RELAY-001",
"title": "Protocol enum values are defined and stable",
"description": "relay::Protocol shall define CAN=1, DDS=2, LIN=3, MQTT=4, RCP=5, SOMEIP=6 as stable integer values matching RELAY spec v1.11 §3.",
"description": "relay::Protocol shall define CAN=1, DDS=2, LIN=3, MQTT=4, RCP=5, SOMEIP=6 as stable integer values matching RELAY spec v1.14 §3.",
"asil": "ASIL-B",
"rationale": "Protocol values are wire-format identifiers; changing them breaks cross-language interop.",
"tags": ["relay", "protocol"]
Expand Down Expand Up @@ -1003,8 +1003,8 @@
},
{
"id": "REQ-RELAY-020",
"title": "kSpecVersion constant equals '1.11'",
"description": "relay::kSpecVersion shall be a constexpr const char* equal to '1.11'.",
"title": "kSpecVersion constant equals '1.14'",
"description": "relay::kSpecVersion shall be a constexpr const char* equal to '1.14'.",
"asil": "ASIL-B",
"rationale": "RELAY §2: spec version constant enables runtime conformance checking.",
"tags": ["relay", "version"]
Expand Down
103 changes: 82 additions & 21 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,17 @@ jobs:
go-version: 'stable'

- name: Install relay tool
run: go install github.com/SoundMatt/RELAY/cmd/relay@latest
# Pinned, not @latest: an unpinned install means the spec version
# actually being conformance-checked against can silently change
# between CI runs with no diff to review (see cpp-LIN#22). v2.0.0 is
# RELAY's current tagged release but is not installable via
# `go install ...@v2.0.0` — its go.mod doesn't declare the
# `/v2` module path suffix Go's semantic import versioning requires
# for a v2+ major version, so the install fails outright (filed
# upstream as SoundMatt/RELAY#68). v1.14.0 is therefore the current
# actually-installable latest; keep this in sync with README.md and
# requirements/requirements.json's declared spec version.
run: go install github.com/SoundMatt/RELAY/cmd/relay@v1.14.0

- name: RELAY conformance gate
run: relay conform --strict ./build/cli/cpp-lin-cli
Expand Down Expand Up @@ -234,7 +244,7 @@ jobs:
with:
repository: SoundMatt/cpp-FuSa
path: cpp-FuSa
ref: v0.15.0
ref: v0.17.1

- name: Install tools
run: sudo apt-get update -qq && sudo apt-get install -y cmake ninja-build zip
Expand All @@ -249,7 +259,14 @@ jobs:

- name: cpfusa init
working-directory: cpp-LIN
run: ../cpp-FuSa/build/cpfusa init --name cpp-LIN --standard iso26262 --asil ASIL-B --project-version 0.4.0 --force || true
# No --force: .fusa.json/.fusa-reqs.json are checked into the repo
# and already populated (hundreds of real REQ-* entries). --force
# would silently overwrite them with an empty scaffold right before
# the traceability step reads them, making the traceability gate a
# permanent no-op (see cpp-LIN#19). Without --force, `init` just
# prints "already exists" and exits 0 when the files are present, so
# no `|| true` is needed either.
run: ../cpp-FuSa/build/cpfusa init --name cpp-LIN --standard iso26262 --asil ASIL-B --project-version 0.4.0

- name: cpfusa check
working-directory: cpp-LIN
Expand All @@ -273,23 +290,7 @@ jobs:

- name: cpfusa hara init
working-directory: cpp-LIN
run: ../cpp-FuSa/build/cpfusa hara init --project cpp-LIN --dir . || true

- name: cpfusa iso26262 (ASIL-B)
working-directory: cpp-LIN
run: |
../cpp-FuSa/build/cpfusa iso26262 \
--asil ASIL-B \
--output iso26262-gap-report.json \
--dir . || true

- name: cpfusa iec61508 (SIL-2)
working-directory: cpp-LIN
run: |
../cpp-FuSa/build/cpfusa iec61508 \
--sil SIL-2 \
--output iec61508-gap-report.json \
--dir . || true
run: ../cpp-FuSa/build/cpfusa hara init --project cpp-LIN --dir .

- name: cpfusa boundary
working-directory: cpp-LIN
Expand All @@ -315,6 +316,66 @@ jobs:
working-directory: cpp-LIN
run: ../cpp-FuSa/build/cpfusa sci --dir .

- name: cpfusa release (SBOM + provenance + artifact manifest)
working-directory: cpp-LIN
# Was never called even though the evidence-upload step below has
# always listed sbom.json/provenance.json/artifact-manifest.json —
# they never actually existed at upload time.
run: ../cpp-FuSa/build/cpfusa release --dir .

- name: cpfusa iso26262 (ASIL-B gap gate)
working-directory: cpp-LIN
# Run after every other evidence-generating step above so the gap
# analysis sees the real, complete evidence set (previously this ran
# right after `hara init`, before boundary/tara/fmea/safety-case/
# sas/sci/release had produced anything, so it under-reported).
#
# `cpfusa iso26262` exits 1 whenever any objective is in the "gap"
# state, which is real behavior, not a bug: with the full evidence
# set in place, 11 of the 20 ASIL-B objectives still report "gap"
# (6-5.2, 6-6.1, 6-6.2, 6-6.3, 6-7.1, 6-7.2, 6-8.1, 6-9.1, 8-6.1,
# 8-6.2, 9-1.1) purely because cpfusa v0.17.1's own
# iso26262::detect_status() has no evidence-detection case at all for
# those clauses (it falls through to Status::Gap unconditionally,
# regardless of what's actually in the repo — e.g. 8-6.2 "Safety
# manual" reports gap even though SAFETY_MANUAL.md exists and is
# substantial). Filed upstream as SoundMatt/cpp-FuSa#57. Until that's
# fixed, blanket `|| true` here would hide real regressions just as
# much as it hides this known floor, so instead this gate fails only
# if the gap count regresses past that documented floor.
run: |
../cpp-FuSa/build/cpfusa iso26262 \
--asil ASIL-B \
--output iso26262-gap-report.json \
--dir . || true
GAPS=$(jq '.summary.gaps' iso26262-gap-report.json)
echo "ISO 26262 ASIL-B: $(jq -c '.summary' iso26262-gap-report.json)"
MAX_GAPS=11
if [ "$GAPS" -gt "$MAX_GAPS" ]; then
echo "::error::ISO 26262 ASIL-B gap count ($GAPS) exceeds the known ${MAX_GAPS}-gap floor (see step comment / SoundMatt/cpp-FuSa#57) — this is a real regression, not the known tool limitation. Investigate before merging."
exit 1
fi

- name: cpfusa iec61508 (SIL-2 gap gate)
working-directory: cpp-LIN
# Same reasoning as the ISO 26262 step above: 10 of the 18 required
# SIL-2 objectives (1-7.1, 1-8.1, 1-8.2, 3-7.2, 3-7.4, 3-7.5, 3-7.6,
# 3-7.7, 3-7.8, 2-7.1) have no detect_status() case in cpfusa v0.17.1
# and can never leave "gap" via this tool version regardless of real
# project evidence. Same upstream issue (SoundMatt/cpp-FuSa#57).
run: |
../cpp-FuSa/build/cpfusa iec61508 \
--sil SIL-2 \
--output iec61508-gap-report.json \
--dir . || true
GAPS=$(jq '.summary.gaps' iec61508-gap-report.json)
echo "IEC 61508 SIL-2: $(jq -c '.summary' iec61508-gap-report.json)"
MAX_GAPS=10
if [ "$GAPS" -gt "$MAX_GAPS" ]; then
echo "::error::IEC 61508 SIL-2 gap count ($GAPS) exceeds the known ${MAX_GAPS}-gap floor (see step comment / SoundMatt/cpp-FuSa#57) — this is a real regression, not the known tool limitation. Investigate before merging."
exit 1
fi

- name: cpfusa badge
working-directory: cpp-LIN
run: ../cpp-FuSa/build/cpfusa badge --dir .
Expand Down Expand Up @@ -435,7 +496,7 @@ jobs:
with:
repository: SoundMatt/cpp-FuSa
path: cpp-FuSa
ref: v0.15.0
ref: v0.17.1

- name: Install tools
run: sudo apt-get update -qq && sudo apt-get install -y cmake ninja-build
Expand Down
27 changes: 22 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ jobs:
name: Build release binaries (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
# So a failure on one OS doesn't cancel the other two in-flight
# matrix legs (GH's default fail-fast:true did exactly that every
# time the macOS leg failed — see cpp-LIN#13 — hiding whether
# ubuntu/windows would themselves have passed).
fail-fast: false
matrix:
include:
- os: ubuntu-22.04
Expand All @@ -38,10 +43,20 @@ jobs:
run: |
cmake -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_STANDARD=17

- name: Build CLI
run: cmake --build build --parallel --target cpp-lin-cli --config Release
-DCMAKE_CXX_STANDARD=17 \
-G Ninja

- name: Build
# Build everything (lib + CLI + tests), matching ci.yml's
# build-and-test job. The previous `--target cpp-lin-cli` here built
# only the CLI binary and never the cpplin_tests target at all, so
# the "Run tests" step below always hit ctest's `_NOT_BUILT`
# sentinel — on every OS, not just macOS. Combined with the missing
# `-G Ninja` (which left macOS on its multi-config Xcode default,
# a second independent reason `ctest` couldn't find a Debug/Release
# binary it recognized), this is why the macOS release job has
# failed on every tagged release (cpp-LIN#13).
run: cmake --build build --parallel

- name: Run tests
run: ctest --test-dir build --output-on-failure -j1
Expand All @@ -55,7 +70,9 @@ jobs:
- name: Stage artifact (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: Copy-Item build\cli\Release\cpp-lin-cli.exe ${{ matrix.artifact }}.exe
# -G Ninja is a single-config generator: no per-config (Release/)
# output subdirectory, unlike the Visual Studio default generator.
run: Copy-Item build\cli\cpp-lin-cli.exe ${{ matrix.artifact }}.exe

- name: Upload artifact
uses: actions/upload-artifact@v4
Expand Down
96 changes: 96 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Changelog

All notable changes to cpp-LIN are documented here. Format loosely follows
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## [Unreleased]

## [0.4.0] — 2026-07-27

cpp-LIN v0.4.0 — RELAY ecosystem audit fixes. Fixes all 8 open issues filed by
the RELAY ecosystem audit (2026-07-27). See PR #12 for full details.

### Fixed — spec conformance

- `lin::Errc::invalid_frame` — a LIN-specific error category, distinct from
`ErrPayloadTooLarge`, for out-of-range LIN frame IDs (spec §5.3:
`ErrInvalidFrame` and `ErrPayloadTooLarge` are distinct; `ValidateFrame`
MUST NOT return `ErrPayloadTooLarge`). Applied to
`virtual::Bus::do_publish()`/`send_header()`,
`master::Node::set_schedule()`/`run()`, and `slave::Node::set_response()`.
- `convert` now writes the correct `ErrInvalidFrame` sentinel name to stderr
instead of the nonexistent `ErrInvalidInput` (spec §11.2).
- `capabilities` now reports an actual transport backend (`"virtual"`)
instead of the protocol name (`"LIN"`) in the `transports` array
(spec §12.2).
- `"tool"` field lowercased to `"cpp-lin"` to match the CLI-binary-name
convention used by peers (`go-can`, `cpp-rcp`) (spec §13.2).
- `version`/`status` now support `--format text|json`, exiting `2` on an
unrecognized format value or any other unrecognized argument (spec §11.1).
- `lin::mock` — the RELAY spec §13.7.1 canonical `mock` module, aliasing the
existing `lin::virt::Bus`.

## [0.3.0] — 2026-06-19

RELAY v1.11 §17.7 — CLI waiver removed. RELAY v1.11 removes the waiver that
previously allowed CLI-less C++ library implementations to mark CLI
conformance requirements as "not applicable". Every conformant C++
implementation must now ship the `version` / `capabilities` / `status` CLI,
buildable via `-DRELAY_BUILD_CLI=ON`.

cpp-LIN has shipped the full CLI since v0.1.0 — no new code was required.
This release aligns the declared spec version and CMake interface with the
new spec text (`kSpecVersion "1.10"` → `"1.11"` in `relay.hpp`/`lin.hpp`,
`spec_version` in CLI JSON output, `RELAY_BUILD_CLI` CMake alias option,
RELAY test vectors updated to `spec_version: "1.11"`).

## [0.2.0] — 2026-06-19

Full Safety & Cyber Pack.

### Added

- **Safety documentation** (ISO 26262 / IEC 61508 / DO-178C): `TARA.md` +
`tara.json` (7 threat scenarios, CVSS 3.1, 8 security controls, attack
tree, residual risk acceptance — ISO/SAE 21434:2021 + IEC 62443-4-1 SL-2);
`fmea.json` (14 failure mode entries linked to HARA hazards H-01..H-05, all
closed — ISO 26262-9); `sas.md` (9 modules, invariants, public interfaces,
data flow, memory safety strategy — ISO 26262-6 §7.4); `boundary.mermaid`
(ISO 26262-6 §7.4.1); `SAFETY_MANUAL.md` (safe API patterns, anti-patterns,
thread safety matrix, memory budget, shutdown sequencing — ISO 26262-6 §7 /
Part 10 §9 SEooC); `SECURITY.md` and `INCIDENT-RESPONSE.md` (coordinated
disclosure, ASIL impact assessment, ISN process).
- **Requirements traceability**: 19 IEC 62443 security controls in
`.fusa-iec62443.json` (expanded from a 5-line stub); 32 new
`REQ-RELAY-001..029,051,056,059` entries in `.fusa-reqs.json`, closing all
orphan `fusa:req` annotations. All 109 pre-existing FuSa requirements
retained; full traceability matrix intact.

## [0.1.0] — 2026-06-19

First release of the C++ LIN bus library — a complete port of go-LIN
implementing the RELAY spec v1.10, qualified to ISO 26262 ASIL-B.

### Added

- Core LIN types: `Frame`, `Filter`, `ScheduleEntry`, `IBus`, `IMasterBus` —
full feature parity with go-LIN.
- Virtual bus (`lin::virt::Bus`): thread-safe, metrics, health provider,
subscriber drainer.
- E2E safety (`lin::safety`): CRC-16/CCITT-FALSE end-to-end data protection
with monotonic sequence counter.
- LDF parser (`lin::ldf`): parses LIN Description Files — frames, signals,
schedule tables.
- Master node (`lin::master::Node`): schedule-driven header transmission
with per-slot callbacks.
- Slave node (`lin::slave::Node`): response registry with frame
subscription.
- RELAY adapter (`lin::adapt()`): wraps any `IBus` as a `relay::INode`.
- CLI binary (`cpp-lin-cli`): RELAY `version`, `capabilities`, `status`,
`convert --protocol LIN`.

[Unreleased]: https://github.com/SoundMatt/cpp-LIN/compare/v0.4.0...HEAD
[0.4.0]: https://github.com/SoundMatt/cpp-LIN/releases/tag/v0.4.0
[0.3.0]: https://github.com/SoundMatt/cpp-LIN/releases/tag/v0.3.0
[0.2.0]: https://github.com/SoundMatt/cpp-LIN/releases/tag/v0.2.0
[0.1.0]: https://github.com/SoundMatt/cpp-LIN/releases/tag/v0.1.0
2 changes: 1 addition & 1 deletion HARA.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,6 @@ ASIL-D at system level if required.

- ISO 26262:2018 Part 3 — Concept phase
- LIN Specification Package Rev 2.2A — Section 2 (Frame structure)
- RELAY Specification v1.11 — §15 (Error handling)
- RELAY Specification v1.14 — §15 (Error handling)
- `SEOOC.md` — Assumptions on use
- `SAFETY_PLAN.md` — Development process
2 changes: 1 addition & 1 deletion INCIDENT-RESPONSE.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,6 @@ For safety-critical (ASIL-B) vulnerabilities, the following additional steps app
- **ISO/SAE 21434:2021** §7.4 — Vulnerability management and disclosure
- **IEC 62443-4-1:2018** SM-2 — Security management (vulnerability response)
- **IEC/TR 62443-2-3:2015** — Patch management for IACS
- **RELAY Spec v1.11** §22 — Security considerations
- **RELAY Spec v1.14** §22 — Security considerations
- `SECURITY.md` — Public-facing vulnerability disclosure policy
- `SEOOC.md` — Safety Element out of Context assumptions (integrator scope)
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
C++ LIN bus library — RELAY-conformant, ISO 26262 ASIL-B.

[![CI](https://github.com/SoundMatt/cpp-LIN/actions/workflows/ci.yml/badge.svg)](https://github.com/SoundMatt/cpp-LIN/actions/workflows/ci.yml)
[![RELAY Conformant](https://img.shields.io/badge/RELAY-v1.11%20conformant-blue)](https://github.com/SoundMatt/RELAY)
[![RELAY Conformant](https://img.shields.io/badge/RELAY-v1.14%20conformant-blue)](https://github.com/SoundMatt/RELAY)
[![ASIL-B](https://img.shields.io/badge/ISO%2026262-ASIL--B-orange)](SAFETY_PLAN.md)
[![License: MPL 2.0](https://img.shields.io/badge/License-MPL%202.0-brightgreen.svg)](LICENSE)

## Overview

cpp-LIN is a production-quality C++ implementation of the LIN (Local Interconnect
Network) protocol, following the RELAY specification v1.11. It is the C++ sibling
Network) protocol, following the RELAY specification v1.14. It is the C++ sibling
of [go-LIN](https://github.com/SoundMatt/go-LIN) and is patterned after
[cpp-CAN](https://github.com/SoundMatt/cpp-CAN).

Expand Down Expand Up @@ -50,7 +50,7 @@ ctest --test-dir build --output-on-failure
```
include/lin/
channel.hpp — Chan<T>: bounded, thread-safe FIFO
relay.hpp — RELAY v1.11 types (Protocol, Message, INode, …)
relay.hpp — RELAY v1.14 types (Protocol, Message, INode, …)
lin.hpp — IBus, IMasterBus, Frame, Filter, free functions
virtual/bus.hpp — In-process virtual LIN bus
mock/mock.hpp — RELAY spec §13.7.1 canonical `mock` module (alias of virtual::Bus)
Expand Down Expand Up @@ -97,7 +97,7 @@ P1 = NOT(ID1 ^ ID3 ^ ID4 ^ ID5) (bit 7)

## RELAY Integration

cpp-LIN exposes a RELAY v1.11 `INode` adapter:
cpp-LIN exposes a RELAY v1.14 `INode` adapter:

```cpp
#include <lin/lin.hpp>
Expand Down
2 changes: 1 addition & 1 deletion ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
- [x] Virtual bus with Classic and Enhanced checksum support
- [x] Protected Identifier (PID) computation and verification
- [x] LDF parser (nodes, signals, frames, schedule tables, signal decode)
- [x] Master node with schedule table runner (`std::stop_token`)
- [x] Master node with schedule table runner (`std::atomic<bool>&`)
- [x] Slave node with per-ID response registration
- [x] E2E safety: Protector and Receiver (CRC-16/CCITT-FALSE, 10-byte header)
- [x] RELAY v1.10 adapter (`relay::INode`)
Expand Down
4 changes: 2 additions & 2 deletions SAFETY_PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

This Safety Plan governs the development of **cpp-LIN**, a C++ software
component implementing the LIN (Local Interconnect Network) bus protocol,
conformant to the RELAY specification v1.11.
conformant to the RELAY specification v1.14.

cpp-LIN is classified as a **Safety Element out of Context (SEooC)** per
ISO 26262-10 §9. It is intended for integration into automotive ECUs and
Expand Down Expand Up @@ -131,7 +131,7 @@ See [HARA.md](HARA.md).
- IEC 61508:2010 — Functional safety of E/E/PE safety-related systems
- ISO/SAE 21434:2021 — Road vehicles — Cybersecurity engineering
- LIN Specification Package, Revision 2.2A (LIN Consortium)
- RELAY Specification v1.11 (SoundMatt)
- RELAY Specification v1.14 (SoundMatt)
- `.fusa-reqs.json` — Machine-readable requirements
- `HARA.md` — Hazard Analysis and Risk Assessment
- `SEOOC.md` — Safety Element out of Context document
2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,4 @@ escalation contacts.

- ISO/SAE 21434:2021 §7.4 — Vulnerability management
- IEC 62443-4-1:2018 SM-2 — Security management
- RELAY Spec v1.11 §22 — Security considerations
- RELAY Spec v1.14 §22 — Security considerations
Loading
Loading