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;
}
}