diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d3250c0..7028891 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,17 +23,26 @@ jobs: with: dotnet-version: 8.0.x - - name: Restore app + - name: Restore Publisher run: dotnet restore src/ARSVIN/ARSVIN.csproj + - name: Restore Subscriber + run: dotnet restore src/ARSVIN.Subscriber/ARSVIN.Subscriber.csproj + - name: Restore tests run: dotnet restore tests/ARSVIN.Tests/ARSVIN.Tests.csproj - - name: Build app + - name: Build Publisher run: dotnet build src/ARSVIN/ARSVIN.csproj -c Release --no-restore + - name: Build Subscriber + run: dotnet build src/ARSVIN.Subscriber/ARSVIN.Subscriber.csproj -c Release --no-restore + - name: Test run: dotnet test tests/ARSVIN.Tests/ARSVIN.Tests.csproj -c Release --no-restore --logger trx - - name: Dependency vulnerability report + - name: Publisher dependency vulnerability report run: dotnet list src/ARSVIN/ARSVIN.csproj package --vulnerable --include-transitive + + - name: Subscriber dependency vulnerability report + run: dotnet list src/ARSVIN.Subscriber/ARSVIN.Subscriber.csproj package --vulnerable --include-transitive diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 21b8cc8..79558ff 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,18 +1,32 @@ -name: Release Portable Windows EXE +name: Build Windows Release on: push: tags: - 'v*.*.*' workflow_dispatch: + inputs: + version: + description: 'Version used for manual artifact builds (for example 0.3.0)' + required: false + default: '0.0.0-dev' permissions: contents: write +concurrency: + group: release-${{ github.ref }} + cancel-in-progress: false + +env: + DOTNET_CLI_TELEMETRY_OPTOUT: '1' + DOTNET_NOLOGO: '1' + jobs: - publish: - name: Publish win-x64 portable package + release: + name: Portable EXEs and installer runs-on: windows-latest + steps: - name: Checkout uses: actions/checkout@v4 @@ -21,24 +35,111 @@ jobs: uses: actions/setup-dotnet@v4 with: dotnet-version: 8.0.x + cache: true + cache-dependency-path: | + **/*.csproj + Directory.Packages.props + + - name: Resolve version + id: version + shell: pwsh + run: | + if ('${{ github.ref_type }}' -eq 'tag') { + $version = '${{ github.ref_name }}' -replace '^[vV]', '' + } + else { + $version = '${{ inputs.version }}' + if ([string]::IsNullOrWhiteSpace($version)) { + $version = '0.0.0-dev' + } + $version = $version -replace '^[vV]', '' + } + + if ($version -notmatch '^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$') { + throw "Unsupported release version: $version" + } + + "value=$version" >> $env:GITHUB_OUTPUT + Write-Host "Release version: $version" - name: Build and test shell: pwsh run: .\build.ps1 - - name: Publish portable ZIP + - name: Publish single-file portable applications shell: pwsh - run: .\publish-win-x64.ps1 + run: .\scripts\publish-release.ps1 -Version '${{ steps.version.outputs.value }}' -SkipTests + + - name: Install Inno Setup + shell: pwsh + run: choco install innosetup --no-progress -y + + - name: Build Windows installer + shell: pwsh + run: | + $iscc = @( + "${env:ProgramFiles(x86)}\Inno Setup 6\ISCC.exe", + "${env:ProgramFiles}\Inno Setup 6\ISCC.exe" + ) | Where-Object { Test-Path $_ } | Select-Object -First 1 + + if (-not $iscc) { + throw 'Inno Setup compiler (ISCC.exe) was not found.' + } + + $sourceDir = (Resolve-Path '.\artifacts\installer-input').Path + $outputDir = (Resolve-Path '.\artifacts\release').Path + $version = '${{ steps.version.outputs.value }}' + + & $iscc ` + "/DMyAppVersion=$version" ` + "/DSourceDir=$sourceDir" ` + "/DOutputDir=$outputDir" ` + '.\installer\ARSVIN.iss' + + if ($LASTEXITCODE -ne 0) { + throw "Inno Setup failed with exit code $LASTEXITCODE." + } + + - name: Generate SHA-256 checksums + shell: pwsh + run: | + $releaseRoot = Resolve-Path '.\artifacts\release' + $lines = Get-ChildItem $releaseRoot -File | + Where-Object { $_.Name -ne 'SHA256SUMS.txt' } | + Sort-Object Name | + ForEach-Object { + $hash = (Get-FileHash $_.FullName -Algorithm SHA256).Hash.ToLowerInvariant() + "$hash $($_.Name)" + } + + [System.IO.File]::WriteAllLines( + (Join-Path $releaseRoot 'SHA256SUMS.txt'), + $lines, + [System.Text.UTF8Encoding]::new($false) + ) + + Get-Content (Join-Path $releaseRoot 'SHA256SUMS.txt') - - name: Upload workflow artifact + - name: Upload release workflow artifact uses: actions/upload-artifact@v4 with: - name: ARSVIN-win-x64-portable - path: artifacts/ARSVIN-win-x64-portable.zip + name: ARSVIN-${{ steps.version.outputs.value }}-windows-x64 + path: | + artifacts/release/*.exe + artifacts/release/*.zip + artifacts/release/SHA256SUMS.txt + if-no-files-found: error + retention-days: 30 - name: Create GitHub Release - if: startsWith(github.ref, 'refs/tags/') + if: github.ref_type == 'tag' uses: softprops/action-gh-release@v3 with: - files: artifacts/ARSVIN-win-x64-portable.zip generate_release_notes: true + fail_on_unmatched_files: true + files: | + artifacts/release/ARSVIN-Publisher-win-x64.exe + artifacts/release/ArSubsv-Subscriber-win-x64.exe + artifacts/release/ARSVIN-Suite-Setup-win-x64.exe + artifacts/release/ARSVIN-win-x64-portable.zip + artifacts/release/SHA256SUMS.txt diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9b60785..2e5ad2b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,13 +2,13 @@ Thank you for considering a contribution to ARSVIN. -ARSVIN is an engineering tool for IEC 61850 Sampled Values lab publishing. The project values clear code, cautious live-network behavior, reproducible test notes, and documentation that an engineer can use in the field. +ARSVIN is an engineering suite for IEC 61850 Sampled Values laboratory workflows. The project values clear code, cautious live-network behavior, reproducible test notes, and documentation that an engineer can use in the field. ## Project principles -- Keep the product focused on SV publishing and relay readability checks. -- Do not turn ARSVIN into a general protocol analyzer unless the feature directly improves publishing safety or setup correctness. -- Keep live packet injection guarded, visible, and clearly labelled. +- Keep Publisher and Subscriber responsibilities explicit and independently testable. +- Add analysis features only when they improve Sampled Values visibility, interoperability, troubleshooting, or evidence quality. +- Keep live packet capture and injection guarded, visible, and clearly labelled. - Preserve Apache-2.0 compatibility. - Prefer explicit engineering wording over marketing claims. - Update documentation when behavior, UI, safety assumptions, or release packaging changes. @@ -20,7 +20,7 @@ Recommended environment: - Windows 10/11 x64 - .NET 8 SDK - PowerShell 7+ -- Npcap for live packet publishing tests +- Npcap for live packet capture/publishing tests - Wireshark for packet inspection Build: @@ -35,10 +35,10 @@ Run tests: dotnet test tests/ARSVIN.Tests/ARSVIN.Tests.csproj -c Release ``` -Create a portable package: +Create portable release artifacts: ```powershell -.\publish-win-x64.ps1 +.\scripts\publish-release.ps1 -Version 0.1.0 ``` ## Pull request checklist @@ -46,7 +46,7 @@ Create a portable package: Before opening a PR, please check: - The change has a narrow engineering purpose. -- The app builds in Release mode. +- Both affected applications build in Release mode. - Relevant unit tests were added or updated where practical. - Safety behavior is not weakened. - Docs are updated for user-visible changes. @@ -68,12 +68,13 @@ Document smpSynch compatibility mode Use GitHub Issues and include: - ARSVIN version or commit +- Application: Publisher or ArSubsv Subscriber - Windows version - Npcap version -- SCL/COMTRADE sample if shareable +- SCL/COMTRADE/PCAP sample if shareable - Steps to reproduce - Expected behavior - Actual behavior - Screenshots or Wireshark capture notes when relevant -Do not upload confidential station SCL files, relay IP plans, or production network captures. +Do not upload confidential station SCL files, relay IP plans, credentials, or production network captures. diff --git a/NOTICE b/NOTICE index 93f6c74..1c4c2b6 100644 --- a/NOTICE +++ b/NOTICE @@ -1,9 +1,12 @@ -ARSVIN - IEC 61850 Sampled Values Publisher & Process Bus Traffic Tester +ARSVIN - IEC 61850 Sampled Values Engineering Suite Copyright 2026 Ari Sulistiono Licensed under the Apache License, Version 2.0. Author: Ari Sulistiono GitHub: https://github.com/masarray +Project: https://github.com/masarray/arsvin -ARSVIN can transmit raw Ethernet frames and is intended only for isolated lab networks, point-to-point engineering tests, and educational use. +ARSVIN includes a Sampled Values Publisher and the ArSubsv Subscriber companion. The software can capture and transmit raw Ethernet frames and is intended only for isolated laboratory networks, authorized point-to-point engineering tests, development, troubleshooting support, and education. + +ARSVIN is not a certified IEC 61850 conformance tool, calibrated merging unit, protection test set, deterministic real-time platform, or production process-bus monitoring system. diff --git a/README.md b/README.md index ba086ee..4212361 100644 --- a/README.md +++ b/README.md @@ -1,132 +1,127 @@ -# ARSVIN — IEC 61850 Sampled Values Publisher for Windows +# ARSVIN — Open-Source IEC 61850 Sampled Values Workbench for Windows [![CI](https://github.com/masarray/arsvin/actions/workflows/ci.yml/badge.svg)](https://github.com/masarray/arsvin/actions/workflows/ci.yml) [![Release](https://github.com/masarray/arsvin/actions/workflows/release.yml/badge.svg)](https://github.com/masarray/arsvin/actions/workflows/release.yml) [![CodeQL](https://github.com/masarray/arsvin/actions/workflows/codeql.yml/badge.svg)](https://github.com/masarray/arsvin/actions/workflows/codeql.yml) [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE) -[![Platform](https://img.shields.io/badge/platform-Windows-0078D4.svg)](#requirements) +[![Platform](https://img.shields.io/badge/platform-Windows%2010%2F11-0078D4.svg)](#system-requirements) [![.NET](https://img.shields.io/badge/.NET-8.0-512BD4.svg)](#build-from-source) -**ARSVIN** is an Apache-2.0 IEC 61850 **Sampled Values Publisher** for Windows. It helps substation automation engineers publish SV streams from SCL settings, replay COMTRADE records, run repeatable publisher scenarios, and export TX-side evidence for controlled lab work. +**ARSVIN** is a focused, Apache-2.0 engineering suite for IEC 61850 Sampled Values on Windows. It combines an SCL-driven **SV Publisher** with **ArSubsv**, a live/PCAP **SV Subscriber and analysis companion** for transparent, repeatable laboratory workflows.

- ARSVIN IEC 61850 Sampled Values Publisher preview showing SCL setup, nofASDU, TX timing health, PCAP evidence, and scenario presets + ARSVIN Publisher SV Setup interface with SCL stream selection, network parameters, source modes, and manual output controls

- Download latest release · - Landing page · + Download · + Product site · Quick start · - Documentation + Documentation · + Contribute

-> [!WARNING] -> ARSVIN transmits raw Ethernet frames. Use it only on isolated lab networks, point-to-point test links, or networks where you have explicit authorization. ARSVIN is **not** a certified relay test set, calibrated current/voltage source, calibrated merging unit, production process-bus tool, or certified IEC 61850-9-3 PTP grandmaster. +> [!CAUTION] +> ARSVIN can capture and transmit raw Ethernet traffic. Use it only on isolated laboratory networks, point-to-point test links, or networks where you have explicit authorization. It is not a certified relay test set, calibrated merging unit, protection trip-time platform, production process-bus monitor, or IEC 61850 conformance tool. -## Why ARSVIN exists +## Real application views -IEC 61850 Sampled Values testing often needs transparent tooling: a way to inspect stream settings, publish repeatable SV frames, replay simple analog records, and preserve evidence without hiding the implementation behind a black box. ARSVIN focuses on that workflow. +| ArSubsv stream monitor | ArSubsv live analysis | +|---|---| +| ArSubsv stream monitor with voltage and current waveforms, phasor view, RMS values, and discovered Sampled Values streams | ArSubsv live analysis workspace with channel table, phasor display, voltage waveform, and current waveform | -ARSVIN is intentionally narrow: +The screenshots above are captured from the actual Windows applications. They show the Publisher setup workflow and the Subscriber waveform, phasor, channel, RMS, and stream-analysis views. -```text -SCL-driven SV publishing → TX timing visibility → generated PCAP/report evidence -``` +## Two focused applications + +| Application | Purpose | Typical workflow | +|---|---|---| +| **ARSVIN Publisher** | Generate IEC 61850 Sampled Values from SCL settings, manual values, scenarios, or COMTRADE records. | Configure → preflight → dry run/live TX → export PCAP and report. | +| **ArSubsv Subscriber** | Discover, receive, decode, visualize, and assess SV streams from a live Npcap adapter or PCAP file. | Capture/import → bind to SCL → inspect values, waveform, phasor, RMS, and stream health → export report. | -It does **not** try to replace StationScout, Wireshark, IEDScout, Omicron-class test sets, RTDS/HIL platforms, or certified conformance tools. +The tools are intentionally separated. Publisher evidence proves what the PC generated; Subscriber evidence proves what the selected PC/NIC received and decoded. Neither alone proves that a protection IED consumed the multicast stream. ## Key capabilities -| Capability | What it does | -|---|---| -| IEC 61850 SV publisher | Publishes Ethernet Sampled Values frames from a Windows workstation using Npcap. | -| SCL-driven setup | Reads APPID, destination MAC, VLAN, `svID`, dataset, `confRev`, `smpRate`, `smpMod`, and `nofASDU` from SCL/SCD. | -| Multi-ASDU packing | Supports `nofASDU=1/2/4/8` for lab-oriented SV frame packing. | -| Multi-stream publishing | Runs up to three independent publisher slots for repeatable lab streams. | -| COMTRADE replay | Replays ASCII, BINARY, BINARY32, and FLOAT32 analog COMTRADE records as SV values. | -| Publisher scenarios | Generates balanced and per-phase state sequencer presets: 3P fault, A-G fault, B-C fault, negative/zero sequence, CT saturation stress, VT fuse fail, harmonic injection, DC offset, frequency steps, phase jump, and load reversal. | -| TX Timing Health | Reports target FPS, actual FPS, jitter, late frames, missed schedule count, send duration, and overall TX health. | -| PCAP evidence export | Exports generated SV frames to PCAP for offline inspection in Wireshark or other packet tools. | -| Markdown evidence report | Exports TX-side publisher evidence with stream settings, preflight findings, timing health, and scenario metadata. | -| Safety-first UX | Preflight warnings and explicit boundaries keep live publishing decisions visible. | - -## Supported publishing profiles - -| Area | Current support | Notes | -|---|---|---| -| IEC 61850 Sampled Values APDU | Lab publisher implementation | Focused on generated SV streams, not certified conformance. | -| IEC 61850-9-2LE style 4I+4V | Supported as lab profile | Includes sample SCL and common 4 current + 4 voltage payload shape. | -| `nofASDU` | `1`, `2`, `4`, `8` | Sample counter advances per ASDU. | -| Quality bits | Good, invalid, questionable, oldData, test, operatorBlocked | Used for intentional relay behavior tests. | -| PTP / `smpSynch` | Compatibility/lab behavior only | Not a certified IEC 61850-9-3 timing implementation. | -| IEC 61869-9 generic datasets | Partial/future | See [SV profile support](docs/sv-profile-support.md). | +### Publisher -## Common workflows +- SCL/SCD stream setup for APPID, destination MAC, VLAN, `svID`, dataset, `confRev`, `smpRate`, `smpMod`, and `nofASDU`. +- Lab-oriented IEC 61850-9-2LE-style 4I+4V publishing. +- Multi-ASDU frame packing with `nofASDU=1/2/4/8`. +- Up to three independent publisher slots. +- Manual values, ramps, state sequences, per-phase scenarios, waveform shaping, and COMTRADE replay. +- Intentional quality-bit modes for controlled behavior checks. +- TX timing health: target/actual FPS, jitter, late frames, missed schedules, and send duration. +- Generated PCAP and Markdown evidence reports. -### Publish from SCL +### Subscriber / ArSubsv -1. Open an SCL/SCD file. -2. Select Publisher 1, 2, or 3. -3. Choose an SV stream. -4. Review APPID, MAC, VLAN, `svID`, dataset, `smpRate`, `smpMod`, and `nofASDU`. -5. Run dry mode first. -6. Publish live only on an isolated lab link. +- Live SV capture through Npcap and offline classic-PCAP import. +- Stream discovery and SCL-assisted binding. +- APPID, VLAN, `svID`, `confRev`, `nofASDU`, sample-rate, and payload-layout checks. +- `smpCnt` continuity and stream-health diagnostics. +- Decoded instantaneous values, oscilloscope waveform, phasor, and RMS views. +- Receiver-side Markdown evidence reports. -### Replay COMTRADE as SV +## Release downloads -1. Load a COMTRADE `.cfg` and matching `.dat`. -2. Map analog channels to current/voltage fields. -3. Select the SV stream profile. -4. Publish or export generated evidence. +Every tagged release builds reproducible Windows x64 artifacts: -### Preserve TX-side evidence +| Artifact | Use | +|---|---| +| `ARSVIN-Publisher-win-x64.exe` | Self-contained, single-file portable Publisher. | +| `ArSubsv-Subscriber-win-x64.exe` | Self-contained, single-file portable Subscriber. | +| `ARSVIN-Suite-Setup-win-x64.exe` | Installer containing both applications, Start Menu shortcuts, documentation, and uninstaller. | +| `ARSVIN-win-x64-portable.zip` | Portable suite folder containing both applications and essential documentation. | +| `SHA256SUMS.txt` | SHA-256 checksums for release verification. | -1. Run preflight. -2. Start a dry run or live publisher session. -3. Check TX Timing Health. -4. Export generated PCAP. -5. Export Markdown evidence report. +The binaries are currently **unsigned**. Windows SmartScreen may show an unknown-publisher warning. Releases do not silently install Npcap; download Npcap from its official website when live capture or transmission is required. -## Companion app: ARSVIN Subscriber +## Quick start -This repository now includes **ARSVIN Subscriber**, a separate WPF receiver-side verification companion for ARSVIN Publisher. It listens to IEC 61850 Sampled Values on an Npcap adapter, binds received streams to SCL when available, verifies APPID/VLAN/svID/confRev/nofASDU/sample-rate/payload layout, tracks `smpCnt` health, decodes values, and exports a receiver-side evidence report. +### Installer -Build it with: +1. Download `ARSVIN-Suite-Setup-win-x64.exe` from the latest release. +2. Install the suite. +3. Install Npcap separately for live Ethernet capture/transmission. +4. Open **ARSVIN Publisher** or **ArSubsv Subscriber** from the Start Menu. +5. Start with a dry run, sample file, PCAP import, or isolated point-to-point link. -```powershell -dotnet build .\src\ARSVIN.Subscriber\ARSVIN.Subscriber.csproj -c Release -``` - -The subscriber proves that **this PC/NIC** receives and decodes the stream. It does not prove that a relay or IED consumed the multicast SV stream. See [`docs/subscriber-verification-app.md`](docs/subscriber-verification-app.md). +### Portable -## Quick start +1. Download the Publisher or Subscriber portable `.exe`. +2. Run the selected application directly. +3. Run as Administrator only when the selected Npcap/live-network workflow requires it. -### Download portable release +See [Quick Start](docs/quick-start.md) and [Build and Release](docs/build-and-release.md). -1. Install [Npcap](https://npcap.com/) on Windows. -2. Download `ARSVIN-win-x64-portable.zip` from [Releases](https://github.com/masarray/arsvin/releases). -3. Extract the ZIP. -4. Run `ARSVIN.exe` as Administrator when live publishing raw Ethernet frames. -5. Open a sample SCL from `samples/scl` or your lab SCD. -6. Start with dry mode before live TX. +## Supported scope -See [Quick Start](docs/quick-start.md) for the full flow. +| Area | Current status | Boundary | +|---|---|---| +| IEC 61850 Sampled Values APDU | Publisher and subscriber implementation for engineering/lab use | Not certified conformance testing. | +| IEC 61850-9-2LE-style 4I+4V | Supported lab profile | Validate formal requirements independently. | +| `nofASDU` | `1`, `2`, `4`, `8` | Publisher and receiver behavior is software/PC timing dependent. | +| COMTRADE | ASCII, BINARY, BINARY32, FLOAT32 analog replay | Verify scaling and channel mapping before live TX. | +| PTP / `smpSynch` | Compatibility and lab behavior | Not an IEC 61850-9-3 certified clock. | +| Windows timing | Best-effort scheduling with visible health metrics | Not deterministic real-time execution. | +| IED subscription proof | Not provided | SV multicast has no application-layer acknowledgement. | -## Requirements +## System requirements For users: -- Windows 10/11 x64 -- Npcap for live Ethernet publishing -- Administrator rights for live packet transmission -- Wireshark or equivalent tool for independent packet inspection +- Windows 10 or Windows 11, x64. +- Npcap for live capture or transmission. +- Administrator permission when required by the local Npcap/network configuration. +- Wireshark or another independent packet tool is recommended for verification. For developers: -- Windows 10/11 x64 -- .NET 8 SDK -- PowerShell 7+ recommended -- Visual Studio 2022, Rider, or VS Code with C# tooling +- .NET 8 SDK. +- PowerShell 7+ recommended. +- Visual Studio 2022, JetBrains Rider, or VS Code with C# tooling. +- Inno Setup 6 only when building the installer locally. ## Build from source @@ -136,107 +131,63 @@ cd arsvin .\build.ps1 ``` -Create a portable Windows package: +Build all release artifacts except the installer: ```powershell -.\publish-win-x64.ps1 +.\scripts\publish-release.ps1 -Version 0.1.0 ``` -Run tests: +Compatibility wrapper: ```powershell -dotnet test tests/ARSVIN.Tests/ARSVIN.Tests.csproj -c Release +.\publish-win-x64.ps1 -Version 0.1.0 ``` -## Repository structure +Run tests directly: -```text -src/ARSVIN/ WPF desktop application and IEC 61850 publisher engine -tests/ARSVIN.Tests/ Unit tests for protocol primitives and publisher helpers -docs/ Engineering documentation, safety notes, and public launch docs -samples/ SCL, COMTRADE, scenario, and evidence samples -site/ Static GitHub Pages landing page -.github/workflows/ CI, CodeQL, Pages, and release automation +```powershell +dotnet test .\tests\ARSVIN.Tests\ARSVIN.Tests.csproj -c Release ``` -## Documentation - -Start with [Documentation Index](docs/index.md), or jump directly to: - -- [Quick Start](docs/quick-start.md) -- [SV Profile Support](docs/sv-profile-support.md) -- [P0 Publisher Protocol Roadmap](docs/p0-publisher-protocol-roadmap.md) -- [P1 Publisher Evidence Workflow](docs/p1-publisher-evidence-workflow.md) -- [P2 Full Publisher Scenario Engine](docs/p2-full-publisher-scenarios.md) -- [Waveform Shape Panel](docs/waveform-shape-panel.md) -- [Multi-Stream SV Publishing](docs/multi-stream.md) -- [COMTRADE Replay](docs/comtrade-replay.md) -- [TX Safety Boundaries](docs/safety-boundaries.md) -- [PTP and smpSynch Compatibility](docs/ptp-and-smpsynch.md) -- [Build and Release](docs/build-and-release.md) -- [SEO and Public Launch Checklist](docs/seo-public-launch-checklist.md) - -## What ARSVIN is not - -ARSVIN is not: - -- a live SV subscriber/analyzer, -- a certified IEC 61850 conformance test tool, -- a calibrated merging unit, -- a protection trip-time validation platform, -- a production process-bus diagnostic suite, -- a replacement for relay vendor tools, StationScout, Wireshark, or Omicron-class test sets. - -SV is multicast and unacknowledged. A publisher cannot know which IEDs are live subscribers unless that information is derived from complete SCL/SCD engineering data or from external tooling. - -## SEO topics for GitHub - -Set these in the GitHub repository **About → Topics** panel: +## Repository structure ```text -iec61850 -iec-61850 -sampled-values -sampled-values-publisher -sv-publisher -sv-injector -merging-unit -merging-unit-simulator -process-bus -digital-substation -substation-automation -comtrade -ptp -wpf -dotnet -windows +src/ARSVIN/ Publisher application and SV generation engine +src/ARSVIN.Subscriber/ ArSubsv subscriber and visualization companion +tests/ARSVIN.Tests/ Protocol and publisher helper tests +installer/ Inno Setup definition for the Windows suite +scripts/ Repeatable release packaging scripts +docs/ Engineering, safety, and contributor documentation +samples/ SCL, COMTRADE, scenario, and evidence samples +site/ Static, SEO-ready GitHub Pages product site +.github/workflows/ CI, CodeQL, Pages, and release automation ``` -Suggested GitHub About description: - -```text -Apache-2.0 IEC 61850 Sampled Values Publisher for Windows — SCL-driven SV publishing, COMTRADE replay, nofASDU support, TX timing health, per-phase scenario presets, and PCAP evidence export. -``` +## Documentation -## Contributing +- [Documentation index](docs/index.md) +- [Quick start](docs/quick-start.md) +- [Subscriber verification app](docs/subscriber-verification-app.md) +- [ArSubsv SV scout companion](docs/arsubsv-sv-scout-companion.md) +- [SV profile support](docs/sv-profile-support.md) +- [COMTRADE replay](docs/comtrade-replay.md) +- [Multi-stream publishing](docs/multi-stream.md) +- [Publisher evidence workflow](docs/p1-publisher-evidence-workflow.md) +- [Full publisher scenarios](docs/p2-full-publisher-scenarios.md) +- [Safety boundaries](docs/safety-boundaries.md) +- [PTP and `smpSynch` compatibility](docs/ptp-and-smpsynch.md) +- [Build and release](docs/build-and-release.md) -Practical engineering contributions are welcome. Please read [CONTRIBUTING.md](CONTRIBUTING.md), keep pull requests focused, include test notes, and keep safety wording honest. +## Security and responsible use -## Author +Do not attach confidential station SCL/SCD files, relay credentials, production packet captures, or internal network plans to public issues. Report vulnerabilities through GitHub Security Advisories as described in [SECURITY.md](SECURITY.md). -Created and maintained by **Ari Sulistiono**. +## Contributing -GitHub: [github.com/masarray](https://github.com/masarray) +Focused engineering contributions are welcome. Read [CONTRIBUTING.md](CONTRIBUTING.md), keep changes reviewable, include test evidence where practical, and preserve explicit safety boundaries. ## License -Apache License 2.0. See [LICENSE](LICENSE). - -Third-party dependency notes are listed in [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md). - - -## ArSubsv — Sampled Values Scout Companion - -The repository now includes **ArSubsv**, a separate WPF receiver-side SV scout app. It provides live stream discovery, SCL-bound decoding, oscilloscope waveform visualization, phasor/RMS indicators, classic PCAP import, stream health checks, and Markdown evidence reports. It is not an OMICRON product and does not copy OMICRON branding; it targets the same engineering class of Sampled Values visualization while keeping the ARSVIN visual identity. +Copyright © 2026 Ari Sulistiono. -See [`docs/arsubsv-sv-scout-companion.md`](docs/arsubsv-sv-scout-companion.md). +Licensed under the [Apache License 2.0](LICENSE). Third-party dependency notices are documented in [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md). diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md index a2a67ac..3a61b09 100644 --- a/THIRD_PARTY_NOTICES.md +++ b/THIRD_PARTY_NOTICES.md @@ -1,11 +1,11 @@ # Third-Party Notices -This file summarizes third-party components that ARSVIN depends on directly or expects users to install for live packet publishing. +This file summarizes third-party components that ARSVIN depends on directly or expects users to install for live packet capture and transmission. ## SharpPcap - Package: `SharpPcap` -- Purpose: Packet capture and injection API used for live Ethernet publishing support +- Purpose: Packet capture and injection API used by ARSVIN Publisher and ArSubsv Subscriber - License: MIT - Project: https://github.com/dotpcap/sharppcap - Package: https://www.nuget.org/packages/SharpPcap @@ -14,11 +14,11 @@ SharpPcap is consumed as a NuGet package and is not authored by the ARSVIN maint ## Npcap -- Purpose: Windows packet capture/transmission driver required for live packet publishing +- Purpose: Windows packet capture/transmission driver required for live Ethernet workflows - Project: https://npcap.com/ -Npcap is not bundled in this repository. Users install it separately and are responsible for following its license and usage terms. +Npcap is not bundled in this repository or silently installed by the ARSVIN installer. Users install it separately and are responsible for following its license and usage terms. ## .NET and WPF -ARSVIN is built with .NET and WPF. See Microsoft documentation and license terms for the installed SDK/runtime components. +ARSVIN is built with .NET and WPF. Self-contained release binaries include applicable .NET runtime components. See Microsoft documentation and license terms for those components. diff --git a/build.ps1 b/build.ps1 index a9ce19d..9a020ba 100644 --- a/build.ps1 +++ b/build.ps1 @@ -1,24 +1,35 @@ $ErrorActionPreference = 'Stop' +Set-StrictMode -Version Latest $root = $PSScriptRoot $appProject = Join-Path $root 'src\ARSVIN\ARSVIN.csproj' $subscriberProject = Join-Path $root 'src\ARSVIN.Subscriber\ARSVIN.Subscriber.csproj' $testProject = Join-Path $root 'tests\ARSVIN.Tests\ARSVIN.Tests.csproj' -Write-Host '==> Restoring ARSVIN Publisher' -dotnet restore $appProject +function Invoke-DotNet { + param( + [Parameter(Mandatory)] + [string[]] $Arguments + ) -Write-Host '==> Restoring ARSVIN Subscriber' -dotnet restore $subscriberProject + & dotnet @Arguments + if ($LASTEXITCODE -ne 0) { + throw "dotnet $($Arguments -join ' ') failed with exit code $LASTEXITCODE." + } +} -Write-Host '==> Restoring ARSVIN tests' -dotnet restore $testProject +Write-Host '==> Restoring solution projects' +Invoke-DotNet -Arguments @('restore', $appProject) +Invoke-DotNet -Arguments @('restore', $subscriberProject) +Invoke-DotNet -Arguments @('restore', $testProject) Write-Host '==> Building ARSVIN Publisher' -dotnet build $appProject -c Release --no-restore +Invoke-DotNet -Arguments @('build', $appProject, '-c', 'Release', '--no-restore') -Write-Host '==> Building ARSVIN Subscriber' -dotnet build $subscriberProject -c Release --no-restore +Write-Host '==> Building ArSubsv Subscriber' +Invoke-DotNet -Arguments @('build', $subscriberProject, '-c', 'Release', '--no-restore') Write-Host '==> Running tests' -dotnet test $testProject -c Release --no-restore +Invoke-DotNet -Arguments @('test', $testProject, '-c', 'Release', '--no-restore') + +Write-Host '==> Build completed successfully' diff --git a/docs/build-and-release.md b/docs/build-and-release.md index eb90e53..8a51d6e 100644 --- a/docs/build-and-release.md +++ b/docs/build-and-release.md @@ -1,66 +1,163 @@ # Build and Release -## Build +ARSVIN uses a tag-driven GitHub Actions workflow to build two self-contained portable applications, one suite installer, one portable ZIP, and SHA-256 checksums. -Requirements: +## Prerequisites + +For local source builds: - Windows 10/11 x64 - .NET 8 SDK - PowerShell 7+ recommended +For local installer builds: + +- All requirements above +- Inno Setup 6 + +Npcap is required only for live capture/transmission testing. It is not silently bundled or installed by the ARSVIN release process. + +## Build and test + ```powershell .\build.ps1 ``` -The build script restores the WPF application and test project, builds Release configuration, and runs the unit tests. +The script restores, builds, and tests: + +- `src/ARSVIN/ARSVIN.csproj` +- `src/ARSVIN.Subscriber/ARSVIN.Subscriber.csproj` +- `tests/ARSVIN.Tests/ARSVIN.Tests.csproj` + +External command exit codes are checked, so CI and local builds stop immediately when a `dotnet` command fails. + +## Build portable release artifacts + +```powershell +.\scripts\publish-release.ps1 -Version 0.3.0 +``` -## Test +Compatibility wrapper: ```powershell -dotnet test tests/ARSVIN.Tests/ARSVIN.Tests.csproj -c Release +.\publish-win-x64.ps1 -Version 0.3.0 +``` + +Generated files: + +```text +artifacts/release/ +├── ARSVIN-Publisher-win-x64.exe +├── ArSubsv-Subscriber-win-x64.exe +└── ARSVIN-win-x64-portable.zip +``` + +Staging files for the installer are generated under: + +```text +artifacts/installer-input/ ``` -The current test project focuses on stable protocol primitives. More SCL, COMTRADE, SV, and PTP tests should be added as public APIs stabilize. +The two direct `.exe` files are self-contained .NET 8 single-file applications. The ZIP includes both applications, essential documentation, license notices, and sample files. + +## Build the installer locally -## Publish portable Windows package +After running the publish script: ```powershell -.\publish-win-x64.ps1 +$version = '0.3.0' +$sourceDir = (Resolve-Path '.\artifacts\installer-input').Path +$outputDir = (Resolve-Path '.\artifacts\release').Path +$iscc = "${env:ProgramFiles(x86)}\Inno Setup 6\ISCC.exe" + +& $iscc ` + "/DMyAppVersion=$version" ` + "/DSourceDir=$sourceDir" ` + "/DOutputDir=$outputDir" ` + '.\installer\ARSVIN.iss' ``` Output: ```text -artifacts/ARSVIN-win-x64-portable.zip +artifacts/release/ARSVIN-Suite-Setup-win-x64.exe ``` -The ZIP should include: +The installer: + +- installs per-user under `%LOCALAPPDATA%\Programs\ARSVIN`, +- includes Publisher and Subscriber, +- creates Start Menu shortcuts, +- offers an optional Publisher desktop shortcut, +- includes an uninstaller, +- preserves Apache-2.0 and third-party notices, +- warns when Npcap is not detected. -- `ARSVIN.exe` -- README -- LICENSE -- NOTICE -- THIRD_PARTY_NOTICES -- documentation files needed for safe use +## GitHub Actions release flow -## GitHub release +Workflow: `.github/workflows/release.yml` + +### Tagged release Create and push a semantic version tag: ```powershell -git tag v0.1.0 -git push origin v0.1.0 +git tag v0.3.0 +git push origin v0.3.0 +``` + +The workflow then: + +1. restores, builds, and tests the solution, +2. publishes both self-contained single-file applications, +3. creates the portable suite ZIP, +4. installs Inno Setup on the Windows runner, +5. compiles the suite installer, +6. generates `SHA256SUMS.txt`, +7. uploads the files as a workflow artifact, +8. creates a GitHub Release and attaches all public artifacts. + +### Manual artifact build + +Run **Build Windows Release** from the Actions tab and provide a version such as `0.3.0-dev.1`. + +Manual runs upload workflow artifacts but do not create a GitHub Release because no tag is present. + +## Release assets + +| File | Description | +|---|---| +| `ARSVIN-Publisher-win-x64.exe` | Portable Publisher. | +| `ArSubsv-Subscriber-win-x64.exe` | Portable Subscriber/analysis companion. | +| `ARSVIN-Suite-Setup-win-x64.exe` | Installer for both applications. | +| `ARSVIN-win-x64-portable.zip` | Portable suite package. | +| `SHA256SUMS.txt` | Integrity hashes for all release assets. | + +## Verify a download + +```powershell +Get-FileHash .\ARSVIN-Suite-Setup-win-x64.exe -Algorithm SHA256 ``` -The release workflow builds a self-contained win-x64 package and attaches it to the GitHub Release. +Compare the result with `SHA256SUMS.txt` from the same GitHub Release. + +## Code signing status + +Release binaries are currently unsigned. Windows SmartScreen may display an unknown-publisher warning. The workflow intentionally does not contain placeholder signing steps or require paid signing secrets. + +When a trusted code-signing certificate becomes available, sign the portable executables before compiling the installer, then sign the completed installer before checksum generation. -## Manual release checklist +## Release checklist -Before publishing: +Before tagging a public release: -- Run the build script on Windows. -- Test dry run mode. +- Confirm `main` CI and CodeQL are green. +- Test Publisher dry run. - Test live publishing only on an isolated lab link. -- Verify packet behavior in Wireshark. +- Test Subscriber live capture and PCAP import. +- Verify generated SV traffic independently in Wireshark. +- Verify portable executables on a clean Windows 10/11 x64 machine. +- Verify install, upgrade, shortcuts, launch, and uninstall behavior. - Review [Known Limitations](known-limitations.md). +- Review [Safety Boundaries](safety-boundaries.md). - Review [Public Release Checklist](public-release-checklist.md). diff --git a/docs/github-repository-settings.md b/docs/github-repository-settings.md index 483b3be..1a0f923 100644 --- a/docs/github-repository-settings.md +++ b/docs/github-repository-settings.md @@ -1,13 +1,17 @@ # GitHub Repository Settings -These settings cannot be applied from the source tree, but they should be configured manually after pushing the repository. +These settings are stored in GitHub rather than the source tree. Apply them manually after the pull request is merged. + +## Repository visibility + +Set the repository to **Public**. The repository is already public as of July 11, 2026. ## About panel Description: ```text -Apache-2.0 IEC 61850 Sampled Values Publisher for Windows — SCL-driven SV publishing, COMTRADE replay, nofASDU support, TX timing health, scenario presets, and PCAP evidence export. +Apache-2.0 IEC 61850 Sampled Values workbench for Windows — SCL-driven SV publishing, COMTRADE replay, live/PCAP subscriber analysis, waveform, phasor, RMS, timing health, and evidence export. ``` Website: @@ -16,6 +20,13 @@ Website: https://masarray.github.io/arsvin/ ``` +Enable: + +- Releases +- Packages only when a package feed is introduced +- Issues +- Discussions only when there is enough maintainer capacity + Topics: ```text @@ -23,20 +34,23 @@ iec61850 iec-61850 sampled-values sampled-values-publisher +sampled-values-subscriber sv-publisher +sv-subscriber sv-injector -merging-unit -merging-unit-simulator process-bus digital-substation substation-automation comtrade -ptp +pcap +phasor wpf dotnet windows ``` +Avoid topics that imply certification, calibration, deterministic real-time performance, or affiliation with another vendor. + ## Social preview Upload: @@ -48,13 +62,13 @@ site/assets/arsvin-social-preview.png Recommended preview message: ```text -ARSVIN — IEC 61850 Sampled Values Publisher -SCL • COMTRADE • nofASDU • TX Timing • PCAP Evidence +ARSVIN — IEC 61850 Sampled Values Workbench +Publisher • Subscriber • SCL • COMTRADE • PCAP • Engineering Evidence ``` ## Pages -Use the existing workflow: +Use **GitHub Actions** as the Pages source. The existing workflow is: ```text .github/workflows/pages.yml @@ -66,19 +80,40 @@ Expected public URL: https://masarray.github.io/arsvin/ ``` +After deployment, verify: + +- canonical URL, +- responsive layout, +- Open Graph preview, +- direct latest-release links, +- `robots.txt`, +- `sitemap.xml`. + ## Releases -Use release assets for portable downloads. Recommended asset naming: +The release workflow publishes stable asset names: ```text +ARSVIN-Publisher-win-x64.exe +ArSubsv-Subscriber-win-x64.exe +ARSVIN-Suite-Setup-win-x64.exe ARSVIN-win-x64-portable.zip +SHA256SUMS.txt ``` Release notes should include: -- capability summary, -- installation steps, -- Npcap/admin requirement, +- Publisher and Subscriber capability summary, +- installer and portable usage, +- Npcap requirement for live workflows, +- unsigned-binary/SmartScreen note, - safety warning, - known limitations, - link to documentation. + +## Recommended merge settings + +- Enable squash merge. +- Automatically delete head branches after merge. +- Require the CI and CodeQL checks before merging into `main` when branch protection is enabled. +- Require pull requests for changes to `main` when the project begins accepting external contributors. diff --git a/docs/index.md b/docs/index.md index b46ac3f..50d7af7 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,11 +1,11 @@ # ARSVIN Documentation -ARSVIN is a focused IEC 61850 Sampled Values Publisher for Windows. This index groups the documentation by workflow so users can find the right page quickly. +ARSVIN is a focused IEC 61850 Sampled Values engineering suite for Windows. It includes ARSVIN Publisher for stream generation and ArSubsv Subscriber for live/PCAP reception, decoding, visualization, and receiver-side evidence. ## Start here -- [Quick Start](quick-start.md) — install, open SCL, choose a stream, and publish safely. -- [Safety Boundaries](safety-boundaries.md) — lab-only assumptions and responsible use. +- [Quick Start](quick-start.md) — install the suite, choose Publisher or Subscriber, and begin with a safe workflow. +- [Safety Boundaries](safety-boundaries.md) — laboratory assumptions and responsible use. - [Known Limitations](known-limitations.md) — current protocol and runtime boundaries. ## Publisher workflows @@ -16,14 +16,19 @@ ARSVIN is a focused IEC 61850 Sampled Values Publisher for Windows. This index g - [Live Preflight Diagnostics](live-preflight-diagnostics.md) — preflight checks before live TX. - [P0 Publisher Protocol Roadmap](p0-publisher-protocol-roadmap.md) — nofASDU, quality, timing, and PCAP foundation. - [P1 Publisher Evidence Workflow](p1-publisher-evidence-workflow.md) — generated PCAP and Markdown evidence export. -- [P2 Full Publisher Scenario Engine](p2-full-publisher-scenarios.md) -- [Waveform Shape Panel](waveform-shape-panel.md) — per-phase and waveform-shaped publisher scenario presets. +- [P2 Full Publisher Scenario Engine](p2-full-publisher-scenarios.md) — repeatable protection and process-bus scenarios. +- [Waveform Shape Panel](waveform-shape-panel.md) — per-phase and waveform-shaped publisher scenarios. + +## Subscriber workflows + +- [Subscriber Verification App](subscriber-verification-app.md) — receiver-side stream binding, validation, health, and evidence. +- [ArSubsv SV Scout Companion](arsubsv-sv-scout-companion.md) — discovery, waveform, phasor, RMS, and PCAP analysis. ## Data sources and timing - [COMTRADE Replay](comtrade-replay.md) — replaying analog records as Sampled Values. -- [PTP and smpSynch Compatibility](ptp-and-smpsynch.md) — timing and synchronization boundaries. -- [Sync Compatibility Mode](sync-compatibility-mode.md) — lab smpSynch behavior. +- [PTP and `smpSynch` Compatibility](ptp-and-smpsynch.md) — timing and synchronization boundaries. +- [Sync Compatibility Mode](sync-compatibility-mode.md) — laboratory `smpSynch` behavior. ## Build, release, and public repository @@ -36,12 +41,7 @@ ARSVIN is a focused IEC 61850 Sampled Values Publisher for Windows. This index g ## Samples -- `samples/scl` — minimal and nofASDU sample SCL files. -- `samples/comtrade` — simple COMTRADE replay files. -- `samples/evidence` — sample Markdown evidence report. -- `samples/scenarios` — P2 full scenario preset notes and scenario matrix. - -- [ARSVIN Subscriber verification app](subscriber-verification-app.md) - - -- [ArSubsv — IEC 61850 Sampled Values Scout Companion](arsubsv-sv-scout-companion.md) +- `samples/scl` — minimal and `nofASDU` sample SCL files. +- `samples/comtrade` — COMTRADE replay files. +- `samples/evidence` — sample Markdown evidence reports. +- `samples/scenarios` — publisher scenario notes and matrices. diff --git a/docs/quick-start.md b/docs/quick-start.md index 754c84c..de6cf2a 100644 --- a/docs/quick-start.md +++ b/docs/quick-start.md @@ -1,86 +1,124 @@ # Quick Start -## 1. Install prerequisites +ARSVIN contains two focused Windows applications: -- Windows 10/11 -- Npcap for live Ethernet publishing -- Administrator rights for live packet transmission -- A lab network or isolated point-to-point setup when using live publish mode +- **ARSVIN Publisher** for generating IEC 61850 Sampled Values. +- **ArSubsv Subscriber** for live/PCAP capture, decoding, visualization, and receiver-side evidence. -## 2. Start ARSVIN +## 1. Install or run portable -Run `ARSVIN.exe`. +### Installer -For live packet publishing, launch it as **Administrator**. +Download `ARSVIN-Suite-Setup-win-x64.exe` from the latest GitHub Release and install the suite. Start Menu shortcuts are created for Publisher and Subscriber. -## 3. Open SCL +### Portable -Use **Config** to open an SCL file and select an SV stream. +Download either: -The imported stream can provide APPID, VLAN, destination MAC, `svID`, dataset reference, and other network details. +- `ARSVIN-Publisher-win-x64.exe` +- `ArSubsv-Subscriber-win-x64.exe` -## 4. Select a publisher slot +The applications are self-contained single-file Windows x64 executables. -Use the Publisher selector to switch between: +## 2. Install live-network prerequisite -- Publisher 1 -- Publisher 2 -- Publisher 3 +Install Npcap separately from its official website when live Ethernet capture or transmission is required. -Each publisher can have its own stream, APPID, MAC, VLAN, sample rate, and values. +Npcap is not bundled or silently installed by ARSVIN. Offline PCAP import, configuration, documentation, and Publisher dry-run workflows do not require live network access. -## 5. Choose a publishing workflow +## 3. Use an authorized test environment -ARSVIN supports several practical lab workflows: +For live traffic, use only: -- **Manual Continue** — continuous steady-state publishing until stopped -- **Ramp** — state-based magnitude / angle changes using the configured ramp timing -- **Sequencer** — timed state sequence publishing using the configured state durations -- **COMTRADE Replay** — replay analog records as Sampled Values +- an isolated laboratory network, +- a point-to-point engineering link, or +- another network where you have explicit authorization. -## 6. Review network settings +Administrator rights may be required by the local Npcap/network configuration. -Before using live mode, confirm: +# Publisher workflow -- selected adapter -- destination MAC -- source MAC -- APPID -- VLAN ID and priority -- sample rate / `smpCnt` progression expectation -- selected `smpSynch` behavior / compatibility mode +## 4. Open SCL -## 7. Publish +Open **ARSVIN Publisher**, then use **Config** to load an SCL/SCD file and select an SV stream. -Use **Check** for optional live diagnostics, then **Start** for live publishing. ARSVIN uses a KM Looptest friendly preflight model: warnings do not block live publish, but fatal errors still stop invalid traffic. +Imported engineering data can provide APPID, VLAN, destination MAC, `svID`, dataset reference, `confRev`, sample rate, `smpMod`, and `nofASDU`. -You can also run a dry test for validation without transmitting on the network. +## 5. Select a publisher slot -## 8. Verify +Switch between Publisher 1, Publisher 2, and Publisher 3. Each slot can use its own stream, APPID, MAC, VLAN, sample rate, source mode, and values. -Use Wireshark and the relay / subscriber status to confirm the stream is visible and readable. +## 6. Choose a source mode -Useful checks include: +Available workflows include: -- Ethernet type `0x88BA` -- correct destination multicast MAC -- correct APPID -- correct VLAN tag -- expected `svID` -- expected `smpSynch` behavior, especially whether the relay requires global compatibility mode +- **Manual Continue** — continuous steady-state publishing. +- **Ramp** — magnitude/angle changes using configured timing. +- **Sequencer** — timed states and repeatable per-phase scenarios. +- **COMTRADE Replay** — analog record replay as Sampled Values. +- **Waveform shaping** — harmonic, DC-offset, clipping, and related laboratory scenarios. -## Sync compatibility note +## 7. Review and preflight + +Before live transmission, confirm: + +- selected adapter, +- destination and source MAC, +- APPID, +- VLAN ID and priority, +- `svID`, dataset, and `confRev`, +- sample rate and `nofASDU`, +- expected `smpCnt` progression, +- selected quality mode, +- `smpSynch` compatibility behavior. + +Run a dry test first. Warnings remain visible but do not block valid laboratory traffic; fatal configuration errors do. + +## 8. Publish and preserve evidence + +Start live publishing only after preflight and network authorization. + +Use TX Timing Health to inspect target/actual FPS, jitter, late frames, missed schedules, and send duration. Export generated PCAP and the Markdown publisher report when evidence is needed. + +# Subscriber workflow + +## 9. Select live capture or PCAP import -For point-to-point relay readability checks, **Global compatibility — smpSynch=2** is usually the most practical starting point. It helps strict subscribers accept the SV stream, but it does not prove real PTP timing accuracy. +Open **ArSubsv Subscriber** and choose: +- a live Npcap adapter, or +- a classic PCAP file for offline analysis. -## 9. Use the modern SV setup workflow +When SCL is available, load it to assist stream binding and expected-configuration checks. -The **SV Setup** window is organized for quick looptest work: +## 10. Inspect the stream -- use the left **SV streams** navigator to select SV1, SV2, or SV3 -- edit the selected stream in the main panel -- choose **Manual**, **Ramp**, **Sequence**, or **COMTRADE** source mode -- press **Check** to open the Preflight Results window when you need details +Review: + +- discovered streams, +- APPID, VLAN, `svID`, and `confRev`, +- `nofASDU`, sample rate, and payload layout, +- `smpCnt` continuity and stream health, +- decoded values, +- waveform, +- phasor and RMS views. + +Export the receiver-side Markdown report when a repeatable record is required. + +## 11. Verify independently + +Use Wireshark, relay diagnostics, vendor tools, or certified equipment when independent verification is required. + +Useful packet checks include: + +- Ethernet type `0x88BA`, +- correct multicast destination MAC, +- correct APPID and VLAN tag, +- expected `svID`, dataset, and `confRev`, +- expected ASDU packing and sample counter behavior. + +Publisher evidence shows what the PC generated. Subscriber evidence shows what the selected PC/NIC received and decoded. Neither alone proves that a protection IED consumed the multicast stream. + +## Sync compatibility note -Warnings are shown in the Preflight Results window and event log. They do not block live publishing. Only fatal configuration errors block live publishing. +For point-to-point relay readability checks, **Global compatibility — `smpSynch=2`** can be a practical starting point for strict subscribers. It does not prove IEC 61850-9-3 timing accuracy or make the Windows PC a certified PTP grandmaster. diff --git a/installer/ARSVIN.iss b/installer/ARSVIN.iss new file mode 100644 index 0000000..b20e7b3 --- /dev/null +++ b/installer/ARSVIN.iss @@ -0,0 +1,97 @@ +; ARSVIN Suite installer +; Built by .github/workflows/release.yml with Inno Setup 6. + +#ifndef MyAppVersion + #define MyAppVersion "0.0.0-dev" +#endif + +#ifndef SourceDir + #define SourceDir "..\artifacts\installer-input" +#endif + +#ifndef OutputDir + #define OutputDir "..\artifacts\release" +#endif + +#define MyAppName "ARSVIN Suite" +#define MyAppPublisher "Ari Sulistiono" +#define MyAppUrl "https://github.com/masarray/arsvin" + +[Setup] +AppId={{A76AC909-93A0-4EA3-A6EE-DA3B64595F52} +AppName={#MyAppName} +AppVersion={#MyAppVersion} +AppVerName={#MyAppName} {#MyAppVersion} +AppPublisher={#MyAppPublisher} +AppPublisherURL={#MyAppUrl} +AppSupportURL={#MyAppUrl}/issues +AppUpdatesURL={#MyAppUrl}/releases +DefaultDirName={localappdata}\Programs\ARSVIN +DefaultGroupName=ARSVIN +DisableProgramGroupPage=yes +OutputDir={#OutputDir} +OutputBaseFilename=ARSVIN-Suite-Setup-win-x64 +SetupIconFile=..\src\ARSVIN\Assets\arsvin.ico +UninstallDisplayIcon={app}\ARSVIN.exe +Compression=lzma2/ultra64 +SolidCompression=yes +WizardStyle=modern +PrivilegesRequired=lowest +ArchitecturesAllowed=x64compatible +MinVersion=10.0 +CloseApplications=yes +RestartApplications=no +VersionInfoCompany={#MyAppPublisher} +VersionInfoDescription=ARSVIN IEC 61850 Sampled Values engineering suite +VersionInfoProductName={#MyAppName} +LicenseFile=..\LICENSE + +[Languages] +Name: "english"; MessagesFile: "compiler:Default.isl" + +[Tasks] +Name: "desktopicon"; Description: "Create a desktop shortcut for ARSVIN Publisher"; GroupDescription: "Additional shortcuts:"; Flags: unchecked + +[Files] +Source: "{#SourceDir}\ARSVIN.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "{#SourceDir}\ArSubsv.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "{#SourceDir}\README.md"; DestDir: "{app}"; Flags: ignoreversion +Source: "{#SourceDir}\LICENSE.txt"; DestDir: "{app}"; Flags: ignoreversion +Source: "{#SourceDir}\NOTICE.txt"; DestDir: "{app}"; Flags: ignoreversion +Source: "{#SourceDir}\THIRD_PARTY_NOTICES.md"; DestDir: "{app}"; Flags: ignoreversion +Source: "{#SourceDir}\VERSION.txt"; DestDir: "{app}"; Flags: ignoreversion +Source: "{#SourceDir}\docs\*"; DestDir: "{app}\docs"; Flags: ignoreversion recursesubdirs createallsubdirs +Source: "{#SourceDir}\samples\*"; DestDir: "{app}\samples"; Flags: ignoreversion recursesubdirs createallsubdirs + +[Icons] +Name: "{group}\ARSVIN Publisher"; Filename: "{app}\ARSVIN.exe"; WorkingDir: "{app}" +Name: "{group}\ArSubsv Subscriber"; Filename: "{app}\ArSubsv.exe"; WorkingDir: "{app}" +Name: "{group}\Documentation"; Filename: "{app}\README.md" +Name: "{group}\Project website"; Filename: "{#MyAppUrl}" +Name: "{group}\Uninstall ARSVIN Suite"; Filename: "{uninstallexe}" +Name: "{autodesktop}\ARSVIN Publisher"; Filename: "{app}\ARSVIN.exe"; WorkingDir: "{app}"; Tasks: desktopicon + +[Run] +Filename: "{app}\ARSVIN.exe"; Description: "Launch ARSVIN Publisher"; WorkingDir: "{app}"; Flags: nowait postinstall skipifsilent + +[Code] +function NpcapInstalled(): Boolean; +begin + Result := + FileExists(ExpandConstant('{sys}\Npcap\wpcap.dll')) or + FileExists(ExpandConstant('{sys}\wpcap.dll')); +end; + +procedure CurStepChanged(CurStep: TSetupStep); +begin + if (CurStep = ssPostInstall) and (not NpcapInstalled()) then + begin + MsgBox( + 'ARSVIN was installed successfully.' + #13#10 + #13#10 + + 'Live IEC 61850 Sampled Values capture and transmission require Npcap. ' + + 'Install Npcap separately from its official website before using live network features.', + mbInformation, + MB_OK + ); + end; +end; diff --git a/publish-win-x64.ps1 b/publish-win-x64.ps1 index 7847f26..31a3bc4 100644 --- a/publish-win-x64.ps1 +++ b/publish-win-x64.ps1 @@ -1,56 +1,15 @@ -$ErrorActionPreference = 'Stop' - -$root = $PSScriptRoot -$artifactRoot = Join-Path $root 'artifacts' -$out = Join-Path $artifactRoot 'ARSVIN-win-x64' -$publisherOut = Join-Path $out 'Publisher' -$subscriberOut = Join-Path $out 'Subscriber' -$publisherProject = Join-Path $root 'src\ARSVIN\ARSVIN.csproj' -$subscriberProject = Join-Path $root 'src\ARSVIN.Subscriber\ARSVIN.Subscriber.csproj' -$zipPath = Join-Path $artifactRoot 'ARSVIN-win-x64-portable.zip' - -if (Test-Path $out) { Remove-Item $out -Recurse -Force } -New-Item -ItemType Directory -Path $publisherOut -Force | Out-Null -New-Item -ItemType Directory -Path $subscriberOut -Force | Out-Null - -if (Test-Path $zipPath) { Remove-Item $zipPath -Force } +param( + [string] $Version = '0.0.0-dev', + [string] $Runtime = 'win-x64', + [switch] $SkipTests +) -Write-Host '==> Publishing ARSVIN Publisher win-x64 portable package' -dotnet publish $publisherProject ` - -c Release ` - -r win-x64 ` - --self-contained true ` - -p:PublishSingleFile=true ` - -p:IncludeNativeLibrariesForSelfExtract=true ` - -p:EnableCompressionInSingleFile=true ` - -p:DebugType=None ` - -p:DebugSymbols=false ` - -o $publisherOut - -Write-Host '==> Publishing ARSVIN Subscriber win-x64 portable package' -dotnet publish $subscriberProject ` - -c Release ` - -r win-x64 ` - --self-contained true ` - -p:PublishSingleFile=true ` - -p:IncludeNativeLibrariesForSelfExtract=true ` - -p:EnableCompressionInSingleFile=true ` - -p:DebugType=None ` - -p:DebugSymbols=false ` - -o $subscriberOut - -Copy-Item (Join-Path $root 'README.md') (Join-Path $out 'README.md') -Force -Copy-Item (Join-Path $root 'LICENSE') (Join-Path $out 'LICENSE.txt') -Force -Copy-Item (Join-Path $root 'NOTICE') (Join-Path $out 'NOTICE.txt') -Force -Copy-Item (Join-Path $root 'THIRD_PARTY_NOTICES.md') (Join-Path $out 'THIRD_PARTY_NOTICES.md') -Force +$ErrorActionPreference = 'Stop' +Set-StrictMode -Version Latest -$docsOut = Join-Path $out 'docs' -New-Item -ItemType Directory -Path $docsOut -Force | Out-Null -Copy-Item (Join-Path $root 'docs\quick-start.md') $docsOut -Force -Copy-Item (Join-Path $root 'docs\live-mode-safety.md') $docsOut -Force -Copy-Item (Join-Path $root 'docs\known-limitations.md') $docsOut -Force -Copy-Item (Join-Path $root 'docs\safety-boundaries.md') $docsOut -Force -Copy-Item (Join-Path $root 'docs\subscriber-verification-app.md') $docsOut -Force +$script = Join-Path $PSScriptRoot 'scripts\publish-release.ps1' +& $script -Version $Version -Runtime $Runtime -SkipTests:$SkipTests -Compress-Archive -Path (Join-Path $out '*') -DestinationPath $zipPath -Force -Write-Host "Created $zipPath" +if ($LASTEXITCODE -ne 0) { + exit $LASTEXITCODE +} diff --git a/scripts/publish-release.ps1 b/scripts/publish-release.ps1 new file mode 100644 index 0000000..0d9b52e --- /dev/null +++ b/scripts/publish-release.ps1 @@ -0,0 +1,168 @@ +param( + [string] $Version = '0.0.0-dev', + [string] $Runtime = 'win-x64', + [switch] $SkipTests +) + +$ErrorActionPreference = 'Stop' +Set-StrictMode -Version Latest + +$root = Split-Path -Parent $PSScriptRoot +$artifactRoot = Join-Path $root 'artifacts' +$releaseRoot = Join-Path $artifactRoot 'release' +$tempRoot = Join-Path $artifactRoot 'publish-temp' +$portableRoot = Join-Path $artifactRoot 'ARSVIN-win-x64' +$installerInput = Join-Path $artifactRoot 'installer-input' + +$publisherProject = Join-Path $root 'src\ARSVIN\ARSVIN.csproj' +$subscriberProject = Join-Path $root 'src\ARSVIN.Subscriber\ARSVIN.Subscriber.csproj' +$testProject = Join-Path $root 'tests\ARSVIN.Tests\ARSVIN.Tests.csproj' + +$normalizedVersion = ($Version.Trim() -replace '^[vV]', '') +if ($normalizedVersion -notmatch '^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$') { + throw "Version '$Version' is not a supported semantic version. Example: 1.2.3 or 1.2.3-beta.1." +} + +$coreVersion = ($normalizedVersion -split '[-+]')[0] +$fileVersion = "$coreVersion.0" +$informationalVersion = $normalizedVersion + +function Invoke-DotNet { + param( + [Parameter(Mandatory)] + [string[]] $Arguments + ) + + & dotnet @Arguments + if ($LASTEXITCODE -ne 0) { + throw "dotnet $($Arguments -join ' ') failed with exit code $LASTEXITCODE." + } +} + +function Reset-Directory { + param([Parameter(Mandatory)][string] $Path) + + if (Test-Path $Path) { + Remove-Item $Path -Recurse -Force + } + New-Item -ItemType Directory -Path $Path -Force | Out-Null +} + +function Copy-ReleaseDocumentation { + param([Parameter(Mandatory)][string] $Destination) + + New-Item -ItemType Directory -Path $Destination -Force | Out-Null + + Copy-Item (Join-Path $root 'README.md') (Join-Path $Destination 'README.md') -Force + Copy-Item (Join-Path $root 'LICENSE') (Join-Path $Destination 'LICENSE.txt') -Force + Copy-Item (Join-Path $root 'NOTICE') (Join-Path $Destination 'NOTICE.txt') -Force + Copy-Item (Join-Path $root 'THIRD_PARTY_NOTICES.md') (Join-Path $Destination 'THIRD_PARTY_NOTICES.md') -Force + + $docsOut = Join-Path $Destination 'docs' + New-Item -ItemType Directory -Path $docsOut -Force | Out-Null + + $documents = @( + 'quick-start.md', + 'live-mode-safety.md', + 'known-limitations.md', + 'safety-boundaries.md', + 'subscriber-verification-app.md', + 'arsubsv-sv-scout-companion.md' + ) + + foreach ($document in $documents) { + $source = Join-Path $root "docs\$document" + if (Test-Path $source) { + Copy-Item $source $docsOut -Force + } + } + + $samplesSource = Join-Path $root 'samples' + if (Test-Path $samplesSource) { + Copy-Item $samplesSource (Join-Path $Destination 'samples') -Recurse -Force + } +} + +Reset-Directory $releaseRoot +Reset-Directory $tempRoot +Reset-Directory $portableRoot +Reset-Directory $installerInput + +if (-not $SkipTests) { + Write-Host '==> Restoring and testing' + Invoke-DotNet -Arguments @('restore', $publisherProject) + Invoke-DotNet -Arguments @('restore', $subscriberProject) + Invoke-DotNet -Arguments @('restore', $testProject) + Invoke-DotNet -Arguments @('test', $testProject, '-c', 'Release', '--no-restore') +} + +$commonPublishArguments = @( + '-c', 'Release', + '-r', $Runtime, + '--self-contained', 'true', + '-p:PublishSingleFile=true', + '-p:IncludeNativeLibrariesForSelfExtract=true', + '-p:EnableCompressionInSingleFile=true', + '-p:PublishReadyToRun=false', + '-p:DebugType=None', + '-p:DebugSymbols=false', + "-p:Version=$normalizedVersion", + "-p:FileVersion=$fileVersion", + "-p:AssemblyVersion=$fileVersion", + "-p:InformationalVersion=$informationalVersion" +) + +$publisherOut = Join-Path $tempRoot 'publisher' +$subscriberOut = Join-Path $tempRoot 'subscriber' + +Write-Host "==> Publishing ARSVIN Publisher $normalizedVersion" +Invoke-DotNet -Arguments (@('publish', $publisherProject) + $commonPublishArguments + @('-o', $publisherOut)) + +Write-Host "==> Publishing ArSubsv Subscriber $normalizedVersion" +Invoke-DotNet -Arguments (@('publish', $subscriberProject) + $commonPublishArguments + @('-o', $subscriberOut)) + +$publisherExe = Join-Path $publisherOut 'ARSVIN.exe' +$subscriberExe = Join-Path $subscriberOut 'ARSVIN.Subscriber.exe' + +if (-not (Test-Path $publisherExe)) { + throw "Publisher executable was not found: $publisherExe" +} +if (-not (Test-Path $subscriberExe)) { + throw "Subscriber executable was not found: $subscriberExe" +} + +$publisherPortable = Join-Path $releaseRoot 'ARSVIN-Publisher-win-x64.exe' +$subscriberPortable = Join-Path $releaseRoot 'ArSubsv-Subscriber-win-x64.exe' + +Copy-Item $publisherExe $publisherPortable -Force +Copy-Item $subscriberExe $subscriberPortable -Force + +Copy-Item $publisherExe (Join-Path $portableRoot 'ARSVIN.exe') -Force +Copy-Item $subscriberExe (Join-Path $portableRoot 'ArSubsv.exe') -Force +Copy-ReleaseDocumentation -Destination $portableRoot + +Copy-Item $publisherExe (Join-Path $installerInput 'ARSVIN.exe') -Force +Copy-Item $subscriberExe (Join-Path $installerInput 'ArSubsv.exe') -Force +Copy-ReleaseDocumentation -Destination $installerInput + +$versionFile = @" +ARSVIN Suite +Version: $normalizedVersion +Runtime: $Runtime +Publisher: ARSVIN.exe +Subscriber: ArSubsv.exe +"@ +Set-Content -Path (Join-Path $portableRoot 'VERSION.txt') -Value $versionFile -Encoding utf8 +Set-Content -Path (Join-Path $installerInput 'VERSION.txt') -Value $versionFile -Encoding utf8 + +$portableZip = Join-Path $releaseRoot 'ARSVIN-win-x64-portable.zip' +if (Test-Path $portableZip) { + Remove-Item $portableZip -Force +} +Compress-Archive -Path (Join-Path $portableRoot '*') -DestinationPath $portableZip -CompressionLevel Optimal -Force + +Write-Host '==> Portable release artifacts' +Get-ChildItem $releaseRoot -File | Select-Object Name, Length | Format-Table -AutoSize + +Write-Host "Release output: $releaseRoot" +Write-Host "Installer input: $installerInput" diff --git a/site/assets/arsvin-publisher-sv-setup.webp b/site/assets/arsvin-publisher-sv-setup.webp new file mode 100644 index 0000000..6e3cc10 Binary files /dev/null and b/site/assets/arsvin-publisher-sv-setup.webp differ diff --git a/site/assets/arsvin-subscriber-live-analysis.webp b/site/assets/arsvin-subscriber-live-analysis.webp new file mode 100644 index 0000000..774ca0b Binary files /dev/null and b/site/assets/arsvin-subscriber-live-analysis.webp differ diff --git a/site/assets/arsvin-subscriber-waveform-phasor.webp b/site/assets/arsvin-subscriber-waveform-phasor.webp new file mode 100644 index 0000000..8277a78 Binary files /dev/null and b/site/assets/arsvin-subscriber-waveform-phasor.webp differ diff --git a/site/index.html b/site/index.html index 38c2614..95f5d08 100644 --- a/site/index.html +++ b/site/index.html @@ -3,23 +3,26 @@ - ARSVIN — IEC 61850 Sampled Values Publisher for Windows - + ARSVIN — Open-Source IEC 61850 Sampled Values Publisher & Subscriber + + - - + + + + - - + + @@ -32,19 +35,30 @@ "@context": "https://schema.org", "@type": "SoftwareApplication", "name": "ARSVIN", - "alternateName": "ARSVIN IEC 61850 Sampled Values Publisher", + "alternateName": "ARSVIN IEC 61850 Sampled Values Workbench", "applicationCategory": "EngineeringApplication", - "operatingSystem": "Windows 10/11 x64", - "softwareRequirements": "Npcap, .NET 8 SDK for source builds", + "applicationSubCategory": "Substation automation and process bus engineering", + "operatingSystem": "Windows 10, Windows 11", "license": "https://www.apache.org/licenses/LICENSE-2.0", + "isAccessibleForFree": true, "codeRepository": "https://github.com/masarray/arsvin", "url": "https://masarray.github.io/arsvin/", - "downloadUrl": "https://github.com/masarray/arsvin/releases", + "downloadUrl": "https://github.com/masarray/arsvin/releases/latest", + "screenshot": [ + "https://masarray.github.io/arsvin/assets/arsvin-publisher-sv-setup.webp", + "https://masarray.github.io/arsvin/assets/arsvin-subscriber-live-analysis.webp", + "https://masarray.github.io/arsvin/assets/arsvin-subscriber-waveform-phasor.webp" + ], "image": "https://masarray.github.io/arsvin/assets/arsvin-social-preview.png", - "author": { "@type": "Person", "name": "Ari Sulistiono", "url": "https://github.com/masarray" }, - "description": "Apache-2.0 IEC 61850 Sampled Values Publisher for Windows with SCL setup, nofASDU support, COMTRADE replay, TX timing health, per-phase scenario presets, and PCAP evidence export for isolated lab use." + "author": { + "@type": "Person", + "name": "Ari Sulistiono", + "url": "https://github.com/masarray" + }, + "description": "Apache-2.0 IEC 61850 Sampled Values Publisher and Subscriber suite for Windows with SCL-driven stream setup, COMTRADE replay, live and PCAP analysis, waveform, phasor, RMS, timing health, and evidence export." } +