moonbit-iec104

    Portable IEC 60870-5-104 protocol core for SCADA, gateways, and deterministic simulation.

    iec104
    scada
    telecontrol
    protocol
    Download zip
    Author
    Version
    0.2.0
    License
    Apache-2.0
    Last updated
    26 days ago
    Downloads
    17

    #moonbit-iec104

    一个面向 SCADA、变电站自动化、配电网关和协议仿真的 IEC 60870-5-104 协议核心。项目使用 MoonBit 编写,库层不绑定 TCP 实现或操作系统 I/O,便于嵌入网关、测试工具和确定性仿真器。

    #项目定位

    本项目覆盖 IEC 104 链路层与常用应用层数据模型,重点放在可验证的二进制编解码、链路状态、序号窗口、信息对象和边界行为。网络传输由调用方接入,协议核心因此可以在 native、wasm-gc 等目标上复用。

    #核心能力

    • APCI I/S/U 帧编解码、15 位发送/接收序号和序号窗口。
    • STARTDT、STOPDT、TESTFR 链路状态机、定时器和流式 APDU 解析。
    • IEC 104 常用 Type ID、VSQ、传送原因、公共地址和信息体地址模型。
    • 单点、双点、步位、归一化值、标度值、短浮点值、累计量及命令对象。
    • CP24Time2a、CP56Time2a、质量描述符、地址序列和带时标 ASDU 编解码。
    • 点表、历史变更、总召唤/计数量召唤、读命令、时钟同步和命令策略。
    • 资源限制、重放保护、CRC、帧统计、健康报告和确定性仿真工作负载。

    #快速开始

    需要 MoonBit stable 工具链。首次使用时执行:

    moon update moon fmt moon check --deny-warn --target all moon build --target wasm-gc moon test --deny-warn --target wasm-gc

    运行示例 CLI:

    moon run cmd/main moon run cmd/main -- --help moon run cmd/main -- --benchmark

    在库代码中构造并编码一个 I 帧:

    ///|
    let payload = @hhxhhx78/moonbit-iec104.normalized_value_asdu(3, 1, 2300, 0)

    ///|
    let apdu = @hhxhhx78/moonbit-iec104.encode_frame(
    @hhxhhx78/moonbit-iec104.information_frame(0, 0, payload),
    )

    #CLI

    cmd/main 提供一个不依赖外部服务的可重复示例:默认编码一个归一化测量值 I 帧;--benchmark 执行固定的 10,000 帧编解码工作负载并输出帧数、字节数和校验和;--help 显示用法。宿主机耗时由基准命令外部测量,避免把平台时钟引入协议核心。

    #架构

    层次主要文件职责
    链路与帧frame_types.mbt, codec.mbt, validation.mbt, state_machine.mbtAPCI、ASDU 基础模型、校验和链路状态
    应用数据protocol_domain.mbt, quality.mbt, time_tags.mbt, application_objects.mbt, extended_asdu.mbtType ID、地址、质量、时标和信息对象
    服务与状态transport_layer.mbt, application_services.mbt, point_store.mbt序号窗口、定时器、召唤事务、点表和历史
    工具与可靠性wire_tools.mbt, security_limits.mbt, diagnostics_metrics.mbt, health_report.mbt字节工具、资源保护、指标和诊断
    仿真与契约simulation.mbt, conformance_catalog.mbt, protocol_profiles.mbt, benchmark_api.mbt确定性仿真、类型目录、能力协商和基准接口
    示例cmd/main可运行的最小 CLI

    #基准

    基准工作负载由 run_benchmark_workload 定义,输入、输出字节数和 CRC 校验和均是确定的;宿主机实测结果记录在 BENCHMARKS.md,包含执行环境、命令、重复次数和原始输出。重新测量:

    1..5 | ForEach-Object { Measure-Command { moon run cmd/main -- --benchmark } }

    该数据用于比较同一环境下的回归趋势,不代表所有设备或网络部署的吞吐承诺。

    #测试

    测试覆盖帧编解码、链路状态、Type ID 和地址边界、CP24/CP56 闰年与无效日期、质量位、签名测量值、ASDU 截断/尾随字节、序号回绕、流式输入、点表历史、服务事务、资源限制、CRC 和确定性基准。推荐在本地分别运行:

    moon check --deny-warn --target all moon test --deny-warn --target wasm-gc moon test --deny-warn --target native

    #CI

    .github/workflows/check.yml 在 Ubuntu、macOS 和 Windows 上安装 MoonBit stable,执行版本检查、依赖更新、格式检查、接口文件一致性、所有目标检查、wasm-gc 构建和测试。CI 使用最小只读仓库权限;本地若缺少某个后端运行时,应以对应平台 CI 结果和明确的本地环境提示为准。

    #许可证

    本项目采用 Apache License 2.0

    AdmissionDecision

    pub enum AdmissionDecision {
    AcceptedAdmission
    RejectedAdmission(Diagnostic)
    } derive(
    Debug
    )

    ApduParseResult

    pub enum ApduParseResult {
    NeedMore(Int)
    Complete(Frame, Int)
    Invalid(Diagnostic)
    } derive(
    Debug
    )

    Incremental APDU parsing result for TCP or serial gateway adapters.

    ApduStreamDecoder

    pub struct ApduStreamDecoder {
    buffer : Array[Byte]
    max_apdu : Int
    } derive(
    Debug
    )

    A portable byte accumulator for stream transports.

    ApduStreamDecoder::available_frames

    fn ApduStreamDecoder::available_frames(self : ApduStreamDecoder) -> Int

    Number of complete frames available in a buffered stream.

    ApduStreamDecoder::buffered

    fn ApduStreamDecoder::buffered(self : ApduStreamDecoder) -> Int

    ApduStreamDecoder::clear

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

    ApduStreamDecoder::new

    fn ApduStreamDecoder::new(max_apdu? : Int) -> Result[ApduStreamDecoder, String]

    ApduStreamDecoder::next

    Parse and remove the first complete APDU, preserving partial data.

    ApduStreamDecoder::push

    fn ApduStreamDecoder::push(self : ApduStreamDecoder, data : Bytes) -> Result[Int, Diagnostic]

    ApplicationObject

    pub struct ApplicationObject {
    address : InformationAddress
    type_id : ApplicationType
    value : ApplicationValue
    time_tag : TimeTag?
    } derive(Eq,
    Debug
    )

    An address-qualified application object with an optional time tag.

    ApplicationObject::address

    ApplicationObject::is_command

    fn ApplicationObject::is_command(self : ApplicationObject) -> Bool

    ApplicationObject::is_measurement

    fn ApplicationObject::is_measurement(self : ApplicationObject) -> Bool

    ApplicationObject::new

    fn ApplicationObject::new(address : InformationAddress, value : ApplicationValue, time_tag? : TimeTag) -> Result[ApplicationObject, String]

    Construct an application object and optionally attach its standard time tag.

    ApplicationObject::summary

    fn ApplicationObject::summary(self : ApplicationObject) -> (Int, Int, Int, Bool)

    Return a type-tagged object as a stable compact summary tuple.

    ApplicationObject::time_tag

    ApplicationObject::type_id

    ApplicationObject::validate

    fn ApplicationObject::validate(self : ApplicationObject) -> Result[Unit, Diagnostic]

    Validate an application object before placing it in an ASDU.

    ApplicationObject::value

    ApplicationType

    pub enum ApplicationType {
    MSpNa
    MSpTa
    MDpNa
    MDpTa
    MStNa
    MStTa
    MBoNa
    MBoTa
    MMeNa
    MMeTa
    MMeNb
    MMeTb
    MMeNc
    MMeTc
    MItNa
    MItTa
    MEpTa
    MEpTb
    MEpTc
    MPsNa
    MMeNd
    MSpTb
    MDpTb
    MStTb
    MBoTb
    MMeTd
    MMeTe
    MMeTf
    MItTb
    MEpTd
    MEpTe
    MEpTf
    MEiNa
    CScNa
    CDcNa
    CRcNa
    CSeNa
    CSeNb
    CSeNc
    CBoNa
    CIcNa
    CCiNa
    CRdNa
    CCsNa
    CTsNa
    CRpNa
    UnknownType(Int)
    } derive(Eq,
    Debug
    )

    Standard IEC 104 application type identifiers.

    ApplicationType::has_time_tag

    fn ApplicationType::has_time_tag(self : ApplicationType) -> Bool

    Whether a type carries a CP24 or CP56 time tag.

    ApplicationType::is_control

    fn ApplicationType::is_control(self : ApplicationType) -> Bool

    Whether an application type belongs to control direction data.

    ApplicationType::is_monitoring

    fn ApplicationType::is_monitoring(self : ApplicationType) -> Bool

    Whether an application type belongs to monitor direction data.

    ApplicationType::number

    fn ApplicationType::number(self : ApplicationType) -> Int

    Return an IEC 104 type identifier number.

    ApplicationType::value_width

    fn ApplicationType::value_width(self : ApplicationType) -> Int?

    Preferred information-object payload width, excluding IOA and time tag.

    ApplicationValue

    pub enum ApplicationValue {
    SinglePointValue(SinglePointValue)
    DoublePointValue(DoublePointValue)
    StepPositionValue(StepPositionValue)
    BitStringValue(UInt)
    NormalizedMeasurement(NormalizedValue)
    ScaledMeasurement(ScaledValue)
    ShortFloatMeasurement(ShortFloatValue)
    BinaryCounterMeasurement(BinaryCounterValue)
    SingleCommand(Bool, Int)
    DoubleCommand(Int, Int)
    RegulatingStepCommand(Int, Int)
    NormalizedSetPoint(Int, Int)
    ScaledSetPoint(Int, Int)
    ShortFloatSetPoint(Float, Int)
    BitStringCommand(UInt)
    InterrogationCommand(Int)
    CounterInterrogationCommand(Int)
    ReadCommand
    ClockSyncCommand(Cp56Time)
    TestCommand(Int)
    ResetCommand(Int)
    DelayCommand(Int)
    EndOfInitialization(Int)
    RawValue(Bytes)
    } derive(Eq,
    Debug
    )

    Values carried by standard IEC 104 information objects.

    AsduEnvelope

    pub struct AsduEnvelope {
    type_id : ApplicationType
    sequence : Bool
    cause : CauseOfTransmission
    common_address : CommonAddress
    objects : Array[ApplicationObject]
    } derive(Eq,
    Debug
    )

    A complete ASDU envelope with address-qualified application objects.

    AsduEnvelope::cause

    AsduEnvelope::common_address

    fn AsduEnvelope::common_address(self : AsduEnvelope) -> CommonAddress

    AsduEnvelope::count

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

    AsduEnvelope::new

    fn AsduEnvelope::new(type_id : ApplicationType, sequence : Bool, cause : CauseOfTransmission, common_address : CommonAddress, objects : Array[ApplicationObject]) -> Result[AsduEnvelope, Diagnostic]

    Construct an ASDU envelope and check its object/type relationship.

    AsduEnvelope::objects

    AsduEnvelope::sequence

    fn AsduEnvelope::sequence(self : AsduEnvelope) -> Bool

    AsduEnvelope::type_id

    AsduHeader

    pub struct AsduHeader {
    type_id : TypeId
    variable_count : Int
    sequence : Bool
    cause : Int
    common_address : Int
    } derive(Eq,
    Debug
    )

    Common information object address and cause of transmission.

    AsduHeader::cause

    fn AsduHeader::cause(self : AsduHeader) -> Int

    AsduHeader::common_address

    fn AsduHeader::common_address(self : AsduHeader) -> Int

    AsduHeader::count

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

    AsduHeader::is_sequence

    fn AsduHeader::is_sequence(self : AsduHeader) -> Bool

    AsduHeader::type_id

    fn AsduHeader::type_id(self : AsduHeader) -> TypeId

    BenchmarkCase

    pub struct BenchmarkCase {
    name : String
    rounds : Int
    payload_size : Int
    target : String
    } derive(Eq,
    Debug
    )

    A repeatable benchmark case with a deterministic workload definition.

    BenchmarkCase::name

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

    BenchmarkCase::new

    fn BenchmarkCase::new(name : String, rounds : Int, payload_size : Int, target : String) -> Result[BenchmarkCase, String]

    BenchmarkCase::payload_size

    fn BenchmarkCase::payload_size(self : BenchmarkCase) -> Int

    BenchmarkCase::rounds

    fn BenchmarkCase::rounds(self : BenchmarkCase) -> Int

    BenchmarkCase::target

    fn BenchmarkCase::target(self : BenchmarkCase) -> String

    BenchmarkResult

    pub struct BenchmarkResult {
    case : BenchmarkCase
    encoded_frames : Int
    encoded_bytes : Int
    checksum : UInt
    elapsed_micros : Int
    } derive(Eq,
    Debug
    )

    BenchmarkResult::case

    BenchmarkResult::checksum

    fn BenchmarkResult::checksum(self : BenchmarkResult) -> UInt

    BenchmarkResult::elapsed_micros

    fn BenchmarkResult::elapsed_micros(self : BenchmarkResult) -> Int

    BenchmarkResult::encoded_bytes

    fn BenchmarkResult::encoded_bytes(self : BenchmarkResult) -> Int

    BenchmarkResult::encoded_frames

    fn BenchmarkResult::encoded_frames(self : BenchmarkResult) -> Int

    BenchmarkResult::frames_per_second

    fn BenchmarkResult::frames_per_second(self : BenchmarkResult) -> Float

    BenchmarkResult::megabytes_per_second

    fn BenchmarkResult::megabytes_per_second(self : BenchmarkResult) -> Float

    BenchmarkResult::new

    fn BenchmarkResult::new(case : BenchmarkCase, workload : BenchmarkWorkload, elapsed_micros : Int) -> Result[BenchmarkResult, String]

    BenchmarkSuite

    pub struct BenchmarkSuite {
    cases : Array[BenchmarkCase]
    } derive(
    Debug
    )

    BenchmarkSuite::add

    fn BenchmarkSuite::add(self : BenchmarkSuite, case : BenchmarkCase) -> Result[Unit, String]

    BenchmarkSuite::cases

    BenchmarkSuite::len

    fn BenchmarkSuite::len(self : BenchmarkSuite) -> Int

    BenchmarkSuite::new

    BenchmarkSuite::run

    fn BenchmarkSuite::run(self : BenchmarkSuite, elapsed_micros : Array[Int]) -> Result[Array[BenchmarkResult], String]

    Run a deterministic benchmark workload; elapsed time is supplied by the host.

    BenchmarkWorkload

    pub struct BenchmarkWorkload {
    rounds : Int
    payload_size : Int
    encoded_frames : Int
    encoded_bytes : Int
    checksum : UInt
    } derive(Eq,
    Debug
    )

    A repeatable workload used by local benchmark runs.

    BenchmarkWorkload::checksum

    fn BenchmarkWorkload::checksum(self : BenchmarkWorkload) -> UInt

    BenchmarkWorkload::encoded_bytes

    fn BenchmarkWorkload::encoded_bytes(self : BenchmarkWorkload) -> Int

    BenchmarkWorkload::encoded_frames

    fn BenchmarkWorkload::encoded_frames(self : BenchmarkWorkload) -> Int

    BenchmarkWorkload::payload_size

    fn BenchmarkWorkload::payload_size(self : BenchmarkWorkload) -> Int

    BenchmarkWorkload::rounds

    fn BenchmarkWorkload::rounds(self : BenchmarkWorkload) -> Int

    BinaryCounterValue

    pub struct BinaryCounterValue {
    value : UInt
    sequence : Int
    carry : Bool
    adjusted : Bool
    invalid : Bool
    } derive(Eq,
    Debug
    )

    32-bit binary counter value with sequence and overflow flags.

    BinaryCounterValue::flags

    fn BinaryCounterValue::flags(self : BinaryCounterValue) -> Int

    BinaryCounterValue::new

    fn BinaryCounterValue::new(value : UInt, sequence? : Int, carry? : Bool, adjusted? : Bool, invalid? : Bool) -> Result[BinaryCounterValue, String]

    BinaryCounterValue::sequence

    fn BinaryCounterValue::sequence(self : BinaryCounterValue) -> Int

    BinaryCounterValue::value

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

    ByteCursor

    pub struct ByteCursor {
    data : Bytes
    offset : Int
    } derive(
    Debug
    )

    A bounds-checked cursor for binary protocol decoders.

    ByteCursor::done

    fn ByteCursor::done(self : ByteCursor) -> Bool

    ByteCursor::new

    fn ByteCursor::new(data : Bytes) -> ByteCursor

    ByteCursor::offset

    fn ByteCursor::offset(self : ByteCursor) -> Int

    ByteCursor::read_byte

    fn ByteCursor::read_byte(self : ByteCursor) -> Result[Byte, Diagnostic]

    ByteCursor::read_bytes

    fn ByteCursor::read_bytes(self : ByteCursor, length : Int) -> Result[Bytes, Diagnostic]

    ByteCursor::read_u16

    fn ByteCursor::read_u16(self : ByteCursor) -> Result[Int, Diagnostic]

    ByteCursor::read_u24

    fn ByteCursor::read_u24(self : ByteCursor) -> Result[Int, Diagnostic]

    ByteCursor::read_u32

    fn ByteCursor::read_u32(self : ByteCursor) -> Result[UInt, Diagnostic]

    ByteCursor::remaining

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

    ByteCursor::seek

    fn ByteCursor::seek(self : ByteCursor, offset : Int) -> Result[Unit, Diagnostic]

    ByteCursor::skip

    fn ByteCursor::skip(self : ByteCursor, length : Int) -> Result[Unit, Diagnostic]

    ByteStatistics

    pub struct ByteStatistics {
    length : Int
    zeroes : Int
    high_bit : Int
    checksum : UInt
    minimum : Int
    maximum : Int
    } derive(Eq,
    Debug
    )

    Per-byte statistics useful for fixture and link diagnostics.

    ByteStatistics::checksum

    fn ByteStatistics::checksum(self : ByteStatistics) -> UInt

    ByteStatistics::high_bit

    fn ByteStatistics::high_bit(self : ByteStatistics) -> Int

    ByteStatistics::length

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

    ByteStatistics::maximum

    fn ByteStatistics::maximum(self : ByteStatistics) -> Int

    ByteStatistics::minimum

    fn ByteStatistics::minimum(self : ByteStatistics) -> Int

    ByteStatistics::zeroes

    fn ByteStatistics::zeroes(self : ByteStatistics) -> Int

    ByteWriter

    pub struct ByteWriter {
    bytes : Array[Byte]
    } derive(
    Debug
    )

    A small writer used by application-specific extensions.

    ByteWriter::len

    fn ByteWriter::len(self : ByteWriter) -> Int

    ByteWriter::new

    fn ByteWriter::new() -> ByteWriter

    ByteWriter::push

    fn ByteWriter::push(self : ByteWriter, value : Byte) -> Unit

    ByteWriter::push_bytes

    fn ByteWriter::push_bytes(self : ByteWriter, value : Bytes) -> Unit

    ByteWriter::push_u16

    fn ByteWriter::push_u16(self : ByteWriter, value : Int) -> Result[Unit, String]

    ByteWriter::push_u24

    fn ByteWriter::push_u24(self : ByteWriter, value : Int) -> Result[Unit, String]

    ByteWriter::push_u32

    fn ByteWriter::push_u32(self : ByteWriter, value : UInt) -> Unit

    ByteWriter::to_bytes

    fn ByteWriter::to_bytes(self : ByteWriter) -> Bytes

    Cause

    pub enum Cause {
    Periodic
    Background
    Spontaneous
    Initialised
    Request
    Activation
    ActivationConfirmation
    ActivationTermination
    Unknown(Int)
    } derive(Eq,
    Debug
    )

    Standard causes of transmission used by IEC 104 application services.

    Cause::is_activation

    fn Cause::is_activation(self : Cause) -> Bool

    Cause::is_spontaneous

    fn Cause::is_spontaneous(self : Cause) -> Bool

    Cause::is_termination

    fn Cause::is_termination(self : Cause) -> Bool

    Cause::number

    fn Cause::number(self : Cause) -> Int

    CauseCategory

    pub enum CauseCategory {
    Periodic
    Background
    Spontaneous
    Initialised
    Request
    Activation
    ActivationConfirmation
    ActivationTermination
    ReturnInformationRemote
    ReturnInformationLocal
    UnknownCause
    } derive(Eq,
    Debug
    )

    Cause of transmission category. The numeric value is kept separate from the qualifier so applications can preserve vendor extensions.

    CauseCategory::number

    fn CauseCategory::number(self : CauseCategory) -> Int

    Return the standard six-bit cause value.

    CauseOfTransmission

    pub struct CauseOfTransmission {
    category : CauseCategory
    number : Int
    positive : Bool
    test_flag : Bool
    originator : Int
    qualifier : Int
    } derive(Eq,
    Debug
    )

    Full cause of transmission, including the originator and qualifier bits.

    CauseOfTransmission::flags

    fn CauseOfTransmission::flags(self : CauseOfTransmission) -> Int

    Return the four low flag bits in the IEC COT representation.

    CauseOfTransmission::from_number

    fn CauseOfTransmission::from_number(number : Int, positive? : Bool, test_flag? : Bool, originator? : Int, qualifier? : Int) -> Result[CauseOfTransmission, String]

    Construct a cause from a raw standard number while preserving extension data.

    CauseOfTransmission::new

    fn CauseOfTransmission::new(category : CauseCategory, positive? : Bool, test_flag? : Bool, originator? : Int, qualifier? : Int) -> Result[CauseOfTransmission, String]

    Construct a validated cause of transmission.

    CauseOfTransmission::originator

    fn CauseOfTransmission::originator(self : CauseOfTransmission) -> Int

    Return the originator address.

    CauseOfTransmission::qualifier

    fn CauseOfTransmission::qualifier(self : CauseOfTransmission) -> Int

    Return the qualifier value.

    CauseOfTransmission::raw

    Return the raw cause number.

    ClockSyncTransaction

    pub struct ClockSyncTransaction {
    request : ServiceRequest
    status : ServiceStatus
    received : Cp56Time?
    applied_at : Int?
    } derive(
    Debug
    )

    Clock synchronization service with a deterministic skew calculation.

    ClockSyncTransaction::activate

    fn ClockSyncTransaction::activate(self : ClockSyncTransaction) -> Result[Unit, String]

    ClockSyncTransaction::apply

    fn ClockSyncTransaction::apply(self : ClockSyncTransaction, timestamp : Cp56Time, applied_at : Int) -> Result[Int, String]

    ClockSyncTransaction::new

    fn ClockSyncTransaction::new(request : ServiceRequest) -> Result[ClockSyncTransaction, String]

    ClockSyncTransaction::received

    ClockSyncTransaction::status

    CommandOutcome

    pub struct CommandOutcome {
    accepted : Bool
    status : ServiceStatus
    object : ApplicationObject?
    message : String
    } derive(
    Debug
    )

    CommandOutcome::accepted

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

    CommandOutcome::message

    fn CommandOutcome::message(self : CommandOutcome) -> String

    CommandOutcome::object

    CommandOutcome::status

    CommandPolicy

    pub struct CommandPolicy {
    allowed : Map[Int, Bool]
    allow_all : Bool
    max_qualifier : Int
    } derive(
    Debug
    )

    A command authorization policy for host applications.

    CommandPolicy::allow

    fn CommandPolicy::allow(self : CommandPolicy, address : InformationAddress) -> Unit

    CommandPolicy::allow_all

    fn CommandPolicy::allow_all() -> CommandPolicy

    CommandPolicy::deny

    fn CommandPolicy::deny(self : CommandPolicy, address : InformationAddress) -> Unit

    CommandPolicy::deny_all

    fn CommandPolicy::deny_all() -> CommandPolicy

    CommandPolicy::permits

    fn CommandPolicy::permits(self : CommandPolicy, object : ApplicationObject) -> Bool

    CommandPolicy::set_max_qualifier

    fn CommandPolicy::set_max_qualifier(self : CommandPolicy, value : Int) -> Result[Unit, String]

    CommandQueue

    pub struct CommandQueue {
    pending : Array[ApplicationObject]
    completed : Array[CommandOutcome]
    limit : Int
    } derive(
    Debug
    )

    A FIFO command queue with explicit outcomes.

    CommandQueue::completed_count

    fn CommandQueue::completed_count(self : CommandQueue) -> Int

    CommandQueue::enqueue

    fn CommandQueue::enqueue(self : CommandQueue, object : ApplicationObject) -> Result[Unit, String]

    CommandQueue::new

    fn CommandQueue::new(limit? : Int) -> Result[CommandQueue, String]

    CommandQueue::outcomes

    CommandQueue::pending_count

    fn CommandQueue::pending_count(self : CommandQueue) -> Int

    CommandQueue::process_one

    fn CommandQueue::process_one(self : CommandQueue, policy : CommandPolicy) -> CommandOutcome?

    CommonAddress

    pub struct CommonAddress {
    value : Int
    } derive(Eq,
    Debug
    )

    Common address of ASDU values. Zero is reserved for an unassigned station.

    CommonAddress::is_global

    fn CommonAddress::is_global(self : CommonAddress) -> Bool

    Return whether this common address is the global station address.

    CommonAddress::new

    fn CommonAddress::new(value : Int) -> Result[CommonAddress, String]

    Create a two-byte common address.

    CommonAddress::number

    fn CommonAddress::number(self : CommonAddress) -> Int

    Return the numeric common address.

    ConformanceReport

    pub struct ConformanceReport {
    valid : Bool
    type_id : ApplicationType
    object_count : Int
    expected_width : Int
    actual_width : Int
    issues : Array[String]
    } derive(Eq,
    Debug
    )

    An ASDU consistency report that can be shown in CLI diagnostics.

    ConformanceReport::actual_width

    fn ConformanceReport::actual_width(self : ConformanceReport) -> Int

    ConformanceReport::add_issue

    fn ConformanceReport::add_issue(self : ConformanceReport, message : String) -> Unit

    ConformanceReport::expected_width

    fn ConformanceReport::expected_width(self : ConformanceReport) -> Int

    ConformanceReport::issues

    fn ConformanceReport::issues(self : ConformanceReport) -> Array[String]

    ConformanceReport::new

    ConformanceReport::object_count

    fn ConformanceReport::object_count(self : ConformanceReport) -> Int

    ConformanceReport::type_id

    ConformanceReport::valid

    fn ConformanceReport::valid(self : ConformanceReport) -> Bool

    ConnectionParameters

    pub struct ConnectionParameters {
    k : Int
    w : Int
    t0_seconds : Int
    t1_seconds : Int
    t2_seconds : Int
    t3_seconds : Int
    } derive(Eq,
    Debug
    )

    IEC 104 link-layer timing and window parameters.

    ConnectionParameters::default

    Default parameters from the commonly deployed IEC 104 profile.

    ConnectionParameters::k

    ConnectionParameters::new

    fn ConnectionParameters::new(k : Int, w : Int, t0_seconds : Int, t1_seconds : Int, t2_seconds : Int, t3_seconds : Int) -> Result[ConnectionParameters, String]

    Validate and construct link-layer parameters.

    ConnectionParameters::t0

    ConnectionParameters::t1

    ConnectionParameters::t2

    ConnectionParameters::t3

    ConnectionParameters::w

    CounterInterrogationRequest

    pub struct CounterInterrogationRequest {
    common_address : CommonAddress
    qualifier : Int
    created_at : Int
    } derive(Eq,
    Debug
    )

    Counter-interrogation request used for historical counter snapshots.

    CounterInterrogationRequest::common_address

    CounterInterrogationRequest::created_at

    CounterInterrogationRequest::new

    fn CounterInterrogationRequest::new(common_address : CommonAddress, qualifier : Int, created_at : Int) -> Result[CounterInterrogationRequest, String]

    CounterInterrogationRequest::qualifier

    Cp24Time

    pub struct Cp24Time {
    millisecond : Int
    minute : Int
    } derive(Eq,
    Debug
    )

    Three-byte CP24Time2a value used by short time-tagged ASDUs.

    Cp24Time::from_bytes

    fn Cp24Time::from_bytes(data : Bytes, offset? : Int) -> Result[Cp24Time, String]

    Cp24Time::millisecond

    fn Cp24Time::millisecond(self : Cp24Time) -> Int

    Cp24Time::minute

    fn Cp24Time::minute(self : Cp24Time) -> Int

    Cp24Time::new

    fn Cp24Time::new(millisecond : Int, minute : Int) -> Result[Cp24Time, String]

    Cp24Time::remainder_millisecond

    fn Cp24Time::remainder_millisecond(self : Cp24Time) -> Int

    Cp24Time::second

    fn Cp24Time::second(self : Cp24Time) -> Int

    Cp24Time::to_array

    fn Cp24Time::to_array(self : Cp24Time) -> Array[Byte]

    Cp56Time

    pub struct Cp56Time {
    year : Int
    month : Int
    day : Int
    weekday : Int
    hour : Int
    minute : Int
    millisecond : Int
    } derive(Eq,
    Debug
    )

    Seven-byte CP56Time2a timestamp.

    Cp56Time::calendar_year

    fn Cp56Time::calendar_year(self : Cp56Time, century? : Int) -> Int

    Return the four-digit calendar year represented by the protocol year.

    Cp56Time::day

    fn Cp56Time::day(self : Cp56Time) -> Int

    Cp56Time::from_bytes

    fn Cp56Time::from_bytes(data : Bytes, offset? : Int) -> Result[Cp56Time, String]

    Cp56Time::hour

    fn Cp56Time::hour(self : Cp56Time) -> Int

    Cp56Time::millisecond

    fn Cp56Time::millisecond(self : Cp56Time) -> Int

    Cp56Time::minute

    fn Cp56Time::minute(self : Cp56Time) -> Int

    Cp56Time::month

    fn Cp56Time::month(self : Cp56Time) -> Int

    Cp56Time::new

    fn Cp56Time::new(year : Int, month : Int, day : Int, hour : Int, minute : Int, millisecond : Int, weekday? : Int) -> Result[Cp56Time, String]

    Construct a CP56 timestamp. The year is the two-digit protocol year.

    Cp56Time::ordering_key

    fn Cp56Time::ordering_key(self : Cp56Time) -> Int

    A deterministic date-time ordering key.

    Cp56Time::remainder_millisecond

    fn Cp56Time::remainder_millisecond(self : Cp56Time) -> Int

    Cp56Time::second

    fn Cp56Time::second(self : Cp56Time) -> Int

    Cp56Time::to_array

    fn Cp56Time::to_array(self : Cp56Time) -> Array[Byte]

    Cp56Time::weekday

    fn Cp56Time::weekday(self : Cp56Time) -> Int

    Cp56Time::year

    fn Cp56Time::year(self : Cp56Time) -> Int

    Diagnostic

    pub struct Diagnostic {
    kind : DiagnosticKind
    message : String
    offset : Int?
    } derive(Eq,
    Debug
    )

    Structured diagnostic returned by validation and service layers.

    Diagnostic::kind

    Diagnostic::message

    fn Diagnostic::message(self : Diagnostic) -> String

    Diagnostic::new

    fn Diagnostic::new(kind : DiagnosticKind, message : String, offset? : Int) -> Diagnostic

    Diagnostic::offset

    fn Diagnostic::offset(self : Diagnostic) -> Int?

    Diagnostic::to_line

    fn Diagnostic::to_line(self : Diagnostic) -> String

    Produce a compact human-readable diagnostic line for CLI and logs.

    DiagnosticKind

    pub enum DiagnosticKind {
    MalformedFrame
    InvalidSequence
    InvalidAddress
    InvalidType
    InvalidQualifier
    UnsupportedFeature
    WindowExhausted
    TimerExpired
    StateViolation
    TransportFailure
    } derive(Eq,
    Debug
    )

    A stable classification for protocol diagnostics.

    DoublePointValue

    pub struct DoublePointValue {
    state : Int
    quality : StatusQuality
    } derive(Eq,
    Debug
    )

    Double point information value. IEC 104 reserves state value 0 and 3.

    DoublePointValue::from_byte

    fn DoublePointValue::from_byte(value : Int) -> Result[DoublePointValue, String]

    DoublePointValue::new

    fn DoublePointValue::new(state : Int, quality? : StatusQuality) -> Result[DoublePointValue, String]

    DoublePointValue::quality

    DoublePointValue::state

    fn DoublePointValue::state(self : DoublePointValue) -> Int

    DoublePointValue::to_byte

    fn DoublePointValue::to_byte(self : DoublePointValue) -> Int

    EventLog

    pub struct EventLog {
    events : Array[ProtocolEvent]
    }

    In-memory event log for examples, tests and host applications.

    EventLog::all

    fn EventLog::all(self : EventLog) -> Array[ProtocolEvent]

    EventLog::len

    fn EventLog::len(self : EventLog) -> Int

    EventLog::new

    fn EventLog::new() -> EventLog

    EventLog::push

    fn EventLog::push(self : EventLog, event : ProtocolEvent) -> Unit

    Frame

    pub struct Frame {
    kind : FrameKind
    send_sequence : Int
    receive_sequence : Int
    control : UInt16
    payload : Bytes
    } derive(Eq,
    Debug
    )

    A decoded APCI frame. payload contains the ASDU for I frames.

    Frame::control

    fn Frame::control(self : Frame) -> UInt16

    Frame::is_information

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

    Frame::is_supervisory

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

    Frame::is_unnumbered

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

    Frame::kind

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

    Stable accessors for frame values used by host integrations.

    Frame::payload

    fn Frame::payload(self : Frame) -> Bytes

    Frame::receive_sequence

    fn Frame::receive_sequence(self : Frame) -> Int

    Frame::send_sequence

    fn Frame::send_sequence(self : Frame) -> Int

    FrameKind

    pub enum FrameKind {
    Information
    Supervisory
    Unnumbered
    } derive(Eq,
    Debug
    )

    IEC 60870-5-104 frame kinds.

    FrameMetrics

    pub struct FrameMetrics {
    frames_encoded : Int
    frames_decoded : Int
    information_frames : Int
    supervisory_frames : Int
    unnumbered_frames : Int
    bytes_encoded : Int
    bytes_decoded : Int
    malformed_frames : Int
    sequence_errors : Int
    service_failures : Int
    } derive(Eq,
    Debug
    )

    Counters for protocol throughput and error monitoring.

    FrameMetrics::error_count

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

    FrameMetrics::new

    FrameMetrics::record_decoded

    fn FrameMetrics::record_decoded(self : FrameMetrics, frame : Frame) -> Unit

    FrameMetrics::record_encoded

    fn FrameMetrics::record_encoded(self : FrameMetrics, frame : Frame) -> Unit

    FrameMetrics::record_malformed

    fn FrameMetrics::record_malformed(self : FrameMetrics) -> Unit

    FrameMetrics::record_sequence_error

    fn FrameMetrics::record_sequence_error(self : FrameMetrics) -> Unit

    FrameMetrics::record_service_failure

    fn FrameMetrics::record_service_failure(self : FrameMetrics) -> Unit

    FrameMetrics::snapshot

    fn FrameMetrics::snapshot(self : FrameMetrics) -> MetricsSnapshot

    FrameMetrics::success_rate

    fn FrameMetrics::success_rate(self : FrameMetrics) -> Float

    FrameMetrics::total_bytes

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

    FrameMetrics::total_frames

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

    GatewayAdmissionPolicy

    pub struct GatewayAdmissionPolicy {
    max_objects : Int
    allow_monitoring : Bool
    allow_control : Bool
    allowed_types : Array[ApplicationType]
    denied_types : Array[ApplicationType]
    } derive(Eq,
    Debug
    )

    Admission policy applied before a gateway accepts an ASDU.

    GatewayAdmissionPolicy::allow_type

    fn GatewayAdmissionPolicy::allow_type(self : GatewayAdmissionPolicy, type_id : ApplicationType) -> Unit

    GatewayAdmissionPolicy::default

    GatewayAdmissionPolicy::deny_type

    fn GatewayAdmissionPolicy::deny_type(self : GatewayAdmissionPolicy, type_id : ApplicationType) -> Unit

    GatewayAdmissionPolicy::evaluate

    fn GatewayAdmissionPolicy::evaluate(self : GatewayAdmissionPolicy, envelope : AsduEnvelope) -> Result[Unit, String]

    GatewayAdmissionPolicy::max_objects

    fn GatewayAdmissionPolicy::max_objects(self : GatewayAdmissionPolicy) -> Int

    GatewayAdmissionPolicy::new

    fn GatewayAdmissionPolicy::new(max_objects : Int, allow_monitoring? : Bool, allow_control? : Bool) -> Result[GatewayAdmissionPolicy, String]

    GatewayCounters

    pub struct GatewayCounters {
    accepted : Int
    forwarded : Int
    dropped : Int
    rejected : Int
    stored : Int
    } derive(Eq,
    Debug
    )

    Counters exposed by the gateway for operational dashboards.

    GatewayCounters::accepted

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

    GatewayCounters::dropped

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

    GatewayCounters::empty

    GatewayCounters::forwarded

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

    GatewayCounters::rejected

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

    GatewayCounters::stored

    fn GatewayCounters::stored(self : GatewayCounters) -> Int

    GatewayCounters::total

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

    GatewayDispatch

    pub enum GatewayDispatch {
    Forwarded(GatewayEnvelope, GatewayRoute)
    Dropped(GatewayEnvelope, String)
    } derive(
    Debug
    )

    GatewayDispatch::envelope

    GatewayDispatch::is_forwarded

    fn GatewayDispatch::is_forwarded(self : GatewayDispatch) -> Bool

    GatewayDispatch::message

    fn GatewayDispatch::message(self : GatewayDispatch) -> String

    GatewayEnvelope

    pub struct GatewayEnvelope {
    ingress : Int
    egress : Int
    common_address : CommonAddress
    asdu : AsduEnvelope
    received_at : Int
    trace_id : String
    } derive(
    Debug
    )

    An ASDU together with gateway ingress metadata.

    GatewayEnvelope::asdu

    GatewayEnvelope::common_address

    fn GatewayEnvelope::common_address(self : GatewayEnvelope) -> CommonAddress

    GatewayEnvelope::egress

    fn GatewayEnvelope::egress(self : GatewayEnvelope) -> Int

    GatewayEnvelope::ingress

    fn GatewayEnvelope::ingress(self : GatewayEnvelope) -> Int

    GatewayEnvelope::new

    fn GatewayEnvelope::new(ingress : Int, egress : Int, asdu : AsduEnvelope, received_at : Int, trace_id? : String) -> Result[GatewayEnvelope, String]

    GatewayEnvelope::object_count

    fn GatewayEnvelope::object_count(self : GatewayEnvelope) -> Int

    GatewayEnvelope::received_at

    fn GatewayEnvelope::received_at(self : GatewayEnvelope) -> Int

    GatewayEnvelope::trace_id

    fn GatewayEnvelope::trace_id(self : GatewayEnvelope) -> String

    GatewayMode

    pub enum GatewayMode {
    Stopped
    Starting
    Running
    Draining
    Faulted(String)
    } derive(Eq,
    Debug
    )

    Lifecycle of an in-memory IEC 104 gateway runtime.

    GatewayMode::is_accepting

    fn GatewayMode::is_accepting(self : GatewayMode) -> Bool

    GatewayMode::is_quiescent

    fn GatewayMode::is_quiescent(self : GatewayMode) -> Bool

    GatewayMode::name

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

    GatewayRoute

    pub struct GatewayRoute {
    id : Int
    source : Int
    destination : Int
    common_address : CommonAddress?
    type_ids : Array[ApplicationType]
    enabled : Bool
    priority : Int
    } derive(Eq,
    Debug
    )

    A route between two logical gateway endpoints.

    GatewayRoute::common_address

    fn GatewayRoute::common_address(self : GatewayRoute) -> CommonAddress?

    GatewayRoute::describe

    fn GatewayRoute::describe(self : GatewayRoute) -> String

    GatewayRoute::destination

    fn GatewayRoute::destination(self : GatewayRoute) -> Int

    GatewayRoute::enabled

    fn GatewayRoute::enabled(self : GatewayRoute) -> Bool

    GatewayRoute::id

    fn GatewayRoute::id(self : GatewayRoute) -> Int

    GatewayRoute::new

    fn GatewayRoute::new(id : Int, source : Int, destination : Int, common_address? : CommonAddress, type_ids? : Array[ApplicationType], priority? : Int) -> Result[GatewayRoute, String]

    GatewayRoute::priority

    fn GatewayRoute::priority(self : GatewayRoute) -> Int

    GatewayRoute::set_enabled

    fn GatewayRoute::set_enabled(self : GatewayRoute, enabled : Bool) -> Unit

    GatewayRoute::source

    fn GatewayRoute::source(self : GatewayRoute) -> Int

    GatewayRoute::type_ids

    GatewayRouteTable

    pub struct GatewayRouteTable {
    routes : Array[GatewayRoute]
    capacity : Int
    } derive(
    Debug
    )

    Deterministic route table. Higher priority wins; ties use the lower route id.

    GatewayRouteTable::add

    fn GatewayRouteTable::add(self : GatewayRouteTable, route : GatewayRoute) -> Result[Unit, String]

    GatewayRouteTable::capacity

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

    GatewayRouteTable::len

    fn GatewayRouteTable::len(self : GatewayRouteTable) -> Int

    GatewayRouteTable::new

    fn GatewayRouteTable::new(capacity? : Int) -> Result[GatewayRouteTable, String]

    GatewayRouteTable::remove

    fn GatewayRouteTable::remove(self : GatewayRouteTable, route_id : Int) -> Bool

    GatewayRouteTable::routes

    GatewayRouteTable::select

    fn GatewayRouteTable::select(self : GatewayRouteTable, source : Int, common_address : CommonAddress, type_id : ApplicationType) -> GatewayRoute?

    GatewayRouteTable::set_enabled

    fn GatewayRouteTable::set_enabled(self : GatewayRouteTable, route_id : Int, enabled : Bool) -> Bool

    GatewayRuntime

    pub struct GatewayRuntime {
    mode : GatewayMode
    routes : GatewayRouteTable
    policy : GatewayAdmissionPolicy
    inbound : Array[GatewayEnvelope]
    outbound : Array[GatewayEnvelope]
    dead_letters : Array[GatewayEnvelope]
    stores : Array[GatewayStoreBinding]
    counters : GatewayCounters
    max_queue : Int
    last_error : String?
    } derive(
    Debug
    )

    Deterministic in-memory routing runtime. Network adapters can feed its queue and poll the outbound queue without coupling protocol logic to a socket API.

    GatewayRuntime::add_route

    fn GatewayRuntime::add_route(self : GatewayRuntime, route : GatewayRoute) -> Result[Unit, String]

    GatewayRuntime::attach_store

    fn GatewayRuntime::attach_store(self : GatewayRuntime, binding : GatewayStoreBinding) -> Result[Unit, String]

    GatewayRuntime::begin_drain

    fn GatewayRuntime::begin_drain(self : GatewayRuntime) -> Result[Unit, String]

    GatewayRuntime::counters

    GatewayRuntime::dead_letter_len

    fn GatewayRuntime::dead_letter_len(self : GatewayRuntime) -> Int

    GatewayRuntime::diagnostics

    fn GatewayRuntime::diagnostics(self : GatewayRuntime) -> String

    Return a stable, line-oriented diagnostics report for logs and health probes.

    GatewayRuntime::drain

    fn GatewayRuntime::drain(self : GatewayRuntime, max_dispatches? : Int) -> Array[GatewayDispatch]

    GatewayRuntime::enqueue

    fn GatewayRuntime::enqueue(self : GatewayRuntime, envelope : GatewayEnvelope) -> Result[Unit, String]

    GatewayRuntime::fail

    fn GatewayRuntime::fail(self : GatewayRuntime, message : String) -> Unit

    GatewayRuntime::ingest_to_store

    fn GatewayRuntime::ingest_to_store(self : GatewayRuntime, envelope : GatewayEnvelope) -> Result[Int, String]

    GatewayRuntime::last_error

    fn GatewayRuntime::last_error(self : GatewayRuntime) -> String?

    GatewayRuntime::mode

    GatewayRuntime::new

    fn GatewayRuntime::new(max_queue : Int, route_capacity? : Int, policy? : GatewayAdmissionPolicy) -> Result[GatewayRuntime, String]

    GatewayRuntime::outbound_len

    fn GatewayRuntime::outbound_len(self : GatewayRuntime) -> Int

    GatewayRuntime::poll_outbound

    fn GatewayRuntime::poll_outbound(self : GatewayRuntime) -> GatewayEnvelope?

    GatewayRuntime::queue_len

    fn GatewayRuntime::queue_len(self : GatewayRuntime) -> Int

    GatewayRuntime::remove_route

    fn GatewayRuntime::remove_route(self : GatewayRuntime, route_id : Int) -> Bool

    GatewayRuntime::routes

    GatewayRuntime::set_policy

    fn GatewayRuntime::set_policy(self : GatewayRuntime, policy : GatewayAdmissionPolicy) -> Unit

    GatewayRuntime::snapshot

    GatewayRuntime::start

    fn GatewayRuntime::start(self : GatewayRuntime) -> Result[Unit, String]

    GatewayRuntime::stop

    fn GatewayRuntime::stop(self : GatewayRuntime) -> Result[Unit, String]

    GatewayRuntime::store_count

    fn GatewayRuntime::store_count(self : GatewayRuntime) -> Int

    GatewayRuntime::take_dead_letter

    fn GatewayRuntime::take_dead_letter(self : GatewayRuntime) -> GatewayEnvelope?

    GatewaySnapshot

    pub struct GatewaySnapshot {
    mode : GatewayMode
    routes : Int
    queue : Int
    outbound : Int
    dead_letters : Int
    counters : GatewayCounters
    last_error : String?
    } derive(Eq,
    Debug
    )

    Snapshot suitable for a health endpoint or a periodic metrics export.

    GatewaySnapshot::counters

    GatewaySnapshot::dead_letters

    fn GatewaySnapshot::dead_letters(self : GatewaySnapshot) -> Int

    GatewaySnapshot::last_error

    fn GatewaySnapshot::last_error(self : GatewaySnapshot) -> String?

    GatewaySnapshot::mode

    GatewaySnapshot::outbound

    fn GatewaySnapshot::outbound(self : GatewaySnapshot) -> Int

    GatewaySnapshot::queue

    fn GatewaySnapshot::queue(self : GatewaySnapshot) -> Int

    GatewaySnapshot::routes

    fn GatewaySnapshot::routes(self : GatewaySnapshot) -> Int

    GatewayStoreBinding

    pub struct GatewayStoreBinding {
    common_address : CommonAddress
    store : PointStore
    accepted : Int
    rejected : Int
    } derive(
    Debug
    )

    A point store attached to one common address in the gateway.

    GatewayStoreBinding::accepted

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

    GatewayStoreBinding::common_address

    GatewayStoreBinding::ingest

    fn GatewayStoreBinding::ingest(self : GatewayStoreBinding, envelope : GatewayEnvelope) -> Result[Int, String]

    GatewayStoreBinding::new

    fn GatewayStoreBinding::new(common_address : CommonAddress, history_limit? : Int) -> Result[GatewayStoreBinding, String]

    GatewayStoreBinding::rejected

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

    GatewayStoreBinding::store

    HealthReport

    pub struct HealthReport {
    state : HealthState
    score : Int
    checks : Array[String]
    warnings : Array[String]
    } derive(Eq,
    Debug
    )

    HealthReport::checks

    fn HealthReport::checks(self : HealthReport) -> Array[String]

    HealthReport::new

    fn HealthReport::new(state : HealthState, score : Int, checks : Array[String], warnings : Array[String]) -> HealthReport

    HealthReport::score

    fn HealthReport::score(self : HealthReport) -> Int

    HealthReport::state

    HealthReport::warnings

    fn HealthReport::warnings(self : HealthReport) -> Array[String]

    HealthState

    pub enum HealthState {
    Healthy
    Degraded
    Unready
    } derive(Eq,
    Debug
    )

    Health state suitable for gateway readiness endpoints.

    InformationAddress

    pub struct InformationAddress {
    value : Int
    } derive(Eq,
    Debug
    )

    The three-byte information object address used by IEC 104.

    InformationAddress::from_octets

    fn InformationAddress::from_octets(low : Int, middle : Int, high : Int) -> Result[InformationAddress, String]

    Construct an information object address from its three octets.

    InformationAddress::high

    fn InformationAddress::high(self : InformationAddress) -> Int

    Return the most significant address octet.

    InformationAddress::is_broadcast

    fn InformationAddress::is_broadcast(self : InformationAddress) -> Bool

    Return whether the address is the protocol's broadcast address.

    InformationAddress::low

    fn InformationAddress::low(self : InformationAddress) -> Int

    Return the least significant address octet.

    InformationAddress::middle

    fn InformationAddress::middle(self : InformationAddress) -> Int

    Return the middle address octet.

    InformationAddress::new

    fn InformationAddress::new(value : Int) -> Result[InformationAddress, String]

    Create an information object address in the inclusive 0..0xffffff range.

    InformationAddress::number

    fn InformationAddress::number(self : InformationAddress) -> Int

    Return the numeric address.

    InformationObject

    pub enum InformationObject {
    Single(Bool, Int)
    Double(Int, Int)
    Normalized(Int, Int)
    ShortFloat(Float, Int)
    BitString(UInt, Int)
    } derive(Eq,
    Debug
    )

    IEC information object values supported by the first stable API.

    Interrogation

    pub struct Interrogation {
    request : InterrogationRequest
    phase : InterrogationPhase
    objects_sent : Int
    }

    Small deterministic transaction tracker; data transport remains caller-owned.

    Interrogation::activate

    fn Interrogation::activate(self : Interrogation) -> Int

    Interrogation::finish

    fn Interrogation::finish(self : Interrogation) -> Int

    Interrogation::new

    Interrogation::record

    fn Interrogation::record(self : Interrogation, count : Int) -> Result[Unit, String]

    InterrogationPhase

    pub enum InterrogationPhase {
    Idle
    Activated
    Sending
    Terminated
    } derive(Eq,
    Debug
    )

    Phases emitted by an interrogation transaction.

    InterrogationPlan

    pub struct InterrogationPlan {
    request : InterrogationRequest
    objects : Array[ApplicationObject]
    batch_size : Int
    cursor : Int
    status : ServiceStatus
    } derive(
    Debug
    )

    A total interrogation plan which can be emitted in deterministic batches.

    InterrogationPlan::activate

    fn InterrogationPlan::activate(self : InterrogationPlan) -> Result[Int, String]

    InterrogationPlan::new

    fn InterrogationPlan::new(request : InterrogationRequest, objects : Array[ApplicationObject], batch_size? : Int) -> Result[InterrogationPlan, String]

    InterrogationPlan::next_batch

    fn InterrogationPlan::next_batch(self : InterrogationPlan) -> Result[Array[ApplicationObject], String]

    InterrogationPlan::remaining

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

    InterrogationPlan::request

    InterrogationPlan::status

    InterrogationPlan::terminate

    fn InterrogationPlan::terminate(self : InterrogationPlan) -> Result[Int, String]

    InterrogationRequest

    pub struct InterrogationRequest {
    common_address : Int
    qualifier : Int
    } derive(Eq,
    Debug
    )

    A total interrogation request, suitable for a master command queue.

    InterrogationRequest::new

    fn InterrogationRequest::new(common_address : Int, qualifier? : Int) -> InterrogationRequest

    LengthHistogram

    pub struct LengthHistogram {
    buckets : Map[Int, Int]
    samples : Int
    } derive(
    Debug
    )

    A compact histogram for APDU length distribution.

    LengthHistogram::all

    fn LengthHistogram::all(self : LengthHistogram) -> Array[(Int, Int)]

    LengthHistogram::bucket

    fn LengthHistogram::bucket(self : LengthHistogram, maximum : Int) -> Int

    LengthHistogram::new

    LengthHistogram::observe

    fn LengthHistogram::observe(self : LengthHistogram, length : Int) -> Unit

    LengthHistogram::samples

    fn LengthHistogram::samples(self : LengthHistogram) -> Int

    LinkState

    pub enum LinkState {
    Disconnected
    Connecting
    Started
    Stopped
    TestPending
    } derive(Eq,
    Debug
    )

    Link-layer state used by a master or outstation session.

    LinkState::is_connected

    fn LinkState::is_connected(self : LinkState) -> Bool

    LinkState::is_terminal

    fn LinkState::is_terminal(self : LinkState) -> Bool

    MeasurementState

    pub enum MeasurementState {
    Good
    Blocked
    Substituted
    NotTopical
    Invalid
    } derive(Eq,
    Debug
    )

    Quality-preserving measurement classification used by point stores.

    MetricsSnapshot

    pub struct MetricsSnapshot {
    frames : Int
    bytes : Int
    errors : Int
    success_rate : Float
    } derive(Eq,
    Debug
    )

    Snapshot an evolving metrics object for export or health endpoints.

    MetricsSnapshot::bytes

    fn MetricsSnapshot::bytes(self : MetricsSnapshot) -> Int

    MetricsSnapshot::errors

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

    MetricsSnapshot::frames

    fn MetricsSnapshot::frames(self : MetricsSnapshot) -> Int

    MetricsSnapshot::success_rate

    fn MetricsSnapshot::success_rate(self : MetricsSnapshot) -> Float

    NegotiationDecision

    pub enum NegotiationDecision {
    CompatibleProfile
    IncompatibleProfile(Array[String])
    } derive(
    Debug
    )

    NormalizedValue

    pub struct NormalizedValue {
    value : Int
    quality : QualityDescriptor
    } derive(Eq,
    Debug
    )

    Normalized signed 16-bit measurement.

    NormalizedValue::new

    fn NormalizedValue::new(value : Int, quality? : QualityDescriptor) -> Result[NormalizedValue, String]

    NormalizedValue::quality

    NormalizedValue::raw_unsigned

    fn NormalizedValue::raw_unsigned(self : NormalizedValue) -> Int

    NormalizedValue::to_array

    fn NormalizedValue::to_array(self : NormalizedValue) -> Array[Byte]

    NormalizedValue::value

    fn NormalizedValue::value(self : NormalizedValue) -> Int

    Outstation

    pub struct Outstation {
    common_address : Int
    single_points : Map[Int, Bool]
    normalized_values : Map[Int, Int]
    }

    A compact in-memory outstation used in tests, demos and protocol simulations.

    Outstation::new

    fn Outstation::new(common_address : Int) -> Outstation

    Outstation::normalized

    fn Outstation::normalized(self : Outstation, ioa : Int) -> Int?

    Outstation::set_normalized

    fn Outstation::set_normalized(self : Outstation, ioa : Int, value : Int) -> Unit

    Outstation::set_single

    fn Outstation::set_single(self : Outstation, ioa : Int, value : Bool) -> Unit

    Outstation::single

    fn Outstation::single(self : Outstation, ioa : Int) -> Bool?

    Outstation::snapshot_normalized

    fn Outstation::snapshot_normalized(self : Outstation) -> Array[PointSnapshot]

    Outstation::snapshot_single

    fn Outstation::snapshot_single(self : Outstation) -> Array[PointSnapshot]

    PointChange

    pub struct PointChange {
    kind : PointChangeKind
    address : InformationAddress
    revision : Int
    timestamp : Int
    message : String
    } derive(Eq,
    Debug
    )

    PointChange::address

    PointChange::kind

    PointChange::message

    fn PointChange::message(self : PointChange) -> String

    PointChange::new

    fn PointChange::new(kind : PointChangeKind, address : InformationAddress, revision : Int, timestamp : Int, message : String) -> PointChange

    PointChange::revision

    fn PointChange::revision(self : PointChange) -> Int

    PointChange::timestamp

    fn PointChange::timestamp(self : PointChange) -> Int

    PointChangeKind

    pub enum PointChangeKind {
    Inserted
    Updated
    Removed
    Rejected
    } derive(Eq,
    Debug
    )

    A change recorded by the point store.

    PointDirection

    pub enum PointDirection {
    MonitorDirection
    ControlDirection
    } derive(Eq,
    Debug
    )

    Point direction used by a station data model.

    PointFilter

    pub struct PointFilter {
    direction : PointDirection?
    type_id : ApplicationType?
    first_address : InformationAddress?
    last_address : InformationAddress?
    only_valid : Bool
    source : String?
    } derive(Eq,
    Debug
    )

    Query constraints for a point-store snapshot.

    PointFilter::all

    PointFilter::control

    fn PointFilter::control() -> PointFilter

    PointFilter::from_source

    fn PointFilter::from_source(self : PointFilter, source : String) -> PointFilter

    PointFilter::monitoring

    fn PointFilter::monitoring() -> PointFilter

    PointFilter::valid_only

    fn PointFilter::valid_only(self : PointFilter) -> PointFilter

    PointFilter::with_range

    fn PointFilter::with_range(self : PointFilter, first : InformationAddress, last : InformationAddress) -> PointFilter

    PointFilter::with_type

    fn PointFilter::with_type(self : PointFilter, type_id : ApplicationType) -> PointFilter

    PointRecord

    pub struct PointRecord {
    address : InformationAddress
    type_id : ApplicationType
    value : ApplicationValue
    time_tag : TimeTag?
    revision : Int
    updated_at : Int
    source : String
    } derive(Eq,
    Debug
    )

    A stored value with its protocol identity and update metadata.

    PointRecord::address

    PointRecord::direction

    fn PointRecord::direction(self : PointRecord) -> PointDirection

    PointRecord::is_valid

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

    PointRecord::new

    fn PointRecord::new(object : ApplicationObject, updated_at : Int, revision? : Int, source? : String) -> PointRecord

    PointRecord::revision

    fn PointRecord::revision(self : PointRecord) -> Int

    PointRecord::source

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

    PointRecord::time_tag

    fn PointRecord::time_tag(self : PointRecord) -> TimeTag?

    PointRecord::type_id

    fn PointRecord::type_id(self : PointRecord) -> ApplicationType

    PointRecord::updated_at

    fn PointRecord::updated_at(self : PointRecord) -> Int

    PointRecord::value

    PointSnapshot

    pub struct PointSnapshot {
    ioa : Int
    value : InformationObject
    }

    An immutable snapshot of values that can be used to build a response ASDU.

    PointStore

    pub struct PointStore {
    common_address : CommonAddress
    points : Map[Int, PointRecord]
    history : Array[PointChange]
    history_limit : Int
    } derive(
    Debug
    )

    Deterministic point store for outstations, simulators and gateways.

    PointStore::addresses

    fn PointStore::addresses(self : PointStore) -> Array[InformationAddress]

    PointStore::common_address

    fn PointStore::common_address(self : PointStore) -> CommonAddress

    PointStore::get

    fn PointStore::get(self : PointStore, address : InformationAddress) -> PointRecord?

    PointStore::history

    fn PointStore::history(self : PointStore) -> Array[PointChange]

    PointStore::history_len

    fn PointStore::history_len(self : PointStore) -> Int

    PointStore::len

    fn PointStore::len(self : PointStore) -> Int

    PointStore::new

    fn PointStore::new(common_address : CommonAddress, history_limit? : Int) -> Result[PointStore, String]

    PointStore::objects

    fn PointStore::objects(self : PointStore, filter : PointFilter) -> Array[ApplicationObject]

    Convert a store snapshot into application objects for interrogation.

    PointStore::query

    fn PointStore::query(self : PointStore, filter : PointFilter) -> Array[PointRecord]

    PointStore::remove

    fn PointStore::remove(self : PointStore, address : InformationAddress, timestamp : Int) -> Result[PointChange, Diagnostic]

    PointStore::statistics

    fn PointStore::statistics(self : PointStore) -> StoreStatistics

    PointStore::upsert

    fn PointStore::upsert(self : PointStore, object : ApplicationObject, timestamp : Int, source? : String) -> Result[PointChange, Diagnostic]

    ProfileRegistry

    pub struct ProfileRegistry {
    profiles : Map[String, StationProfile]
    } derive(
    Debug
    )

    ProfileRegistry::get

    fn ProfileRegistry::get(self : ProfileRegistry, name : String) -> StationProfile?

    ProfileRegistry::len

    fn ProfileRegistry::len(self : ProfileRegistry) -> Int

    ProfileRegistry::names

    fn ProfileRegistry::names(self : ProfileRegistry) -> Array[String]

    ProfileRegistry::new

    ProfileRegistry::put

    fn ProfileRegistry::put(self : ProfileRegistry, profile : StationProfile) -> Result[Unit, String]

    ProfileRegistry::remove

    fn ProfileRegistry::remove(self : ProfileRegistry, name : String) -> Bool

    ProfileRegistry::replace

    fn ProfileRegistry::replace(self : ProfileRegistry, profile : StationProfile) -> Unit

    ProtocolEvent

    pub enum ProtocolEvent {
    Connected
    Started
    Stopped
    Sent(Int)
    Received(Int)
    Acknowledged(Int)
    Fault(String)
    } derive(Eq,
    Debug
    )

    A protocol event useful for deterministic simulation and diagnostics.

    ProtocolTimers

    pub struct ProtocolTimers {
    t0 : TimerState
    t1 : TimerState
    t2 : TimerState
    t3 : TimerState
    } derive(Eq,
    Debug
    )

    ProtocolTimers::expired

    fn ProtocolTimers::expired(self : ProtocolTimers, now : Int) -> Array[String]

    ProtocolTimers::new

    ProtocolTimers::start_t0

    fn ProtocolTimers::start_t0(self : ProtocolTimers, deadline : Int) -> Unit

    ProtocolTimers::start_t1

    fn ProtocolTimers::start_t1(self : ProtocolTimers, deadline : Int) -> Unit

    ProtocolTimers::start_t2

    fn ProtocolTimers::start_t2(self : ProtocolTimers, deadline : Int) -> Unit

    ProtocolTimers::start_t3

    fn ProtocolTimers::start_t3(self : ProtocolTimers, deadline : Int) -> Unit

    ProtocolTimers::stop_t0

    fn ProtocolTimers::stop_t0(self : ProtocolTimers) -> Unit

    ProtocolTimers::stop_t1

    fn ProtocolTimers::stop_t1(self : ProtocolTimers) -> Unit

    ProtocolTimers::stop_t2

    fn ProtocolTimers::stop_t2(self : ProtocolTimers) -> Unit

    ProtocolTimers::stop_t3

    fn ProtocolTimers::stop_t3(self : ProtocolTimers) -> Unit

    QualityDescriptor

    pub struct QualityDescriptor {
    overflow : Bool
    blocked : Bool
    substituted : Bool
    not_topical : Bool
    invalid : Bool
    } derive(Eq,
    Debug
    )

    Quality descriptor shared by status and measurement objects.

    QualityDescriptor::clear

    QualityDescriptor::flags

    fn QualityDescriptor::flags(self : QualityDescriptor) -> Array[String]

    QualityDescriptor::from_byte

    fn QualityDescriptor::from_byte(value : Int) -> Result[QualityDescriptor, String]

    Decode the low byte of a QDS value.

    QualityDescriptor::has_status_change

    fn QualityDescriptor::has_status_change(self : QualityDescriptor) -> Bool

    QualityDescriptor::is_usable

    fn QualityDescriptor::is_usable(self : QualityDescriptor) -> Bool

    QualityDescriptor::to_byte

    fn QualityDescriptor::to_byte(self : QualityDescriptor) -> Int

    QualityDescriptor::with_blocked

    fn QualityDescriptor::with_blocked(self : QualityDescriptor, value : Bool) -> QualityDescriptor

    QualityDescriptor::with_invalid

    fn QualityDescriptor::with_invalid(self : QualityDescriptor, value : Bool) -> QualityDescriptor

    QualityDescriptor::with_not_topical

    fn QualityDescriptor::with_not_topical(self : QualityDescriptor, value : Bool) -> QualityDescriptor

    QualityDescriptor::with_overflow

    fn QualityDescriptor::with_overflow(self : QualityDescriptor, value : Bool) -> QualityDescriptor

    QualityDescriptor::with_substituted

    fn QualityDescriptor::with_substituted(self : QualityDescriptor, value : Bool) -> QualityDescriptor

    RateLimiter

    pub struct RateLimiter {
    window_start : Int
    window_size : Int
    limit : Int
    used : Int
    } derive(Eq,
    Debug
    )

    A fixed-window rate limiter for commands and diagnostics.

    RateLimiter::allow

    fn RateLimiter::allow(self : RateLimiter, now : Int) -> Bool

    RateLimiter::new

    fn RateLimiter::new(window_size : Int, limit : Int) -> Result[RateLimiter, String]

    RateLimiter::remaining

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

    RateLimiter::used

    fn RateLimiter::used(self : RateLimiter) -> Int

    ReadTransaction

    pub struct ReadTransaction {
    request : ServiceRequest
    status : ServiceStatus
    } derive(
    Debug
    )

    Read service state for a single information object.

    ReadTransaction::activate

    fn ReadTransaction::activate(self : ReadTransaction) -> Result[Unit, String]

    ReadTransaction::complete

    fn ReadTransaction::complete(self : ReadTransaction, object : ApplicationObject) -> Result[ServiceResponse, String]

    ReadTransaction::new

    fn ReadTransaction::new(request : ServiceRequest) -> Result[ReadTransaction, String]

    ReadTransaction::reject

    fn ReadTransaction::reject(self : ReadTransaction, message : String) -> ServiceResponse

    ReadTransaction::status

    ReplayGuard

    pub struct ReplayGuard {
    seen : Map[UInt, Int]
    ttl : Int
    limit : Int
    } derive(
    Debug
    )

    Replay guard keyed by APDU checksum and a bounded time interval.

    ReplayGuard::is_replay

    fn ReplayGuard::is_replay(self : ReplayGuard, frame : Bytes, now : Int) -> Bool

    ReplayGuard::len

    fn ReplayGuard::len(self : ReplayGuard) -> Int

    ReplayGuard::new

    fn ReplayGuard::new(ttl : Int, limit : Int) -> Result[ReplayGuard, String]

    ReplayGuard::purge

    fn ReplayGuard::purge(self : ReplayGuard, now : Int) -> Int

    ReplayGuard::remember

    fn ReplayGuard::remember(self : ReplayGuard, frame : Bytes, now : Int) -> Result[Unit, String]

    ResourceLimits

    pub struct ResourceLimits {
    max_apdu : Int
    max_asdu : Int
    max_objects : Int
    max_history : Int
    max_commands : Int
    max_trace_events : Int
    } derive(Eq,
    Debug
    )

    Resource limits prevent malformed peers from exhausting a gateway.

    ResourceLimits::default

    ResourceLimits::max_apdu

    fn ResourceLimits::max_apdu(self : ResourceLimits) -> Int

    ResourceLimits::max_asdu

    fn ResourceLimits::max_asdu(self : ResourceLimits) -> Int

    ResourceLimits::max_commands

    fn ResourceLimits::max_commands(self : ResourceLimits) -> Int

    ResourceLimits::max_history

    fn ResourceLimits::max_history(self : ResourceLimits) -> Int

    ResourceLimits::max_objects

    fn ResourceLimits::max_objects(self : ResourceLimits) -> Int

    ResourceLimits::max_trace_events

    fn ResourceLimits::max_trace_events(self : ResourceLimits) -> Int

    ResourceLimits::new

    fn ResourceLimits::new(max_apdu : Int, max_asdu : Int, max_objects : Int, max_history : Int, max_commands : Int, max_trace_events : Int) -> Result[ResourceLimits, String]

    ScaledValue

    pub struct ScaledValue {
    value : Int
    quality : QualityDescriptor
    } derive(Eq,
    Debug
    )

    Signed 16-bit scaled measurement.

    ScaledValue::new

    fn ScaledValue::new(value : Int, quality? : QualityDescriptor) -> Result[ScaledValue, String]

    ScaledValue::quality

    ScaledValue::to_array

    fn ScaledValue::to_array(self : ScaledValue) -> Array[Byte]

    ScaledValue::value

    fn ScaledValue::value(self : ScaledValue) -> Int

    ScheduledAction

    pub struct ScheduledAction {
    at : Int
    ordinal : Int
    action : SimulationAction
    } derive(
    Debug
    )

    ScheduledAction::action

    ScheduledAction::at

    fn ScheduledAction::at(self : ScheduledAction) -> Int

    ScheduledAction::new

    fn ScheduledAction::new(at : Int, ordinal : Int, action : SimulationAction) -> ScheduledAction

    ScheduledAction::ordinal

    fn ScheduledAction::ordinal(self : ScheduledAction) -> Int

    SequenceWindow

    pub struct SequenceWindow {
    first_unacknowledged : Int
    next_send : Int
    next_receive : Int
    capacity : Int
    } derive(Eq,
    Debug
    )

    A validated receive/send sequence window.

    SequenceWindow::acknowledge

    fn SequenceWindow::acknowledge(self : SequenceWindow, sequence : Int) -> Result[Int, String]

    SequenceWindow::available

    fn SequenceWindow::available(self : SequenceWindow) -> Int

    SequenceWindow::can_send

    fn SequenceWindow::can_send(self : SequenceWindow) -> Bool

    SequenceWindow::new

    fn SequenceWindow::new(capacity : Int) -> Result[SequenceWindow, String]

    SequenceWindow::next_receive

    fn SequenceWindow::next_receive(self : SequenceWindow) -> Int

    SequenceWindow::next_send

    fn SequenceWindow::next_send(self : SequenceWindow) -> Int

    SequenceWindow::pending

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

    SequenceWindow::receive

    fn SequenceWindow::receive(self : SequenceWindow, sequence : Int) -> Result[Unit, String]

    SequenceWindow::reserve_send

    fn SequenceWindow::reserve_send(self : SequenceWindow) -> Result[Int, String]

    ServiceKind

    pub enum ServiceKind {
    InterrogationService
    CounterInterrogationService
    ReadService
    ClockSyncService
    CommandService
    ResetService
    DelayAcquisitionService
    } derive(Eq,
    Debug
    )

    Application service classes supported by the portable core.

    ServiceRequest

    pub struct ServiceRequest {
    service : ServiceKind
    address : InformationAddress
    common_address : CommonAddress
    qualifier : Int
    created_at : Int
    originator : Int
    } derive(Eq,
    Debug
    )

    An application service request independent of a transport.

    ServiceRequest::address

    ServiceRequest::common_address

    fn ServiceRequest::common_address(self : ServiceRequest) -> CommonAddress

    ServiceRequest::created_at

    fn ServiceRequest::created_at(self : ServiceRequest) -> Int

    ServiceRequest::new

    fn ServiceRequest::new(service : ServiceKind, address : InformationAddress, common_address : CommonAddress, qualifier : Int, created_at : Int, originator? : Int) -> Result[ServiceRequest, Diagnostic]

    ServiceRequest::originator

    fn ServiceRequest::originator(self : ServiceRequest) -> Int

    ServiceRequest::qualifier

    fn ServiceRequest::qualifier(self : ServiceRequest) -> Int

    ServiceRequest::service

    ServiceResponse

    pub struct ServiceResponse {
    request : ServiceRequest
    status : ServiceStatus
    cause : CauseOfTransmission
    objects : Array[ApplicationObject]
    message : String
    } derive(
    Debug
    )

    A service response with optional application data.

    ServiceResponse::cause

    ServiceResponse::message

    fn ServiceResponse::message(self : ServiceResponse) -> String

    ServiceResponse::new

    fn ServiceResponse::new(request : ServiceRequest, status : ServiceStatus, cause : CauseOfTransmission, objects : Array[ApplicationObject], message? : String) -> ServiceResponse

    ServiceResponse::objects

    ServiceResponse::request

    ServiceResponse::status

    ServiceStatus

    pub enum ServiceStatus {
    IdleService
    ActiveService
    ConfirmedService
    TerminatedService
    RejectedService
    FailedService
    } derive(Eq,
    Debug
    )

    Result state used by application transactions.

    Session

    pub struct Session {
    state : LinkState
    send_sequence : Int
    receive_sequence : Int
    window_size : Int
    pending : Int
    } derive(
    Debug
    )

    A deterministic session state machine. Transport I/O is intentionally injected by callers.

    Session::new

    fn Session::new(window_size? : Int) -> Session

    Session::receive

    fn Session::receive(self : Session, frame : Frame) -> Result[Unit, String]

    Session::send

    fn Session::send(self : Session, payload : Bytes) -> Result[Frame, String]

    Session::snapshot

    fn Session::snapshot(self : Session) -> SessionSnapshot

    Session::start

    fn Session::start(self : Session) -> Frame

    Session::stop

    fn Session::stop(self : Session) -> Frame

    fn Session::test_link(self : Session) -> Frame

    SessionAction

    pub enum SessionAction {
    SendStart
    SendStop
    SendTest
    SendSupervisory(Int)
    SendInformation(Int)
    DeliverInformation(Bytes)
    Acknowledge(Int)
    Report(Diagnostic)
    NoAction
    } derive(
    Debug
    )

    A deterministic action emitted by a session driver.

    SessionSnapshot

    pub struct SessionSnapshot {
    state : LinkState
    send_sequence : Int
    receive_sequence : Int
    pending : Int
    window_size : Int
    } derive(Eq,
    Debug
    )

    Host-visible session observation.

    SessionSnapshot::available

    fn SessionSnapshot::available(self : SessionSnapshot) -> Int

    SessionSnapshot::is_started

    fn SessionSnapshot::is_started(self : SessionSnapshot) -> Bool

    SessionSnapshot::pending

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

    SessionSnapshot::receive_sequence

    fn SessionSnapshot::receive_sequence(self : SessionSnapshot) -> Int

    SessionSnapshot::send_sequence

    fn SessionSnapshot::send_sequence(self : SessionSnapshot) -> Int

    ShortFloatValue

    pub struct ShortFloatValue {
    value : Float
    quality : QualityDescriptor
    } derive(Eq,
    Debug
    )

    IEEE-754 short floating point measurement.

    ShortFloatValue::new

    fn ShortFloatValue::new(value : Float, quality? : QualityDescriptor) -> ShortFloatValue

    ShortFloatValue::quality

    ShortFloatValue::value

    fn ShortFloatValue::value(self : ShortFloatValue) -> Float

    Simulation

    pub struct Simulation {
    clock : VirtualClock
    actions : Array[ScheduledAction]
    events : Array[SimulationEvent]
    next_ordinal : Int
    max_events : Int
    } derive(
    Debug
    )

    Simulation::clear_events

    fn Simulation::clear_events(self : Simulation) -> Unit

    Simulation::events

    Simulation::new

    fn Simulation::new(start? : Int, max_events? : Int) -> Result[Simulation, String]

    Simulation::now

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

    Simulation::pending

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

    Simulation::run_until

    fn Simulation::run_until(self : Simulation, timestamp : Int) -> Result[Int, String]

    Run all scheduled actions up to an inclusive timestamp.

    Simulation::schedule

    fn Simulation::schedule(self : Simulation, at : Int, action : SimulationAction) -> Result[Unit, String]

    Simulation::step

    fn Simulation::step(self : Simulation) -> Result[Bool, String]

    Run the next scheduled action, if any.

    SimulationAction

    pub enum SimulationAction {
    Receive(Frame)
    Publish(ApplicationObject)
    AdvanceTimer(String)
    Record(String)
    } derive(
    Debug
    )

    Work scheduled for a deterministic simulation tick.

    SimulationEvent

    pub enum SimulationEvent {
    FrameProduced(Int, Frame)
    ObjectPublished(Int, ApplicationObject)
    TimerAdvanced(Int, String)
    Note(Int, String)
    SimulationFault(Int, Diagnostic)
    } derive(
    Debug
    )

    Results emitted by one simulation step.

    SinglePointValue

    pub struct SinglePointValue {
    state : Bool
    quality : StatusQuality
    } derive(Eq,
    Debug
    )

    Single point information value, including its QDS.

    SinglePointValue::from_byte

    fn SinglePointValue::from_byte(value : Int) -> Result[SinglePointValue, String]

    SinglePointValue::new

    fn SinglePointValue::new(state : Bool, quality? : StatusQuality) -> SinglePointValue

    SinglePointValue::quality

    SinglePointValue::state

    fn SinglePointValue::state(self : SinglePointValue) -> Bool

    SinglePointValue::to_byte

    fn SinglePointValue::to_byte(self : SinglePointValue) -> Int

    StationProfile

    pub struct StationProfile {
    name : String
    common_address : CommonAddress
    parameters : ConnectionParameters
    supported_types : Array[ApplicationType]
    max_objects : Int
    tls_required : Bool
    } derive(
    Debug
    )

    A station profile exchanged by deployment configuration and test tools.

    StationProfile::common_address

    fn StationProfile::common_address(self : StationProfile) -> CommonAddress

    StationProfile::max_objects

    fn StationProfile::max_objects(self : StationProfile) -> Int

    StationProfile::name

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

    StationProfile::new

    fn StationProfile::new(name : String, common_address : CommonAddress, parameters : ConnectionParameters, supported_types : Array[ApplicationType], max_objects? : Int, tls_required? : Bool) -> Result[StationProfile, String]

    StationProfile::parameters

    StationProfile::supported_types

    fn StationProfile::supported_types(self : StationProfile) -> Array[ApplicationType]

    StationProfile::supports

    fn StationProfile::supports(self : StationProfile, type_id : ApplicationType) -> Bool

    StationProfile::tls_required

    fn StationProfile::tls_required(self : StationProfile) -> Bool

    StationSimulation

    pub struct StationSimulation {
    store : PointStore
    session : Session
    simulation : Simulation
    metrics : FrameMetrics
    trace : TraceLog
    } derive(
    Debug
    )

    A deterministic station simulation composed from a point store and session.

    StationSimulation::events

    StationSimulation::ingest

    fn StationSimulation::ingest(self : StationSimulation, object : ApplicationObject, timestamp : Int) -> Result[PointChange, Diagnostic]

    StationSimulation::metrics

    StationSimulation::new

    fn StationSimulation::new(common_address : CommonAddress, window_size? : Int) -> Result[StationSimulation, String]

    StationSimulation::receive

    fn StationSimulation::receive(self : StationSimulation, frame : Frame) -> Result[Unit, String]

    StationSimulation::run_until

    fn StationSimulation::run_until(self : StationSimulation, timestamp : Int) -> Result[Int, String]

    StationSimulation::schedule

    fn StationSimulation::schedule(self : StationSimulation, at : Int, action : SimulationAction) -> Result[Unit, String]

    StationSimulation::send

    fn StationSimulation::send(self : StationSimulation, payload : Bytes) -> Result[Frame, String]

    StationSimulation::session

    StationSimulation::start

    StationSimulation::stop

    StationSimulation::store

    StationSimulation::trace

    StatusQuality

    pub struct StatusQuality {
    blocked : Bool
    substituted : Bool
    not_topical : Bool
    invalid : Bool
    } derive(Eq,
    Debug
    )

    Quality descriptor for single and double point status values.

    StatusQuality::as_measurement

    fn StatusQuality::as_measurement(self : StatusQuality) -> QualityDescriptor

    StatusQuality::clear

    StatusQuality::from_byte

    fn StatusQuality::from_byte(value : Int) -> Result[StatusQuality, String]

    StatusQuality::is_usable

    fn StatusQuality::is_usable(self : StatusQuality) -> Bool

    StatusQuality::to_byte

    fn StatusQuality::to_byte(self : StatusQuality) -> Int

    StepPositionValue

    pub struct StepPositionValue {
    position : Int
    transient : Bool
    quality : StatusQuality
    } derive(Eq,
    Debug
    )

    Step position value with a signed seven-bit position and transient flag.

    StepPositionValue::new

    fn StepPositionValue::new(position : Int, transient? : Bool, quality? : StatusQuality) -> Result[StepPositionValue, String]

    StepPositionValue::position

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

    StepPositionValue::quality

    StepPositionValue::to_array

    fn StepPositionValue::to_array(self : StepPositionValue) -> Array[Byte]

    StoreStatistics

    pub struct StoreStatistics {
    total : Int
    monitoring : Int
    control : Int
    valid : Int
    invalid : Int
    revisions : Int
    changes : Int
    } derive(Eq,
    Debug
    )

    Aggregate counts for an in-memory point store.

    StoreStatistics::changes

    fn StoreStatistics::changes(self : StoreStatistics) -> Int

    StoreStatistics::control

    fn StoreStatistics::control(self : StoreStatistics) -> Int

    StoreStatistics::empty

    StoreStatistics::invalid

    fn StoreStatistics::invalid(self : StoreStatistics) -> Int

    StoreStatistics::monitoring

    fn StoreStatistics::monitoring(self : StoreStatistics) -> Int

    StoreStatistics::revisions

    fn StoreStatistics::revisions(self : StoreStatistics) -> Int

    StoreStatistics::total

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

    StoreStatistics::valid

    fn StoreStatistics::valid(self : StoreStatistics) -> Int

    StoreTransaction

    pub struct StoreTransaction {
    pending : Array[(ApplicationObject, Int, String)]
    removed : Array[(InformationAddress, Int)]
    committed : Bool
    } derive(
    Debug
    )

    A transaction that stages changes before committing them to a store.

    StoreTransaction::commit

    fn StoreTransaction::commit(self : StoreTransaction, store : PointStore) -> Result[Array[PointChange], Diagnostic]

    StoreTransaction::new

    StoreTransaction::pending_count

    fn StoreTransaction::pending_count(self : StoreTransaction) -> Int

    StoreTransaction::rollback

    fn StoreTransaction::rollback(self : StoreTransaction) -> Unit

    StoreTransaction::stage

    fn StoreTransaction::stage(self : StoreTransaction, object : ApplicationObject, timestamp : Int, source? : String) -> Result[Unit, Diagnostic]

    StoreTransaction::stage_remove

    fn StoreTransaction::stage_remove(self : StoreTransaction, address : InformationAddress, timestamp : Int) -> Result[Unit, Diagnostic]

    TimeTag

    pub enum TimeTag {
    Short(Cp24Time)
    Long(Cp56Time)
    } derive(Eq,
    Debug
    )

    A tagged union used by event stores and application services.

    TimeTag::kind

    fn TimeTag::kind(self : TimeTag) -> TimeTagKind

    TimeTag::to_array

    fn TimeTag::to_array(self : TimeTag) -> Array[Byte]

    TimeTag::width

    fn TimeTag::width(self : TimeTag) -> Int

    TimeTagKind

    pub enum TimeTagKind {
    NoTimeTag
    Cp24TimeTag
    Cp56TimeTag
    } derive(Eq,
    Debug
    )

    Tag precision carried by a time-tagged application object.

    TimeTagKind::width

    fn TimeTagKind::width(self : TimeTagKind) -> Int

    TimerState

    pub enum TimerState {
    Inactive
    Running(Int)
    Expired
    } derive(Eq,
    Debug
    )

    State of a timer that is driven by a host monotonic clock.

    TraceEvent

    pub struct TraceEvent {
    timestamp : Int
    kind : TraceKind
    detail : String
    correlation : Int
    } derive(Eq,
    Debug
    )

    TraceEvent::correlation

    fn TraceEvent::correlation(self : TraceEvent) -> Int

    TraceEvent::detail

    fn TraceEvent::detail(self : TraceEvent) -> String

    TraceEvent::kind

    fn TraceEvent::kind(self : TraceEvent) -> TraceKind

    TraceEvent::new

    fn TraceEvent::new(timestamp : Int, kind : TraceKind, detail : String, correlation? : Int) -> TraceEvent

    TraceEvent::timestamp

    fn TraceEvent::timestamp(self : TraceEvent) -> Int

    TraceKind

    pub enum TraceKind {
    FrameSent
    FrameReceived
    StateChanged
    PointUpdated
    ServiceStarted
    ServiceCompleted
    DiagnosticRaised
    } derive(Eq,
    Debug
    )

    A trace event with a monotonic timestamp.

    TraceLog

    pub struct TraceLog {
    events : Array[TraceEvent]
    limit : Int
    } derive(
    Debug
    )

    TraceLog::all

    fn TraceLog::all(self : TraceLog) -> Array[TraceEvent]

    TraceLog::len

    fn TraceLog::len(self : TraceLog) -> Int

    TraceLog::new

    fn TraceLog::new(limit? : Int) -> Result[TraceLog, String]

    TraceLog::push

    fn TraceLog::push(self : TraceLog, event : TraceEvent) -> Unit

    TraceLog::since

    fn TraceLog::since(self : TraceLog, timestamp : Int) -> Array[TraceEvent]

    TransportMode

    pub enum TransportMode {
    Tcp
    SerialGateway
    ReplayFile
    InMemory
    } derive(Eq,
    Debug
    )

    TypeDescriptor

    pub struct TypeDescriptor {
    type_id : ApplicationType
    name : String
    direction : PointDirection
    time_tag : TimeTagKind
    value_width : Int
    supported : Bool
    command : Bool
    } derive(Eq,
    Debug
    )

    Machine-readable description of an IEC 104 application type.

    TypeDescriptor::direction

    TypeDescriptor::is_command

    fn TypeDescriptor::is_command(self : TypeDescriptor) -> Bool

    TypeDescriptor::name

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

    TypeDescriptor::supported

    fn TypeDescriptor::supported(self : TypeDescriptor) -> Bool

    TypeDescriptor::time_tag

    fn TypeDescriptor::time_tag(self : TypeDescriptor) -> TimeTagKind

    TypeDescriptor::type_id

    TypeDescriptor::value_width

    fn TypeDescriptor::value_width(self : TypeDescriptor) -> Int

    TypeId

    pub enum TypeId {
    SinglePoint
    DoublePoint
    NormalizedValue
    ShortFloat
    BitString32
    Unknown(Int)
    } derive(Eq,
    Debug
    )

    Application type identifiers used by this library.

    TypeId::is_known

    fn TypeId::is_known(self : TypeId) -> Bool

    TypeId::name

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

    TypeId::number

    fn TypeId::number(self : TypeId) -> Int

    UCommand

    pub enum UCommand {
    StartDataTransfer
    StopDataTransfer
    TestFrame
    Unknown(UInt16)
    } derive(Eq,
    Debug
    )

    IEC 104 U-frame commands.

    UCommand::control

    fn UCommand::control(self : UCommand) -> UInt16

    VirtualClock

    pub struct VirtualClock {
    now : Int
    } derive(Eq,
    Debug
    )

    A deterministic monotonic clock for protocol simulations and tests.

    VirtualClock::advance

    fn VirtualClock::advance(self : VirtualClock, delta : Int) -> Result[Int, String]

    VirtualClock::new

    fn VirtualClock::new(start? : Int) -> Result[VirtualClock, String]

    VirtualClock::now

    fn VirtualClock::now(self : VirtualClock) -> Int

    VirtualClock::set

    fn VirtualClock::set(self : VirtualClock, timestamp : Int) -> Result[Unit, String]

    admit_envelope

    fn admit_envelope(envelope : AsduEnvelope, limits : ResourceLimits) -> AdmissionDecision

    admit_frame

    fn admit_frame(frame : Frame, limits : ResourceLimits) -> AdmissionDecision

    admit_inbound

    fn admit_inbound(data : Bytes, limits : ResourceLimits, replay : ReplayGuard, now : Int) -> Result[Frame, Diagnostic]

    Admission pipeline for an inbound APDU.

    append_u24

    fn append_u24(out : Array[Byte], value : Int) -> Result[Unit, String]

    application_service_examples

    fn application_service_examples() -> Array[ServiceStatus]

    application_type

    fn application_type(value : Int) -> ApplicationType

    Decode all currently assigned standard IEC 104 type identifiers.

    application_type_catalog

    fn application_type_catalog() -> Array[TypeDescriptor]

    Return the standard catalog used to negotiate object capabilities.

    application_value_examples

    fn application_value_examples() -> Array[ApplicationValue]

    application_value_is_command

    fn application_value_is_command(value : ApplicationValue) -> Bool

    application_value_is_measurement

    fn application_value_is_measurement(value : ApplicationValue) -> Bool

    application_value_type

    fn application_value_type(value : ApplicationValue) -> ApplicationType

    application_value_width

    fn application_value_width(value : ApplicationValue) -> Int

    assess_metrics

    fn assess_metrics(metrics : MetricsSnapshot) -> HealthReport

    assess_session

    fn assess_session(snapshot : SessionSnapshot) -> HealthReport

    assess_store

    fn assess_store(store : PointStore) -> HealthReport

    benchmark_fixture_checksums

    fn benchmark_fixture_checksums() -> Array[UInt]

    benchmark_result_table

    fn benchmark_result_table(results : Array[BenchmarkResult]) -> String

    binary_counter_object

    fn binary_counter_object(address : InformationAddress, value : UInt, sequence? : Int, time_tag? : TimeTag) -> Result[ApplicationObject, String]

    bit_is_set

    fn bit_is_set(value : Int, bit : Int) -> Bool

    bit_string_object

    fn bit_string_object(address : InformationAddress, value : UInt, time_tag? : TimeTag) -> Result[ApplicationObject, String]

    byte_statistics

    fn byte_statistics(data : Bytes) -> ByteStatistics

    bytes_equal_left

    fn bytes_equal_left(a : Bytes, b : Bytes) -> Bool

    calendar_weekday

    fn calendar_weekday(year : Int, month : Int, day : Int) -> Result[Int, String]

    Calculate ISO-like weekday for a Gregorian date: Monday is 1, Sunday is 7.

    cause

    fn cause(value : Int) -> Cause

    cause_category

    fn cause_category(value : Int) -> CauseCategory

    Decode a standard cause category without rejecting extension values.

    clock_sync_object

    fn clock_sync_object(address : InformationAddress, value : Cp56Time) -> Result[ApplicationObject, String]

    compatibility_examples

    fn compatibility_examples() -> Array[String]

    conformance_examples

    fn conformance_examples() -> Array[TypeDescriptor]

    control_type_catalog

    fn control_type_catalog() -> Array[TypeDescriptor]

    counter_interrogation_object

    fn counter_interrogation_object(address : InformationAddress, qualifier : Int) -> Result[ApplicationObject, String]

    crc16_ibm

    fn crc16_ibm(data : Bytes) -> UInt

    CRC-16/IBM helper for gateways that wrap IEC APDUs in a framed channel.

    crc32_ieee

    fn crc32_ieee(data : Bytes) -> UInt

    CRC-32 used by fixture manifests and deterministic transport tests.

    create_interrogation_plan

    fn create_interrogation_plan(store : PointStore, request : InterrogationRequest, filter : PointFilter, batch_size? : Int) -> Result[InterrogationPlan, String]

    Build plans from a point store while retaining type and address boundaries.

    days_in_month

    fn days_in_month(year : Int, month : Int) -> Int?

    Return the number of days in a Gregorian month.

    days_in_year

    fn days_in_year(year : Int) -> Int

    Return the number of days in a year.

    decode_asdu

    fn decode_asdu(data : Bytes) -> Result[(AsduHeader, Array[InformationObject]), String]

    Decode an ASDU header and its information objects.

    decode_extended_asdu

    fn decode_extended_asdu(data : Bytes) -> Result[AsduEnvelope, Diagnostic]

    Decode a complete address-qualified ASDU.

    decode_frame

    fn decode_frame(data : Bytes) -> Result[Frame, String]

    Decode one complete APDU. Extra bytes after the declared APDU are rejected.

    decode_signed16

    fn decode_signed16(low : Int, high : Int) -> Result[Int, String]

    Return the signed value represented by a two-byte little-endian field.

    decode_time_tag

    fn decode_time_tag(kind : TimeTagKind, data : Bytes, offset? : Int) -> Result[TimeTag, String]

    Decode the selected tag precision from a byte sequence.

    default_benchmark_suite

    fn default_benchmark_suite() -> BenchmarkSuite

    Produce the standard local suite used by README benchmark commands.

    diagnostic_kind_examples

    fn diagnostic_kind_examples() -> Array[DiagnosticKind]

    Keep all diagnostic categories available to host-side telemetry adapters.

    diagnostic_kind_name

    fn diagnostic_kind_name(kind : DiagnosticKind) -> String

    diagnostics_examples

    fn diagnostics_examples() -> Array[DiagnosticKind]

    double_command_object

    fn double_command_object(address : InformationAddress, state : Int, qualifier : Int) -> Result[ApplicationObject, String]

    double_point_object

    fn double_point_object(address : InformationAddress, state : Int, quality? : StatusQuality, time_tag? : TimeTag) -> Result[ApplicationObject, String]

    encode_application_object

    fn encode_application_object(object : ApplicationObject) -> Bytes

    Encode an IOA-qualified object without the ASDU header.

    encode_asdu

    fn encode_asdu(header : AsduHeader, objects : Array[InformationObject]) -> Bytes

    Encode an ASDU header followed by information objects.

    encode_extended_asdu

    fn encode_extended_asdu(envelope : AsduEnvelope) -> Result[Bytes, Diagnostic]

    Encode an address-qualified ASDU into its IEC 104 application payload.

    encode_frame

    fn encode_frame(frame : Frame) -> Bytes

    Encode one APCI frame, including the 0x68 start byte and length byte.

    encode_signed16

    fn encode_signed16(value : Int) -> Result[Array[Byte], String]

    Encode a signed value into a little-endian two-byte field.

    encode_time_tag

    fn encode_time_tag(tag : TimeTag) -> Bytes

    encoded_frame_size

    fn encoded_frame_size(frame : Frame) -> Int

    Return the number of octets that an encoded frame will occupy.

    end_of_initialization_object

    fn end_of_initialization_object(address : InformationAddress, value : Int) -> Result[ApplicationObject, String]

    evaluate_command

    fn evaluate_command(policy : CommandPolicy, object : ApplicationObject) -> CommandOutcome

    extended_asdu_examples

    fn extended_asdu_examples() -> Array[AsduEnvelope]

    frame_fits_apdu

    fn frame_fits_apdu(frame : Frame, maximum : Int) -> Bool

    Return a conservative APDU limit check for gateways.

    frame_kind_name

    fn frame_kind_name(kind : FrameKind) -> String

    health_state_examples

    fn health_state_examples() -> Array[HealthState]

    health_state_name

    fn health_state_name(state : HealthState) -> String

    hex_decode

    fn hex_decode(text : String) -> Result[Bytes, String]

    hex_digit

    fn hex_digit(value : Int) -> Char

    Convert a hexadecimal nibble to a display character.

    hex_encode

    fn hex_encode(data : Bytes) -> String

    hex_value

    fn hex_value(value : Char) -> Int?

    implementation_version

    fn implementation_version() -> String

    information_frame

    fn information_frame(send_sequence : Int, receive_sequence : Int, payload : Bytes) -> Frame

    Create an I frame from a sequence pair and an ASDU payload.

    interrogation_object

    fn interrogation_object(address : InformationAddress, qualifier : Int) -> Result[ApplicationObject, String]

    is_leap_year

    fn is_leap_year(year : Int) -> Bool

    Whether a year is a Gregorian leap year.

    mask_bits

    fn mask_bits(value : Int, mask : Int) -> Int

    measurement_state

    fn measurement_state(quality : QualityDescriptor) -> MeasurementState

    measurement_state_examples

    fn measurement_state_examples() -> Array[MeasurementState]

    milliseconds_since_midnight

    fn milliseconds_since_midnight(hour : Int, minute : Int, second : Int, millisecond : Int) -> Result[Int, String]

    Sum milliseconds since midnight, used by deterministic simulations.

    monitoring_type_catalog

    fn monitoring_type_catalog() -> Array[TypeDescriptor]

    negotiate_profiles

    fn negotiate_profiles(local_profile : StationProfile, remote : StationProfile) -> NegotiationDecision

    normalize_quality

    fn normalize_quality(value : Int) -> Int

    Clamp a quality byte to the protocol's low eight bits.

    normalized_object

    fn normalized_object(address : InformationAddress, value : Int, quality? : QualityDescriptor, time_tag? : TimeTag) -> Result[ApplicationObject, String]

    normalized_set_point_object

    fn normalized_set_point_object(address : InformationAddress, value : Int, qualifier : Int) -> Result[ApplicationObject, String]

    normalized_value_asdu

    fn normalized_value_asdu(cause : Int, common_address : Int, value : Int, quality : Int) -> Bytes

    Build a normalized telemetry value.

    observe_frame_length

    fn observe_frame_length(histogram : LengthHistogram, frame : Frame) -> Unit

    Record an APDU length observation.

    ordinal_day

    fn ordinal_day(year : Int, month : Int, day : Int) -> Result[Int, String]

    Convert a month/day pair to a one-based ordinal day.

    pad_bytes

    fn pad_bytes(data : Bytes, length : Int, fill : Byte) -> Result[Bytes, String]

    parse_apdu_prefix

    fn parse_apdu_prefix(data : Bytes) -> ApduParseResult

    Parse one APDU from a byte view without requiring a socket implementation.

    parse_vsq

    fn parse_vsq(value : Int) -> Result[(Int, Bool), String]

    Validate a VSQ byte and return its count/sequence pair.

    point_change_kind_examples

    fn point_change_kind_examples() -> Array[PointChangeKind]

    point_direction

    fn point_direction(type_id : ApplicationType) -> PointDirection

    point_store_examples

    fn point_store_examples() -> Array[PointDirection]

    profile_examples

    fn profile_examples() -> Array[StationProfile]

    protocol_event_examples

    fn protocol_event_examples() -> Array[ProtocolEvent]

    Standard event constructors for host integrations.

    protocol_name

    fn protocol_name() -> String

    quality_for_state

    fn quality_for_state(state : MeasurementState) -> QualityDescriptor

    Build a quality descriptor from a measurement state.

    read_object

    fn read_object(address : InformationAddress) -> Result[ApplicationObject, String]

    read_u24

    fn read_u24(data : Bytes, offset : Int) -> Result[Int, String]

    regulating_step_command_object

    fn regulating_step_command_object(address : InformationAddress, step : Int, qualifier : Int) -> Result[ApplicationObject, String]

    reset_command_object

    fn reset_command_object(address : InformationAddress, value : Int) -> Result[ApplicationObject, String]

    run_benchmark_workload

    fn run_benchmark_workload(rounds : Int, payload_size : Int) -> Result[BenchmarkWorkload, String]

    safe_apdu_payload

    fn safe_apdu_payload(data : Bytes) -> Result[Bytes, Diagnostic]

    scaled_object

    fn scaled_object(address : InformationAddress, value : Int, quality? : QualityDescriptor, time_tag? : TimeTag) -> Result[ApplicationObject, String]

    scaled_set_point_object

    fn scaled_set_point_object(address : InformationAddress, value : Int, qualifier : Int) -> Result[ApplicationObject, String]

    security_examples

    fn security_examples() -> Array[AdmissionDecision]

    sequence_acknowledges

    fn sequence_acknowledges(send_cursor : Int, acknowledgement : Int) -> Bool

    Whether a sequence acknowledgement is valid for a send cursor.

    sequence_before

    fn sequence_before(start : Int, candidate : Int, limit : Int) -> Bool

    Whether candidate is strictly before limit from start.

    sequence_distance

    fn sequence_distance(start : Int, end : Int) -> Int

    Distance from start to end on the 15-bit sequence ring.

    sequence_next

    fn sequence_next(value : Int) -> Int

    Return the next sequence number on the IEC ring.

    sequence_normalize

    fn sequence_normalize(value : Int) -> Int

    Sequence numbers are modulo 32768 in IEC 104.

    sequence_previous

    fn sequence_previous(value : Int) -> Int

    Return the previous sequence number on the IEC ring.

    service_kind_examples

    fn service_kind_examples() -> Array[ServiceKind]

    service_status_examples

    fn service_status_examples() -> Array[ServiceStatus]

    service_status_name

    fn service_status_name(status : ServiceStatus) -> String

    session_action_examples

    fn session_action_examples() -> Array[SessionAction]

    set_bit

    fn set_bit(value : Int, bit : Int, enabled : Bool) -> Int

    short_float_object

    fn short_float_object(address : InformationAddress, value : Float, quality? : QualityDescriptor, time_tag? : TimeTag) -> Result[ApplicationObject, String]

    short_float_set_point_object

    fn short_float_set_point_object(address : InformationAddress, value : Float, qualifier : Int) -> Result[ApplicationObject, String]

    simulation_action_examples

    fn simulation_action_examples() -> Array[SimulationAction]

    simulation_event_examples

    fn simulation_event_examples() -> Array[SimulationEvent]

    single_command_object

    fn single_command_object(address : InformationAddress, state : Bool, qualifier : Int) -> Result[ApplicationObject, String]

    single_object_asdu

    fn single_object_asdu(object : ApplicationObject, cause : CauseOfTransmission, common_address : CommonAddress) -> Result[AsduEnvelope, Diagnostic]

    Build an ASDU containing one object.

    single_point_asdu

    fn single_point_asdu(cause : Int, common_address : Int, ioa : Int, status : Bool, quality : Int) -> Bytes

    Build a single-point status ASDU.

    single_point_object

    fn single_point_object(address : InformationAddress, state : Bool, quality? : StatusQuality, time_tag? : TimeTag) -> Result[ApplicationObject, String]

    split_apdus

    fn split_apdus(data : Bytes) -> Result[(Array[Frame], Bytes), Diagnostic]

    Split a byte stream into complete APDUs and retain incomplete tails.

    split_milliseconds_since_midnight

    fn split_milliseconds_since_midnight(value : Int) -> Result[(Int, Int, Int, Int), String]

    Split milliseconds since midnight into hour, minute, second and remainder.

    step_position_object

    fn step_position_object(address : InformationAddress, position : Int, transient? : Bool, quality? : StatusQuality, time_tag? : TimeTag) -> Result[ApplicationObject, String]

    supervisory_frame

    fn supervisory_frame(receive_sequence : Int) -> Frame

    Create an S frame acknowledging received I frames.

    supported_type_catalog

    fn supported_type_catalog() -> Array[TypeDescriptor]

    test_command_object

    fn test_command_object(address : InformationAddress, value : Int) -> Result[ApplicationObject, String]

    time_tag_examples

    fn time_tag_examples() -> Array[TimeTag]

    time_tag_kind_for_type

    fn time_tag_kind_for_type(type_id : ApplicationType) -> TimeTagKind

    timer_state_examples

    fn timer_state_examples() -> Array[TimerState]

    trace_kind_examples

    fn trace_kind_examples() -> Array[TraceKind]

    transport_examples

    fn transport_examples() -> Array[ApduParseResult]

    transport_mode_examples

    fn transport_mode_examples() -> Array[TransportMode]

    transport_mode_name

    fn transport_mode_name(mode : TransportMode) -> String

    trim_trailing_bytes

    fn trim_trailing_bytes(data : Bytes, value : Byte) -> Bytes

    type_descriptor

    fn type_descriptor(type_id : ApplicationType) -> TypeDescriptor

    type_id

    fn type_id(value : Int) -> TypeId

    type_id_examples

    fn type_id_examples() -> Array[TypeId]

    type_is_supported

    fn type_is_supported(type_id : ApplicationType) -> Bool

    type_name

    fn type_name(type_id : ApplicationType) -> String

    type_wire_width

    fn type_wire_width(type_id : ApplicationType) -> Int

    u_command

    fn u_command(control : UInt16) -> UCommand

    unnumbered_frame

    fn unnumbered_frame(control : UInt16) -> Frame

    Create a U frame. The low six control bits are retained by the encoder.

    validate_common_address

    fn validate_common_address(value : Int) -> Result[CommonAddress, Diagnostic]

    validate_envelope

    fn validate_envelope(envelope : AsduEnvelope) -> ConformanceReport

    validate_frame

    fn validate_frame(frame : Frame) -> Result[Unit, String]

    Validate invariants that are independent of a concrete transport.

    validate_information_address

    fn validate_information_address(value : Int) -> Result[InformationAddress, Diagnostic]

    validate_transport_frame

    fn validate_transport_frame(frame : Frame) -> Result[Unit, Diagnostic]

    Validate a frame against transport-level limits before sending it.

    wire_tool_examples

    fn wire_tool_examples() -> Array[Bytes]

    xor_checksum

    fn xor_checksum(data : Bytes) -> Byte