Files
lmxopcua/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip/NativeAbCipDevice.cs
T

56 lines
2.7 KiB
C#

using ZB.MOM.WW.OtOpcUa.Driver.Ab.Transport.Cip;
namespace ZB.MOM.WW.OtOpcUa.Driver.AbCip;
/// <summary>
/// Maps <see cref="AbCipTagCreateParams"/> onto the native transport's connection identity and
/// settings. Shared by the native tag runtime, enumerator and template reader so every handle on
/// one device leases the same pooled connection.
/// </summary>
internal static class NativeAbCipDevice
{
/// <summary>The EtherNet/IP default TCP port, used when no usable port was configured.</summary>
internal const int DefaultPort = 44818;
/// <summary>The <c>plc=</c> attribute of the Micro800 family profile.</summary>
private const string Micro800Attribute = "micro800";
/// <summary>The pool key: one CIP connection per <c>(host, port, cipPath, plcAttribute)</c>.</summary>
/// <param name="p">The tag creation parameters.</param>
/// <returns>The device key.</returns>
public static DeviceKey Key(AbCipTagCreateParams p) =>
new(p.Gateway, p.Port > 0 ? p.Port : DefaultPort, p.CipPath, p.LibplctagPlcAttribute);
/// <summary>The connection settings for the device <paramref name="p"/> addresses.</summary>
/// <param name="p">The tag creation parameters.</param>
/// <returns>The connection options.</returns>
public static ConnectionOptions Options(AbCipTagCreateParams p) => new()
{
Routing = RoutingFor(p),
Timeout = p.Timeout,
ConnectionSize = p.ConnectionSize,
AllowPacking = p.AllowPacking,
};
/// <summary>
/// How requests reach the controller's message router.
/// </summary>
/// <remarks>
/// Micro800 is <b>always</b> <see cref="CipRouting.Connected"/> with an empty route, even though its
/// family profile says <c>SupportsConnectedMessaging: false</c>: libplctag opens a Large Forward
/// Open with connection path <c>20 02 24 01</c> and reads connected (Captures/micro800-read-dint.hex,
/// Captures/README.md "Routing observed"; ruling R12-1 — the capture beats the profile flag).
/// Every other family follows the profile: connected-capable ⇒ Forward Open; otherwise
/// Unconnected Send when a route is configured, bare SendRRData when it is not.
/// </remarks>
/// <param name="p">The tag creation parameters.</param>
/// <returns>The routing mode.</returns>
internal static CipRouting RoutingFor(AbCipTagCreateParams p)
{
if (string.Equals(p.LibplctagPlcAttribute, Micro800Attribute, StringComparison.OrdinalIgnoreCase))
return CipRouting.Connected;
if (p.UseConnectedMessaging) return CipRouting.Connected;
return string.IsNullOrWhiteSpace(p.CipPath) ? CipRouting.Direct : CipRouting.UnconnectedSend;
}
}