a6ae4e22d1
Driver.Cli.Common-007 + Driver.Cli.Common-008 resolution.
Driver.Cli.Common-007 (High, Correctness):
0x80550000 is the canonical OPC UA spec value for BadSecurityPolicyRejected,
not BadDeviceFailure. The correct spec value for BadDeviceFailure is
0x808B0000 (verified against OPC Foundation Opc.Ua.StatusCodes;
corroborated locally by Driver.Galaxy.Runtime.StatusCodeMap and both
Wonderware historian quality mappers which all hand-pin the correct
value).
The bug was duplicated across six driver modules:
- FocasStatusMapper.BadDeviceFailure
- AbCipStatusMapper.BadDeviceFailure
- AbLegacyStatusMapper.BadDeviceFailure
- TwinCATStatusMapper.BadDeviceFailure
- ModbusDriver.StatusBadDeviceFailure
- S7Driver.StatusBadDeviceFailure
Plus the SnapshotFormatter shortlist that named 0x80550000 as
BadDeviceFailure, and three downstream Modbus tests that asserted
against the wrong value (so CI was blind).
This commit fixes all six native-mapper constants, the formatter
shortlist, and the three Modbus tests in one pass. Added a regression
guard to FormatStatus_does_not_apply_pre_fix_wrong_names that pins
0x80550000 never renders as BadDeviceFailure (mirroring the existing
-001 wrong-name guards).
Behavior change: OPC UA clients consuming the native drivers now see
the canonical BadDeviceFailure (0x808B0000) on device-fault paths
instead of the misnamed BadSecurityPolicyRejected (0x80550000). Wire-
level status semantics now match operator-facing CLI labels.
Driver.Cli.Common-008 (Low, Testing):
Deleted the redundant FormatStatus_names_native_driver_emitted_codes
Theory — its five InlineData rows were already covered by the
well-known Theory in the same commit (5a9c459), and used a weaker
ShouldContain vs the well-known Theory's ShouldBe (exact match).
Verification:
- Driver.Cli.Common.Tests: 43/43 pass (was 48 after the -008 deletion).
- Driver.Modbus.Tests: 263/263 pass.
- Driver.AbCip.Tests: 262/262.
- Driver.AbLegacy.Tests: 157/157.
- Driver.FOCAS.Tests: 178/178.
- Driver.S7.Tests: 112/112.
- Driver.TwinCAT.Tests: 131/131.
Total: 1146 tests across the affected modules, all green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
83 lines
4.8 KiB
C#
83 lines
4.8 KiB
C#
namespace ZB.MOM.WW.OtOpcUa.Driver.TwinCAT;
|
||
|
||
/// <summary>
|
||
/// Maps AMS / ADS error codes to OPC UA StatusCodes. ADS error codes are taken from the
|
||
/// <c>AdsErrorCode</c> enum in <c>Beckhoff.TwinCAT.Ads</c> 7.x — numeric values are the
|
||
/// authoritative source (not the hex shorthand in older Beckhoff InfoSys pages, which has
|
||
/// known transcription errors). Key device-layer codes start at 0x0700 (1792 decimal).
|
||
/// </summary>
|
||
public static class TwinCATStatusMapper
|
||
{
|
||
public const uint Good = 0u;
|
||
|
||
// ---- OPC UA StatusCode constants ----
|
||
public const uint BadInternalError = 0x80020000u;
|
||
public const uint BadNodeIdUnknown = 0x80340000u;
|
||
public const uint BadNotWritable = 0x803B0000u;
|
||
public const uint BadOutOfRange = 0x803C0000u;
|
||
public const uint BadNotSupported = 0x803D0000u;
|
||
public const uint BadDeviceFailure = 0x808B0000u;
|
||
public const uint BadCommunicationError = 0x80050000u;
|
||
public const uint BadTimeout = 0x800A0000u;
|
||
public const uint BadTypeMismatch = 0x80730000u;
|
||
public const uint BadOutOfService = 0x80BE0000u;
|
||
public const uint BadInvalidState = 0x80350000u;
|
||
|
||
// ---- AdsErrorCode numeric values (confirmed from Beckhoff.TwinCAT.Ads 7.0.172) ----
|
||
|
||
/// <summary>
|
||
/// ADS <c>DeviceSymbolVersionInvalid</c> — error code 1809 (0x0711 decimal).
|
||
/// Raised by the runtime after a PLC program re-download: every symbol handle and
|
||
/// notification handle the driver holds is now stale. The driver treats this as an
|
||
/// <see cref="Core.Abstractions.IRediscoverable"/> trigger, not a connection error
|
||
/// (docs/v2/driver-specs.md §6, Driver.TwinCAT-013).
|
||
/// <para>
|
||
/// Note: legacy Beckhoff InfoSys documentation sometimes cites this as "0x0702"; that
|
||
/// is a transcription error — 0x0702 is <c>DeviceInvalidGroup</c> (1794). The SDK enum
|
||
/// value 1809 (0x0711) is authoritative (Driver.TwinCAT-011).
|
||
/// </para>
|
||
/// </summary>
|
||
public const uint AdsSymbolVersionChanged = 1809u; // DeviceSymbolVersionInvalid = 0x0711
|
||
|
||
/// <summary>True when <paramref name="adsError"/> is the symbol-version-changed code.</summary>
|
||
public static bool IsSymbolVersionChanged(uint adsError) => adsError == AdsSymbolVersionChanged;
|
||
|
||
/// <summary>
|
||
/// Map an AMS / ADS error code (uint cast from <c>AdsErrorCode</c> enum) to an OPC UA
|
||
/// StatusCode. 0 = success. Device-layer codes (0x0700–0x073F) cover the operations a
|
||
/// driver actually encounters during normal runtime.
|
||
/// </summary>
|
||
public static uint MapAdsError(uint adsError) => adsError switch
|
||
{
|
||
0 => Good,
|
||
|
||
// AMS router / transport errors
|
||
6 or 7 => BadCommunicationError, // TargetPortNotFound / TargetMachineNotFound
|
||
1285 or 1290 => BadCommunicationError, // RouterNotInitialized / RouterNotActive
|
||
|
||
// Device-layer codes (Beckhoff.TwinCAT.Ads AdsErrorCode enum, confirmed 7.0.172)
|
||
1792 => BadDeviceFailure, // DeviceError (generic device error)
|
||
1793 => BadNotSupported, // DeviceServiceNotSupported
|
||
1794 => BadOutOfRange, // DeviceInvalidGroup (ADS index-group error)
|
||
1795 => BadOutOfRange, // DeviceInvalidOffset (ADS index-offset error)
|
||
1796 => BadNotWritable, // DeviceInvalidAccess (write-access denied)
|
||
1797 => BadOutOfRange, // DeviceInvalidSize (size mismatch)
|
||
1798 => BadTypeMismatch, // DeviceInvalidData (data format mismatch)
|
||
1799 => BadOutOfService, // DeviceNotReady (PLC not running / in config)
|
||
1804 => BadNodeIdUnknown, // DeviceNotFound
|
||
1807 => BadDeviceFailure, // DeviceIncompatible (0x070E)
|
||
1808 => BadNodeIdUnknown, // DeviceSymbolNotFound (0x0710)
|
||
1809 => BadInvalidState, // DeviceSymbolVersionInvalid — rediscovery trigger
|
||
1810 => BadInvalidState, // DeviceInvalidState (PLC in Config mode, 0x0712)
|
||
1811 => BadNotSupported, // DeviceTransModeNotSupported (0x0713)
|
||
1812 => BadNodeIdUnknown, // DeviceNotifyHandleInvalid (stale handle, 0x0714)
|
||
1827 => BadNotWritable, // DeviceAccessDenied (0x0723)
|
||
1844 => BadOutOfRange, // DeviceOutOfRange (0x0734)
|
||
|
||
// Client-layer timeout
|
||
1861 => BadTimeout, // ClientSyncTimeOut (0x0745)
|
||
|
||
_ => BadCommunicationError,
|
||
};
|
||
}
|