Skip to content

fix: add SequenceNumber to Get/SetMultiVariables payloads#742

Merged
gijzelaerr merged 1 commit into
masterfrom
fix-payload-sequence-number
Jun 19, 2026
Merged

fix: add SequenceNumber to Get/SetMultiVariables payloads#742
gijzelaerr merged 1 commit into
masterfrom
fix-payload-sequence-number

Conversation

@gijzelaerr

Copy link
Copy Markdown
Owner

Summary

  • Insert a VLQ-encoded SequenceNumber (value 1) after the ObjectQualifier in all 6 Get/SetMultiVariables payload builder functions
  • S7-1200 FW V4.5 rejects requests without this field with error 11862009
  • Add unit tests verifying the SequenceNumber is present in all payload types

Closes #738

Test plan

  • TestSequenceNumber — 6 new tests verify every payload builder includes SequenceNumber after ObjectQualifier
  • Full test suite passes (1520 passed, 82 skipped)
  • pre-commit, mypy, ruff all pass
  • Needs real hardware verification on S7-1200 FW V4.5

🤖 Generated with Claude Code

@tommasofaedo

Copy link
Copy Markdown

Tested on real hardware: Siemens S7-1200 CPU 1212C DC/DC/DC, firmware V4.5.

Without this fix, every GetMultiVariables and SetMultiVariables request is
rejected by the PLC with error code 11862009 (0xB50FF9). This applies to all
six payload builders: read, write, area read, area write, symbolic read,
symbolic write.

With the SequenceNumber field (VLQ-encoded value 1) inserted after
encode_object_qualifier(), all requests are accepted. I verified reads across:

- DB area: DB100.bool_1 (BOOL) via GetMultiVariables → correct value ✓  
- Q area: QB0 (BYTE) and Q0.4 (BOOL bit) → match physical output state ✓  
- I area: IB0 (BYTE) → correct value (0x00, no inputs active) ✓  
- M area: Clock_0.5Hz (BOOL) → oscillates 0↔1 at ~0.7 s intervals ✓  

This is the foundational fix — without it nothing else in the S7CommPlus
client works on FW V4.5. Fix is correct and working on real hardware.

S7-1200 FW V4.5 requires a VLQ-encoded SequenceNumber field after the
ObjectQualifier in all Get/SetMultiVariables requests. Without it the
PLC rejects with error 11862009.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@gijzelaerr gijzelaerr force-pushed the fix-payload-sequence-number branch from 22a5c08 to 72e982d Compare June 19, 2026 15:16

@gijzelaerr gijzelaerr left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Review

Conflict resolved (test imports only — the client-side changes auto-merged cleanly). Rebased onto current master, pre-commit + tests pass.

The fix is correct. All 6 payload builders (_build_read_payload, _build_write_payload, _build_area_read_payload, _build_area_write_payload, _build_symbolic_read_payload, _build_symbolic_write_payload) now emit encode_uint32_vlq(1) (SequenceNumber = 1) immediately after the ObjectQualifier. The S7-1200 FW V4.5 requires this field; without it the PLC responds with error 11862009.

The tests verify each builder by locating the ObjectQualifier bytes in the output and asserting the next byte is VLQ-encoded 1.

No security concerns. No architectural impact — appends one VLQ byte to existing payloads.

PLC compatibility: S7CommPlus only. The SequenceNumber is harmless on PLCs that don't require it (just an extra ignored field). S7-300/400 legacy snap7/ is untouched.

Ready to merge.

@gijzelaerr gijzelaerr merged commit b01e942 into master Jun 19, 2026
8 of 39 checks passed
gijzelaerr added a commit that referenced this pull request Jun 19, 2026
The #742 merge left unresolved conflict markers in the import section.
Combines both sides: master's codec.py-based imports with #742's
payload builder imports for the SequenceNumber tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

fix: add SequenceNumber to GetMultiVariables/SetMultiVariables payloads

2 participants