Skip to content

feat(plc4net): add serial and COTP transports - #2788

Merged
sruehl merged 5 commits into
apache:developfrom
openIndu:feat/plc4net-transports
Oct 2, 2026
Merged

sruehl merged 5 commits into
apache:developfrom
openIndu:feat/plc4net-transports

Conversation

@TomNewChao

@TomNewChao TomNewChao commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • add a serial transport for RS-232 and RS-485 links, including connection-string configuration and validation
  • add a COTP transport over TCP with TPKT framing, TSAP handshake, segmentation, and disconnect propagation
  • harden serial and COTP connection lifecycle, concurrent handshake, malformed-frame handling, and transport failure boundaries
  • register both transport projects in the PLC4Net solution and add regression coverage without requiring physical hardware

Context

This is the next transport-layer slice after the PLC4Net generator work. It is intentionally limited to reusable transports: Modbus RTU and S7 driver integration remain separate follow-up changes.

Validation

  • dotnet build plc4net/plc4net.sln --configuration Debug --no-restore --no-incremental --nologo
    • 0 warnings, 0 errors
  • dotnet test plc4net/plc4net.sln --configuration Debug --no-build --no-restore --nologo
    • 229 SPI tests and 139 code-generation tests passed
  • python plc4net/tools/code-gen/generate_parsers.py --check
  • git diff --check

@TomNewChao
TomNewChao force-pushed the feat/plc4net-transports branch from 1be917b to 0e00860 Compare September 30, 2026 11:48
@TomNewChao

Copy link
Copy Markdown
Contributor Author

Hi @sruehl, the PR is ready for review now.

This PR adds the serial and COTP transport layers required by plc4net, including connection lifecycle handling, COTP handshake and framing, serial-port configuration, and regression coverage for concurrent and malformed-frame scenarios.

The build and all plc4net tests pass. Could you please take another look? Thank you

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

COTP shutdown races, blocked-write cancellation, disconnect handling, and oversized TPKT framing require correction.

Review effort: Balanced
Findings: 1 High severity · 3 Medium severity · 1 Low severity

Open (5)
What changed in this PR

Adds reusable serial and COTP transports to PLC4Net, including configuration, framing, lifecycle handling, and regression tests.

Changes:

  • Implements configurable RS-232/RS-485 transport.
  • Implements COTP handshake, TPKT framing, segmentation, and diagnostics.
  • Registers projects and adds transport tests.
File Description
plc4net/​transports/​serial/​SerialTransportInstance.cs Implements serial I/O lifecycle and buffering.
plc4net/​transports/​serial/​SerialTransportConfiguration.cs Defines serial settings.
plc4net/​transports/​serial/​SerialTransport.cs Parses and validates serial configuration.
plc4net/​transports/​serial/​serial.csproj Defines the serial project.
plc4net/​transports/​cotp/​TpktFrame.cs Implements TPKT framing helpers.
plc4net/​transports/​cotp/​CotpTransportInstance.cs Implements COTP protocol handling.
plc4net/​transports/​cotp/​CotpTransport.cs Wraps TCP with COTP transport creation.
plc4net/​transports/​cotp/​cotp.csproj Defines the COTP project.
plc4net/​test/​spi-test/​transports/​SerialTransportConfigurationTests.cs Tests serial configuration.
plc4net/​test/​spi-test/​transports/​CotpTransportInstanceTests.cs Tests COTP framing and lifecycle behavior.
plc4net/​test/​spi-test/​spi-test.csproj References new transport projects.
plc4net/​plc4net.sln Registers both projects.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread plc4net/transports/cotp/CotpTransportInstance.cs
Comment thread plc4net/transports/cotp/CotpTransportInstance.cs
Comment thread plc4net/transports/cotp/CotpTransportInstance.cs Outdated
Comment thread plc4net/transports/cotp/TpktFrame.cs Outdated
Comment thread plc4net/transports/cotp/CotpTransport.cs
- Keep the handshake lock out of the blocking socket write. Writers are
  serialized by a dedicated lock, and Close() closes the inner transport
  before it takes the state lock, so a send stalled on a peer that stopped
  reading can no longer block Close() or the polling reads.
- Revalidate that the handshake is still the current one before Open()
  publishes success, so a Close() that raced the Confirm is not undone.
- Treat Disconnect Request, Disconnect Confirm (0xC0) and TPDU Error as
  session-ending: close the transport and report the teardown instead of
  leaving a session that looks usable.
- Reject payloads that do not fit the 16-bit TPKT length field instead of
  silently truncating the length.
- Correct the CotpTransport remarks about who performs the handshake and
  the framing.
- When the peer ends the COTP session (Disconnect Request, Disconnect
  Confirm or TPDU Error), keep the payload it already delivered readable
  instead of discarding it with the closed session. The transport still
  closes right away, so IsOpen turns false and Write() fails, but the
  teardown is reported only once no delivered bytes are left, or when a
  read asks for more than arrived. Write() and Open() now fail with the
  teardown reason instead of claiming that Open() was never called.
- Reject a null inner transport with ArgumentNullException instead of a
  NullReferenceException.
- Reject write-timeout=0 in the serial configuration: SerialPort only
  accepts a positive WriteTimeout or -1.
- Add a test with two concurrent multi-fragment writers, which pins the
  write lock, and make the stalled-write test check how the blocked
  writer ends.

Each fix is covered by a test that fails without it.
@sruehl
sruehl merged commit 50249f5 into apache:develop Oct 2, 2026
5 checks passed
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.

3 participants