Repository navigation
Read the real CPU state from SZL 0x0424 - #988
Merged
Merged
Conversation
get_cpu_state() sent a read request whose parameter section was one byte
long and returned "S7CpuStatusRun" without looking at the reply. It only
appeared to work because the server answered a read request that has no
address with the first four bytes of DB1.
Both clients now read SZL 0x0424 index 0 through read_szl and decode it
with snap7.szl.parse_cpu_state_szl. The payload is the partial-list
header (LENTHDR = 0x0014, N_DR = 1) followed by one 20-byte record:
ereig(2) ae(1) bzu-id(1) res(4) anlinfo1..4(4) time(8)
bzu-id holds the requested mode in bits 0-3 and the previous mode in
bits 4-7: 1-4 are STOP variants, 5 and 7 startup, 8 RUN, 0xA HOLD,
0xD DEFECT.
Sources for the layout:
- Wireshark, epan/dissectors/packet-s7comm_szl_ids.c,
s7comm_decode_szl_id_0424_idx_0000 and szl_0424_0000_bzu_id_names.
- Snap7 (github.com/SCADACS/snap7), src/core/s7_micro_client.cpp:
opGetPlcStatus reads opData[7], the same byte after the 4-byte
partial-list header. In src/core/s7_server.cpp, SZL_ID424 writes the
CPU status at offset 15 of the reply data (8 bytes of data and SZL
header, 4 bytes of partial-list header, record offset 3).
The Siemens reference manual "System Software for S7-300/400 System and
Standard Functions" (05/2010, A5E02789976-01) has no section for
SSL-ID W#16#xy24, so it could not be used.
The two sources read the byte differently. Snap7 compares the whole byte
with 0x00, 0x04 and 0x08 and reports anything else as STOP. This change
reports a zero byte as Unknown, a requested-mode nibble of 8 as Run and
everything else as Stop. That agrees with Snap7 for 0x00, 0x03, 0x04 and
0x08, and differs only when RUN comes with a non-zero previous mode,
which Snap7 would report as Stop.
Not tested on hardware. The record layout and the mapping come from the
sources above and from the server in this repository only.
Also:
- The server answers SZL 0x0424 from its CPU state and lists the ID in
SZL 0x0000.
- The server refuses a read request without an address specification
instead of falling back to DB1, offset 0, 4 bytes.
- The heartbeat of the synchronous client treats an answered refusal as
a live connection. A CPU that rejects SZL 0x0424 would otherwise be
reconnected on every interval. Transport failures and lost or stale
replies still mark the connection dead.
- S7Protocol.build_cpu_state_request and extract_cpu_state are kept and
documented as deprecated.
gijzelaerr
force-pushed
the
fix/real-cpu-state
branch
from
November 11, 2026 13:26
82dd899 to
a1be61a
Compare
gijzelaerr
enabled auto-merge (squash)
November 11, 2026 13:26
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
get_cpu_state()sent a read request with no address specification and always returnedS7CpuStatusRun. It passed only because the server answered such a request with default address values.Both clients now read SZL 0x0424, the server answers it from its real CPU state, and the server refuses a read request with no address. The heartbeat probe treats a refusal as proof the connection is alive. The old builder and extractor stay as deprecated public names.
Commits
Testing
end-of-file-fixeron.dockerignore, which is a symlink artefact on Windows.🤖 Generated with Claude Code