C++ LIN bus library — RELAY-conformant, ISO 26262 ASIL-B.
CI RELAY Conformant ASIL-B License: MPL 2.0
cpp-LIN is a production-quality C++ implementation of the LIN (Local Interconnect Network) protocol, following the RELAY specification v2.0. It is the C++ sibling of go-LIN and is patterned after cpp-CAN.
- Virtual bus — in-process, thread-safe LIN bus for testing and simulation
- Mock module — RELAY spec §13.7.1 canonical
mocknamespace (lin::mock::Bus) - LDF parser — parse LIN Description Files (
.ldf), decode signals - Master node — schedule table runner with configurable slot timing
- Slave node — publish response payloads for specific LIN frame IDs
- E2E safety — End-to-End protection (10-byte header, CRC-16/CCITT-FALSE)
- RELAY adapter — exposes any
IBusas arelay::INodefor cross-protocol routing - CLI —
cpp-lin-clibinary for RELAY conform/interop test harness integration - ISO 26262 ASIL-B — full requirements traceability via
.fusa-reqs.json
# Clone git clone https://github.com/SoundMatt/cpp-LIN.git cd cpp-LIN # Build (requires CMake >= 3.21, C++17) cmake -B build -DCMAKE_BUILD_TYPE=Release cmake --build build --parallel # Test ctest --test-dir build --output-on-failure # CLI ./build/cli/cpp-lin-cli version ./build/cli/cpp-lin-cli capabilities
include/lin/
channel.hpp — Chan<T>: bounded, thread-safe FIFO
relay.hpp — RELAY v2.0 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)
safety/e2e.hpp — E2E Protector / Receiver
ldf/parser.hpp — LDF file parser / signal decoder
master/node.hpp — Master schedule runner
slave/node.hpp — Slave response publisher
src/
relay.cpp — RELAY type implementations
lin.cpp — PID, checksum, validation, RELAY adapter
virtual/bus.cpp — Virtual bus implementation
safety/e2e.cpp — CRC-16 and E2E framing
ldf/parser.cpp — LDF tokeniser and parser
master/node.cpp — Master node run loop
slave/node.cpp — Slave node
cli/
main.cpp — CLI entry point (version/capabilities/status/convert)
json.hpp — JSON helpers
tests/ — Catch2 unit tests (≥ 70% line coverage enforced)
testdata/ — RELAY spec test vectors
docker/ — Dockerfile + docker-compose.yml
| Property | Value |
|---|---|
| Max frame ID | 0x3F (6-bit) |
| Max data length | 8 bytes |
| Diagnostic request ID | 0x3C |
| Diagnostic response ID | 0x3D |
| Classic checksum | Data bytes only |
| Enhanced checksum | PID + data bytes |
| Diagnostic frames | Classic checksum only |
Protected Identifier (PID):
P0 = ID0 ^ ID1 ^ ID2 ^ ID4 (bit 6)
P1 = NOT(ID1 ^ ID3 ^ ID4 ^ ID5) (bit 7)
cpp-LIN exposes a RELAY v2.0 INode adapter:
#include <lin/lin.hpp> #include <lin/virtual/bus.hpp> auto bus = std::make_shared<lin::virt::Bus>(); auto node = lin::adapt(bus); // node is a relay::INode* — plug it into any RELAY router
The CLI exposes the RELAY test harness interface:
relay conform ./build/cli/cpp-lin-cli --strict relay interop --protocol LIN ./build/cli/cpp-lin-cli
#include <lin/safety/e2e.hpp> lin::safety::Config cfg{.data_id = 0x0042, .source_id = 0x0001}; lin::safety::Protector prot(cfg); lin::safety::Receiver recv(cfg); std::vector<uint8_t> payload = {0x01, 0x02, 0x03}; auto protected_msg = prot.protect(payload); auto unwrapped = recv.unwrap(protected_msg); // throws E2EError on failure
#include <lin/ldf/parser.hpp> #include <fstream> std::ifstream f("example.ldf"); auto db = lin::ldf::parse(f); auto& fr = db->frame(0x10); // frame by ID auto decoded = db->decode(0x10, {0xAB, 0xCD}); // signal values
All requirements are tracked in .fusa-reqs.json. Every source file carries
// fusa:req REQ-XXX-NNN annotations; every test file carries
// fusa:test REQ-XXX-NNN annotations. The CI pipeline runs cpfusa qualify
to enforce ASIL-B traceability coverage.
See SAFETY_PLAN.md for the full safety plan.
See CONTRIBUTING.md. All commits require a DCO sign-off:
git commit -s -m "feat: your change"Mozilla Public License 2.0 — see LICENSE.
Copyright (c) 2026 Matt Jones. All rights reserved.