Skip to content

fix(IEC-101): exact engineer-readable multiline Trace blocks for each physical FT1.2 frame - #43

Merged
masarray merged 4 commits into
masterfrom
fix/iec101-multiline-trace-contract-20261029
Oct 28, 2026
Merged

masarray merged 4 commits into
masterfrom
fix/iec101-multiline-trace-contract-20261029

Conversation

@masarray

@masarray masarray commented Oct 28, 2026 •

Copy link
Copy Markdown
Owner

Screenshot-driven mandatory UI contract

Prior PR #42 produced a one-line title + one generic narrative, not the required engineer-readable four-part line monitor. This PR implements exact physical telegram structure: ⇧/⇩ [PC time] service, Data Link: flags and DL Address (+ Length), ASDU: Type/Count, COT/Origin, Comm Addr, one row per IOA incl quality/time, Hex Frame: complete original bytes. Compact TX-blue/RX-green WPF monospace text, no bulky cards or repeated timestamps.

Correctness and scope

  • Pure formatter consumes existing typed Ft12FrameDecode.LinkControl + Iec10xAsduDecode.Objects, never parses HEX twice, calls no WPF APIs and performs no transport I/O.
  • FC10/11 requests show PRM/FCV/FCB only; secondary FC9 no-data shows PRM/ACD/DFC and correct Class 1 availability. FC8 includes decoded Type ID, COT, P/N/TEST, OA, CA, each information object with SIQ/DIQ/QDS flags and CP56 validity/SU.
  • Duplicate per-object evidence from a single multi-IOA telegram no longer repeats whole HEX in Trace; per-object Values/Events are preserved.
  • HEX grouped by original bytes once per evidence row even for passive compact HEX; Capture/Inspector remain source-linked.
  • Example user-provided ASDU has mismatched length/checksum and out-of-range CP56 milliseconds: invalid data must be reported as invalid rather than falsely displayed as valid. Tests use corrected valid synthetic frame, real fixed-frame samples and explicit invalid sample.
  • Active master polling/FCB, dual-link, passive RX-only, bounded UI queue, 1200-row ring and 75ms batching stay unchanged.
  • docs/IEC101_TRACE_MULTILINE_CONTRACT_20261029.md includes exact format and FAT checks.

Merge gates

Windows Release + format, protocol smoke + all xUnit, GUI packaging/smoke, CodeQL + hygiene + dependency review, checked against exact commit SHA. Real SICAM/independent IEC-101 reference FAT still required; no premature real-device claims.


var primary = $"[PRM:1,FCV:{Bit(link.Fcv)}] [FCB:{Bit(link.Fcb)}]";
var secondary = $"[PRM:0,ACD:{Bit(link.Acd)},DFC:{Bit(link.Dfc)}]";
var declaredLength = frame?.DeclaredLength is int len ? $" Length {len}" : "";
$"Master requests {requested} queued data from RTU · [{flags}].");
}
true => ", Class 1 Data Available!",
false => ", No Class 1 Data Indicated",
10, 0, 0, 1,
11, 0, 0, 0
});
var f = LinkFrame("10 29 69 92 16", "Class 1");
@masarray
masarray marked this pull request as ready for review October 28, 2026 21:39
@masarray
masarray merged commit 9ef09e6 into master Oct 28, 2026
5 checks passed
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-28T21:41:43.152358Z b901d24 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b901d24a76

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +214 to +218
if (timeByteOffset >= 0 && obj.RawBytes.Count >= timeByteOffset + 7)
{
details += $"; IOA {first.InformationObjectAddress}={first.ShortValue}";
if (first.QualityDetails is not null) details += $"; Quality={first.QualityDetails.DisplayText}";
if (!string.IsNullOrWhiteSpace(first.TimestampText)) details += $"; RTU time={first.TimestampText}";
var minuteFlags = obj.RawBytes[timeByteOffset + 2];
var hourFlags = obj.RawBytes[timeByteOffset + 3];
invalid |= (minuteFlags & 0x80) != 0;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Move CP56 field decoding into the shared protocol decoder

For timestamped ASDUs, this formatter now selects type-dependent information-element offsets and decodes CP56 validity and summer-time bits directly from RawBytes. This introduces a second ASDU interpretation implementation in Desktop alongside Iec10xAsduDecoder.DecodeTimestampText, requiring protocol changes to be maintained in both layers. AGENTS.md explicitly prohibits Desktop ownership of ASDU parsing. Expose the required time flags as typed decoder results and restrict this formatter to presenting them.

AGENTS.md reference: AGENTS.md:L76-L76

Useful? React with 👍 / 👎.

Comment on lines +184 to +186
if (obj.QualityDetails is { } q)
builder.Append(" [").Append(q.Invalid ? "Invalid" : q.DisplayText == "Good" ? "Valid" : "Valid, " + q.DisplayText)
.Append(']');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve other quality flags when IV is set

When a received object's quality has IV set together with another flag, the new conditional prints only Invalid, discarding the remaining decoded quality information. For example, SIQ 0xB1 previously displayed Invalid, Blocked, Substituted through QualityDetails.DisplayText, but now displays only [Invalid]; QDS overflow and BCR carry/adjusted flags are similarly hidden whenever IV is set. Keep q.DisplayText for invalid objects as well so operators can distinguish these conditions without manually decoding the raw bytes.

Useful? React with 👍 / 👎.

Comment on lines +760 to +763
if (item.ProtocolMode == Iec60870ProtocolMode.Iec101 &&
item.AsduDetails is not null &&
item.InformationObjectDetails is { Index: > 1 })
return false;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Update the required output policy for the trace changes

This commit changes Frame Trace output and retention behavior by introducing multiline blocks and suppressing secondary per-object trace rows, but only adds a standalone contract document. AGENTS.md specifically requires updating docs/OUTPUT_AND_PERFORMANCE_POLICY.md when output, retention, or rendering behavior changes; that policy is untouched. Update the canonical policy to describe physical-frame deduplication and the new presentation contract so its documented behavior remains consistent with the implementation.

AGENTS.md reference: AGENTS.md:L194-L194

Useful? React with 👍 / 👎.

@masarray masarray changed the title fix(IEC-101): exact ASE-style multiline Trace blocks for each physical FT1.2 frame fix(IEC-101): exact engineer-readable multiline Trace blocks for each physical FT1.2 frame Oct 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants