[abcip] AbCip — CIP multi-tag write packing #320

Merged
dohertj2 merged 1 commits from auto/abcip/1.4 into auto/driver-gaps 2026-04-25 13:16:51 -04:00
Owner

Summary

Adds AbCipMultiWritePlanner.cs that groups WriteRequests by device and classifies each as packable vs. bit-RMW.

  • Families with SupportsRequestPacking=true (ControlLogix / CompactLogix / GuardLogix): packable writes within a device dispatched concurrently via Task.WhenAll so libplctag's native scheduler can coalesce them onto one CIP Multi-Service Packet.
  • Micro800 (SupportsRequestPacking=false) keeps sequential per-tag writes.
  • BOOL-within-DINT writes still go through the existing per-parent RMW semaphore — excluded from packing because two concurrent RMWs on the same DINT could race.
  • Per-tag StatusCode fan-out preserves caller input order across Good / transport / type-mismatch / overflow / not-writable / unknown-tag / unknown-device.

The libplctag .NET wrapper does not expose CIP Multi-Service Packet construction at the per-Tag API surface, so this is the lighter coalescing approach (parallel writes under one device's scheduler) the issue brief permits.

Test plan

  • dotnet build src/ZB.MOM.WW.OtOpcUa.Driver.AbCip — clean (0 / 0)
  • dotnet test tests/ZB.MOM.WW.OtOpcUa.Driver.AbCip.Tests269 / 269 passed (5 new in AbCipMultiWritePackingTests)
  • Integration tests — skipped (live PLC required)

🤖 Auto-generated by the Mode-B execution loop. Closes #228.

Closes #228

## Summary Adds `AbCipMultiWritePlanner.cs` that groups `WriteRequest`s by device and classifies each as packable vs. bit-RMW. - Families with `SupportsRequestPacking=true` (ControlLogix / CompactLogix / GuardLogix): packable writes within a device dispatched concurrently via `Task.WhenAll` so libplctag's native scheduler can coalesce them onto one CIP Multi-Service Packet. - Micro800 (`SupportsRequestPacking=false`) keeps sequential per-tag writes. - BOOL-within-DINT writes still go through the existing per-parent RMW semaphore — excluded from packing because two concurrent RMWs on the same DINT could race. - Per-tag StatusCode fan-out preserves caller input order across Good / transport / type-mismatch / overflow / not-writable / unknown-tag / unknown-device. > The libplctag .NET wrapper does not expose CIP Multi-Service Packet construction at the per-Tag API surface, so this is the lighter coalescing approach (parallel writes under one device's scheduler) the issue brief permits. ## Test plan - [x] `dotnet build src/ZB.MOM.WW.OtOpcUa.Driver.AbCip` — clean (0 / 0) - [x] `dotnet test tests/ZB.MOM.WW.OtOpcUa.Driver.AbCip.Tests` — **269 / 269 passed** (5 new in `AbCipMultiWritePackingTests`) - [ ] Integration tests — skipped (live PLC required) 🤖 Auto-generated by the Mode-B execution loop. Closes #228. Closes #228
dohertj2 added 1 commit 2026-04-25 13:16:47 -04:00
Group writes by device through new AbCipMultiWritePlanner; for families that
support CIP request packing (ControlLogix / CompactLogix / GuardLogix) the
packable writes for one device are dispatched concurrently so libplctag's
native scheduler can coalesce them onto one Multi-Service Packet (0x0A).
Micro800 keeps SupportsRequestPacking=false and falls back to per-tag
sequential writes. BOOL-within-DINT writes are excluded from packing and
continue to go through the per-parent RMW semaphore so two concurrent bit
writes against the same DINT cannot lose one another's update.

The libplctag .NET wrapper does not expose a Multi-Service Packet construction
API at the per-Tag surface (each Tag is one CIP service), so this PR uses
client-side coalescing — concurrent Task.WhenAll dispatch per device — rather
than building raw CIP frames. The native libplctag scheduler does pack
concurrent same-connection writes when the family allows it, which gives the
round-trip reduction #228 calls for without ballooning the diff.

Per-tag StatusCodes preserve caller order across success, transport failure,
non-writable tags, unknown references, and unknown devices, including in
mixed concurrent batches.

Closes #228
dohertj2 merged commit 651d6c005c into auto/driver-gaps 2026-04-25 13:16:51 -04:00
dohertj2 deleted branch auto/abcip/1.4 2026-04-25 13:16:52 -04:00
Sign in to join this conversation.