fix(ablegacy): refuse libplctag writes to translated status bits (#659 fix round 1)
The read translation R6:0.DN -> R6:0.CON/13 made those names parse in libplctag, which would have turned a write - previously impossible, tag creation failed - into a masked write to the control word. LibplctagLegacyTagRuntime.WriteRefusal (via IAbLegacyTagFactory.WriteRefusal, same plumbing as native) now refuses writes to every rewritten status bit (R EN/EU/DN/EM/ER/UL/IN/FD, C UA) with BadNotSupported before a runtime is created; the runtime also refuses as defence in depth. Reads stay translated. T/C status bits libplctag parses itself keep their pre-existing behaviour. 13 new tests fail with the predicate disabled. Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
@@ -194,8 +194,9 @@ Native routing: SLC500/MicroLogix/PLC-5 are direct; `logixpccc` uses Unconnected
|
||||
follow-up). PLC-5 writes are refused the same way. libplctag performs a masked bit write here; a native
|
||||
read-modify-write of the control word would race the PLC updating TT/DN. Reads of status bits are unaffected.
|
||||
- ⚠️ **On libplctag (the default) a status-bit write is NOT refused** — it goes to the controller as a write to the
|
||||
timer/counter/control element (libplctag's masked bit-tag write; an `R` status bit is sent as `R<f>:<e>.CON/<bit>`
|
||||
since #659; not exercised on a wire — `ab_server` has no T/C/R files). Nothing in authoring prevents it: the address is free text,
|
||||
timer/counter element (libplctag's masked bit-tag write; not exercised on a wire — `ab_server` has no T/C/R
|
||||
files). This covers the status bits libplctag parses itself (`T` `EN/TT/DN`, `C` `CU/CD/DN/OV/UN`); the ones it
|
||||
has no mnemonic for — every `R` status bit and `C…UA` — **are** refused on libplctag too (`BadNotSupported`, #659). Nothing in authoring prevents it: the address is free text,
|
||||
any `dataType` may be chosen (a status bit is naturally authored `Bit`), and `writable` defaults to `true`.
|
||||
Author status-bit tags with `"writable": false` unless writing them is genuinely intended.
|
||||
- **PLC-5 native is N-file reads only**; every other PLC-5 operation is refused with `BadNotSupported`.
|
||||
@@ -242,9 +243,13 @@ 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 also means a
|
||||
libplctag **write** to an `R` status bit now reaches the controller as libplctag's masked bit write (it used to fail
|
||||
at tag creation) — the same behaviour T/C status bits always had on libplctag; see the status-bit write 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, 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).
|
||||
Not tested on hardware: L and A files (no press has them), function files, PLC-5, SLC, `logixpccc`.
|
||||
|
||||
Simulator evidence:
|
||||
|
||||
Reference in New Issue
Block a user