mirror of
https://github.com/OPCFoundation/UA-.NETStandard.git
synced 2026-10-22 17:50:03 +08:00
3a378e8644
Headers incorrectly state that the RCL applies to members, however the OPC Source Deliverables license states RCL is applicable only to corporate members. The OPC Foundation Technical Control Board on March 30th decided on the following changes with regard of the license headers: • Change the dual license in the source files so that “members” are replaced with “corporate members”. Co-authored-by: Suciu Mircea Adrian <Mircea-Adrian.Suciu@softing.com>
3557 lines
122 KiB
C#
3557 lines
122 KiB
C#
/* Copyright (c) 1996-2022 The OPC Foundation. All rights reserved.
|
|
The source code in this file is covered under a dual-license scenario:
|
|
- RCL: for OPC Foundation Corporate Members in good-standing
|
|
- GPL V2: everybody else
|
|
RCL license terms accompanied with this source code. See http://opcfoundation.org/License/RCL/1.00/
|
|
GNU General Public License as published by the Free Software Foundation;
|
|
version 2 of the License are accompanied with this source code. See http://opcfoundation.org/License/GPLv2
|
|
This source code is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
*/
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.Serialization;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
|
|
namespace Opc.Ua
|
|
{
|
|
#region ApplicationConfiguration
|
|
/// <summary>
|
|
/// Stores the configurable configuration information for a UA application.
|
|
/// </summary>
|
|
[DataContract(Namespace = Namespaces.OpcUaConfig)]
|
|
public partial class ApplicationConfiguration
|
|
{
|
|
#region Constructors
|
|
/// <summary>
|
|
/// The default constructor.
|
|
/// </summary>
|
|
public ApplicationConfiguration()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
/// <summary>
|
|
/// The constructor from a template.
|
|
/// </summary>
|
|
public ApplicationConfiguration(ApplicationConfiguration template)
|
|
{
|
|
Initialize();
|
|
|
|
m_applicationName = template.m_applicationName;
|
|
m_applicationType = template.m_applicationType;
|
|
m_applicationUri = template.m_applicationUri;
|
|
m_discoveryServerConfiguration = template.m_discoveryServerConfiguration;
|
|
m_securityConfiguration = template.m_securityConfiguration;
|
|
m_transportConfigurations = template.m_transportConfigurations;
|
|
m_serverConfiguration = template.m_serverConfiguration;
|
|
m_clientConfiguration = template.m_clientConfiguration;
|
|
m_disableHiResClock = template.m_disableHiResClock;
|
|
m_certificateValidator = template.m_certificateValidator;
|
|
m_transportQuotas = template.m_transportQuotas;
|
|
m_traceConfiguration = template.m_traceConfiguration;
|
|
m_extensions = template.m_extensions;
|
|
m_extensionObjects = template.m_extensionObjects;
|
|
m_sourceFilePath = template.m_sourceFilePath;
|
|
m_messageContext = template.m_messageContext;
|
|
m_properties = template.m_properties;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets private members to default values.
|
|
/// </summary>
|
|
private void Initialize()
|
|
{
|
|
m_sourceFilePath = null;
|
|
m_securityConfiguration = new SecurityConfiguration();
|
|
m_transportConfigurations = new TransportConfigurationCollection();
|
|
m_disableHiResClock = false;
|
|
m_properties = new Dictionary<string, object>();
|
|
m_certificateValidator = new CertificateValidator();
|
|
m_extensionObjects = new List<object>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes the object during deserialization.
|
|
/// </summary>
|
|
/// <param name="context">The context.</param>
|
|
[OnDeserializing()]
|
|
public void Initialize(StreamingContext context) => Initialize();
|
|
#endregion
|
|
|
|
#region Public Properties
|
|
/// <summary>
|
|
/// Gets an object used to synchronize access to the properties dictionary.
|
|
/// </summary>
|
|
/// <value>
|
|
/// The object used to synchronize access to the properties dictionary.
|
|
/// </value>
|
|
public object PropertiesLock => m_properties;
|
|
|
|
/// <summary>
|
|
/// Gets a dictionary used to save state associated with the application.
|
|
/// </summary>
|
|
/// <value>
|
|
/// The dictionary used to save state associated with the application.
|
|
/// </value>
|
|
public IDictionary<string, object> Properties => m_properties;
|
|
|
|
/// <summary>
|
|
/// Storage for decoded extensions of the application.
|
|
/// Used by ParseExtension if no matching XmlElement is found.
|
|
/// </summary>
|
|
public IList<object> ExtensionObjects => m_extensionObjects;
|
|
#endregion
|
|
|
|
#region Persistent Properties
|
|
/// <summary>
|
|
/// A descriptive name for the application (not necessarily unique).
|
|
/// </summary>
|
|
/// <value>The name of the application.</value>
|
|
[DataMember(IsRequired = true, EmitDefaultValue = false, Order = 0)]
|
|
public string ApplicationName
|
|
{
|
|
get { return m_applicationName; }
|
|
set { m_applicationName = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// A unique identifier for the application instance.
|
|
/// </summary>
|
|
/// <value>The application URI.</value>
|
|
[DataMember(IsRequired = true, EmitDefaultValue = false, Order = 1)]
|
|
public string ApplicationUri
|
|
{
|
|
get { return m_applicationUri; }
|
|
set { m_applicationUri = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// A unique identifier for the product.
|
|
/// </summary>
|
|
/// <value>The product URI.</value>
|
|
[DataMember(IsRequired = false, Order = 2)]
|
|
public string ProductUri
|
|
{
|
|
get { return m_productUri; }
|
|
set { m_productUri = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The type of application.
|
|
/// </summary>
|
|
/// <value>The type of the application.</value>
|
|
[DataMember(IsRequired = true, Order = 3)]
|
|
public ApplicationType ApplicationType
|
|
{
|
|
get { return m_applicationType; }
|
|
set { m_applicationType = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The security configuration for the application.
|
|
/// </summary>
|
|
/// <value>The security configuration.</value>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = true, Order = 4)]
|
|
public SecurityConfiguration SecurityConfiguration
|
|
{
|
|
get
|
|
{
|
|
return m_securityConfiguration;
|
|
}
|
|
|
|
set
|
|
{
|
|
m_securityConfiguration = value ?? new SecurityConfiguration();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The transport configuration for the application.
|
|
/// </summary>
|
|
/// <value>The transport configurations.</value>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = true, Order = 5)]
|
|
public TransportConfigurationCollection TransportConfigurations
|
|
{
|
|
get
|
|
{
|
|
return m_transportConfigurations;
|
|
}
|
|
|
|
set
|
|
{
|
|
m_transportConfigurations = value ?? new TransportConfigurationCollection();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The quotas that are used at the transport layer.
|
|
/// </summary>
|
|
/// <value>The transport quotas.</value>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = true, Order = 6)]
|
|
public TransportQuotas TransportQuotas
|
|
{
|
|
get { return m_transportQuotas; }
|
|
set { m_transportQuotas = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Additional configuration for server applications.
|
|
/// </summary>
|
|
/// <value>The server configuration.</value>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 7)]
|
|
public ServerConfiguration ServerConfiguration
|
|
{
|
|
get { return m_serverConfiguration; }
|
|
set { m_serverConfiguration = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Additional configuration for client applications.
|
|
/// </summary>
|
|
/// <value>The client configuration.</value>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 8)]
|
|
public ClientConfiguration ClientConfiguration
|
|
{
|
|
get { return m_clientConfiguration; }
|
|
set { m_clientConfiguration = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Additional configuration of the discovery server.
|
|
/// </summary>
|
|
/// <value>The discovery server configuration.</value>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 9)]
|
|
public DiscoveryServerConfiguration DiscoveryServerConfiguration
|
|
{
|
|
get { return m_discoveryServerConfiguration; }
|
|
set { m_discoveryServerConfiguration = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// A bucket to store additional application specific configuration data.
|
|
/// </summary>
|
|
/// <value>The extensions.</value>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 10)]
|
|
public XmlElementCollection Extensions
|
|
{
|
|
get { return m_extensions; }
|
|
set { m_extensions = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Configuration of the trace and information about log file
|
|
/// </summary>
|
|
/// <value>The trace configuration.</value>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 11)]
|
|
public TraceConfiguration TraceConfiguration
|
|
{
|
|
get { return m_traceConfiguration; }
|
|
set { m_traceConfiguration = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Disabling / enabling high resolution clock
|
|
/// </summary>
|
|
/// <value><c>true</c> if high resolution clock is disabled; otherwise, <c>false</c>.</value>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 12)]
|
|
public bool DisableHiResClock
|
|
{
|
|
get { return m_disableHiResClock; }
|
|
set { m_disableHiResClock = value; }
|
|
}
|
|
#endregion
|
|
|
|
#region Private Fields
|
|
private string m_applicationName;
|
|
private string m_applicationUri;
|
|
private string m_productUri;
|
|
private ApplicationType m_applicationType;
|
|
|
|
private SecurityConfiguration m_securityConfiguration;
|
|
private TransportConfigurationCollection m_transportConfigurations;
|
|
|
|
private TransportQuotas m_transportQuotas;
|
|
private ServerConfiguration m_serverConfiguration;
|
|
private ClientConfiguration m_clientConfiguration;
|
|
private DiscoveryServerConfiguration m_discoveryServerConfiguration;
|
|
private TraceConfiguration m_traceConfiguration;
|
|
private bool m_disableHiResClock;
|
|
private XmlElementCollection m_extensions;
|
|
private List<object> m_extensionObjects;
|
|
private string m_sourceFilePath;
|
|
|
|
private IServiceMessageContext m_messageContext;
|
|
private CertificateValidator m_certificateValidator;
|
|
private Dictionary<string, object> m_properties;
|
|
#endregion
|
|
}
|
|
#endregion
|
|
|
|
#region TransportQuotas Class
|
|
/// <summary>
|
|
/// Specifies various limits that apply to the transport or secure channel layers.
|
|
/// </summary>
|
|
[DataContract(Namespace = Namespaces.OpcUaConfig)]
|
|
public class TransportQuotas
|
|
{
|
|
#region Constructors
|
|
/// <summary>
|
|
/// The default constructor.
|
|
/// </summary>
|
|
public TransportQuotas()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets private members to default values.
|
|
/// </summary>
|
|
private void Initialize()
|
|
{
|
|
m_operationTimeout = 120000;
|
|
m_maxStringLength = 65535;
|
|
m_maxByteStringLength = 65535;
|
|
m_maxArrayLength = 65535;
|
|
m_maxMessageSize = 1048576;
|
|
m_maxBufferSize = 65535;
|
|
m_channelLifetime = 600000;
|
|
m_securityTokenLifetime = 3600000;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes the object during deserialization.
|
|
/// </summary>
|
|
/// <param name="context">The context.</param>
|
|
[OnDeserializing()]
|
|
public void Initialize(StreamingContext context) => Initialize();
|
|
#endregion
|
|
|
|
#region Persistent Properties
|
|
/// <summary>
|
|
/// The default timeout to use when sending requests (in milliseconds).
|
|
/// </summary>
|
|
/// <value>The operation timeout.</value>
|
|
[DataMember(IsRequired = false, Order = 0)]
|
|
public int OperationTimeout
|
|
{
|
|
get { return m_operationTimeout; }
|
|
set { m_operationTimeout = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The maximum length of string encoded in a message body.
|
|
/// </summary>
|
|
/// <value>The max length of the string.</value>
|
|
[DataMember(IsRequired = false, Order = 1)]
|
|
public int MaxStringLength
|
|
{
|
|
get { return m_maxStringLength; }
|
|
set { m_maxStringLength = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The maximum length of a byte string encoded in a message body.
|
|
/// </summary>
|
|
/// <value>The max length of the byte string.</value>
|
|
[DataMember(IsRequired = false, Order = 2)]
|
|
public int MaxByteStringLength
|
|
{
|
|
get { return m_maxByteStringLength; }
|
|
set { m_maxByteStringLength = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The maximum length of an array encoded in a message body.
|
|
/// </summary>
|
|
/// <value>The max length of the array.</value>
|
|
[DataMember(IsRequired = false, Order = 3)]
|
|
public int MaxArrayLength
|
|
{
|
|
get { return m_maxArrayLength; }
|
|
set { m_maxArrayLength = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The maximum length of a message body.
|
|
/// </summary>
|
|
/// <value>The max size of the message.</value>
|
|
[DataMember(IsRequired = false, Order = 4)]
|
|
public int MaxMessageSize
|
|
{
|
|
get { return m_maxMessageSize; }
|
|
set { m_maxMessageSize = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The maximum size of the buffer to use when sending messages.
|
|
/// </summary>
|
|
/// <value>The max size of the buffer.</value>
|
|
[DataMember(IsRequired = false, Order = 5)]
|
|
public int MaxBufferSize
|
|
{
|
|
get { return m_maxBufferSize; }
|
|
set { m_maxBufferSize = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The lifetime of a secure channel (in milliseconds).
|
|
/// </summary>
|
|
/// <value>The channel lifetime.</value>
|
|
[DataMember(IsRequired = false, Order = 6)]
|
|
public int ChannelLifetime
|
|
{
|
|
get { return m_channelLifetime; }
|
|
set { m_channelLifetime = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The lifetime of a security token (in milliseconds).
|
|
/// </summary>
|
|
/// <value>The security token lifetime.</value>
|
|
[DataMember(IsRequired = false, Order = 7)]
|
|
public int SecurityTokenLifetime
|
|
{
|
|
get { return m_securityTokenLifetime; }
|
|
set { m_securityTokenLifetime = value; }
|
|
}
|
|
#endregion
|
|
|
|
#region Private Fields
|
|
private int m_operationTimeout;
|
|
private int m_maxStringLength;
|
|
private int m_maxByteStringLength;
|
|
private int m_maxArrayLength;
|
|
private int m_maxMessageSize;
|
|
private int m_maxBufferSize;
|
|
private int m_channelLifetime;
|
|
private int m_securityTokenLifetime;
|
|
#endregion
|
|
}
|
|
#endregion
|
|
|
|
#region TraceConfiguration Class
|
|
/// <summary>
|
|
/// Specifies parameters used for tracing.
|
|
/// </summary>
|
|
[DataContract(Namespace = Namespaces.OpcUaConfig)]
|
|
public partial class TraceConfiguration
|
|
{
|
|
#region Constructors
|
|
/// <summary>
|
|
/// The default constructor.
|
|
/// </summary>
|
|
public TraceConfiguration()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets private members to default values.
|
|
/// </summary>
|
|
private void Initialize()
|
|
{
|
|
m_outputFilePath = null;
|
|
m_deleteOnLoad = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes the object during deserialization.
|
|
/// </summary>
|
|
/// <param name="context">The context.</param>
|
|
[OnDeserializing()]
|
|
public void Initialize(StreamingContext context) => Initialize();
|
|
#endregion
|
|
|
|
#region Persistent Properties
|
|
/// <summary>
|
|
/// The output file used to log the trace information.
|
|
/// </summary>
|
|
/// <value>The output file path.</value>
|
|
[DataMember(IsRequired = false, Order = 0)]
|
|
public string OutputFilePath
|
|
{
|
|
get { return m_outputFilePath; }
|
|
set { m_outputFilePath = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Whether the existing log file should be deleted when the application configuration is loaded.
|
|
/// </summary>
|
|
/// <value><c>true</c> if existing log file should be deleted when the application configuration is loaded; otherwise, <c>false</c>.</value>
|
|
[DataMember(IsRequired = false, Order = 1)]
|
|
public bool DeleteOnLoad
|
|
{
|
|
get { return m_deleteOnLoad; }
|
|
set { m_deleteOnLoad = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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;
|
|
/// </summary>
|
|
/// <value>The trace masks.</value>
|
|
[DataMember(IsRequired = false, Order = 2)]
|
|
public int TraceMasks
|
|
{
|
|
get { return m_traceMasks; }
|
|
set { m_traceMasks = value; }
|
|
}
|
|
#endregion
|
|
|
|
#region Private Fields
|
|
private string m_outputFilePath;
|
|
private bool m_deleteOnLoad;
|
|
private int m_traceMasks;
|
|
#endregion
|
|
}
|
|
#endregion
|
|
|
|
#region TransportConfiguration Class
|
|
/// <summary>
|
|
/// Specifies the configuration information for a transport protocol
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Each application is allows to have one transport configure per protocol type.
|
|
/// </remarks>
|
|
[DataContract(Namespace = Namespaces.OpcUaConfig)]
|
|
public class TransportConfiguration
|
|
{
|
|
#region Constructors
|
|
/// <summary>
|
|
/// The default constructor.
|
|
/// </summary>
|
|
public TransportConfiguration()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// The default constructor.
|
|
/// </summary>
|
|
/// <param name="urlScheme">The URL scheme.</param>
|
|
/// <param name="type">The type.</param>
|
|
public TransportConfiguration(string urlScheme, Type type)
|
|
{
|
|
m_uriScheme = urlScheme;
|
|
m_typeName = type.AssemblyQualifiedName;
|
|
}
|
|
#endregion
|
|
|
|
#region Persistent Properties
|
|
/// <summary>
|
|
/// The URL prefix used by the application (http, opc.tcp, net.tpc, etc.).
|
|
/// </summary>
|
|
/// <value>The URI scheme.</value>
|
|
[DataMember(IsRequired = true, EmitDefaultValue = false, Order = 0)]
|
|
public string UriScheme
|
|
{
|
|
get { return m_uriScheme; }
|
|
set { m_uriScheme = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The name of the class that defines the binding for the transport.
|
|
/// </summary>
|
|
/// <value>The name of the type.</value>
|
|
/// <remarks>
|
|
/// 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)
|
|
/// </remarks>
|
|
[DataMember(IsRequired = true, EmitDefaultValue = false, Order = 1)]
|
|
public string TypeName
|
|
{
|
|
get { return m_typeName; }
|
|
set { m_typeName = value; }
|
|
}
|
|
#endregion
|
|
|
|
#region Private Fields
|
|
private string m_uriScheme;
|
|
private string m_typeName;
|
|
#endregion
|
|
}
|
|
#endregion
|
|
|
|
#region TransportConfigurationCollection Class
|
|
/// <summary>
|
|
/// A collection of TransportConfiguration objects.
|
|
/// </summary>
|
|
[CollectionDataContract(Name = "ListOfTransportConfiguration", Namespace = Namespaces.OpcUaConfig, ItemName = "TransportConfiguration")]
|
|
public partial class TransportConfigurationCollection : List<TransportConfiguration>
|
|
{
|
|
/// <summary>
|
|
/// Initializes an empty collection.
|
|
/// </summary>
|
|
public TransportConfigurationCollection() { }
|
|
|
|
/// <summary>
|
|
/// Initializes the collection from another collection.
|
|
/// </summary>
|
|
/// <param name="collection">A collection of values to add to this new collection</param>
|
|
/// <exception cref="ArgumentNullException">
|
|
/// <paramref name="collection"/> is null.
|
|
/// </exception>
|
|
public TransportConfigurationCollection(IEnumerable<TransportConfiguration> collection) : base(collection) { }
|
|
|
|
/// <summary>
|
|
/// Initializes the collection with the specified capacity.
|
|
/// </summary>
|
|
/// <param name="capacity">The capacity.</param>
|
|
public TransportConfigurationCollection(int capacity) : base(capacity) { }
|
|
}
|
|
#endregion
|
|
|
|
#region ServerSecurityPolicy Class
|
|
/// <summary>
|
|
/// A class that defines a group of sampling rates supported by the server.
|
|
/// </summary>
|
|
[DataContract(Namespace = Namespaces.OpcUaConfig)]
|
|
public class ServerSecurityPolicy
|
|
{
|
|
#region Constructors
|
|
/// <summary>
|
|
/// The default constructor.
|
|
/// </summary>
|
|
public ServerSecurityPolicy()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets private members to default values.
|
|
/// </summary>
|
|
private void Initialize()
|
|
{
|
|
m_securityMode = MessageSecurityMode.SignAndEncrypt;
|
|
m_securityPolicyUri = SecurityPolicies.Basic256Sha256;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes the object during deserialization.
|
|
/// </summary>
|
|
/// <param name="context">The context.</param>
|
|
[OnDeserializing()]
|
|
public void Initialize(StreamingContext context) => Initialize();
|
|
#endregion
|
|
|
|
#region Public Properties
|
|
/// <summary>
|
|
/// 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
|
|
/// </summary>
|
|
public static byte CalculateSecurityLevel(MessageSecurityMode mode, string policyUri)
|
|
{
|
|
if ((mode == MessageSecurityMode.Invalid) || (mode == MessageSecurityMode.None))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
byte result = 0;
|
|
switch (policyUri)
|
|
{
|
|
case SecurityPolicies.Basic128Rsa15: result = 2; break;
|
|
case SecurityPolicies.Basic256: result = 4; break;
|
|
case SecurityPolicies.Basic256Sha256: result = 6; break;
|
|
case SecurityPolicies.Aes128_Sha256_RsaOaep: result = 8; break;
|
|
case SecurityPolicies.Aes256_Sha256_RsaPss: result = 10; break;
|
|
case SecurityPolicies.None:
|
|
default: return 0;
|
|
}
|
|
|
|
if (mode == MessageSecurityMode.SignAndEncrypt)
|
|
{
|
|
result += 100;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Specifies whether the messages are signed and encrypted or simply signed
|
|
/// </summary>
|
|
/// <value>The security mode.</value>
|
|
[DataMember(IsRequired = false, Order = 1)]
|
|
public MessageSecurityMode SecurityMode
|
|
{
|
|
get { return m_securityMode; }
|
|
set { m_securityMode = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The security policy to use.
|
|
/// </summary>
|
|
/// <value>The security policy URI.</value>
|
|
[DataMember(IsRequired = false, Order = 2)]
|
|
public string SecurityPolicyUri
|
|
{
|
|
get { return m_securityPolicyUri; }
|
|
set { m_securityPolicyUri = value; }
|
|
}
|
|
#endregion
|
|
|
|
#region Private Members
|
|
private MessageSecurityMode m_securityMode;
|
|
private string m_securityPolicyUri;
|
|
#endregion
|
|
}
|
|
#endregion
|
|
|
|
#region ServerSecurityPolicyCollection Class
|
|
/// <summary>
|
|
/// A collection of ServerSecurityPolicy objects.
|
|
/// </summary>
|
|
[CollectionDataContract(Name = "ListOfServerSecurityPolicy", Namespace = Namespaces.OpcUaConfig, ItemName = "ServerSecurityPolicy")]
|
|
public partial class ServerSecurityPolicyCollection : List<ServerSecurityPolicy>
|
|
{
|
|
/// <summary>
|
|
/// Initializes an empty collection.
|
|
/// </summary>
|
|
public ServerSecurityPolicyCollection() { }
|
|
|
|
/// <summary>
|
|
/// Initializes the collection from another collection.
|
|
/// </summary>
|
|
/// <param name="collection">A collection of values to add to this new collection</param>
|
|
/// <exception cref="System.ArgumentNullException">
|
|
/// <paramref name="collection"/> is null.
|
|
/// </exception>
|
|
public ServerSecurityPolicyCollection(IEnumerable<ServerSecurityPolicy> collection) : base(collection) { }
|
|
|
|
/// <summary>
|
|
/// Initializes the collection with the specified capacity.
|
|
/// </summary>
|
|
/// <param name="capacity">The capacity.</param>
|
|
public ServerSecurityPolicyCollection(int capacity) : base(capacity) { }
|
|
}
|
|
#endregion
|
|
|
|
#region SecurityConfiguration Class
|
|
/// <summary>
|
|
/// The security configuration for the application.
|
|
/// </summary>
|
|
[DataContract(Namespace = Namespaces.OpcUaConfig)]
|
|
public partial class SecurityConfiguration
|
|
{
|
|
#region Constructors
|
|
/// <summary>
|
|
/// The default constructor.
|
|
/// </summary>
|
|
public SecurityConfiguration()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets private members to default values.
|
|
/// </summary>
|
|
private void Initialize()
|
|
{
|
|
m_trustedIssuerCertificates = new CertificateTrustList();
|
|
m_trustedPeerCertificates = new CertificateTrustList();
|
|
m_nonceLength = 32;
|
|
m_autoAcceptUntrustedCertificates = false;
|
|
m_rejectSHA1SignedCertificates = true;
|
|
m_rejectUnknownRevocationStatus = false;
|
|
m_minCertificateKeySize = CertificateFactory.DefaultKeySize;
|
|
m_addAppCertToTrustedStore = true;
|
|
m_sendCertificateChain = false;
|
|
m_suppressNonceValidationErrors = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes the object during deserialization.
|
|
/// </summary>
|
|
[OnDeserializing()]
|
|
public void Initialize(StreamingContext context) => Initialize();
|
|
#endregion
|
|
|
|
#region Persistent Properties
|
|
/// <summary>
|
|
/// The application instance certificate.
|
|
/// </summary>
|
|
/// <value>The application certificate.</value>
|
|
/// <remarks>
|
|
/// This certificate must contain the application uri.
|
|
/// For servers, URLs for each supported protocol must also be present.
|
|
/// </remarks>
|
|
[DataMember(IsRequired = true, EmitDefaultValue = false, Order = 0)]
|
|
public CertificateIdentifier ApplicationCertificate
|
|
{
|
|
get { return m_applicationCertificate; }
|
|
set { m_applicationCertificate = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The store containing any additional issuer certificates.
|
|
/// </summary>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 2)]
|
|
public CertificateTrustList TrustedIssuerCertificates
|
|
{
|
|
get
|
|
{
|
|
return m_trustedIssuerCertificates;
|
|
}
|
|
|
|
set
|
|
{
|
|
m_trustedIssuerCertificates = value ?? new CertificateTrustList();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The trusted certificate store.
|
|
/// </summary>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 4)]
|
|
public CertificateTrustList TrustedPeerCertificates
|
|
{
|
|
get
|
|
{
|
|
return m_trustedPeerCertificates;
|
|
}
|
|
|
|
set
|
|
{
|
|
m_trustedPeerCertificates = value ?? new CertificateTrustList();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The length of nonce in the CreateSession service.
|
|
/// </summary>
|
|
/// <value>
|
|
/// The length of nonce in the CreateSession service.
|
|
/// </value>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 6)]
|
|
public int NonceLength
|
|
{
|
|
get { return m_nonceLength; }
|
|
set { m_nonceLength = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// A store where invalid certificates can be placed for later review by the administrator.
|
|
/// </summary>
|
|
/// <value>
|
|
/// A store where invalid certificates can be placed for later review by the administrator.
|
|
/// </value>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 7)]
|
|
public CertificateStoreIdentifier RejectedCertificateStore
|
|
{
|
|
get { return m_rejectedCertificateStore; }
|
|
set { m_rejectedCertificateStore = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether untrusted certificates should be automatically accepted.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// 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.
|
|
/// </remarks>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 8)]
|
|
public bool AutoAcceptUntrustedCertificates
|
|
{
|
|
get { return m_autoAcceptUntrustedCertificates; }
|
|
set { m_autoAcceptUntrustedCertificates = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets a directory which contains files representing users roles.
|
|
/// </summary>
|
|
[DataMember(Order = 9)]
|
|
public string UserRoleDirectory
|
|
{
|
|
get { return m_userRoleDirectory; }
|
|
set { m_userRoleDirectory = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether SHA-1 signed certificates are accepted.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// This flag can be set to false by servers that accept SHA-1 signed certificates.
|
|
/// </remarks>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 10)]
|
|
public bool RejectSHA1SignedCertificates
|
|
{
|
|
get { return m_rejectSHA1SignedCertificates; }
|
|
set { m_rejectSHA1SignedCertificates = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether certificates with unavailable revocation lists are not accepted.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// This flag can be set to true by servers that must have a revocation list for each CA (even if empty).
|
|
/// </remarks>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 11)]
|
|
public bool RejectUnknownRevocationStatus
|
|
{
|
|
get { return m_rejectUnknownRevocationStatus; }
|
|
set { m_rejectUnknownRevocationStatus = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating which minimum certificate key strength is accepted.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// This value can be set to 1024, 2048 or 4096 by servers
|
|
/// </remarks>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 12)]
|
|
public ushort MinimumCertificateKeySize
|
|
{
|
|
get { return m_minCertificateKeySize; }
|
|
set { m_minCertificateKeySize = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether the application cert should be copied to the trusted store.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// It is useful for client/server applications running on the same host and sharing the cert store to autotrust.
|
|
/// </remarks>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 13)]
|
|
public bool AddAppCertToTrustedStore
|
|
{
|
|
get { return m_addAppCertToTrustedStore; }
|
|
set { m_addAppCertToTrustedStore = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether the application should send the complete certificate chain.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// If set to true the complete certificate chain will be sent for CA signed certificates.
|
|
/// </remarks>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 14)]
|
|
public bool SendCertificateChain
|
|
{
|
|
get { return m_sendCertificateChain; }
|
|
set { m_sendCertificateChain = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The store containing additional user issuer certificates.
|
|
/// </summary>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 15)]
|
|
public CertificateTrustList UserIssuerCertificates
|
|
{
|
|
get
|
|
{
|
|
return m_userIssuerCertificates;
|
|
}
|
|
|
|
set
|
|
{
|
|
m_userIssuerCertificates = value;
|
|
|
|
if (m_userIssuerCertificates == null)
|
|
{
|
|
m_userIssuerCertificates = new CertificateTrustList();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The store containing trusted user certificates.
|
|
/// </summary>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 16)]
|
|
public CertificateTrustList TrustedUserCertificates
|
|
{
|
|
get
|
|
{
|
|
return m_trustedUserCertificates;
|
|
}
|
|
|
|
set
|
|
{
|
|
m_trustedUserCertificates = value;
|
|
|
|
if (m_trustedUserCertificates == null)
|
|
{
|
|
m_trustedUserCertificates = new CertificateTrustList();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The store containing additional Https issuer certificates.
|
|
/// </summary>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 17)]
|
|
public CertificateTrustList HttpsIssuerCertificates
|
|
{
|
|
get
|
|
{
|
|
return m_httpsIssuerCertificates;
|
|
}
|
|
|
|
set
|
|
{
|
|
m_httpsIssuerCertificates = value;
|
|
|
|
if (m_httpsIssuerCertificates == null)
|
|
{
|
|
m_httpsIssuerCertificates = new CertificateTrustList();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The store containing trusted Https certificates.
|
|
/// </summary>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 18)]
|
|
public CertificateTrustList TrustedHttpsCertificates
|
|
{
|
|
get
|
|
{
|
|
return m_trustedHttpsCertificates;
|
|
}
|
|
|
|
set
|
|
{
|
|
m_trustedHttpsCertificates = value;
|
|
|
|
if (m_trustedHttpsCertificates == null)
|
|
{
|
|
m_trustedHttpsCertificates = new CertificateTrustList();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether the server nonce validation errors should be suppressed.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// 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.
|
|
/// </remarks>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 19)]
|
|
public bool SuppressNonceValidationErrors
|
|
{
|
|
get { return m_suppressNonceValidationErrors; }
|
|
set { m_suppressNonceValidationErrors = value; }
|
|
}
|
|
#endregion
|
|
|
|
#region Private Fields
|
|
private CertificateIdentifier m_applicationCertificate;
|
|
private CertificateTrustList m_trustedIssuerCertificates;
|
|
private CertificateTrustList m_trustedPeerCertificates;
|
|
private CertificateTrustList m_httpsIssuerCertificates;
|
|
private CertificateTrustList m_trustedHttpsCertificates;
|
|
private CertificateTrustList m_userIssuerCertificates;
|
|
private CertificateTrustList m_trustedUserCertificates;
|
|
private int m_nonceLength;
|
|
private CertificateStoreIdentifier m_rejectedCertificateStore;
|
|
private bool m_autoAcceptUntrustedCertificates;
|
|
private string m_userRoleDirectory;
|
|
private bool m_rejectSHA1SignedCertificates;
|
|
private bool m_rejectUnknownRevocationStatus;
|
|
private ushort m_minCertificateKeySize;
|
|
private bool m_addAppCertToTrustedStore;
|
|
private bool m_sendCertificateChain;
|
|
private bool m_suppressNonceValidationErrors;
|
|
#endregion
|
|
}
|
|
#endregion
|
|
|
|
#region SamplingRateGroup Class
|
|
/// <summary>
|
|
/// A class that defines a group of sampling rates supported by the server.
|
|
/// </summary>
|
|
[DataContract(Namespace = Namespaces.OpcUaConfig)]
|
|
public class SamplingRateGroup
|
|
{
|
|
#region Constructors
|
|
/// <summary>
|
|
/// The default constructor.
|
|
/// </summary>
|
|
public SamplingRateGroup()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a group with the specified settings.
|
|
/// </summary>
|
|
/// <param name="start">The start.</param>
|
|
/// <param name="increment">The increment.</param>
|
|
/// <param name="count">The count.</param>
|
|
public SamplingRateGroup(int start, int increment, int count)
|
|
{
|
|
m_start = start;
|
|
m_increment = increment;
|
|
m_count = count;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets private members to default values.
|
|
/// </summary>
|
|
private void Initialize()
|
|
{
|
|
m_start = 1000;
|
|
m_increment = 0;
|
|
m_count = 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes the object during deserialization.
|
|
/// </summary>
|
|
/// <param name="context">The context.</param>
|
|
[OnDeserializing()]
|
|
public void Initialize(StreamingContext context) => Initialize();
|
|
#endregion
|
|
|
|
#region Public Properties
|
|
/// <summary>
|
|
/// The first sampling rate in the group (in milliseconds).
|
|
/// </summary>
|
|
/// <value>The first sampling rate in the group (in milliseconds).</value>
|
|
[DataMember(IsRequired = false, Order = 1)]
|
|
public double Start
|
|
{
|
|
get { return m_start; }
|
|
set { m_start = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The increment between sampling rates in the group (in milliseconds).
|
|
/// </summary>
|
|
/// <value>The increment.</value>
|
|
/// <remarks>
|
|
/// An increment of 0 means the group only contains one sampling rate equal to the start.
|
|
/// </remarks>
|
|
[DataMember(IsRequired = false, Order = 2)]
|
|
public double Increment
|
|
{
|
|
get { return m_increment; }
|
|
set { m_increment = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The number of sampling rates in the group.
|
|
/// </summary>
|
|
/// <value>The count.</value>
|
|
/// <remarks>
|
|
/// A count of 0 means there is no limit.
|
|
/// </remarks>
|
|
[DataMember(IsRequired = false, Order = 3)]
|
|
public int Count
|
|
{
|
|
get { return m_count; }
|
|
set { m_count = value; }
|
|
}
|
|
#endregion
|
|
|
|
#region Private Members
|
|
private double m_start;
|
|
private double m_increment;
|
|
private int m_count;
|
|
#endregion
|
|
}
|
|
#endregion
|
|
|
|
#region SamplingRateGroupCollection Class
|
|
/// <summary>
|
|
/// A collection of SamplingRateGroup objects.
|
|
/// </summary>
|
|
[CollectionDataContract(Name = "ListOfSamplingRateGroup", Namespace = Namespaces.OpcUaConfig, ItemName = "SamplingRateGroup")]
|
|
public partial class SamplingRateGroupCollection : List<SamplingRateGroup>
|
|
{
|
|
/// <summary>
|
|
/// Initializes an empty collection.
|
|
/// </summary>
|
|
public SamplingRateGroupCollection() { }
|
|
|
|
/// <summary>
|
|
/// Initializes the collection from another collection.
|
|
/// </summary>
|
|
/// <param name="collection">A collection of values to add to this new collection</param>
|
|
/// <exception cref="ArgumentNullException">
|
|
/// <paramref name="collection"/> is null.
|
|
/// </exception>
|
|
public SamplingRateGroupCollection(IEnumerable<SamplingRateGroup> collection) : base(collection) { }
|
|
|
|
/// <summary>
|
|
/// Initializes the collection with the specified capacity.
|
|
/// </summary>
|
|
/// <param name="capacity">The capacity.</param>
|
|
public SamplingRateGroupCollection(int capacity) : base(capacity) { }
|
|
}
|
|
#endregion
|
|
|
|
#region ServerBaseConfiguration Class
|
|
/// <summary>
|
|
/// Specifies the configuration for a server application.
|
|
/// </summary>
|
|
[DataContract(Namespace = Namespaces.OpcUaConfig)]
|
|
public partial class ServerBaseConfiguration
|
|
{
|
|
#region Constructors
|
|
/// <summary>
|
|
/// The default constructor.
|
|
/// </summary>
|
|
public ServerBaseConfiguration()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets private members to default values.
|
|
/// </summary>
|
|
private void Initialize()
|
|
{
|
|
m_baseAddresses = new StringCollection();
|
|
m_alternateBaseAddresses = new StringCollection();
|
|
m_securityPolicies = new ServerSecurityPolicyCollection();
|
|
m_minRequestThreadCount = 10;
|
|
m_maxRequestThreadCount = 100;
|
|
m_maxQueuedRequestCount = 200;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes the object during deserialization.
|
|
/// </summary>
|
|
/// <param name="context">The context.</param>
|
|
[OnDeserializing()]
|
|
public void Initialize(StreamingContext context) => Initialize();
|
|
|
|
/// <summary>
|
|
/// Remove unsupported security policies and expand wild cards.
|
|
/// </summary>
|
|
[OnDeserialized()]
|
|
private void ValidateSecurityPolicyCollection(StreamingContext context)
|
|
{
|
|
var supportedPolicies = Opc.Ua.SecurityPolicies.GetDisplayNames();
|
|
var newPolicies = new ServerSecurityPolicyCollection();
|
|
foreach (var securityPolicy in m_securityPolicies)
|
|
{
|
|
if (String.IsNullOrWhiteSpace(securityPolicy.SecurityPolicyUri))
|
|
{
|
|
// add wild card policies
|
|
foreach (var policyUri in Opc.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]))
|
|
{
|
|
if (newPolicies.Find(s =>
|
|
s.SecurityMode == securityPolicy.SecurityMode &&
|
|
string.Equals(s.SecurityPolicyUri, securityPolicy.SecurityPolicyUri,
|
|
StringComparison.Ordinal)) == null)
|
|
{
|
|
newPolicies.Add(securityPolicy);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
m_securityPolicies = newPolicies;
|
|
}
|
|
#endregion
|
|
|
|
#region Persistent Properties
|
|
/// <summary>
|
|
/// The base addresses for the server.
|
|
/// </summary>
|
|
/// <value>The base addresses.</value>
|
|
/// <remarks>
|
|
/// The actually endpoints are constructed from the security policies.
|
|
/// On one base address per supported transport protocol is allowed.
|
|
/// </remarks>
|
|
[DataMember(IsRequired = false, Order = 0)]
|
|
public StringCollection BaseAddresses
|
|
{
|
|
get
|
|
{
|
|
return m_baseAddresses;
|
|
}
|
|
|
|
set
|
|
{
|
|
m_baseAddresses = value;
|
|
|
|
if (m_baseAddresses == null)
|
|
{
|
|
m_baseAddresses = new StringCollection();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the alternate base addresses.
|
|
/// </summary>
|
|
/// <value>The alternate base addresses.</value>
|
|
/// <remarks>
|
|
/// 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.
|
|
/// </remarks>
|
|
[DataMember(IsRequired = false, Order = 1)]
|
|
public StringCollection AlternateBaseAddresses
|
|
{
|
|
get
|
|
{
|
|
return m_alternateBaseAddresses;
|
|
}
|
|
|
|
set
|
|
{
|
|
m_alternateBaseAddresses = value;
|
|
|
|
if (m_alternateBaseAddresses == null)
|
|
{
|
|
m_alternateBaseAddresses = new StringCollection();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The security policies supported by the server.
|
|
/// </summary>
|
|
/// <value>The security policies.</value>
|
|
/// <remarks>
|
|
/// An endpoint description is created for each combination of base address and security policy.
|
|
/// </remarks>
|
|
[DataMember(IsRequired = false, Order = 2)]
|
|
public ServerSecurityPolicyCollection SecurityPolicies
|
|
{
|
|
get
|
|
{
|
|
return m_securityPolicies;
|
|
}
|
|
|
|
set
|
|
{
|
|
m_securityPolicies = value;
|
|
|
|
if (m_securityPolicies == null)
|
|
{
|
|
m_securityPolicies = new ServerSecurityPolicyCollection();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The minimum number of threads assigned to processing requests.
|
|
/// </summary>
|
|
/// <value>The minimum request thread count.</value>
|
|
[DataMember(IsRequired = false, Order = 3)]
|
|
public int MinRequestThreadCount
|
|
{
|
|
get { return m_minRequestThreadCount; }
|
|
set { m_minRequestThreadCount = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The maximum number of threads assigned to processing requests.
|
|
/// </summary>
|
|
/// <value>The maximum request thread count.</value>
|
|
[DataMember(IsRequired = false, Order = 4)]
|
|
public int MaxRequestThreadCount
|
|
{
|
|
get { return m_maxRequestThreadCount; }
|
|
set { m_maxRequestThreadCount = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The maximum number of requests that will be queued waiting for a thread.
|
|
/// </summary>
|
|
/// <value>The maximum queued request count.</value>
|
|
[DataMember(IsRequired = false, Order = 5)]
|
|
public int MaxQueuedRequestCount
|
|
{
|
|
get { return m_maxQueuedRequestCount; }
|
|
set { m_maxQueuedRequestCount = value; }
|
|
}
|
|
#endregion
|
|
|
|
#region Private Members
|
|
private StringCollection m_baseAddresses;
|
|
private StringCollection m_alternateBaseAddresses;
|
|
private ServerSecurityPolicyCollection m_securityPolicies;
|
|
private int m_minRequestThreadCount;
|
|
private int m_maxRequestThreadCount;
|
|
private int m_maxQueuedRequestCount;
|
|
#endregion
|
|
}
|
|
#endregion
|
|
|
|
#region ServerConfiguration Class
|
|
/// <summary>
|
|
/// Specifies the configuration for a server application.
|
|
/// </summary>
|
|
[DataContract(Namespace = Namespaces.OpcUaConfig)]
|
|
public partial class ServerConfiguration : ServerBaseConfiguration
|
|
{
|
|
#region Constructors
|
|
/// <summary>
|
|
/// The default constructor.
|
|
/// </summary>
|
|
public ServerConfiguration()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets private members to default values.
|
|
/// </summary>
|
|
private void Initialize()
|
|
{
|
|
m_userTokenPolicies = new UserTokenPolicyCollection();
|
|
m_diagnosticsEnabled = false;
|
|
m_maxSessionCount = 100;
|
|
m_maxSessionTimeout = 3600000;
|
|
m_minSessionTimeout = 10000;
|
|
m_maxBrowseContinuationPoints = 10;
|
|
m_maxQueryContinuationPoints = 10;
|
|
m_maxHistoryContinuationPoints = 100;
|
|
m_maxRequestAge = 600000;
|
|
m_minPublishingInterval = 100;
|
|
m_maxPublishingInterval = 3600000;
|
|
m_publishingResolution = 100;
|
|
m_minSubscriptionLifetime = 10000;
|
|
m_maxSubscriptionLifetime = 3600000;
|
|
m_maxMessageQueueSize = 10;
|
|
m_maxNotificationQueueSize = 100;
|
|
m_maxNotificationsPerPublish = 100;
|
|
m_minMetadataSamplingInterval = 1000;
|
|
m_availableSamplingRates = new SamplingRateGroupCollection();
|
|
m_registrationEndpoint = null;
|
|
m_maxRegistrationInterval = 30000;
|
|
m_maxPublishRequestCount = 20;
|
|
m_maxSubscriptionCount = 100;
|
|
m_maxEventQueueSize = 10000;
|
|
// https://opcfoundation-onlineapplications.org/profilereporting/ for list of available profiles
|
|
m_serverProfileArray = new string[] { "http://opcfoundation.org/UA-Profile/Server/StandardUA2017" };
|
|
m_shutdownDelay = 5;
|
|
m_serverCapabilities = new string[] { "DA" };
|
|
m_supportedPrivateKeyFormats = new string[] { "PFX", "PEM" };
|
|
m_maxTrustListSize = 0;
|
|
m_multicastDnsEnabled = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes the object during deserialization.
|
|
/// </summary>
|
|
/// <param name="context">The context.</param>
|
|
[OnDeserializing()]
|
|
public new void Initialize(StreamingContext context) => Initialize();
|
|
#endregion
|
|
|
|
#region Persistent Properties
|
|
/// <summary>
|
|
/// The user tokens accepted by the server.
|
|
/// </summary>
|
|
/// <value>The user token policies.</value>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 3)]
|
|
public UserTokenPolicyCollection UserTokenPolicies
|
|
{
|
|
get
|
|
{
|
|
return m_userTokenPolicies;
|
|
}
|
|
|
|
set
|
|
{
|
|
m_userTokenPolicies = value;
|
|
|
|
if (m_userTokenPolicies == null)
|
|
{
|
|
m_userTokenPolicies = new UserTokenPolicyCollection();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Whether diagnostics are enabled.
|
|
/// </summary>
|
|
/// <value><c>true</c> if diagnostic is enabled; otherwise, <c>false</c>.</value>
|
|
[DataMember(IsRequired = false, Order = 4)]
|
|
public bool DiagnosticsEnabled
|
|
{
|
|
get { return m_diagnosticsEnabled; }
|
|
set { m_diagnosticsEnabled = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The maximum number of open sessions.
|
|
/// </summary>
|
|
/// <value>The maximum session count.</value>
|
|
[DataMember(IsRequired = false, Order = 5)]
|
|
public int MaxSessionCount
|
|
{
|
|
get { return m_maxSessionCount; }
|
|
set { m_maxSessionCount = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// That minimum period of that a session is allowed to remain
|
|
/// open without communication from the client (in milliseconds).
|
|
/// </summary>
|
|
/// <value>The minimum session timeout.</value>
|
|
[DataMember(IsRequired = false, Order = 6)]
|
|
public int MinSessionTimeout
|
|
{
|
|
get { return m_minSessionTimeout; }
|
|
set { m_minSessionTimeout = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// That maximum period of that a session is allowed to remain
|
|
/// open without communication from the client (in milliseconds).
|
|
/// </summary>
|
|
/// <value>The maximum session timeout.</value>
|
|
[DataMember(IsRequired = false, Order = 7)]
|
|
public int MaxSessionTimeout
|
|
{
|
|
get { return m_maxSessionTimeout; }
|
|
set { m_maxSessionTimeout = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The maximum number of continuation points used for
|
|
/// Browse/BrowseNext operations.
|
|
/// </summary>
|
|
/// <value>The maximum number of continuation points used for Browse/BrowseNext operations</value>
|
|
[DataMember(IsRequired = false, Order = 8)]
|
|
public int MaxBrowseContinuationPoints
|
|
{
|
|
get { return m_maxBrowseContinuationPoints; }
|
|
set { m_maxBrowseContinuationPoints = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The maximum number of continuation points used for
|
|
/// Query/QueryNext operations.
|
|
/// </summary>
|
|
/// <value>The maximum number of query continuation points.</value>
|
|
[DataMember(IsRequired = false, Order = 9)]
|
|
public int MaxQueryContinuationPoints
|
|
{
|
|
get { return m_maxQueryContinuationPoints; }
|
|
set { m_maxQueryContinuationPoints = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The maximum number of continuation points used for HistoryRead operations.
|
|
/// </summary>
|
|
/// <value>The maximum number of history continuation points.</value>
|
|
[DataMember(IsRequired = false, Order = 10)]
|
|
public int MaxHistoryContinuationPoints
|
|
{
|
|
get { return m_maxHistoryContinuationPoints; }
|
|
set { m_maxHistoryContinuationPoints = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The maximum age of an incoming request (old requests are rejected) (in milliseconds).
|
|
/// </summary>
|
|
/// <value>The maximum age of an incoming request.</value>
|
|
[DataMember(IsRequired = false, Order = 11)]
|
|
public int MaxRequestAge
|
|
{
|
|
get { return m_maxRequestAge; }
|
|
set { m_maxRequestAge = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The minimum publishing interval supported by the server (in milliseconds).
|
|
/// </summary>
|
|
/// <value>The minimum publishing interval.</value>
|
|
[DataMember(IsRequired = false, Order = 12)]
|
|
public int MinPublishingInterval
|
|
{
|
|
get { return m_minPublishingInterval; }
|
|
set { m_minPublishingInterval = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The maximum publishing interval supported by the server (in milliseconds).
|
|
/// </summary>
|
|
/// <value>The maximum publishing interval.</value>
|
|
[DataMember(IsRequired = false, Order = 13)]
|
|
public int MaxPublishingInterval
|
|
{
|
|
get { return m_maxPublishingInterval; }
|
|
set { m_maxPublishingInterval = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The minimum difference between supported publishing interval (in milliseconds).
|
|
/// </summary>
|
|
/// <value>The publishing resolution.</value>
|
|
[DataMember(IsRequired = false, Order = 14)]
|
|
public int PublishingResolution
|
|
{
|
|
get { return m_publishingResolution; }
|
|
set { m_publishingResolution = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// How long the subscriptions will remain open without a publish from the client.
|
|
/// </summary>
|
|
/// <value>The maximum subscription lifetime.</value>
|
|
[DataMember(IsRequired = false, Order = 15)]
|
|
public int MaxSubscriptionLifetime
|
|
{
|
|
get { return m_maxSubscriptionLifetime; }
|
|
set { m_maxSubscriptionLifetime = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The maximum number of messages saved in the queue for each subscription.
|
|
/// </summary>
|
|
/// <value>The maximum size of the message queue.</value>
|
|
[DataMember(IsRequired = false, Order = 16)]
|
|
public int MaxMessageQueueSize
|
|
{
|
|
get { return m_maxMessageQueueSize; }
|
|
set { m_maxMessageQueueSize = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The maximum number of notificates saved in the queue for each monitored item.
|
|
/// </summary>
|
|
/// <value>The maximum size of the notification queue.</value>
|
|
[DataMember(IsRequired = false, Order = 17)]
|
|
public int MaxNotificationQueueSize
|
|
{
|
|
get { return m_maxNotificationQueueSize; }
|
|
set { m_maxNotificationQueueSize = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The maximum number of notifications per publish.
|
|
/// </summary>
|
|
/// <value>The maximum number of notifications per publish.</value>
|
|
[DataMember(IsRequired = false, Order = 18)]
|
|
public int MaxNotificationsPerPublish
|
|
{
|
|
get { return m_maxNotificationsPerPublish; }
|
|
set { m_maxNotificationsPerPublish = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The minimum sampling interval for metadata.
|
|
/// </summary>
|
|
/// <value>The minimum sampling interval for metadata.</value>
|
|
[DataMember(IsRequired = false, Order = 19)]
|
|
public int MinMetadataSamplingInterval
|
|
{
|
|
get { return m_minMetadataSamplingInterval; }
|
|
set { m_minMetadataSamplingInterval = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The available sampling rates.
|
|
/// </summary>
|
|
/// <value>The available sampling rates.</value>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 20)]
|
|
public SamplingRateGroupCollection AvailableSamplingRates
|
|
{
|
|
get { return m_availableSamplingRates; }
|
|
set { m_availableSamplingRates = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The endpoint description for the registration endpoint.
|
|
/// </summary>
|
|
/// <value>The registration endpoint.</value>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 21)]
|
|
public EndpointDescription RegistrationEndpoint
|
|
{
|
|
get { return m_registrationEndpoint; }
|
|
set { m_registrationEndpoint = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The maximum time between registration attempts (in milliseconds).
|
|
/// </summary>
|
|
/// <value>The maximum time between registration attempts (in milliseconds).</value>
|
|
[DataMember(IsRequired = false, Order = 22)]
|
|
public int MaxRegistrationInterval
|
|
{
|
|
get { return m_maxRegistrationInterval; }
|
|
set { m_maxRegistrationInterval = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The path to the file containing nodes persisted by the core node manager.
|
|
/// </summary>
|
|
/// <value>The path to the file containing nodes persisted by the core node manager.</value>
|
|
[DataMember(IsRequired = false, Order = 23)]
|
|
public string NodeManagerSaveFile
|
|
{
|
|
get { return m_nodeManagerSaveFile; }
|
|
set { m_nodeManagerSaveFile = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The minimum lifetime for a subscription (in milliseconds).
|
|
/// </summary>
|
|
/// <value>The minimum lifetime for a subscription.</value>
|
|
[DataMember(IsRequired = false, Order = 24)]
|
|
public int MinSubscriptionLifetime
|
|
{
|
|
get { return m_minSubscriptionLifetime; }
|
|
set { m_minSubscriptionLifetime = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The max publish request count.
|
|
/// </summary>
|
|
/// <value>The max publish request count.</value>
|
|
[DataMember(IsRequired = false, Order = 25)]
|
|
public int MaxPublishRequestCount
|
|
{
|
|
get { return m_maxPublishRequestCount; }
|
|
set { m_maxPublishRequestCount = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The max subscription count.
|
|
/// </summary>
|
|
/// <value>The max subscription count.</value>
|
|
[DataMember(IsRequired = false, Order = 26)]
|
|
public int MaxSubscriptionCount
|
|
{
|
|
get { return m_maxSubscriptionCount; }
|
|
set { m_maxSubscriptionCount = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The max size of the event queue.
|
|
/// </summary>
|
|
/// <value>The max size of the event queue.</value>
|
|
[DataMember(IsRequired = false, Order = 27)]
|
|
public int MaxEventQueueSize
|
|
{
|
|
get { return m_maxEventQueueSize; }
|
|
set { m_maxEventQueueSize = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The server profile array.
|
|
/// </summary>
|
|
/// <value>The array of server profiles.</value>
|
|
[DataMember(IsRequired = false, Order = 28)]
|
|
public StringCollection ServerProfileArray
|
|
{
|
|
get { return m_serverProfileArray; }
|
|
set
|
|
{
|
|
m_serverProfileArray = value;
|
|
if (m_serverProfileArray == null)
|
|
{
|
|
m_serverProfileArray = new StringCollection();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The server shutdown delay.
|
|
/// </summary>
|
|
/// <value>The number of seconds to delay the shutdown if a client is connected.</value>
|
|
[DataMember(IsRequired = false, Order = 29)]
|
|
public int ShutdownDelay
|
|
{
|
|
get { return m_shutdownDelay; }
|
|
set
|
|
{
|
|
m_shutdownDelay = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The server capabilities.
|
|
/// The latest set of server capabilities is listed
|
|
/// <see href="http://www.opcfoundation.org/UA/schemas/1.04/ServerCapabilities.csv">here.</see>
|
|
/// </summary>
|
|
/// <value>The array of server capabilites.</value>
|
|
[DataMember(IsRequired = false, Order = 30)]
|
|
public StringCollection ServerCapabilities
|
|
{
|
|
get { return m_serverCapabilities; }
|
|
set
|
|
{
|
|
m_serverCapabilities = value;
|
|
if (m_serverCapabilities == null)
|
|
{
|
|
m_serverCapabilities = new StringCollection();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the supported private key format.
|
|
/// </summary>
|
|
/// <value>The array of server profiles.</value>
|
|
[DataMember(IsRequired = false, Order = 31)]
|
|
public StringCollection SupportedPrivateKeyFormats
|
|
{
|
|
get { return m_supportedPrivateKeyFormats; }
|
|
set
|
|
{
|
|
m_supportedPrivateKeyFormats = value;
|
|
if (m_supportedPrivateKeyFormats == null)
|
|
{
|
|
m_supportedPrivateKeyFormats = new StringCollection();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the max size of the trust list.
|
|
/// </summary>
|
|
[DataMember(IsRequired = false, Order = 32)]
|
|
public int MaxTrustListSize
|
|
{
|
|
get { return m_maxTrustListSize; }
|
|
set { m_maxTrustListSize = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets if multicast DNS is enabled.
|
|
/// </summary>
|
|
[DataMember(IsRequired = false, Order = 33)]
|
|
public bool MultiCastDnsEnabled
|
|
{
|
|
get { return m_multicastDnsEnabled; }
|
|
set { m_multicastDnsEnabled = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets reverse connect server configuration.
|
|
/// </summary>
|
|
[DataMember(IsRequired = false, Order = 34)]
|
|
public ReverseConnectServerConfiguration ReverseConnect
|
|
{
|
|
get { return m_reverseConnect; }
|
|
set { m_reverseConnect = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the operation limits of the OPC UA Server.
|
|
/// </summary>
|
|
[DataMember(IsRequired = false, Order = 35)]
|
|
public OperationLimits OperationLimits
|
|
{
|
|
get { return m_operationLimits; }
|
|
set { m_operationLimits = value; }
|
|
}
|
|
#endregion
|
|
|
|
#region Private Members
|
|
private UserTokenPolicyCollection m_userTokenPolicies;
|
|
private bool m_diagnosticsEnabled;
|
|
private int m_maxSessionCount;
|
|
private int m_minSessionTimeout;
|
|
private int m_maxSessionTimeout;
|
|
private int m_maxBrowseContinuationPoints;
|
|
private int m_maxQueryContinuationPoints;
|
|
private int m_maxHistoryContinuationPoints;
|
|
private int m_maxRequestAge;
|
|
private int m_minPublishingInterval;
|
|
private int m_maxPublishingInterval;
|
|
private int m_publishingResolution;
|
|
private int m_minSubscriptionLifetime;
|
|
private int m_maxSubscriptionLifetime;
|
|
private int m_maxMessageQueueSize;
|
|
private int m_maxNotificationQueueSize;
|
|
private int m_maxNotificationsPerPublish;
|
|
private int m_minMetadataSamplingInterval;
|
|
private SamplingRateGroupCollection m_availableSamplingRates;
|
|
private EndpointDescription m_registrationEndpoint;
|
|
private int m_maxRegistrationInterval;
|
|
private string m_nodeManagerSaveFile;
|
|
private int m_maxPublishRequestCount;
|
|
private int m_maxSubscriptionCount;
|
|
private int m_maxEventQueueSize;
|
|
private StringCollection m_serverProfileArray;
|
|
private int m_shutdownDelay;
|
|
private StringCollection m_serverCapabilities;
|
|
private StringCollection m_supportedPrivateKeyFormats;
|
|
private int m_maxTrustListSize;
|
|
private bool m_multicastDnsEnabled;
|
|
private ReverseConnectServerConfiguration m_reverseConnect;
|
|
private OperationLimits m_operationLimits;
|
|
#endregion
|
|
}
|
|
#endregion
|
|
|
|
#region ReverseConnectServerConfiguration Class
|
|
/// <summary>
|
|
/// Stores the configuration of the reverse connections.
|
|
/// </summary>
|
|
[DataContract(Namespace = Namespaces.OpcUaConfig)]
|
|
public class ReverseConnectServerConfiguration
|
|
{
|
|
#region Constructors
|
|
/// <summary>
|
|
/// The default constructor.
|
|
/// </summary>
|
|
public ReverseConnectServerConfiguration()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes the object during deserialization.
|
|
/// </summary>
|
|
[OnDeserializing]
|
|
private void Initialize(StreamingContext context) => Initialize();
|
|
|
|
/// <summary>
|
|
/// Sets private members to default values.
|
|
/// </summary>
|
|
private void Initialize()
|
|
{
|
|
ConnectInterval = 15000;
|
|
ConnectTimeout = 30000;
|
|
RejectTimeout = 60000;
|
|
}
|
|
#endregion
|
|
|
|
#region Public Properties
|
|
/// <summary>
|
|
/// A collection of reverse connect clients.
|
|
/// </summary>
|
|
[DataMember(Order = 10)]
|
|
public ReverseConnectClientCollection Clients { get; set; }
|
|
|
|
/// <summary>
|
|
/// The interval after which a new reverse connection is attempted.
|
|
/// </summary>
|
|
[DataMember(Order = 20)]
|
|
public int ConnectInterval { get; set; }
|
|
|
|
/// <summary>
|
|
/// The default timeout to wait for a response to a reverse connection.
|
|
/// </summary>
|
|
[DataMember(Order = 30)]
|
|
public int ConnectTimeout { get; set; }
|
|
|
|
/// <summary>
|
|
/// The timeout to wait to establish a new reverse
|
|
/// connection after a rejected attempt.
|
|
/// </summary>
|
|
[DataMember(Order = 40)]
|
|
public int RejectTimeout { get; set; }
|
|
#endregion
|
|
}
|
|
#endregion
|
|
|
|
#region OperationLimits Class
|
|
/// <summary>
|
|
/// Stores the operation limits of a OPC UA Server.
|
|
/// </summary>
|
|
[DataContract(Namespace = Namespaces.OpcUaConfig)]
|
|
public class OperationLimits
|
|
{
|
|
#region Constructors
|
|
/// <summary>
|
|
/// The default constructor.
|
|
/// </summary>
|
|
public OperationLimits()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes the object during deserialization.
|
|
/// </summary>
|
|
[OnDeserializing]
|
|
private void Initialize(StreamingContext context) => Initialize();
|
|
|
|
/// <summary>
|
|
/// Sets private members to default values.
|
|
/// </summary>
|
|
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;
|
|
}
|
|
#endregion
|
|
|
|
#region Public Properties
|
|
/// <summary>
|
|
/// Indicates the maximum size of the nodesToRead array when a Client calls the Read Service.
|
|
/// </summary>
|
|
[DataMember(Order = 10)]
|
|
public uint MaxNodesPerRead { get; set; }
|
|
/// <summary>
|
|
/// Indicates the maximum size of the nodesToRead array when a Client calls the HistoryRead
|
|
/// Service using the historyReadDetails RAW, PROCESSED, MODIFIED or ATTIME.
|
|
/// </summary>
|
|
[DataMember(Order = 20)]
|
|
public uint MaxNodesPerHistoryReadData { get; set; }
|
|
/// <summary>
|
|
/// Indicates the maximum size of the nodesToRead array when a Client calls the HistoryRead
|
|
/// Service using the historyReadDetails EVENTS.
|
|
/// </summary>
|
|
[DataMember(Order = 30)]
|
|
public uint MaxNodesPerHistoryReadEvents { get; set; }
|
|
/// <summary>
|
|
/// Indicates the maximum size of the nodesToWrite array when a Client calls the Write Service.
|
|
/// </summary>
|
|
[DataMember(Order = 40)]
|
|
public uint MaxNodesPerWrite { get; set; }
|
|
/// <summary>
|
|
/// Indicates the maximum size of the historyUpdateDetails array supported by the Server
|
|
/// when a Client calls the HistoryUpdate Service.
|
|
/// </summary>
|
|
[DataMember(Order = 50)]
|
|
public uint MaxNodesPerHistoryUpdateData { get; set; }
|
|
/// <summary>
|
|
/// Indicates the maximum size of the historyUpdateDetails array
|
|
/// when a Client calls the HistoryUpdate Service.
|
|
/// </summary>
|
|
[DataMember(Order = 60)]
|
|
public uint MaxNodesPerHistoryUpdateEvents { get; set; }
|
|
/// <summary>
|
|
/// Indicates the maximum size of the methodsToCall array when a Client calls the Call Service.
|
|
/// </summary>
|
|
[DataMember(Order = 70)]
|
|
public uint MaxNodesPerMethodCall { get; set; }
|
|
/// <summary>
|
|
/// Indicates the maximum size of the nodesToBrowse array when calling the Browse Service
|
|
/// or the continuationPoints array when a Client calls the BrowseNext Service.
|
|
/// </summary>
|
|
[DataMember(Order = 80)]
|
|
public uint MaxNodesPerBrowse { get; set; }
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
[DataMember(Order = 90)]
|
|
public uint MaxNodesPerRegisterNodes { get; set; }
|
|
/// <summary>
|
|
/// Indicates the maximum size of the browsePaths array when a Client calls the TranslateBrowsePathsToNodeIds Service.
|
|
/// </summary>
|
|
[DataMember(Order = 100)]
|
|
public uint MaxNodesPerTranslateBrowsePathsToNodeIds { get; set; }
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
[DataMember(Order = 110)]
|
|
public uint MaxNodesPerNodeManagement { get; set; }
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
[DataMember(Order = 120)]
|
|
public uint MaxMonitoredItemsPerCall { get; set; }
|
|
#endregion
|
|
}
|
|
#endregion
|
|
|
|
#region ReverseConnectClient Class
|
|
/// <summary>
|
|
/// Stores the configuration of the reverse connections.
|
|
/// </summary>
|
|
[DataContract(Namespace = Namespaces.OpcUaConfig)]
|
|
public class ReverseConnectClient
|
|
{
|
|
#region Constructors
|
|
/// <summary>
|
|
/// The default constructor.
|
|
/// </summary>
|
|
public ReverseConnectClient()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes the object during deserialization.
|
|
/// </summary>
|
|
[OnDeserializing]
|
|
private void Initialize(StreamingContext context) => Initialize();
|
|
|
|
/// <summary>
|
|
/// Sets private members to default values.
|
|
/// </summary>
|
|
private void Initialize()
|
|
{
|
|
Enabled = true;
|
|
}
|
|
#endregion
|
|
|
|
#region Persistent Properties
|
|
/// <summary>
|
|
/// The endpoint Url of the reverse connect client endpoint.
|
|
/// </summary>
|
|
[DataMember(Order = 10)]
|
|
public string EndpointUrl { get; set; }
|
|
|
|
/// <summary>
|
|
/// The timeout to wait for a response to a reverse connection.
|
|
/// Overrides the default reverse connection setting.
|
|
/// </summary>
|
|
[DataMember(Order = 20)]
|
|
public int Timeout { get; set; }
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
[DataMember(Order = 30)]
|
|
public int MaxSessionCount { get; set; }
|
|
|
|
/// <summary>
|
|
/// Specifies whether the sending of reverse connect attempts is enabled.
|
|
/// </summary>
|
|
[DataMember(Order = 40)]
|
|
public bool Enabled { get; set; } = true;
|
|
#endregion
|
|
}
|
|
#endregion
|
|
|
|
#region ReverseConnectClientCollection Class
|
|
/// <summary>
|
|
/// A collection of reverse connect clients.
|
|
/// </summary>
|
|
[CollectionDataContract(Name = "ListOfReverseConnectClient", Namespace = Namespaces.OpcUaConfig, ItemName = "ReverseConnectClient")]
|
|
public class ReverseConnectClientCollection : List<ReverseConnectClient>
|
|
{
|
|
#region Constructors
|
|
/// <summary>
|
|
/// Initializes an empty collection.
|
|
/// </summary>
|
|
public ReverseConnectClientCollection() { }
|
|
|
|
/// <summary>
|
|
/// Initializes the collection from another collection.
|
|
/// </summary>
|
|
/// <param name="collection">A collection of values to add to this new collection</param>
|
|
/// <exception cref="ArgumentNullException">
|
|
/// <paramref name="collection"/> is null.
|
|
/// </exception>
|
|
public ReverseConnectClientCollection(IEnumerable<ReverseConnectClient> collection) : base(collection) { }
|
|
|
|
/// <summary>
|
|
/// Initializes the collection with the specified capacity.
|
|
/// </summary>
|
|
/// <param name="capacity">The capacity.</param>
|
|
public ReverseConnectClientCollection(int capacity) : base(capacity) { }
|
|
#endregion
|
|
}
|
|
#endregion
|
|
|
|
#region ClientConfiguration Class
|
|
/// <summary>
|
|
/// The configuration for a client application.
|
|
/// </summary>
|
|
[DataContract(Namespace = Namespaces.OpcUaConfig)]
|
|
public partial class ClientConfiguration
|
|
{
|
|
#region Constructors
|
|
/// <summary>
|
|
/// The default constructor.
|
|
/// </summary>
|
|
public ClientConfiguration()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets private members to default values.
|
|
/// </summary>
|
|
private void Initialize()
|
|
{
|
|
m_defaultSessionTimeout = 60000;
|
|
m_minSubscriptionLifetime = 10000;
|
|
m_wellKnownDiscoveryUrls = new StringCollection();
|
|
m_discoveryServers = new EndpointDescriptionCollection();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes the object during deserialization.
|
|
/// </summary>
|
|
/// <param name="context">The context.</param>
|
|
[OnDeserializing()]
|
|
public void Initialize(StreamingContext context) => Initialize();
|
|
#endregion
|
|
|
|
#region Persistent Properties
|
|
/// <summary>
|
|
/// The default session timeout (in milliseconds).
|
|
/// </summary>
|
|
/// <value>The default session timeout.</value>
|
|
[DataMember(IsRequired = false, Order = 0)]
|
|
public int DefaultSessionTimeout
|
|
{
|
|
get { return m_defaultSessionTimeout; }
|
|
set { m_defaultSessionTimeout = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The well known URLs for the local discovery servers.
|
|
/// </summary>
|
|
/// <value>The well known discovery URLs.</value>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 1)]
|
|
public StringCollection WellKnownDiscoveryUrls
|
|
{
|
|
get
|
|
{
|
|
return m_wellKnownDiscoveryUrls;
|
|
}
|
|
|
|
set
|
|
{
|
|
m_wellKnownDiscoveryUrls = value;
|
|
|
|
if (m_wellKnownDiscoveryUrls == null)
|
|
{
|
|
m_wellKnownDiscoveryUrls = new StringCollection();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The endpoint descriptions for central discovery servers.
|
|
/// </summary>
|
|
/// <value>The endpoint descriptions for central discovery servers.</value>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 2)]
|
|
public EndpointDescriptionCollection DiscoveryServers
|
|
{
|
|
get
|
|
{
|
|
return m_discoveryServers;
|
|
}
|
|
|
|
set
|
|
{
|
|
m_discoveryServers = value;
|
|
|
|
if (m_discoveryServers == null)
|
|
{
|
|
m_discoveryServers = new EndpointDescriptionCollection();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The path to the file containing the cached endpoints.
|
|
/// </summary>
|
|
/// <value>The path to the file containing the cached endpoints.</value>
|
|
[DataMember(IsRequired = false, Order = 3)]
|
|
public string EndpointCacheFilePath
|
|
{
|
|
get { return m_endpointCacheFilePath; }
|
|
set { m_endpointCacheFilePath = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The minimum lifetime for a subscription (in milliseconds).
|
|
/// </summary>
|
|
/// <value>The minimum lifetime for a subscription.</value>
|
|
[DataMember(IsRequired = false, Order = 4)]
|
|
public int MinSubscriptionLifetime
|
|
{
|
|
get { return m_minSubscriptionLifetime; }
|
|
set { m_minSubscriptionLifetime = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The reverse connect Client configuration.
|
|
/// </summary>
|
|
[DataMember(IsRequired = false, Order = 5)]
|
|
public ReverseConnectClientConfiguration ReverseConnect
|
|
{
|
|
get { return m_reverseConnect; }
|
|
set { m_reverseConnect = value; }
|
|
}
|
|
#endregion
|
|
|
|
#region Private Members
|
|
private StringCollection m_wellKnownDiscoveryUrls;
|
|
private EndpointDescriptionCollection m_discoveryServers;
|
|
private int m_defaultSessionTimeout;
|
|
private string m_endpointCacheFilePath;
|
|
private int m_minSubscriptionLifetime;
|
|
private ReverseConnectClientConfiguration m_reverseConnect;
|
|
#endregion
|
|
}
|
|
#endregion
|
|
|
|
#region ReverseConnectClientConfiguration Class
|
|
/// <summary>
|
|
/// Stores the configuration of the reverse connections.
|
|
/// </summary>
|
|
[DataContract(Namespace = Namespaces.OpcUaConfig)]
|
|
public class ReverseConnectClientConfiguration
|
|
{
|
|
#region Constructors
|
|
/// <summary>
|
|
/// The default constructor.
|
|
/// </summary>
|
|
public ReverseConnectClientConfiguration()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes the object during deserialization.
|
|
/// </summary>
|
|
[OnDeserializing]
|
|
private void Initialize(StreamingContext context) => Initialize();
|
|
|
|
/// <summary>
|
|
/// Sets private members to default values.
|
|
/// </summary>
|
|
private void Initialize()
|
|
{
|
|
}
|
|
#endregion
|
|
|
|
#region Public Properties
|
|
/// <summary>
|
|
/// A collection of reverse connect client endpoints.
|
|
/// </summary>
|
|
[DataMember(Order = 10, IsRequired = false)]
|
|
public ReverseConnectClientEndpointCollection ClientEndpoints { get; set; }
|
|
|
|
/// <summary>
|
|
/// The time a reverse hello port is held open to wait for a
|
|
/// reverse connection until the request is rejected.
|
|
/// </summary>
|
|
[DataMember(Order = 20, IsRequired = false)]
|
|
public int HoldTime { get; set; } = 15000;
|
|
|
|
/// <summary>
|
|
/// The timeout to wait for a reverse hello message.
|
|
/// </summary>
|
|
[DataMember(Order = 30, IsRequired = false)]
|
|
public int WaitTimeout { get; set; } = 20000;
|
|
#endregion
|
|
}
|
|
#endregion
|
|
|
|
#region ReverseConnectClientEndpoint Class
|
|
/// <summary>
|
|
/// Stores the configuration of the reverse connections.
|
|
/// </summary>
|
|
[DataContract(Namespace = Namespaces.OpcUaConfig)]
|
|
public class ReverseConnectClientEndpoint
|
|
{
|
|
#region Constructors
|
|
/// <summary>
|
|
/// The default constructor.
|
|
/// </summary>
|
|
public ReverseConnectClientEndpoint()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes the object during deserialization.
|
|
/// </summary>
|
|
[OnDeserializing]
|
|
private void Initialize(StreamingContext context) => Initialize();
|
|
|
|
/// <summary>
|
|
/// Sets private members to default values.
|
|
/// </summary>
|
|
private void Initialize()
|
|
{
|
|
}
|
|
#endregion
|
|
|
|
#region Persistent Properties
|
|
/// <summary>
|
|
/// The endpoint Url of a reverse connect client.
|
|
/// </summary>
|
|
[DataMember(Order = 1, IsRequired = false)]
|
|
public string EndpointUrl { get; set; }
|
|
#endregion
|
|
}
|
|
#endregion
|
|
|
|
#region ReverseConnectClientEndpointCollection Class
|
|
/// <summary>
|
|
/// A collection of reverse connect client endpoints.
|
|
/// </summary>
|
|
[CollectionDataContract(Name = "ListOfReverseConnectClientEndpoint", Namespace = Namespaces.OpcUaConfig, ItemName = "ClientEndpoint")]
|
|
public class ReverseConnectClientEndpointCollection : List<ReverseConnectClientEndpoint>
|
|
{
|
|
#region Constructors
|
|
/// <summary>
|
|
/// Initializes an empty collection.
|
|
/// </summary>
|
|
public ReverseConnectClientEndpointCollection() { }
|
|
|
|
/// <summary>
|
|
/// Initializes the collection from another collection.
|
|
/// </summary>
|
|
/// <param name="collection">A collection of values to add to this new collection</param>
|
|
/// <exception cref="ArgumentNullException">
|
|
/// <paramref name="collection"/> is null.
|
|
/// </exception>
|
|
public ReverseConnectClientEndpointCollection(IEnumerable<ReverseConnectClientEndpoint> collection) : base(collection) { }
|
|
|
|
/// <summary>
|
|
/// Initializes the collection with the specified capacity.
|
|
/// </summary>
|
|
/// <param name="capacity">The capacity.</param>
|
|
public ReverseConnectClientEndpointCollection(int capacity) : base(capacity) { }
|
|
#endregion
|
|
}
|
|
#endregion
|
|
|
|
#region DiscoveryServerConfiguration Class
|
|
/// <summary>
|
|
/// Specifies the configuration for a discovery server application.
|
|
/// </summary>
|
|
[DataContract(Namespace = Namespaces.OpcUaConfig)]
|
|
public class DiscoveryServerConfiguration : ServerBaseConfiguration
|
|
{
|
|
#region Constructors
|
|
/// <summary>
|
|
/// The default constructor.
|
|
/// </summary>
|
|
public DiscoveryServerConfiguration()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets private members to default values.
|
|
/// </summary>
|
|
private void Initialize()
|
|
{
|
|
m_serverNames = new LocalizedTextCollection();
|
|
m_serverRegistrations = new ServerRegistrationCollection();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes the object during deserialization.
|
|
/// </summary>
|
|
/// <param name="context">The context.</param>
|
|
[OnDeserializing()]
|
|
public new void Initialize(StreamingContext context) => Initialize();
|
|
#endregion
|
|
|
|
#region Persistent Properties
|
|
/// <summary>
|
|
/// The localized names for the discovery server.
|
|
/// </summary>
|
|
/// <value>The server names.</value>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 2)]
|
|
public LocalizedTextCollection ServerNames
|
|
{
|
|
get
|
|
{
|
|
return m_serverNames;
|
|
}
|
|
|
|
set
|
|
{
|
|
m_serverNames = value;
|
|
|
|
if (m_serverNames == null)
|
|
{
|
|
m_serverNames = new LocalizedTextCollection();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The path to the file containing servers saved by the discovery server.
|
|
/// </summary>
|
|
/// <value>The discovery server cache file.</value>
|
|
[DataMember(IsRequired = false, Order = 3)]
|
|
public string DiscoveryServerCacheFile
|
|
{
|
|
get { return m_discoveryServerCacheFile; }
|
|
set { m_discoveryServerCacheFile = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the server registrations associated with the discovery server.
|
|
/// </summary>
|
|
/// <value>The server registrations.</value>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 4)]
|
|
public ServerRegistrationCollection ServerRegistrations
|
|
{
|
|
get { return m_serverRegistrations; }
|
|
set { m_serverRegistrations = value; }
|
|
}
|
|
#endregion
|
|
|
|
#region Private Members
|
|
private LocalizedTextCollection m_serverNames;
|
|
private string m_discoveryServerCacheFile;
|
|
private ServerRegistrationCollection m_serverRegistrations;
|
|
#endregion
|
|
}
|
|
#endregion
|
|
|
|
#region ServerRegistration Class
|
|
/// <summary>
|
|
/// Specifies the configuration for a discovery server application.
|
|
/// </summary>
|
|
[DataContract(Namespace = Namespaces.OpcUaConfig)]
|
|
public class ServerRegistration
|
|
{
|
|
#region Constructors
|
|
/// <summary>
|
|
/// The default constructor.
|
|
/// </summary>
|
|
public ServerRegistration()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets private members to default values.
|
|
/// </summary>
|
|
private void Initialize()
|
|
{
|
|
m_applicationUri = null;
|
|
m_alternateDiscoveryUrls = new StringCollection();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes the object during deserialization.
|
|
/// </summary>
|
|
/// <param name="context">The context.</param>
|
|
[OnDeserializing()]
|
|
public void Initialize(StreamingContext context) => Initialize();
|
|
#endregion
|
|
|
|
#region Persistent Properties
|
|
/// <summary>
|
|
/// Gets or sets the application URI of the server which the registration applies to.
|
|
/// </summary>
|
|
/// <value>The application uri.</value>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 1)]
|
|
public string ApplicationUri
|
|
{
|
|
get
|
|
{
|
|
return m_applicationUri;
|
|
}
|
|
|
|
set
|
|
{
|
|
m_applicationUri = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the alternate discovery urls.
|
|
/// </summary>
|
|
/// <value>The alternate discovery urls.</value>
|
|
/// <remarks>
|
|
/// 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 disovery server
|
|
/// directly without requiring a patch to the server.
|
|
/// </remarks>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 2)]
|
|
public StringCollection AlternateDiscoveryUrls
|
|
{
|
|
get
|
|
{
|
|
return m_alternateDiscoveryUrls;
|
|
}
|
|
|
|
set
|
|
{
|
|
m_alternateDiscoveryUrls = value;
|
|
|
|
if (m_alternateDiscoveryUrls == null)
|
|
{
|
|
m_alternateDiscoveryUrls = new StringCollection();
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Private Members
|
|
private string m_applicationUri;
|
|
private StringCollection m_alternateDiscoveryUrls;
|
|
#endregion
|
|
}
|
|
#endregion
|
|
|
|
#region ServerRegistrationCollection Class
|
|
/// <summary>
|
|
/// A collection of AdditionalServerRegistrationInfo objects.
|
|
/// </summary>
|
|
[CollectionDataContract(Name = "ListOfServerRegistration", Namespace = Namespaces.OpcUaConfig, ItemName = "ServerRegistration")]
|
|
public partial class ServerRegistrationCollection : List<ServerRegistration>
|
|
{
|
|
/// <summary>
|
|
/// Initializes an empty collection.
|
|
/// </summary>
|
|
public ServerRegistrationCollection() { }
|
|
|
|
/// <summary>
|
|
/// Initializes the collection from another collection.
|
|
/// </summary>
|
|
/// <param name="collection">A collection of values to add to this new collection</param>
|
|
/// <exception cref="ArgumentNullException">
|
|
/// <paramref name="collection"/> is null.
|
|
/// </exception>
|
|
public ServerRegistrationCollection(IEnumerable<ServerRegistration> collection) : base(collection) { }
|
|
|
|
/// <summary>
|
|
/// Initializes the collection with the specified capacity.
|
|
/// </summary>
|
|
/// <param name="capacity">The capacity.</param>
|
|
public ServerRegistrationCollection(int capacity) : base(capacity) { }
|
|
}
|
|
#endregion
|
|
|
|
#region CertificateStoreIdentifier Class
|
|
/// <summary>
|
|
/// Describes a certificate store.
|
|
/// </summary>
|
|
[DataContract(Namespace = Namespaces.OpcUaConfig)]
|
|
public partial class CertificateStoreIdentifier
|
|
{
|
|
#region Persistent Properties
|
|
/// <summary>
|
|
/// The type of certificate store.
|
|
/// </summary>
|
|
/// <value>
|
|
/// If the StoreName is not empty, the CertificateStoreType.X509Store is returned, otherwise the StoreType is returned.
|
|
/// </value>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 0)]
|
|
public string StoreType
|
|
{
|
|
get
|
|
{
|
|
if (!String.IsNullOrEmpty(m_storeName))
|
|
{
|
|
return CertificateStoreType.X509Store;
|
|
}
|
|
|
|
return m_storeType;
|
|
}
|
|
|
|
set
|
|
{
|
|
m_storeType = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The path that identifies the certificate store.
|
|
/// </summary>
|
|
/// <value>
|
|
/// 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.
|
|
/// </value>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 1)]
|
|
public string StorePath
|
|
{
|
|
get
|
|
{
|
|
if (!String.IsNullOrEmpty(m_storeName))
|
|
{
|
|
if (String.IsNullOrEmpty(m_storeLocation))
|
|
{
|
|
return CurrentUser + m_storeName;
|
|
}
|
|
|
|
return Utils.Format("{1}\\{0}", m_storeName, m_storeLocation);
|
|
}
|
|
|
|
return m_storePath;
|
|
}
|
|
|
|
set
|
|
{
|
|
m_storePath = value;
|
|
|
|
if (!String.IsNullOrEmpty(m_storePath))
|
|
{
|
|
if (String.IsNullOrEmpty(m_storeType))
|
|
{
|
|
m_storeType = CertificateStoreIdentifier.DetermineStoreType(m_storePath);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The name of the certifcate store that contains the trusted certficates.
|
|
/// </summary>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 2)]
|
|
[Obsolete("Use StoreType/StorePath instead")]
|
|
public string StoreName
|
|
{
|
|
get { return m_storeName; }
|
|
set { m_storeName = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The location of the certifcate store that contains the trusted certficates.
|
|
/// </summary>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 3)]
|
|
[Obsolete("Use StoreType/StorePath instead")]
|
|
public string StoreLocation
|
|
{
|
|
get { return m_storeLocation; }
|
|
set { m_storeLocation = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Options that can be used to suppress certificate validation errors.
|
|
/// </summary>
|
|
[DataMember(Name = "ValidationOptions", IsRequired = false, EmitDefaultValue = false, Order = 4)]
|
|
private int XmlEncodedValidationOptions
|
|
{
|
|
get { return (int)m_validationOptions; }
|
|
set { m_validationOptions = (CertificateValidationOptions)value; }
|
|
}
|
|
#endregion
|
|
|
|
#region Private Fields
|
|
private string m_storeType;
|
|
private string m_storePath;
|
|
private string m_storeLocation;
|
|
private string m_storeName;
|
|
private CertificateValidationOptions m_validationOptions;
|
|
#endregion
|
|
}
|
|
#endregion
|
|
|
|
#region CertificateTrustList Class
|
|
[DataContract(Namespace = Namespaces.OpcUaConfig)]
|
|
public partial class CertificateTrustList : CertificateStoreIdentifier
|
|
{
|
|
#region Constructors
|
|
/// <summary>
|
|
/// The default constructor.
|
|
/// </summary>
|
|
public CertificateTrustList()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets private members to default values.
|
|
/// </summary>
|
|
private void Initialize()
|
|
{
|
|
m_lock = new object();
|
|
m_trustedCertificates = new CertificateIdentifierCollection();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes the object during deserialization.
|
|
/// </summary>
|
|
[OnDeserializing()]
|
|
public void Initialize(StreamingContext context) => Initialize();
|
|
#endregion
|
|
|
|
#region Persistent Properties
|
|
/// <summary>
|
|
/// The list of trusted certificates.
|
|
/// </summary>
|
|
/// <value>
|
|
/// The list of trusted certificates is set when TrustedCertificates is not a null value, otherwise new CertificateIdentifierCollection is set.
|
|
/// </value>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 3)]
|
|
public CertificateIdentifierCollection TrustedCertificates
|
|
{
|
|
get
|
|
{
|
|
return m_trustedCertificates;
|
|
}
|
|
|
|
set
|
|
{
|
|
m_trustedCertificates = value;
|
|
|
|
if (m_trustedCertificates == null)
|
|
{
|
|
m_trustedCertificates = new CertificateIdentifierCollection();
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Private Fields
|
|
private CertificateIdentifierCollection m_trustedCertificates;
|
|
#endregion
|
|
}
|
|
#endregion
|
|
|
|
#region CertificateIdentifierCollection Class
|
|
[CollectionDataContract(Name = "ListOfCertificateIdentifier", Namespace = Namespaces.OpcUaConfig, ItemName = "CertificateIdentifier")]
|
|
public partial class CertificateIdentifierCollection : List<CertificateIdentifier>
|
|
{
|
|
/// <summary>
|
|
/// Initializes an empty collection.
|
|
/// </summary>
|
|
public CertificateIdentifierCollection() { }
|
|
|
|
/// <summary>
|
|
/// Initializes the collection from another collection.
|
|
/// </summary>
|
|
/// <param name="collection">A collection of values to add to this new collection</param>
|
|
public CertificateIdentifierCollection(IEnumerable<CertificateIdentifier> collection) : base(collection) { }
|
|
|
|
/// <summary>
|
|
/// Initializes the collection with the specified capacity.
|
|
/// </summary>
|
|
public CertificateIdentifierCollection(int capacity) : base(capacity) { }
|
|
}
|
|
#endregion
|
|
|
|
#region CertificateIdentifier Class
|
|
[DataContract(Namespace = Namespaces.OpcUaConfig)]
|
|
public partial class CertificateIdentifier
|
|
{
|
|
#region Constructors
|
|
/// <summary>
|
|
/// The default constructor.
|
|
/// </summary>
|
|
public CertificateIdentifier()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes the identifier with the raw data from a certificate.
|
|
/// </summary>
|
|
public CertificateIdentifier(X509Certificate2 certificate)
|
|
{
|
|
Initialize();
|
|
m_certificate = certificate;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes the identifier with the raw data from a certificate.
|
|
/// </summary>
|
|
public CertificateIdentifier(X509Certificate2 certificate, CertificateValidationOptions validationOptions)
|
|
{
|
|
Initialize();
|
|
m_certificate = certificate;
|
|
m_validationOptions = validationOptions;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Initializes the identifier with the raw data from a certificate.
|
|
/// </summary>
|
|
public CertificateIdentifier(byte[] rawData)
|
|
{
|
|
Initialize();
|
|
m_certificate = CertificateFactory.Create(rawData, true);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets private members to default values.
|
|
/// </summary>
|
|
private void Initialize()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes the object during deserialization.
|
|
/// </summary>
|
|
[OnDeserializing()]
|
|
public void Initialize(StreamingContext context) => Initialize();
|
|
#endregion
|
|
|
|
#region Public Properties
|
|
/// <summary>
|
|
/// The type of certificate store.
|
|
/// </summary>
|
|
/// <value>The type of the store - defined in the <see cref="CertificateStoreType"/>.</value>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 0)]
|
|
public string StoreType
|
|
{
|
|
get
|
|
{
|
|
if (!String.IsNullOrEmpty(m_storeName))
|
|
{
|
|
return CertificateStoreType.X509Store;
|
|
}
|
|
|
|
return m_storeType;
|
|
}
|
|
|
|
set
|
|
{
|
|
m_storeType = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The path that identifies the certificate store.
|
|
/// </summary>
|
|
/// <value>The store path in the form <c>StoreName\\Store Location</c> .</value>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 1)]
|
|
public string StorePath
|
|
{
|
|
get
|
|
{
|
|
if (!String.IsNullOrEmpty(m_storeName))
|
|
{
|
|
if (String.IsNullOrEmpty(m_storeLocation))
|
|
{
|
|
return Utils.Format("LocalMachine\\{0}", m_storeName);
|
|
}
|
|
|
|
return Utils.Format("{1}\\{0}", m_storeName, m_storeLocation);
|
|
}
|
|
|
|
return m_storePath;
|
|
}
|
|
|
|
set
|
|
{
|
|
m_storePath = value;
|
|
|
|
if (!String.IsNullOrEmpty(m_storePath))
|
|
{
|
|
if (String.IsNullOrEmpty(m_storeType))
|
|
{
|
|
m_storeType = CertificateStoreIdentifier.DetermineStoreType(m_storePath);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The name of the store that contains the certificate.
|
|
/// </summary>
|
|
/// <value>The name of the store.</value>
|
|
/// <seealso cref="System.Security.Cryptography.X509Certificates.StoreName"/>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 2)]
|
|
[Obsolete("Use StoreType/StorePath instead")]
|
|
public string StoreName
|
|
{
|
|
get { return m_storeName; }
|
|
set { m_storeName = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The location of the store that contains the certificate.
|
|
/// </summary>
|
|
/// <value>The store location.</value>
|
|
/// <seealso cref="System.Security.Cryptography.X509Certificates.StoreLocation"/>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 3)]
|
|
[Obsolete("Use StoreType/StorePath instead")]
|
|
public string StoreLocation
|
|
{
|
|
get { return m_storeLocation; }
|
|
set { m_storeLocation = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The certificate's subject name - the distinguished name of an X509 certificate.
|
|
/// </summary>
|
|
/// <value>
|
|
/// The distinguished name of an X509 certificate acording to the Abstract Syntax Notation One (ASN.1) syntax.
|
|
/// </value>
|
|
/// <remarks> 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:
|
|
/// <list type="bullet">
|
|
/// <item>CN commonName</item>
|
|
/// <item>L localityName</item>
|
|
/// <item>ST stateOrProvinceName</item>
|
|
/// <item>O organizationName</item>
|
|
/// <item>OU organizationalUnitName</item>
|
|
/// <item>C countryName</item>
|
|
/// <item>STREET streetAddress</item>
|
|
/// <item>DC domainComponent</item>
|
|
/// <item>UID userid</item>
|
|
/// </list>
|
|
/// 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):
|
|
/// <code>CN=Steve Kille,O=Isode Limited,C=GB</code>
|
|
///
|
|
/// RFC 3280 Internet X.509 Public Key Infrastructure, April 2002
|
|
/// RFC 2253 LADPv3 Distinguished Names, December 1997
|
|
/// </remarks>
|
|
/// <seealso cref="System.Security.Cryptography.X509Certificates.X500DistinguishedName"/>
|
|
/// <seealso cref="System.Security.Cryptography.AsnEncodedData"/>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 4)]
|
|
public string SubjectName
|
|
{
|
|
get
|
|
{
|
|
if (m_certificate == null)
|
|
{
|
|
return m_subjectName;
|
|
}
|
|
|
|
return m_certificate.Subject;
|
|
}
|
|
|
|
set
|
|
{
|
|
if (m_certificate != null && !String.IsNullOrEmpty(value))
|
|
{
|
|
if (m_certificate.Subject != value)
|
|
{
|
|
throw new ArgumentException("SubjectName does not match the SubjectName of the current certificate.");
|
|
}
|
|
}
|
|
|
|
m_subjectName = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The certificate's thumbprint.
|
|
/// </summary>
|
|
/// <value>The thumbprint of a certificate..</value>
|
|
/// <seealso cref="X509Certificate2"/>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 5)]
|
|
public string Thumbprint
|
|
{
|
|
get
|
|
{
|
|
if (m_certificate == null)
|
|
{
|
|
return m_thumbprint;
|
|
}
|
|
|
|
return m_certificate.Thumbprint;
|
|
}
|
|
|
|
set
|
|
{
|
|
if (m_certificate != null)
|
|
{
|
|
if (!String.IsNullOrEmpty(value) && m_certificate.Thumbprint != value)
|
|
{
|
|
throw new ArgumentException("Thumbprint does not match the thumbprint of the current certificate.");
|
|
}
|
|
}
|
|
|
|
m_thumbprint = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the DER encoded certificate data or create emebeded in this instance certifcate using the DER encoded certificate data.
|
|
/// </summary>
|
|
/// <value>A byte array containing the X.509 certificate data.</value>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 6)]
|
|
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, true);
|
|
m_subjectName = m_certificate.Subject;
|
|
m_thumbprint = m_certificate.Thumbprint;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the XML encoded validation options - use to serialize the validation options.
|
|
/// </summary>
|
|
/// <value>The XML encoded validation options.</value>
|
|
[DataMember(Name = "ValidationOptions", IsRequired = false, EmitDefaultValue = false, Order = 7)]
|
|
private int XmlEncodedValidationOptions
|
|
{
|
|
get { return (int)m_validationOptions; }
|
|
set { m_validationOptions = (CertificateValidationOptions)value; }
|
|
}
|
|
#endregion
|
|
|
|
#region Private Fields
|
|
private string m_storeType;
|
|
private string m_storePath;
|
|
private string m_storeLocation;
|
|
private string m_storeName;
|
|
private string m_subjectName;
|
|
private string m_thumbprint;
|
|
private X509Certificate2 m_certificate;
|
|
private CertificateValidationOptions m_validationOptions;
|
|
#endregion
|
|
}
|
|
#endregion
|
|
|
|
#region ConfiguredEndpointCollection Class
|
|
/// <summary>
|
|
/// Stores a list of cached enpoints.
|
|
/// </summary>
|
|
[DataContract(Namespace = Namespaces.OpcUaConfig)]
|
|
public partial class ConfiguredEndpointCollection
|
|
{
|
|
#region Constructors
|
|
/// <summary>
|
|
/// The default constructor.
|
|
/// </summary>
|
|
public ConfiguredEndpointCollection()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called by the .NET framework during deserialization.
|
|
/// </summary>
|
|
[OnDeserializing]
|
|
public void Initialize(StreamingContext context) => Initialize();
|
|
|
|
/// <summary>
|
|
/// Sets private members to default values.
|
|
/// </summary>
|
|
private void Initialize()
|
|
{
|
|
m_knownHosts = new StringCollection();
|
|
m_discoveryUrls = new StringCollection(Utils.DiscoveryUrls);
|
|
m_endpoints = new List<ConfiguredEndpoint>();
|
|
m_defaultConfiguration = EndpointConfiguration.Create();
|
|
}
|
|
#endregion
|
|
|
|
#region Public Properties
|
|
/// <summary>
|
|
/// A list of known hosts that can be used for discovery.
|
|
/// </summary>
|
|
[DataMember(Name = "KnownHosts", IsRequired = false, Order = 1)]
|
|
public StringCollection KnownHosts
|
|
{
|
|
get
|
|
{
|
|
return m_knownHosts;
|
|
}
|
|
|
|
set
|
|
{
|
|
if (value == null)
|
|
{
|
|
m_knownHosts = new StringCollection();
|
|
}
|
|
else
|
|
{
|
|
m_knownHosts = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The default configuration to use when connecting to an endpoint.
|
|
/// </summary>
|
|
[DataMember(Name = "Endpoints", IsRequired = false, Order = 2)]
|
|
public List<ConfiguredEndpoint> Endpoints
|
|
{
|
|
get
|
|
{
|
|
return m_endpoints;
|
|
}
|
|
|
|
private set
|
|
{
|
|
if (value == null)
|
|
{
|
|
m_endpoints = new List<ConfiguredEndpoint>();
|
|
}
|
|
else
|
|
{
|
|
m_endpoints = value;
|
|
}
|
|
|
|
foreach (ConfiguredEndpoint endpoint in m_endpoints)
|
|
{
|
|
endpoint.Collection = this;
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// The URL of the UA TCP proxy server.
|
|
/// </summary>
|
|
[DataMember(Name = "TcpProxyUrl", EmitDefaultValue = false, Order = 3)]
|
|
public Uri TcpProxyUrl
|
|
{
|
|
get
|
|
{
|
|
return m_tcpProxyUrl;
|
|
}
|
|
|
|
set
|
|
{
|
|
m_tcpProxyUrl = value;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Private Fields
|
|
private string m_filepath;
|
|
private StringCollection m_knownHosts;
|
|
private StringCollection m_discoveryUrls;
|
|
private EndpointConfiguration m_defaultConfiguration;
|
|
private List<ConfiguredEndpoint> m_endpoints;
|
|
private Uri m_tcpProxyUrl;
|
|
#endregion
|
|
}
|
|
#endregion
|
|
|
|
#region ConfiguredEndpoint Class
|
|
/// <summary>
|
|
/// Stores the configuration information for an endpoint.
|
|
/// </summary>
|
|
[DataContract(Namespace = Namespaces.OpcUaConfig)]
|
|
[KnownType(typeof(UserNameIdentityToken))]
|
|
[KnownType(typeof(X509IdentityToken))]
|
|
[KnownType(typeof(IssuedIdentityToken))]
|
|
public partial class ConfiguredEndpoint
|
|
{
|
|
#region Constructors
|
|
/// <summary>
|
|
/// The default constructor.
|
|
/// </summary>
|
|
public ConfiguredEndpoint()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called by the .NET framework during deserialization.
|
|
/// </summary>
|
|
[OnDeserializing]
|
|
public void Initialize(StreamingContext context) => Initialize();
|
|
|
|
/// <summary>
|
|
/// Sets private members to default values.
|
|
/// </summary>
|
|
private void Initialize()
|
|
{
|
|
m_collection = null;
|
|
m_description = new EndpointDescription();
|
|
m_configuration = null;
|
|
m_updateBeforeConnect = true;
|
|
m_binaryEncodingSupport = BinaryEncodingSupport.Optional;
|
|
m_selectedUserTokenPolicyIndex = 0;
|
|
m_userIdentity = null;
|
|
m_reverseConnect = null;
|
|
}
|
|
#endregion
|
|
|
|
#region Public Properties
|
|
/// <summary>
|
|
/// The description for the endpoint.
|
|
/// </summary>
|
|
[DataMember(Name = "Endpoint", Order = 1, IsRequired = true)]
|
|
public EndpointDescription Description
|
|
{
|
|
get
|
|
{
|
|
return m_description;
|
|
}
|
|
|
|
private set
|
|
{
|
|
if (value == null)
|
|
{
|
|
m_description = new EndpointDescription();
|
|
}
|
|
else
|
|
{
|
|
m_description = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The configuration to use when connecting to an endpoint.
|
|
/// </summary>
|
|
[DataMember(Name = "Configuration", Order = 2, IsRequired = false)]
|
|
public EndpointConfiguration Configuration
|
|
{
|
|
get
|
|
{
|
|
return 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());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Whether the endpoint information should be updated before connecting to the server.
|
|
/// </summary>
|
|
[DataMember(Name = "UpdateBeforeConnect", Order = 3, IsRequired = false)]
|
|
public bool UpdateBeforeConnect
|
|
{
|
|
get { return m_updateBeforeConnect; }
|
|
set { m_updateBeforeConnect = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The user identity to use when connecting to the endpoint.
|
|
/// </summary>
|
|
[DataMember(Name = "BinaryEncodingSupport", Order = 4, IsRequired = false)]
|
|
public BinaryEncodingSupport BinaryEncodingSupport
|
|
{
|
|
get { return m_binaryEncodingSupport; }
|
|
set { m_binaryEncodingSupport = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The user identity to use when connecting to the endpoint.
|
|
/// </summary>
|
|
[DataMember(Name = "SelectedUserTokenPolicy", Order = 5, IsRequired = false)]
|
|
public int SelectedUserTokenPolicyIndex
|
|
{
|
|
get { return m_selectedUserTokenPolicyIndex; }
|
|
set { m_selectedUserTokenPolicyIndex = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The user identity to use when connecting to the endpoint.
|
|
/// </summary>
|
|
[DataMember(Name = "UserIdentity", Order = 6, IsRequired = false)]
|
|
public UserIdentityToken UserIdentity
|
|
{
|
|
get { return m_userIdentity; }
|
|
set { m_userIdentity = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The reverse connect information.
|
|
/// </summary>
|
|
[DataMember(Name = "ReverseConnect", Order = 8, IsRequired = false)]
|
|
public ReverseConnectEndpoint ReverseConnect
|
|
{
|
|
get { return m_reverseConnect; }
|
|
set { m_reverseConnect = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// A bucket to store additional application specific configuration data.
|
|
/// </summary>
|
|
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 9)]
|
|
public XmlElementCollection Extensions
|
|
{
|
|
get { return m_extensions; }
|
|
set { m_extensions = value; }
|
|
}
|
|
#endregion
|
|
|
|
#region Private Fields
|
|
private ConfiguredEndpointCollection m_collection;
|
|
private EndpointDescription m_description;
|
|
private EndpointConfiguration m_configuration;
|
|
private bool m_updateBeforeConnect;
|
|
private BinaryEncodingSupport m_binaryEncodingSupport;
|
|
private int m_selectedUserTokenPolicyIndex;
|
|
private UserIdentityToken m_userIdentity;
|
|
private ReverseConnectEndpoint m_reverseConnect;
|
|
private XmlElementCollection m_extensions;
|
|
#endregion
|
|
}
|
|
#endregion
|
|
|
|
#region BinaryEncodingSupport Enumeration
|
|
/// <summary>
|
|
/// The type of binary encoding support allowed by a channel.
|
|
/// </summary>
|
|
[DataContract(Namespace = Namespaces.OpcUaConfig)]
|
|
public enum BinaryEncodingSupport
|
|
{
|
|
/// <summary>
|
|
/// The UA binary encoding may be used.
|
|
/// </summary>
|
|
[EnumMember()]
|
|
Optional,
|
|
|
|
/// <summary>
|
|
/// The UA binary encoding must be used.
|
|
/// </summary>
|
|
[EnumMember()]
|
|
Required,
|
|
|
|
/// <summary>
|
|
/// The UA binary encoding may not be used.
|
|
/// </summary>
|
|
[EnumMember()]
|
|
None
|
|
}
|
|
#endregion
|
|
|
|
#region ReverseConnectEndpoint Class
|
|
/// <summary>
|
|
/// Stores the reverse connect information for an endpoint.
|
|
/// </summary>
|
|
[DataContract(Namespace = Namespaces.OpcUaConfig)]
|
|
public partial class ReverseConnectEndpoint
|
|
{
|
|
#region Constructors
|
|
/// <summary>
|
|
/// The default constructor.
|
|
/// </summary>
|
|
public ReverseConnectEndpoint()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called by the .NET framework during deserialization.
|
|
/// </summary>
|
|
[OnDeserializing]
|
|
public void Initialize(StreamingContext context) => Initialize();
|
|
|
|
/// <summary>
|
|
/// Sets private members to default values.
|
|
/// </summary>
|
|
private void Initialize()
|
|
{
|
|
m_enabled = false;
|
|
m_serverUri = null;
|
|
m_thumbprint = null;
|
|
}
|
|
#endregion
|
|
|
|
#region Public Properties
|
|
/// <summary>
|
|
/// Whether reverse connect is enabled for the endpoint.
|
|
/// </summary>
|
|
[DataMember(Name = "Enabled", Order = 1, IsRequired = false)]
|
|
public bool Enabled
|
|
{
|
|
get { return m_enabled; }
|
|
set { m_enabled = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The server Uri of the endpoint.
|
|
/// </summary>
|
|
[DataMember(Name = "ServerUri", Order = 2, IsRequired = false)]
|
|
public string ServerUri
|
|
{
|
|
get { return m_serverUri; }
|
|
set { m_serverUri = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The thumbprint of the certificate which contains
|
|
/// the server Uri.
|
|
/// </summary>
|
|
[DataMember(Name = "Thumbprint", Order = 3, IsRequired = false)]
|
|
public string Thumbprint
|
|
{
|
|
get { return m_thumbprint; }
|
|
set { m_thumbprint = value; }
|
|
}
|
|
#endregion
|
|
|
|
#region Private Fields
|
|
private bool m_enabled;
|
|
private string m_serverUri;
|
|
private string m_thumbprint;
|
|
#endregion
|
|
}
|
|
#endregion
|
|
}
|