b66972b6f5
On a wire the native PCCC path is proven only for N-file reads/writes and one F8 read (ab_server). An absent transport key now resolves to Libplctag for every family; explicit Native still wins and still warns once per instance on PLC-5/LogixPccc. AdminUI dropdown, CLI help, evidence claims (PcccFileType, AbLegacy.md wire-evidence table, release note) corrected: S:0 (default probe) and B/T/C/R/S/L/ST/A/O/I are unverified natively. Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
58 lines
3.2 KiB
C#
58 lines
3.2 KiB
C#
using ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.PlcFamilies;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Driver.AbLegacy;
|
|
|
|
/// <summary>
|
|
/// The ONE place an AbLegacy driver's effective transport is decided from its configured
|
|
/// <see cref="AbLegacyDriverOptions.Transport"/>. The driver constructor, the Test Connect probe and the
|
|
/// CLI (through the driver) all resolve through here.
|
|
/// <para>An absent key means <see cref="Default"/> = <see cref="AbLegacyTransport.Libplctag"/> for EVERY
|
|
/// family (final review I3): on a wire the native PCCC path is proven only for N-file reads and writes
|
|
/// and one F8 read, so Native stays opt-in. An explicit value always wins (an operator choice). An
|
|
/// explicit Native on a PLC-5 / LogixPccc device is allowed but logs a once-per-instance Warning
|
|
/// (<see cref="NativeLimitedFamilies"/>).</para>
|
|
/// </summary>
|
|
public static class AbLegacyTransportResolver
|
|
{
|
|
/// <summary>Returns true for a family whose native transport support is limited.</summary>
|
|
/// <param name="family">The PLC family.</param>
|
|
/// <returns>True for PLC-5 and LogixPccc.</returns>
|
|
public static bool IsNativeLimited(AbLegacyPlcFamily family) =>
|
|
family is AbLegacyPlcFamily.Plc5 or AbLegacyPlcFamily.LogixPccc;
|
|
|
|
/// <summary>Returns the distinct native-limited families among <paramref name="devices"/>.</summary>
|
|
/// <param name="devices">The configured devices.</param>
|
|
/// <returns>The limited families present, in declaration order.</returns>
|
|
public static IReadOnlyList<AbLegacyPlcFamily> NativeLimitedFamilies(IEnumerable<AbLegacyDeviceOptions> devices)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(devices);
|
|
return [.. devices.Select(d => d.PlcFamily).Where(IsNativeLimited).Distinct()];
|
|
}
|
|
|
|
/// <summary>The transport an absent / null <c>transport</c> key selects (all families).</summary>
|
|
public const AbLegacyTransport Default = AbLegacyTransport.Libplctag;
|
|
|
|
/// <summary>Returns the effective transport: an explicit value always wins; null means <see cref="Default"/>.</summary>
|
|
/// <param name="configured">The configured transport, or null for "use the default".</param>
|
|
/// <returns>The transport the driver runs on.</returns>
|
|
public static AbLegacyTransport Resolve(AbLegacyTransport? configured) => configured ?? Default;
|
|
|
|
/// <summary>Returns the effective transport for <paramref name="options"/>.</summary>
|
|
/// <param name="options">The driver options.</param>
|
|
/// <returns>The transport the driver runs on.</returns>
|
|
public static AbLegacyTransport Resolve(AbLegacyDriverOptions options)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(options);
|
|
return Resolve(options.Transport);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Operator-facing description of the configured-vs-effective transport for the init log line:
|
|
/// <c>Libplctag (default)</c> when the key was absent, <c>Native (configured)</c> when explicit.
|
|
/// </summary>
|
|
/// <param name="configured">The configured transport, or null.</param>
|
|
/// <returns>A short description.</returns>
|
|
public static string Describe(AbLegacyTransport? configured) =>
|
|
configured is null ? $"{Resolve(configured)} (default)" : $"{configured} (configured)";
|
|
}
|