From af280af8427a69ad72b0b5d55e124a8a789075c5 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Tue, 16 Jun 2026 07:12:48 -0400 Subject: [PATCH] =?UTF-8?q?docs(phase5):=20correct=20FOCAS=20probe=20bindi?= =?UTF-8?q?ng=20=E2=80=94=20direct=20DllImport,=20not=20WireFocasClient=20?= =?UTF-8?q?(integration=20review)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/drivers/TestConnectProbes.md | 6 ++++-- docs/plans/2026-06-16-stillpending-phase-5-probes-design.md | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/drivers/TestConnectProbes.md b/docs/drivers/TestConnectProbes.md index 9d224a4b..c539f888 100644 --- a/docs/drivers/TestConnectProbes.md +++ b/docs/drivers/TestConnectProbes.md @@ -47,7 +47,7 @@ with a human-readable explanation rather than a false-green TCP-open tick. | **AbCip** | `libplctag` Tag `InitializeAsync` (EIP session + CIP Forward Open). A CIP-level error such as tag-not-found still proves the controller answered CIP → `Ok`. A session/ForwardOpen/connect error → handshake fail. | `"CIP session OK"` | `10.100.0.35:44818` (CIP sim) | | **AbLegacy** | Same `libplctag` `InitializeAsync` handshake as AbCip, PCCC protocol family. | `"CIP session OK"` (PCCC family) | Deferred — no PLC5/SLC sim | | **TwinCAT** | `AdsClient.Connect` + `ReadStateAsync`. See [degrade semantics](#twincat-degrade) below. | `"ADS state: {state}"` | Deferred — no ADS target | -| **FOCAS** | `cnc_allclibhndl3` via FWLIB P/Invoke (`Wire.WireFocasClient`). See [degrade semantics](#focas-degrade) below. | `"FOCAS handle OK"` | Deferred — no CNC + FWLIB | +| **FOCAS** | `cnc_allclibhndl3` via a direct `DllImport("fwlib32")` in the probe. See [degrade semantics](#focas-degrade) below. | `"FOCAS handle OK"` | Deferred — no CNC + FWLIB | | **Galaxy** | gRPC unary call to `GalaxyRepository.TestConnection` on the configured mxaccessgw endpoint. See [auth-rejection rule](#galaxy-auth-rejection) below. | `"gateway gRPC OK"` | `http://10.100.0.48:5120` (mxaccessgw) | **Historian.Wonderware** already performed a real handshake (`Hello` → `HelloAck`) @@ -86,7 +86,9 @@ managed AMS router cannot start): On a Windows host with the FANUC FWLIB shared library present: -- `cnc_allclibhndl3` is called via the existing `Wire.WireFocasClient` P/Invoke. +- `cnc_allclibhndl3` is called via a direct `DllImport("fwlib32")` declared in + the probe (the production `Wire.WireFocasClient` is a pure-managed FOCAS/2 TCP + client, not an FWLIB P/Invoke, so the probe carries its own native binding). A successful handle allocation → `Ok=true`, `"FOCAS handle OK"`. - A CNC-level rejection → handshake fail. diff --git a/docs/plans/2026-06-16-stillpending-phase-5-probes-design.md b/docs/plans/2026-06-16-stillpending-phase-5-probes-design.md index 42940277..c30a5df4 100644 --- a/docs/plans/2026-06-16-stillpending-phase-5-probes-design.md +++ b/docs/plans/2026-06-16-stillpending-phase-5-probes-design.md @@ -26,7 +26,8 @@ operator gets a false "connection OK" and only discovers the truth when the driv - TwinCAT: `AdsClient.Connect(netId, port)` + `ReadStateAsync` (`AdsTwinCATClient.cs:90,194`). - OpcUaClient: `DiscoveryClient.GetEndpointsAsync` (no session / cert / auth — `OpcUaClientDriver.cs:422`). - Galaxy: the `MxGateway.Client` gRPC channel + one lightweight unary call. - - FOCAS: `cnc_allclibhndl3` via the existing wire P/Invoke (`Wire.WireFocasClient`). + - FOCAS: `cnc_allclibhndl3` via a direct `DllImport("fwlib32")` in the probe (the production + `Wire.WireFocasClient` is pure-managed FOCAS/2 TCP, not an FWLIB P/Invoke). - **Probe dispatch** clamps the timeout to 1–60 s and passes a cancelled-on-timeout `ct` (`AdminOperationsActor.cs:284-291`). Probes MUST honour it and MUST NOT mutate state (read-only handshakes). - **A proven skip-gated E2E harness exists** (`DriverTestConnectE2eTests`) targeting the live Modbus sim with