fix(ablegacy): refuse every libplctag write the #659 translation changes (fix round 2)
Review M1: round 1 refused only the rewritten status bits, so S:/O:/I: writes - which never worked on libplctag because tag creation failed - would have started reaching the PLC (outputs, status-file words) on the default transport. WriteRefusal now keys on LibplctagLegacyName.IsTranslated: file number supplied (S/O/I, incl. bit writes like O:0/3, refused ahead of the parent-word RMW) or status bit rewritten. Reads unaffected. Docs/comments now true; gate doc notes R bit-number wire evidence is non-discriminating (L1). 12 new cases fail with the round-1 predicate. Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
@@ -243,13 +243,15 @@ status file when a digit follows it), and its sub-element table has only `con`/`
|
||||
bit libplctag lacks (`R` `EN/EU/DN/EM/ER/UL/IN/FD`, `C` `UA`) → `R6:0.CON/<bit>` (control word + bit, bit numbers
|
||||
from the native table). The authored grammar is unchanged; `S2:0`/`O0:0`/`I1:0` stay rejected by the parser (one
|
||||
spelling per address). Re-run on the same idle press 2026-10-09: every address above reads **identical** on both
|
||||
transports (`S:4` is a free-running clock and differs read to read on each). **The translation is read-side only —
|
||||
it does not widen the write surface:** before it, a libplctag write to an `R` status bit (or `C…UA`) could never reach
|
||||
the PLC (tag creation failed), and `R6:0.CON/13` would otherwise turn it into a masked write to the control word. So
|
||||
on libplctag a write to any status bit the translation rewrites (`R` `EN/EU/DN/EM/ER/UL/IN/FD`, `C` `UA`) is refused
|
||||
**`BadNotSupported` before a runtime is created** — nothing sent, health unchanged
|
||||
(`LibplctagLegacyTagRuntime.WriteRefusal`, asked through `IAbLegacyTagFactory.WriteRefusal`, the same plumbing as the
|
||||
native refusal). T/C status bits libplctag parses itself keep their pre-existing write behaviour (note above).
|
||||
transports (`S:4` is a free-running clock and differs read to read on each). **The translation is read-side only — it does not widen the write surface:** before it, libplctag could not create a
|
||||
tag for `S:`/`O:`/`I:` or for an `R`/`C…UA` status bit, so no write to one ever reached the PLC. Now that the
|
||||
translated names parse, a write would drive a physical output, a status-file word or (masked) a control word. So on
|
||||
libplctag **every write whose address the translation changes** — `S:`, `O:`, `I:` (word and bit writes; a bit write
|
||||
such as `O:0/3` is refused ahead of the parent-word read-modify-write) and the rewritten status bits (`R`
|
||||
`EN/EU/DN/EM/ER/UL/IN/FD`, `C` `UA`) — is refused **`BadNotSupported` before a runtime is created**: nothing read or
|
||||
sent, health unchanged (`LibplctagLegacyTagRuntime.WriteRefusal`, asked through `IAbLegacyTagFactory.WriteRefusal`, the
|
||||
same plumbing as the native refusal). Those writes never worked on libplctag, so nothing is lost; the native
|
||||
transport (opt-in) does write `S`/`O`/`I`. T/C status bits libplctag parses itself keep their pre-existing write behaviour (note above).
|
||||
Not tested on hardware: L and A files (no press has them), function files, PLC-5, SLC, `logixpccc`.
|
||||
|
||||
Simulator evidence:
|
||||
|
||||
@@ -700,3 +700,5 @@ ST14:10 String Native value="Z-33323" status=0x00000000 (
|
||||
```
|
||||
|
||||
Every address reads identically on both transports. `S:4` is the free-running clock, so its value differs read to read on each transport (both Good). `I:0` = -29376 = 0x8D40, and bits `/6` and `/15` read true on both while `/0`, `/1`, `/7` read false — the bit is extracted from the word libplctag read, not defaulted. ab_server has no S/O/I files, so this real-controller read is the only wire evidence; the translation is unit-pinned against a model of the `pccc.c` parser (`LibplctagLegacyNameTests`).
|
||||
|
||||
Caveats: `R6:0.DN` and `R6:0.EN` read `false` on both transports, so this read does not discriminate the control-word bit number (a wrong bit would very likely also read false) — the R bit mapping rests on the native table and the `pccc.c` parser model, not on this wire evidence. Writes: on libplctag every address the translation changes (`S:`/`O:`/`I:`, R/UA status bits) is refused `BadNotSupported` (#659 review), so this fix adds no libplctag write path.
|
||||
|
||||
Reference in New Issue
Block a user