Commit Graph

3604 Commits

Author SHA1 Message Date
Joseph Doherty 9a576599e1 docs(plans): native AB transport tasks.json status sync 2026-10-07 19:11:03 -04:00
Joseph Doherty d613575f32 merge: libplctag empty-path fix (null Path for an empty CIP route) 2026-10-07 19:06:36 -04:00
Joseph Doherty b8ebafc642 feat(adminui): Transport dropdown on AbCip/AbLegacy driver forms (live-verified on docker-dev)
- AbCip/AbLegacy driver forms gain a Transport InputSelect; FromOptions/ToOptions now carry
  Transport, so saving any other field no longer silently reverts Native to libplctag.
- Both drivers log the constructed transport once per init.
- AbCip factory now takes the host ILoggerFactory (it ran on NullLogger in production, hiding
  every AbCip log line); DriverFactoryBootstrap passes it.
- Gate results: AdminUI /run (T19) native, inverted (dead port) and libplctag legs.
2026-10-07 19:05:50 -04:00
Joseph Doherty afe6850f3d fix(abcip,ablegacy): pass a null libplctag path for an empty CIP route (Micro800 / unrouted MicroLogix)
The libplctag adapters assigned Tag.Path straight from the device's parsed
CipPath. A device address with no route (ab://host:44818/ - the normal
Micro800 form, and a MicroLogix with no route) parses to "", and libplctag
rejects an empty path attribute with ErrorBadData; omitting the attribute
(null) is what it accepts. So Micro800 could not connect on the default
libplctag transport.

This predates the native transport work and exists on master.

Add an internal LibplctagPath.Normalize helper per driver project (blank ->
null) and route all four Tag constructions through it (AbCip tag runtime,
symbol-list enumerator, template reader; AbLegacy tag runtime). The runtime
tag construction is extracted to an internal BuildTag so tests can inspect
Tag.Path without connecting. Tests fail with Normalize reverted to identity.
Update the Micro800 smoke-test comment: both transports are expected to pass.
2026-10-07 19:05:43 -04:00
Joseph Doherty c8b35663e5 docs(plans): native AB transport tasks.json status sync 2026-10-07 18:29:04 -04:00
Joseph Doherty 566ab20d72 test(abcip): differential stops on first connection failure, paces + caps requests, reserves array/UDT slots, fails vacuous template parity; write tests opt-in (Task 18 review r1) 2026-10-07 18:24:25 -04:00
Joseph Doherty 1d6501f427 feat(ab-transport): process-wide open-attempt budget so the differential never retries an open (Task 18 review r1) 2026-10-07 18:10:25 -04:00
Joseph Doherty 0e20a8e5a9 test(abcip): read-only differential harness comparing native and libplctag on one target 2026-10-07 17:58:47 -04:00
Joseph Doherty d1ad2600d1 docs(plans): tasks.json sync 2026-10-07 17:46:19 -04:00
Joseph Doherty 52670447ca docs(plans): T17 results commit reference 2026-10-07 17:36:16 -04:00
Joseph Doherty 8c68694df1 test(ab): run the ab_server integration suites on both transports 2026-10-07 17:35:31 -04:00
Joseph Doherty 2171fc8ce3 fix(ablegacy): PCCC requestor id is libplctag's captured identity (found by Task 17 slc500)
ab_server answers every Execute PCCC with a fixed requestor id (pccc.c
PCCC_RESP_PREFIX: 07 3D F3 45 43 50 21) instead of echoing the request's, so
the R14-3 echo check rejected every native reply sent under the 0x1337 CIP
originator identity as BadReply. The pooled runtime now sends libplctag's
identity (PcccServices.RequestorVendor/RequestorSerial), which passes the echo
check against ab_server and against a real controller that echoes. Pinned by a
FakeEipServer round trip that answers with ab_server's fixed prefix.
2026-10-07 17:31:45 -04:00
Joseph Doherty 82d011c7a8 fix(ab-transport): RegisterSession carries a zero sender context (found by Task 17 controllogix)
ab_server's RegisterSession sanity check rejects any non-zero sender context
with encapsulation status 1 and a header-only reply, so every native session
against the simulator failed with BadCommunicationError. libplctag sends zero
(logix-register-session.hex); the codec test now matches that capture byte for
byte instead of excluding the context, and a client test pins the zero on the wire.
2026-10-07 17:20:06 -04:00
Joseph Doherty 72c73f525e docs(plans): tasks.json sync 2026-10-07 17:15:54 -04:00
Joseph Doherty e66b05fddf docs(plans): native AB transport tasks.json status sync 2026-10-07 17:14:02 -04:00
Joseph Doherty cff57d25c5 test(abcip): Task 15 nullable warning fix 2026-10-07 17:13:53 -04:00
Joseph Doherty 45f6e1793f feat(abcip): Transport option selects native or libplctag across driver, probe and CLI 2026-10-07 17:13:37 -04:00
Joseph Doherty 1211cd9a83 test(abcip): Task 13 review r2 - non-vacuous exclusive-packing tests
Scheduler tests (exclusive mid-queue and at head) and a template-reader test that
genuinely queues a Read Template behind a small read; bounded QueuedCount wait
replaces the fixed delay. Falsified: removing exclusive from the reader turns the
reader test red; removing the Exclusive handling in RequestScheduler turns all three red.
2026-10-07 17:10:35 -04:00
Joseph Doherty b2b9aa04ed fix(abcip): Task 13 review r1 - bounded listing pager, exclusive large reads, template bound, safe lease release 2026-10-07 17:07:05 -04:00
Joseph Doherty 78e60a5a75 feat(abcip): native symbol listing and template reads feeding the unchanged decoders 2026-10-07 17:01:40 -04:00
Joseph Doherty 5dd1b987b9 docs(plans): native AB transport tasks.json status sync 2026-10-07 16:58:54 -04:00
Joseph Doherty f2f1e4280c merge: Task 12 — native AbCip tag runtime, factory and device mapping 2026-10-07 16:58:37 -04:00
Joseph Doherty 5fd9ff941e feat(ablegacy): Transport option selects native or libplctag across driver, probe and CLI 2026-10-07 16:57:20 -04:00
Joseph Doherty e2e441d45e fix(abcip): native runtime write guards, same-width integer exemption, deferred path encoding (Task 12 review r1) 2026-10-07 16:56:30 -04:00
Joseph Doherty f2377251af merge: Task 14 — native AbLegacy tag runtime + factory 2026-10-07 16:54:40 -04:00
Joseph Doherty b249c15c1a fix(ablegacy): refuse status-bit writes, decode status bits as 0/1, reject over-long replies, global TNS 2026-10-07 16:54:18 -04:00
Joseph Doherty d0f89f9ec1 docs(plans): native AB transport tasks.json status sync 2026-10-07 16:49:32 -04:00
Joseph Doherty 33dbd342e5 fix(ab-transport): trim-only CIP path canonicalisation, observe abandoned shared opens, no Forward Open after dispose during connect 2026-10-07 16:49:19 -04:00
Joseph Doherty 25cc836865 feat(abcip): native tag runtime over the managed CIP transport, with returned-type checking 2026-10-07 16:47:48 -04:00
Joseph Doherty c31e6deebf feat(ablegacy): native PCCC tag runtime over the managed transport 2026-10-07 16:45:50 -04:00
Joseph Doherty a251954bf7 fix(ab-transport): harden Task 9 pool and connection (close chaining, uncancellable shared open, monotonic throttle, canonical CIP path, internal ctors, shared-pool logger) 2026-10-07 16:45:26 -04:00
Joseph Doherty b82fffd269 feat(ab-transport): per-device connection with routing modes, shared scheduler, keep-alive and Forward Open throttle 2026-10-07 16:35:11 -04:00
Joseph Doherty d7145ddfa5 docs(plans): native AB transport tasks.json status sync 2026-10-07 16:23:09 -04:00
Joseph Doherty ba73f48f9c merge: Task 10 — RequestScheduler (MSP coalescing) + LogixTagClient fragment loops 2026-10-07 16:23:08 -04:00
Joseph Doherty 5211975067 fix(ab-transport): harden Task 10 scheduler and tag client (dispose faults, pump guard, read cap, write validation, 8-byte wide-struct alignment) 2026-10-07 16:22:40 -04:00
Joseph Doherty 1c7fd5d5de feat(ab-transport): MSP-coalescing request scheduler and fragmented Logix read/write 2026-10-07 16:15:05 -04:00
Joseph Doherty 2f9c7eff58 merge: Task 5 — EtherNet/IP encapsulation codec + single-flight client 2026-10-07 16:14:02 -04:00
Joseph Doherty 4c1c362b0e feat(ab-transport): EtherNet/IP encapsulation codec and single-flight session client 2026-10-07 16:09:06 -04:00
Joseph Doherty 7c81844be5 merge: Task 8 — PCCC codec (Execute PCCC, SLC typed, PLC-5 range read) 2026-10-07 16:07:32 -04:00
Joseph Doherty 5eb018937b fix(ab-transport): PCCC review r1 - UA bit, bit limits, stricter ParseReply, non-const verified flags 2026-10-07 16:07:13 -04:00
Joseph Doherty 110fb861e9 merge: Task 7 — CIP service codecs (CM, MSP, Logix, symbol, template) 2026-10-07 16:07:07 -04:00
Joseph Doherty 6d16765804 fix(ab-transport): harden Task 7 codecs (read status, 32-bit start instance, empty-More, size range) 2026-10-07 16:06:49 -04:00
Joseph Doherty 13d631d856 feat(ab-transport): PCCC Execute-PCCC codec for SLC/MicroLogix typed logical and PLC-5 range read 2026-10-07 16:03:43 -04:00
Joseph Doherty 5f86b370f7 feat(ab-transport): Connection Manager, MSP, Logix read/write, symbol and template service codecs 2026-10-07 16:03:41 -04:00
Joseph Doherty ec1a39ff6e merge: Task 4 — golden libplctag<->ab_server frame captures 2026-10-07 15:59:39 -04:00
Joseph Doherty 617b9ba40c docs(plans): native AB transport tasks.json status sync 2026-10-07 15:59:39 -04:00
Joseph Doherty b085360454 test(ab-transport): non-zero array/BOOL captures, committed capture client, sim quirks
Review round 1 on the golden frames:
- Re-captured logix-read-dint-array16 (element i = ((i+1)<<24)|(i+1)) and
  logix-read-bool (= 1) so neither decode oracle is all zeros. ab_server rejects
  libplctag's own BOOL write with CIP 0x03 (two data bytes for a one-byte BOOL),
  so the BOOL is seeded by a raw UCMM Write Tag (client seed-bool).
- Committed the capture client as scripts/ab-capture/client (outside the slnx,
  CPM off, libplctag 1.5.2 pinned); capture.sh gains a `client` subcommand.
- README documents simulator-only behaviour: zeroed reply sender context, STRING
  typed D0 00 instead of A0 02 + handle, and the BOOL write refusal.
- capture.sh no longer claims UnregisterSession reaches the wire (session ends in RST).
- CaptureFileTests also check the CPF walk ends at the frame end and that every
  reply service is its request service | 0x80.
2026-10-07 15:58:05 -04:00
Joseph Doherty 1201d5fcfb test(ab-transport): golden libplctag<->ab_server frame captures for Logix, Micro800 and PCCC
17 .hex fixtures captured from libplctag 1.5.2 (native 2.6.0) against
otopcua-ab-server:libplctag-release, plus the CaptureFile loader, its
length/alternation tests, and the re-runnable scripts/ab-capture/capture.sh.

Observed and recorded in Captures/README.md "Routing observed":
- Micro800 is NOT UCMM under libplctag 2.6.0: it opens a Large Forward Open
  (path 20 02 24 01) and reads connected; use_connected_msg=0 is ignored.
- SLC500/MicroLogix/PLC-5 send Execute PCCC 0x4B unconnected and unwrapped;
  a configured path=1,0 never reaches the wire.
- Only Large FO 0x5B was observed; no 0x54 fallback occurred.
- LogixPccc is unreachable against ab_server (CIP 0x08); no fixture committed.
2026-10-07 15:50:00 -04:00
Joseph Doherty de14d354e6 fix(ab-transport): widen libplctag guard regex to catch aliases and static usings 2026-10-07 15:49:24 -04:00
Joseph Doherty 29f456c3ef test(ab-transport): guard libplctag confinement to its adapters (falsified by adding using libplctag to AbCipDriver.cs) 2026-10-07 15:47:52 -04:00