Repository navigation
v0.3.0
Date: 2026-10-28
Summary
Two more interop stacks and GOOSE. mms-interop-dscsystems runs
dscsystems/go-iec61850 (pure Go, GPL-3.0) and mms-interop-iec61850-rust
runs csp0924/iec61850-rust (Rust, MIT OR Apache-2.0) behind the same
commands and JSON Lines as the libiec61850 adapter. libiec61850,
dscsystems and iec61850-rust all gain a GOOSE publisher and subscriber
with one shared contract, fixture and Docker L2 recipe.
Changes
Added
- Image
ghcr.io/otfabric/mms-interop-dscsystems(adapters/dscsystems/, GPL-3.0 withLICENSEandNOTICEin that directory), pinned to dscsystems/go-iec61850 commit6bf3f37(v0.6.5-1-g6bf3f37):dscsystems-mms-server,-mms-client,-ied-server,-ied-client,-ied-controller,-ied-reporter,-goose-publisher,-goose-subscriber. Flags, fixture defaults, ready events and output lines mirror the libiec61850 commands, so a harness switches stack by image and command prefix. - Image
ghcr.io/otfabric/mms-interop-iec61850-rust(adapters/iec61850-rust/, with upstream'sLICENSE-MIT,LICENSE-APACHEand aNOTICE), pinned to csp0924/iec61850-rust commitd4e8952(v0.2.0) and built with Rust 1.95.0: the same eight commands under theiec61850-rust-prefix. Upstream has no generic MMS server, so the adapter runs the association with upstream's ISO layers and encodes the remaining services itself. No command is unsupported; one that were would answer{"event":"error","code":"unsupported",...}and exit 4. libiec61850-goose-publisherandlibiec61850-goose-subscriber(raw GoosePublisher / GooseReceiver API).- GOOSE contract (
docs/goose.md): the publisher announces--valuesas stNum 1, retransmits MinTime → doubling → MaxTime, takes{"cmd":"set"}/{"cmd":"stop"}on stdin and emitspublishedper frame; the subscriber emits onegooseevent per frame (gocbRef, datSet, goID, appID, dst, src, stNum, sqNum, timeAllowedToLive, confRev, test, simulation, ndsCom, numDatSetEntries, t, values) andsupervisiontimeout/ok per gocbRef.testis goosePdu field [7],simulationthe Edition 2 S bit of Reserved1. - Fixture revision
goose-v1(fixtures/goose/):interop-goose.cid(interop.icd plus datasetsdsGooseAll— boolean, integer, unsigned, float32, quality, utc-time, Dbpos, nested MV structure — anddsGooseBool,GSEControlgcbAll/gcbBooland theirGSEaddresses) andgoose.json(on-wire references, members, initial and update values).scripts/validate-fixtures.pychecks both against each other and againstinterop.icd; the fixture workflow runs genmodel on the CID. scripts/goose-crosscheck.sh: publisher → subscriber check between two images on a Docker bridge, optionally from the host side of the bridge. CI runs it between every pair of libiec61850, dscsystems and iec61850-rust (all nine directions), with and without the flags, and from the host side.docker compose --profile goose(bridgegoose0),make build-dscsystems,make build-iec61850-rust,make goose-crosscheck.fixtures/capabilities.json: the new commands,gooseFixtureRevision, the dscsystems upstream, and seven dscsystems known limitations (alternate access ranges in the server; alternate access, NVL writes, association-scope NVLs and FileOpen lastModified in the client; Enum type description and ST writes in the IED server), the iec61850-rust upstream, and five iec61850-rust known limitations (RptEna without Resv and ST writes in the IED server, abort in the MMS client, ObtainFile role reversal and domain/VMD NVL deletion in the MMS server).
Changed
- CI runs on pull requests, builds and smoke-tests all four images (including MMS and IED pairs of dscsystems and iec61850-rust against libiec61850) and vets the Go adapter; the release workflow builds and publishes the dscsystems and iec61850-rust images for linux/amd64 and linux/arm64 and records their digests and upstream commits in
manifest.json. - The libiec61850 image ships
fixtures/goose/; its GOOSE binaries carrycap_net_raw+ep, so they run as the non-root adapter user in a container withNET_RAW.
Notes
- The dscsystems MMS server sends both InformationReport forms of the fixture, listOfVariable first; the libiec61850 server sends only the named-list form. It seeks FileOpen
initialPosition, which libiec61850 does not. - The dscsystems IED server returns directory names in model order, libiec61850 sorted.
- The iec61850-rust MMS server keeps its file store in memory (
--filestoreis accepted and ignored), lists directories sorted by path, seeks FileOpeninitialPositionand, like dscsystems, sends both InformationReport forms. - A Go test on macOS cannot reach the GOOSE adapters natively: run it in a container on the bridge network (
docs/goose.md).
Adapter images
| Image | Digest |
|---|---|
ghcr.io/otfabric/mms-interop-libiec61850:v0.3.0 |
sha256:18e7e5c249f74e708a0699bd64732cd238ad9579574431a16b27b9c6000232a0 |
ghcr.io/otfabric/mms-interop-iec61850bean:v0.3.0 |
sha256:8d76b3cc065c2b18cc031bb26b2b879a7b433e164f9664ce9a3363241db65514 |
ghcr.io/otfabric/mms-interop-dscsystems:v0.3.0 (GPL-3.0) |
sha256:f0b233737c1bd6e9cc6cfe7338bb287ed0e5b4a6b589b7496ae2409501dc6deb |
ghcr.io/otfabric/mms-interop-iec61850-rust:v0.3.0 |
sha256:ebd09921ef9b22ed9a318256eb2fac74268dde7f18a17f9e8300aba46c624110 |
Pinning in consumer repositories
LIBIEC61850_IMAGE=ghcr.io/otfabric/mms-interop-libiec61850@sha256:18e7e5c249f74e708a0699bd64732cd238ad9579574431a16b27b9c6000232a0
IEC61850BEAN_IMAGE=ghcr.io/otfabric/mms-interop-iec61850bean@sha256:8d76b3cc065c2b18cc031bb26b2b879a7b433e164f9664ce9a3363241db65514
DSCSYSTEMS_IMAGE=ghcr.io/otfabric/mms-interop-dscsystems@sha256:f0b233737c1bd6e9cc6cfe7338bb287ed0e5b4a6b589b7496ae2409501dc6deb
IEC61850RUST_IMAGE=ghcr.io/otfabric/mms-interop-iec61850-rust@sha256:ebd09921ef9b22ed9a318256eb2fac74268dde7f18a17f9e8300aba46c624110See manifest.json for full provenance (libiec61850 commit SHA, iec61850bean version, dscsystems/go-iec61850 and iec61850-rust commit SHAs, fixture revisions).