diff --git a/SampleApplications/SDK/Opc.Ua.Client.ComplexTypes/ComplexTypeSystem.cs b/SampleApplications/SDK/Opc.Ua.Client.ComplexTypes/ComplexTypeSystem.cs
index 5236f3a5b1..d2b8c27bcb 100644
--- a/SampleApplications/SDK/Opc.Ua.Client.ComplexTypes/ComplexTypeSystem.cs
+++ b/SampleApplications/SDK/Opc.Ua.Client.ComplexTypes/ComplexTypeSystem.cs
@@ -52,37 +52,6 @@ namespace Opc.Ua.Client.ComplexTypes
///
public class ComplexTypeSystem
{
- #region Exception
- public class DataTypeNotFoundException : Exception
- {
- public ExpandedNodeId nodeId;
- public string typeName;
-
- public DataTypeNotFoundException(ExpandedNodeId nodeId)
- {
- this.nodeId = nodeId;
- }
-
- public DataTypeNotFoundException(string typeName, string message)
- : base(message)
- {
- this.nodeId = NodeId.Null;
- this.typeName = typeName;
- }
-
- public DataTypeNotFoundException(ExpandedNodeId nodeId, string message)
- : base(message)
- {
- this.nodeId = nodeId;
- }
-
- public DataTypeNotFoundException(ExpandedNodeId nodeId, string message, Exception inner)
- : base(message, inner)
- {
- this.nodeId = nodeId;
- }
- }
- #endregion
#region Constructors
///
@@ -371,6 +340,12 @@ namespace Opc.Ua.Client.ComplexTypes
retryStructureList.Add(item);
continue;
}
+ catch (DataTypeNotSupportedException typeNotSupportedException)
+ {
+ Utils.Trace(typeNotSupportedException,
+ $"Skipped the type definition of {item.Name} because it is not supported.");
+ continue;
+ }
catch (ServiceResultException sre)
{
Utils.Trace(sre, $"Skip the type definition of {item.Name}.");
@@ -395,11 +370,19 @@ namespace Opc.Ua.Client.ComplexTypes
xmlEncodingId
);
}
- catch (DataTypeNotFoundException)
+ catch (DataTypeNotFoundException typeNotFoundException)
{
+ Utils.Trace(typeNotFoundException,
+ $"Skipped the type definition of {item.Name}. Retry in next round.");
retryStructureList.Add(item);
continue;
}
+ catch (DataTypeNotSupportedException typeNotSupportedException)
+ {
+ Utils.Trace(typeNotSupportedException,
+ $"Skipped the type definition of {item.Name} because it is not supported.");
+ continue;
+ }
// Add new type to factory
if (complexType != null)
@@ -588,13 +571,21 @@ namespace Opc.Ua.Client.ComplexTypes
var typeMatch = structTypesWorkList.Where(n => n.NodeId == dtnfex.nodeId).FirstOrDefault();
if (typeMatch == null)
{
- throw dtnfex;
+ throw;
}
else
{ // known missing type, retry on next round
+ Utils.Trace(dtnfex,
+ $"Skipped the type definition of {dataTypeNode.BrowseName.Name}. Retry in next round.");
retryAddStructType = true;
}
}
+ catch (DataTypeNotSupportedException dtnsex)
+ {
+ Utils.Trace(dtnsex,
+ $"Skipped the type definition of {dataTypeNode.BrowseName.Name} because it is not supported.");
+ continue;
+ }
catch
{
// creating the new type failed, likely a missing dependency, retry later
@@ -636,6 +627,23 @@ namespace Opc.Ua.Client.ComplexTypes
{
if (dataTypeNode.DataTypeDefinition?.Body is StructureDefinition structureDefinition)
{
+ // Validate the DataTypeDefinition structure,
+ // but not if the type is supported
+ if (structureDefinition.Fields == null ||
+ structureDefinition.BaseDataType.IsNullNodeId ||
+ structureDefinition.BinaryEncodingId.IsNull)
+ {
+ return null;
+ }
+ foreach (var field in structureDefinition.Fields)
+ {
+ if (field.BinaryEncodingId.IsNull ||
+ field.DataType.IsNullNodeId ||
+ field.TypeId.IsNull)
+ {
+ return null;
+ }
+ }
return structureDefinition;
}
return null;
@@ -835,6 +843,10 @@ namespace Opc.Ua.Client.ComplexTypes
serverStructTypes.Insert(0, dataTypeNode);
break;
}
+ else if (TypeInfo.GetBuiltInType(superType) != BuiltInType.Null)
+ {
+ break;
+ }
} while (true);
}
@@ -918,24 +930,24 @@ namespace Opc.Ua.Client.ComplexTypes
}
}
}
- else
- {
- enumDescription = allEnumerationTypes.Where(node =>
- node.BrowseName.Name == item.Name &&
- (node.BrowseName.NamespaceIndex == complexTypeBuilder.TargetNamespaceIndex ||
- complexTypeBuilder.TargetNamespaceIndex == -1)).FirstOrDefault()
- as DataTypeNode;
- }
- if (enumDescription != null)
- {
- var qName = new XmlQualifiedName(item.Name, complexTypeBuilder.TargetNamespace);
- typeDictionary[qName] = enumType.NodeId;
- }
- if (newType != null)
- {
- // match namespace and add to type factory
- AddEncodeableType(enumType.NodeId, newType);
- }
+ }
+ else
+ {
+ enumDescription = allEnumerationTypes.Where(node =>
+ node.BrowseName.Name == item.Name &&
+ (node.BrowseName.NamespaceIndex == complexTypeBuilder.TargetNamespaceIndex ||
+ complexTypeBuilder.TargetNamespaceIndex == -1)).FirstOrDefault()
+ as DataTypeNode;
+ }
+ if (enumDescription != null)
+ {
+ var qName = new XmlQualifiedName(item.Name, complexTypeBuilder.TargetNamespace);
+ typeDictionary[qName] = enumDescription.NodeId;
+ }
+ if (newType != null)
+ {
+ // match namespace and add to type factory
+ AddEncodeableType(enumType.NodeId, newType);
}
}
}
@@ -1044,12 +1056,32 @@ namespace Opc.Ua.Client.ComplexTypes
///
private Type GetFieldType(StructureField field)
{
- Type fieldType = null;
Type collectionType = null;
+
+ if (field.ValueRank != ValueRanks.Scalar &&
+ field.ValueRank != ValueRanks.OneDimension)
+ {
+ throw new DataTypeNotSupportedException(field.DataType, $"The ValueRank {field.ValueRank} is not supported.");
+ }
+
+ Type fieldType = field.DataType.NamespaceIndex == 0 ?
+ Opc.Ua.TypeInfo.GetSystemType(field.DataType, m_session.Factory) :
+ GetSystemType(field.DataType);
+ if (fieldType == null)
+ {
+ var superType = GetBuiltInSuperType(field.DataType);
+ if (superType != null &&
+ !superType.IsNullNodeId)
+ {
+ field.DataType = superType;
+ return GetFieldType(field);
+ }
+ return null;
+ }
+
if (field.DataType.NamespaceIndex == 0)
{
- fieldType = Opc.Ua.TypeInfo.GetSystemType(field.DataType, m_session.Factory);
- if (field.ValueRank >= 0)
+ if (field.ValueRank == ValueRanks.OneDimension)
{
if (fieldType == typeof(Byte[]))
{
@@ -1069,12 +1101,7 @@ namespace Opc.Ua.Client.ComplexTypes
}
else
{
- fieldType = GetSystemType(field.DataType);
- if (fieldType == null)
- {
- return null;
- }
- if (field.ValueRank >= 0)
+ if (field.ValueRank == ValueRanks.OneDimension)
{
String collectionClassName = (fieldType.Namespace != null) ? fieldType.Namespace + "." : "";
collectionClassName += fieldType.Name + "Collection, " + fieldType.Assembly;
@@ -1082,7 +1109,7 @@ namespace Opc.Ua.Client.ComplexTypes
}
}
- if (field.ValueRank >= 0)
+ if (field.ValueRank == ValueRanks.OneDimension)
{
fieldType = collectionType ?? fieldType.MakeArrayType();
}
@@ -1090,6 +1117,33 @@ namespace Opc.Ua.Client.ComplexTypes
return fieldType;
}
+ ///
+ /// Find superType for a datatype.
+ ///
+ private NodeId GetBuiltInSuperType(NodeId dataType)
+ {
+ var superType = dataType;
+ do
+ {
+ superType = m_session.NodeCache.FindSuperType(superType);
+ if (superType == null ||
+ superType.IsNullNodeId)
+ {
+ return null;
+ }
+ if (superType.NamespaceIndex == 0)
+ {
+ if (superType == DataTypeIds.Enumeration ||
+ superType == DataTypeIds.Structure)
+ {
+ return null;
+ }
+ break;
+ }
+ } while (true);
+ return superType;
+ }
+
///
/// Split the dictionary types into a list of structures and enumerations.
/// Sort the structures by dependencies, with structures with dependent
@@ -1129,14 +1183,13 @@ namespace Opc.Ua.Client.ComplexTypes
}
}
}
- #endregion
+#endregion
- #region Private Fields
+#region Private Fields
private Session m_session;
private IComplexTypeFactory m_complexTypeBuilderFactory;
private string[] m_supportedEncodings = new string[] { BrowseNames.DefaultBinary, BrowseNames.DefaultXml, BrowseNames.DefaultJson };
private const string kOpcComplexTypesPrefix = "Opc.Ua.ComplexTypes.";
- #endregion
+#endregion
}
-
}//namespace
diff --git a/SampleApplications/SDK/Opc.Ua.Client.ComplexTypes/DataTypeDefinitionExtension.cs b/SampleApplications/SDK/Opc.Ua.Client.ComplexTypes/DataTypeDefinitionExtension.cs
index 884356a1be..00aa267962 100644
--- a/SampleApplications/SDK/Opc.Ua.Client.ComplexTypes/DataTypeDefinitionExtension.cs
+++ b/SampleApplications/SDK/Opc.Ua.Client.ComplexTypes/DataTypeDefinitionExtension.cs
@@ -108,13 +108,13 @@ namespace Opc.Ua.Client.ComplexTypes
// test forbidden combinations
if (!isSupportedType)
{
- throw new ServiceResultException(StatusCodes.BadNotSupported,
+ throw new DataTypeNotSupportedException(
"The structure definition uses a Terminator or LengthInBytes, which are not supported.");
}
if (isUnionType && hasBitField)
{
- throw new ServiceResultException(StatusCodes.BadNotSupported,
+ throw new DataTypeNotSupportedException(
"The structure definition combines a Union and a bit filed, both of which are not supported in a single structure.");
}
@@ -148,7 +148,7 @@ namespace Opc.Ua.Client.ComplexTypes
}
else
{
- throw new ServiceResultException(StatusCodes.BadNotSupported,
+ throw new DataTypeNotSupportedException(
"Options for bit selectors must be 32 bit in size, use the Int32 datatype and must be the first element in the structure.");
}
continue;
@@ -157,7 +157,7 @@ namespace Opc.Ua.Client.ComplexTypes
if (switchFieldBitPosition != 0 &&
switchFieldBitPosition != 32)
{
- throw new ServiceResultException(StatusCodes.BadNotSupported,
+ throw new DataTypeNotSupportedException(
"Bitwise option selectors must have 32 bits.");
}
@@ -177,7 +177,7 @@ namespace Opc.Ua.Client.ComplexTypes
var lastField = structureDefinition.Fields.Last();
if (lastField.Name != field.LengthField)
{
- throw new ServiceResultException(StatusCodes.BadNotSupported,
+ throw new DataTypeNotSupportedException(
"The length field must precede the type field of an array.");
}
lastField.Name = field.Name;
@@ -193,14 +193,14 @@ namespace Opc.Ua.Client.ComplexTypes
{
if (structureDefinition.Fields.Count != 0)
{
- throw new ServiceResultException(StatusCodes.BadNotSupported,
+ throw new DataTypeNotSupportedException(
"The switch field of a union must be the first field in the complex type.");
}
continue;
}
if (structureDefinition.Fields.Count != dataTypeFieldPosition)
{
- throw new ServiceResultException(StatusCodes.BadNotSupported,
+ throw new DataTypeNotSupportedException(
"The count of the switch field of the union member is not matching the field position.");
}
dataTypeFieldPosition++;
@@ -213,7 +213,7 @@ namespace Opc.Ua.Client.ComplexTypes
byte value;
if (!switchFieldBits.TryGetValue(field.SwitchField, out value))
{
- throw new ServiceResultException(StatusCodes.BadNotSupported,
+ throw new DataTypeNotSupportedException(
$"The switch field for {field.SwitchField} does not exist.");
}
}
@@ -261,7 +261,7 @@ namespace Opc.Ua.Client.ComplexTypes
var internalField = typeof(DataTypeIds).GetField(typeName.Name);
if (internalField == null)
{
- throw new ServiceResultException(StatusCodes.BadDataTypeIdUnknown,
+ throw new DataTypeNotFoundException(
$"The type {typeName.Name} was not found in the internal type factory.");
}
return (NodeId)internalField.GetValue(typeName.Name);
@@ -270,7 +270,7 @@ namespace Opc.Ua.Client.ComplexTypes
{
if (!typeCollection.TryGetValue(typeName, out NodeId referenceId))
{
- throw new ComplexTypeSystem.DataTypeNotFoundException(
+ throw new DataTypeNotFoundException(
typeName.Name,
$"The type {typeName.Name} in namespace {typeName.Namespace} was not found.");
}
diff --git a/SampleApplications/SDK/Opc.Ua.Client.ComplexTypes/DataTypeException.cs b/SampleApplications/SDK/Opc.Ua.Client.ComplexTypes/DataTypeException.cs
new file mode 100644
index 0000000000..390b5ca8e0
--- /dev/null
+++ b/SampleApplications/SDK/Opc.Ua.Client.ComplexTypes/DataTypeException.cs
@@ -0,0 +1,101 @@
+/* ========================================================================
+ * Copyright (c) 2005-2019 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+
+namespace Opc.Ua.Client.ComplexTypes
+{
+
+ ///
+ /// Exception is thrown if data type is not found.
+ ///
+ public class DataTypeNotFoundException : Exception
+ {
+ public ExpandedNodeId nodeId;
+ public string typeName;
+
+ public DataTypeNotFoundException(ExpandedNodeId nodeId)
+ {
+ this.nodeId = nodeId;
+ }
+
+ public DataTypeNotFoundException(string typeName, string message)
+ : base(message)
+ {
+ this.nodeId = NodeId.Null;
+ this.typeName = typeName;
+ }
+
+ public DataTypeNotFoundException(ExpandedNodeId nodeId, string message)
+ : base(message)
+ {
+ this.nodeId = nodeId;
+ }
+
+ public DataTypeNotFoundException(ExpandedNodeId nodeId, string message, Exception inner)
+ : base(message, inner)
+ {
+ this.nodeId = nodeId;
+ }
+ }
+
+ ///
+ /// DataType is not supported due to structure or value rank.
+ ///
+ public class DataTypeNotSupportedException : Exception
+ {
+ public ExpandedNodeId nodeId;
+ public string typeName;
+
+ public DataTypeNotSupportedException(ExpandedNodeId nodeId)
+ {
+ this.nodeId = nodeId;
+ }
+
+ public DataTypeNotSupportedException(string typeName, string message)
+ : base(message)
+ {
+ this.nodeId = NodeId.Null;
+ this.typeName = typeName;
+ }
+
+ public DataTypeNotSupportedException(ExpandedNodeId nodeId, string message)
+ : base(message)
+ {
+ this.nodeId = nodeId;
+ }
+
+ public DataTypeNotSupportedException(ExpandedNodeId nodeId, string message, Exception inner)
+ : base(message, inner)
+ {
+ this.nodeId = nodeId;
+ }
+ }
+
+}//namespace
diff --git a/SampleApplications/SDK/Opc.Ua.Client.ComplexTypes/Types/BaseComplexType.cs b/SampleApplications/SDK/Opc.Ua.Client.ComplexTypes/Types/BaseComplexType.cs
index 43794f8f7e..449fbf7f1c 100644
--- a/SampleApplications/SDK/Opc.Ua.Client.ComplexTypes/Types/BaseComplexType.cs
+++ b/SampleApplications/SDK/Opc.Ua.Client.ComplexTypes/Types/BaseComplexType.cs
@@ -95,7 +95,7 @@ namespace Opc.Ua.Client.ComplexTypes
public ExpandedNodeId XmlEncodingId { get; set; }
///
- public StructureType StructureType => StructureType.Structure;
+ public virtual StructureType StructureType => StructureType.Structure;
///
/// Makes a deep copy of the object.
@@ -663,7 +663,7 @@ namespace Opc.Ua.Client.ComplexTypes
var propertyType = property.PropertyType;
if (propertyType == typeof(Boolean))
{
- property.SetValue(this, decoder.ReadBoolean(property.Name));
+ property.SetValue(this, decoder.ReadBoolean(name));
}
else if (propertyType == typeof(SByte))
{
diff --git a/SampleApplications/SDK/Opc.Ua.Client.ComplexTypes/Types/OptionalFieldsComplexType.cs b/SampleApplications/SDK/Opc.Ua.Client.ComplexTypes/Types/OptionalFieldsComplexType.cs
index 06173f3035..c6fc7dc5c0 100644
--- a/SampleApplications/SDK/Opc.Ua.Client.ComplexTypes/Types/OptionalFieldsComplexType.cs
+++ b/SampleApplications/SDK/Opc.Ua.Client.ComplexTypes/Types/OptionalFieldsComplexType.cs
@@ -59,7 +59,7 @@ namespace Opc.Ua.Client.ComplexTypes
#region Public Properties
///
- new public StructureType StructureType => StructureType.StructureWithOptionalFields;
+ public override StructureType StructureType => StructureType.StructureWithOptionalFields;
///
/// The encoding mask for the optional fields.
diff --git a/SampleApplications/SDK/Opc.Ua.Client.ComplexTypes/Types/UnionComplexType.cs b/SampleApplications/SDK/Opc.Ua.Client.ComplexTypes/Types/UnionComplexType.cs
index 9a0793964d..1da4abdd02 100644
--- a/SampleApplications/SDK/Opc.Ua.Client.ComplexTypes/Types/UnionComplexType.cs
+++ b/SampleApplications/SDK/Opc.Ua.Client.ComplexTypes/Types/UnionComplexType.cs
@@ -65,7 +65,7 @@ namespace Opc.Ua.Client.ComplexTypes
public UInt32 SwitchField => m_switchField;
///
- new public StructureType StructureType => StructureType.Union;
+ public override StructureType StructureType => StructureType.Union;
///
/// Makes a deep copy of the object.
diff --git a/SampleApplications/Samples/GDS/ClientCommon/GlobalDiscoveryServerClient.cs b/SampleApplications/Samples/GDS/ClientCommon/GlobalDiscoveryServerClient.cs
index 86723d1c79..9cdd88bf5e 100644
--- a/SampleApplications/Samples/GDS/ClientCommon/GlobalDiscoveryServerClient.cs
+++ b/SampleApplications/Samples/GDS/ClientCommon/GlobalDiscoveryServerClient.cs
@@ -944,7 +944,7 @@ namespace Opc.Ua.Gds.Client
{
try
{
- if (Object.ReferenceEquals(Session.Identity, AdminCredentials))
+ if (!Object.ReferenceEquals(Session.Identity, oldUser))
{
Session.UpdateSession(oldUser, PreferredLocales);
}
diff --git a/SampleApplications/Samples/GDS/ClientCommon/ServerPushConfigurationClient.cs b/SampleApplications/Samples/GDS/ClientCommon/ServerPushConfigurationClient.cs
index 6082b63bbc..b85e0cc57d 100644
--- a/SampleApplications/Samples/GDS/ClientCommon/ServerPushConfigurationClient.cs
+++ b/SampleApplications/Samples/GDS/ClientCommon/ServerPushConfigurationClient.cs
@@ -30,11 +30,11 @@
using System;
using System.IO;
-using Opc.Ua.Client;
-using Opc.Ua.Configuration;
+using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
-using System.Reflection;
+using Opc.Ua.Client;
+using Opc.Ua.Configuration;
namespace Opc.Ua.Gds.Client
{
@@ -59,7 +59,7 @@ namespace Opc.Ua.Gds.Client
public NodeId DefaultHttpsGroup { get; private set; }
public NodeId DefaultUserTokenGroup { get; private set; }
// TODO: currently only sha256 cert is supported
- public NodeId ApplicationCertificateType { get { return Opc.Ua.ObjectTypeIds.RsaSha256ApplicationCertificateType; } }
+ public NodeId ApplicationCertificateType => Opc.Ua.ObjectTypeIds.RsaSha256ApplicationCertificateType;
///
/// Gets the application instance.
@@ -67,10 +67,7 @@ namespace Opc.Ua.Gds.Client
///
/// The application instance.
///
- public ApplicationInstance Application
- {
- get { return m_application; }
- }
+ public ApplicationInstance Application => m_application;
///
/// Gets or sets the admin credentials.
@@ -124,10 +121,7 @@ namespace Opc.Ua.Gds.Client
///
/// true if the session is connected; otherwise, false.
///
- public bool IsConnected
- {
- get { return m_session != null && m_session.Connected; }
- }
+ public bool IsConnected => m_session != null && m_session.Connected;
///
/// Gets the session.
@@ -135,10 +129,7 @@ namespace Opc.Ua.Gds.Client
///
/// The session.
///
- public Session Session
- {
- get { return m_session; }
- }
+ public Session Session => m_session;
///
/// Gets the endpoint.
@@ -253,7 +244,7 @@ namespace Opc.Ua.Gds.Client
false,
m_application.ApplicationName,
60000,
- null,
+ m_adminCredentials,
m_preferredLocales);
m_endpoint = m_session.ConfiguredEndpoint;
@@ -782,7 +773,7 @@ namespace Opc.Ua.Gds.Client
{
try
{
- if (Object.ReferenceEquals(m_session.Identity, m_adminCredentials))
+ if (!Object.ReferenceEquals(m_session.Identity, oldUser))
{
m_session.UpdateSession(oldUser, m_preferredLocales);
}
diff --git a/SampleApplications/Samples/NetCoreComplexClient/Program.cs b/SampleApplications/Samples/NetCoreComplexClient/Program.cs
index 575c3c33af..5a96aafde6 100644
--- a/SampleApplications/Samples/NetCoreComplexClient/Program.cs
+++ b/SampleApplications/Samples/NetCoreComplexClient/Program.cs
@@ -75,18 +75,26 @@ namespace NetCoreConsoleClient
int stopTimeout = Timeout.Infinite;
bool autoAccept = false;
bool writeComplexInt = false;
- bool noloadTypes = false;
+ bool noTypes = false;
+ bool noBrowse = false;
bool verbose = false;
bool json = false;
+ bool jsonReversible = false;
+ string username = null;
+ string pw = null;
Mono.Options.OptionSet options = new Mono.Options.OptionSet {
{ "h|help", "show this message and exit", h => showHelp = h != null },
{ "a|autoaccept", "auto accept certificates (for testing only)", a => autoAccept = a != null },
{ "t|timeout=", "the number of seconds until the client stops.", (int t) => stopTimeout = t },
{ "w|writeint", "Read and increment all complex types with an Int32.", w => writeComplexInt = w != null},
- { "n|noloadtypes", "Load the type system dictionary from the server.", n => noloadTypes = n != null},
+ { "n|notypes", "Do not load the type system dictionary from the server.", n => noTypes = n != null},
+ { "b|nobrowse", "Do not browse the address space of the server.", n => noBrowse = n != null},
+ { "u|username=", "Username to access server.", (string n) => username = n},
+ { "p|password=", "Password to access server.", (string n) => pw = n},
{ "v|verbose", "Verbose output.", v => verbose = v != null},
{ "j|json", "Print custom nodes as Json.", j => json = j != null},
+ { "r|reversible", "Use Json reversible encoding.", r => jsonReversible = r != null},
};
IList extraArgs = null;
@@ -133,9 +141,13 @@ namespace NetCoreConsoleClient
MySampleClient client = new MySampleClient(endpointURL, autoAccept, stopTimeout) {
Verbose = verbose,
- LoadTypeSystem = !noloadTypes,
+ LoadTypeSystem = !noTypes,
+ BrowseAdddressSpace = !noBrowse,
WriteComplexInt = writeComplexInt,
- PrintAsJson = json
+ PrintAsJson = json,
+ JsonReversible = jsonReversible,
+ Username = username,
+ Password = pw
};
return (int)client.Run();
}
@@ -143,12 +155,17 @@ namespace NetCoreConsoleClient
public class MySampleClient
{
- const int kReconnectPeriod = 10;
+ public int ReconnectPeriod { get; set; } = 10;
public ExitCode ExitCode { get; set; }
public bool Verbose { get; set; } = false;
public bool WriteComplexInt { get; set; } = false;
public bool PrintAsJson { get; set; } = false;
+ public bool JsonReversible { get; set; } = false;
public bool LoadTypeSystem { get; set; } = false;
+ public bool BrowseAdddressSpace { get; set; } = false;
+ public String Username { get; set; }
+ public String Password { get; set; }
+
public MySampleClient(
string endpointURL,
@@ -222,10 +239,10 @@ namespace NetCoreConsoleClient
};
// load the application configuration.
- ApplicationConfiguration config = await application.LoadApplicationConfiguration(false);
+ ApplicationConfiguration config = await application.LoadApplicationConfiguration(false).ConfigureAwait(false);
// check the application certificate.
- bool haveAppCertificate = await application.CheckApplicationInstanceCertificate(false, 0);
+ bool haveAppCertificate = await application.CheckApplicationInstanceCertificate(false, 0).ConfigureAwait(false);
if (!haveAppCertificate)
{
throw new Exception("Application instance certificate invalid!");
@@ -254,8 +271,19 @@ namespace NetCoreConsoleClient
Console.WriteLine("3 - Create a session with OPC UA server.");
ExitCode = ExitCode.ErrorCreateSession;
+ // create the user identity
+ UserIdentity userIdentity;
+ if (String.IsNullOrEmpty(Username) && String.IsNullOrEmpty(Password))
+ {
+ userIdentity = new UserIdentity(new AnonymousIdentityToken());
+ }
+ else
+ {
+ userIdentity = new UserIdentity(Username, Password);
+ }
+
// create worker session
- m_session = await CreateSession(config, selectedEndpoint);
+ m_session = await CreateSession(config, selectedEndpoint, userIdentity).ConfigureAwait(false);
// register keep alive handler
m_session.KeepAlive += Client_KeepAlive;
@@ -265,7 +293,7 @@ namespace NetCoreConsoleClient
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
- var allVariableNodes = BrowseAllVariables();
+ var allVariableNodes = BrowseAdddressSpace ? BrowseAllVariables() : new List();
var allCustomTypeVariables = allVariableNodes.Where(n => ((VariableNode)n).DataType.NamespaceIndex != 0).ToList();
stopWatch.Stop();
@@ -286,7 +314,7 @@ namespace NetCoreConsoleClient
stopWatch.Start();
var complexTypeSystem = new ComplexTypeSystem(m_session);
- await complexTypeSystem.Load();
+ await complexTypeSystem.Load().ConfigureAwait(false);
stopWatch.Stop();
@@ -369,13 +397,13 @@ namespace NetCoreConsoleClient
try
{
Console.WriteLine($"Open session for {variableNode}:");
- testSession = await CreateSession(config, selectedEndpoint);
+ testSession = await CreateSession(config, selectedEndpoint, userIdentity).ConfigureAwait(false);
var complexTypeSystem = new ComplexTypeSystem(testSession);
NodeId dataType = variableNode.DataType;
Type nullType = testSession.Factory.GetSystemType(dataType);
var valueBefore = testSession.ReadValue(variableNode.NodeId);
Console.WriteLine($" -- {valueBefore}");
- Type systemType = await complexTypeSystem.LoadType(dataType);
+ Type systemType = await complexTypeSystem.LoadType(dataType).ConfigureAwait(false);
var valueAfter = testSession.ReadValue(variableNode.NodeId);
Console.WriteLine($" -- {variableNode}: {systemType} {dataType}");
Console.WriteLine($" -- {valueAfter}");
@@ -505,7 +533,7 @@ namespace NetCoreConsoleClient
{
Console.WriteLine("--- RECONNECTING ---");
m_reconnectHandler = new SessionReconnectHandler();
- m_reconnectHandler.BeginReconnect(sender, kReconnectPeriod * 1000, Client_ReconnectComplete);
+ m_reconnectHandler.BeginReconnect(sender, ReconnectPeriod * 1000, Client_ReconnectComplete);
}
}
}
@@ -543,11 +571,11 @@ namespace NetCoreConsoleClient
}
}
- private Task CreateSession(ApplicationConfiguration config, EndpointDescription selectedEndpoint)
+ private Task CreateSession(ApplicationConfiguration config, EndpointDescription selectedEndpoint, IUserIdentity userIdentity)
{
var endpointConfiguration = EndpointConfiguration.Create(config);
var endpoint = new ConfiguredEndpoint(null, selectedEndpoint, endpointConfiguration);
- return Session.Create(config, endpoint, false, "OPC UA Console Client", 60000, new UserIdentity(new AnonymousIdentityToken()), null);
+ return Session.Create(config, endpoint, false, "OPC UA Complex Types Client", 60000, userIdentity, null);
}
private void WriteValue(Session session, NodeId variableId, DataValue value)
@@ -586,7 +614,7 @@ namespace NetCoreConsoleClient
private void PrintValueAsJson(string name, DataValue value)
{
- var jsonEncoder = new JsonEncoder(m_session.MessageContext, false);
+ var jsonEncoder = new JsonEncoder(m_session.MessageContext, JsonReversible);
jsonEncoder.WriteDataValue(name, value);
var textbuffer = jsonEncoder.CloseAndReturnText();
// prettify
@@ -611,7 +639,7 @@ namespace NetCoreConsoleClient
Console.WriteLine(textbuffer);
Console.WriteLine(stringWriter.ToString());
ExitCode = ExitCode.ErrorJSONDecode;
- throw ex;
+ throw ;
}
}
}
diff --git a/Stack/Opc.Ua.Core/Security/Certificates/CertificateFactory.cs b/Stack/Opc.Ua.Core/Security/Certificates/CertificateFactory.cs
index 6246670d14..0580b2598a 100644
--- a/Stack/Opc.Ua.Core/Security/Certificates/CertificateFactory.cs
+++ b/Stack/Opc.Ua.Core/Security/Certificates/CertificateFactory.cs
@@ -536,7 +536,11 @@ public class CertificateFactory
List certCACrl = store.EnumerateCRLs(certCA, false);
- var certificateCollection = new X509Certificate2Collection() { certificate };
+ var certificateCollection = new X509Certificate2Collection() { };
+ if (!isCACert)
+ {
+ certificateCollection.Add(certificate);
+ }
updatedCRL = RevokeCertificate(certCAWithPrivateKey, certCACrl, certificateCollection);
store.AddCRL(updatedCRL);
diff --git a/Stack/Opc.Ua.Core/Stack/Https/HttpsListener.cs b/Stack/Opc.Ua.Core/Stack/Https/HttpsListener.cs
index ea7c37d8d8..41e11a144d 100644
--- a/Stack/Opc.Ua.Core/Stack/Https/HttpsListener.cs
+++ b/Stack/Opc.Ua.Core/Stack/Https/HttpsListener.cs
@@ -177,7 +177,7 @@ namespace Opc.Ua.Bindings
{
Startup.Listener = this;
m_hostBuilder = new WebHostBuilder();
-#if NETSTANDARD2_0
+#if NETSTANDARD2_0 || NETSTANDARD2_1
HttpsConnectionAdapterOptions httpsOptions = new HttpsConnectionAdapterOptions();
httpsOptions.CheckCertificateRevocation = false;
httpsOptions.ClientCertificateMode = ClientCertificateMode.NoCertificate;
diff --git a/Stack/Opc.Ua.Core/Types/Encoders/EncodableObject.cs b/Stack/Opc.Ua.Core/Types/Encoders/EncodableObject.cs
index e1ba8f1806..260bcece54 100644
--- a/Stack/Opc.Ua.Core/Types/Encoders/EncodableObject.cs
+++ b/Stack/Opc.Ua.Core/Types/Encoders/EncodableObject.cs
@@ -67,9 +67,9 @@ namespace Opc.Ua
return StatusCodes.BadDataEncodingUnsupported;
}
- bool useXml = dataEncoding.Name == DefaultXml;
+ bool useXml = dataEncoding.Name == BrowseNames.DefaultXml;
- if (!useXml && dataEncoding.Name != DefaultBinary)
+ if (!useXml && dataEncoding.Name != BrowseNames.DefaultBinary)
{
return StatusCodes.BadDataEncodingInvalid;
}
@@ -198,16 +198,6 @@ namespace Opc.Ua
encoder.WriteEncodeable(null, encodeable, null);
return encoder.CloseAndReturnBuffer();
}
-
- ///
- /// The BrowseName for the DefaultBinary component.
- ///
- private const string DefaultBinary = "Default Binary";
-
- ///
- /// The BrowseName for the DefaultXml component.
- ///
- private const string DefaultXml = "Default XML";
#endregion
///
diff --git a/Stack/Opc.Ua.Core/Types/Schemas/BinarySchemaValidator.cs b/Stack/Opc.Ua.Core/Types/Schemas/BinarySchemaValidator.cs
index 481c85dcbf..72387a349f 100644
--- a/Stack/Opc.Ua.Core/Types/Schemas/BinarySchemaValidator.cs
+++ b/Stack/Opc.Ua.Core/Types/Schemas/BinarySchemaValidator.cs
@@ -339,7 +339,7 @@ namespace Opc.Ua.Schema.Binary
return false;
}
- if (!Char.IsLetter(name[0]) && name[0] != '_')
+ if (!Char.IsLetter(name[0]) && name[0] != '_' && name[0] != '"')
{
return false;
}
@@ -351,7 +351,7 @@ namespace Opc.Ua.Schema.Binary
continue;
}
- if (name[ii] == '.' || name[ii] == '-' || name[ii] == '_')
+ if (name[ii] == '.' || name[ii] == '-' || name[ii] == '_' || name[ii] == '"')
{
continue;
}