/* ======================================================================== * Copyright (c) 2005-2025 The OPC Foundation, Inc. All rights reserved. * * OPC Foundation MIT License 1.00 * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * The complete license agreement can be found here: * http://opcfoundation.org/License/MIT/1.00/ * ======================================================================*/ using System; using System.Collections.Generic; using Microsoft.Extensions.Logging; using Opc.Ua.Bindings; using Opc.Ua.Security; using Opc.Ua.Security.Certificates; namespace Opc.Ua { /// /// Stores the configurable configuration information for a UA application. /// [DataType(Namespace = Namespaces.OpcUaConfig)] public partial class ApplicationConfiguration { /// /// The default constructor. /// public ApplicationConfiguration() { m_securityConfiguration = new SecurityConfiguration(); m_transportConfigurations = []; m_properties = []; m_extensionObjects = []; m_logger = m_telemetry.CreateLogger(); } /// /// The default constructor. /// public ApplicationConfiguration(ITelemetryContext telemetry) { m_securityConfiguration = new SecurityConfiguration(); m_transportConfigurations = []; m_properties = []; m_extensionObjects = []; m_telemetry = telemetry; m_logger = telemetry.CreateLogger(); } /// /// The constructor from a template. /// public ApplicationConfiguration(ApplicationConfiguration template) { ApplicationName = template.ApplicationName; ApplicationType = template.ApplicationType; ApplicationUri = template.ApplicationUri; DiscoveryServerConfiguration = template.DiscoveryServerConfiguration; m_securityConfiguration = template.m_securityConfiguration; m_transportConfigurations = template.m_transportConfigurations; ServerConfiguration = template.ServerConfiguration; ClientConfiguration = template.ClientConfiguration; DisableHiResClock = template.DisableHiResClock; // Share the same CertificateManager instance with the template so that // both configurations see the same trust list, rejected store, and // cached validators. CertificateManager = template.CertificateManager; TransportQuotas = template.TransportQuotas; TraceConfiguration = template.TraceConfiguration; m_extensions = template.m_extensions; m_extensionObjects = template.m_extensionObjects; SourceFilePath = template.SourceFilePath; m_properties = template.m_properties; m_telemetry = template.m_telemetry; m_logger = template.m_logger; } /// /// Gets an object used to synchronize access to the properties /// dictionary. /// public object PropertiesLock => m_properties; /// /// Gets a dictionary used to save state associated with the /// application. /// public IDictionary Properties => m_properties; /// /// Storage for decoded extensions of the application. /// Used by ParseExtension if no matching XmlElement is found. /// public IList ExtensionObjects => m_extensionObjects; /// /// A descriptive name for the application (not necessarily unique). /// [DataTypeField(Order = 0, IsRequired = true)] public string? ApplicationName { get; set; } /// /// A unique identifier for the application instance. /// [DataTypeField(Order = 1, IsRequired = true)] public string? ApplicationUri { get; set; } /// /// A unique identifier for the product. /// [DataTypeField(Order = 2)] public string? ProductUri { get; set; } /// /// The type of application. /// [DataTypeField(Order = 3, IsRequired = true)] public ApplicationType ApplicationType { get; set; } /// /// The security configuration for the application. /// [DataTypeField(Order = 4, StructureHandling = StructureHandling.Inline)] public SecurityConfiguration SecurityConfiguration { get => m_securityConfiguration; set => m_securityConfiguration = value ?? new SecurityConfiguration(); } /// /// The transport configuration for the application. /// [DataTypeField(Order = 5, StructureHandling = StructureHandling.Inline)] public ArrayOf TransportConfigurations { get => m_transportConfigurations; set => m_transportConfigurations = value; } /// /// The quotas that are used at the transport layer. /// [DataTypeField(Order = 6, StructureHandling = StructureHandling.Inline)] public TransportQuotas? TransportQuotas { get; set; } /// /// Additional configuration for server applications. /// [DataTypeField(Order = 7, StructureHandling = StructureHandling.Inline)] public ServerConfiguration? ServerConfiguration { get; set; } /// /// Additional configuration for client applications. /// [DataTypeField(Order = 8, StructureHandling = StructureHandling.Inline)] public ClientConfiguration? ClientConfiguration { get; set; } /// /// Additional configuration of the discovery server. /// [DataTypeField(Order = 9, StructureHandling = StructureHandling.Inline)] public DiscoveryServerConfiguration? DiscoveryServerConfiguration { get; set; } /// /// A bucket to store additional application specific configuration data. /// [DataTypeField(Order = 10)] public ArrayOf Extensions { get => m_extensions; set => m_extensions = value; } /// /// Configuration of the trace and information about log file /// [DataTypeField(Order = 11, StructureHandling = StructureHandling.Inline)] public TraceConfiguration? TraceConfiguration { get; set; } /// /// Disabling / enabling high resolution clock /// [DataTypeField(Order = 12)] public bool DisableHiResClock { get; set; } private readonly ITelemetryContext m_telemetry = null!; private readonly ILogger m_logger = null!; private SecurityConfiguration m_securityConfiguration; private ArrayOf m_transportConfigurations; private ArrayOf m_extensions; private readonly List m_extensionObjects; private readonly Dictionary m_properties; } /// /// Specifies various limits that apply to the transport or secure channel layers. /// [DataType(Namespace = Namespaces.OpcUaConfig)] public partial class TransportQuotas { /// /// The default constructor. /// public TransportQuotas() { // encoding limits MaxMessageSize = DefaultEncodingLimits.MaxMessageSize; MaxStringLength = DefaultEncodingLimits.MaxStringLength; MaxByteStringLength = DefaultEncodingLimits.MaxByteStringLength; MaxArrayLength = DefaultEncodingLimits.MaxArrayLength; MaxEncodingNestingLevels = DefaultEncodingLimits.MaxEncodingNestingLevels; MaxDecoderRecoveries = DefaultEncodingLimits.MaxDecoderRecoveries; // message limits MaxBufferSize = TcpMessageLimits.DefaultMaxBufferSize; OperationTimeout = TcpMessageLimits.DefaultOperationTimeout; ChannelLifetime = TcpMessageLimits.DefaultChannelLifetime; SecurityTokenLifetime = TcpMessageLimits.DefaultSecurityTokenLifeTime; } /// /// The default timeout to use when sending requests (in milliseconds). /// [DataTypeField(Order = 0)] public int OperationTimeout { get; set; } /// /// The maximum length of string encoded in a message body. /// [DataTypeField(Order = 1)] public int MaxStringLength { get; set; } /// /// The maximum length of a byte string encoded in a message body. /// [DataTypeField(Order = 2)] public int MaxByteStringLength { get; set; } /// /// The maximum length of an array encoded in a message body. /// [DataTypeField(Order = 3)] public int MaxArrayLength { get; set; } /// /// The maximum length of a message body. /// [DataTypeField(Order = 4)] public int MaxMessageSize { get; set; } /// /// The maximum size of the buffer to use when sending /// messages. /// [DataTypeField(Order = 5)] public int MaxBufferSize { get; set; } /// /// The maximum nesting level accepted while encoding /// or decoding objects. /// [DataTypeField(Order = 6)] public int MaxEncodingNestingLevels { get; set; } /// /// The number of times the decoder can recover from a /// decoder error of an IEncodeable before throwing a /// decoder error. /// [DataTypeField(Order = 7)] public int MaxDecoderRecoveries { get; set; } /// /// The lifetime of a secure channel (in milliseconds). /// [DataTypeField(Order = 8)] public int ChannelLifetime { get; set; } /// /// The lifetime of a security token (in milliseconds). /// [DataTypeField(Order = 9)] public int SecurityTokenLifetime { get; set; } } /// /// Specifies parameters used for tracing. /// [DataType(Namespace = Namespaces.OpcUaConfig)] public partial class TraceConfiguration { /// /// The output file used to log the trace information. /// [DataTypeField(Order = 0)] public string? OutputFilePath { get; set; } /// /// Whether the existing log file should be deleted when the /// application configuration is loaded. /// [DataTypeField(Order = 1)] public bool DeleteOnLoad { get; set; } /// /// The masks used to select what is written to the output /// Masks supported by the trace feature: /// - Do not output any messages -None = 0x0; /// - Output error messages - Error = 0x1; /// - Output informational messages - Information = 0x2; /// - Output stack traces - StackTrace = 0x4; /// - Output basic messages for service calls - Service = 0x8; /// - Output detailed messages for service calls - ServiceDetail = 0x10; /// - Output basic messages for each operation - Operation = 0x20; /// - Output detailed messages for each operation - OperationDetail = 0x40; /// - Output messages related to application initialization or shutdown - StartStop = 0x80; /// - Output messages related to a call to an external system - ExternalSystem = 0x100; /// - Output messages related to security. - Security = 0x200; /// [DataTypeField(Order = 2)] public int TraceMasks { get; set; } } /// /// Specifies the configuration information for a transport protocol /// /// /// Each application is allows to have one transport configure per protocol type. /// [DataType(Namespace = Namespaces.OpcUaConfig)] public partial class TransportConfiguration { /// /// The default constructor. /// public TransportConfiguration() { } /// /// Create TransportConfiguration with scheme and type /// public TransportConfiguration(string urlScheme, Type type) { UriScheme = urlScheme; TypeName = type.AssemblyQualifiedName!; } /// /// The URL prefix used by the application (http, opc.tcp, net.tpc, etc.). /// [DataTypeField(IsRequired = true, Order = 0)] public string UriScheme { get; set; } = string.Empty; /// /// The name of the class that defines the binding for the transport. /// /// This can be any instance of the System.ServiceModel.Channels.Binding class /// that implements these constructors: /// /// /// XxxBinding(EndpointDescription description, EndpointConfiguration configuration); /// XxxBinding(IList{EndpointDescription} descriptions, EndpointConfiguration configuration) /// XxxBinding(EndpointConfiguration configuration) /// /// [DataTypeField(IsRequired = true, Order = 1)] public string TypeName { get; set; } = string.Empty; } /// /// A class that defines a group of security policies supported by the server. /// [DataType(Namespace = Namespaces.OpcUaConfig)] public partial class ServerSecurityPolicy { /// /// The default constructor. /// public ServerSecurityPolicy() { SecurityMode = MessageSecurityMode.SignAndEncrypt; SecurityPolicyUri = SecurityPolicies.Basic256Sha256; } /// /// Obsolete version of CalculateSecurityLevel that does not take a logger. /// [Obsolete("Use CalculateSecurityLevel(MessageSecurityMode mode, string policyUri, ILogger logger) instead.")] public static byte CalculateSecurityLevel( MessageSecurityMode mode, string policyUri) { return SecuredApplication.CalculateSecurityLevel(mode, policyUri); } /// /// Calculates the security level, given the security mode and policy /// Invalid and none is discouraged /// Just signing is always weaker than any use of encryption /// public static byte CalculateSecurityLevel( MessageSecurityMode mode, string policyUri, ILogger logger) { return SecuredApplication.CalculateSecurityLevel(mode, policyUri, logger); } /// /// Specifies whether the messages are signed and encrypted /// or simply signed /// [DataTypeField(Order = 0)] public MessageSecurityMode SecurityMode { get; set; } /// /// The security policy to use. /// [DataTypeField(Order = 1)] public string SecurityPolicyUri { get; set; } = SecurityPolicies.Basic256Sha256; } /// /// The security configuration for the application. /// [DataType(Namespace = Namespaces.OpcUaConfig)] public partial class SecurityConfiguration { /// /// The default constructor. /// public SecurityConfiguration() { m_applicationCertificates = []; m_trustedIssuerCertificates = new CertificateTrustList(); m_trustedPeerCertificates = new CertificateTrustList(); MinimumCertificateKeySize = CertificateFactory.DefaultKeySize; } /// /// The application instance certificate. /// Kept for backward compatibility with configuration files which only /// support RSA certificates. /// This certificate must contain the application uri. /// For servers, URLs for each supported protocol must also be present. /// public CertificateIdentifier? ApplicationCertificate { get { if (m_applicationCertificates.Count > 0) { return m_applicationCertificates[0]; } return null; } set { var list = new List(m_applicationCertificates.ToArray() ?? []); if (list.Count > 0) { if (value == null) { list.RemoveAt(0); } else { list[0] = value; } } else if (value != null) { list.Add(value); } m_applicationCertificates = list.ToArrayOf(); SupportedSecurityPolicies = BuildSupportedSecurityPolicies(); if (m_applicationCertificates.Count > 0) { m_applicationCertificates[0].CertificateType = ObjectTypeIds.RsaSha256ApplicationCertificateType; } IsDeprecatedConfiguration = true; } } /// /// This private property exists solely to control serialization of the legacy single /// certificate element. It is emitted only when the configuration was marked deprecated. /// [DataTypeField(Order = 0, StructureHandling = StructureHandling.Inline, Name = "ApplicationCertificate")] private CertificateIdentifier? ApplicationCertificateLegacy { get => IsDeprecatedConfiguration ? ApplicationCertificate : null; set { if (value != null) { ApplicationCertificate = value; } } } /// /// The application instance certificates in use for the application. /// [DataTypeField(Order = 1, StructureHandling = StructureHandling.Inline)] public ArrayOf ApplicationCertificates { get => m_applicationCertificates; set { // When the element is absent from XML, the decoder passes default (IsNull). // Preserve existing state (e.g., set by the legacy ApplicationCertificate). if (value.IsNull) { return; } if (value.IsEmpty) { m_applicationCertificates = []; return; } // If both legacy () and modern () elements // are present during deserialization (as a consequence of previous serialization that included both unintentionally), // prefer the modern representation and clear the // deprecated flag when we process the collection below. var newCertificates = new List(value.ToArray() ?? []); // Remove unsupported certificate types for (int i = newCertificates.Count - 1; i >= 0; i--) { if (!Utils.IsSupportedCertificateType(newCertificates[i].CertificateType)) { // TODO: Log when ITelemetry instance is available newCertificates.RemoveAt(i); } } // Remove any duplicates based on thumbprint for (int i = 0; i < newCertificates.Count; i++) { for (int j = newCertificates.Count - 1; j > i; j--) { bool isDuplicate = false; if (!string.IsNullOrEmpty(newCertificates[i].Thumbprint) && !string.IsNullOrEmpty(newCertificates[j].Thumbprint)) { isDuplicate = newCertificates[i].Thumbprint!.Equals( newCertificates[j].Thumbprint, StringComparison.OrdinalIgnoreCase); } if (isDuplicate) { newCertificates.RemoveAt(j); } } } m_applicationCertificates = newCertificates.ToArrayOf(); // Presence of the modern collection takes precedence over legacy; clear the flag so // hybrid configurations are treated as modern. IsDeprecatedConfiguration = false; SupportedSecurityPolicies = BuildSupportedSecurityPolicies(); } } /// /// The store containing any additional issuer certificates. /// [DataTypeField(IsRequired = true, Order = 2, StructureHandling = StructureHandling.Inline)] public CertificateTrustList TrustedIssuerCertificates { get => m_trustedIssuerCertificates; set => m_trustedIssuerCertificates = value ?? new CertificateTrustList(); } /// /// The trusted certificate store. /// [DataTypeField(IsRequired = true, Order = 3, StructureHandling = StructureHandling.Inline)] public CertificateTrustList TrustedPeerCertificates { get => m_trustedPeerCertificates; set => m_trustedPeerCertificates = value ?? new CertificateTrustList(); } /// /// The length of nonce in the CreateSession service. /// [DataTypeField(Order = 4)] public int NonceLength { get; set; } = 32; /// /// A store where invalid certificates can be placed for later review /// by the administrator. /// [DataTypeField(Order = 5, StructureHandling = StructureHandling.Inline)] public CertificateStoreIdentifier? RejectedCertificateStore { get; set; } /// /// Gets or sets a value indicating how many certificates are kept /// in the rejected store before the oldest is removed. /// /// /// This value can be set by applications. /// The number of certificates to keep in the rejected store before /// it is updated. /// to keep all rejected certificates. /// A negative number to keep no history. /// Default is 5. /// [DataTypeField(Order = 6)] public int MaxRejectedCertificates { get; set; } = 5; /// /// Gets or sets a value indicating whether untrusted certificates /// should be automatically accepted. /// /// /// This flag can be set to by servers that allow anonymous clients /// or use user credentials for authentication. /// It can be set by clients that connect to URLs specified in /// configuration rather than with user entry. /// [DataTypeField(Order = 7)] public bool AutoAcceptUntrustedCertificates { get; set; } /// /// Gets or sets a directory which contains files representing /// users roles. /// [DataTypeField(Order = 8)] public string? UserRoleDirectory { get; set; } /// /// This flag can be set to false by servers that accept SHA-1 /// signed certificates. /// [DataTypeField(Order = 9)] public bool RejectSHA1SignedCertificates { get; set; } = true; /// /// Gets or sets a value indicating whether certificates with /// unavailable revocation lists are not accepted. /// This flag can be set to true by servers that must have a /// revocation list for each CA (even if empty). /// [DataTypeField(Order = 10)] public bool RejectUnknownRevocationStatus { get; set; } /// /// Gets or sets a value indicating which minimum certificate /// key strength is accepted. /// The value is ignored for certificates with a ECDSA signature. /// This value can be set to 1024, 2048 or 4096 for servers /// [DataTypeField(Order = 11)] public ushort MinimumCertificateKeySize { get; set; } /// /// Gets or sets a value indicating whether the Validator skips /// the full chain validation for already validated or accepted /// certificates. /// This flag can be set to true for applications. /// [DataTypeField(Order = 12)] public bool UseValidatedCertificates { get; set; } /// /// Gets or sets a value indicating whether the application cert /// should be copied to the trusted store. /// It is useful for client/server applications running on the /// same host and sharing the cert store to autotrust. /// [DataTypeField(Order = 13)] public bool AddAppCertToTrustedStore { get; set; } = true; /// /// Gets or sets a value indicating whether the application /// should send the complete certificate chain. /// If set to true the complete certificate chain will be sent /// for CA signed certificates. /// [DataTypeField(Order = 14)] public bool SendCertificateChain { get; set; } = true; /// /// The store containing additional user issuer certificates. /// [DataTypeField(Order = 15, StructureHandling = StructureHandling.Inline)] public CertificateTrustList? UserIssuerCertificates { get => m_userIssuerCertificates; set => m_userIssuerCertificates = value; } /// /// The store containing trusted user certificates. /// [DataTypeField(Order = 16, StructureHandling = StructureHandling.Inline)] public CertificateTrustList? TrustedUserCertificates { get => m_trustedUserCertificates; set => m_trustedUserCertificates = value; } /// /// The store containing additional Https issuer certificates. /// [DataTypeField(Order = 17, StructureHandling = StructureHandling.Inline)] public CertificateTrustList? HttpsIssuerCertificates { get => m_httpsIssuerCertificates; set => m_httpsIssuerCertificates = value; } /// /// The store containing trusted Https certificates. /// [DataTypeField(Order = 18, StructureHandling = StructureHandling.Inline)] public CertificateTrustList? TrustedHttpsCertificates { get => m_trustedHttpsCertificates; set => m_trustedHttpsCertificates = value; } /// /// Gets or sets a value indicating whether the server nonce /// validation errors should be suppressed. /// Allows client interoperability with legacy servers which /// do not comply with the specification for nonce usage. /// If set to true the server nonce validation errors are suppressed. /// Please set this flag to true only in close and secured /// networks since it can cause security vulnerabilities. /// [DataTypeField(Order = 19)] public bool SuppressNonceValidationErrors { get; set; } /// /// The type of Configuration (deprecated or not) /// public bool IsDeprecatedConfiguration { get; set; } private ArrayOf m_applicationCertificates; private CertificateTrustList m_trustedIssuerCertificates; private CertificateTrustList m_trustedPeerCertificates; private CertificateTrustList? m_httpsIssuerCertificates; private CertificateTrustList? m_trustedHttpsCertificates; private CertificateTrustList? m_userIssuerCertificates; private CertificateTrustList? m_trustedUserCertificates; } /// /// A class that defines a group of sampling rates supported by the server. /// [DataType(Namespace = Namespaces.OpcUaConfig)] public partial class SamplingRateGroup { /// /// The default constructor. /// public SamplingRateGroup() { } /// /// Creates a group with the specified settings. /// /// The start. /// The increment. /// The count. public SamplingRateGroup(int start, int increment, int count) { Start = start; Increment = increment; Count = count; } /// /// The first sampling rate in the group (in milliseconds). /// /// The first sampling rate in the group (in milliseconds). [DataTypeField(Order = 0)] public double Start { get; set; } = 1000; /// /// The increment between sampling rates in the group (in milliseconds). /// /// The increment. /// /// An increment of 0 means the group only contains one sampling rate equal to the start. /// [DataTypeField(Order = 1)] public double Increment { get; set; } /// /// The number of sampling rates in the group. /// /// The count. /// /// A count of 0 means there is no limit. /// [DataTypeField(Order = 2)] public int Count { get; set; } } /// /// Specifies the configuration for a server application. /// [DataType(Namespace = Namespaces.OpcUaConfig)] public partial class ServerBaseConfiguration { /// /// The default constructor. /// public ServerBaseConfiguration() { m_baseAddresses = []; m_alternateBaseAddresses = []; m_securityPolicies = []; } /// /// Remove unsupported security policies and expand wild cards. /// internal void ValidateSecurityPolicies() { string[] supportedPolicies = Ua.SecurityPolicies.GetDisplayNames(); var newPolicies = new List(); foreach (ServerSecurityPolicy securityPolicy in m_securityPolicies) { if (string.IsNullOrWhiteSpace(securityPolicy.SecurityPolicyUri)) { // add wild card policies foreach (string policyUri in Ua.SecurityPolicies.GetDefaultUris()) { var newPolicy = new ServerSecurityPolicy { SecurityMode = securityPolicy.SecurityMode, SecurityPolicyUri = policyUri }; if (newPolicies.Find(s => s.SecurityMode == newPolicy.SecurityMode && string.Equals( s.SecurityPolicyUri, newPolicy.SecurityPolicyUri, StringComparison.Ordinal) ) == null) { newPolicies.Add(newPolicy); } } } else { for (int i = 0; i < supportedPolicies.Length; i++) { if (securityPolicy.SecurityPolicyUri .Contains(supportedPolicies[i], StringComparison.Ordinal)) { if (newPolicies.Find(s => s.SecurityMode == securityPolicy.SecurityMode && string.Equals( s.SecurityPolicyUri, securityPolicy.SecurityPolicyUri, StringComparison.Ordinal) ) == null) { newPolicies.Add(securityPolicy); } break; } } } } m_securityPolicies = newPolicies.ToArrayOf(); } /// /// The base addresses for the server. /// /// The base addresses. /// /// The actually endpoints are constructed from the security policies. /// On one base address per supported transport protocol is allowed. /// [DataTypeField(Order = 0)] public ArrayOf BaseAddresses { get => m_baseAddresses; set => m_baseAddresses = value; } /// /// Gets or sets the alternate base addresses. /// /// The alternate base addresses. /// /// These addresses are used to specify alternate paths to ther via firewalls, proxies /// or similar network infrastructure. If these paths are specified in the configuration /// file then the server will use the domain of the URL used by the client to determine /// which, if any, or the alternate addresses to use instead of the primary addresses. /// [DataTypeField(Order = 1)] public ArrayOf AlternateBaseAddresses { get => m_alternateBaseAddresses; set => m_alternateBaseAddresses = value; } /// /// The security policies supported by the server. /// /// The security policies. /// /// An endpoint description is created for each combination of base address and security policy. /// [DataTypeField(Order = 2, StructureHandling = StructureHandling.Inline)] public ArrayOf SecurityPolicies { get => m_securityPolicies; set => m_securityPolicies = value; } /// /// The minimum number of threads assigned to processing requests. /// /// The minimum request thread count. [DataTypeField(Order = 3)] public int MinRequestThreadCount { get; set; } = 10; /// /// The maximum number of threads assigned to processing requests. /// /// The maximum request thread count. [DataTypeField(Order = 4)] public int MaxRequestThreadCount { get; set; } = 100; /// /// The maximum number of requests that will be queued waiting for a thread. /// /// The maximum queued request count. [DataTypeField(Order = 5)] public int MaxQueuedRequestCount { get; set; } = 200; private ArrayOf m_baseAddresses; private ArrayOf m_alternateBaseAddresses; private ArrayOf m_securityPolicies; } /// /// Specifies the configuration for a server application. /// [DataType(Namespace = Namespaces.OpcUaConfig)] public partial class ServerConfiguration : ServerBaseConfiguration { /// /// The default constructor. /// public ServerConfiguration() { m_userTokenPolicies = []; AvailableSamplingRates = []; // https://opcfoundation-onlineapplications.org/profilereporting/ for list of available profiles m_serverProfileArray = ["http://opcfoundation.org/UA-Profile/Server/StandardUA2017"]; m_serverCapabilities = ["DA"]; m_supportedPrivateKeyFormats = ["PFX", "PEM"]; } /// /// The user tokens accepted by the server. /// /// The user token policies. [DataTypeField(Order = 0, StructureHandling = StructureHandling.Inline)] public ArrayOf UserTokenPolicies { get => m_userTokenPolicies; set => m_userTokenPolicies = value; } /// /// Whether diagnostics are enabled. /// /// true if diagnostic is enabled; otherwise, false. [DataTypeField(Order = 1)] public bool DiagnosticsEnabled { get; set; } /// /// The maximum number of open sessions. /// /// The maximum session count. [DataTypeField(Order = 2)] public int MaxSessionCount { get; set; } = 100; /// /// The maximum number of supported secure channels. /// /// The channel lifetime. [DataTypeField(Order = 3)] public int MaxChannelCount { get; set; } = 1000; /// /// That minimum period of that a session is allowed to remain /// open without communication from the client (in milliseconds). /// /// The minimum session timeout. [DataTypeField(Order = 4)] public int MinSessionTimeout { get; set; } = 10000; /// /// That maximum period of that a session is allowed to remain /// open without communication from the client (in milliseconds). /// /// The maximum session timeout. [DataTypeField(Order = 5)] public int MaxSessionTimeout { get; set; } = 3600000; /// /// The maximum number of continuation points used for /// Browse/BrowseNext operations. /// /// The maximum number of continuation points used for Browse/BrowseNext operations [DataTypeField(Order = 6)] public int MaxBrowseContinuationPoints { get; set; } = 10; /// /// The maximum number of continuation points used for /// Query/QueryNext operations. /// /// The maximum number of query continuation points. [DataTypeField(Order = 7)] public int MaxQueryContinuationPoints { get; set; } = 10; /// /// The maximum number of continuation points used for HistoryRead operations. /// /// The maximum number of history continuation points. [DataTypeField(Order = 8)] public int MaxHistoryContinuationPoints { get; set; } = 100; /// /// The maximum age of an incoming request (old requests are rejected) (in milliseconds). /// /// The maximum age of an incoming request. [DataTypeField(Order = 9)] public int MaxRequestAge { get; set; } = 600000; /// /// The minimum publishing interval supported by the server (in milliseconds). /// /// The minimum publishing interval. [DataTypeField(Order = 10)] public int MinPublishingInterval { get; set; } = 100; /// /// The maximum publishing interval supported by the server (in milliseconds). /// /// The maximum publishing interval. [DataTypeField(Order = 11)] public int MaxPublishingInterval { get; set; } = 3600000; /// /// The minimum difference between supported publishing interval (in milliseconds). /// /// The publishing resolution. [DataTypeField(Order = 12)] public int PublishingResolution { get; set; } = 100; /// /// How long the subscriptions will remain open without a publish from the client. /// /// The maximum subscription lifetime. [DataTypeField(Order = 13)] public int MaxSubscriptionLifetime { get; set; } = 3600000; /// /// The maximum number of messages saved in the queue for each subscription. /// /// The maximum size of the message queue. [DataTypeField(Order = 14)] public int MaxMessageQueueSize { get; set; } = 10; /// /// The maximum number of notificates saved in the queue for each monitored item. /// /// The maximum size of the notification queue. [DataTypeField(Order = 15)] public int MaxNotificationQueueSize { get; set; } = 100; /// /// The maximum number of notifications per publish. /// /// The maximum number of notifications per publish. [DataTypeField(Order = 16)] public int MaxNotificationsPerPublish { get; set; } = 100; /// /// The minimum sampling interval for metadata. /// /// The minimum sampling interval for metadata. [DataTypeField(Order = 17)] public int MinMetadataSamplingInterval { get; set; } = 1000; /// /// The available sampling rates. /// /// The available sampling rates. [DataTypeField(Order = 18, StructureHandling = StructureHandling.Inline)] public ArrayOf AvailableSamplingRates { get; set; } /// /// The endpoint description for the registration endpoint. /// /// The registration endpoint. [DataTypeField(Order = 19, StructureHandling = StructureHandling.Inline)] public EndpointDescription? RegistrationEndpoint { get; set; } /// /// The maximum time between registration attempts (in milliseconds). /// /// The maximum time between registration attempts (in milliseconds). [DataTypeField(Order = 20)] public int MaxRegistrationInterval { get; set; } = 30000; /// /// The path to the file containing nodes persisted by the core node manager. /// /// The path to the file containing nodes persisted by the core node manager. [DataTypeField(Order = 21)] public string? NodeManagerSaveFile { get; set; } /// /// The minimum lifetime for a subscription (in milliseconds). /// /// The minimum lifetime for a subscription. [DataTypeField(Order = 22)] public int MinSubscriptionLifetime { get; set; } = 10000; /// /// The max publish request count. /// /// The max publish request count. [DataTypeField(Order = 23)] public int MaxPublishRequestCount { get; set; } = 20; /// /// The max subscription count. /// /// The max subscription count. [DataTypeField(Order = 24)] public int MaxSubscriptionCount { get; set; } = 100; /// /// The max size of the event queue. /// /// The max size of the event queue. [DataTypeField(Order = 25)] public int MaxEventQueueSize { get; set; } = 10000; /// /// The server profile array. /// /// The array of server profiles. [DataTypeField(Order = 26)] public ArrayOf ServerProfileArray { get => m_serverProfileArray; set => m_serverProfileArray = value; } /// /// The server shutdown delay. /// /// The number of seconds to delay the shutdown if a client is connected. [DataTypeField(Order = 27)] public int ShutdownDelay { get; set; } = 5; /// /// The server capabilities. /// The latest set of server capabilities is listed /// here. /// /// The array of server capabilites. [DataTypeField(Order = 28)] public ArrayOf ServerCapabilities { get => m_serverCapabilities; set => m_serverCapabilities = value; } /// /// Gets or sets the supported private key format. /// /// The array of server profiles. [DataTypeField(Order = 29)] public ArrayOf SupportedPrivateKeyFormats { get => m_supportedPrivateKeyFormats; set => m_supportedPrivateKeyFormats = value; } /// /// Gets or sets the max size of the trust list. /// [DataTypeField(Order = 30)] public int MaxTrustListSize { get; set; } /// /// Gets or sets if multicast DNS is enabled. /// [DataTypeField(Order = 31)] public bool MultiCastDnsEnabled { get; set; } /// /// Gets or sets reverse connect server configuration. /// [DataTypeField(Order = 32, StructureHandling = StructureHandling.Inline)] public ReverseConnectServerConfiguration? ReverseConnect { get; set; } /// /// Gets or sets the operation limits of the OPC UA Server. /// [DataTypeField(Order = 33, StructureHandling = StructureHandling.Inline)] public OperationLimits OperationLimits { get; set; } = new(); /// /// Whether auditing is enabled. /// /// true if auditing is enabled; otherwise, false. [DataTypeField(Order = 34)] public bool AuditingEnabled { get; set; } /// /// Whether mTLS is required/enforced by the HttpsTransportListener /// /// true if mutual TLS is enabled; otherwise, false. [DataTypeField(Order = 35)] public bool HttpsMutualTls { get; set; } = true; /// /// Enable / disable support for durable subscriptions /// /// true if durable subscriptions are enabled; otherwise, false. [DataTypeField(Order = 36)] public bool DurableSubscriptionsEnabled { get; set; } /// /// The maximum number of notifications saved in the durable queue for each monitored item. /// /// The maximum size of the durable notification queue. [DataTypeField(Order = 37)] public int MaxDurableNotificationQueueSize { get; set; } = 200000; /// /// The max size of the durable event queue. /// /// The max size of the durable event queue. [DataTypeField(Order = 38)] public int MaxDurableEventQueueSize { get; set; } = 200000; /// /// How long the durable subscriptions will remain open without a publish from the client. /// /// The maximum durable subscription lifetime. [DataTypeField(Order = 39)] public int MaxDurableSubscriptionLifetimeInHours { get; set; } = 10; private ArrayOf m_userTokenPolicies; private ArrayOf m_serverProfileArray; private ArrayOf m_serverCapabilities; private ArrayOf m_supportedPrivateKeyFormats; } /// /// Stores the configuration of the reverse connections. /// [DataType(Namespace = Namespaces.OpcUaConfig)] public partial class ReverseConnectServerConfiguration { /// /// The default constructor. /// public ReverseConnectServerConfiguration() { } /// /// A collection of reverse connect clients. /// [DataTypeField(Order = 0, StructureHandling = StructureHandling.Inline)] public ArrayOf Clients { get; set; } /// /// The interval after which a new reverse connection is attempted. /// [DataTypeField(Order = 1)] public int ConnectInterval { get; set; } = 15000; /// /// The default timeout to wait for a response to a reverse connection. /// [DataTypeField(Order = 2)] public int ConnectTimeout { get; set; } = 30000; /// /// The timeout to wait to establish a new reverse /// connection after a rejected attempt. /// [DataTypeField(Order = 3)] public int RejectTimeout { get; set; } = 60000; } /// /// Stores the operation limits of a OPC UA Server. /// [DataType(Namespace = Namespaces.OpcUaConfig)] public partial class OperationLimits { /// /// The default constructor. /// public OperationLimits() { } /// /// Indicates the maximum size of the nodesToRead array when a Client calls the Read Service. /// [DataTypeField(Order = 0)] public uint MaxNodesPerRead { get; set; } /// /// Indicates the maximum size of the nodesToRead array when a Client calls the HistoryRead /// Service using the historyReadDetails RAW, PROCESSED, MODIFIED or ATTIME. /// [DataTypeField(Order = 1)] public uint MaxNodesPerHistoryReadData { get; set; } /// /// Indicates the maximum size of the nodesToRead array when a Client calls the HistoryRead /// Service using the historyReadDetails EVENTS. /// [DataTypeField(Order = 2)] public uint MaxNodesPerHistoryReadEvents { get; set; } /// /// Indicates the maximum size of the nodesToWrite array when a Client calls the Write Service. /// [DataTypeField(Order = 3)] public uint MaxNodesPerWrite { get; set; } /// /// Indicates the maximum size of the historyUpdateDetails array supported by the Server /// when a Client calls the HistoryUpdate Service. /// [DataTypeField(Order = 4)] public uint MaxNodesPerHistoryUpdateData { get; set; } /// /// Indicates the maximum size of the historyUpdateDetails array /// when a Client calls the HistoryUpdate Service. /// [DataTypeField(Order = 5)] public uint MaxNodesPerHistoryUpdateEvents { get; set; } /// /// Indicates the maximum size of the methodsToCall array when a Client calls the Call Service. /// [DataTypeField(Order = 6)] public uint MaxNodesPerMethodCall { get; set; } /// /// Indicates the maximum size of the nodesToBrowse array when calling the Browse Service /// or the continuationPoints array when a Client calls the BrowseNext Service. /// [DataTypeField(Order = 7)] public uint MaxNodesPerBrowse { get; set; } /// /// Indicates the maximum size of the nodesToRegister array when a Client calls the RegisterNodes Service /// and the maximum size of the nodesToUnregister when calling the UnregisterNodes Service. /// [DataTypeField(Order = 8)] public uint MaxNodesPerRegisterNodes { get; set; } /// /// Indicates the maximum size of the browsePaths array when a Client calls the TranslateBrowsePathsToNodeIds Service. /// [DataTypeField(Order = 9)] public uint MaxNodesPerTranslateBrowsePathsToNodeIds { get; set; } /// /// Indicates the maximum size of the nodesToAdd array when a Client calls the AddNodes Service, /// the maximum size of the referencesToAdd array when a Client calls the AddReferences Service, /// the maximum size of the nodesToDelete array when a Client calls the DeleteNodes Service, /// and the maximum size of the referencesToDelete array when a Client calls the DeleteReferences Service. /// [DataTypeField(Order = 10)] public uint MaxNodesPerNodeManagement { get; set; } /// /// Indicates the maximum size of the itemsToCreate array when a Client calls the CreateMonitoredItems Service, /// the maximum size of the itemsToModify array when a Client calls the ModifyMonitoredItems Service, /// the maximum size of the monitoredItemIds array when a Client calls the SetMonitoringMode Service or the DeleteMonitoredItems Service, /// the maximum size of the sum of the linksToAdd and linksToRemove arrays when a Client calls the SetTriggering Service. /// [DataTypeField(Order = 11)] public uint MaxMonitoredItemsPerCall { get; set; } } /// /// Stores the configuration of the reverse connections. /// [DataType(Namespace = Namespaces.OpcUaConfig)] public partial class ReverseConnectClient { /// /// The default constructor. /// public ReverseConnectClient() { } /// /// The endpoint Url of the reverse connect client endpoint. /// [DataTypeField(Order = 0)] public string? EndpointUrl { get; set; } /// /// The timeout to wait for a response to a reverse connection. /// Overrides the default reverse connection setting. /// [DataTypeField(Order = 1)] public int Timeout { get; set; } /// /// The maximum count of active reverse connect sessions. /// 0 or undefined means unlimited number of sessions. /// 1 means a single connection is created at a time. /// n disables reverse hello once the total number of sessions /// in the server reaches n. /// [DataTypeField(Order = 2)] public int MaxSessionCount { get; set; } /// /// Specifies whether the sending of reverse connect attempts is enabled. /// [DataTypeField(Order = 3, DefaultValueHandling = DefaultValueHandling.Emit)] public bool Enabled { get; set; } = true; } /// /// The configuration for a client application. /// [DataType(Namespace = Namespaces.OpcUaConfig)] public partial class ClientConfiguration { /// /// The default constructor. /// public ClientConfiguration() { m_wellKnownDiscoveryUrls = []; m_discoveryServers = []; } /// /// The default session timeout (in milliseconds). /// /// The default session timeout. [DataTypeField(Order = 0)] public int DefaultSessionTimeout { get; set; } = 60000; /// /// The well known URLs for the local discovery servers. /// /// The well known discovery URLs. [DataTypeField(Order = 1)] public ArrayOf WellKnownDiscoveryUrls { get => m_wellKnownDiscoveryUrls; set => m_wellKnownDiscoveryUrls = value; } /// /// The endpoint descriptions for central discovery servers. /// /// The endpoint descriptions for central discovery servers. [DataTypeField(Order = 2, StructureHandling = StructureHandling.Inline)] public ArrayOf DiscoveryServers { get => m_discoveryServers; set => m_discoveryServers = value; } /// /// The path to the file containing the cached endpoints. /// /// The path to the file containing the cached endpoints. [DataTypeField(Order = 3)] public string EndpointCacheFilePath { get; set; } = string.Empty; /// /// The minimum lifetime for a subscription (in milliseconds). /// /// The minimum lifetime for a subscription. [DataTypeField(Order = 4)] public int MinSubscriptionLifetime { get; set; } = 10000; /// /// The reverse connect Client configuration. /// [DataTypeField(Order = 5, StructureHandling = StructureHandling.Inline)] public ReverseConnectClientConfiguration? ReverseConnect { get; set; } /// /// Gets or sets the default operation limits of the OPC UA client. /// /// /// Values not equal to zero are overwritten with smaller values set by the server. /// The values are used to limit client service calls. /// [DataTypeField(Order = 6, StructureHandling = StructureHandling.Inline)] public OperationLimits OperationLimits { get; set; } = new(); private ArrayOf m_wellKnownDiscoveryUrls; private ArrayOf m_discoveryServers; } /// /// Stores the configuration of the reverse connections. /// [DataType(Namespace = Namespaces.OpcUaConfig)] public partial class ReverseConnectClientConfiguration { /// /// A collection of reverse connect client endpoints. /// [DataTypeField(Order = 0, StructureHandling = StructureHandling.Inline)] public ArrayOf ClientEndpoints { get; set; } /// /// The time a reverse hello port is held open to wait for a /// reverse connection until the request is rejected. /// [DataTypeField(Order = 1)] public int HoldTime { get; set; } = 15000; /// /// The timeout to wait for a reverse hello message. /// [DataTypeField(Order = 2)] public int WaitTimeout { get; set; } = 20000; } /// /// Stores the configuration of the reverse connections. /// [DataType(Namespace = Namespaces.OpcUaConfig)] public partial class ReverseConnectClientEndpoint { /// /// The endpoint Url of a reverse connect client. /// [DataTypeField(Order = 0)] public string? EndpointUrl { get; set; } } /// /// Specifies the configuration for a discovery server application. /// [DataType(Namespace = Namespaces.OpcUaConfig)] public partial class DiscoveryServerConfiguration : ServerBaseConfiguration { /// /// The default constructor. /// public DiscoveryServerConfiguration() { ServerNames = []; ServerRegistrations = []; } /// /// The localized names for the discovery server. /// /// The server names. [DataTypeField(Order = 0)] public ArrayOf ServerNames { get; set; } /// /// The path to the file containing servers saved by the discovery server. /// /// The discovery server cache file. [DataTypeField(Order = 1)] public string? DiscoveryServerCacheFile { get; set; } /// /// Gets or sets the server registrations associated with the discovery server. /// /// The server registrations. [DataTypeField(Order = 2, StructureHandling = StructureHandling.Inline)] public ArrayOf ServerRegistrations { get; set; } } /// /// Specifies the configuration for a discovery server application. /// [DataType(Namespace = Namespaces.OpcUaConfig)] public partial class ServerRegistration { /// /// The default constructor. /// public ServerRegistration() { AlternateDiscoveryUrls = []; } /// /// Gets or sets the application URI of the server which the registration applies to. /// /// The application uri. [DataTypeField(Order = 0)] public string? ApplicationUri { get; set; } /// /// Gets or sets the alternate discovery urls. /// /// The alternate discovery urls. /// /// /// These addresses are used to specify alternate paths to ther via firewalls, proxies /// or similar network infrastructure. If these paths are specified in the configuration /// file then the server will use the domain of the URL used by the client to determine /// which, if any, or the alternate addresses to use instead of the primary addresses. /// /// /// In the ideal world the server would provide these URLs during registration but this /// table allows the administrator to provide the information to the discovery server /// directly without requiring a patch to the server. /// /// [DataTypeField(Order = 1)] public ArrayOf AlternateDiscoveryUrls { get; set; } } /// /// Describes a certificate store. /// [DataType(Namespace = Namespaces.OpcUaConfig)] public partial class CertificateStoreIdentifier { /// /// The type of certificate store. /// /// /// If the StoreName is not empty, the CertificateStoreType.X509Store is returned, otherwise the StoreType is returned. /// [DataTypeField(Order = 0)] public string? StoreType { get; set; } /// /// The path that identifies the certificate store. /// /// /// If the StoreName is not empty and the StoreLocation is empty, the Utils.Format("CurrentUser\\{0}", m_storeName) is returned. /// If the StoreName is not empty and the StoreLocation is not empty, the Utils.Format("{1}\\{0}", m_storeName, m_storeLocation) is returned. /// If the StoreName is empty, the m_storePath is returned. /// [DataTypeField(Order = 1)] public string? StorePath { get => m_storePath; set { m_storePath = value; if (!string.IsNullOrEmpty(m_storePath) && string.IsNullOrEmpty(StoreType)) { StoreType = DetermineStoreType(m_storePath!); } } } /// /// Options that can be used to suppress certificate validation errors. /// [DataTypeField(Order = 2, Name = "ValidationOptions")] internal int XmlEncodedValidationOptions { get => (int)ValidationOptions; set => ValidationOptions = (CertificateValidationOptions)value; } private string? m_storePath; } [DataType(Namespace = Namespaces.OpcUaConfig)] public partial class CertificateTrustList : CertificateStoreIdentifier { /// /// The default constructor. /// public CertificateTrustList() { m_trustedCertificates = []; } /// /// The list of trusted certificates. /// /// /// The list of trusted certificates. /// [DataTypeField(Order = 0, StructureHandling = StructureHandling.Inline)] public ArrayOf TrustedCertificates { get => m_trustedCertificates; set => m_trustedCertificates = value; } private ArrayOf m_trustedCertificates; } [DataType(Namespace = Namespaces.OpcUaConfig)] public partial class CertificateIdentifier { /// /// The default constructor. /// public CertificateIdentifier() { } /// /// The type of certificate store. /// /// The type of the store - defined in the . [DataTypeField(Order = 0)] public string? StoreType { get; set; } /// /// The path that identifies the certificate store. /// /// The store path in the form StoreName\\Store Location . [DataTypeField(Order = 1)] public string? StorePath { get => m_storePath; set { m_storePath = value; if (!string.IsNullOrEmpty(m_storePath) && string.IsNullOrEmpty(StoreType)) { StoreType = CertificateStoreIdentifier.DetermineStoreType(m_storePath!); } } } /// /// The certificate's subject name - the distinguished name of an X509 certificate. /// [DataTypeField(Order = 2)] public string? SubjectName { get => m_subjectName; set => m_subjectName = value; } /// /// The certificate's thumbprint. /// [DataTypeField(Order = 3)] public string? Thumbprint { get => m_thumbprint; set => m_thumbprint = value; } /// /// Gets the DER encoded certificate data, or sets it from raw bytes. /// /// /// When set, derives , , /// and by parsing the certificate. The /// resolver consumes via its inline branch /// (Certificate.FromRawData) to materialize a Certificate on demand. /// public byte[]? RawData { get => m_rawData; set { if (value == null || value.Length == 0) { m_rawData = null; return; } m_rawData = value; using var parsed = Certificate.FromRawData(value); m_subjectName = parsed.Subject; m_thumbprint = parsed.Thumbprint; CertificateType = GetCertificateType(parsed); } } /// /// Gets or sets the XML encoded validation options - use to serialize the validation options. /// /// The XML encoded validation options. [DataTypeField(Order = 4, Name = "ValidationOptions")] internal int XmlEncodedValidationOptions { get => (int)ValidationOptions; set => ValidationOptions = (CertificateValidationOptions)value; } /// /// Gets or sets the certificate type. /// /// The NodeId of the certificate type, e.g. EccNistP256ApplicationCertificateType. [DataTypeField(Order = 5)] public NodeId CertificateType { get; set; } /// /// The string representation of the certificate /// /// Rsa, RsaMin, RsaSha256, NistP256, NistP384, BrainpoolP256r1, BrainpoolP384r1, Curve25519, Curve448 [DataTypeField(Order = 6)] public string? CertificateTypeString { get => EncodeCertificateType(CertificateType); set => CertificateType = DecodeCertificateType(value); } private string? m_storePath; private string? m_subjectName; private string? m_thumbprint; private byte[]? m_rawData; } /// /// Stores a list of cached endpoints. /// [DataType(Namespace = Namespaces.OpcUaConfig)] public partial class ConfiguredEndpointCollection { /// /// The default constructor. /// public ConfiguredEndpointCollection() { m_knownHosts = []; m_discoveryUrls = [.. Utils.DiscoveryUrls]; m_endpoints = []; DefaultConfiguration = EndpointConfiguration.Create(); } /// /// A list of known hosts that can be used for discovery. /// [DataTypeField(Order = 0)] public ArrayOf KnownHosts { get => m_knownHosts; set => m_knownHosts = value; } /// /// The configured endpoints. /// public List Endpoints { get => m_endpoints; private set { m_endpoints = value ?? []; foreach (ConfiguredEndpoint endpoint in m_endpoints) { endpoint.Collection = this; } } } [DataTypeField(Order = 1, StructureHandling = StructureHandling.Inline, Name = "Endpoints")] private ArrayOf EndpointsEncodeable { get => m_endpoints.ToArrayOf(); set { m_endpoints = value.ToList(); foreach (ConfiguredEndpoint endpoint in m_endpoints) { endpoint.Collection = this; } } } /// /// The URL of the UA TCP proxy server. /// public Uri? TcpProxyUrl { get; set; } [DataTypeField(Order = 2, Name = "TcpProxyUrl")] private string? TcpProxyUrlString { get => TcpProxyUrl?.ToString(); set => TcpProxyUrl = value != null ? new Uri(value) : null; } private string? m_filepath; private ArrayOf m_knownHosts; private ArrayOf m_discoveryUrls; private List m_endpoints; } /// /// Stores the configuration information for an endpoint. /// [DataType(Namespace = Namespaces.OpcUaConfig)] public partial class ConfiguredEndpoint { /// /// The default constructor. /// public ConfiguredEndpoint() { m_description = new EndpointDescription(); BinaryEncodingSupport = BinaryEncodingSupport.Optional; } /// /// The description for the endpoint. /// [DataTypeField(IsRequired = true, Order = 0, Name = "Endpoint", StructureHandling = StructureHandling.Inline)] public EndpointDescription Description { get => m_description; private set => m_description = value ?? new EndpointDescription(); } /// /// The configuration to use when connecting to an endpoint. /// [DataTypeField(Order = 1, StructureHandling = StructureHandling.Inline)] public EndpointConfiguration? Configuration { get => m_configuration; set { m_configuration = value; // copy default configuration if not already set. if (m_configuration == null) { if (m_collection != null) { Update(m_collection.DefaultConfiguration); } else { Update(EndpointConfiguration.Create()); } } } } /// /// Whether the endpoint information should be updated before connecting /// to the server. /// [DataTypeField(Order = 2, DefaultValueHandling = DefaultValueHandling.Emit)] public bool UpdateBeforeConnect { get; set; } = true; /// /// The user identity to use when connecting to the endpoint. /// public BinaryEncodingSupport BinaryEncodingSupport { get; set; } [DataTypeField(Order = 3, Name = "BinaryEncodingSupport")] private string BinaryEncodingSupportString { get => BinaryEncodingSupport.ToString(); set { if (Enum.TryParse(value, out BinaryEncodingSupport parsed)) { BinaryEncodingSupport = parsed; } } } /// /// The user identity to use when connecting to the endpoint. /// [DataTypeField(Order = 4, Name = "SelectedUserTokenPolicy")] public int SelectedUserTokenPolicyIndex { get; set; } /// /// The user identity to use when connecting to the endpoint. /// [DataTypeField(Order = 5, StructureHandling = StructureHandling.Inline)] public UserIdentityToken? UserIdentity { get; set; } /// /// The reverse connect information. /// [DataTypeField(Order = 6, StructureHandling = StructureHandling.Inline)] public ReverseConnectEndpoint? ReverseConnect { get; set; } /// /// A bucket to store additional application specific configuration data. /// [DataTypeField(Order = 7)] public ArrayOf Extensions { get => m_extensions; set => m_extensions = value; } private ConfiguredEndpointCollection? m_collection; private EndpointDescription m_description; private EndpointConfiguration? m_configuration; private ArrayOf m_extensions; } /// /// The type of binary encoding support allowed by a channel. /// [DataType(Namespace = Namespaces.OpcUaConfig)] public enum BinaryEncodingSupport { /// /// The UA binary encoding may be used. /// Optional, /// /// The UA binary encoding must be used. /// Required, /// /// The UA binary encoding may not be used. /// None } /// /// Stores the reverse connect information for an endpoint. /// [DataType(Namespace = Namespaces.OpcUaConfig)] public partial class ReverseConnectEndpoint { /// /// The default constructor. /// public ReverseConnectEndpoint() { Enabled = false; ServerUri = null; Thumbprint = null; } /// /// Whether reverse connect is enabled for the endpoint. /// [DataTypeField(Order = 1)] public bool Enabled { get; set; } /// /// The server Uri of the endpoint. /// [DataTypeField(Order = 2)] public string? ServerUri { get; set; } /// /// The thumbprint of the certificate which contains /// the server Uri. /// [DataTypeField(Order = 3)] public string? Thumbprint { get; set; } } }