using ZB.MOM.WW.OtOpcUa.Driver.Ab.Transport.Cip; namespace ZB.MOM.WW.OtOpcUa.Driver.AbCip; /// /// Maps 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. /// internal static class NativeAbCipDevice { /// The EtherNet/IP default TCP port, used when no usable port was configured. internal const int DefaultPort = 44818; /// The plc= attribute of the Micro800 family profile. private const string Micro800Attribute = "micro800"; /// The pool key: one CIP connection per (host, port, cipPath, plcAttribute). /// The tag creation parameters. /// The device key. public static DeviceKey Key(AbCipTagCreateParams p) => new(p.Gateway, p.Port > 0 ? p.Port : DefaultPort, p.CipPath, p.LibplctagPlcAttribute); /// The connection settings for the device addresses. /// The tag creation parameters. /// The connection options. public static ConnectionOptions Options(AbCipTagCreateParams p) => new() { Routing = RoutingFor(p), Timeout = p.Timeout, ConnectionSize = p.ConnectionSize, AllowPacking = p.AllowPacking, }; /// /// How requests reach the controller's message router. /// /// /// Micro800 is always with an empty route, even though its /// family profile says SupportsConnectedMessaging: false: libplctag opens a Large Forward /// Open with connection path 20 02 24 01 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. /// /// The tag creation parameters. /// The routing mode. 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; } }