Merge hw5-592 (#592)
Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
+24
-11
@@ -165,8 +165,8 @@ The driver has two interchangeable wire transports, selected by one `DriverConfi
|
||||
the connection size. A read whose size cannot be bounded (structure / unknown authored type) is sent
|
||||
alone; writes and status-only replies count their 4-byte header. Pinned by
|
||||
`RequestSchedulerTests.Mixed_scalar_string_and_array_replies_are_packed_within_the_reply_budget`.
|
||||
⚠️ RESIDUAL: mixed STRING/array packing has not been exercised against a real controller (the real-press
|
||||
gate predates the budget); the budget is unit-tested against the scheduler and fake channel only.
|
||||
Exercised on a real CompactLogix (Z-35162, hw4, 2026-10-09): a STRING, an array element, a DINT[32] and two
|
||||
scalars rode one Multiple Service Packet in 5/5 attempts, values equal to single reads.
|
||||
- **Fragmented-read integrity (#567):** `Read Tag Fragmented` replies are compared against the first reply;
|
||||
a changed type code *or* structure handle mid-read fails the read with `BadReply` rather than stitching
|
||||
two types into one value.
|
||||
@@ -179,9 +179,16 @@ The driver has two interchangeable wire transports, selected by one `DriverConfi
|
||||
and the next request reopens through the throttle. The request that got the reply fails
|
||||
`BadCommunicationError` (transport `BadConnection`); a keep-alive that gets it recycles the connection
|
||||
before any request fails. Every other status — tag-level errors, other `0x01` extended codes — is left to
|
||||
the request. ⚠️ RESIDUAL: which of the two codes a real Logix controller returns for a forgotten
|
||||
connection (and whether it answers at all rather than dropping TCP) is unobserved; the check is correct
|
||||
whichever it does — a silent target still faults the session through the exchange timeout.
|
||||
the request. **Observed on a real CompactLogix (Z-35162, hw5, 2026-10-09): neither code.** A connection left
|
||||
idle 60 s, past its 16 s timeout (keep-alive disabled for the test), was closed at the TCP level somewhere in
|
||||
that 16–60 s window — the exact moment, and whether the controller sent RST or FIN, were not captured (no
|
||||
packet capture; EPIPE on the first write only says the close was complete by then); the next request
|
||||
failed on its write in 9 ms (`Broken pipe` → `BadConnection` → `BadCommunicationError`, no CIP or
|
||||
encapsulation status) and the request after it reopened with a fresh Forward Open. That path needs no CIP
|
||||
check — a faulted session always reopens on the next send — and is pinned offline by
|
||||
`CipConnectionTests.A_target_that_resets_an_idle_session_fails_the_next_request_fast_and_the_one_after_reopens`.
|
||||
The 0x0107/0x0203 recycle stays for targets that keep TCP up. In production the keep-alive (every 8 s) stops
|
||||
a held connection idling out, so this shape follows a controller restart / re-download or a network gap.
|
||||
- `ConnectionSize` / `Timeout` / `AllowPacking` are honoured per pooled connection, and the **first**
|
||||
driver/device to open a given device key wins — including a Test Connect probe on a fused `admin,driver`
|
||||
node (its connection carries the probe timeout). A later opener with different options is ignored and
|
||||
@@ -241,16 +248,22 @@ The driver has two interchangeable wire transports, selected by one `DriverConfi
|
||||
and templates on Z-35162; a user-approved one-off on 2026-10-09 added **scalar native writes on a real CompactLogix**
|
||||
(DINT `test2`, BOOL `Program:UN01_Press.xxtest`, REAL `Program:ES03_EM03_Zone3._ff_test`: write, read back, restore, all
|
||||
Good), and the #611 gate added **native UDT member writes** (DINT, BIT and REAL members of `_EmptyTemperatureSegment`).
|
||||
Still ab_server-only: array and STRING writes, libplctag member writes, and fragmented writes. Mixed STRING/array/scalar
|
||||
hw5 (2026-10-09) added a **native STRING write** (`Program:ES03_TemperatureControl._StrTmp`, through the driver:
|
||||
write, read back, restored byte-exact). A user-approved **native array-element write** followed: `Program:EM01_PowerUnit._SEQ_EP[31]`
|
||||
0→4242→0 (the array's only alias targets `[1]`, no routine indexes or block-copies it; all 32 elements snapshotted
|
||||
twice before, after the write and after the restore — only `[31]` changed). Still ab_server-only: whole-array
|
||||
writes (the driver has none), libplctag member writes, and fragmented writes. #566 is answered (the controller drops TCP; see "A target-closed CIP connection"). Mixed STRING/array/scalar
|
||||
Multiple Service Packet reads (#582) are proven on the press (one 5-read MSP, values equal to single reads). Results:
|
||||
[native-ab-transport-gate-results](../plans/2026-10-07-native-ab-transport-gate-results.md).
|
||||
- **libplctag cannot be deleted yet.** Scalar native writes are proven on a CompactLogix (2026-10-09); what remains is #567
|
||||
(fragmented wide-struct writes), array/STRING writes on hardware, and AbLegacy native (simulator-only, no PCCC hardware).
|
||||
- **libplctag cannot be deleted yet.** Scalar, UDT-member and STRING native writes are proven on a CompactLogix
|
||||
(2026-10-09); what remains is #567 (fragmented wide-struct writes), whole-array writes on hardware, and AbLegacy
|
||||
native beyond the MicroLogix 1400 evidence.
|
||||
- UDT **member writes** (#611) are proven on a real CompactLogix on the **native** transport only (2026-10-09); the
|
||||
libplctag member-write path is `ab_server`-only. See [Member writes](#member-writes).
|
||||
- ⚠️ RESIDUAL (#567): wide-struct **fragmented writes** (8-byte alignment) are unit-tested only. Production
|
||||
presses are read-only and there is no bench controller, so this cannot be proven; it stays open until a
|
||||
bench controller exists.
|
||||
- ⚠️ RESIDUAL (#567): wide-struct **fragmented writes** (8-byte alignment) are unit-tested only. A write fragments only
|
||||
above `MaxRequestBytes` (4000 B on a Large Forward Open), so it needs a ~4 KB value; Z-35162 has no safe one (a DINT[32]
|
||||
or a STRING is a single Write Tag, and AbCip has no whole-array write anyway). It stays open until a bench controller
|
||||
or an approved large scratch tag exists.
|
||||
- Native browse (#572, resolved in code): listing paging no longer assumes ascending instance order, pages
|
||||
are paced, and a browse's template reads share one lease. Observed on Z-35162 (2026-10-09, 41
|
||||
pages / 3162 tags): every page strictly ascending, so out-of-order listing has never been seen on a real controller — the
|
||||
|
||||
Reference in New Issue
Block a user