moonbit-canbus

A deterministic, dependency-free CAN 2.0 and CAN-FD toolkit for MoonBit.

can
can-fd
dbc
isotp
j1939
vehicle-network
moon add myc1234567/moonbit-canbus@0.1.0
Download zip
Version
0.1.0
License
Apache-2.0
Last updated
2 hours ago
Downloads
2
README

#MoonBit CAN Bus

一个纯 MoonBit、无原生依赖的 CAN 2.0 / CAN-FD 协议与仿真工具包,面向汽车电子、机器人、工业控制和协议测试场景。项目把帧语义、线级编解码、传输层、诊断、DBC 信号、网关和确定性仿真组合成可独立复用的 API。

#项目定位

本项目解决的是“没有硬件也能可靠验证控制器网络逻辑”的问题:同一套数据模型可以用于协议单元测试、DBC 信号解码、虚拟 ECU 联调、日志分析和网关规则验证。它不直接驱动 CAN 控制器,也不替代操作系统的 SocketCAN 或商业硬件 SDK。

#核心能力

  • 标准 11-bit、扩展 29-bit、数据帧、远程帧、错误帧和 CAN-FD 帧模型。
  • CAN-FD DLC 映射、CRC-15/17/21、位填充与去填充、完整 wire 编解码和稳定二进制帧格式。
  • 优先级仲裁、掩码/精确过滤器、确定性虚拟总线、节点注册、发送队列和多节点网络模型。
  • ISO-TP 分段与重组、J1939 标识符与 BAM、CANopen COB-ID/SDO/PDO,以及 UDS 请求、会话、DTC 编解码。
  • DBC BO_ / SG_ 解析、运行时信号编解码、规范化序列化、结构校验和 schema diff。
  • 路由网关、调度器、帧批处理、日志/trace、总线指标、延迟窗口和帧准入策略。

#快速开始

需要已安装 MoonBit stable 工具链。

moon check --target all --deny-warn moon test --target all --deny-warn

在 MoonBit 中创建并检查一帧:

let frame = @moonbit_canbus.data_frame(0x120, [0x2A]) catch {
_ => panic()
}
let wire = @moonbit_canbus.encode_frame(frame)
let restored = @moonbit_canbus.decode_frame(wire) catch {
_ => panic()
}
assert_true(@moonbit_canbus.frame_equal(frame, restored))

#CLI

CLI 位于 src/cmd/canctl,用于快速查看帧编码和指标:

moon run src/cmd/canctl -- demo moon run src/cmd/canctl -- decode 01000000012303102030

基准程序位于 src/cmd/bench,执行 100,000 次稳定帧编码/解码并输出耗时、吞吐、字节数和校验值:

moon run src/cmd/bench

#架构

层次主要模块责任
Frame / wireframe.mbt, frame_codec.mbt, wire.mbt, wire_codec.mbt帧不变量、DLC、CRC、bit stuffing 和可移植编码
Transporttransport.mbt, isotp_engine.mbt, transport_queue.mbtISO-TP、队列、时序与边界处理
Databasedbc.mbt, dbc_extended.mbt, dbc_runtime.mbt, dbc_serializer.mbtDBC 解析、信号运行时和 schema 工具
Diagnosticsdiagnostic.mbt, uds_stack.mbt, diagnostic_session.mbt, diagnostic_codec.mbtUDS 服务、会话状态和 DTC 报文
Networkfilter.mbt, can_network.mbt, routing.mbt, simulation.mbt过滤、网关、多节点网络和确定性仿真
Analysistrace.mbt, trace_tools.mbt, metrics.mbt, latency.mbt日志、指标、延迟和质量分析

模块之间通过 FrameFilterTrace 等小型值对象连接,避免把硬件 I/O、时钟和协议状态耦合到核心算法中。

#基准

基准程序使用本地 MoonBit WASM-GC 后端和固定的 8-byte Classic CAN 数据帧,实际运行记录见 BENCHMARKS.md。基准输出包含可复核的迭代次数、墙钟耗时、吞吐和 checksum;不同机器和后端的绝对数值会变化,因此仓库不把单次机器结果当作性能承诺。

#测试与边界覆盖

测试覆盖 Classic CAN、CAN-FD、29-bit ID、64-byte payload、DLC 边界、CRC/bit stuffing、ISO-TP 长消息、UDS 负响应、DTC、DBC 非法布局、队列满/空、时间逆序、节点离线、速率限制、trace 和延迟百分位等路径。

本地质量门禁:

moon fmt moon check --target all --deny-warn moon test --target all --deny-warn moon info

#CI

.github/workflows/check.yml 在 Linux、macOS 和 Windows 上安装 MoonBit stable,显式配置 Node.js 运行时,执行格式检查、moon info、全后端 check/build/test,并验证生产 MoonBit 源码规模门槛。工作流使用官方安装脚本,便于工具链持续跟随 stable。

#许可证

本项目采用 Apache License 2.0

#
AdmissionError

pub suberror AdmissionError {
InvalidRule
NoMatchingRule
ProtocolNotAllowed
PayloadTooLarge
RemoteNotAllowed
RateExceeded
TimestampReversed
} derive(
Debug
)

Errors raised by a frame admission policy.

#
BatchError

pub suberror BatchError {
EmptyBatch
BatchTooLarge
InvalidRecord
ChecksumMismatch
} derive(
Debug
)

Errors raised by batch processing and binary archive helpers.

#
BitError

pub suberror BitError {
InvalidWidth
InvalidValue
OutOfBounds
} derive(
Debug
)

Errors raised by the bit-level reader and writer.

#
CanOpenError

pub suberror CanOpenError {
InvalidNodeId
InvalidCobId
InvalidIndex
InvalidSdoPayload
InvalidDataLength
} derive(
Debug
)

Errors raised by CANopen identifier and SDO helpers.

#
CanTextError

pub suberror CanTextError {
InvalidHeader
InvalidFieldCount
InvalidTimestamp
InvalidPayload
} derive(
Debug
)

Errors raised by text log parsing.

#
CanTimingError

pub suberror CanTimingError {
InvalidClock
InvalidBitrate
InvalidSamplePoint
NoTimingCandidate
} derive(
Debug
)

Errors raised by CAN bit-timing calculations.

#
DbcError

pub suberror DbcError {
InvalidMessageLine(String)
InvalidSignalLine(String)
InvalidNumber(String)
}

A small, dependency-free DBC reader for message and signal definitions.

#
DbcExtendedError

pub suberror DbcExtendedError {
InvalidMessage
InvalidSignal
InvalidNumber
MissingMessage
InvalidRange
} derive(
Debug
)

Errors from the extended DBC reader.

#
DbcRuntimeError

pub suberror DbcRuntimeError {
InvalidSignalLayout
PayloadTooShort
PayloadTooLong
DuplicateSignal
MissingSignalValue
ValueOutOfRange
} derive(
Debug
)

Errors raised by checked DBC runtime operations.

#
DbcSchemaError

pub suberror DbcSchemaError {
DuplicateMessageId
InvalidIdentifier
EmptyMessageName
InvalidDlc
InvalidSignalLayout
OverlappingSignals
} derive(
Debug
)

Errors raised when validating or serializing a DBC schema.

#
DtcCodecError

pub suberror DtcCodecError {
InvalidCode
InvalidPayload
InvalidRecordLength
CapacityExceeded
} derive(
Debug
)

Errors raised while encoding or decoding diagnostic trouble codes.

#
FrameCodecError

pub suberror FrameCodecError {
UnsupportedVersion
Truncated
InvalidFlags
InvalidPayloadLength
InvalidHex
} derive(
Debug
)

Errors raised by the portable frame codec.

#
FrameError

pub suberror FrameError {
InvalidIdentifier
InvalidLength
} derive(
Debug
)

A frame validation error.

#
IsoTpError

pub suberror IsoTpError {
InvalidFrameSize
PayloadTooLarge
TruncatedPacket
InvalidFirstFrame
UnexpectedConsecutive
SequenceMismatch
LengthMismatch
UnsupportedFlowStatus
} derive(
Debug
)

Errors raised by checked ISO-TP operations.

#
J1939Error

pub suberror J1939Error {
InvalidPriority
InvalidPgn
InvalidAddress
InvalidPayloadLength
InvalidSequence
TransferTooLarge
} derive(
Debug
)

Errors raised by J1939 identifier and transport helpers.

#
LatencyError

pub suberror LatencyError {
InvalidCapacity
InvalidTimestamp
InvalidPercentile
} derive(
Debug
)

Errors raised by a latency measurement window.

#
NetworkError

pub suberror NetworkError {
InvalidNodeId
DuplicateNode
UnknownNode
InvalidTimestamp
QueueFull
} derive(
Debug
)

Errors raised by the deterministic multi-node network model.

#
NodeRegistryError

pub suberror NodeRegistryError {
InvalidNodeId
DuplicateNode
UnknownNode
} derive(
Debug
)

Errors raised by node registry operations.

#
PayloadError

pub suberror PayloadError {
InvalidOffset
InvalidWidth
InvalidCounter
InvalidFrame
} derive(
Debug
)

Payload transformation errors.

#
PdoError

pub suberror PdoError {
InvalidMapping
TooManyEntries
ValueTooLarge
PayloadOverflow
} derive(
Debug
)

CANopen PDO mapping errors.

#
QueueError

pub suberror QueueError {
InvalidCapacity
InvalidLimit
Full
Empty
UnknownSequence
} derive(
Debug
)

Errors raised by the bounded transmit queue.

#
RoutingError

pub suberror RoutingError {
InvalidOutputIdentifier
InvalidPrefix
PayloadOverflow
} derive(
Debug
)

Errors raised when a gateway transforms a frame.

#
SchedulerError

pub suberror SchedulerError {
InvalidPeriod
InvalidDeadline
DuplicateTask
UnknownTask
} derive(
Debug
)

Errors raised by the deterministic message scheduler.

#
SimulationError

pub suberror SimulationError {
TimeWentBackwards
InvalidPeriod
EventLimitReached
} derive(
Debug
)

Errors raised by deterministic network simulation.

#
TraceError

pub suberror TraceError {
NonMonotonicTimestamp
InvalidLine
InvalidTimestamp
InvalidFrame
} derive(
Debug
)

Errors raised when validating or parsing a trace log.

#
UdsError

pub suberror UdsError {
InvalidIdentifier
InvalidAddressFormat
EmptyPayload
InvalidBlockCounter
InvalidLength
} derive(
Debug
)

Additional errors for building and validating UDS exchanges.

#
UdsSessionError

pub suberror UdsSessionError {
InvalidTransition
SecurityRequired
ResponseTimeout
UnexpectedResponse
} derive(
Debug
)

Errors raised by the session state machine.

#
WireCodecError

pub suberror WireCodecError {
InvalidEof
InvalidCrc
InvalidControl
InvalidDlc
InvalidFrameBits
} derive(
Debug
)

Errors raised by the complete bit-level wire codec.

#
WireError

pub suberror WireError {
InvalidStuffedBit
}

Errors produced when removing CAN bit stuffing.

#
AdmissionDecision

pub struct AdmissionDecision {
accepted : Bool
rule_name : String
reason : String
}

The result of an admission check.

#
AdmissionDecision::accepted

fn AdmissionDecision::accepted(self : AdmissionDecision) -> Bool

#
AdmissionDecision::reason

fn AdmissionDecision::reason(self : AdmissionDecision) -> String

#
AdmissionDecision::rule_name

fn AdmissionDecision::rule_name(self : AdmissionDecision) -> String

#
AdmissionPolicy

pub struct AdmissionPolicy {
rules : Array[AdmissionRule]
accepted_count : Int
rejected_count : Int
last_timestamp_us : UInt64?
}

A first-match frame admission policy with counters and timing guards.

#
AdmissionPolicy::accepted

fn AdmissionPolicy::accepted(self : AdmissionPolicy) -> Int

#
AdmissionPolicy::add_rule

fn AdmissionPolicy::add_rule(self : AdmissionPolicy, rule : AdmissionRule) -> Unit

#
AdmissionPolicy::admit

fn AdmissionPolicy::admit(self : AdmissionPolicy, frame : Frame, timestamp_us : UInt64) -> Bool

Return whether a frame is admitted, preserving the policy counters.

#
AdmissionPolicy::evaluate

fn AdmissionPolicy::evaluate(self : AdmissionPolicy, frame : Frame, timestamp_us : UInt64) -> AdmissionDecision raise AdmissionError

Evaluate the first matching rule and update its rate window on success.

#
AdmissionPolicy::rejected

fn AdmissionPolicy::rejected(self : AdmissionPolicy) -> Int

#
AdmissionPolicy::reset

fn AdmissionPolicy::reset(self : AdmissionPolicy) -> Unit

Reset all per-rule timing windows and counters.

#
AdmissionPolicy::rule_count

fn AdmissionPolicy::rule_count(self : AdmissionPolicy) -> Int

#
AdmissionRule

pub struct AdmissionRule {
name : String
filter : Filter
max_payload : Int
allow_fd : Bool
allow_remote : Bool
min_interval_us : UInt64
last_seen_us : UInt64?
}

A named rule for a group of accepted frames.

#
AdmissionRule::allows_fd

fn AdmissionRule::allows_fd(self : AdmissionRule) -> Bool

#
AdmissionRule::allows_remote

fn AdmissionRule::allows_remote(self : AdmissionRule) -> Bool

#
AdmissionRule::max_payload

fn AdmissionRule::max_payload(self : AdmissionRule) -> Int

#
AdmissionRule::minimum_interval

fn AdmissionRule::minimum_interval(self : AdmissionRule) -> UInt64

#
AdmissionRule::name

fn AdmissionRule::name(self : AdmissionRule) -> String

#
BitReader

pub struct BitReader {
bits : Array[Bool]
position : Int
}

A sequential most-significant-bit-first reader.

#
BitReader::peek

fn BitReader::peek(self : BitReader, width : Int) -> UInt raise BitError

Inspect a bit without advancing the reader.

#
BitReader::position

fn BitReader::position(self : BitReader) -> Int

Return the current read offset.

#
BitReader::read

fn BitReader::read(self : BitReader, width : Int) -> UInt raise BitError

Read an unsigned value of exactly width bits.

#
BitReader::read_bit

fn BitReader::read_bit(self : BitReader) -> Bool raise BitError

Read one bit.

#
BitReader::read_signed

fn BitReader::read_signed(self : BitReader, width : Int) -> Int raise BitError

Read a signed two's-complement value of up to 31 bits.

#
BitReader::remaining

fn BitReader::remaining(self : BitReader) -> Int

Return the number of unread bits.

#
BitReader::skip

fn BitReader::skip(self : BitReader, width : Int) -> Unit raise BitError

Skip a number of bits.

#
BitWriter

pub struct BitWriter {
bits : Array[Bool]
}

A growable most-significant-bit-first writer.

#
BitWriter::align_byte

fn BitWriter::align_byte(self : BitWriter) -> Unit

Add zero padding until the writer reaches a byte boundary.

#
BitWriter::finish

fn BitWriter::finish(self : BitWriter) -> Array[Bool]

Return a defensive copy of the written bits.

#
BitWriter::length

fn BitWriter::length(self : BitWriter) -> Int

Return the number of bits currently written.

#
BitWriter::to_bytes

fn BitWriter::to_bytes(self : BitWriter) -> Array[Byte]

Return the written bits packed into bytes, padding the final byte with 0.

#
BitWriter::write

fn BitWriter::write(self : BitWriter, value : UInt, width : Int) -> Unit raise BitError

Append an unsigned value using exactly width high-to-low bits.

#
BitWriter::write_bit

fn BitWriter::write_bit(self : BitWriter, bit : Bool) -> Unit

Append one bit.

#
BitWriter::write_signed

fn BitWriter::write_signed(self : BitWriter, value : Int, width : Int) -> Unit raise BitError

Append a signed two's-complement value.

#
BusHealth

pub struct BusHealth {
state : BusHealthState
utilization : Double
drop_rate : Double
error_rate : Double
recommendations : Array[String]
}

A deterministic health assessment for dashboards and CI.

#
BusHealth::drop_rate

fn BusHealth::drop_rate(self : BusHealth) -> Double

#
BusHealth::error_rate

fn BusHealth::error_rate(self : BusHealth) -> Double

#
BusHealth::recommendations

fn BusHealth::recommendations(self : BusHealth) -> Array[String]

#
BusHealth::state

fn BusHealth::state(self : BusHealth) -> BusHealthState

#
BusHealth::to_text

fn BusHealth::to_text(self : BusHealth) -> String

#
BusHealth::utilization

fn BusHealth::utilization(self : BusHealth) -> Double

#
BusHealthState

pub enum BusHealthState {
Healthy
Busy
Degraded
Overloaded
Silent
} derive(
Debug
)

Health levels for a monitored CAN channel.

#
ByteOrder

pub(all) enum ByteOrder {
BigEndian
LittleEndian
}

Byte ordering used by application payload adapters.

#
CanBitTiming

pub struct CanBitTiming {
clock_hz : UInt
bitrate : UInt
prescaler : UInt
time_quanta : UInt
propagation_segment : UInt
phase_segment_1 : UInt
phase_segment_2 : UInt
sample_point_percent : Double
}

A nominal or data-phase bit-timing candidate.

#
CanBitTiming::actual_bitrate

fn CanBitTiming::actual_bitrate(self : CanBitTiming) -> UInt

Return the actual bitrate represented by a timing configuration.

#
CanBitTiming::bit_time_ns

fn CanBitTiming::bit_time_ns(self : CanBitTiming) -> UInt64

#
CanBitTiming::bitrate

fn CanBitTiming::bitrate(self : CanBitTiming) -> UInt

#
CanBitTiming::clock_hz

fn CanBitTiming::clock_hz(self : CanBitTiming) -> UInt

#
CanBitTiming::prescaler

fn CanBitTiming::prescaler(self : CanBitTiming) -> UInt

#
CanBitTiming::sample_point

fn CanBitTiming::sample_point(self : CanBitTiming) -> Double

#
CanBitTiming::time_quanta

fn CanBitTiming::time_quanta(self : CanBitTiming) -> UInt

#
CanFdTiming

pub struct CanFdTiming {
nominal : CanBitTiming
data : CanBitTiming
}

CAN-FD timing for nominal and data phases.

#
CanFdTiming::data

#
CanFdTiming::nominal

fn CanFdTiming::nominal(self : CanFdTiming) -> CanBitTiming

#
CanGateway

pub struct CanGateway {
routes : Array[RouteRule]
forwarded : Int
rejected : Int
}

A stateless rule-based CAN gateway.

#
CanGateway::add_rule

fn CanGateway::add_rule(self : CanGateway, rule : RouteRule) -> Unit

#
CanGateway::forward

fn CanGateway::forward(self : CanGateway, input : Frame) -> RoutedFrame? raise RoutingError

Apply the first matching rule.

#
CanGateway::forwarded

fn CanGateway::forwarded(self : CanGateway) -> Int

#
CanGateway::rejected

fn CanGateway::rejected(self : CanGateway) -> Int

#
CanGateway::rule_count

fn CanGateway::rule_count(self : CanGateway) -> Int

#
CanGateway::rule_names

fn CanGateway::rule_names(self : CanGateway) -> Array[String]

Return route names in insertion order.

#
CanLog

pub struct CanLog {
entries : Array[CanLogEntry]
}

A portable text log with stable ordering.

#
CanLog::entries

fn CanLog::entries(self : CanLog) -> Array[CanLogEntry]

#
CanLog::filter_channel

fn CanLog::filter_channel(self : CanLog, channel : String) -> CanLog

#
CanLog::length

fn CanLog::length(self : CanLog) -> Int

#
CanLog::push

fn CanLog::push(self : CanLog, timestamp_us : UInt64, frame : Frame, channel? : String) -> Unit

#
CanLog::sorted

fn CanLog::sorted(self : CanLog) -> CanLog

#
CanLog::to_text

fn CanLog::to_text(self : CanLog) -> String

Encode a log with a header and one comma-separated record per line.

#
CanLogEntry

pub struct CanLogEntry {
timestamp_us : UInt64
frame : Frame
channel : String
}

A human-readable CAN log record.

#
CanLogEntry::channel

fn CanLogEntry::channel(self : CanLogEntry) -> String

#
CanLogEntry::frame

fn CanLogEntry::frame(self : CanLogEntry) -> Frame

#
CanLogEntry::timestamp

fn CanLogEntry::timestamp(self : CanLogEntry) -> UInt64

#
CanNetwork

pub struct CanNetwork {
timeout_us : UInt64
now_us : UInt64
nodes : Array[NetworkNode]
queue : FrameQueue
delivered : Int
}

A deterministic CAN network with bounded transmit buffering and liveness.

#
CanNetwork::add_node

fn CanNetwork::add_node(self : CanNetwork, node_id : Byte, name : String, timestamp_us : UInt64) -> Unit raise NetworkError

Register a node at a known timestamp.

#
CanNetwork::delivered

fn CanNetwork::delivered(self : CanNetwork) -> Int

#
CanNetwork::heartbeat

fn CanNetwork::heartbeat(self : CanNetwork, node_id : Byte, timestamp_us : UInt64) -> Unit raise NetworkError

Record a heartbeat and bring a node online.

#
CanNetwork::node

fn CanNetwork::node(self : CanNetwork, node_id : Byte) -> NetworkNode?

#
CanNetwork::node_count

fn CanNetwork::node_count(self : CanNetwork) -> Int

#
CanNetwork::now

fn CanNetwork::now(self : CanNetwork) -> UInt64

#
CanNetwork::offline_nodes

fn CanNetwork::offline_nodes(self : CanNetwork, timestamp_us : UInt64) -> Array[String] raise NetworkError

Mark nodes stale at a timestamp and return their stable names.

#
CanNetwork::pending

fn CanNetwork::pending(self : CanNetwork) -> Int

#
CanNetwork::poll

fn CanNetwork::poll(self : CanNetwork, timestamp_us : UInt64) -> Array[NetworkDelivery] raise NetworkError

Deliver every frame queued by timestamp_us in arbitration order.

#
CanNetwork::send

fn CanNetwork::send(self : CanNetwork, sender : Byte, frame : Frame, timestamp_us : UInt64) -> UInt raise NetworkError

Queue a frame from a registered sender.

#
CanNode

pub struct CanNode {
node_id : Byte
name : String
filter : Filter
received : Int
transmitted : Int
}

A monitored node and its receive filter.

#
CanNode::name

fn CanNode::name(self : CanNode) -> String

#
CanNode::node_id

fn CanNode::node_id(self : CanNode) -> Byte

#
CanNode::received

fn CanNode::received(self : CanNode) -> Int

#
CanNode::transmitted

fn CanNode::transmitted(self : CanNode) -> Int

#
CanOpenCobId

pub struct CanOpenCobId {
object_type : CanOpenCobType
node_id : Byte
identifier : UInt
}

A decoded CANopen communication object identifier.

#
CanOpenCobId::identifier

fn CanOpenCobId::identifier(self : CanOpenCobId) -> UInt

#
CanOpenCobId::node_id

fn CanOpenCobId::node_id(self : CanOpenCobId) -> Byte

#
CanOpenCobId::object_type

fn CanOpenCobId::object_type(self : CanOpenCobId) -> CanOpenCobType

#
CanOpenCobType

pub(all) enum CanOpenCobType {
Nmt
Sync
Emergency
Pdo1Transmit
Pdo1Receive
Pdo2Transmit
Pdo2Receive
Pdo3Transmit
Pdo3Receive
Pdo4Transmit
Pdo4Receive
SdoTransmit
SdoReceive
Heartbeat
} derive(
Debug
)

CANopen communication object types.

#
CanOpenNmtCommand

pub(all) enum CanOpenNmtCommand {
Start
Stop
EnterPreOperational
ResetNode
ResetCommunication
}

CANopen NMT state commands.

#
CanOpenSdoCommand

pub enum CanOpenSdoCommand {
DownloadInitiate(index~ : UInt, sub_index~ : Byte, data~ : Array[Byte])
UploadInitiate(index~ : UInt, sub_index~ : Byte)
DownloadSegment(toggle~ : Bool, data~ : Array[Byte], last~ : Bool)
UploadSegment(toggle~ : Bool)
Abort(index~ : UInt, sub_index~ : Byte, code~ : UInt)
}

A compact SDO command representation.

#
CanScheduler

pub struct CanScheduler {
tasks : Array[CanTask]
now_us : UInt64
executed : Int
missed : Int
}

A deterministic task scheduler independent from wall-clock time.

#
CanScheduler::add

fn CanScheduler::add(self : CanScheduler, name : String, frame : Frame, first_due_us : UInt64, period_us : UInt64, deadline_us : UInt64, count : Int) -> Unit raise SchedulerError

Add a task. period_us == 0 creates a one-shot task.

#
CanScheduler::executed

fn CanScheduler::executed(self : CanScheduler) -> Int

#
CanScheduler::find

fn CanScheduler::find(self : CanScheduler, name : String) -> CanTask?

#
CanScheduler::missed

fn CanScheduler::missed(self : CanScheduler) -> Int

#
CanScheduler::next_due

fn CanScheduler::next_due(self : CanScheduler) -> UInt64?

Return the next due time among pending tasks.

#
CanScheduler::now

fn CanScheduler::now(self : CanScheduler) -> UInt64

#
CanScheduler::remove

fn CanScheduler::remove(self : CanScheduler, name : String) -> Unit raise SchedulerError

#
CanScheduler::task_count

fn CanScheduler::task_count(self : CanScheduler) -> Int

#
CanScheduler::tick

fn CanScheduler::tick(self : CanScheduler, timestamp_us : UInt64) -> Array[SchedulerTick] raise SchedulerError

Execute all tasks due by timestamp_us, ordered by CAN arbitration.

#
CanTask

pub struct CanTask {
name : String
frame : Frame
next_due_us : UInt64
period_us : UInt64
deadline_us : UInt64
remaining : Int
priority : Int
}

A periodic or one-shot transmission task.

#
DbcDatabase

pub struct DbcDatabase {
messages : Array[Message]
}

A lookup table for message definitions.

#
DbcDatabase::add

fn DbcDatabase::add(self : DbcDatabase, item : Message) -> Unit raise DbcRuntimeError

Add a message definition, rejecting duplicate numeric identifiers.

#
DbcDatabase::by_id

fn DbcDatabase::by_id(self : DbcDatabase, id : UInt) -> Message?

Find a message by CAN identifier.

#
DbcDatabase::by_name

fn DbcDatabase::by_name(self : DbcDatabase, name : String) -> Message?

Find a message by its symbolic name.

#
DbcDatabase::decode_frame

fn DbcDatabase::decode_frame(self : DbcDatabase, frame : Frame) -> DecodedMessage? raise DbcRuntimeError

Decode a frame using the message selected by its identifier.

#
DbcDatabase::ids

fn DbcDatabase::ids(self : DbcDatabase) -> Array[UInt]

Return all numeric message identifiers.

#
DbcDatabase::length

fn DbcDatabase::length(self : DbcDatabase) -> Int

Return the number of definitions.

#
DbcDatabase::messages

fn DbcDatabase::messages(self : DbcDatabase) -> Array[Message]

Return all message definitions in source order.

#
DbcParseReport

pub struct DbcParseReport {
messages : Array[Message]
ignored_lines : Int
signal_lines : Int
}

A parse result that records ignored non-semantic lines.

#
DbcParseReport::ignored_lines

fn DbcParseReport::ignored_lines(self : DbcParseReport) -> Int

#
DbcParseReport::message_count

fn DbcParseReport::message_count(self : DbcParseReport) -> Int

#
DbcParseReport::messages

fn DbcParseReport::messages(self : DbcParseReport) -> Array[Message]

#
DbcParseReport::signal_lines

fn DbcParseReport::signal_lines(self : DbcParseReport) -> Int

#
DbcSchemaChange

pub struct DbcSchemaChange {
id : UInt
kind : String
before : String?
after : String?
}

A single schema difference between two message collections.

#
DbcSchemaChange::after

fn DbcSchemaChange::after(self : DbcSchemaChange) -> String?

#
DbcSchemaChange::before

fn DbcSchemaChange::before(self : DbcSchemaChange) -> String?

#
DbcSchemaChange::id

fn DbcSchemaChange::id(self : DbcSchemaChange) -> UInt

#
DbcSchemaChange::kind

fn DbcSchemaChange::kind(self : DbcSchemaChange) -> String

#
DbcSchemaReport

pub struct DbcSchemaReport {
message_count : Int
signal_count : Int
unique_identifier_count : Int
maximum_required_bytes : Int
}

Stable statistics for a validated DBC schema.

#
DbcSchemaReport::maximum_required_bytes

fn DbcSchemaReport::maximum_required_bytes(self : DbcSchemaReport) -> Int

#
DbcSchemaReport::message_count

fn DbcSchemaReport::message_count(self : DbcSchemaReport) -> Int

#
DbcSchemaReport::signal_count

fn DbcSchemaReport::signal_count(self : DbcSchemaReport) -> Int

#
DbcSchemaReport::unique_identifier_count

fn DbcSchemaReport::unique_identifier_count(self : DbcSchemaReport) -> Int

#
DecodedMessage

pub struct DecodedMessage {
id : UInt
name : String
signals : Array[DecodedSignal]
}

A decoded DBC message with the source identifier.

#
DecodedMessage::find

fn DecodedMessage::find(self : DecodedMessage, name : String) -> DecodedSignal?

Find a decoded value by signal name.

#
DecodedMessage::id

fn DecodedMessage::id(self : DecodedMessage) -> UInt

Return the message identifier from a decoded message.

#
DecodedMessage::name

fn DecodedMessage::name(self : DecodedMessage) -> String

Return the message name from a decoded message.

#
DecodedMessage::signals

Return decoded signals.

#
DecodedMessage::to_text

fn DecodedMessage::to_text(self : DecodedMessage) -> String

Render a decoded message as a stable diagnostic line.

#
DecodedSignal

pub struct DecodedSignal {
name : String
raw : UInt
physical : Double
unit : String
}

A decoded physical signal value.

#
DecodedSignal::name

fn DecodedSignal::name(self : DecodedSignal) -> String

#
DecodedSignal::physical

fn DecodedSignal::physical(self : DecodedSignal) -> Double

#
DecodedSignal::raw

fn DecodedSignal::raw(self : DecodedSignal) -> UInt

#
DecodedSignal::unit

fn DecodedSignal::unit(self : DecodedSignal) -> String

#
DiagnosticRequest

pub struct DiagnosticRequest {
service : UdsService
payload : Array[Byte]
}

A diagnostic request represented as a CAN payload.

#
DiagnosticRequest::payload

fn DiagnosticRequest::payload(self : DiagnosticRequest) -> Array[Byte]

Return a defensive copy of the UDS payload.

#
DiagnosticRequest::service

Return the service kind.

#
DiagnosticRequest::service_id

fn DiagnosticRequest::service_id(self : DiagnosticRequest) -> Byte

Return the request's numeric service identifier.

#
DiagnosticRequest::service_name

fn DiagnosticRequest::service_name(self : DiagnosticRequest) -> String

Return the service's name.

#
DiagnosticRequest::suppress_response

fn DiagnosticRequest::suppress_response(self : DiagnosticRequest) -> Bool

Return whether a request contains a suppress-positive-response bit.

#
DiagnosticResponse

pub enum DiagnosticResponse {
Positive(Array[Byte])
Negative(code~ : Byte)
Malformed
}

A response classification for a diagnostic exchange.

#
DtcRecord

pub struct DtcRecord {
code : UInt
status : Byte
occurrence : UInt
snapshot : Array[Byte]
}

A normalized three-byte diagnostic trouble code.

#
DtcRecord::code

fn DtcRecord::code(self : DtcRecord) -> UInt

#
DtcRecord::occurrence

fn DtcRecord::occurrence(self : DtcRecord) -> UInt

#
DtcRecord::snapshot

fn DtcRecord::snapshot(self : DtcRecord) -> Array[Byte]

#
DtcRecord::status

fn DtcRecord::status(self : DtcRecord) -> Byte

#
DtcReport

pub struct DtcReport {
subfunction : Byte
status_availability_mask : Byte
records : Array[DtcRecord]
}

A parsed ReadDTCInformation response.

#
DtcReport::records

fn DtcReport::records(self : DtcReport) -> Array[DtcRecord]

#
DtcReport::status_availability_mask

fn DtcReport::status_availability_mask(self : DtcReport) -> Byte

#
DtcReport::subfunction

fn DtcReport::subfunction(self : DtcReport) -> Byte

#
DtcStore

pub struct DtcStore {
capacity : Int
records : Array[DtcRecord]
updates : UInt
}

A bounded DTC store suitable for an ECU simulator or gateway cache.

#
DtcStore::clear_mask

fn DtcStore::clear_mask(self : DtcStore, code : UInt, mask : UInt) -> Int

Clear all records whose code matches a 24-bit mask.

#
DtcStore::find

fn DtcStore::find(self : DtcStore, code : UInt) -> DtcRecord?

#
DtcStore::length

fn DtcStore::length(self : DtcStore) -> Int

#
DtcStore::query_status

fn DtcStore::query_status(self : DtcStore, status_mask : Byte) -> Array[DtcRecord]

Query records whose status contains every bit in status_mask.

#
DtcStore::remove

fn DtcStore::remove(self : DtcStore, code : UInt) -> Bool

Remove one DTC, returning whether it existed.

#
DtcStore::snapshot

fn DtcStore::snapshot(self : DtcStore) -> Array[DtcRecord]

#
DtcStore::updates

fn DtcStore::updates(self : DtcStore) -> UInt

#
DtcStore::upsert

fn DtcStore::upsert(self : DtcStore, record : DtcRecord) -> Unit raise DtcCodecError

Add a code or update the status and occurrence count of an existing code.

#
Filter

pub struct Filter {
id : UInt
mask : UInt
extended : Bool?
}

A CAN acceptance filter.

#
Filter::extended

fn Filter::extended(self : Filter) -> Bool?

#
Filter::id

fn Filter::id(self : Filter) -> UInt

Return a filter's identifier pattern.

#
Filter::mask

fn Filter::mask(self : Filter) -> UInt

#
Filter::matches

fn Filter::matches(self : Filter, frame : Frame) -> Bool

Return whether a frame passes this filter.

#
FilterBank

pub struct FilterBank {
filters : Array[Filter]
}

A group of filters evaluated in insertion order.

#
FilterBank::accepts

fn FilterBank::accepts(self : FilterBank, frame : Frame) -> Bool

Test whether any filter accepts a frame. An empty bank rejects all frames.

#
FilterBank::add

fn FilterBank::add(self : FilterBank, filter : Filter) -> Unit

Add a filter to the bank.

#
FilterBank::filters

fn FilterBank::filters(self : FilterBank) -> Array[Filter]

#
FilterBank::length

fn FilterBank::length(self : FilterBank) -> Int

#
FilterIndex

pub struct FilterIndex {
bank : FilterBank
accepted : Int
rejected : Int
}

A compact exact-or-mask index for a monitoring application.

#
FilterIndex::accepted

fn FilterIndex::accepted(self : FilterIndex) -> Int

#
FilterIndex::check

fn FilterIndex::check(self : FilterIndex, frame : Frame) -> Bool

#
FilterIndex::rejected

fn FilterIndex::rejected(self : FilterIndex) -> Int

#
Frame

pub struct Frame {
id : UInt
extended : Bool
kind : FrameKind
protocol : Protocol
bitrate_switch : Bool
error_state_indicator : Bool
data : Array[Byte]
}

A normalized CAN frame.

#
Frame::bitrate_switch

fn Frame::bitrate_switch(self : Frame) -> Bool

Return whether the CAN-FD bit-rate switch is set.

#
Frame::data

fn Frame::data(self : Frame) -> Array[Byte]

Return a defensive copy of the payload.

#
Frame::dlc

fn Frame::dlc(self : Frame) -> Byte

Return the data length code for this frame.

#
Frame::error_state_indicator

fn Frame::error_state_indicator(self : Frame) -> Bool

Return whether the CAN-FD error-state indicator is set.

#
Frame::id

fn Frame::id(self : Frame) -> UInt

The arbitration identifier.

#
Frame::is_data

fn Frame::is_data(self : Frame) -> Bool

Return whether this frame carries application data.

#
Frame::is_error

fn Frame::is_error(self : Frame) -> Bool

Return whether this frame is a local simulation error.

#
Frame::is_extended

fn Frame::is_extended(self : Frame) -> Bool

Whether the frame uses the 29-bit identifier format.

#
Frame::is_remote

fn Frame::is_remote(self : Frame) -> Bool

Return whether this frame is a remote request.

#
Frame::kind

fn Frame::kind(self : Frame) -> FrameKind

Return the frame kind.

#
Frame::protocol

fn Frame::protocol(self : Frame) -> Protocol

Return the protocol version.

#
FrameAnalysis

pub struct FrameAnalysis {
unique_ids : Int
changed_payloads : Int
repeated_payloads : Int
average_payload : Double
minimum_gap_us : UInt64?
maximum_gap_us : UInt64?
}

A compact analysis of identifier and payload behavior.

#
FrameAnalysis::average_payload

fn FrameAnalysis::average_payload(self : FrameAnalysis) -> Double

#
FrameAnalysis::changed_payloads

fn FrameAnalysis::changed_payloads(self : FrameAnalysis) -> Int

#
FrameAnalysis::maximum_gap

fn FrameAnalysis::maximum_gap(self : FrameAnalysis) -> UInt64?

#
FrameAnalysis::minimum_gap

fn FrameAnalysis::minimum_gap(self : FrameAnalysis) -> UInt64?

#
FrameAnalysis::repeated_payloads

fn FrameAnalysis::repeated_payloads(self : FrameAnalysis) -> Int

#
FrameAnalysis::to_text

fn FrameAnalysis::to_text(self : FrameAnalysis) -> String

#
FrameAnalysis::unique_ids

fn FrameAnalysis::unique_ids(self : FrameAnalysis) -> Int

#
FrameBatch

pub struct FrameBatch {
sequence : UInt
frames : Array[Frame]
}

A validated batch of frames with a caller-provided sequence number.

#
FrameBatch::checksum

fn FrameBatch::checksum(self : FrameBatch) -> Byte

Return a non-cryptographic checksum suitable for corruption detection.

#
FrameBatch::encode

fn FrameBatch::encode(self : FrameBatch) -> Array[Byte]

Encode a batch as a length-prefixed binary archive.

#
FrameBatch::frames

fn FrameBatch::frames(self : FrameBatch) -> Array[Frame]

#
FrameBatch::length

fn FrameBatch::length(self : FrameBatch) -> Int

#
FrameBatch::payload_bytes

fn FrameBatch::payload_bytes(self : FrameBatch) -> Int

Return the sum of payload bytes in the batch.

#
FrameBatch::sequence

fn FrameBatch::sequence(self : FrameBatch) -> UInt

#
FrameClass

pub enum FrameClass {
ClassicData
ClassicRemote
CanFdData
SimulationError
}

A coarse frame class useful for metrics and routing policies.

#
FrameKind

pub enum FrameKind {
Data
Remote
Error
}

A CAN frame kind.

#
FrameMetrics

pub struct FrameMetrics {
total : Int
classic_data : Int
classic_remote : Int
can_fd : Int
errors : Int
extended : Int
payload_bytes : Int
wire_bits : Int
minimum_id : UInt?
maximum_id : UInt?
identifiers : Array[UInt]
payload_histogram : Array[Int]
}

Aggregate counters for a collection of CAN frames.

#
FrameMetrics::can_fd

fn FrameMetrics::can_fd(self : FrameMetrics) -> Int

#
FrameMetrics::classic_data

fn FrameMetrics::classic_data(self : FrameMetrics) -> Int

#
FrameMetrics::classic_remote

fn FrameMetrics::classic_remote(self : FrameMetrics) -> Int

#
FrameMetrics::errors

fn FrameMetrics::errors(self : FrameMetrics) -> Int

#
FrameMetrics::extended

fn FrameMetrics::extended(self : FrameMetrics) -> Int

#
FrameMetrics::identifiers

fn FrameMetrics::identifiers(self : FrameMetrics) -> Array[UInt]

#
FrameMetrics::maximum_id

fn FrameMetrics::maximum_id(self : FrameMetrics) -> UInt?

#
FrameMetrics::minimum_id

fn FrameMetrics::minimum_id(self : FrameMetrics) -> UInt?

#
FrameMetrics::payload_bytes

fn FrameMetrics::payload_bytes(self : FrameMetrics) -> Int

#
FrameMetrics::payload_count

fn FrameMetrics::payload_count(self : FrameMetrics, length : Int) -> Int

#
FrameMetrics::to_text

fn FrameMetrics::to_text(self : FrameMetrics) -> String

Render a stable metrics report for a CLI or CI artifact.

#
FrameMetrics::total

fn FrameMetrics::total(self : FrameMetrics) -> Int

#
FrameMetrics::wire_bits

fn FrameMetrics::wire_bits(self : FrameMetrics) -> Int

#
FrameQueue

pub struct FrameQueue {
capacity : Int
next_sequence : UInt
items : Array[QueueItem]
dropped : Int
}

A deterministic priority queue for CAN transmit pipelines.

#
FrameQueue::capacity

fn FrameQueue::capacity(self : FrameQueue) -> Int

#
FrameQueue::clear

fn FrameQueue::clear(self : FrameQueue) -> Unit

Remove every pending item.

#
FrameQueue::dequeue

fn FrameQueue::dequeue(self : FrameQueue) -> QueueItem raise QueueError

Remove the highest-priority item.

#
FrameQueue::dropped

fn FrameQueue::dropped(self : FrameQueue) -> Int

#
FrameQueue::enqueue

fn FrameQueue::enqueue(self : FrameQueue, channel : Byte, frame : Frame, enqueued_us : UInt64, deadline_us : UInt64) -> UInt raise QueueError

Add a frame and return its monotonic sequence number.

#
FrameQueue::expire

fn FrameQueue::expire(self : FrameQueue, now_us : UInt64) -> Array[QueueItem]

Remove items whose deadline has expired at now_us.

#
FrameQueue::is_empty

fn FrameQueue::is_empty(self : FrameQueue) -> Bool

#
FrameQueue::is_full

fn FrameQueue::is_full(self : FrameQueue) -> Bool

#
FrameQueue::length

fn FrameQueue::length(self : FrameQueue) -> Int

#
FrameQueue::peek

fn FrameQueue::peek(self : FrameQueue) -> QueueItem?

Return the highest-priority item without removing it.

#
FrameQueue::remove

fn FrameQueue::remove(self : FrameQueue, sequence : UInt) -> QueueItem raise QueueError

Remove a particular sequence number.

#
FrameQueue::snapshot

fn FrameQueue::snapshot(self : FrameQueue) -> Array[QueueItem]

#
FrameQueue::take_channel

fn FrameQueue::take_channel(self : FrameQueue, channel : Byte, limit : Int) -> Array[QueueItem] raise QueueError

Take up to limit items for one logical channel.

#
FrameReport

pub struct FrameReport {
valid : Bool
violations : Array[FrameViolation]
wire_bits : Int
stuffed_bits : Int
}

The result of validating a normalized frame.

#
FrameReport::is_valid

fn FrameReport::is_valid(self : FrameReport) -> Bool

#
FrameReport::stuffed_bits

fn FrameReport::stuffed_bits(self : FrameReport) -> Int

#
FrameReport::violations

fn FrameReport::violations(self : FrameReport) -> Array[FrameViolation]

#
FrameReport::wire_bits

fn FrameReport::wire_bits(self : FrameReport) -> Int

#
FrameViolation

pub enum FrameViolation {
IdentifierRange
ClassicPayloadRange
FdPayloadRange
RemoteCarriesData
FdControlOnClassic
InvalidErrorShape
NonCanonicalDlc
} derive(
Debug
)

A concrete validation finding.

#
GatewayPair

pub struct GatewayPair {
left_to_right : CanGateway
right_to_left : CanGateway
}

Create a bidirectional bridge from two gateways.

#
GatewayPair::left

fn GatewayPair::left(self : GatewayPair) -> CanGateway

#
GatewayPair::right

fn GatewayPair::right(self : GatewayPair) -> CanGateway

#
IsoTpConfig

pub struct IsoTpConfig {
frame_bytes : Int
block_size : Byte
separation_time : Byte
}

ISO-TP transfer parameters for classic CAN and CAN-FD.

#
IsoTpConfig::block_size

fn IsoTpConfig::block_size(self : IsoTpConfig) -> Byte

#
IsoTpConfig::frame_bytes

fn IsoTpConfig::frame_bytes(self : IsoTpConfig) -> Int

#
IsoTpConfig::separation_time

fn IsoTpConfig::separation_time(self : IsoTpConfig) -> Byte

#
IsoTpPacket

pub enum IsoTpPacket {
Single(payload~ : Array[Byte])
First(total_length~ : Int, payload~ : Array[Byte])
Consecutive(sequence~ : Byte, payload~ : Array[Byte])
FlowControl(status~ : Byte, block_size~ : Byte, separation_time~ : Byte)
}

A decoded ISO-TP packet.

#
IsoTpReceiver

pub struct IsoTpReceiver {
config : IsoTpConfig
total_length : Int
payload : Array[Byte]
next_sequence : Byte
block_count : Int
}

An incremental ISO-TP receiver for a single outstanding transfer.

#
IsoTpReceiver::flow_control

fn IsoTpReceiver::flow_control(self : IsoTpReceiver) -> Array[Byte]

Return a flow-control packet for this receiver's configured limits.

#
IsoTpReceiver::push

fn IsoTpReceiver::push(self : IsoTpReceiver, packet : IsoTpPacket) -> IsoTpStatus raise IsoTpError

Feed one decoded packet into the receiver.

#
IsoTpReceiver::reset

fn IsoTpReceiver::reset(self : IsoTpReceiver) -> Unit

Clear the current transfer.

#
IsoTpStatus

pub enum IsoTpStatus {
Waiting(received~ : Int, total~ : Int)
Complete(payload~ : Array[Byte])
}

The state of an incremental receiver.

#
J1939Id

pub struct J1939Id {
priority : Byte
data_page : Bool
pdu_format : Byte
pdu_specific : Byte
source_address : Byte
}

A decoded 29-bit J1939 identifier.

#
J1939Id::data_page

fn J1939Id::data_page(self : J1939Id) -> Bool

#
J1939Id::destination

fn J1939Id::destination(self : J1939Id) -> Byte?

#
J1939Id::pdu_format

fn J1939Id::pdu_format(self : J1939Id) -> Byte

#
J1939Id::pdu_specific

fn J1939Id::pdu_specific(self : J1939Id) -> Byte

#
J1939Id::pgn

fn J1939Id::pgn(self : J1939Id) -> UInt

Return the PGN, omitting destination address for PDU1 messages.

#
J1939Id::priority

fn J1939Id::priority(self : J1939Id) -> Byte

#
J1939Id::source

fn J1939Id::source(self : J1939Id) -> Byte

The source address of a J1939 message.

#
J1939Message

pub struct J1939Message {
identifier : J1939Id
payload : Array[Byte]
}

A J1939 application payload with its decoded identifier.

#
J1939Message::identifier

fn J1939Message::identifier(self : J1939Message) -> J1939Id

#
J1939Message::payload

fn J1939Message::payload(self : J1939Message) -> Array[Byte]

#
J1939Message::to_frame

fn J1939Message::to_frame(self : J1939Message) -> Frame raise FrameError

Create a data frame from a J1939 message.

#
LatencySample

pub struct LatencySample {
sequence : UInt
created_us : UInt64
completed_us : UInt64
payload_bytes : Int
}

One completed request/response timing sample.

#
LatencySample::completed_at

fn LatencySample::completed_at(self : LatencySample) -> UInt64

#
LatencySample::created_at

fn LatencySample::created_at(self : LatencySample) -> UInt64

#
LatencySample::duration

fn LatencySample::duration(self : LatencySample) -> UInt64

#
LatencySample::payload_bytes

fn LatencySample::payload_bytes(self : LatencySample) -> Int

#
LatencySample::sequence

fn LatencySample::sequence(self : LatencySample) -> UInt

#
LatencyStats

pub struct LatencyStats {
count : Int
minimum_us : UInt64?
maximum_us : UInt64?
average_us : Double
p95_us : UInt64?
jitter_us : UInt64
payload_bytes : Int
}

A summary of samples currently retained by a latency window.

#
LatencyStats::average

fn LatencyStats::average(self : LatencyStats) -> Double

#
LatencyStats::count

fn LatencyStats::count(self : LatencyStats) -> Int

#
LatencyStats::has_data

fn LatencyStats::has_data(self : LatencyStats) -> Bool

#
LatencyStats::jitter

fn LatencyStats::jitter(self : LatencyStats) -> UInt64

#
LatencyStats::maximum

fn LatencyStats::maximum(self : LatencyStats) -> UInt64?

#
LatencyStats::minimum

fn LatencyStats::minimum(self : LatencyStats) -> UInt64?

#
LatencyStats::p95

fn LatencyStats::p95(self : LatencyStats) -> UInt64?

#
LatencyStats::payload_bytes

fn LatencyStats::payload_bytes(self : LatencyStats) -> Int

#
LatencyStats::throughput_bytes_per_second

fn LatencyStats::throughput_bytes_per_second(self : LatencyStats, duration_us : UInt64) -> Double

Calculate payload throughput over an observation interval.

#
LatencyStats::to_text

fn LatencyStats::to_text(self : LatencyStats) -> String

Render a compact, stable summary for benchmark artifacts.

#
LatencyWindow

pub struct LatencyWindow {
capacity : Int
next_sequence : UInt
samples : Array[LatencySample]
last_completed_us : UInt64?
}

A bounded rolling timing window for transport and diagnostic paths.

#
LatencyWindow::capacity

fn LatencyWindow::capacity(self : LatencyWindow) -> Int

#
LatencyWindow::is_empty

fn LatencyWindow::is_empty(self : LatencyWindow) -> Bool

#
LatencyWindow::latest

Return the newest retained sample, if any.

#
LatencyWindow::length

fn LatencyWindow::length(self : LatencyWindow) -> Int

#
LatencyWindow::oldest

Return the oldest retained sample, if any.

#
LatencyWindow::percentile

fn LatencyWindow::percentile(self : LatencyWindow, percent : Int) -> UInt64 raise LatencyError

Return an arbitrary percentile using nearest-rank selection.

#
LatencyWindow::record

fn LatencyWindow::record(self : LatencyWindow, created_us : UInt64, completed_us : UInt64, payload_bytes : Int) -> UInt raise LatencyError

Record a completed sample and return its sequence number.

#
LatencyWindow::samples

#
LatencyWindow::stats

Calculate a stable summary of the retained timing samples.

#
Message

pub struct Message {
id : UInt
name : String
dlc : Int
signals : Array[Signal]
}

A CAN message with named signals.

#
Message::add_signal

fn Message::add_signal(self : Message, item : Signal) -> Unit

Add a signal to a message.

#
Message::decode

fn Message::decode(self : Message, data : Array[Byte]) -> DecodedMessage raise DbcRuntimeError

Decode all signals in a payload.

#
Message::dlc

fn Message::dlc(self : Message) -> Int

The configured payload length.

#
Message::encode_frame

fn Message::encode_frame(self : Message, values : Map[String, Double], extended? : Bool) -> Frame raise DbcRuntimeError

Encode a message definition and values as a CAN frame.

#
Message::encode_values

fn Message::encode_values(self : Message, values : Map[String, Double], initial? : Array[Byte]) -> Array[Byte] raise DbcRuntimeError

Encode physical signal values into a message payload.

#
Message::find

fn Message::find(self : Message, name : String) -> Signal?

Find a signal by name.

#
Message::id

fn Message::id(self : Message) -> UInt

The message identifier.

#
Message::name

fn Message::name(self : Message) -> String

The message name.

#
Message::required_bytes

fn Message::required_bytes(self : Message) -> Int

Return a message's maximum configured bit end.

#
Message::schema_text

fn Message::schema_text(self : Message) -> String

Return a stable schema summary for tooling.

#
Message::signal_count

fn Message::signal_count(self : Message) -> Int

Return the number of defined signals.

#
Message::signals

fn Message::signals(self : Message) -> Array[Signal]

Return signal definitions in source order.

#
Message::signals_by_start_bit

fn Message::signals_by_start_bit(self : Message) -> Array[Signal]

Return a message's signals ordered by start bit.

#
Message::validate

fn Message::validate(self : Message) -> Bool

Validate message size and all signal bit ranges.

#
NetworkDelivery

pub struct NetworkDelivery {
timestamp_us : UInt64
sender : Byte
frame : Frame
recipients : Array[String]
}

One broadcast delivery produced by CanNetwork::poll.

#
NetworkDelivery::frame

#
NetworkDelivery::recipients

fn NetworkDelivery::recipients(self : NetworkDelivery) -> Array[String]

#
NetworkDelivery::sender

fn NetworkDelivery::sender(self : NetworkDelivery) -> Byte

#
NetworkDelivery::timestamp

fn NetworkDelivery::timestamp(self : NetworkDelivery) -> UInt64

#
NetworkNode

pub struct NetworkNode {
node_id : Byte
name : String
last_seen_us : UInt64
online : Bool
transmitted : Int
received : Int
}

A node registered with the network model.

#
NetworkNode::last_seen

fn NetworkNode::last_seen(self : NetworkNode) -> UInt64

#
NetworkNode::name

fn NetworkNode::name(self : NetworkNode) -> String

#
NetworkNode::node_id

fn NetworkNode::node_id(self : NetworkNode) -> Byte

#
NetworkNode::online

fn NetworkNode::online(self : NetworkNode) -> Bool

#
NetworkNode::received

fn NetworkNode::received(self : NetworkNode) -> Int

#
NetworkNode::transmitted

fn NetworkNode::transmitted(self : NetworkNode) -> Int

#
NodeRegistry

pub struct NodeRegistry {
nodes : Array[CanNode]
}

A registry used by simulations and gateway applications.

#
NodeRegistry::deliver

fn NodeRegistry::deliver(self : NodeRegistry, frame : Frame) -> Array[String]

Deliver a frame to every matching registered node.

#
NodeRegistry::find

fn NodeRegistry::find(self : NodeRegistry, node_id : Byte) -> CanNode?

#
NodeRegistry::length

fn NodeRegistry::length(self : NodeRegistry) -> Int

#
NodeRegistry::record_transmission

fn NodeRegistry::record_transmission(self : NodeRegistry, node_id : Byte) -> Unit raise NodeRegistryError

Record a transmission for a node.

#
NodeRegistry::register

fn NodeRegistry::register(self : NodeRegistry, node_id : Byte, name : String, filter : Filter) -> Unit raise NodeRegistryError

#
NodeRegistry::unregister

fn NodeRegistry::unregister(self : NodeRegistry, node_id : Byte) -> Unit raise NodeRegistryError

#
PdoMapEntry

pub struct PdoMapEntry {
index : UInt
sub_index : Byte
bit_offset : Int
bit_length : Int
}

One object-dictionary entry mapped into a PDO.

#
PdoMapEntry::bit_length

fn PdoMapEntry::bit_length(self : PdoMapEntry) -> Int

#
PdoMapEntry::bit_offset

fn PdoMapEntry::bit_offset(self : PdoMapEntry) -> Int

#
PdoMapEntry::index

fn PdoMapEntry::index(self : PdoMapEntry) -> UInt

#
PdoMapEntry::sub_index

fn PdoMapEntry::sub_index(self : PdoMapEntry) -> Byte

#
PdoMapping

pub struct PdoMapping {
entries : Array[PdoMapEntry]
payload_bytes : Int
}

A bit-packed PDO mapping.

#
PdoMapping::add

fn PdoMapping::add(self : PdoMapping, index : UInt, sub_index : Byte, bit_length : Int) -> Unit raise PdoError

Add a mapping entry at the next available bit offset.

#
PdoMapping::entries

fn PdoMapping::entries(self : PdoMapping) -> Array[PdoMapEntry]

#
PdoMapping::length

fn PdoMapping::length(self : PdoMapping) -> Int

#
PdoMapping::pack

fn PdoMapping::pack(self : PdoMapping, values : Array[UInt]) -> Array[Byte] raise PdoError

Pack values in mapping order into a little-endian bit payload.

#
PdoMapping::payload_bytes

fn PdoMapping::payload_bytes(self : PdoMapping) -> Int

#
PdoMapping::unpack

fn PdoMapping::unpack(self : PdoMapping, data : Array[Byte]) -> Array[PdoValue] raise PdoError

Unpack all mapped values from a PDO payload.

#
PdoValue

pub struct PdoValue {
index : UInt
sub_index : Byte
value : UInt
}

A decoded mapped value.

#
PdoValue::index

fn PdoValue::index(self : PdoValue) -> UInt

#
PdoValue::sub_index

fn PdoValue::sub_index(self : PdoValue) -> Byte

#
PdoValue::value

fn PdoValue::value(self : PdoValue) -> UInt

#
PeriodicPublisher

pub struct PeriodicPublisher {
source : String
frame : Frame
period_us : UInt64
remaining : Int
}

A periodic publisher registered with a simulation.

#
Pgn

pub struct Pgn {
number : UInt
name : String
data_length : Int
}

A J1939 parameter group entry.

#
Pgn::name

fn Pgn::name(self : Pgn) -> String

Return the PGN label.

#
Pgn::number

fn Pgn::number(self : Pgn) -> UInt

Return the PGN number.

#
Protocol

pub enum Protocol {
Can20
CanFd
}

A CAN bus protocol version.

#
QueueItem

pub struct QueueItem {
sequence : UInt
channel : Byte
frame : Frame
enqueued_us : UInt64
deadline_us : UInt64
}

A queued frame with timing and channel metadata.

#
QueueItem::channel

fn QueueItem::channel(self : QueueItem) -> Byte

#
QueueItem::deadline

fn QueueItem::deadline(self : QueueItem) -> UInt64

#
QueueItem::enqueued_at

fn QueueItem::enqueued_at(self : QueueItem) -> UInt64

#
QueueItem::frame

fn QueueItem::frame(self : QueueItem) -> Frame

#
QueueItem::sequence

fn QueueItem::sequence(self : QueueItem) -> UInt

#
RouteRule

pub struct RouteRule {
name : String
filter : Filter
output_id : UInt?
output_extended : Bool?
prefix : Array[Byte]
strip_prefix : Int
}

A deterministic one-way gateway rule.

#
RouteRule::name

fn RouteRule::name(self : RouteRule) -> String

Return a route's stable name.

#
RouteRule::prefix

fn RouteRule::prefix(self : RouteRule) -> Array[Byte]

Return the rule's payload prefix.

#
RoutedFrame

pub struct RoutedFrame {
rule_name : String
input_id : UInt
frame : Frame
}

A frame accepted and transformed by a route.

#
RoutedFrame::frame

fn RoutedFrame::frame(self : RoutedFrame) -> Frame

#
RoutedFrame::input_id

fn RoutedFrame::input_id(self : RoutedFrame) -> UInt

#
RoutedFrame::rule_name

fn RoutedFrame::rule_name(self : RoutedFrame) -> String

#
ScheduledFrame

pub struct ScheduledFrame {
timestamp_us : UInt64
frame : Frame
source : String
}

A frame scheduled for a simulated bus time.

#
ScheduledFrame::frame

fn ScheduledFrame::frame(self : ScheduledFrame) -> Frame

#
ScheduledFrame::source

fn ScheduledFrame::source(self : ScheduledFrame) -> String

#
ScheduledFrame::timestamp

fn ScheduledFrame::timestamp(self : ScheduledFrame) -> UInt64

#
SchedulerTick

pub struct SchedulerTick {
timestamp_us : UInt64
task_name : String
frame : Frame
late : Bool
}

A scheduler execution result.

#
SchedulerTick::frame

fn SchedulerTick::frame(self : SchedulerTick) -> Frame

#
SchedulerTick::is_late

fn SchedulerTick::is_late(self : SchedulerTick) -> Bool

#
SchedulerTick::task_name

fn SchedulerTick::task_name(self : SchedulerTick) -> String

#
SchedulerTick::timestamp

fn SchedulerTick::timestamp(self : SchedulerTick) -> UInt64

#
Signal

pub struct Signal {
name : String
start_bit : Int
size : Int
little_endian : Bool
signed : Bool
factor : Double
offset : Double
minimum : Double
maximum : Double
unit : String
}

A DBC signal description.

#
Signal::accepts

fn Signal::accepts(self : Signal, value : Double) -> Bool

Check a physical value against the configured range.

#
Signal::decode

fn Signal::decode(self : Signal, data : Array[Byte]) -> Double

Decode a physical value using factor and offset.

#
Signal::decode_physical

fn Signal::decode_physical(self : Signal, data : Array[Byte]) -> Double

Decode a physical value while honoring the DBC signedness flag.

#
Signal::decode_raw

fn Signal::decode_raw(self : Signal, data : Array[Byte]) -> UInt

Extract a raw signal value from a payload.

#
Signal::decode_signed

fn Signal::decode_signed(self : Signal, data : Array[Byte]) -> Int

Decode a signed raw value using the signal width.

#
Signal::encode

fn Signal::encode(self : Signal, data : Array[Byte], value : Double) -> Array[Byte]

Encode a physical value into a payload copy.

#
Signal::encode_raw

fn Signal::encode_raw(self : Signal, data : Array[Byte], value : UInt) -> Array[Byte]

Encode a raw value into a payload copy.

#
Signal::factor

fn Signal::factor(self : Signal) -> Double

#
Signal::has_range

fn Signal::has_range(self : Signal) -> Bool

Return the signal's inclusive physical range when configured.

#
Signal::is_signed

fn Signal::is_signed(self : Signal) -> Bool

Return whether this signal uses signed two's-complement values.

#
Signal::is_valid

fn Signal::is_valid(self : Signal, dlc : Int) -> Bool

Check whether a signal fits inside a payload of dlc bytes.

#
Signal::little_endian

fn Signal::little_endian(self : Signal) -> Bool

Return whether the signal uses Intel/little-endian bit ordering.

#
Signal::maximum

fn Signal::maximum(self : Signal) -> Double

#
Signal::minimum

fn Signal::minimum(self : Signal) -> Double

#
Signal::name

fn Signal::name(self : Signal) -> String

The signal name.

#
Signal::offset

fn Signal::offset(self : Signal) -> Double

#
Signal::raw_max

fn Signal::raw_max(self : Signal) -> UInt

Return the largest raw unsigned value representable by this signal.

#
Signal::size

fn Signal::size(self : Signal) -> Int

Return the configured signal bit size.

#
Signal::start_bit

fn Signal::start_bit(self : Signal) -> Int

The signal's start bit.

#
Signal::unit

fn Signal::unit(self : Signal) -> String

#
Simulation

pub struct Simulation {
now_us : UInt64
bus : VirtualBus
events : Array[ScheduledFrame]
publishers : Array[PeriodicPublisher]
trace : Trace
scheduled : Int
delivered : Int
dropped : Int
arbitration_bits : UInt64
bitrate_kbps : UInt
}

A deterministic, single-threaded CAN network model.

#
Simulation::add_periodic

fn Simulation::add_periodic(self : Simulation, source : String, frame : Frame, first_timestamp_us : UInt64, period_us : UInt64, count : Int) -> Unit raise SimulationError

Register a periodic publisher and schedule its first event.

#
Simulation::bus

fn Simulation::bus(self : Simulation) -> VirtualBus

#
Simulation::now

fn Simulation::now(self : Simulation) -> UInt64

#
Simulation::pending_events

fn Simulation::pending_events(self : Simulation) -> Int

#
Simulation::receive

fn Simulation::receive(self : Simulation) -> Frame?

Drain the highest-priority frame ready at the current time.

#
Simulation::report

fn Simulation::report(self : Simulation, start_us : UInt64) -> SimulationReport

Return a summary of the run so far.

#
Simulation::run_steps

fn Simulation::run_steps(self : Simulation, limit : Int) -> Int raise SimulationError

Execute at most limit events.

#
Simulation::run_until

fn Simulation::run_until(self : Simulation, end_us : UInt64) -> Int raise SimulationError

Execute events up to an inclusive timestamp.

#
Simulation::schedule

fn Simulation::schedule(self : Simulation, timestamp_us : UInt64, frame : Frame, source? : String) -> Unit raise SimulationError

Schedule a frame at an absolute microsecond timestamp.

#
Simulation::step

fn Simulation::step(self : Simulation) -> ScheduledFrame?

Execute the next event and deliver it through the virtual bus.

#
Simulation::trace

fn Simulation::trace(self : Simulation) -> Trace

Return the captured trace.

#
SimulationReport

pub struct SimulationReport {
start_us : UInt64
end_us : UInt64
scheduled : Int
delivered : Int
dropped : Int
arbitration_bits : UInt64
}

Counters produced by a deterministic simulation run.

#
SimulationReport::arbitration_bits

fn SimulationReport::arbitration_bits(self : SimulationReport) -> UInt64

#
SimulationReport::delivered

fn SimulationReport::delivered(self : SimulationReport) -> Int

#
SimulationReport::dropped

fn SimulationReport::dropped(self : SimulationReport) -> Int

#
SimulationReport::duration_us

fn SimulationReport::duration_us(self : SimulationReport) -> UInt64

#
SimulationReport::scheduled

fn SimulationReport::scheduled(self : SimulationReport) -> Int

#
Trace

pub struct Trace {
entries : Array[TraceEntry]
}

An append-only trace that can be replayed deterministically.

#
Trace::between

fn Trace::between(self : Trace, start_us : UInt64, end_us : UInt64) -> Trace

Select entries in a closed timestamp interval.

#
Trace::entries

fn Trace::entries(self : Trace) -> Array[TraceEntry]

Return entries in capture order.

#
Trace::filter_id

fn Trace::filter_id(self : Trace, id : UInt) -> Trace

Select entries matching an identifier.

#
Trace::frames

fn Trace::frames(self : Trace) -> Array[Frame]

Return all frames in capture order.

#
Trace::length

fn Trace::length(self : Trace) -> Int

Return the number of captured frames.

#
Trace::record

fn Trace::record(self : Trace, timestamp_us : UInt64, frame : Frame) -> Unit

Append a timestamped frame.

#
Trace::replay

fn Trace::replay(self : Trace, bus : VirtualBus) -> Int

Replay frames to a virtual bus, preserving capture order.

#
Trace::sorted

fn Trace::sorted(self : Trace) -> Trace

Return a capture-order copy sorted by timestamp and arbitration id.

#
Trace::time_range

fn Trace::time_range(self : Trace) -> (UInt64, UInt64)?

Return the first and last capture timestamps.

#
Trace::to_text

fn Trace::to_text(self : Trace) -> String

Encode a trace in a stable CSV-like text format.

#
Trace::validate

fn Trace::validate(self : Trace) -> Unit raise TraceError

Validate timestamps and frame invariants in capture order.

#
TraceEntry

pub struct TraceEntry {
timestamp_us : UInt64
frame : Frame
}

A timestamped frame captured from a virtual bus.

#
TraceEntry::frame

fn TraceEntry::frame(self : TraceEntry) -> Frame

The captured frame.

#
TraceEntry::timestamp

fn TraceEntry::timestamp(self : TraceEntry) -> UInt64

The capture timestamp in microseconds.

#
UdsResponseInfo

pub struct UdsResponseInfo {
positive : Bool
response_service : Byte
payload : Array[Byte]
negative_code : Byte?
}

A parsed positive or negative response with its service identifier.

#
UdsResponseInfo::is_positive

fn UdsResponseInfo::is_positive(self : UdsResponseInfo) -> Bool

#
UdsResponseInfo::negative_code

fn UdsResponseInfo::negative_code(self : UdsResponseInfo) -> Byte?

#
UdsResponseInfo::payload

fn UdsResponseInfo::payload(self : UdsResponseInfo) -> Array[Byte]

#
UdsResponseInfo::response_service

fn UdsResponseInfo::response_service(self : UdsResponseInfo) -> Byte

#
UdsService

pub enum UdsService {
DiagnosticSessionControl
EcuReset
ReadDataByIdentifier
WriteDataByIdentifier
ReadMemoryByAddress
WriteMemoryByAddress
RoutineControl
SecurityAccess
CommunicationControl
ClearDiagnosticInformation
ReadDtcInformation
RequestDownload
TransferData
RequestTransferExit
TesterPresent
}

Common UDS service identifiers used by a diagnostic client.

#
UdsSession

pub struct UdsSession {
state : UdsSessionState
unlocked : Bool
last_activity_us : UInt64
p2_timeout_us : UInt64
pending_service : UdsService?
}

A small deterministic UDS session tracker.

#
UdsSession::accept

fn UdsSession::accept(self : UdsSession, request : DiagnosticRequest, payload : Array[Byte], timestamp_us : UInt64) -> UdsResponseInfo raise UdsSessionError

Apply a diagnostic response and advance session state.

#
UdsSession::allows

fn UdsSession::allows(self : UdsSession, service : UdsService) -> Bool

Return whether a service is safe in the current state.

#
UdsSession::begin

fn UdsSession::begin(self : UdsSession, request : DiagnosticRequest, timestamp_us : UInt64) -> DiagnosticRequest raise UdsSessionError

Begin a request and remember the expected service.

#
UdsSession::change_state

fn UdsSession::change_state(self : UdsSession, target : UdsSessionState) -> Unit raise UdsSessionError

Force a session change after an externally validated response.

#
UdsSession::is_unlocked

fn UdsSession::is_unlocked(self : UdsSession) -> Bool

#
UdsSession::last_activity

fn UdsSession::last_activity(self : UdsSession) -> UInt64

#
UdsSession::pending_service

fn UdsSession::pending_service(self : UdsSession) -> UdsService?

#
UdsSession::state

#
UdsSession::timed_out

fn UdsSession::timed_out(self : UdsSession, timestamp_us : UInt64) -> Bool

Check whether the response timer has expired.

#
UdsSession::touch

fn UdsSession::touch(self : UdsSession, timestamp_us : UInt64) -> Unit

Mark the current activity time.

#
UdsSessionState

pub enum UdsSessionState {
DefaultSession
ProgrammingSession
ExtendedDiagnosticSession
SafetySystemDiagnosticSession
LockedSession
} derive(
Debug
)

UDS application session states.

#
VirtualBus

pub struct VirtualBus {
capacity : Int
queue : Array[Frame]
filters : FilterBank
dropped : Int
}

A deterministic in-memory CAN bus.

#
VirtualBus::dropped

fn VirtualBus::dropped(self : VirtualBus) -> Int

Number of dropped frames.

#
VirtualBus::filters

fn VirtualBus::filters(self : VirtualBus) -> FilterBank

Configure the receiver acceptance filters.

#
VirtualBus::pending

fn VirtualBus::pending(self : VirtualBus) -> Int

Number of pending frames.

#
VirtualBus::publish

fn VirtualBus::publish(self : VirtualBus, frame : Frame) -> Bool

Publish a frame. The queue is ordered by arbitration priority.

#
VirtualBus::receive

fn VirtualBus::receive(self : VirtualBus) -> Frame?

Receive and remove the highest-priority pending frame.

#
VirtualBus::set_filters

fn VirtualBus::set_filters(self : VirtualBus, filters : FilterBank) -> Unit

Replace all acceptance filters.

#
admission_rule

fn admission_rule(name : String, filter : Filter, max_payload? : Int, allow_fd? : Bool, allow_remote? : Bool, min_interval_us? : UInt64) -> AdmissionRule raise AdmissionError

Construct a policy rule.

#
analyze_trace

fn analyze_trace(trace : Trace) -> FrameAnalysis

Analyze adjacent frames in capture order.

#
append_bits

fn append_bits(target : Array[Bool], value : UInt, width : Int) -> Unit

Append a value as most-significant-bit-first bits.

#
arbitration_winner

fn arbitration_winner(frames : Array[Frame]) -> Frame?

Calculate the arbitration winner: the numerically lowest identifier wins.

#
assess_bus_health

fn assess_bus_health(metrics : FrameMetrics, dropped : Int, duration_us : UInt64, bitrate_kbps : UInt) -> BusHealth

Assess health from frame metrics and virtual-bus counters.

#
batch_frames

fn batch_frames(frames : Array[Frame], size : Int) -> Array[FrameBatch] raise BatchError

Partition frames into batches with at most size members.

#
bit_at

fn bit_at(bits : Array[Bool], position : Int) -> Bool?

Return the bit at an absolute offset, or None when outside the array.

#
bit_reader_from_bytes

fn bit_reader_from_bytes(bytes : Array[Byte]) -> BitReader

Create a reader directly from packed bytes.

#
bits_of

fn bits_of(value : UInt, width : Int) -> Array[Bool]

Convert an integer to most-significant-bit-first bits.

#
bits_to_bytes

fn bits_to_bytes(bits : Array[Bool]) -> Array[Byte]

Convert bits to packed bytes. The last byte is zero padded.

#
bits_to_string

fn bits_to_string(bits : Array[Bool]) -> String

Return a string made of 0 and 1 for diagnostics and golden tests.

#
bus_health_name

fn bus_health_name(state : BusHealthState) -> String

#
bus_utilization

fn bus_utilization(metrics : FrameMetrics, duration_us : UInt64, bitrate_kbps : UInt) -> Double

Calculate approximate utilization for a bitrate in kbit/s.

#
bytes_to_bits

fn bytes_to_bits(bytes : Array[Byte]) -> Array[Bool]

Convert packed bytes to high-to-low bits.

#
calculate_bit_timing

fn calculate_bit_timing(clock_hz : UInt, bitrate : UInt, sample_point_percent : Double) -> CanBitTiming raise CanTimingError

Calculate a practical timing candidate using an integer clock divider.

#
can_fd_timing

fn can_fd_timing(nominal : CanBitTiming, data : CanBitTiming) -> CanFdTiming raise CanTimingError

#
can_line

fn can_line(timestamp_us : UInt64, frame : Frame) -> String

Encode a single compact line for shell tools.

#
can_log_from_text

fn can_log_from_text(text : String) -> CanLog raise CanTextError

Parse a log produced by CanLog::to_text.

#
canonicalize_dbc

fn canonicalize_dbc(input : String) -> String raise DbcExtendedError

Parse, validate and normalize an extended DBC document.

#
canopen_cob_id

fn canopen_cob_id(object_type : CanOpenCobType, node_id : Byte) -> UInt raise CanOpenError

Create a standard CANopen COB-ID for a node.

#
canopen_cob_name

fn canopen_cob_name(object_type : CanOpenCobType) -> String

Return the textual name of a CANopen object type.

#
canopen_emergency

fn canopen_emergency(error_code : UInt, error_register : Byte, manufacturer_data : Array[Byte]) -> Array[Byte] raise CanOpenError

Build an emergency payload with standard CANopen fields.

#
canopen_heartbeat

fn canopen_heartbeat(state : Byte) -> Array[Byte]

Build a heartbeat payload.

#
canopen_nmt

fn canopen_nmt(command : CanOpenNmtCommand, node_id : Byte) -> Array[Byte] raise CanOpenError

Build an NMT command frame.

#
canopen_sdo_decode

fn canopen_sdo_decode(payload : Array[Byte]) -> CanOpenSdoCommand raise CanOpenError

Decode one SDO response command.

#
canopen_sdo_download

fn canopen_sdo_download(index : UInt, sub_index : Byte, data : Array[Byte]) -> Array[Byte] raise CanOpenError

Build an expedited SDO download request.

#
canopen_sdo_download_command

fn canopen_sdo_download_command(index : UInt, sub_index : Byte, data : Array[Byte]) -> CanOpenSdoCommand raise CanOpenError

Build a typed expedited download command.

#
canopen_sdo_download_segment

fn canopen_sdo_download_segment(toggle : Bool, data : Array[Byte], last : Bool) -> CanOpenSdoCommand raise CanOpenError

Build a typed segmented download command.

#
canopen_sdo_frame

fn canopen_sdo_frame(node_id : Byte, transmit : Bool, payload : Array[Byte]) -> Frame raise CanOpenError

Build a CAN frame for an SDO payload.

#
canopen_sdo_upload

fn canopen_sdo_upload(index : UInt, sub_index : Byte) -> Array[Byte] raise CanOpenError

Build an SDO upload request.

#
canopen_sdo_upload_segment

fn canopen_sdo_upload_segment(toggle : Bool) -> CanOpenSdoCommand

Build a typed segmented upload command.

#
classify_frame

fn classify_frame(frame : Frame) -> FrameClass

Classify a frame for counters and dashboards.

#
clear_diagnostic_information

fn clear_diagnostic_information(group : UInt) -> DiagnosticRequest raise UdsError

Build a request to clear one DTC group or all groups.

#
communication_control

fn communication_control(control_type : Byte, communication_type : Byte) -> DiagnosticRequest

Build a communication-control request.

#
compare_frames

fn compare_frames(left : Frame, right : Frame) -> Int

Compare frames in the order used by deterministic arbitration.

#
count_stuffed_bits

fn count_stuffed_bits(bits : Array[Bool]) -> Int

Count stuffed bits in a sequence without allocating the stuffed result.

#
counter_is_next

fn counter_is_next(previous : Byte, current : Byte) -> Bool

Verify the expected modulo-16 counter progression.

#
counter_nibble

fn counter_nibble(data : Array[Byte], offset : Int, high_nibble : Bool) -> Byte raise PayloadError

Read a rolling counter nibble.

#
crc15

fn crc15(bits : Array[Bool]) -> UInt

CRC-15 used by the classical CAN frame format.

#
crc17

fn crc17(bits : Array[Bool]) -> UInt

CRC-17 used by CAN-FD frames with a payload up to 16 bytes.

#
crc21

fn crc21(bits : Array[Bool]) -> UInt

CRC-21 used by CAN-FD frames with a payload above 16 bytes.

#
crc8_autosar

fn crc8_autosar(data : Array[Byte], initial : Byte) -> Byte

Return the CRC-8/AUTOSAR checksum with configurable initial value.

#
crc8_sae_j1850

fn crc8_sae_j1850(data : Array[Byte]) -> Byte

Return the CRC-8/SAE-J1850 checksum of a payload.

#
data_frame

fn data_frame(id : UInt, data : Array[Byte], extended? : Bool) -> Frame raise FrameError

Create a classic CAN data frame.

#
decode_canopen_cob_id

fn decode_canopen_cob_id(identifier : UInt) -> CanOpenCobId raise CanOpenError

Decode a standard CANopen COB-ID using the conventional ranges.

#
decode_frame

fn decode_frame(bytes : Array[Byte]) -> Frame raise FrameCodecError

Decode one frame from the stable binary representation.

#
decode_frame_batch

fn decode_frame_batch(bytes : Array[Byte]) -> FrameBatch raise BatchError

Decode a batch archive and check its checksum.

#
decode_j1939

fn decode_j1939(id : UInt) -> J1939Id

Decode the fields of a J1939 identifier.

#
decode_j1939_frame

fn decode_j1939_frame(frame : Frame) -> J1939Message? raise J1939Error

Decode an extended CAN data frame as a J1939 message.

#
decode_response

fn decode_response(request : DiagnosticRequest, payload : Array[Byte]) -> DiagnosticResponse

Decode a UDS response payload.

#
decode_wire_can20

fn decode_wire_can20(bits : Array[Bool]) -> Frame raise WireCodecError

Decode a classic CAN wire sequence produced by encode_wire.

#
decode_wire_canfd

fn decode_wire_canfd(bits : Array[Bool]) -> Frame raise WireCodecError

Decode a CAN-FD wire sequence produced by encode_wire.

#
destuff

fn destuff(bits : Array[Bool]) -> Array[Bool] raise WireError

Remove CAN bit stuffing from a received bit sequence.

#
diagnostic_frame

fn diagnostic_frame(request : DiagnosticRequest, id : UInt, extended? : Bool) -> Frame raise FrameError

Return a service request encoded as a CAN data frame.

#
diff_dbc_schema

fn diff_dbc_schema(before : Array[Message], after : Array[Message]) -> Array[DbcSchemaChange]

Compare message collections by identifier and canonical schema text.

#
dtc_record

fn dtc_record(code : UInt, status : Byte, occurrence? : UInt, snapshot? : Array[Byte]) -> DtcRecord raise DtcCodecError

Create a DTC record with an optional occurrence counter and snapshot.

#
ecu_reset

fn ecu_reset(reset_type : Byte) -> DiagnosticRequest

Build an ECU reset request.

#
encode_bits

fn encode_bits(frame : Frame) -> Array[Bool]

Encode a frame's arbitration and control fields before CRC.

#
encode_dtc_record

fn encode_dtc_record(record : DtcRecord) -> Array[Byte]

Encode the four-byte DTC record used in a UDS response.

#
encode_dtc_report

fn encode_dtc_report(report : DtcReport) -> Array[Byte]

Encode a report while preserving record order.

#
encode_frame

fn encode_frame(frame : Frame) -> Array[Byte]

A stable binary representation for trace files and test fixtures.

The format is: version, flags, four-byte identifier, payload length, data. All multi-byte values are big-endian so the format is identical on every MoonBit backend.

#
encode_j1939

fn encode_j1939(value : J1939Id) -> UInt

Encode a J1939 identifier from its fields.

#
encode_wire

fn encode_wire(frame : Frame) -> Array[Bool]

Encode identifier, control, data, CRC, stuffing and EOF bits.

#
encoded_wire_length

fn encoded_wire_length(frame : Frame) -> Int

Return the stuffed frame length, including SOF-free EOF bits.

#
error_frame

fn error_frame(code : Byte) -> Frame

Create a local error frame for simulation and diagnostics.

#
estimate_transmission_us

fn estimate_transmission_us(frame : Frame, arbitration_kbps : UInt, data_kbps : UInt) -> UInt64

Estimate transmission time in microseconds.

#
exact_filter

fn exact_filter(id : UInt, extended? : Bool) -> Filter

Match an exact identifier.

#
fd_frame

fn fd_frame(id : UInt, data : Array[Byte], extended? : Bool, bitrate_switch? : Bool, error_state_indicator? : Bool) -> Frame raise FrameError

Create a CAN-FD data frame.

#
fd_frame_duration_ns

fn fd_frame_duration_ns(frame : Frame, timing : CanFdTiming) -> UInt64

Estimate the data-phase duration for a CAN-FD frame with BRS.

#
fd_length_from_dlc

fn fd_length_from_dlc(dlc : Byte) -> Int

Decode a CAN-FD DLC into its payload capacity.

#
filter_bank_is_valid

fn filter_bank_is_valid(bank : FilterBank) -> Bool

Return whether all filters in a bank are valid.

#
filter_is_valid

fn filter_is_valid(filter : Filter) -> Bool

Validate a filter against the selected identifier width.

#
frame_batch

fn frame_batch(sequence : UInt, frames : Array[Frame]) -> FrameBatch raise BatchError

#
frame_class_name

fn frame_class_name(class : FrameClass) -> String

Return the frame class as a stable text label.

#
frame_crc

fn frame_crc(frame : Frame) -> UInt

Return the CRC for the unstuffed arbitration/control/data sequence.

#
frame_duration_ns

fn frame_duration_ns(frame : Frame, timing : CanBitTiming) -> UInt64

Estimate a frame's nominal-only transmission duration.

#
frame_encoded_size

fn frame_encoded_size(frame : Frame) -> Int

Return the number of encoded frame bytes, including the codec header.

#
frame_equal

fn frame_equal(left : Frame, right : Frame) -> Bool

Compare frame payloads and all control flags.

#
frame_from_hex

fn frame_from_hex(text : String) -> Frame raise FrameCodecError

Decode a hexadecimal frame representation.

#
frame_is_valid

fn frame_is_valid(frame : Frame) -> Bool

Return whether a frame passes all normalized invariants.

#
frame_metrics

fn frame_metrics(frames : Array[Frame]) -> FrameMetrics

Calculate deterministic metrics without changing the input order.

#
frame_summary

fn frame_summary(frame : Frame) -> String

Return a compact human-readable frame summary.

#
frame_to_hex

fn frame_to_hex(frame : Frame) -> String

Encode a frame as lowercase hexadecimal bytes.

#
frame_violation_message

fn frame_violation_message(violation : FrameViolation) -> String

Return a diagnostic description for a validation finding.

#
frame_wire_bits

fn frame_wire_bits(frame : Frame) -> Int

Return the approximate wire bit count before inter-frame spacing.

#
frame_with_data

fn frame_with_data(frame : Frame, data : Array[Byte]) -> Frame raise PayloadError

Rebuild a frame with a defensive payload copy.

#
frame_with_id

fn frame_with_id(frame : Frame, id : UInt) -> Frame raise PayloadError

Rebuild a frame with a different arbitration identifier.

#
frames_per_second

fn frames_per_second(metrics : FrameMetrics, duration_us : UInt64) -> Double

Calculate frames per second over an observation interval.

#
gateway_pair

fn gateway_pair(left_to_right : CanGateway, right_to_left : CanGateway) -> GatewayPair

#
isotp_config

fn isotp_config(frame_bytes? : Int, block_size? : Byte, separation_time? : Byte) -> IsoTpConfig raise IsoTpError

Create an ISO-TP configuration. Data capacity is normally 8 or 64 bytes.

#
isotp_decode

fn isotp_decode(packet : Array[Byte]) -> IsoTpPacket?

Decode one ISO-TP packet.

#
isotp_decode_checked

fn isotp_decode_checked(packet : Array[Byte], config : IsoTpConfig) -> IsoTpPacket raise IsoTpError

Decode a packet while enforcing its declared payload length.

#
isotp_frames

fn isotp_frames(tx_id : UInt, payload : Array[Byte], config : IsoTpConfig, extended? : Bool) -> Array[Frame] raise IsoTpError

Wrap ISO-TP packets in CAN or CAN-FD data frames.

#
isotp_reassemble

fn isotp_reassemble(first : IsoTpPacket, rest : Array[IsoTpPacket]) -> Array[Byte]?

Reassemble consecutive ISO-TP packets after a first frame.

#
isotp_reassemble_checked

fn isotp_reassemble_checked(packets : Array[IsoTpPacket]) -> Array[Byte] raise IsoTpError

Reassemble a complete ISO-TP transfer and verify sequence numbers.

#
isotp_reassemble_frames

fn isotp_reassemble_frames(frames : Array[Frame], config : IsoTpConfig) -> Array[Byte] raise IsoTpError

Decode and reassemble a sequence of CAN data frames.

#
isotp_segment

fn isotp_segment(payload : Array[Byte]) -> Array[Array[Byte]]

Encode a payload into ISO-TP packets carried by classic CAN frames.

#
isotp_segment_checked

fn isotp_segment_checked(payload : Array[Byte], config : IsoTpConfig) -> Array[Array[Byte]] raise IsoTpError

Segment a payload while respecting frame size and the 12-bit classic length.

#
j1939_bam

fn j1939_bam(pgn : UInt, payload : Array[Byte]) -> Array[Array[Byte]] raise J1939Error

Build a J1939 BAM transport-protocol announcement.

#
j1939_destination

fn j1939_destination(identifier : J1939Id) -> Byte

Return the numeric destination address, or broadcast for PDU2 messages.

#
j1939_id

fn j1939_id(priority : Byte, data_page : Bool, pdu_format : Byte, pdu_specific : Byte, source_address : Byte) -> J1939Id

Create a J1939 identifier from its wire fields.

#
j1939_matches_pgn

fn j1939_matches_pgn(identifier : J1939Id, pgn : UInt) -> Bool

Test whether a J1939 identifier belongs to a PGN.

#
j1939_message

fn j1939_message(identifier : J1939Id, payload : Array[Byte]) -> J1939Message raise J1939Error

#
j1939_parse_bam

fn j1939_parse_bam(announcement : Array[Byte]) -> (Int, Int, UInt)?

Parse a BAM announcement as (length, packet_count, pgn).

#
j1939_reassemble_bam

fn j1939_reassemble_bam(packets : Array[Array[Byte]], total_length : Int) -> Array[Byte] raise J1939Error

Reassemble BAM data packets after validating their sequence numbers.

#
j1939_with_priority

fn j1939_with_priority(identifier : J1939Id, priority : Byte) -> J1939Id raise J1939Error

Return a priority-adjusted arbitration identifier.

#
j1939_with_source

fn j1939_with_source(identifier : J1939Id, source : Byte) -> J1939Id raise J1939Error

Return a source-address-adjusted identifier.

#
locked_uds_session

fn locked_uds_session(p2_timeout_us? : UInt64) -> UdsSession

Create a session that requires security access for protected services.

#
mask_filter

fn mask_filter(id : UInt, mask : UInt, extended? : Bool?) -> Filter

Match identifier bits selected by a mask.

#
mask_payload

fn mask_payload(data : Array[Byte], offset : Int, mask : Byte) -> Array[Byte] raise PayloadError

Mask a payload byte range without changing its length.

#
matching_filters

fn matching_filters(bank : FilterBank, frame : Frame) -> Array[Filter]

Return all filters that match a frame.

#
max_payload

fn max_payload(protocol : Protocol) -> Int

Return the maximum payload allowed by the protocol.

#
merge_traces

fn merge_traces(left : Trace, right : Trace) -> Trace

Merge two traces and normalize their ordering.

#
message

fn message(id : UInt, name : String, dlc : Int) -> Message

Create a message definition.

#
new_admission_policy

fn new_admission_policy() -> AdmissionPolicy

#
new_bit_reader

fn new_bit_reader(bits : Array[Bool]) -> BitReader

Create a reader over a defensive copy of the input bits.

#
new_bit_writer

fn new_bit_writer() -> BitWriter

Create an empty bit writer.

#
new_bus

fn new_bus(capacity : Int) -> VirtualBus

Create a bus. A zero capacity means an unbounded queue.

#
new_can_log

fn new_can_log() -> CanLog

#
new_can_network

fn new_can_network(timeout_us? : UInt64, queue_capacity? : Int) -> CanNetwork raise QueueError

Create a network. A zero timeout disables automatic offline detection.

#
new_dbc_database

fn new_dbc_database() -> DbcDatabase

Create an empty database.

#
new_dtc_report

fn new_dtc_report(subfunction : Byte, status_availability_mask : Byte, records : Array[DtcRecord]) -> DtcReport

Construct a report for a positive ReadDTCInformation response.

#
new_dtc_store

fn new_dtc_store(capacity : Int) -> DtcStore raise DtcCodecError

#
new_filter_bank

fn new_filter_bank() -> FilterBank

Create an empty filter bank.

#
new_filter_index

fn new_filter_index(bank : FilterBank) -> FilterIndex

#
new_frame_queue

fn new_frame_queue(capacity : Int) -> FrameQueue raise QueueError

Create a queue. Capacity zero means unlimited buffering.

#
new_gateway

fn new_gateway() -> CanGateway

Create an empty gateway.

#
new_isotp_receiver

fn new_isotp_receiver(config : IsoTpConfig) -> IsoTpReceiver

#
new_latency_window

fn new_latency_window(capacity : Int) -> LatencyWindow raise LatencyError

#
new_node_registry

fn new_node_registry() -> NodeRegistry

#
new_pdo_mapping

fn new_pdo_mapping(payload_bytes? : Int) -> PdoMapping raise PdoError

#
new_scheduler

fn new_scheduler() -> CanScheduler

#
new_simulation

fn new_simulation(capacity : Int, bitrate_kbps : UInt) -> Simulation

Create a simulation with a bounded or unbounded receive queue.

#
new_trace

fn new_trace() -> Trace

Create an empty trace.

#
new_uds_session

fn new_uds_session(p2_timeout_us? : UInt64) -> UdsSession

#
parse_can_line

fn parse_can_line(line : String) -> (UInt64, Frame) raise CanTextError

Parse a compact two-field line.

#
parse_dbc

fn parse_dbc(input : String) -> Array[Message] raise DbcError

Parse the message/signal subset commonly used by simulation tools.

#
parse_dbc_database

fn parse_dbc_database(input : String) -> DbcDatabase raise DbcError

Build a database using the existing DBC subset parser.

#
parse_dbc_extended

fn parse_dbc_extended(input : String) -> DbcParseReport raise DbcExtendedError

Parse common factor, offset, range and unit fields in SG_ records.

#
parse_dtc_report

fn parse_dtc_report(payload : Array[Byte]) -> DtcReport raise DtcCodecError

Parse a positive ReadDTCInformation response.

#
parse_uds_response

fn parse_uds_response(request : DiagnosticRequest, payload : Array[Byte]) -> UdsResponseInfo raise UdsError

Parse a response and preserve the original payload for callers.

#
payload_set_uint

fn payload_set_uint(data : Array[Byte], offset : Int, width : Int, value : UInt, order : ByteOrder) -> Array[Byte] raise PayloadError

Insert an unsigned integer into a copied payload.

#
payload_uint

fn payload_uint(data : Array[Byte], offset : Int, width : Int, order : ByteOrder) -> UInt raise PayloadError

Extract an unsigned integer from a payload.

#
pdo_frame

fn pdo_frame(node_id : Byte, transmit_number : Byte, data : Array[Byte]) -> Frame raise PdoError

Build a PDO frame with the standard 11-bit COB-ID.

#
pgn

fn pgn(number : UInt, name : String, data_length : Int) -> Pgn

Describe a PGN for higher-level applications.

#
read_data

fn read_data(identifier : UInt) -> DiagnosticRequest

Build a read-data-by-identifier request.

#
read_dtc_information

fn read_dtc_information(subfunction : Byte, mask : Byte) -> DiagnosticRequest

Build a DTC information request.

#
read_memory

fn read_memory(address : UInt, length : UInt, address_bytes? : Int, length_bytes? : Int) -> DiagnosticRequest raise UdsError

Build a memory read request using a compact address/length format.

#
remote_frame

fn remote_frame(id : UInt, extended? : Bool) -> Frame raise FrameError

Create a remote request frame.

#
request_download

fn request_download(data_format : Byte, address : UInt, length : UInt, address_bytes? : Int, length_bytes? : Int) -> DiagnosticRequest raise UdsError

Build a request-download command.

#
request_transfer_exit

fn request_transfer_exit(data? : Array[Byte]) -> DiagnosticRequest

#
reverse_payload

fn reverse_payload(data : Array[Byte], start : Int, end : Int) -> Array[Byte] raise PayloadError

Return a payload with bytes reversed in a selected range.

#
route_batch

fn route_batch(gateway : CanGateway, frames : Array[Frame]) -> Array[RoutedFrame] raise RoutingError

Route a batch and keep only successfully forwarded frames.

#
route_rule

fn route_rule(name : String, filter : Filter, output_id? : UInt?, output_extended? : Bool?, prefix? : Array[Byte], strip_prefix? : Int) -> RouteRule raise RoutingError

Construct a route rule with optional identifier and payload rewrites.

#
routine_control

fn routine_control(routine_type : Byte, identifier : UInt, data? : Array[Byte]) -> DiagnosticRequest raise UdsError

Build a routine-control request with an optional input record.

#
schedule_miss_rate

fn schedule_miss_rate(ticks : Array[SchedulerTick]) -> Double

Return the fraction of ticks that missed their deadline.

#
schedule_wire_bits

fn schedule_wire_bits(ticks : Array[SchedulerTick]) -> Int

Estimate the total wire bits for one scheduler window.

#
security_access

fn security_access(subfunction : Byte) -> DiagnosticRequest

Build a security-access seed/key request.

#
serialize_dbc_schema

fn serialize_dbc_schema(messages : Array[Message]) -> String raise DbcSchemaError

Serialize a schema to deterministic DBC text.

#
session_control

fn session_control(session : Byte) -> DiagnosticRequest

Build a session-control request.

#
set_bit

fn set_bit(bits : Array[Bool], position : Int, value : Bool) -> Array[Bool]

Set a bit in a defensive copy. Out-of-range positions are ignored.

#
set_counter_nibble

fn set_counter_nibble(data : Array[Byte], offset : Int, counter : Byte, high_nibble : Bool) -> Array[Byte] raise PayloadError

Insert a rolling counter into a payload nibble.

#
signal

fn signal(name : String, start_bit : Int, size : Int, little_endian? : Bool, signed? : Bool, factor? : Double, offset? : Double, minimum? : Double, maximum? : Double, unit? : String) -> Signal

Create a signal descriptor.

#
sort_by_arbitration

fn sort_by_arbitration(frames : Array[Frame]) -> Array[Frame]

Return a stable arbitration-sorted copy.

#
sort_j1939

fn sort_j1939(messages : Array[J1939Message]) -> Array[J1939Message]

Return the standard J1939 priority ordering for messages.

#
stuff

fn stuff(bits : Array[Bool]) -> Array[Bool]

Apply CAN bit stuffing to a bit sequence.

#
tester_present

fn tester_present(suppress_response? : Bool) -> DiagnosticRequest

Build a tester-present request.

#
trace_from_text

fn trace_from_text(text : String) -> Trace raise TraceError

Parse a trace produced by Trace::to_text.

#
trace_metrics

fn trace_metrics(trace : Trace) -> FrameMetrics

Compute metrics directly from a trace.

#
transfer_data

fn transfer_data(block_counter : Byte, data : Array[Byte]) -> DiagnosticRequest raise UdsError

Build a transfer-data block.

#
uds_negative_code_name

fn uds_negative_code_name(code : Byte) -> String

Return a stable description for common UDS negative response codes.

#
uds_service_id

fn uds_service_id(service : UdsService) -> Byte

Return the numeric service identifier.

#
uds_service_name

fn uds_service_name(service : UdsService) -> String

Return the service's stable diagnostic name.

#
uds_session_name

fn uds_session_name(state : UdsSessionState) -> String

Return a stable state label.

#
validate_dbc_schema

fn validate_dbc_schema(messages : Array[Message]) -> DbcSchemaReport raise DbcSchemaError

Validate identifiers, payload bounds and signal overlap.

#
validate_frame

fn validate_frame(frame : Frame) -> FrameReport

Validate protocol and simulation invariants.

#
validate_j1939

fn validate_j1939(value : J1939Id) -> Unit raise J1939Error

Validate a J1939 identifier's fields.

#
wire_round_trip

fn wire_round_trip(frame : Frame) -> Bool

Verify that a frame's wire encoding can be decoded without loss.

#
write_data

fn write_data(identifier : UInt, data : Array[Byte]) -> DiagnosticRequest raise UdsError

Build a write-data-by-identifier request.

#
write_memory

fn write_memory(address : UInt, data : Array[Byte], address_bytes? : Int) -> DiagnosticRequest raise UdsError

Build a memory write request.