feat(focas): real FANUC 30i/31i-B PDU-v3 support (live-validated on a 31i-B)

First real FOCAS hardware contact (Makino Pro 5 / 31i-B @ 10.201.31.5). A full
v3 data-PDU capture corrected the initial diagnosis: the v3 block envelope is
identical to v1, so only specific payload structs / request math / one client
robustness gap were wrong — not "framing rewrites".

Fixes (all re-validated live through the fixed driver):
- version gate: accept inbound PDU {1,3}, keep emitting v1 (FocasWireProtocol).
- cnc_rdtimer: 8-byte {minute,msec} payload is little-endian (ParseTimer) — the
  only decode with an in-range msec field.
- pmc_rdpmcrng: request range widened to the data-type byte width
  (end = start + width - 1) so a Word/Long isn't truncated to 0 values
  (was spurious BadOutOfRange); decode extracted to ParsePmcRange.
- cnc_rdsvmeter: per-axis LOADELM is 8 bytes (not 12) and names come from the
  0x0089 block — ParseServoMeters fixes the misaligned 655360 garbage. Also the
  "hang" was NetworkStream.ReadAsync not aborting a stalled socket: ReadExactlyAsync
  now disposes the stream on cancellation so a stalled peer can't wedge a poll loop.
- cnc_rddynamic2: contract guard rejecting axis < 1 (driver poll already 1-based).
- FocasDriverProbe: run a real wire session (initiate + cnc_statinfo) instead of
  degrading to Ok=true "TCP reachability only" when FWLIB is absent — a bare TCP
  listener no longer reports HEALTHY.

cnc_rdparam (0x000e) is unsupported on this control — EW_FUNC across 14
request-framing variants x 4 known-present params; needs a reference FWLIB trace
or is restricted. Deferred (deployed config uses macros, not parameters).

Tests: FOCAS suite 234 green (+16), full solution builds 0 errors. Raw v3
captures checked in under tests/.../Fixtures/v3/. Capture tools under scripts/focas/.

Docs: docs/plans/2026-06-25-focas-pdu-v3-{30i-b-support,implementation-plan}.md,
docs/drivers/FOCAS.md, docs/v2/focas-version-matrix.md,
docs/deployments/wonder-app-vd03-makino-z-34184.md.
This commit is contained in:
Joseph Doherty
2026-06-25 16:41:42 -04:00
parent fd01448ac4
commit 5f0a52864c
36 changed files with 1567 additions and 177 deletions
+22
View File
@@ -143,3 +143,25 @@ The expensive half is Tier-C process isolation so that a crashing
`Fwlib64.dll` doesn't take the main OPC UA server down with it. See
[`docs/v2/implementation/focas-isolation-plan.md`](implementation/focas-isolation-plan.md)
for that plan (task #220).
## Real-hardware validation (first live FOCAS contact)
**2026-06-25 — FANUC 31i-B (Makino Pro 5), `10.201.31.5:8193`.** The first time the managed wire
client met real FOCAS hardware. The control answers **PDU version 3**; the 10-byte header framing and
response block envelope are byte-identical to v1 (only the version field differs). `cnc_sysinfo`
reports CncType 31, Series `G431`, 7 axes (X Y Z B C A A), MtType MM.
| Command family | v3 result | Notes |
| --- | --- | --- |
| `cnc_sysinfo`, `cnc_rdaxisname`, `cnc_rdspdlname` | ✅ validated | identity / axis / spindle names |
| `cnc_rddynamic2` (positions, feed, spindle, program/seq) | ✅ validated | 1-based axis iteration; program O-number reads via big-endian |
| `cnc_rdopmode`, `cnc_exeprgname2` | ✅ validated | mode + executing program |
| `cnc_rdmacro` | ✅ validated | deployed `MACRO:3901/3902` tags read Good |
| `cnc_rdtimer` | ✅ validated | 8-byte {minute, msec} payload is **little-endian** (unlike the big-endian envelope) |
| `pmc_rdpmcrng` | ✅ validated | request range must be widened to the data-type byte width (`end = start + width - 1`) |
| `cnc_rdsvmeter` | ✅ validated | per-axis LOADELM is **8 bytes**, not 12; names come from the 0x0089 block; load *scaling* unconfirmed |
| `cnc_rdalmmsg2` | ✅ validated | read a live active alarm (`#3080`) |
| `cnc_rdparam` | ❌ **unsupported** | `EW_FUNC` across 14 request-framing variants × 4 known-present params — likely wrong v3 command id (`0x000e`) or restricted on this control; needs a reference FWLIB trace |
Full finding + captured wire bytes + the fix per surface:
[`../plans/2026-06-25-focas-pdu-v3-30i-b-support.md`](../plans/2026-06-25-focas-pdu-v3-30i-b-support.md).