Skip to content

Make MMS server interoperable with current live clients - #66

Merged
masarray merged 1 commit into
agent/iedsim-wire-parity-currentfrom
agent/mms-server-live-client-fix
Aug 11, 2026
Merged

masarray merged 1 commit into
agent/iedsim-wire-parity-currentfrom
agent/mms-server-live-client-fix

Conversation

@masarray

@masarray masarray commented Aug 11, 2026 •

Copy link
Copy Markdown
Owner

Outcome

Completes the runnable read-only/control-capable MMS server phase against the repository's current working clients, while keeping the change isolated on top of #61.

Interoperability fixes

  • optionally advertises both Logical Node roots and flattened child aliases for the current discovery client;
  • gives the URCB simulator a truthful LLN0 root type and exact DataSet/RCB structure;
  • propagates application status, service, and invoke ID through the server session;
  • emits canonical routed MMS write envelopes for Direct Oper;
  • returns MMS ConfirmedError for valid-but-missing optional objects instead of a protocol Reject;
  • advertises only the MMS services the server actually implements.

Verified evidence

  • full repository Release: 41/41 tests passed;
  • embedded hard profile: 19/19 tests passed;
  • MMS server live-client profile: 5/5 tests passed;
  • direct server discovery: LD1, LN3, DO18, DA34, DS1, exact reads 34/34;
  • URCB discovery: LD1, LN2, DO9, DA19, DS1, RCB1, exact reads 19/19;
  • control inventory: 8/8 ready;
  • armed Direct Oper loopback accepted and read back true.

Evidence boundary

This is verified software loopback interoperability, not IEC 61850 conformance or physical external IEC 61850 client/ESP32 certification. Check-bit validation remains fail-closed; the explicit test disables unsupported synchro/interlock checks.

@masarray
masarray merged commit a31112b into agent/iedsim-wire-parity-current Aug 11, 2026
26 checks passed

@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: 993dae54e1

ℹ️ 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".

!writer.write_tlv_header(
asn1::BerClass::context_specific, true, 0, *access_tlv) ||
!writer.write_tlv_header(asn1::BerClass::context_specific, false, 7, 1U) ||
!writer.write_byte(2U) || writer.size() != *required) {

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 Encode object-non-existent with access value 1

When a valid request references a missing optional object, this emits error class access [7] with value 2, which denotes object-access-denied; object-non-existent is value 1 in that MMS error-class enumeration. Clients that inspect the ConfirmedError will therefore treat an absent object as a permissions failure, defeating the intended optional-object discovery behavior.

Useful? React with 👍 / 👎.

Comment on lines +78 to +82
// serviceError.errorClass uses access[7] object-non-existent(2). This is
// the interoperable outcome for optional IEC 61850 objects such as Cancel:
// the request was syntactically valid, but the named service object is not
// present. A RejectPDU would incorrectly classify the request itself as
// malformed and abort otherwise valid control discovery clients.

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 Keep Reject responses for malformed and unsupported requests

This encoder is not limited to the valid-but-missing case described here: connection_runtime_iedsim.cpp routes malformed_request, unsupported_service, and unsupported_request through the same function via compatibility_error_status(). After this change those requests receive an access-class ConfirmedError and appear to be object lookup failures, rather than receiving the protocol Reject appropriate for malformed or unrecognized requests; route only object_not_found to this encoder and retain Reject encoding for the other statuses.

Useful? React with 👍 / 👎.

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.

1 participant