/* ========================================================================
* 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 System.Runtime.Serialization;
using System.Security.Cryptography.X509Certificates;
using Microsoft.Extensions.Logging;
using Opc.Ua.Bindings;
using Opc.Ua.Security;
namespace Opc.Ua
{
///
/// Stores the configurable configuration information for a UA application.
///
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public partial class ApplicationConfiguration
{
///
/// The default constructor.
///
public ApplicationConfiguration()
{
Initialize();
}
///
/// The default constructor.
///
public ApplicationConfiguration(ITelemetryContext telemetry)
{
Initialize(telemetry);
Initialize();
}
///
/// 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;
CertificateValidator = template.CertificateValidator;
TransportQuotas = template.TransportQuotas;
#pragma warning disable CS0618 // Type or member is obsolete
TraceConfiguration = template.TraceConfiguration;
#pragma warning restore CS0618 // Type or member is obsolete
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;
}
///
/// Sets private members to default values.
///
private void Initialize()
{
SourceFilePath = null;
m_securityConfiguration = new SecurityConfiguration();
m_transportConfigurations = [];
DisableHiResClock = false;
m_properties = [];
m_extensionObjects = [];
CertificateValidator ??= new CertificateValidator(m_telemetry);
m_logger ??= m_telemetry.CreateLogger();
}
///
/// Initialize telemetry context - after loading
///
/// The telemetry context to use to create obvservability instruments
internal void Initialize(ITelemetryContext telemetry)
{
m_telemetry = telemetry;
m_logger = telemetry.CreateLogger();
CertificateValidator = new CertificateValidator(m_telemetry);
}
///
/// Initializes the object during deserialization.
///
/// The context.
[OnDeserializing]
public void Initialize(StreamingContext context)
{
m_telemetry = AmbientMessageContext.Telemetry;
Initialize();
}
///
/// Gets an object used to synchronize access to the properties dictionary.
///
///
/// The 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.
///
///
/// The 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).
///
/// The name of the application.
[DataMember(IsRequired = true, EmitDefaultValue = false, Order = 0)]
public string ApplicationName { get; set; }
///
/// A unique identifier for the application instance.
///
/// The application URI.
[DataMember(IsRequired = true, EmitDefaultValue = false, Order = 1)]
public string ApplicationUri { get; set; }
///
/// A unique identifier for the product.
///
/// The product URI.
[DataMember(IsRequired = false, Order = 2)]
public string ProductUri { get; set; }
///
/// The type of application.
///
/// The type of the application.
[DataMember(IsRequired = true, Order = 3)]
public ApplicationType ApplicationType { get; set; }
///
/// The security configuration for the application.
///
/// The security configuration.
[DataMember(IsRequired = false, EmitDefaultValue = true, Order = 4)]
public SecurityConfiguration SecurityConfiguration
{
get => m_securityConfiguration;
set => m_securityConfiguration = value ?? new SecurityConfiguration();
}
///
/// The transport configuration for the application.
///
/// The transport configurations.
[DataMember(IsRequired = false, EmitDefaultValue = true, Order = 5)]
public TransportConfigurationCollection TransportConfigurations
{
get => m_transportConfigurations;
set => m_transportConfigurations = value ?? [];
}
///
/// The quotas that are used at the transport layer.
///
/// The transport quotas.
[DataMember(IsRequired = false, EmitDefaultValue = true, Order = 6)]
public TransportQuotas TransportQuotas { get; set; }
///
/// Additional configuration for server applications.
///
/// The server configuration.
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 7)]
public ServerConfiguration ServerConfiguration { get; set; }
///
/// Additional configuration for client applications.
///
/// The client configuration.
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 8)]
public ClientConfiguration ClientConfiguration { get; set; }
///
/// Additional configuration of the discovery server.
///
/// The discovery server configuration.
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 9)]
public DiscoveryServerConfiguration DiscoveryServerConfiguration { get; set; }
///
/// A bucket to store additional application specific configuration data.
///
/// The extensions.
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 10)]
public XmlElementCollection Extensions
{
get => m_extensions;
set => m_extensions = value;
}
///
/// Configuration of the trace and information about log file
///
/// The trace configuration.
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 11)]
[Obsolete("Use ITelemetryContext and ILogger-based diagnostics instead.")]
public TraceConfiguration TraceConfiguration { get; set; }
///
/// Disabling / enabling high resolution clock
///
/// true if high resolution clock is disabled; otherwise, false .
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 12)]
public bool DisableHiResClock { get; set; }
private ITelemetryContext m_telemetry;
private ILogger m_logger;
private SecurityConfiguration m_securityConfiguration;
private TransportConfigurationCollection m_transportConfigurations;
private XmlElementCollection m_extensions;
private List m_extensionObjects;
private Dictionary m_properties;
}
///
/// Specifies various limits that apply to the transport or secure channel layers.
///
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public class TransportQuotas
{
///
/// The default constructor.
///
public TransportQuotas()
{
Initialize();
}
///
/// Sets private members to default values.
///
private void Initialize()
{
// 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;
}
///
/// Initializes the object during deserialization.
///
/// The context.
[OnDeserializing]
public void Initialize(StreamingContext context)
{
Initialize();
}
///
/// The default timeout to use when sending requests (in milliseconds).
///
/// The operation timeout.
[DataMember(IsRequired = false, Order = 0)]
public int OperationTimeout { get; set; }
///
/// The maximum length of string encoded in a message body.
///
/// The max length of the string.
[DataMember(IsRequired = false, Order = 1)]
public int MaxStringLength { get; set; }
///
/// The maximum length of a byte string encoded in a message body.
///
/// The max length of the byte string.
[DataMember(IsRequired = false, Order = 2)]
public int MaxByteStringLength { get; set; }
///
/// The maximum length of an array encoded in a message body.
///
/// The max length of the array.
[DataMember(IsRequired = false, Order = 3)]
public int MaxArrayLength { get; set; }
///
/// The maximum length of a message body.
///
/// The max size of the message.
[DataMember(IsRequired = false, Order = 4)]
public int MaxMessageSize { get; set; }
///
/// The maximum size of the buffer to use when sending messages.
///
/// The max size of the buffer.
[DataMember(IsRequired = false, Order = 5)]
public int MaxBufferSize { get; set; }
///
/// The maximum nesting level accepted while encoding or decoding objects.
///
[DataMember(IsRequired = false, 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.
///
[DataMember(IsRequired = false, Order = 7)]
public int MaxDecoderRecoveries { get; set; }
///
/// The lifetime of a secure channel (in milliseconds).
///
/// The channel lifetime.
[DataMember(IsRequired = false, Order = 8)]
public int ChannelLifetime { get; set; }
///
/// The lifetime of a security token (in milliseconds).
///
/// The security token lifetime.
[DataMember(IsRequired = false, Order = 9)]
public int SecurityTokenLifetime { get; set; }
}
///
/// Specifies parameters used for tracing.
///
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public class TraceConfiguration
{
///
/// The default constructor.
///
public TraceConfiguration()
{
Initialize();
}
///
/// Sets private members to default values.
///
private void Initialize()
{
OutputFilePath = null;
DeleteOnLoad = false;
}
///
/// Initializes the object during deserialization.
///
/// The context.
[OnDeserializing]
public void Initialize(StreamingContext context)
{
Initialize();
}
///
/// The output file used to log the trace information.
///
/// The output file path.
[DataMember(IsRequired = false, Order = 0)]
public string OutputFilePath { get; set; }
///
/// Whether the existing log file should be deleted when the application configuration is loaded.
///
/// true if existing log file should be deleted when the application configuration is loaded; otherwise, false .
[DataMember(IsRequired = false, 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;
///
/// The trace masks.
[DataMember(IsRequired = false, 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.
///
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public class TransportConfiguration
{
///
/// The default constructor.
///
public TransportConfiguration()
{
}
///
/// The default constructor.
///
/// The URL scheme.
/// The 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.).
///
/// The URI scheme.
[DataMember(IsRequired = true, EmitDefaultValue = false, Order = 0)]
public string UriScheme { get; set; }
///
/// The name of the class that defines the binding for the transport.
///
/// The name of the type.
///
///
/// 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)
///
///
[DataMember(IsRequired = true, EmitDefaultValue = false, Order = 1)]
public string TypeName { get; set; }
}
///
/// A collection of TransportConfiguration objects.
///
[CollectionDataContract(
Name = "ListOfTransportConfiguration",
Namespace = Namespaces.OpcUaConfig,
ItemName = "TransportConfiguration"
)]
public class TransportConfigurationCollection : List
{
///
/// Initializes an empty collection.
///
public TransportConfigurationCollection()
{
}
///
/// Initializes the collection from another collection.
///
/// A collection of values to add to this new collection
///
/// is null.
///
public TransportConfigurationCollection(IEnumerable collection)
: base(collection)
{
}
///
/// Initializes the collection with the specified capacity.
///
/// The capacity.
public TransportConfigurationCollection(int capacity)
: base(capacity)
{
}
}
///
/// A class that defines a group of security policies supported by the server.
///
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public class ServerSecurityPolicy
{
///
/// The default constructor.
///
public ServerSecurityPolicy()
{
Initialize();
}
///
/// Sets private members to default values.
///
private void Initialize()
{
SecurityMode = MessageSecurityMode.SignAndEncrypt;
SecurityPolicyUri = SecurityPolicies.Basic256Sha256;
}
///
/// Initializes the object during deserialization.
///
/// The context.
[OnDeserializing]
public void Initialize(StreamingContext context)
{
Initialize();
}
///
/// 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
///
/// The security mode.
[DataMember(IsRequired = false, Order = 1)]
public MessageSecurityMode SecurityMode { get; set; }
///
/// The security policy to use.
///
/// The security policy URI.
[DataMember(IsRequired = false, Order = 2)]
public string SecurityPolicyUri { get; set; }
}
///
/// A collection of ServerSecurityPolicy objects.
///
[CollectionDataContract(
Name = "ListOfServerSecurityPolicy",
Namespace = Namespaces.OpcUaConfig,
ItemName = "ServerSecurityPolicy"
)]
public class ServerSecurityPolicyCollection : List
{
///
/// Initializes an empty collection.
///
public ServerSecurityPolicyCollection()
{
}
///
/// Initializes the collection from another collection.
///
/// A collection of values to add to this new collection
///
/// is null.
///
public ServerSecurityPolicyCollection(IEnumerable collection)
: base(collection)
{
}
///
/// Initializes the collection with the specified capacity.
///
/// The capacity.
public ServerSecurityPolicyCollection(int capacity)
: base(capacity)
{
}
}
///
/// The security configuration for the application.
///
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public partial class SecurityConfiguration
{
///
/// The default constructor.
///
public SecurityConfiguration()
{
Initialize();
}
///
/// Sets private members to default values.
///
private void Initialize()
{
m_applicationCertificates = [];
m_trustedIssuerCertificates = new CertificateTrustList();
m_trustedPeerCertificates = new CertificateTrustList();
NonceLength = 32;
MaxRejectedCertificates = 5;
AutoAcceptUntrustedCertificates = false;
RejectSHA1SignedCertificates = true;
RejectUnknownRevocationStatus = false;
MinimumCertificateKeySize = CertificateFactory.DefaultKeySize;
AddAppCertToTrustedStore = true;
SendCertificateChain = true;
SuppressNonceValidationErrors = false;
IsDeprecatedConfiguration = false;
}
///
/// Initializes the object during deserialization.
///
[OnDeserializing]
public void Initialize(StreamingContext context)
{
Initialize();
}
///
/// The application instance certificate.
/// Kept for backward compatibility with configuration files which only support RSA certificates.
///
/// The application certificate.
///
/// This certificate must contain the application uri.
/// For servers, URLs for each supported protocol must also be present.
///
[IgnoreDataMember]
public CertificateIdentifier ApplicationCertificate
{
get
{
if (m_applicationCertificates.Count > 0)
{
return m_applicationCertificates[0];
}
return null;
}
set
{
if (m_applicationCertificates.Count > 0)
{
if (value == null)
{
m_applicationCertificates.RemoveAt(0);
}
else
{
m_applicationCertificates[0] = value;
}
}
else
{
m_applicationCertificates.Add(value);
}
SupportedSecurityPolicies = BuildSupportedSecurityPolicies();
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.
///
[DataMember(Name = "ApplicationCertificate", IsRequired = false, EmitDefaultValue = false, Order = 0)]
private CertificateIdentifier ApplicationCertificateLegacy
{
get => IsDeprecatedConfiguration ? ApplicationCertificate : null;
set => ApplicationCertificate = value;
}
///
/// The application instance certificates in use for the application.
///
[IgnoreDataMember]
public CertificateIdentifierCollection ApplicationCertificates
{
get => m_applicationCertificates;
set
{
if (value == null || value.Count == 0)
{
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 CertificateIdentifierCollection(value);
// 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
// Only perform duplicate detection if we have actual loaded certificates
for (int i = 0; i < newCertificates.Count; i++)
{
for (int j = newCertificates.Count - 1; j > i; j--)
{
bool isDuplicate = false;
// Only check for duplicates if both certificates are actually loaded
if (newCertificates[i].Certificate != null && newCertificates[j].Certificate != null)
{
// Compare by actual certificate thumbprint
isDuplicate = newCertificates[i].Certificate.Thumbprint.Equals(
newCertificates[j].Certificate.Thumbprint,
StringComparison.OrdinalIgnoreCase);
}
// If certificates aren't loaded yet, compare by explicit thumbprint configuration
else 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;
// Presence of the modern collection takes precedence over legacy; clear the flag so
// hybrid configurations are treated as modern.
IsDeprecatedConfiguration = false;
SupportedSecurityPolicies = BuildSupportedSecurityPolicies();
}
}
///
/// This private property exists solely to control the serialization of the modern certificates collection.
/// Emit only when the configuration is not marked deprecated.
///
[DataMember(Name = "ApplicationCertificates", IsRequired = false, EmitDefaultValue = false, Order = 1)]
private CertificateIdentifierCollection ApplicationCertificatesDataContract
{
get => IsDeprecatedConfiguration ? null : ApplicationCertificates;
set => ApplicationCertificates = value;
}
///
/// The store containing any additional issuer certificates.
///
[DataMember(IsRequired = true, EmitDefaultValue = false, Order = 2)]
public CertificateTrustList TrustedIssuerCertificates
{
get => m_trustedIssuerCertificates;
set => m_trustedIssuerCertificates = value ?? new CertificateTrustList();
}
///
/// The trusted certificate store.
///
[DataMember(IsRequired = true, EmitDefaultValue = false, Order = 4)]
public CertificateTrustList TrustedPeerCertificates
{
get => m_trustedPeerCertificates;
set => m_trustedPeerCertificates = value ?? new CertificateTrustList();
}
///
/// The length of nonce in the CreateSession service.
///
///
/// The length of nonce in the CreateSession service.
///
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 6)]
public int NonceLength { get; set; }
///
/// A store where invalid certificates can be placed for later review by the administrator.
///
///
/// A store where invalid certificates can be placed for later review by the administrator.
///
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 7)]
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.
///
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 8)]
public int MaxRejectedCertificates { get; set; }
///
/// 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.
///
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 9)]
public bool AutoAcceptUntrustedCertificates { get; set; }
///
/// Gets or sets a directory which contains files representing users roles.
///
[DataMember(Order = 10)]
public string UserRoleDirectory { get; set; }
///
/// Gets or sets a value indicating whether SHA-1 signed certificates are accepted.
///
///
/// This flag can be set to false by servers that accept SHA-1 signed certificates.
///
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 11)]
public bool RejectSHA1SignedCertificates { get; set; }
///
/// 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).
///
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 12)]
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 by servers
///
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 13)]
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 by applications.
///
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 14)]
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.
///
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 15)]
public bool AddAppCertToTrustedStore { get; set; }
///
/// 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.
///
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 16)]
public bool SendCertificateChain { get; set; }
///
/// The store containing additional user issuer certificates.
///
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 17)]
public CertificateTrustList UserIssuerCertificates
{
get => m_userIssuerCertificates;
set => m_userIssuerCertificates = value ?? new CertificateTrustList();
}
///
/// The store containing trusted user certificates.
///
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 18)]
public CertificateTrustList TrustedUserCertificates
{
get => m_trustedUserCertificates;
set => m_trustedUserCertificates = value ?? new CertificateTrustList();
}
///
/// The store containing additional Https issuer certificates.
///
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 19)]
public CertificateTrustList HttpsIssuerCertificates
{
get => m_httpsIssuerCertificates;
set => m_httpsIssuerCertificates = value ?? new CertificateTrustList();
}
///
/// The store containing trusted Https certificates.
///
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 20)]
public CertificateTrustList TrustedHttpsCertificates
{
get => m_trustedHttpsCertificates;
set => m_trustedHttpsCertificates = value ?? new CertificateTrustList();
}
///
/// 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.
///
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 21)]
public bool SuppressNonceValidationErrors { get; set; }
///
/// The type of Configuration (deprecated or not)
///
public bool IsDeprecatedConfiguration { get; set; }
private CertificateIdentifierCollection 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.
///
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public class SamplingRateGroup
{
///
/// The default constructor.
///
public SamplingRateGroup()
{
Initialize();
}
///
/// 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;
}
///
/// Sets private members to default values.
///
private void Initialize()
{
Start = 1000;
Increment = 0;
Count = 0;
}
///
/// Initializes the object during deserialization.
///
/// The context.
[OnDeserializing]
public void Initialize(StreamingContext context)
{
Initialize();
}
///
/// The first sampling rate in the group (in milliseconds).
///
/// The first sampling rate in the group (in milliseconds).
[DataMember(IsRequired = false, Order = 1)]
public double Start { get; set; }
///
/// 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.
///
[DataMember(IsRequired = false, Order = 2)]
public double Increment { get; set; }
///
/// The number of sampling rates in the group.
///
/// The count.
///
/// A count of 0 means there is no limit.
///
[DataMember(IsRequired = false, Order = 3)]
public int Count { get; set; }
}
///
/// A collection of SamplingRateGroup objects.
///
[CollectionDataContract(
Name = "ListOfSamplingRateGroup",
Namespace = Namespaces.OpcUaConfig,
ItemName = "SamplingRateGroup"
)]
public class SamplingRateGroupCollection : List
{
///
/// Initializes an empty collection.
///
public SamplingRateGroupCollection()
{
}
///
/// Initializes the collection from another collection.
///
/// A collection of values to add to this new collection
///
/// is null.
///
public SamplingRateGroupCollection(IEnumerable collection)
: base(collection)
{
}
///
/// Initializes the collection with the specified capacity.
///
/// The capacity.
public SamplingRateGroupCollection(int capacity)
: base(capacity)
{
}
}
///
/// Specifies the configuration for a server application.
///
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public partial class ServerBaseConfiguration
{
///
/// The default constructor.
///
public ServerBaseConfiguration()
{
Initialize();
}
///
/// Sets private members to default values.
///
private void Initialize()
{
m_baseAddresses = [];
m_alternateBaseAddresses = [];
m_securityPolicies = [];
MinRequestThreadCount = 10;
MaxRequestThreadCount = 100;
MaxQueuedRequestCount = 200;
}
///
/// Initializes the object during deserialization.
///
/// The context.
[OnDeserializing]
public void Initialize(StreamingContext context)
{
Initialize();
}
///
/// Remove unsupported security policies and expand wild cards.
///
[OnDeserialized]
private void ValidateSecurityPolicyCollection(StreamingContext context)
{
string[] supportedPolicies = Ua.SecurityPolicies.GetDisplayNames();
var newPolicies = new ServerSecurityPolicyCollection();
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;
}
///
/// 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.
///
[DataMember(IsRequired = false, Order = 0)]
public StringCollection 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.
///
[DataMember(IsRequired = false, Order = 1)]
public StringCollection 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.
///
[DataMember(IsRequired = false, Order = 2)]
public ServerSecurityPolicyCollection SecurityPolicies
{
get => m_securityPolicies;
set => m_securityPolicies = value ?? [];
}
///
/// The minimum number of threads assigned to processing requests.
///
/// The minimum request thread count.
[DataMember(IsRequired = false, Order = 3)]
public int MinRequestThreadCount { get; set; }
///
/// The maximum number of threads assigned to processing requests.
///
/// The maximum request thread count.
[DataMember(IsRequired = false, Order = 4)]
public int MaxRequestThreadCount { get; set; }
///
/// The maximum number of requests that will be queued waiting for a thread.
///
/// The maximum queued request count.
[DataMember(IsRequired = false, Order = 5)]
public int MaxQueuedRequestCount { get; set; }
private StringCollection m_baseAddresses;
private StringCollection m_alternateBaseAddresses;
private ServerSecurityPolicyCollection m_securityPolicies;
}
///
/// Specifies the configuration for a server application.
///
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public partial class ServerConfiguration : ServerBaseConfiguration
{
///
/// The default constructor.
///
public ServerConfiguration()
{
Initialize();
}
///
/// Sets private members to default values.
///
private void Initialize()
{
m_userTokenPolicies = [];
DiagnosticsEnabled = false;
MaxSessionCount = 100;
MaxChannelCount = 1000;
MaxSessionTimeout = 3600000;
MinSessionTimeout = 10000;
MaxBrowseContinuationPoints = 10;
MaxQueryContinuationPoints = 10;
MaxHistoryContinuationPoints = 100;
MaxRequestAge = 600000;
MinPublishingInterval = 100;
MaxPublishingInterval = 3600000;
PublishingResolution = 100;
MinSubscriptionLifetime = 10000;
MaxSubscriptionLifetime = 3600000;
MaxMessageQueueSize = 10;
MaxNotificationQueueSize = 100;
MaxNotificationsPerPublish = 100;
MinMetadataSamplingInterval = 1000;
AvailableSamplingRates = [];
RegistrationEndpoint = null;
MaxRegistrationInterval = 30000;
MaxPublishRequestCount = 20;
MaxSubscriptionCount = 100;
MaxEventQueueSize = 10000;
// https://opcfoundation-onlineapplications.org/profilereporting/ for list of available profiles
m_serverProfileArray = new string[] {
"http://opcfoundation.org/UA-Profile/Server/StandardUA2017" };
ShutdownDelay = 5;
m_serverCapabilities = new string[] { "DA" };
m_supportedPrivateKeyFormats = new string[] { "PFX", "PEM" };
MaxTrustListSize = 0;
MultiCastDnsEnabled = false;
OperationLimits = new OperationLimits();
AuditingEnabled = false;
HttpsMutualTls = true;
DurableSubscriptionsEnabled = false;
MaxDurableNotificationQueueSize = 200000;
MaxDurableEventQueueSize = 200000;
MaxDurableSubscriptionLifetimeInHours = 10;
}
///
/// Initializes the object during deserialization.
///
/// The context.
[OnDeserializing]
public new void Initialize(StreamingContext context)
{
Initialize();
}
///
/// The user tokens accepted by the server.
///
/// The user token policies.
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 3)]
public UserTokenPolicyCollection UserTokenPolicies
{
get => m_userTokenPolicies;
set => m_userTokenPolicies = value ?? [];
}
///
/// Whether diagnostics are enabled.
///
/// true if diagnostic is enabled; otherwise, false .
[DataMember(IsRequired = false, Order = 4)]
public bool DiagnosticsEnabled { get; set; }
///
/// The maximum number of open sessions.
///
/// The maximum session count.
[DataMember(IsRequired = false, Order = 5)]
public int MaxSessionCount { get; set; }
///
/// The maximum number of supported secure channels.
///
/// The channel lifetime.
[DataMember(IsRequired = false, Order = 6)]
public int MaxChannelCount { get; set; }
///
/// That minimum period of that a session is allowed to remain
/// open without communication from the client (in milliseconds).
///
/// The minimum session timeout.
[DataMember(IsRequired = false, Order = 7)]
public int MinSessionTimeout { get; set; }
///
/// That maximum period of that a session is allowed to remain
/// open without communication from the client (in milliseconds).
///
/// The maximum session timeout.
[DataMember(IsRequired = false, Order = 8)]
public int MaxSessionTimeout { get; set; }
///
/// The maximum number of continuation points used for
/// Browse/BrowseNext operations.
///
/// The maximum number of continuation points used for Browse/BrowseNext operations
[DataMember(IsRequired = false, Order = 9)]
public int MaxBrowseContinuationPoints { get; set; }
///
/// The maximum number of continuation points used for
/// Query/QueryNext operations.
///
/// The maximum number of query continuation points.
[DataMember(IsRequired = false, Order = 10)]
public int MaxQueryContinuationPoints { get; set; }
///
/// The maximum number of continuation points used for HistoryRead operations.
///
/// The maximum number of history continuation points.
[DataMember(IsRequired = false, Order = 11)]
public int MaxHistoryContinuationPoints { get; set; }
///
/// The maximum age of an incoming request (old requests are rejected) (in milliseconds).
///
/// The maximum age of an incoming request.
[DataMember(IsRequired = false, Order = 12)]
public int MaxRequestAge { get; set; }
///
/// The minimum publishing interval supported by the server (in milliseconds).
///
/// The minimum publishing interval.
[DataMember(IsRequired = false, Order = 13)]
public int MinPublishingInterval { get; set; }
///
/// The maximum publishing interval supported by the server (in milliseconds).
///
/// The maximum publishing interval.
[DataMember(IsRequired = false, Order = 14)]
public int MaxPublishingInterval { get; set; }
///
/// The minimum difference between supported publishing interval (in milliseconds).
///
/// The publishing resolution.
[DataMember(IsRequired = false, Order = 15)]
public int PublishingResolution { get; set; }
///
/// How long the subscriptions will remain open without a publish from the client.
///
/// The maximum subscription lifetime.
[DataMember(IsRequired = false, Order = 16)]
public int MaxSubscriptionLifetime { get; set; }
///
/// The maximum number of messages saved in the queue for each subscription.
///
/// The maximum size of the message queue.
[DataMember(IsRequired = false, Order = 17)]
public int MaxMessageQueueSize { get; set; }
///
/// The maximum number of notificates saved in the queue for each monitored item.
///
/// The maximum size of the notification queue.
[DataMember(IsRequired = false, Order = 18)]
public int MaxNotificationQueueSize { get; set; }
///
/// The maximum number of notifications per publish.
///
/// The maximum number of notifications per publish.
[DataMember(IsRequired = false, Order = 19)]
public int MaxNotificationsPerPublish { get; set; }
///
/// The minimum sampling interval for metadata.
///
/// The minimum sampling interval for metadata.
[DataMember(IsRequired = false, Order = 20)]
public int MinMetadataSamplingInterval { get; set; }
///
/// The available sampling rates.
///
/// The available sampling rates.
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 21)]
public SamplingRateGroupCollection AvailableSamplingRates { get; set; }
///
/// The endpoint description for the registration endpoint.
///
/// The registration endpoint.
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 22)]
public EndpointDescription RegistrationEndpoint { get; set; }
///
/// The maximum time between registration attempts (in milliseconds).
///
/// The maximum time between registration attempts (in milliseconds).
[DataMember(IsRequired = false, Order = 23)]
public int MaxRegistrationInterval { get; set; }
///
/// 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.
[DataMember(IsRequired = false, Order = 24)]
public string NodeManagerSaveFile { get; set; }
///
/// The minimum lifetime for a subscription (in milliseconds).
///
/// The minimum lifetime for a subscription.
[DataMember(IsRequired = false, Order = 25)]
public int MinSubscriptionLifetime { get; set; }
///
/// The max publish request count.
///
/// The max publish request count.
[DataMember(IsRequired = false, Order = 26)]
public int MaxPublishRequestCount { get; set; }
///
/// The max subscription count.
///
/// The max subscription count.
[DataMember(IsRequired = false, Order = 27)]
public int MaxSubscriptionCount { get; set; }
///
/// The max size of the event queue.
///
/// The max size of the event queue.
[DataMember(IsRequired = false, Order = 28)]
public int MaxEventQueueSize { get; set; }
///
/// The server profile array.
///
/// The array of server profiles.
[DataMember(IsRequired = false, Order = 29)]
public StringCollection 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.
[DataMember(IsRequired = false, Order = 30)]
public int ShutdownDelay { get; set; }
///
/// The server capabilities.
/// The latest set of server capabilities is listed
/// here.
///
/// The array of server capabilites.
[DataMember(IsRequired = false, Order = 31)]
public StringCollection ServerCapabilities
{
get => m_serverCapabilities;
set => m_serverCapabilities = value ?? [];
}
///
/// Gets or sets the supported private key format.
///
/// The array of server profiles.
[DataMember(IsRequired = false, Order = 32)]
public StringCollection SupportedPrivateKeyFormats
{
get => m_supportedPrivateKeyFormats;
set => m_supportedPrivateKeyFormats = value ?? [];
}
///
/// Gets or sets the max size of the trust list.
///
[DataMember(IsRequired = false, Order = 33)]
public int MaxTrustListSize { get; set; }
///
/// Gets or sets if multicast DNS is enabled.
///
[DataMember(IsRequired = false, Order = 34)]
public bool MultiCastDnsEnabled { get; set; }
///
/// Gets or sets reverse connect server configuration.
///
[DataMember(IsRequired = false, Order = 35)]
public ReverseConnectServerConfiguration ReverseConnect { get; set; }
///
/// Gets or sets the operation limits of the OPC UA Server.
///
[DataMember(IsRequired = false, Order = 36)]
public OperationLimits OperationLimits { get; set; }
///
/// Whether auditing is enabled.
///
/// true if auditing is enabled; otherwise, false .
[DataMember(IsRequired = false, Order = 37)]
public bool AuditingEnabled { get; set; }
///
/// Whether mTLS is required/enforced by the HttpsTransportListener
///
/// true if mutual TLS is enabled; otherwise, false .
[DataMember(IsRequired = false, Order = 38)]
public bool HttpsMutualTls { get; set; }
///
/// Enable / disable support for durable subscriptions
///
/// true if durable subscriptions are enabled; otherwise, false .
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 39)]
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.
[DataMember(IsRequired = false, Order = 40)]
public int MaxDurableNotificationQueueSize { get; set; }
///
/// The max size of the durable event queue.
///
/// The max size of the durable event queue.
[DataMember(IsRequired = false, Order = 41)]
public int MaxDurableEventQueueSize { get; set; }
///
/// How long the durable subscriptions will remain open without a publish from the client.
///
/// The maximum durable subscription lifetime.
[DataMember(IsRequired = false, Order = 42)]
public int MaxDurableSubscriptionLifetimeInHours { get; set; }
private UserTokenPolicyCollection m_userTokenPolicies;
private StringCollection m_serverProfileArray;
private StringCollection m_serverCapabilities;
private StringCollection m_supportedPrivateKeyFormats;
}
///
/// Stores the configuration of the reverse connections.
///
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public class ReverseConnectServerConfiguration
{
///
/// The default constructor.
///
public ReverseConnectServerConfiguration()
{
Initialize();
}
///
/// Initializes the object during deserialization.
///
[OnDeserializing]
private void Initialize(StreamingContext context)
{
Initialize();
}
///
/// Sets private members to default values.
///
private void Initialize()
{
ConnectInterval = 15000;
ConnectTimeout = 30000;
RejectTimeout = 60000;
}
///
/// A collection of reverse connect clients.
///
[DataMember(Order = 10)]
public ReverseConnectClientCollection Clients { get; set; }
///
/// The interval after which a new reverse connection is attempted.
///
[DataMember(Order = 20)]
public int ConnectInterval { get; set; }
///
/// The default timeout to wait for a response to a reverse connection.
///
[DataMember(Order = 30)]
public int ConnectTimeout { get; set; }
///
/// The timeout to wait to establish a new reverse
/// connection after a rejected attempt.
///
[DataMember(Order = 40)]
public int RejectTimeout { get; set; }
}
///
/// Stores the operation limits of a OPC UA Server.
///
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public class OperationLimits
{
///
/// The default constructor.
///
public OperationLimits()
{
Initialize();
}
///
/// Initializes the object during deserialization.
///
[OnDeserializing]
private void Initialize(StreamingContext context)
{
Initialize();
}
///
/// Sets private members to default values.
///
private void Initialize()
{
MaxNodesPerRead = 0;
MaxNodesPerHistoryReadData = 0;
MaxNodesPerHistoryReadEvents = 0;
MaxNodesPerWrite = 0;
MaxNodesPerHistoryUpdateData = 0;
MaxNodesPerHistoryUpdateEvents = 0;
MaxNodesPerMethodCall = 0;
MaxNodesPerBrowse = 0;
MaxNodesPerRegisterNodes = 0;
MaxNodesPerTranslateBrowsePathsToNodeIds = 0;
MaxNodesPerNodeManagement = 0;
MaxMonitoredItemsPerCall = 0;
}
///
/// Indicates the maximum size of the nodesToRead array when a Client calls the Read Service.
///
[DataMember(Order = 10)]
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.
///
[DataMember(Order = 20)]
public uint MaxNodesPerHistoryReadData { get; set; }
///
/// Indicates the maximum size of the nodesToRead array when a Client calls the HistoryRead
/// Service using the historyReadDetails EVENTS.
///
[DataMember(Order = 30)]
public uint MaxNodesPerHistoryReadEvents { get; set; }
///
/// Indicates the maximum size of the nodesToWrite array when a Client calls the Write Service.
///
[DataMember(Order = 40)]
public uint MaxNodesPerWrite { get; set; }
///
/// Indicates the maximum size of the historyUpdateDetails array supported by the Server
/// when a Client calls the HistoryUpdate Service.
///
[DataMember(Order = 50)]
public uint MaxNodesPerHistoryUpdateData { get; set; }
///
/// Indicates the maximum size of the historyUpdateDetails array
/// when a Client calls the HistoryUpdate Service.
///
[DataMember(Order = 60)]
public uint MaxNodesPerHistoryUpdateEvents { get; set; }
///
/// Indicates the maximum size of the methodsToCall array when a Client calls the Call Service.
///
[DataMember(Order = 70)]
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.
///
[DataMember(Order = 80)]
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.
///
[DataMember(Order = 90)]
public uint MaxNodesPerRegisterNodes { get; set; }
///
/// Indicates the maximum size of the browsePaths array when a Client calls the TranslateBrowsePathsToNodeIds Service.
///
[DataMember(Order = 100)]
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.
///
[DataMember(Order = 110)]
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.
///
[DataMember(Order = 120)]
public uint MaxMonitoredItemsPerCall { get; set; }
}
///
/// Stores the configuration of the reverse connections.
///
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public class ReverseConnectClient
{
///
/// The default constructor.
///
public ReverseConnectClient()
{
Initialize();
}
///
/// Initializes the object during deserialization.
///
[OnDeserializing]
private void Initialize(StreamingContext context)
{
Initialize();
}
///
/// Sets private members to default values.
///
private void Initialize()
{
Enabled = true;
}
///
/// The endpoint Url of the reverse connect client endpoint.
///
[DataMember(Order = 10)]
public string EndpointUrl { get; set; }
///
/// The timeout to wait for a response to a reverse connection.
/// Overrides the default reverse connection setting.
///
[DataMember(Order = 20)]
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.
///
[DataMember(Order = 30)]
public int MaxSessionCount { get; set; }
///
/// Specifies whether the sending of reverse connect attempts is enabled.
///
[DataMember(Order = 40)]
public bool Enabled { get; set; } = true;
}
///
/// A collection of reverse connect clients.
///
[CollectionDataContract(
Name = "ListOfReverseConnectClient",
Namespace = Namespaces.OpcUaConfig,
ItemName = "ReverseConnectClient"
)]
public class ReverseConnectClientCollection : List
{
///
/// Initializes an empty collection.
///
public ReverseConnectClientCollection()
{
}
///
/// Initializes the collection from another collection.
///
/// A collection of values to add to this new collection
///
/// is null.
///
public ReverseConnectClientCollection(IEnumerable collection)
: base(collection)
{
}
///
/// Initializes the collection with the specified capacity.
///
/// The capacity.
public ReverseConnectClientCollection(int capacity)
: base(capacity)
{
}
}
///
/// The configuration for a client application.
///
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public partial class ClientConfiguration
{
///
/// The default constructor.
///
public ClientConfiguration()
{
Initialize();
}
///
/// Sets private members to default values.
///
private void Initialize()
{
DefaultSessionTimeout = 60000;
MinSubscriptionLifetime = 10000;
m_wellKnownDiscoveryUrls = [];
m_discoveryServers = [];
OperationLimits = new OperationLimits();
}
///
/// Initializes the object during deserialization.
///
/// The context.
[OnDeserializing]
public void Initialize(StreamingContext context)
{
Initialize();
}
///
/// The default session timeout (in milliseconds).
///
/// The default session timeout.
[DataMember(IsRequired = false, Order = 0)]
public int DefaultSessionTimeout { get; set; }
///
/// The well known URLs for the local discovery servers.
///
/// The well known discovery URLs.
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 1)]
public StringCollection WellKnownDiscoveryUrls
{
get => m_wellKnownDiscoveryUrls;
set => m_wellKnownDiscoveryUrls = value ?? [];
}
///
/// The endpoint descriptions for central discovery servers.
///
/// The endpoint descriptions for central discovery servers.
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 2)]
public EndpointDescriptionCollection 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.
[DataMember(IsRequired = false, Order = 3)]
public string EndpointCacheFilePath { get; set; }
///
/// The minimum lifetime for a subscription (in milliseconds).
///
/// The minimum lifetime for a subscription.
[DataMember(IsRequired = false, Order = 4)]
public int MinSubscriptionLifetime { get; set; }
///
/// The reverse connect Client configuration.
///
[DataMember(IsRequired = false, Order = 5)]
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.
///
[DataMember(IsRequired = false, Order = 6)]
public OperationLimits OperationLimits { get; set; }
private StringCollection m_wellKnownDiscoveryUrls;
private EndpointDescriptionCollection m_discoveryServers;
}
///
/// Stores the configuration of the reverse connections.
///
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public class ReverseConnectClientConfiguration
{
///
/// A collection of reverse connect client endpoints.
///
[DataMember(Order = 10, IsRequired = false)]
public ReverseConnectClientEndpointCollection ClientEndpoints { get; set; }
///
/// The time a reverse hello port is held open to wait for a
/// reverse connection until the request is rejected.
///
[DataMember(Order = 20, IsRequired = false)]
public int HoldTime { get; set; } = 15000;
///
/// The timeout to wait for a reverse hello message.
///
[DataMember(Order = 30, IsRequired = false)]
public int WaitTimeout { get; set; } = 20000;
}
///
/// Stores the configuration of the reverse connections.
///
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public class ReverseConnectClientEndpoint
{
///
/// The endpoint Url of a reverse connect client.
///
[DataMember(Order = 1, IsRequired = false)]
public string EndpointUrl { get; set; }
}
///
/// A collection of reverse connect client endpoints.
///
[CollectionDataContract(
Name = "ListOfReverseConnectClientEndpoint",
Namespace = Namespaces.OpcUaConfig,
ItemName = "ClientEndpoint"
)]
public class ReverseConnectClientEndpointCollection : List
{
///
/// Initializes an empty collection.
///
public ReverseConnectClientEndpointCollection()
{
}
///
/// Initializes the collection from another collection.
///
/// A collection of values to add to this new collection
///
/// is null.
///
public ReverseConnectClientEndpointCollection(
IEnumerable collection)
: base(collection)
{
}
///
/// Initializes the collection with the specified capacity.
///
/// The capacity.
public ReverseConnectClientEndpointCollection(int capacity)
: base(capacity)
{
}
}
///
/// Specifies the configuration for a discovery server application.
///
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public class DiscoveryServerConfiguration : ServerBaseConfiguration
{
///
/// The default constructor.
///
public DiscoveryServerConfiguration()
{
Initialize();
}
///
/// Sets private members to default values.
///
private void Initialize()
{
m_serverNames = [];
ServerRegistrations = [];
}
///
/// Initializes the object during deserialization.
///
/// The context.
[OnDeserializing]
public new void Initialize(StreamingContext context)
{
Initialize();
}
///
/// The localized names for the discovery server.
///
/// The server names.
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 2)]
public LocalizedTextCollection ServerNames
{
get => m_serverNames;
set => m_serverNames = value ?? [];
}
///
/// The path to the file containing servers saved by the discovery server.
///
/// The discovery server cache file.
[DataMember(IsRequired = false, Order = 3)]
public string DiscoveryServerCacheFile { get; set; }
///
/// Gets or sets the server registrations associated with the discovery server.
///
/// The server registrations.
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 4)]
public ServerRegistrationCollection ServerRegistrations { get; set; }
private LocalizedTextCollection m_serverNames;
}
///
/// Specifies the configuration for a discovery server application.
///
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public class ServerRegistration
{
///
/// The default constructor.
///
public ServerRegistration()
{
Initialize();
}
///
/// Sets private members to default values.
///
private void Initialize()
{
ApplicationUri = null;
m_alternateDiscoveryUrls = [];
}
///
/// Initializes the object during deserialization.
///
/// The context.
[OnDeserializing]
public void Initialize(StreamingContext context)
{
Initialize();
}
///
/// Gets or sets the application URI of the server which the registration applies to.
///
/// The application uri.
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 1)]
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.
///
///
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 2)]
public StringCollection AlternateDiscoveryUrls
{
get => m_alternateDiscoveryUrls;
set => m_alternateDiscoveryUrls = value ?? [];
}
private StringCollection m_alternateDiscoveryUrls;
}
///
/// A collection of AdditionalServerRegistrationInfo objects.
///
[CollectionDataContract(
Name = "ListOfServerRegistration",
Namespace = Namespaces.OpcUaConfig,
ItemName = "ServerRegistration"
)]
public class ServerRegistrationCollection : List
{
///
/// Initializes an empty collection.
///
public ServerRegistrationCollection()
{
}
///
/// Initializes the collection from another collection.
///
/// A collection of values to add to this new collection
///
/// is null.
///
public ServerRegistrationCollection(IEnumerable collection)
: base(collection)
{
}
///
/// Initializes the collection with the specified capacity.
///
/// The capacity.
public ServerRegistrationCollection(int capacity)
: base(capacity)
{
}
}
///
/// Describes a certificate store.
///
[DataContract(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.
///
[DataMember(IsRequired = false, EmitDefaultValue = false, 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.
///
[DataMember(IsRequired = false, EmitDefaultValue = false, 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.
///
[DataMember(
Name = "ValidationOptions",
IsRequired = false,
EmitDefaultValue = false,
Order = 4)]
internal int XmlEncodedValidationOptions
{
get => (int)ValidationOptions;
set => ValidationOptions = (CertificateValidationOptions)value;
}
private string m_storePath;
}
[DataContract(Namespace = Namespaces.OpcUaConfig)]
[KnownType(typeof(CertificateTrustList))]
public partial class CertificateTrustList : CertificateStoreIdentifier
{
///
/// The default constructor.
///
public CertificateTrustList()
{
Initialize();
}
///
/// Sets private members to default values.
///
private void Initialize()
{
m_trustedCertificates = [];
}
///
/// Initializes the object during deserialization.
///
[OnDeserializing]
public void Initialize(StreamingContext context)
{
Initialize();
}
///
/// The list of trusted certificates.
///
///
/// The list of trusted certificates is set when TrustedCertificates is not a null value,
/// otherwise new CertificateIdentifierCollection is set.
///
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 3)]
public CertificateIdentifierCollection TrustedCertificates
{
get => m_trustedCertificates;
set => m_trustedCertificates = value ?? [];
}
private CertificateIdentifierCollection m_trustedCertificates;
}
[CollectionDataContract(
Name = "ApplicationCertificates",
Namespace = Namespaces.OpcUaConfig,
ItemName = "CertificateIdentifier"
)]
public partial class CertificateIdentifierCollection : List
{
///
/// Initializes an empty collection.
///
public CertificateIdentifierCollection()
{
}
///
/// Initializes the collection from another collection.
///
/// A collection of values to add to this new collection
public CertificateIdentifierCollection(IEnumerable collection)
: base(collection)
{
}
///
/// Initializes the collection with the specified capacity.
///
public CertificateIdentifierCollection(int capacity)
: base(capacity)
{
}
}
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public partial class CertificateIdentifier
{
///
/// The default constructor.
///
public CertificateIdentifier()
{
}
///
/// Initializes the identifier with the raw data from a certificate.
///
public CertificateIdentifier(X509Certificate2 certificate)
{
Certificate = certificate;
}
///
/// Initializes the identifier with the raw data from a certificate.
///
public CertificateIdentifier(
X509Certificate2 certificate,
CertificateValidationOptions validationOptions)
{
Certificate = certificate;
ValidationOptions = validationOptions;
}
///
/// Initializes the identifier with the raw data from a certificate.
///
public CertificateIdentifier(byte[] rawData)
{
Certificate = CertificateFactory.Create(rawData);
}
///
/// The type of certificate store.
///
/// The type of the store - defined in the .
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 10)]
public string StoreType { get; set; }
///
/// The path that identifies the certificate store.
///
/// The store path in the form StoreName\\Store Location .
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 15)]
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.
///
///
/// The distinguished name of an X509 certificate acording to the Abstract Syntax Notation One (ASN.1) syntax.
///
/// The subject field identifies the entity associated with the public key stored in the subject public
/// key field. The subject name MAY be carried in the subject field and/or the subjectAltName extension.
/// Where it is non-empty, the subject field MUST contain an X.500 distinguished name (DN).
/// Name is defined by the following ASN.1 structures:
/// Name ::= CHOICE {RDNSequence }
/// RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
/// RelativeDistinguishedName ::= SET OF AttributeTypeAndValue
/// AttributeTypeAndValue ::= SEQUENCE {type AttributeType, value AttributeValue }
/// AttributeType ::= OBJECT IDENTIFIER
/// AttributeValue ::= ANY DEFINED BY AttributeType
/// DirectoryString ::= CHOICE {
/// teletexString TeletexString (SIZE (1..MAX)),
/// printableString PrintableString (SIZE (1..MAX)),
/// universalString UniversalString (SIZE (1..MAX)),
/// utf8String UTF8String (SIZE (1..MAX)),
/// bmpString BMPString (SIZE (1..MAX)) }
/// The Name describes a hierarchical name composed of attributes, such as country name, and
/// corresponding values, such as US. The type of the component AttributeValue is determined by
/// the AttributeType; in general it will be a DirectoryString.
/// String X.500 AttributeType:
///
/// - CN commonName
/// - L localityName
/// - ST stateOrProvinceName
/// - O organizationName
/// - OU organizationalUnitName
/// - C countryName
/// - STREET streetAddress
/// - DC domainComponent
/// - UID userid
///
///
/// This notation is designed to be convenient for common forms of name. This section gives a few
/// examples of distinguished names written using this notation. First is a name containing three relative
/// distinguished names (RDNs):
/// CN=Steve Kille,O=Isode Limited,C=GB
///
///
/// RFC 3280 Internet X.509 Public Key Infrastructure, April 2002
/// RFC 2253 LADPv3 Distinguished Names, December 1997
///
///
///
///
///
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 40)]
public string SubjectName
{
get
{
if (m_certificate == null)
{
return m_subjectName;
}
return m_certificate.Subject;
}
set
{
if (m_certificate != null &&
!string.IsNullOrEmpty(value) &&
m_certificate.Subject != value)
{
throw new ArgumentException(
"SubjectName does not match the SubjectName of the current certificate.");
}
m_subjectName = value;
}
}
///
/// The certificate's thumbprint.
///
/// The thumbprint of a certificate..
///
///
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 50)]
public string Thumbprint
{
get
{
if (m_certificate == null)
{
return m_thumbprint;
}
return m_certificate.Thumbprint;
}
set
{
if (m_certificate != null &&
!string.IsNullOrEmpty(value) &&
m_certificate.Thumbprint != value)
{
throw new ArgumentException(
"Thumbprint does not match the thumbprint of the current certificate.");
}
m_thumbprint = value;
}
}
///
/// Gets the DER encoded certificate data or create embedded in this instance certificate using the DER encoded certificate data.
///
/// A byte array containing the X.509 certificate data.
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 60)]
public byte[] RawData
{
get
{
if (m_certificate == null)
{
return null;
}
return m_certificate.RawData;
}
set
{
if (value == null || value.Length == 0)
{
m_certificate = null;
return;
}
m_certificate = CertificateFactory.Create(value);
m_subjectName = m_certificate.Subject;
m_thumbprint = m_certificate.Thumbprint;
CertificateType = GetCertificateType(m_certificate);
}
}
///
/// Gets or sets the XML encoded validation options - use to serialize the validation options.
///
/// The XML encoded validation options.
[DataMember(
Name = "ValidationOptions",
IsRequired = false,
EmitDefaultValue = false,
Order = 70)]
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.
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 80)]
public NodeId CertificateType { get; set; }
///
/// The string representation of the certificate
///
/// Rsa, RsaMin, RsaSha256, NistP256, NistP384, BrainpoolP256r1, BrainpoolP384r1, Curve25519, Curve448
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 90)]
public string CertificateTypeString
{
get => EncodeCertificateType(CertificateType);
set => CertificateType = DecodeCertificateType(value);
}
private string m_storePath;
private string m_subjectName;
private string m_thumbprint;
private X509Certificate2 m_certificate;
}
///
/// Stores a list of cached endpoints.
///
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public partial class ConfiguredEndpointCollection
{
///
/// The default constructor.
///
public ConfiguredEndpointCollection()
{
Initialize();
}
///
/// Called by the .NET framework during deserialization.
///
[OnDeserializing]
public void Initialize(StreamingContext context)
{
Initialize();
}
///
/// Sets private members to default values.
///
private void Initialize()
{
m_knownHosts = [];
m_discoveryUrls = [.. Utils.DiscoveryUrls];
m_endpoints = [];
DefaultConfiguration = EndpointConfiguration.Create();
}
///
/// A list of known hosts that can be used for discovery.
///
[DataMember(Name = "KnownHosts", IsRequired = false, Order = 1)]
public StringCollection KnownHosts
{
get => m_knownHosts;
set => m_knownHosts = value ?? [];
}
///
/// The default configuration to use when connecting to an endpoint.
///
[DataMember(Name = "Endpoints", IsRequired = false, Order = 2)]
public List Endpoints
{
get => m_endpoints;
private set
{
m_endpoints = value ?? [];
foreach (ConfiguredEndpoint endpoint in m_endpoints)
{
endpoint.Collection = this;
}
}
}
///
/// The URL of the UA TCP proxy server.
///
[DataMember(Name = "TcpProxyUrl", EmitDefaultValue = false, Order = 3)]
public Uri TcpProxyUrl { get; set; }
private string m_filepath;
private StringCollection m_knownHosts;
private StringCollection m_discoveryUrls;
private List m_endpoints;
}
///
/// Stores the configuration information for an endpoint.
///
[DataContract(Namespace = Namespaces.OpcUaConfig)]
[KnownType(typeof(UserNameIdentityToken))]
[KnownType(typeof(X509IdentityToken))]
[KnownType(typeof(IssuedIdentityToken))]
public partial class ConfiguredEndpoint
{
///
/// The default constructor.
///
public ConfiguredEndpoint()
{
Initialize();
}
///
/// Called by the .NET framework during deserialization.
///
[OnDeserializing]
public void Initialize(StreamingContext context)
{
Initialize();
}
///
/// Sets private members to default values.
///
private void Initialize()
{
m_collection = null;
m_description = new EndpointDescription();
m_configuration = null;
UpdateBeforeConnect = true;
BinaryEncodingSupport = BinaryEncodingSupport.Optional;
SelectedUserTokenPolicyIndex = 0;
UserIdentity = null;
ReverseConnect = null;
}
///
/// The description for the endpoint.
///
[DataMember(Name = "Endpoint", Order = 1, IsRequired = true)]
public EndpointDescription Description
{
get => m_description;
private set => m_description = value ?? new EndpointDescription();
}
///
/// The configuration to use when connecting to an endpoint.
///
[DataMember(Name = "Configuration", Order = 2, IsRequired = false)]
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.
///
[DataMember(Name = "UpdateBeforeConnect", Order = 3, IsRequired = false)]
public bool UpdateBeforeConnect { get; set; }
///
/// The user identity to use when connecting to the endpoint.
///
[DataMember(Name = "BinaryEncodingSupport", Order = 4, IsRequired = false)]
public BinaryEncodingSupport BinaryEncodingSupport { get; set; }
///
/// The user identity to use when connecting to the endpoint.
///
[DataMember(Name = "SelectedUserTokenPolicy", Order = 5, IsRequired = false)]
public int SelectedUserTokenPolicyIndex { get; set; }
///
/// The user identity to use when connecting to the endpoint.
///
[DataMember(Name = "UserIdentity", Order = 6, IsRequired = false)]
public UserIdentityToken UserIdentity { get; set; }
///
/// The reverse connect information.
///
[DataMember(Name = "ReverseConnect", Order = 8, IsRequired = false)]
public ReverseConnectEndpoint ReverseConnect { get; set; }
///
/// A bucket to store additional application specific configuration data.
///
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 9)]
public XmlElementCollection Extensions
{
get => m_extensions;
set => m_extensions = value;
}
private ConfiguredEndpointCollection m_collection;
private EndpointDescription m_description;
private EndpointConfiguration m_configuration;
private XmlElementCollection m_extensions;
}
///
/// The type of binary encoding support allowed by a channel.
///
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public enum BinaryEncodingSupport
{
///
/// The UA binary encoding may be used.
///
[EnumMember]
Optional,
///
/// The UA binary encoding must be used.
///
[EnumMember]
Required,
///
/// The UA binary encoding may not be used.
///
[EnumMember]
None
}
///
/// Stores the reverse connect information for an endpoint.
///
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public class ReverseConnectEndpoint
{
///
/// The default constructor.
///
public ReverseConnectEndpoint()
{
Initialize();
}
///
/// Called by the .NET framework during deserialization.
///
[OnDeserializing]
public void Initialize(StreamingContext context)
{
Initialize();
}
///
/// Sets private members to default values.
///
private void Initialize()
{
Enabled = false;
ServerUri = null;
Thumbprint = null;
}
///
/// Whether reverse connect is enabled for the endpoint.
///
[DataMember(Name = "Enabled", Order = 1, IsRequired = false)]
public bool Enabled { get; set; }
///
/// The server Uri of the endpoint.
///
[DataMember(Name = "ServerUri", Order = 2, IsRequired = false)]
public string ServerUri { get; set; }
///
/// The thumbprint of the certificate which contains
/// the server Uri.
///
[DataMember(Name = "Thumbprint", Order = 3, IsRequired = false)]
public string Thumbprint { get; set; }
}
}