using MessagePack; namespace ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Shared.Contracts; /// /// First frame of every FOCAS Proxy -> Host connection. Advertises protocol major/minor /// and the per-process shared secret the Proxy passed to the Host at spawn time. Major /// mismatch is fatal; minor is advisory. /// [MessagePackObject] public sealed class Hello { public const int CurrentMajor = 1; public const int CurrentMinor = 0; [Key(0)] public int ProtocolMajor { get; set; } = CurrentMajor; [Key(1)] public int ProtocolMinor { get; set; } = CurrentMinor; [Key(2)] public string PeerName { get; set; } = string.Empty; /// /// Per-process shared secret verified on the Host side against the value passed by the /// supervisor at spawn time. Protects against a local attacker connecting to the pipe /// after authenticating via the pipe ACL. /// [Key(3)] public string SharedSecret { get; set; } = string.Empty; [Key(4)] public string[] Features { get; set; } = System.Array.Empty(); } [MessagePackObject] public sealed class HelloAck { [Key(0)] public int ProtocolMajor { get; set; } = Hello.CurrentMajor; [Key(1)] public int ProtocolMinor { get; set; } = Hello.CurrentMinor; /// True if the Host accepted the hello; false + filled if not. [Key(2)] public bool Accepted { get; set; } [Key(3)] public string? RejectReason { get; set; } [Key(4)] public string HostName { get; set; } = string.Empty; } [MessagePackObject] public sealed class Heartbeat { [Key(0)] public long MonotonicTicks { get; set; } } [MessagePackObject] public sealed class HeartbeatAck { [Key(0)] public long MonotonicTicks { get; set; } [Key(1)] public long HostUtcUnixMs { get; set; } } [MessagePackObject] public sealed class ErrorResponse { /// Stable symbolic code — e.g. InvalidAddress, SessionNotFound, Fwlib32Crashed. [Key(0)] public string Code { get; set; } = string.Empty; [Key(1)] public string Message { get; set; } = string.Empty; }