Skip to content

fix(server): reassemble COTP fragments and fix INT/DINT byte count - #806

Merged
gijzelaerr merged 1 commit into
masterfrom
fix/804-server-cotp-fragmentation
Aug 10, 2026
Merged

fix(server): reassemble COTP fragments and fix INT/DINT byte count#806
gijzelaerr merged 1 commit into
masterfrom
fix/804-server-cotp-fragmentation

Conversation

@gijzelaerr

Copy link
Copy Markdown
Owner

Fixes two bugs in the pure-Python server reported in #804:

1. COTP fragmented requests not reassembled

The server's COTP Connection Confirm omitted the TPDU size parameter (0xC0), causing spec-compliant clients to fall back to the ISO 8073 class-0 default of 128 bytes. Any request larger than 128 bytes was legitimately fragmented by the client, but the server tried to process each fragment as a standalone S7 PDU — producing PDU too short for S7 header errors.

Fix:

  • Parse TPDU size from the client's Connection Request
  • Echo it back in the Connection Confirm
  • Reassemble DT fragments in receive_data() by looping until the EOT bit is set

2. INT/DINT word lengths return wrong byte count

Read requests using word_len=INT (16-bit) or word_len=DINT (32-bit) fell through to the else branch and treated the item count as a byte count. Requesting 10 DINTs returned 10 bytes instead of 40.

Fix: Add S7WordLen.INT to the 2-byte branch and S7WordLen.DINT to the 4-byte branch in both _handle_read_area and _parse_read_address.

Closes #804

)

Two bugs in the pure-Python server:

1. COTP fragmentation not reassembled: the server's Connection Confirm
   omitted the TPDU size parameter, causing spec-compliant clients to
   fall back to the ISO 8073 default of 128 bytes and fragment requests.
   The server then tried to process each fragment as a standalone PDU.
   Fix: parse TPDU size from the client's Connection Request, echo it
   in the Connection Confirm, and reassemble DT fragments by looping
   until the EOT bit is set.

2. INT and DINT word lengths missing from byte-count conversion: read
   requests using word_len=INT or word_len=DINT returned count bytes
   instead of count*2 or count*4 bytes. Fix: add INT to the 2-byte
   branch and DINT to the 4-byte branch in both _handle_read_area
   and _parse_read_address.

Closes #804
@gijzelaerr
gijzelaerr merged commit cb4203a into master Aug 10, 2026
39 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.

Pure-Python Server: COTP fragmentation not reassembled, and DINT/INT read requests return wrong byte count

1 participant