diff --git a/SUPPORT.md b/SUPPORT.md index 1851bd8b0..d202d1068 100644 --- a/SUPPORT.md +++ b/SUPPORT.md @@ -12,7 +12,7 @@ Useful details include the Studio release, Windows version, ESP32-P4 firmware bu **Can't find the board?** Check the USB data cable and serial device selection; use **Configuration → Firmware** to verify the ESP32-P4 and install matching firmware. -**Can't see SV in Wireshark?** Verify the isolated Ethernet topology, selected capture interface and whether a switch mirror/TAP is needed. +**SMV missing in ARSAS, DigSubAnalyzer or Wireshark?** Follow the [independent Ethernet receiver check](docs/INTEROP_FIRST_PACKET.md): verify SV RUNNING, capture on the actual NIC, and compare priority-tagged VLAN 0 with the optional untagged lab SCL. **Interested in IEC 61850 subscriber testing?** Share results in the [community interoperability guide](docs/COMMUNITY_TESTING.md). diff --git a/apps/arstack_studio/templates/arstack_4i4v_untagged_lab.scd b/apps/arstack_studio/templates/arstack_4i4v_untagged_lab.scd new file mode 100644 index 000000000..ad5186469 --- /dev/null +++ b/apps/arstack_studio/templates/arstack_4i4v_untagged_lab.scd @@ -0,0 +1,70 @@ + +
+ + + + +
+

01-0C-CD-04-00-01

+

4000

+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/INTEROP_FIRST_PACKET.md b/docs/INTEROP_FIRST_PACKET.md new file mode 100644 index 000000000..6eaf726a7 --- /dev/null +++ b/docs/INTEROP_FIRST_PACKET.md @@ -0,0 +1,38 @@ +# First SV packet — independent receiver check + +Use this when ARStack Studio reports SV publishing but ARSAS or DigSubAnalyzer shows no Sampled Values. The goal is to identify whether the frame is **missing from the receiving Ethernet interface** or **arriving but not being decoded**. + +## 1. Confirm SV is actually publishing + +Connect the ESP32-P4 to an **isolated laboratory Ethernet network**. Open ARStack Studio and confirm **SV RUNNING** with increasing transmit/frame counts. PTP RUNNING alone does not mean SV frames are being transmitted. + +## 2. Capture on the receiver's Ethernet adapter + +On the same Windows machine used for the analyzer: + +1. Select the **physical Ethernet adapter** connected to the ESP32-P4 laboratory network, rather than Wi-Fi or the Npcap loopback adapter. +2. In Wireshark, start a new capture **with no capture filter**. A capture filter is different from a display filter. +3. While Studio is publishing, apply the **display filter** `eth.type == 0x88ba || vlan.etype == 0x88ba`. This covers both plain SV Ethernet frames and SV inside an 802.1Q priority/VLAN tag. The outer `eth.type` may be `0x8100` for tagged frames, so `eth.type == 0x88ba` **alone is not sufficient**. +4. Record whether SV frames appear and whether packet details show `APPID`, `svID`, `smpCnt`, destination MAC and, where present, VLAN ID/PCP. Check the actual packet bytes, not only the configured SCL; NIC VLAN offload/stripping can change what a host capture exposes. +5. Save **3–5 seconds** of traffic as `.pcapng` or `.pcap` with **no capture filter**, along with the selected NIC name, physical topology, Studio/firmware versions, analyzer versions and chosen stream filters. Remove confidential project information before sharing. + +The reference M3.H profile uses APPID `0x4000`, destination `01:0C:CD:04:00:01` and approximately **4,000 frames/s**. The stream ID depends on the profile deployed by Studio; do not assume a specific `svID` without examining the wire. + +## 3. Compare VLAN-tagged with untagged laboratory SV + +The included **reference SCL** requests Ethernet **802.1Q priority tagging**: VLAN ID `0`, PCP `4`. Some PC network or switch paths handle priority-tagged traffic differently. + +For diagnosis only, an alternative [untagged 4I+4V SCL](../apps/arstack_studio/templates/arstack_4i4v_untagged_lab.scd) keeps the same APPID, multicast MAC, data-set and sample rate **but omits VLAN tagging**. In Studio, stop publishing, load this SCL, select/deploy its SV stream and restart. Compare the receiving capture against the original configuration. + +**Do not change the VLAN scheme on an operating substation network.** This is an isolated-bench comparison to identify an Ethernet capture path difference; a change in receive behavior is evidence about the path, not proof of an arbitrary SV protocol fault. + +## 4. Interpret the result + +| What the receiver PC observes | Next engineering action | +| --- | --- | +| No plain or VLAN-encapsulated SV frames on the selected adapter | Check board link, Studio TX state, adapter choice, switch mirror/TAP, NIC VLAN offload and tagged VLAN forwarding. First confirm the combined display filter was used. | +| SV appears in Wireshark but not in DigSubAnalyzer | Note raw frame and decoder counters and share the capture; inspect Npcap filter and raw BER path. | +| SV appears in Wireshark but ARSAS snapshot stays empty | Use ARSAS's **First received SV stream** option (when available), or match selected SCL APPID/MAC/`svID` to the actual packet. | +| SV decodes in both applications | Compare samples, `smpCnt` rollover and waveform plausibility, then continue to timing/interoperability checks. | + +Open [P0 receiver acceptance issue #324](https://github.com/masarray/arstack61850/issues/324) for incident tracking. A self-decoded PCAP from Studio cannot replace an **independent RX capture from the affected NIC**. diff --git a/tests/test_scl.cpp b/tests/test_scl.cpp index e9484016e..333e663db 100644 --- a/tests/test_scl.cpp +++ b/tests/test_scl.cpp @@ -1204,6 +1204,54 @@ void parser_detects_duplicate_ieds_and_missing_dataset_references() { })); } +void arstack_untagged_lab_reference_compiles_without_vlan_tag() { + using namespace ar::iec61850::sampled_values; + using namespace ar::iec61850::scl; + + const auto path = std::filesystem::path{ARIEC61850_SOURCE_DIR} / + "apps" / "arstack_studio" / "templates" / + "arstack_4i4v_untagged_lab.scd"; + const auto document = SclParser{}.load(path); + CHECK(document.sampled_values_streams.size() == 1U); + const auto& stream = document.sampled_values_streams.front(); + CHECK(stream.address.app_id == std::optional{static_cast(0x4000U)}); + CHECK(!stream.address.vlan_id.has_value()); + CHECK(!stream.address.vlan_priority.has_value()); + CHECK(stream.entries.size() == 16U); + CHECK(stream.sample_rate == 4000U); + CHECK(stream.no_asdu == 1U); + + // A/B lab isolation must change only the outer Ethernet VLAN tag. + // Preserve the shipped reference stream's application identity and data layout. + const auto reference_path = std::filesystem::path{ARIEC61850_SOURCE_DIR} / + "apps" / "arstack_studio" / "templates" / + "arstack_4i4v_9-2le_reference.scd"; + const auto reference_document = SclParser{}.load(reference_path); + CHECK(reference_document.sampled_values_streams.size() == 1U); + const auto& reference = reference_document.sampled_values_streams.front(); + CHECK(reference.address.vlan_id == std::optional{static_cast(0U)}); + CHECK(reference.address.vlan_priority == std::optional{static_cast(4U)}); + CHECK(stream.address.destination_mac == reference.address.destination_mac); + CHECK(stream.address.app_id == reference.address.app_id); + CHECK(stream.sv_id == reference.sv_id); + CHECK(stream.configuration_revision == reference.configuration_revision); + CHECK(stream.sample_rate == reference.sample_rate); + CHECK(stream.no_asdu == reference.no_asdu); + CHECK(stream.entries.size() == reference.entries.size()); + + SvPublisherProfileCompileContext context; + context.profile_family = SvProfileFamily::legacy_9_2le; + context.sample_counter_modulus = static_cast(4000U); + const auto compiled = SvPublisherProfileCompiler::compile(stream, context); + CHECK(compiled.ok()); + CHECK(compiled.profile.has_value()); + CHECK(!compiled.profile->vlan_present); + CHECK(compiled.profile->app_id == 0x4000U); + CHECK(compiled.profile->payload_size_bytes == 64U); + CHECK(compiled.profile->timing.exact_frame_rate_hz() == + std::optional{4000U}); +} + void parser_detects_editions_from_root_metadata() { using namespace ar::iec61850::scl; @@ -1281,6 +1329,7 @@ int main() { {"Simulator semantic defaults and indexed RCBs", simulator_compiles_semantic_defaults_and_indexed_report_instances}, {"SCL SettingControl", parser_preserves_setting_control_and_invalid_state}, {"SCL conflicts and warnings", parser_detects_duplicate_ieds_and_missing_dataset_references}, + {"ARStack untagged SV lab profile", arstack_untagged_lab_reference_compiles_without_vlan_tag}, {"SCL edition detection", parser_detects_editions_from_root_metadata}, {"SCL prefixed namespace", parser_supports_prefixed_namespaces_and_predefined_entities}, {"SCL secure XML", secure_xml_reader_rejects_dtd_entities_and_malformed_documents},