diff --git a/ComIOP/Common/Client/Ae/AeAreaBrowser.cs b/ComIOP/Common/Client/Ae/AeAreaBrowser.cs
deleted file mode 100644
index 121696269..000000000
--- a/ComIOP/Common/Client/Ae/AeAreaBrowser.cs
+++ /dev/null
@@ -1,285 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using System.Xml;
-using System.IO;
-using System.Reflection;
-using System.Threading;
-using Opc.Ua;
-using Opc.Ua.Server;
-using Opc.Ua.Com;
-using OpcRcw.Ae;
-using OpcRcw.Comn;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// Browses the children of a segment.
- ///
- public class AeAreaBrower : NodeBrowser
- {
- #region Constructors
- ///
- /// Creates a new browser object with a set of filters.
- ///
- /// The system context to use.
- /// The view which may restrict the set of references/nodes found.
- /// The type of references being followed.
- /// Whether subtypes of the reference type are followed.
- /// Which way the references are being followed.
- /// The browse name of a specific target (used when translating browse paths).
- /// Any additional references that should be included.
- /// If true the browser should not making blocking calls to external systems.
- /// Name of the qualified.
- /// Index of the namespace.
- public AeAreaBrower(
- ISystemContext context,
- ViewDescription view,
- NodeId referenceType,
- bool includeSubtypes,
- BrowseDirection browseDirection,
- QualifiedName browseName,
- IEnumerable additionalReferences,
- bool internalOnly,
- string qualifiedName,
- ushort namespaceIndex)
- :
- base(
- context,
- view,
- referenceType,
- includeSubtypes,
- browseDirection,
- browseName,
- additionalReferences,
- internalOnly)
- {
- m_qualifiedName = qualifiedName;
- m_namespaceIndex = namespaceIndex;
- m_stage = Stage.Begin;
- }
- #endregion
-
- #region Overridden Methods
- ///
- /// Returns the next reference.
- ///
- /// The next reference that meets the browse criteria.
- public override IReference Next()
- {
- lock (DataLock)
- {
- IReference reference = null;
-
- // enumerate pre-defined references.
- // always call first to ensure any pushed-back references are returned first.
- reference = base.Next();
-
- if (reference != null)
- {
- return reference;
- }
-
- // don't start browsing huge number of references when only internal references are requested.
- if (InternalOnly)
- {
- return null;
- }
-
- // fetch references from the server.
- do
- {
- // fetch next reference.
- reference = NextChild();
-
- if (reference != null)
- {
- return reference;
- }
-
- // go to the next stage.
- NextStage();
- }
- while (m_stage != Stage.Done);
-
- // all done.
- return null;
- }
- }
- #endregion
-
- #region Private Methods
- ///
- /// Returns the next child.
- ///
- private IReference NextChild()
- {
- // check if a specific browse name is requested.
- if (QualifiedName.IsNull(base.BrowseName))
- {
- return NextChild(m_stage);
- }
-
- // keep fetching references until a matching browse name if found.
- NodeStateReference reference = null;
-
- do
- {
- reference = NextChild(m_stage);
-
- if (reference != null)
- {
- // need to let the caller look up the browse name.
- if (reference.Target == null)
- {
- return reference;
- }
-
- // check for browse name match.
- if (reference.Target.BrowseName == base.BrowseName)
- {
- return reference;
- }
- }
- }
- while (reference != null);
-
- // no match - need to go onto the next stage.
- return null;
- }
-
- ///
- /// Returns the next child.
- ///
- private NodeStateReference NextChild(Stage stage)
- {
- // fetch children.
- if (stage == Stage.Children)
- {
- if (m_browser == null)
- {
- return null;
- }
-
- BaseObjectState node = m_browser.Next(SystemContext, m_namespaceIndex);
-
- if (node != null)
- {
- return new NodeStateReference(ReferenceTypeIds.HasNotifier, false, node.NodeId);
- }
-
- // all done.
- return null;
- }
-
- // fetch child parents.
- if (stage == Stage.Parents)
- {
- return null;
- }
-
- return null;
- }
-
- ///
- /// Initializes the next stage of browsing.
- ///
- private void NextStage()
- {
- ComAeClientManager system = (ComAeClientManager)this.SystemContext.SystemHandle;
- ComAeClient client = system.SelectClient((ServerSystemContext)SystemContext, false);
-
- // determine which stage is next based on the reference types requested.
- for (Stage next = m_stage+1; next <= Stage.Done; next++)
- {
- if (next == Stage.Children)
- {
- if (IsRequired(ReferenceTypeIds.HasNotifier, false))
- {
- m_stage = next;
- break;
- }
- }
-
- else if (next == Stage.Parents)
- {
- if (IsRequired(ReferenceTypeIds.HasNotifier, true))
- {
- m_stage = next;
- break;
- }
- }
-
- else if (next == Stage.Done)
- {
- m_stage = next;
- break;
- }
- }
-
- // start enumerating areas.
- if (m_stage == Stage.Children)
- {
- m_browser = new ComAeBrowserClient(client, m_qualifiedName);
- return;
- }
-
- // start enumerating parents.
- if (m_stage == Stage.Parents)
- {
- return;
- }
-
- // all done.
- }
- #endregion
-
- #region Stage Enumeration
- ///
- /// The stages available in a browse operation.
- ///
- private enum Stage
- {
- Begin,
- Children,
- Parents,
- Done
- }
- #endregion
-
- #region Private Fields
- private Stage m_stage;
- private string m_qualifiedName;
- private ushort m_namespaceIndex;
- private ComAeBrowserClient m_browser;
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/Ae/AeAreaState.cs b/ComIOP/Common/Client/Ae/AeAreaState.cs
deleted file mode 100644
index 618e82c86..000000000
--- a/ComIOP/Common/Client/Ae/AeAreaState.cs
+++ /dev/null
@@ -1,132 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using System.Xml;
-using System.IO;
-using System.Reflection;
-using System.Threading;
-using Opc.Ua;
-using Opc.Ua.Server;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// A object which maps a segment to a UA object.
- ///
- public partial class AeAreaState : FolderState
- {
- #region Constructors
- ///
- /// Initializes a new instance of the class.
- ///
- /// The context.
- /// The qualified name for the area.
- /// The name of the area.
- /// Index of the namespace.
- public AeAreaState(
- ISystemContext context,
- string qualifiedName,
- string name,
- ushort namespaceIndex)
- :
- base(null)
- {
- m_qualifiedName = qualifiedName;
-
- this.SymbolicName = name;
- this.TypeDefinitionId = Opc.Ua.ObjectTypeIds.FolderType;
- this.NodeId = AeModelUtils.ConstructIdForArea(qualifiedName, namespaceIndex);
- this.BrowseName = new QualifiedName(name, namespaceIndex);
- this.DisplayName = this.BrowseName.Name;
- this.Description = null;
- this.WriteMask = 0;
- this.UserWriteMask = 0;
- this.EventNotifier = EventNotifiers.SubscribeToEvents;
- }
- #endregion
-
- #region Public Properties
- ///
- /// Gets the qualified name for the area.
- ///
- /// The qualified name for the area.
- public string QualifiedName
- {
- get { return m_qualifiedName; }
- }
- #endregion
-
- #region Overridden Methods
- ///
- /// Creates a browser that finds the references to the branch.
- ///
- /// The system context to use.
- /// The view which may restrict the set of references/nodes found.
- /// The type of references being followed.
- /// Whether subtypes of the reference type are followed.
- /// Which way the references are being followed.
- /// The browse name of a specific target (used when translating browse paths).
- /// Any additional references that should be included.
- /// If true the browser should not making blocking calls to external systems.
- /// The browse object (must be disposed).
- public override INodeBrowser CreateBrowser(
- ISystemContext context,
- ViewDescription view,
- NodeId referenceType,
- bool includeSubtypes,
- BrowseDirection browseDirection,
- QualifiedName browseName,
- IEnumerable additionalReferences,
- bool internalOnly)
- {
- NodeBrowser browser = new AeAreaBrower(
- context,
- view,
- referenceType,
- includeSubtypes,
- browseDirection,
- browseName,
- additionalReferences,
- internalOnly,
- m_qualifiedName,
- this.NodeId.NamespaceIndex);
-
- PopulateBrowser(context, browser);
-
- return browser;
- }
- #endregion
-
- #region Private Fields
- private string m_qualifiedName;
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/Ae/AeConditionState.cs b/ComIOP/Common/Client/Ae/AeConditionState.cs
deleted file mode 100644
index bfe21b8ce..000000000
--- a/ComIOP/Common/Client/Ae/AeConditionState.cs
+++ /dev/null
@@ -1,79 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using System.Xml;
-using System.IO;
-using System.Reflection;
-using System.Threading;
-using Opc.Ua;
-using Opc.Ua.Server;
-using OpcRcw.Ae;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// A object which represents a COM AE condition.
- ///
- public partial class AeConditionState : AlarmConditionState
- {
- #region Constructors
- ///
- /// Initializes a new instance of the class.
- ///
- /// The context.
- /// The handle.
- /// The acknowledge method.
- public AeConditionState(ISystemContext context, NodeHandle handle, AddCommentMethodState acknowledgeMethod)
- :
- base(null)
- {
- AeParsedNodeId parsedNodeId = (AeParsedNodeId)handle.ParsedNodeId;
-
- this.NodeId = handle.NodeId;
-
- this.TypeDefinitionId = AeParsedNodeId.Construct(
- Constants.CONDITION_EVENT,
- parsedNodeId.CategoryId,
- parsedNodeId.ConditionName,
- parsedNodeId.NamespaceIndex);
-
- this.Acknowledge = acknowledgeMethod;
- this.AddChild(acknowledgeMethod);
- }
- #endregion
-
- #region Public Properties
- #endregion
-
- #region Private Fields
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/Ae/AeEventTypeState.cs b/ComIOP/Common/Client/Ae/AeEventTypeState.cs
deleted file mode 100644
index 9b4ea2792..000000000
--- a/ComIOP/Common/Client/Ae/AeEventTypeState.cs
+++ /dev/null
@@ -1,189 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using Opc.Ua;
-using OpcRcw.Ae;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// Stores information about an AE event type in the server address space.
- ///
- internal class AeEventTypeState : BaseObjectTypeState
- {
- #region Constructors
- ///
- /// Initializes a new instance of the class.
- ///
- public AeEventTypeState(EventType eventType, ushort namespaceIndex)
- {
- m_eventType = eventType;
-
- // create the name for the event type.
- string name = eventType.Description;
-
- if (!String.IsNullOrEmpty(eventType.ConditionName))
- {
- name = eventType.ConditionName;
- }
-
- if (!name.EndsWith("Type"))
- {
- if (eventType.EventTypeId == OpcRcw.Ae.Constants.CONDITION_EVENT)
- {
- name += "AlarmType";
- }
- else
- {
- name += "EventType";
- }
- }
-
- // the attributes.
- this.NodeId = AeParsedNodeId.Construct(eventType, null, namespaceIndex);
- this.BrowseName = new QualifiedName(name, namespaceIndex);
- this.DisplayName = eventType.Description;
- this.IsAbstract = false;
- this.SuperTypeId = AeParsedNodeId.Construct(eventType.EventTypeMapping, namespaceIndex);
-
- // add the attributes as properties.
- if (eventType.Attributes != null)
- {
- for (int ii = 0; ii < eventType.Attributes.Count; ii++)
- {
- string propertyName = eventType.Attributes[ii].Description;
-
- if (AeTypeCache.IsKnownName(propertyName, "ACK COMMENT"))
- {
- continue;
- }
-
- PropertyState property = new PropertyState(this);
-
- property.SymbolicName = propertyName;
- property.ReferenceTypeId = Opc.Ua.ReferenceTypeIds.HasProperty;
- property.TypeDefinitionId = Opc.Ua.VariableTypeIds.PropertyType;
- property.ModellingRuleId = Opc.Ua.ObjectIds.ModellingRule_Optional;
- property.NodeId = AeParsedNodeId.Construct(eventType, propertyName, namespaceIndex);
- property.BrowseName = new QualifiedName(propertyName, namespaceIndex);
- property.DisplayName = property.BrowseName.Name;
- property.AccessLevel = AccessLevels.None;
- property.UserAccessLevel = AccessLevels.None;
- property.MinimumSamplingInterval = MinimumSamplingIntervals.Indeterminate;
- property.Historizing = false;
-
- bool isArray = false;
- property.DataType = ComUtils.GetDataTypeId(eventType.Attributes[ii].VarType, out isArray);
- property.ValueRank = (isArray) ? ValueRanks.OneDimension : ValueRanks.Scalar;
-
- this.AddChild(property);
- }
- }
- }
- #endregion
-
- #region Public Members
- ///
- /// Gets the event type metadata.
- ///
- public EventType EventType
- {
- get { return m_eventType; }
- }
- #endregion
-
- BaseEventState ConstructEvent(ONEVENTSTRUCT e)
- {
- return null;
- }
-
- #region Private Fields
- private EventType m_eventType;
- #endregion
- }
-
- ///
- /// Stores information about an abstract event type that groups AE events in the type hierarchy.
- ///
- internal class AeEventTypeMappingState : BaseObjectTypeState
- {
- #region Constructors
- ///
- /// Initializes a new instance of the class.
- ///
- public AeEventTypeMappingState(EventTypeMapping eventType, ushort namespaceIndex)
- {
- m_eventType = eventType;
-
- // create the name for the event type.
- string name = "COMAE" + eventType.ToString();
-
- // the attributes.
- this.NodeId = AeParsedNodeId.Construct(eventType, namespaceIndex);
- this.BrowseName = new QualifiedName(name, namespaceIndex);
- this.DisplayName = this.BrowseName.Name;
- this.IsAbstract = true;
-
- // set the supertype.
- switch (eventType)
- {
- case EventTypeMapping.AlarmConditionType: { SuperTypeId = Opc.Ua.ObjectTypeIds.AlarmConditionType; break; }
- case EventTypeMapping.AuditEventType: { SuperTypeId = Opc.Ua.ObjectTypeIds.AuditEventType; break; }
- case EventTypeMapping.BaseEventType: { SuperTypeId = Opc.Ua.ObjectTypeIds.BaseEventType; break; }
- case EventTypeMapping.DeviceFailureEventType: { SuperTypeId = Opc.Ua.ObjectTypeIds.DeviceFailureEventType; break; }
- case EventTypeMapping.DiscreteAlarmType: { SuperTypeId = Opc.Ua.ObjectTypeIds.DiscreteAlarmType; break; }
- case EventTypeMapping.NonExclusiveDeviationAlarmType: { SuperTypeId = Opc.Ua.ObjectTypeIds.NonExclusiveDeviationAlarmType; break; }
- case EventTypeMapping.ExclusiveLevelAlarmType: { SuperTypeId = Opc.Ua.ObjectTypeIds.ExclusiveLevelAlarmType; break; }
- case EventTypeMapping.LimitAlarmType: { SuperTypeId = Opc.Ua.ObjectTypeIds.LimitAlarmType; break; }
- case EventTypeMapping.NonExclusiveLevelAlarmType: { SuperTypeId = Opc.Ua.ObjectTypeIds.NonExclusiveLevelAlarmType; break; }
- case EventTypeMapping.OffNormalAlarmType: { SuperTypeId = Opc.Ua.ObjectTypeIds.OffNormalAlarmType; break; }
- case EventTypeMapping.SystemEventType: { SuperTypeId = Opc.Ua.ObjectTypeIds.SystemEventType; break; }
- case EventTypeMapping.TripAlarmType: { SuperTypeId = Opc.Ua.ObjectTypeIds.TripAlarmType; break; }
- case EventTypeMapping.ConditionClassType: { SuperTypeId = Opc.Ua.ObjectTypeIds.BaseConditionClassType; break; }
- }
- }
- #endregion
-
- #region Public Members
- ///
- /// Gets the event type metadata.
- ///
- public EventTypeMapping EventType
- {
- get { return m_eventType; }
- }
- #endregion
-
- #region Private Fields
- private EventTypeMapping m_eventType;
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/Ae/AeModelUtils.cs b/ComIOP/Common/Client/Ae/AeModelUtils.cs
deleted file mode 100644
index 3a5b11f5e..000000000
--- a/ComIOP/Common/Client/Ae/AeModelUtils.cs
+++ /dev/null
@@ -1,142 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using System.Text;
-using Opc.Ua;
-using Opc.Ua.Server;
-using Opc.Ua.Com;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// A class that builds NodeIds used by the DataAccess NodeManager
- ///
- public static class AeModelUtils
- {
- ///
- /// The RootType for a AE Simple Event Type node.
- ///
- public const int AeSimpleEventType = OpcRcw.Ae.Constants.SIMPLE_EVENT;
-
- ///
- /// The RootType for a AE Tracking Event Type node.
- ///
- public const int AeTrackingEventType = OpcRcw.Ae.Constants.TRACKING_EVENT;
-
- ///
- /// The RootType for a AE Condition Event Type node.
- ///
- public const int AeConditionEventType = OpcRcw.Ae.Constants.CONDITION_EVENT;
-
- ///
- /// The RootType for a AE Area
- ///
- public const int AeArea = 5;
-
- ///
- /// The RootType for an AE Source
- ///
- public const int AeSource = 6;
-
- ///
- /// The RootType for an AE Condition
- ///
- public const int AeCondition = 7;
-
- ///
- /// The RootType for a node defined by the UA server.
- ///
- public const int InternalNode = 8;
-
- ///
- /// The RootType for an EventType defined by the AE server.
- ///
- public const int AeEventTypeMapping = 9;
-
- ///
- /// The RootType for a ConditionClass defined by the AE server.
- ///
- public const int AeConditionClassMapping = 10;
-
- ///
- /// Constructs a NodeId from the BrowseName of an internal node.
- ///
- /// The browse name.
- /// Index of the namespace.
- /// The node id.
- public static NodeId ConstructIdForInternalNode(QualifiedName browseName, ushort namespaceIndex)
- {
- ParsedNodeId parsedNodeId = new ParsedNodeId();
-
- parsedNodeId.RootId = browseName.Name;
- parsedNodeId.NamespaceIndex = namespaceIndex;
- parsedNodeId.RootType = InternalNode;
-
- return parsedNodeId.Construct();
- }
-
- ///
- /// Constructs the id for an area.
- ///
- /// The area id.
- /// Index of the namespace.
- ///
- public static NodeId ConstructIdForArea(string areaId, ushort namespaceIndex)
- {
- ParsedNodeId parsedNodeId = new ParsedNodeId();
-
- parsedNodeId.RootId = areaId;
- parsedNodeId.NamespaceIndex = namespaceIndex;
- parsedNodeId.RootType = AeArea;
-
- return parsedNodeId.Construct();
- }
-
- ///
- /// Constructs the id for a source.
- ///
- /// The area id.
- /// Name of the source.
- /// Index of the namespace.
- ///
- public static NodeId ConstructIdForSource(string areaId, string sourceName, ushort namespaceIndex)
- {
- ParsedNodeId parsedNodeId = new ParsedNodeId();
-
- parsedNodeId.RootType = AeSource;
- parsedNodeId.RootId = areaId;
- parsedNodeId.NamespaceIndex = namespaceIndex;
- parsedNodeId.ComponentPath = sourceName;
-
- return parsedNodeId.Construct();
- }
- }
-}
diff --git a/ComIOP/Common/Client/Ae/AeParseNodeId.cs b/ComIOP/Common/Client/Ae/AeParseNodeId.cs
deleted file mode 100644
index 415039bb3..000000000
--- a/ComIOP/Common/Client/Ae/AeParseNodeId.cs
+++ /dev/null
@@ -1,377 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Text;
-using System.Collections.Generic;
-using System.Reflection;
-using Opc.Ua;
-using Opc.Ua.Server;
-
-namespace Opc.Ua.Com.Client
-{
- #region AeParsedNodeId Class
- ///
- /// Stores the elements of a NodeId after it is parsed.
- ///
- ///
- /// The NodeIds used by the samples are strings with an optional path appended.
- /// The RootType identifies the type of Root Node. The RootId is the unique identifier
- /// for the Root Node. The ComponentPath is constructed from the SymbolicNames
- /// of one or more children of the Root Node.
- ///
- public class AeParsedNodeId : ParsedNodeId
- {
- #region Public Interface
- ///
- /// Gets or sets the category id.
- ///
- /// The category id.
- public int CategoryId
- {
- get { return m_categoryId; }
- set { m_categoryId = value; }
- }
-
- ///
- /// Gets or sets the source for a condition.
- ///
- /// The source id of the condition.
- public string SourceId
- {
- get { return m_sourceId; }
- set { m_sourceId = value; }
- }
-
- ///
- /// Gets or sets the name of the condition.
- ///
- /// The name of the condition.
- public string ConditionName
- {
- get { return m_conditionName; }
- set { m_conditionName = value; }
- }
-
- ///
- /// Gets or sets the attribute id.
- ///
- /// The attribute id.
- public string AttributeName
- {
- get { return m_attributeName; }
- set { m_attributeName = value; }
- }
-
- ///
- /// Parses the specified node identifier.
- ///
- /// The node identifier.
- /// The parsed node identifier. Null if the identifier cannot be parsed.
- public static new AeParsedNodeId Parse(NodeId nodeId)
- {
- // can only parse non-null string node identifiers.
- if (NodeId.IsNull(nodeId))
- {
- return null;
- }
-
- string identifier = nodeId.Identifier as string;
-
- if (String.IsNullOrEmpty(identifier))
- {
- return null;
- }
-
- AeParsedNodeId parsedNodeId = new AeParsedNodeId();
- parsedNodeId.NamespaceIndex = nodeId.NamespaceIndex;
-
- int start = 0;
-
- // extract the type of identifier.
- parsedNodeId.RootType = (int)ExtractNumber(identifier, ref start);
-
- if (start >= identifier.Length || identifier[start] != ':')
- {
- return null;
- }
-
- // extract any component path.
- StringBuilder buffer = new StringBuilder();
-
- int index = start+1;
-
- parsedNodeId.RootId = ExtractAndUnescapeString(identifier, ref index, '&', '?');
-
- // extract any component.
- int end = index+1;
- parsedNodeId.ComponentPath = null;
-
- // extract the component path.
- if (end < identifier.Length)
- {
- parsedNodeId.ComponentPath = identifier.Substring(end);
- }
-
- // extract the category and condition name.
- start = 0;
- identifier = parsedNodeId.RootId;
-
- switch (parsedNodeId.RootType)
- {
- case AeModelUtils.AeEventTypeMapping:
- {
- EventTypeMapping mapping = (EventTypeMapping)(int)ExtractNumber(identifier, ref start);
-
- if (start < identifier.Length)
- {
- return null;
- }
-
- parsedNodeId.CategoryId = (int)mapping;
- break;
- }
-
- case AeModelUtils.AeSimpleEventType:
- case AeModelUtils.AeTrackingEventType:
- {
- parsedNodeId.CategoryId = Utils.ToInt32(ExtractNumber(identifier, ref start));
-
- if (start < identifier.Length)
- {
- return null;
- }
-
- break;
- }
-
- case AeModelUtils.AeConditionEventType:
- {
- parsedNodeId.CategoryId = Utils.ToInt32(ExtractNumber(identifier, ref start));
-
- if (start < identifier.Length)
- {
- if (identifier[start] != ':')
- {
- return null;
- }
-
- parsedNodeId.ConditionName = identifier.Substring(start+1);
- }
-
- break;
- }
-
- case AeModelUtils.AeCondition:
- {
- parsedNodeId.SourceId = ExtractAndUnescapeString(identifier, ref start, '0', ':');
-
- if (start < identifier.Length && identifier[start] != ':')
- {
- return null;
- }
-
- start++;
-
- parsedNodeId.CategoryId = Utils.ToInt32(ExtractNumber(identifier, ref start));
-
- if (start < identifier.Length)
- {
- if (identifier[start] != ':')
- {
- return null;
- }
-
- parsedNodeId.ConditionName = identifier.Substring(start+1);
- }
-
- break;
- }
- }
-
- // extract the attribute id.
- if (!String.IsNullOrEmpty(parsedNodeId.ComponentPath))
- {
- start = 0;
- identifier = parsedNodeId.ComponentPath;
-
- switch (parsedNodeId.RootType)
- {
- case AeModelUtils.AeSimpleEventType:
- case AeModelUtils.AeTrackingEventType:
- case AeModelUtils.AeConditionEventType:
- {
- parsedNodeId.AttributeName = identifier.Substring(start+1);
- break;
- }
- }
- }
-
- return parsedNodeId;
- }
-
- ///
- /// Constructs a node identifier.
- ///
- /// The node identifier.
- public new NodeId Construct()
- {
- return Construct(this.RootType, this.RootId, this.ComponentPath, this.NamespaceIndex);
- }
-
- ///
- /// Constructs the NodeId for the specified event type mapping node.
- ///
- internal static NodeId Construct(EventTypeMapping mapping, ushort namespaceIndex)
- {
- return Construct(AeModelUtils.AeEventTypeMapping, ((int)mapping).ToString(), null, namespaceIndex);
- }
-
- ///
- /// Constructs the NodeId for the specified event type node.
- ///
- internal static NodeId Construct(EventType eventType, string componentPath, ushort namespaceIndex)
- {
- StringBuilder buffer = new StringBuilder();
-
- buffer.Append(Utils.ToUInt32(eventType.CategoryId));
-
- if (!String.IsNullOrEmpty(eventType.ConditionName))
- {
- buffer.Append(':');
- buffer.Append(eventType.ConditionName);
- }
-
- return Construct(eventType.EventTypeId, buffer.ToString(), componentPath, namespaceIndex);
- }
-
- ///
- /// Constructs the NodeId for the specified event type.
- ///
- /// Type of the event.
- /// The category id.
- /// Name of the condition.
- /// Index of the namespace.
- /// The NodeId
- public static NodeId Construct(int eventType, int categoryId, string conditionName, ushort namespaceIndex)
- {
- StringBuilder buffer = new StringBuilder();
-
- buffer.Append(Utils.ToUInt32(categoryId));
-
- if (!String.IsNullOrEmpty(conditionName))
- {
- buffer.Append(':');
- buffer.Append(conditionName);
- }
-
- return Construct(eventType, buffer.ToString(), null, namespaceIndex);
- }
-
- ///
- /// Constructs the NodeId for the attribute of the specified event type.
- ///
- /// Type of the event.
- /// The category id.
- /// The attribute id.
- /// Index of the namespace.
- /// The NodeId
- public static NodeId Construct(int eventType, int categoryId, int attributeId, ushort namespaceIndex)
- {
- return Construct(eventType, categoryId.ToString(), attributeId.ToString(), namespaceIndex);
- }
-
- ///
- /// Constructs the NodeId for the attribute of the specified event type.
- ///
- /// Type of the event.
- /// Index of the namespace.
- /// The NodeId
- public static NodeId Construct(int eventType, ushort namespaceIndex)
- {
- return Construct(eventType, String.Empty, null, namespaceIndex);
- }
-
- ///
- /// Constructs the id for condition.
- ///
- /// The source id.
- /// The category id.
- /// Name of the condition.
- /// Index of the namespace.
- ///
- public static NodeId ConstructIdForCondition(string sourceId, int categoryId, string conditionName, ushort namespaceIndex)
- {
- StringBuilder buffer = new StringBuilder();
-
- EscapeAndAppendString(buffer, sourceId, '0', ':');
- buffer.Append(':');
- buffer.Append(Utils.ToUInt32(categoryId));
- buffer.Append(':');
- buffer.Append(conditionName);
-
- return Construct(AeModelUtils.AeCondition, buffer.ToString(), null, namespaceIndex);
- }
-
- ///
- /// Constructs a node identifier.
- ///
- /// The node identifier.
- public static NodeId Construct(int rootType, string rootId, string componentPath, ushort namespaceIndex)
- {
- StringBuilder buffer = new StringBuilder();
-
- // add the root type.
- buffer.Append(rootType);
- buffer.Append(':');
-
- // add the root identifier.
- EscapeAndAppendString(buffer, rootId, '&', '?');
-
- // add the component path.
- if (!String.IsNullOrEmpty(componentPath))
- {
- buffer.Append('?');
- buffer.Append(componentPath);
- }
-
- // construct the node id with the namespace index provided.
- return new NodeId(buffer.ToString(), namespaceIndex);
- }
- #endregion
-
- #region Private Fields
- private string m_sourceId;
- private int m_categoryId;
- private string m_conditionName;
- private string m_attributeName;
- #endregion
- }
- #endregion
-}
diff --git a/ComIOP/Common/Client/Ae/AeSourceState.cs b/ComIOP/Common/Client/Ae/AeSourceState.cs
deleted file mode 100644
index 5dea0e704..000000000
--- a/ComIOP/Common/Client/Ae/AeSourceState.cs
+++ /dev/null
@@ -1,96 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using System.Xml;
-using System.IO;
-using System.Reflection;
-using System.Threading;
-using Opc.Ua;
-using Opc.Ua.Server;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// A object which maps a segment to a UA object.
- ///
- public partial class AeSourceState : BaseObjectState
- {
- #region Constructors
- ///
- /// Initializes a new instance of the class.
- ///
- /// The context.
- /// The area id.
- /// The qualified name for the source.
- /// The name of the source.
- /// Index of the namespace.
- public AeSourceState(
- ISystemContext context,
- string areaId,
- string qualifiedName,
- string name,
- ushort namespaceIndex)
- :
- base(null)
- {
- m_areaId = areaId;
- m_qualifiedName = qualifiedName;
-
- this.TypeDefinitionId = Opc.Ua.ObjectTypeIds.BaseObjectType;
- this.NodeId = AeModelUtils.ConstructIdForSource(m_areaId, name, namespaceIndex);
- this.BrowseName = new QualifiedName(name, namespaceIndex);
- this.DisplayName = this.BrowseName.Name;
- this.Description = null;
- this.WriteMask = 0;
- this.UserWriteMask = 0;
- this.EventNotifier = EventNotifiers.None;
-
- this.AddReference(ReferenceTypeIds.HasNotifier, true, AeModelUtils.ConstructIdForArea(m_areaId, namespaceIndex));
- }
- #endregion
-
- #region Public Properties
- ///
- /// Gets the qualified name for the source.
- ///
- /// The qualified name for the source.
- public string QualifiedName
- {
- get { return m_qualifiedName; }
- }
- #endregion
-
- #region Private Fields
- private string m_areaId;
- private string m_qualifiedName;
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/Ae/AeTypeCache.cs b/ComIOP/Common/Client/Ae/AeTypeCache.cs
deleted file mode 100644
index 4a49523e1..000000000
--- a/ComIOP/Common/Client/Ae/AeTypeCache.cs
+++ /dev/null
@@ -1,581 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using Opc.Ua;
-using Opc.Ua.Server;
-using OpcRcw.Ae;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// Stores the type information provided by the AE server.
- ///
- internal class AeTypeCache
- {
- ///
- /// A table of event types returned from the server.
- ///
- public List EventTypes { get; set; }
-
- ///
- /// A table of attributes for each event category supported by the server,
- ///
- public Dictionary Attributes { get; set; }
-
- ///
- /// A table of node reprenting the AE event catgories and condtions.
- ///
- public NodeIdDictionary EventTypeNodes { get; set; }
-
- ///
- /// Returns the node for the event type mapping identified by the node id.
- ///
- public AeEventTypeMappingState GetMappingNode(ServerSystemContext context, NodeId nodeId)
- {
- BaseObjectTypeState objectType = null;
-
- if (!EventTypeNodes.TryGetValue(nodeId, out objectType))
- {
- return null;
- }
-
- AeEventTypeMappingState mappingNode = objectType as AeEventTypeMappingState;
-
- if (mappingNode == null)
- {
- return null;
- }
-
- if (context.TypeTable.FindSubTypes(mappingNode.NodeId).Count == 0)
- {
- return null;
- }
-
- return mappingNode;
- }
-
- ///
- /// Returns the type identified by the category id and condition name.
- ///
- public AeEventTypeState FindType(ServerSystemContext context, NodeId nodeId)
- {
- if (NodeId.IsNull(nodeId))
- {
- return null;
- }
-
- BaseObjectTypeState eventType = null;
-
- if (!EventTypeNodes.TryGetValue(nodeId, out eventType))
- {
- return null;
- }
-
- return eventType as AeEventTypeState;
- }
-
- ///
- /// Creates an instance of an event.
- ///
- public BaseEventState CreateInstance(ServerSystemContext context, AeEventTypeState eventType)
- {
- BaseEventState instance = null;
-
- switch (eventType.EventType.EventTypeMapping)
- {
- case EventTypeMapping.AlarmConditionType: { instance = new AlarmConditionState(null); break; }
- case EventTypeMapping.AuditEventType: { instance = new AuditEventState(null); break; }
- case EventTypeMapping.BaseEventType: { instance = new BaseEventState(null); break; }
- case EventTypeMapping.DeviceFailureEventType: { instance = new DeviceFailureEventState(null); break; }
- case EventTypeMapping.DiscreteAlarmType: { instance = new DiscreteAlarmState(null); break; }
- case EventTypeMapping.NonExclusiveDeviationAlarmType: { instance = new NonExclusiveDeviationAlarmState(null); break; }
- case EventTypeMapping.ExclusiveLevelAlarmType: { instance = new ExclusiveLevelAlarmState(null); break; }
- case EventTypeMapping.LimitAlarmType: { instance = new LimitAlarmState(null); break; }
- case EventTypeMapping.NonExclusiveLevelAlarmType: { instance = new NonExclusiveLevelAlarmState(null); break; }
- case EventTypeMapping.OffNormalAlarmType: { instance = new OffNormalAlarmState(null); break; }
- case EventTypeMapping.SystemEventType: { instance = new SystemEventState(null); break; }
- case EventTypeMapping.TripAlarmType: { instance = new TripAlarmState(null); break; }
- }
-
- return instance;
- }
-
- ///
- /// Updates the event types in cache with the most recent info fetched from the AE server.
- ///
- public void UpdateCache(ServerSystemContext context, ushort namespaceIndex)
- {
- // clear the existing nodes.
- EventTypeNodes = new NodeIdDictionary();
- Attributes = new Dictionary();
- TypeTable typeTable = context.TypeTable as TypeTable;
-
- // rebuild from the recently fetched list.
- for (int ii = 0; ii < EventTypes.Count; ii++)
- {
- // save the attributes for use when creating filters.
- if (EventTypes[ii].EventTypeMapping != EventTypeMapping.ConditionClassType && !Attributes.ContainsKey(EventTypes[ii].CategoryId))
- {
- EventType eventType = EventTypes[ii];
-
- int[] attributeIds = new int[eventType.Attributes.Count];
-
- for (int jj = 0; jj < attributeIds.Length; jj++)
- {
- attributeIds[jj] = eventType.Attributes[jj].Id;
- }
-
- Attributes.Add(EventTypes[ii].CategoryId, attributeIds);
- }
-
- AeEventTypeState node = new AeEventTypeState(EventTypes[ii], namespaceIndex);
-
- BaseObjectTypeState mappingNode = null;
-
- if (!EventTypeNodes.TryGetValue(node.SuperTypeId, out mappingNode))
- {
- mappingNode = new AeEventTypeMappingState(node.EventType.EventTypeMapping, namespaceIndex);
- EventTypeNodes.Add(mappingNode.NodeId, mappingNode);
-
- // ensure the mapping node is in the type table.
- if (typeTable != null)
- {
- if (!typeTable.IsKnown(mappingNode.NodeId))
- {
- typeTable.AddSubtype(mappingNode.NodeId, mappingNode.SuperTypeId);
- }
- }
- }
-
- EventTypeNodes.Add(node.NodeId, node);
-
- // ensure the type node is in the type table.
- if (typeTable != null)
- {
- if (!typeTable.IsKnown(node.NodeId))
- {
- typeTable.AddSubtype(node.NodeId, mappingNode.NodeId);
- }
- }
- }
- }
-
- ///
- /// Fetches the event type information from the AE server.
- ///
- public void LoadEventTypes(ComAeClient client)
- {
- EventTypes = new List();
- LoadEventType(client, OpcRcw.Ae.Constants.SIMPLE_EVENT);
- LoadEventType(client, OpcRcw.Ae.Constants.TRACKING_EVENT);
- LoadEventType(client, OpcRcw.Ae.Constants.CONDITION_EVENT);
- }
-
- ///
- /// Fetches the event categories for the specified event type.
- ///
- public void LoadEventType(ComAeClient client, int eventTypeId)
- {
- int[] ids = null;
- string[] descriptions = null;
-
- try
- {
- client.GetEventCategories(eventTypeId, out ids, out descriptions);
- }
- catch (Exception e)
- {
- Utils.Trace(e, "Unexpected error fetching event categories.");
- }
-
- if (ids != null)
- {
- for (int ii = 0; ii < ids.Length; ii++)
- {
- List attributes = LoadEventAttributes(client, eventTypeId, ids[ii]);
-
- if (eventTypeId == OpcRcw.Ae.Constants.CONDITION_EVENT)
- {
- LoadConditionEvent(client, eventTypeId, ids[ii], descriptions[ii], attributes);
- continue;
- }
-
- EventType eventType = new EventType();
- eventType.EventTypeId = eventTypeId;
- eventType.CategoryId = ids[ii];
- eventType.Description = descriptions[ii];
- eventType.ConditionName = null;
- eventType.SubConditionNames = null;
- eventType.Attributes = attributes;
- DetermineMapping(eventType);
- EventTypes.Add(eventType);
- }
- }
- }
-
- ///
- /// Uses the recommended names in the AE specification to map to predefined UA event types.
- ///
- private void DetermineMapping(EventType eventType)
- {
- for (int ii = 0; ii < eventType.Attributes.Count; ii++)
- {
- if (AeTypeCache.IsKnownName(eventType.Attributes[ii].Description, "ACK COMMENT"))
- {
- eventType.AckComment = eventType.Attributes[ii];
- break;
- }
- }
-
- eventType.EventTypeMapping = EventTypeMapping.BaseEventType;
-
- if (eventType.EventTypeId == OpcRcw.Ae.Constants.SIMPLE_EVENT)
- {
- if (AeTypeCache.IsKnownName(eventType.Description, "Device Failure"))
- {
- eventType.EventTypeMapping = EventTypeMapping.DeviceFailureEventType;
- return;
- }
-
- if (AeTypeCache.IsKnownName(eventType.Description, "System Message"))
- {
- eventType.EventTypeMapping = EventTypeMapping.SystemEventType;
- return;
- }
-
- eventType.EventTypeMapping = EventTypeMapping.BaseEventType;
- return;
- }
-
- if (eventType.EventTypeId == OpcRcw.Ae.Constants.TRACKING_EVENT)
- {
- eventType.EventTypeMapping = EventTypeMapping.AuditEventType;
- return;
- }
-
- if (eventType.EventTypeId == OpcRcw.Ae.Constants.CONDITION_EVENT)
- {
- if (eventType.ConditionName == null)
- {
- eventType.EventTypeMapping = EventTypeMapping.ConditionClassType;
- return;
- }
-
- eventType.EventTypeMapping = EventTypeMapping.AlarmConditionType;
-
- if (AeTypeCache.IsKnownName(eventType.Description, "Level"))
- {
- if (AeTypeCache.IsKnownName(eventType.ConditionName, "PVLEVEL"))
- {
- eventType.EventTypeMapping = EventTypeMapping.ExclusiveLevelAlarmType;
- return;
- }
-
- if (AeTypeCache.IsKnownName(eventType.ConditionName, "SPLEVEL"))
- {
- eventType.EventTypeMapping = EventTypeMapping.ExclusiveLevelAlarmType;
- return;
- }
-
- if (AeTypeCache.IsKnownName(eventType.ConditionName, "HI HI"))
- {
- eventType.EventTypeMapping = EventTypeMapping.NonExclusiveLevelAlarmType;
- return;
- }
-
- if (AeTypeCache.IsKnownName(eventType.ConditionName, "HI"))
- {
- eventType.EventTypeMapping = EventTypeMapping.NonExclusiveLevelAlarmType;
- return;
- }
-
- if (AeTypeCache.IsKnownName(eventType.ConditionName, "LO"))
- {
- eventType.EventTypeMapping = EventTypeMapping.NonExclusiveLevelAlarmType;
- return;
- }
-
- if (AeTypeCache.IsKnownName(eventType.ConditionName, "LO LO"))
- {
- eventType.EventTypeMapping = EventTypeMapping.NonExclusiveLevelAlarmType;
- return;
- }
-
- eventType.EventTypeMapping = EventTypeMapping.LimitAlarmType;
- return;
- }
-
- if (AeTypeCache.IsKnownName(eventType.Description, "Deviation"))
- {
- eventType.EventTypeMapping = EventTypeMapping.NonExclusiveDeviationAlarmType;
- return;
- }
-
- if (AeTypeCache.IsKnownName(eventType.Description, "Discrete"))
- {
- if (AeTypeCache.IsKnownName(eventType.ConditionName, "CFN"))
- {
- eventType.EventTypeMapping = EventTypeMapping.OffNormalAlarmType;
- return;
- }
-
- if (AeTypeCache.IsKnownName(eventType.ConditionName, "TRIP"))
- {
- eventType.EventTypeMapping = EventTypeMapping.TripAlarmType;
- return;
- }
-
- eventType.EventTypeMapping = EventTypeMapping.DiscreteAlarmType;
- return;
- }
- }
- }
-
- private void LoadConditionEvent(ComAeClient client, int eventTypeId, int categoryId, string description, List attributes)
- {
- string[] conditionNames = null;
-
- try
- {
- client.GetConditionNames(categoryId, out conditionNames);
- }
- catch (Exception e)
- {
- Utils.Trace(e, "Unexpected error fetching condition names.");
- conditionNames = null;
- }
-
- if (conditionNames != null)
- {
- // create a condition class for the category.
- EventType eventType = new EventType();
- eventType.EventTypeId = eventTypeId;
- eventType.CategoryId = categoryId;
- eventType.Description = description;
- eventType.ConditionName = null;
- eventType.SubConditionNames = null;
- eventType.Attributes = new List();
- DetermineMapping(eventType);
- EventTypes.Add(eventType);
-
- // create event types for each condition name.
- for (int ii = 0; ii < conditionNames.Length; ii++)
- {
- eventType = new EventType();
- eventType.EventTypeId = eventTypeId;
- eventType.CategoryId = categoryId;
- eventType.Description = description;
- eventType.ConditionName = conditionNames[ii];
- eventType.SubConditionNames = null;
- eventType.Attributes = attributes;
- DetermineMapping(eventType);
-
- string[] subConditionNames = null;
-
- try
- {
- client.GetSubConditionNames(eventType.ConditionName, out subConditionNames);
- }
- catch (Exception e)
- {
- Utils.Trace(e, "Unexpected error fetching sub-condition names.");
- subConditionNames = null;
- }
-
- if (subConditionNames != null)
- {
- eventType.SubConditionNames = new List(subConditionNames);
- }
-
- EventTypes.Add(eventType);
- }
- }
- }
-
- ///
- /// Fetches the attributes for the category from the AE server.
- ///
- private List LoadEventAttributes(ComAeClient client, int eventTypeId, int categoryId)
- {
- List attributes = new List();
-
- int[] ids = null;
- string[] descriptions = null;
- short[] dataTypes = null;
-
- try
- {
- client.GetEventAttributes(categoryId, out ids, out descriptions, out dataTypes);
- }
- catch (Exception e)
- {
- Utils.Trace(e, "Unexpected error fetching event attributes.");
- ids = null;
- }
-
- if (ids != null)
- {
- for (int ii = 0; ii < ids.Length; ii++)
- {
- EventAttribute attribute = new EventAttribute();
- attribute.Id = ids[ii];
- attribute.Description = descriptions[ii];
- attribute.VarType = dataTypes[ii];
- attributes.Add(attribute);
- }
- }
-
- return attributes;
- }
-
- ///
- /// Checks for alternate spellings of a well known name defined by the AE specification.
- ///
- public static bool IsKnownName(string description, params string[] names)
- {
- if (names != null)
- {
- for (int ii = 0; ii < names.Length; ii++)
- {
- string name = names[ii];
-
- if (String.Compare(name, description, StringComparison.OrdinalIgnoreCase) == 0)
- {
- return true;
- }
-
- name = names[ii].Replace(' ', '_');
-
- if (String.Compare(name, description, StringComparison.OrdinalIgnoreCase) == 0)
- {
- return true;
- }
-
- name = names[ii].Replace(" ", "");
-
- if (String.Compare(name, description, StringComparison.OrdinalIgnoreCase) == 0)
- {
- return true;
- }
- }
- }
-
- return false;
- }
- }
-
- ///
- /// Stores the metadata about an event type defined by the AE server.
- ///
- internal class EventType
- {
- ///
- /// The AE event type.
- ///
- public int EventTypeId { get; set; }
-
- ///
- /// The AE event category.
- ///
- public int CategoryId { get; set; }
-
- ///
- /// The AE event category description.
- ///
- public string Description { get; set; }
-
- ///
- /// The AE condition name.
- ///
- public string ConditionName { get; set; }
-
- ///
- /// The AE sub-condition names.
- ///
- public List SubConditionNames { get; set; }
-
- ///
- /// The list of AE attrivutes for the category.
- ///
- public List Attributes { get; set; }
-
- ///
- /// The AE attribute for the ACK COMMENT `
- ///
- public EventAttribute AckComment { get; set; }
-
- ///
- /// The mapping to a UA event type.
- ///
- public EventTypeMapping EventTypeMapping { get; set; }
- }
-
- ///
- /// The set of possible UA event/condition class mappings.
- ///
- internal enum EventTypeMapping
- {
- BaseEventType,
- DeviceFailureEventType,
- SystemEventType,
- AuditEventType,
- AlarmConditionType,
- LimitAlarmType,
- ExclusiveLevelAlarmType,
- NonExclusiveLevelAlarmType,
- NonExclusiveDeviationAlarmType,
- DiscreteAlarmType,
- OffNormalAlarmType,
- TripAlarmType,
- ConditionClassType
- }
-
- ///
- /// Stores the metadata for an AE event attribute.
- ///
- internal class EventAttribute
- {
- ///
- /// The attribute id.
- ///
- public int Id { get; set; }
-
- ///
- /// The attribute description.
- ///
- public string Description { get; set; }
-
- ///
- /// The attribute COM data type.
- ///
- public short VarType { get; set; }
- }
-}
diff --git a/ComIOP/Common/Client/Ae/ComAeBrowserClient.cs b/ComIOP/Common/Client/Ae/ComAeBrowserClient.cs
deleted file mode 100644
index be93a57b5..000000000
--- a/ComIOP/Common/Client/Ae/ComAeBrowserClient.cs
+++ /dev/null
@@ -1,440 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using System.Xml;
-using System.IO;
-using System.Reflection;
-using System.Threading;
-using Opc.Ua;
-using Opc.Ua.Server;
-using Opc.Ua.Com;
-using OpcRcw.Ae;
-using OpcRcw.Comn;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// Browses areas and sources in the AE server.
- ///
- public class ComAeBrowserClient : ComObject
- {
- #region Constructors
- ///
- /// Initializes a new instance of the class.
- ///
- /// The client.
- /// The qualified area name.
- public ComAeBrowserClient(
- ComAeClient client,
- string qualifiedName)
- {
- m_client = client;
- m_qualifiedName = qualifiedName;
- }
- #endregion
-
- #region IDisposable Members
- ///
- /// An overrideable version of the Dispose.
- ///
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- Utils.SilentDispose(m_enumerator);
- m_enumerator = null;
- }
-
- base.Dispose(disposing);
- }
- #endregion
-
- #region Public Methods
- ///
- /// Returns the next AE area or source.
- ///
- /// A DA element. Null if nothing left to browse.
- public BaseObjectState Next(ISystemContext context, ushort namespaceIndex)
- {
- // check if already completed.
- if (m_completed)
- {
- return null;
- }
-
- // create the browser.
- if (base.Unknown == null)
- {
- base.Unknown = m_client.CreateAreaBrowser();
-
- if (base.Unknown == null)
- {
- return null;
- }
-
- if (!ChangeBrowsePosition(OPCAEBROWSEDIRECTION.OPCAE_BROWSE_TO, m_qualifiedName))
- {
- return null;
- }
- }
-
- // create the enumerator if not already created.
- if (m_enumerator == null)
- {
- m_enumerator = CreateEnumerator(false);
- m_sources = false;
-
- // a null indicates an error.
- if (m_enumerator == null)
- {
- m_completed = true;
- return null;
- }
- }
-
- // need a loop in case errors occur fetching element metadata.
- BaseObjectState node = null;
-
- do
- {
- // fetch the next name.
- string name = m_enumerator.Next();
-
- // a null indicates the end of list.
- if (name == null)
- {
- if (!m_sources)
- {
- m_enumerator.Dispose();
- m_enumerator = CreateEnumerator(true);
- m_sources = true;
- continue;
- }
-
- m_completed = true;
- return null;
- }
-
- // create the node.
- if (m_sources)
- {
- string qualifiedName = GetQualifiedSourceName(name);
-
- if (String.IsNullOrEmpty(qualifiedName))
- {
- continue;
- }
-
- node = new AeSourceState(context, m_qualifiedName, qualifiedName, name, namespaceIndex);
- }
- else
- {
- string qualifiedName = GetQualifiedAreaName(name);
-
- if (String.IsNullOrEmpty(qualifiedName))
- {
- continue;
- }
-
- node = new AeAreaState(context, qualifiedName, name, namespaceIndex);
- }
-
- break;
- }
- while (node == null);
-
- // return node.
- return node;
- }
-
- ///
- /// Finds the area.
- ///
- /// The context.
- /// Name of the qualified.
- /// Index of the namespace.
- ///
- public BaseObjectState FindArea(ISystemContext context, string qualifiedName, ushort namespaceIndex)
- {
- // create the browser.
- if (base.Unknown == null)
- {
- base.Unknown = m_client.CreateAreaBrowser();
-
- if (base.Unknown == null)
- {
- return null;
- }
- }
-
- // goto area.
- if (!ChangeBrowsePosition(OPCAEBROWSEDIRECTION.OPCAE_BROWSE_TO, qualifiedName))
- {
- return null;
- }
-
- // find browse name via parent.
- if (!ChangeBrowsePosition(OPCAEBROWSEDIRECTION.OPCAE_BROWSE_UP, String.Empty))
- {
- return null;
- }
-
- // remove the enumerator.
- if (m_enumerator != null)
- {
- m_enumerator.Dispose();
- m_enumerator = null;
- }
-
- m_enumerator = CreateEnumerator(false);
-
- do
- {
- // fetch the next name.
- string name = m_enumerator.Next();
-
- // a null indicates the end of list.
- if (name == null)
- {
- m_completed = true;
- return null;
- }
-
- // create the node.
- if (qualifiedName == GetQualifiedAreaName(name))
- {
- return new AeAreaState(context, qualifiedName, name, namespaceIndex);
- }
- }
- while (!m_completed);
-
- // return node.
- return null;
- }
-
- ///
- /// Finds the source.
- ///
- /// The context.
- /// Name of the area.
- /// Name of the source.
- /// Index of the namespace.
- /// The source.
- public BaseObjectState FindSource(ISystemContext context, string areaName, string sourceName, ushort namespaceIndex)
- {
- // create the browser.
- if (base.Unknown == null)
- {
- base.Unknown = m_client.CreateAreaBrowser();
-
- if (base.Unknown == null)
- {
- return null;
- }
- }
-
- if (!ChangeBrowsePosition(OPCAEBROWSEDIRECTION.OPCAE_BROWSE_TO, areaName))
- {
- return null;
- }
-
- // remove the enumerator.
- if (m_enumerator != null)
- {
- m_enumerator.Dispose();
- m_enumerator = null;
- }
-
- m_enumerator = CreateEnumerator(true);
-
- do
- {
- // fetch the next name.
- string name = m_enumerator.Next();
-
- // a null indicates the end of list.
- if (name == null)
- {
- m_completed = true;
- return null;
- }
-
- // create the node.
- if (sourceName == name)
- {
- string qualifiedName = GetQualifiedSourceName(name);
- return new AeSourceState(context, m_qualifiedName, qualifiedName, name, namespaceIndex);
- }
- }
- while (!m_completed);
-
- // return node.
- return null;
- }
- #endregion
-
- #region Private Methods
- ///
- /// Changes the browse position.
- ///
- /// The direction.
- /// The qualified area name.
- private bool ChangeBrowsePosition(OPCAEBROWSEDIRECTION direction, string qualifiedName)
- {
- string methodName = "IOPCEventAreaBrowser.CreateAreaBrowser";
-
- try
- {
- IOPCEventAreaBrowser server = BeginComCall(methodName, true);
- server.ChangeBrowsePosition(direction, qualifiedName);
- return true;
- }
- catch (Exception e)
- {
- if (ComUtils.IsUnknownError(e, ResultIds.E_FAIL))
- {
- ComCallError(methodName, e);
- }
-
- return false;
- }
- finally
- {
- EndComCall(methodName);
- }
- }
-
- ///
- /// Gets the qualified name for the area.
- ///
- /// The name.
- /// The qualified name for the area.
- private string GetQualifiedAreaName(string name)
- {
- string methodName = "IOPCEventAreaBrowser.GetQualifiedAreaName";
-
- string qualifiedName = null;
-
- try
- {
- IOPCEventAreaBrowser server = BeginComCall(methodName, true);
- server.GetQualifiedAreaName(name, out qualifiedName);
- }
- catch (Exception e)
- {
- ComCallError(methodName, e);
- return null;
- }
- finally
- {
- EndComCall(methodName);
- }
-
- return qualifiedName;
- }
-
- ///
- /// Gets the qualified name for the source.
- ///
- /// The name.
- /// The qualified name for the area.
- private string GetQualifiedSourceName(string name)
- {
- string methodName = "IOPCEventAreaBrowser.GetQualifiedSourceName";
-
- string qualifiedName = null;
-
- try
- {
- IOPCEventAreaBrowser server = BeginComCall(methodName, true);
- server.GetQualifiedSourceName(name, out qualifiedName);
- }
- catch (Exception e)
- {
- ComCallError(methodName, e);
- return null;
- }
- finally
- {
- EndComCall(methodName);
- }
-
- return qualifiedName;
- }
-
- ///
- /// Creates an enumerator for the current browse position.
- ///
- /// if set to true then sources are enumerated.
- /// The wrapped enumerator.
- private EnumString CreateEnumerator(bool sources)
- {
- IEnumString unknown = null;
-
- string methodName = "IOPCEventAreaBrowser.BrowseOPCAreas";
-
- try
- {
- IOPCEventAreaBrowser server = BeginComCall(methodName, true);
-
- OPCAEBROWSETYPE browseType = OPCAEBROWSETYPE.OPC_AREA;
-
- if (sources)
- {
- browseType = OPCAEBROWSETYPE.OPC_SOURCE;
- }
-
- server.BrowseOPCAreas(browseType, String.Empty, out unknown);
- }
- catch (Exception e)
- {
- ComCallError(methodName, e);
- return null;
- }
- finally
- {
- EndComCall(methodName);
- }
-
- // wrapper the enumrator. hardcoding a buffer size of 256.
- return new EnumString(unknown, 256);
- }
- #endregion
-
- #region Private Fields
- private ComAeClient m_client;
- private string m_qualifiedName;
- private Opc.Ua.Com.Client.EnumString m_enumerator;
- private bool m_completed;
- private bool m_sources;
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/Ae/ComAeClient.cs b/ComIOP/Common/Client/Ae/ComAeClient.cs
deleted file mode 100644
index 02a0f4c2b..000000000
--- a/ComIOP/Common/Client/Ae/ComAeClient.cs
+++ /dev/null
@@ -1,454 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using System.Text;
-using System.Runtime.InteropServices;
-using OpcRcw.Comn;
-using OpcRcw.Ae;
-using Opc.Ua;
-using Opc.Ua.Server;
-using Opc.Ua.Com;
-using Opc.Ua.Com.Client;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// Provides access to a COM DA server.
- ///
- public class ComAeClient : ComClient
- {
- #region Constructors
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- public ComAeClient(ComAeClientConfiguration configuration) : base(configuration)
- {
- m_configuration = configuration;
- }
- #endregion
-
- #region Public Methods
- ///
- /// Creates a new instance of the client with the same configuration.
- ///
- /// The copy of the client.
- public ComAeClient CloneClient()
- {
- return new ComAeClient(m_configuration);
- }
-
- ///
- /// Reads the status from the server.
- ///
- public OPCEVENTSERVERSTATUS? GetStatus()
- {
- string methodName = "IOPCEventServer.GetStatus";
-
- try
- {
- IOPCEventServer server = BeginComCall(methodName, true);
-
- IntPtr ppServerStatus;
- server.GetStatus(out ppServerStatus);
-
- OPCEVENTSERVERSTATUS pStatus = (OPCEVENTSERVERSTATUS)Marshal.PtrToStructure(ppServerStatus, typeof(OPCEVENTSERVERSTATUS));
-
- Marshal.DestroyStructure(ppServerStatus, typeof(OPCEVENTSERVERSTATUS));
- Marshal.FreeCoTaskMem(ppServerStatus);
-
- return pStatus;
- }
- catch (Exception e)
- {
- ComCallError(methodName, e);
- return null;
- }
- finally
- {
- EndComCall(methodName);
- }
- }
- #endregion
-
- #region Private Methods
- ///
- /// Creates the area browser.
- ///
- /// An object which browses areas and sources.
- public IOPCEventAreaBrowser CreateAreaBrowser()
- {
- object unknown = null;
-
- string methodName = "IOPCEventServer.CreateAreaBrowser";
-
- try
- {
- IOPCEventServer server = BeginComCall(methodName, true);
- Guid riid = typeof(IOPCEventAreaBrowser).GUID;
- server.CreateAreaBrowser(ref riid, out unknown);
- }
- catch (Exception e)
- {
- if (ComUtils.IsUnknownError(e, ResultIds.E_FAIL, ResultIds.E_NOTIMPL))
- {
- ComCallError(methodName, e);
- }
-
- return null;
- }
- finally
- {
- EndComCall(methodName);
- }
-
- return (IOPCEventAreaBrowser)unknown;
- }
-
- ///
- /// Creates an event subscription.
- ///
- /// An object which manages a subscription.
- public IOPCEventSubscriptionMgt CreateEventSubscription()
- {
- object unknown = null;
-
- string methodName = "IOPCEventServer.CreateEventSubscription";
-
- try
- {
- IOPCEventServer server = BeginComCall(methodName, true);
- Guid riid = typeof(IOPCEventSubscriptionMgt).GUID;
-
- int revisedBufferTime = 0;
- int revisedMaxSize = 0;
-
- server.CreateEventSubscription(
- 1,
- 0,
- 0,
- 0,
- ref riid,
- out unknown,
- out revisedBufferTime,
- out revisedMaxSize);
- }
- catch (Exception e)
- {
- ComCallError(methodName, e);
- return null;
- }
- finally
- {
- EndComCall(methodName);
- }
-
- return (IOPCEventSubscriptionMgt)unknown;
- }
-
- ///
- /// Acknowledges the specified context.
- ///
- /// The context.
- /// The event id.
- /// The comment.
- ///
- public uint Acknowledge(
- ServerSystemContext context,
- byte[] eventId,
- LocalizedText comment)
- {
- // get the user name from the context.
- string userName = String.Empty;
-
- if (context.UserIdentity != null)
- {
- userName = context.UserIdentity.DisplayName;
- }
-
- // get the comment.
- string commentText = String.Empty;
-
- if (comment != null)
- {
- commentText = comment.Text;
- }
-
- System.Runtime.InteropServices.ComTypes.FILETIME ftActiveTime;
-
- // unpack the event id.
- ServiceMessageContext messageContext = new ServiceMessageContext();
-
- messageContext.NamespaceUris = context.NamespaceUris;
- messageContext.ServerUris = context.ServerUris;
- messageContext.Factory = context.EncodeableFactory;
-
- BinaryDecoder decoder = new BinaryDecoder(eventId, messageContext);
-
- string source = decoder.ReadString(null);
- string conditionName = decoder.ReadString(null);
- ftActiveTime.dwHighDateTime = decoder.ReadInt32(null);
- ftActiveTime.dwLowDateTime = decoder.ReadInt32(null);
- int cookie = decoder.ReadInt32(null);
-
- decoder.Close();
-
- string methodName = "IOPCEventServer.AckCondition";
-
- IntPtr pErrors = IntPtr.Zero;
-
- try
- {
- IOPCEventServer server = BeginComCall(methodName, true);
-
- server.AckCondition(
- 1,
- userName,
- commentText,
- new string[] { source },
- new string[] { conditionName },
- new System.Runtime.InteropServices.ComTypes.FILETIME[] { ftActiveTime },
- new int[] { cookie },
- out pErrors);
- }
- catch (Exception e)
- {
- ComCallError(methodName, e);
- return StatusCodes.BadUnexpectedError;
- }
- finally
- {
- EndComCall(methodName);
- }
-
- // unmarshal results.
- int[] errors = ComUtils.GetInt32s(ref pErrors, 1, true);
-
- if (errors[0] == ResultIds.S_ALREADYACKED)
- {
- return StatusCodes.BadConditionBranchAlreadyAcked;
- }
- else if (errors[0] < 0)
- {
- return StatusCodes.BadEventIdUnknown;
- }
-
- return StatusCodes.Good;
- }
-
- ///
- /// Gets the event categories.
- ///
- /// Type of the event.
- /// The categories.
- /// The descriptions.
- public void GetEventCategories(int eventType, out int[] categories, out string[] descriptions)
- {
- string methodName = "IOPCEventServer.QueryEventCategories";
-
- int count = 0;
- IntPtr pCategories = IntPtr.Zero;
- IntPtr pDescriptions = IntPtr.Zero;
-
- try
- {
- IOPCEventServer server = BeginComCall(methodName, true);
-
- server.QueryEventCategories(
- eventType,
- out count,
- out pCategories,
- out pDescriptions);
- }
- catch (Exception e)
- {
- ComCallError(methodName, e);
- }
- finally
- {
- EndComCall(methodName);
- }
-
- // unmarshal results.
- categories = ComUtils.GetInt32s(ref pCategories, count, true);
- descriptions = ComUtils.GetUnicodeStrings(ref pDescriptions, count, true);
- }
-
- ///
- /// Returns the condition names for the event category.
- ///
- public void GetConditionNames(int eventCategory, out string[] conditionNames)
- {
- conditionNames = null;
- string methodName = "IOPCEventServer.QueryConditionNames";
-
- int count = 0;
- IntPtr pConditionNames = IntPtr.Zero;
-
- try
- {
- IOPCEventServer server = BeginComCall(methodName, true);
-
- server.QueryConditionNames(
- eventCategory,
- out count,
- out pConditionNames);
- }
- catch (Exception e)
- {
- ComCallError(methodName, e);
- }
- finally
- {
- EndComCall(methodName);
- }
-
- // unmarshal results.
- conditionNames = ComUtils.GetUnicodeStrings(ref pConditionNames, count, true);
- }
-
- ///
- /// Returns the sub-condition names for the event condition.
- ///
- public void GetSubConditionNames(string conditionName, out string[] subConditionNames)
- {
- subConditionNames = null;
- string methodName = "IOPCEventServer.QuerySubConditionNames";
-
- int count = 0;
- IntPtr pSubConditionNames = IntPtr.Zero;
-
- try
- {
- IOPCEventServer server = BeginComCall(methodName, true);
-
- server.QuerySubConditionNames(
- conditionName,
- out count,
- out pSubConditionNames);
- }
- catch (Exception e)
- {
- ComCallError(methodName, e);
- }
- finally
- {
- EndComCall(methodName);
- }
-
- // unmarshal results.
- subConditionNames = ComUtils.GetUnicodeStrings(ref pSubConditionNames, count, true);
- }
-
- ///
- /// Gets the event attributes.
- ///
- /// The category id.
- /// The attribute ids.
- /// The descriptions.
- /// The datatypes.
- public bool GetEventAttributes(
- int categoryId,
- out int[] attributeIds,
- out string[] descriptions,
- out short[] datatypes)
- {
- string methodName = "IOPCEventServer.QueryEventAttributes";
-
- int count = 0;
- IntPtr pAttributeIds = IntPtr.Zero;
- IntPtr pDescriptions = IntPtr.Zero;
- IntPtr pDataTypes = IntPtr.Zero;
-
- try
- {
- IOPCEventServer server = BeginComCall(methodName, true);
-
- server.QueryEventAttributes(
- categoryId,
- out count,
- out pAttributeIds,
- out pDescriptions,
- out pDataTypes);
- }
- catch (Exception e)
- {
- ComCallError(methodName, e);
- }
- finally
- {
- EndComCall(methodName);
- }
-
- // unmarshal results.
- attributeIds = ComUtils.GetInt32s(ref pAttributeIds, count, true);
- descriptions = ComUtils.GetUnicodeStrings(ref pDescriptions, count, true);
- datatypes = ComUtils.GetInt16s(ref pDataTypes, count, true);
-
- // remove the AREAS attribute which is never exposed.
- for (int ii = 0; ii < count; ii++)
- {
- if (String.Compare(descriptions[ii], "AREAS", StringComparison.OrdinalIgnoreCase) == 0)
- {
- int[] attributeIds2 = new int[count-1];
- string[] descriptions2 = new string[count-1];
- short[] datatypes2 = new short[count-1];
-
- if (ii > 0)
- {
- Array.Copy(attributeIds, attributeIds2, ii);
- Array.Copy(descriptions, descriptions2, ii);
- Array.Copy(datatypes, datatypes2, ii);
- }
-
- if (ii < count-1)
- {
- Array.Copy(attributeIds, ii+1, attributeIds2, ii, count-ii-1);
- Array.Copy(descriptions, ii+1, descriptions2, ii, count-ii-1);
- Array.Copy(datatypes, ii+1, datatypes2, ii, count-ii-1);
- }
-
- attributeIds = attributeIds2;
- descriptions = descriptions2;
- datatypes = datatypes2;
- break;
- }
- }
-
- return count > 0;
- }
- #endregion
-
- #region Private Fields
- private ComAeClientConfiguration m_configuration;
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/Ae/ComAeClientConfiguration.cs b/ComIOP/Common/Client/Ae/ComAeClientConfiguration.cs
deleted file mode 100644
index 9440d7430..000000000
--- a/ComIOP/Common/Client/Ae/ComAeClientConfiguration.cs
+++ /dev/null
@@ -1,76 +0,0 @@
-/* ========================================================================
- * 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;
-using System.ServiceModel;
-using System.Runtime.Serialization;
-using System.Collections.Generic;
-using Opc.Ua.Server;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// Stores the configuration the alarms and events node manager.
- ///
- [DataContract(Namespace = Namespaces.ComInterop)]
- public class ComAeClientConfiguration : ComClientConfiguration
- {
- #region Constructors
- ///
- /// The default constructor.
- ///
- public ComAeClientConfiguration()
- {
- Initialize();
- }
-
- ///
- /// Initializes the object during deserialization.
- ///
- [OnDeserializing()]
- private void Initialize(StreamingContext context)
- {
- Initialize();
- }
-
- ///
- /// Sets private members to default values.
- ///
- private void Initialize()
- {
- }
- #endregion
-
- #region Public Properties
- #endregion
-
- #region Private Members
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/Ae/ComAeClientManager.cs b/ComIOP/Common/Client/Ae/ComAeClientManager.cs
deleted file mode 100644
index 37a7ea692..000000000
--- a/ComIOP/Common/Client/Ae/ComAeClientManager.cs
+++ /dev/null
@@ -1,141 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading;
-using Opc.Ua;
-using Opc.Ua.Server;
-using Opc.Ua.Com;
-using OpcRcw.Ae;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// Manages the AE COM connections used by the UA server.
- ///
- public class ComAeClientManager : ComClientManager
- {
- #region Constructors
- ///
- /// Initializes a new instance of the class.
- ///
- public ComAeClientManager()
- {
- }
- #endregion
-
- #region Public Members
- ///
- /// Selects the AE COM client to use for the current context.
- ///
- /// The context.
- /// If true the default instance is used.
- /// A AE COM client instance.
- public new ComAeClient SelectClient(ServerSystemContext context, bool useDefault)
- {
- return (ComAeClient)base.SelectClient(context, useDefault);
- }
- #endregion
-
- #region Protected Members
- ///
- /// Gets or sets the default COM client instance.
- ///
- /// The default client.
- protected new ComAeClient DefaultClient
- {
- get { return base.DefaultClient as ComAeClient; }
- set { base.DefaultClient = value; }
- }
-
- ///
- /// Gets the configuration.
- ///
- /// The configuration.
- protected new ComAeClientConfiguration Configuration
- {
- get { return base.Configuration as ComAeClientConfiguration; }
- }
-
- ///
- /// Creates a new client object.
- ///
- protected override ComClient CreateClient()
- {
- return new ComAeClient(Configuration);
- }
-
- ///
- /// Updates the status node.
- ///
- protected override bool UpdateStatus()
- {
- // get the status from the server.
- ComAeClient client = DefaultClient;
- OPCEVENTSERVERSTATUS? status = client.GetStatus();
-
- // check the client has been abandoned.
- if (!Object.ReferenceEquals(client, DefaultClient))
- {
- return false;
- }
-
- // update the server status.
- lock (StatusNodeLock)
- {
- StatusNode.ServerUrl.Value = Configuration.ServerUrl;
-
- if (status != null)
- {
- StatusNode.SetStatusCode(DefaultSystemContext, StatusCodes.Good, DateTime.UtcNow);
-
- StatusNode.ServerState.Value = Utils.Format("{0}", status.Value.dwServerState);
- StatusNode.CurrentTime.Value = ComUtils.GetDateTime(status.Value.ftCurrentTime);
- StatusNode.LastUpdateTime.Value = ComUtils.GetDateTime(status.Value.ftLastUpdateTime);
- StatusNode.StartTime.Value = ComUtils.GetDateTime(status.Value.ftStartTime);
- StatusNode.VendorInfo.Value = status.Value.szVendorInfo;
- StatusNode.SoftwareVersion.Value = Utils.Format("{0}.{1}.{2}", status.Value.wMajorVersion, status.Value.wMinorVersion, status.Value.wBuildNumber);
- }
- else
- {
- StatusNode.SetStatusCode(DefaultSystemContext, StatusCodes.BadOutOfService, DateTime.UtcNow);
- }
-
- StatusNode.ClearChangeMasks(DefaultSystemContext, true);
- return status != null;
- }
- }
- #endregion
-
- #region Private Fields
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/Ae/ComAeClientNodeManager.cs b/ComIOP/Common/Client/Ae/ComAeClientNodeManager.cs
deleted file mode 100644
index 8535c42e4..000000000
--- a/ComIOP/Common/Client/Ae/ComAeClientNodeManager.cs
+++ /dev/null
@@ -1,823 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using System.Text;
-using System.Diagnostics;
-using System.Xml;
-using System.IO;
-using System.Threading;
-using System.Reflection;
-using Opc.Ua;
-using Opc.Ua.Server;
-using Opc.Ua.Com;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// A node manager for a server that exposes several variables.
- ///
- public class ComAeClientNodeManager : ComClientNodeManager
- {
- #region Constructors
- ///
- /// Initializes the node manager.
- ///
- public ComAeClientNodeManager(IServerInternal server, string namespaceUri, ComAeClientConfiguration configuration, bool ownsTypeModel)
- :
- base(server, namespaceUri, ownsTypeModel)
- {
- SystemContext.SystemHandle = m_system = new ComAeClientManager();
- SystemContext.NodeIdFactory = this;
-
- // save the configuration for the node manager.
- m_configuration = configuration;
-
- // set the alias root.
- AliasRoot = m_configuration.ServerName;
-
- if (String.IsNullOrEmpty(AliasRoot))
- {
- AliasRoot = "AE";
- }
-
- m_subscriptions = new Dictionary();
- m_monitoredItems = new Dictionary();
- }
- #endregion
-
- #region IDisposable Members
- ///
- /// An overrideable version of the Dispose.
- ///
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- m_system.Dispose();
- }
-
- base.Dispose(disposing);
- }
- #endregion
-
- #region INodeIdFactory Members
- ///
- /// Creates the NodeId for the specified node.
- ///
- /// The context.
- /// The node.
- /// The new NodeId.
- ///
- /// This method is called by the NodeState.Create() method which initializes a Node from
- /// the type model. During initialization a number of child nodes are created and need to
- /// have NodeIds assigned to them. This implementation constructs NodeIds by constructing
- /// strings. Other implementations could assign unique integers or Guids and save the new
- /// Node in a dictionary for later lookup.
- ///
- public override NodeId New(ISystemContext context, NodeState node)
- {
- if (node is ServerStatusState)
- {
- return node.NodeId;
- }
-
- return ParsedNodeId.ConstructIdForComponent(node, NamespaceIndex);
- }
- #endregion
-
- #region INodeManager Members
- ///
- /// Does any initialization required before the address space can be used.
- ///
- ///
- /// The externalReferences is an out parameter that allows the node manager to link to nodes
- /// in other node managers. For example, the 'Objects' node is managed by the CoreNodeManager and
- /// should have a reference to the root folder node(s) exposed by this node manager.
- ///
- public override void CreateAddressSpace(IDictionary> externalReferences)
- {
- lock (Lock)
- {
- // check if the type model needs to be loaded.
- if (NamespaceIndexes.Length > 1)
- {
- LoadPredefinedNodes(SystemContext, externalReferences);
- }
-
- IList references = null;
-
- // create the root node.
- string serverName = m_configuration.ServerName;
-
- if (String.IsNullOrEmpty(serverName))
- {
- serverName = "ComAeServer";
- }
-
- AeAreaState root = new AeAreaState(SystemContext, String.Empty, serverName, NamespaceIndex);
- root.AddReference(ReferenceTypeIds.Organizes, true, ObjectIds.ObjectsFolder);
-
- // link root to objects folder.
- if (!externalReferences.TryGetValue(ObjectIds.ObjectsFolder, out references))
- {
- externalReferences[ObjectIds.ObjectsFolder] = references = new List();
- }
-
- references.Add(new NodeStateReference(ReferenceTypeIds.Organizes, false, root.NodeId));
-
- // link root to server object.
- if (!externalReferences.TryGetValue(ObjectIds.Server, out references))
- {
- externalReferences[ObjectIds.Server] = references = new List();
- }
-
- references.Add(new NodeStateReference(ReferenceTypeIds.HasNotifier, false, root.NodeId));
-
- // create the status node.
- ComServerStatusState status = new ComServerStatusState(root);
- status.ReferenceTypeId = ReferenceTypeIds.Organizes;
-
- // get the type namepace for the browse name.
- int typeNamepaceIndex = Server.NamespaceUris.GetIndex(Namespaces.ComInterop);
-
- if (typeNamepaceIndex < 0)
- {
- typeNamepaceIndex = NamespaceIndex;
- }
-
- status.Create(
- SystemContext,
- AeModelUtils.ConstructIdForInternalNode("ServerStatus", NamespaceIndex),
- new QualifiedName("ServerStatus", (ushort)typeNamepaceIndex),
- null,
- true);
-
- root.AddChild(status);
-
- // store root folder in the pre-defined nodes.
- AddPredefinedNode(SystemContext, root);
- AddRootNotifier(root);
-
- // create the COM server.
- m_system.Initialize(SystemContext, m_configuration, status, Lock, OnServerReconnected);
-
- // create a template condition that can be used to initialize static metadata.
- m_templateAlarm = new AlarmConditionState(null);
- m_templateAlarm.SymbolicName = "TemplateAlarm";
-
- m_templateAlarm.Create(
- SystemContext,
- null,
- new QualifiedName(m_templateAlarm.SymbolicName, NamespaceIndex),
- null,
- false);
-
- m_templateAlarm.Acknowledge.OnCall = OnAcknowledge;
- StartMetadataUpdates(DoMetadataUpdate, null, 5000, m_configuration.MaxReconnectWait);
- }
- }
-
- ///
- /// Frees any resources allocated for the address space.
- ///
- public override void DeleteAddressSpace()
- {
- lock (Lock)
- {
- base.DeleteAddressSpace();
- }
- }
-
- ///
- /// Returns a unique handle for the node.
- ///
- protected override NodeHandle GetManagerHandle(ServerSystemContext context, NodeId nodeId, IDictionary cache)
- {
- lock (Lock)
- {
- // quickly exclude nodes that are not in the namespace.
- if (!IsNodeIdInNamespace(nodeId))
- {
- return null;
- }
-
- // check cache.
- if (cache != null)
- {
- NodeState node = null;
-
- if (cache.TryGetValue(nodeId, out node))
- {
- return new NodeHandle(nodeId, node);
- }
- }
-
- NodeHandle handle = null;
-
- try
- {
- // check if node already being monitored.
- if (MonitoredNodes != null)
- {
- MonitoredNode2 monitoredNode2 = null;
-
- if (MonitoredNodes.TryGetValue(nodeId, out monitoredNode2))
- {
- handle = new NodeHandle(nodeId, monitoredNode2.Node);
- handle.MonitoredNode = monitoredNode2;
- return handle;
- }
- }
-
- // check for predefined nodes.
- if (PredefinedNodes != null)
- {
- NodeState node = null;
-
- if (PredefinedNodes.TryGetValue(nodeId, out node))
- {
- return handle = new NodeHandle(nodeId, node);
- }
- }
-
- // parse the identifier.
- AeParsedNodeId parsedNodeId = AeParsedNodeId.Parse(nodeId);
-
- if (parsedNodeId != null)
- {
- if (parsedNodeId.RootType == AeModelUtils.AeEventTypeMapping && m_typeCache != null)
- {
- AeEventTypeMappingState mappingNode = m_typeCache.GetMappingNode(SystemContext, nodeId);
-
- if (mappingNode != null)
- {
- return handle = new NodeHandle(nodeId, mappingNode);
- }
-
- return null;
- }
-
- handle = new NodeHandle();
-
- handle.NodeId = nodeId;
- handle.Validated = false;
- handle.Node = null;
- handle.ParsedNodeId = parsedNodeId;
-
- return handle;
- }
- }
- finally
- {
- if (handle != null && handle.Node != null && cache != null)
- {
- cache.Add(nodeId, handle.Node);
- }
- }
-
- return null;
- }
- }
-
- ///
- /// Verifies that the specified node exists.
- ///
- protected override NodeState ValidateNode(
- ServerSystemContext context,
- NodeHandle handle,
- IDictionary cache)
- {
- // not valid if no root.
- if (handle == null)
- {
- return null;
- }
-
- // check if previously validated.
- if (handle.Validated)
- {
- return handle.Node;
- }
-
- NodeState target = null;
-
- // check if already in the cache.
- if (cache != null)
- {
- if (cache.TryGetValue(handle.NodeId, out target))
- {
- // nulls mean a NodeId which was previously found to be invalid has been referenced again.
- if (target == null)
- {
- return null;
- }
-
- handle.Node = target;
- handle.Validated = true;
- return handle.Node;
- }
-
- target = null;
- }
-
- try
- {
- // check if the node id has been parsed.
- AeParsedNodeId parsedNodeId = handle.ParsedNodeId as AeParsedNodeId;
-
- if (parsedNodeId == null)
- {
- return null;
- }
-
- ComAeClient client = m_system.SelectClient(context, false);
-
- switch (parsedNodeId.RootType)
- {
- case AeModelUtils.AeSimpleEventType:
- case AeModelUtils.AeTrackingEventType:
- case AeModelUtils.AeConditionEventType:
- {
- if (m_typeCache == null)
- {
- return null;
- }
-
- BaseObjectTypeState eventTypeNode = null;
- NodeId rootId = AeParsedNodeId.Construct(parsedNodeId.RootType, parsedNodeId.CategoryId, parsedNodeId.ConditionName, parsedNodeId.NamespaceIndex);
-
- if (!m_typeCache.EventTypeNodes.TryGetValue(rootId, out eventTypeNode))
- {
- return null;
- }
-
- target = eventTypeNode;
- break;
- }
-
- case AeModelUtils.AeArea:
- {
- ComAeBrowserClient browser = new ComAeBrowserClient(client, null);
- target = browser.FindArea(context, parsedNodeId.RootId, NamespaceIndex);
- browser.Dispose();
-
- handle.Validated = true;
- handle.Node = target;
- return handle.Node;
- }
-
- case AeModelUtils.AeSource:
- {
- ComAeBrowserClient browser = new ComAeBrowserClient(client, null);
- target = browser.FindSource(context, parsedNodeId.RootId, parsedNodeId.ComponentPath, NamespaceIndex);
- browser.Dispose();
-
- handle.Validated = true;
- handle.Node = target;
- return handle.Node;
- }
-
- case AeModelUtils.AeCondition:
- {
- target = new AeConditionState(context, handle, m_templateAlarm.Acknowledge);
- break;
- }
- }
-
- // node does not exist.
- if (target == null)
- {
- return null;
- }
-
- if (!String.IsNullOrEmpty(parsedNodeId.ComponentPath))
- {
- // validate component.
- NodeState component = target.FindChildBySymbolicName(context, parsedNodeId.ComponentPath);
-
- // component does not exist.
- if (component == null)
- {
- return null;
- }
-
- target = component;
- }
-
- // found a valid component.
- handle.Validated = true;
- handle.Node = target;
- return handle.Node;
- }
- finally
- {
- // store the node in the cache to optimize subsequent lookups.
- if (cache != null)
- {
- cache.Add(handle.NodeId, target);
- }
- }
- }
-
- ///
- /// Called when client manager has reconnected to the COM server.
- ///
- public void OnServerReconnected(object state)
- {
- try
- {
- // refetch the type information.
- DoMetadataUpdate(null);
-
- lock (Lock)
- {
- foreach (ComAeSubscriptionClient subscription in m_subscriptions.Values)
- {
- subscription.Create();
- }
- }
- }
- catch (Exception e)
- {
- Utils.Trace(e, "Could not re-create subscription after reconnect.");
- }
- }
-
- ///
- /// Called when the alarm is acknowledged.
- ///
- private ServiceResult OnAcknowledge(
- ISystemContext context,
- MethodState method,
- NodeId objectId,
- byte[] eventId,
- LocalizedText comment)
- {
- ComAeClientManager system = (ComAeClientManager)this.SystemContext.SystemHandle;
- ComAeClient client = (ComAeClient)system.SelectClient((ServerSystemContext)context, false);
-
- try
- {
- return client.Acknowledge((ServerSystemContext)context, eventId, comment);
- }
- catch (Exception e)
- {
- return ServiceResult.Create(e, StatusCodes.BadUnexpectedError, "Could not acknowledge event.");
- }
- }
- #endregion
-
- #region Overridden Methods
- ///
- /// Loads a node set from a file or resource and addes them to the set of predefined nodes.
- ///
- protected override NodeStateCollection LoadPredefinedNodes(ISystemContext context)
- {
- NodeStateCollection predefinedNodes = new NodeStateCollection();
- predefinedNodes.LoadFromBinaryResource(context, "Opc.Ua.Com.Common.Opc.Ua.Com.PredefinedNodes.uanodes", Assembly.GetAssembly(this.GetType()), true);
- return predefinedNodes;
- }
-
- ///
- /// Waits for the type cache to be initialized.
- ///
- private bool WaitForTypeCache()
- {
- // need to wait until the cache is refreshed for the first time.
- for (int ii = 0; Object.ReferenceEquals(m_typeCache, null) && ii < 200 && Server.IsRunning; ii++)
- {
- Thread.Sleep(100);
- }
-
- return !Object.ReferenceEquals(m_typeCache, null);
- }
-
- ///
- /// Subscribes or unsubscribes to events produced by all event sources.
- ///
- ///
- /// This method is called when a event subscription is created or deleted. The node
- /// manager must start/stop reporting events for all objects that it manages.
- ///
- public override ServiceResult SubscribeToAllEvents(
- OperationContext context,
- uint subscriptionId,
- IEventMonitoredItem monitoredItem,
- bool unsubscribe)
- {
- ServerSystemContext systemContext = SystemContext.Copy(context);
- ComAeClientManager system = (ComAeClientManager)this.SystemContext.SystemHandle;
- ComAeClient client = (ComAeClient)system.SelectClient(systemContext, false);
-
- // need to wait until the cache is refreshed for the first time.
- if (!WaitForTypeCache())
- {
- return StatusCodes.BadOutOfService;
- }
-
- lock (Lock)
- {
- SubscriptionIndex index = new SubscriptionIndex();
- index.NodeId = Opc.Ua.ObjectIds.Server;
- index.LocaleId = client.LocaleId;
-
- if (unsubscribe)
- {
- ComAeSubscriptionClient subscription = null;
-
- if (!m_monitoredItems.TryGetValue(monitoredItem.Id, out subscription))
- {
- return ServiceResult.Good;
- }
-
- m_monitoredItems.Remove(monitoredItem.Id);
- // Utils.Trace("REMOVED ITEM {0}", monitoredItem.Id);
-
- if (subscription.RemoveItem(monitoredItem as MonitoredItem) == 0)
- {
- subscription.Delete();
- m_subscriptions.Remove(index);
- // Utils.Trace("DELETED SUBSCRIPTION {0}", index.NodeId);
- }
- }
- else
- {
- ComAeSubscriptionClient subscription = null;
-
- if (!m_subscriptions.TryGetValue(index, out subscription))
- {
- subscription = new ComAeSubscriptionClient(systemContext, m_configuration, m_typeCache, NamespaceIndex, system, monitoredItem as MonitoredItem);
- m_subscriptions.Add(index, subscription);
- subscription.Create();
- // Utils.Trace("ADDED NEW SUBSCRIPTION {0}", index.NodeId);
- }
- else
- {
- subscription.AddItem(monitoredItem as MonitoredItem);
- }
-
- m_monitoredItems[monitoredItem.Id] = subscription;
- // Utils.Trace("ADDED NEW ITEM {0}", monitoredItem.Id);
- }
- }
-
- return ServiceResult.Good;
- }
-
- ///
- /// Subscribes to events.
- ///
- protected override ServiceResult SubscribeToEvents(
- ServerSystemContext context,
- NodeState source,
- IEventMonitoredItem monitoredItem,
- bool unsubscribe)
- {
- ComAeClientManager system = (ComAeClientManager)this.SystemContext.SystemHandle;
- ComAeClient client = (ComAeClient)system.SelectClient(context, false);
-
- // need to wait until the cache is refreshed for the first time.
- if (!WaitForTypeCache())
- {
- return StatusCodes.BadOutOfService;
- }
-
- lock (Lock)
- {
- SubscriptionIndex index = new SubscriptionIndex();
- index.NodeId = source.NodeId;
- index.LocaleId = client.LocaleId;
-
- if (unsubscribe)
- {
- ComAeSubscriptionClient subscription = null;
-
- if (!m_monitoredItems.TryGetValue(monitoredItem.Id, out subscription))
- {
- return ServiceResult.Good;
- }
-
- m_monitoredItems.Remove(monitoredItem.Id);
- // Utils.Trace("REMOVED ITEM {0}", monitoredItem.Id);
-
- if (subscription.RemoveItem(monitoredItem as MonitoredItem) == 0)
- {
- subscription.Delete();
- m_subscriptions.Remove(index);
- // Utils.Trace("DELETED SUBSCRIPTION {0}", index.NodeId);
- }
- }
- else
- {
- ComAeSubscriptionClient subscription = null;
-
- if (!m_subscriptions.TryGetValue(index, out subscription))
- {
- subscription = new ComAeSubscriptionClient(context, m_configuration, m_typeCache, NamespaceIndex, system, monitoredItem as MonitoredItem);
- m_subscriptions.Add(index, subscription);
- subscription.Create();
- // Utils.Trace("ADDED NEW SUBSCRIPTION {0}", index.NodeId);
- }
- else
- {
- subscription.AddItem(monitoredItem as MonitoredItem);
- }
-
- m_monitoredItems[monitoredItem.Id] = subscription;
- // Utils.Trace("ADDED NEW ITEM {0}", monitoredItem.Id);
- }
- }
-
- // all done.
- return ServiceResult.Good;
- }
-
- ///
- /// Tells the node manager to refresh any conditions associated with the specified monitored items.
- ///
- public override ServiceResult ConditionRefresh(
- OperationContext context,
- IList monitoredItems)
- {
- List itemsToRefresh = new List();
- List subscriptionsToRefresh = new List();
-
- lock (Lock)
- {
- // build list of subscriptions that have to be refreshed.
- for (int ii = 0; ii < monitoredItems.Count; ii++)
- {
- MonitoredItem monitoredItem = monitoredItems[ii] as MonitoredItem;
-
- if (monitoredItem == null)
- {
- continue;
- }
-
- ComAeSubscriptionClient subscription = null;
-
- if (!m_monitoredItems.TryGetValue(monitoredItem.Id, out subscription))
- {
- continue;
- }
-
- itemsToRefresh.Add(monitoredItem);
- subscriptionsToRefresh.Add(subscription);
- }
- }
-
- for (int ii = 0; ii < subscriptionsToRefresh.Count; ii++)
- {
- // collect the events.
- List events = new List();
- subscriptionsToRefresh[ii].Refresh(events);
-
- // queue the events.
- for (int jj = 0; jj < events.Count; jj++)
- {
- itemsToRefresh[ii].QueueEvent(events[jj]);
- }
- }
-
- return ServiceResult.Good;
- }
- #endregion
-
- #region Private Methods
- ///
- /// Updates the type cache.
- ///
- private void DoMetadataUpdate(object state)
- {
- try
- {
- if (!Server.IsRunning)
- {
- return;
- }
-
- ComAeClientManager system = (ComAeClientManager)SystemContext.SystemHandle;
- ComAeClient client = (ComAeClient)system.SelectClient(SystemContext, true);
-
- AeTypeCache cache = new AeTypeCache();
- cache.LoadEventTypes(client);
-
- lock (Lock)
- {
- if (m_typeCache == null)
- {
- m_typeCache = cache;
- }
-
- m_typeCache.EventTypes = cache.EventTypes;
- m_typeCache.UpdateCache(SystemContext, NamespaceIndex);
- }
- }
- catch (Exception e)
- {
- Utils.Trace(e, "Unexpected error updating event type cache.");
- }
- }
- #endregion
-
- #region SubscriptionIndex Class
- ///
- /// Used to maintain an index of current subscriptions.
- ///
- private class SubscriptionIndex
- {
- ///
- /// The locale id for the subscription.
- ///
- public int LocaleId { get; set; }
-
- ///
- /// The node id for the subscription.
- ///
- public NodeId NodeId { get; set; }
-
- ///
- /// Returns true if the object is equal to the instance.
- ///
- public override bool Equals(object obj)
- {
- if (Object.ReferenceEquals(this, obj))
- {
- return true;
- }
-
- SubscriptionIndex index = obj as SubscriptionIndex;
-
- if (index == null)
- {
- return false;
- }
-
- if (index.LocaleId != this.LocaleId)
- {
- return false;
- }
-
- if (index.NodeId != this.NodeId)
- {
- return false;
- }
-
- return true;
- }
-
- ///
- /// Returns a hash code for the instantce.
- ///
- public override int GetHashCode()
- {
- int hash = LocaleId.GetHashCode();
-
- if (NodeId != null)
- {
- hash ^= NodeId.GetHashCode();
- }
-
- return hash;
- }
- }
- #endregion
-
- #region Private Fields
- private ComAeClientManager m_system;
- private ComAeClientConfiguration m_configuration;
- private AlarmConditionState m_templateAlarm;
- private Dictionary m_subscriptions;
- private Dictionary m_monitoredItems;
- private AeTypeCache m_typeCache;
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/Ae/ComAeEventCallback.cs b/ComIOP/Common/Client/Ae/ComAeEventCallback.cs
deleted file mode 100644
index 6899f78cc..000000000
--- a/ComIOP/Common/Client/Ae/ComAeEventCallback.cs
+++ /dev/null
@@ -1,151 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using Opc.Ua;
-using Opc.Ua.Server;
-using Opc.Ua.Com;
-using Opc.Ua.Com.Client;
-using OpcRcw.Ae;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// A class that implements the IOPCEventSink interface.
- ///
- internal class ComAeEventSink : OpcRcw.Ae.IOPCEventSink, IDisposable
- {
- #region Constructors
- ///
- /// Initializes the object with the containing subscription object.
- ///
- public ComAeEventSink(ComAeSubscriptionClient subscription)
- {
- // save group.
- m_subscription = subscription;
-
- // create connection point.
- m_connectionPoint = new ConnectionPoint(subscription.Unknown, typeof(IOPCEventSink).GUID);
-
- // advise.
- m_connectionPoint.Advise(this);
- }
- #endregion
-
- #region IDisposable Members
- ///
- /// Frees any unmanaged resources.
- ///
- public void Dispose()
- {
- Dispose(true);
- }
-
- ///
- /// An overrideable version of the Dispose.
- ///
- protected virtual void Dispose(bool disposing)
- {
- if (m_connectionPoint != null)
- {
- if (disposing)
- {
- m_connectionPoint.Dispose();
- m_connectionPoint = null;
- }
- }
- }
- #endregion
-
- #region Public Properties
- ///
- /// Whether the callback is connected.
- ///
- public bool Connected
- {
- get
- {
- return m_connectionPoint != null;
- }
- }
-
- ///
- /// Gets the cookie returned by the server.
- ///
- /// The cookie.
- public int Cookie
- {
- get
- {
- if (m_connectionPoint != null)
- {
- return m_connectionPoint.Cookie;
- }
-
- return 0;
- }
- }
- #endregion
-
- #region ComAeEventSink Members
- ///
- /// Called when one or events are produce by the server.
- ///
- public void OnEvent(
- int hClientSubscription,
- int bRefresh,
- int bLastRefresh,
- int dwCount,
- ONEVENTSTRUCT[] pEvents)
- {
- try
- {
- if (bRefresh == 0)
- {
- m_subscription.OnEvent(pEvents);
- }
- else
- {
- m_subscription.OnRefresh(pEvents, bLastRefresh != 0);
- }
- }
- catch (Exception e)
- {
- Utils.Trace(e, "Unexpected error processing OnEvent callback.");
- }
- }
- #endregion
-
- #region Private Members
- private ComAeSubscriptionClient m_subscription;
- private ConnectionPoint m_connectionPoint;
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/Ae/ComAeSubscriptionClient.cs b/ComIOP/Common/Client/Ae/ComAeSubscriptionClient.cs
deleted file mode 100644
index 1f68febc2..000000000
--- a/ComIOP/Common/Client/Ae/ComAeSubscriptionClient.cs
+++ /dev/null
@@ -1,762 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using System.Xml;
-using System.IO;
-using System.Reflection;
-using System.Threading;
-using Opc.Ua;
-using Opc.Ua.Server;
-using Opc.Ua.Com;
-using OpcRcw.Ae;
-using OpcRcw.Comn;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// Browses areas and sources in the AE server.
- ///
- internal class ComAeSubscriptionClient : ComObject
- {
- #region Constructors
- ///
- /// Initializes a new instance of the class.
- ///
- /// The context.
- /// The configuration.
- /// The cache for known types.
- /// The namespace index for the event types.
- /// The manager.
- /// The monitored item.
- public ComAeSubscriptionClient(
- ServerSystemContext context,
- ComAeClientConfiguration configuration,
- AeTypeCache cache,
- ushort namespaceIndex,
- ComAeClientManager manager,
- MonitoredItem monitoredItem)
- {
- m_defaultContext = context;
- m_separators = configuration.SeperatorChars;
- m_cache = cache;
- m_namespaceIndex = namespaceIndex;
- m_manager = manager;
- m_refreshComplete = new ManualResetEvent(false);
- m_monitoredItems = new List();
- m_monitoredItems.Add(monitoredItem);
- m_qualifiedName = null;
- m_isSource = false;
-
- NodeHandle handle = monitoredItem.ManagerHandle as NodeHandle;
- AeAreaState area = handle.Node as AeAreaState;
-
- if (area != null)
- {
- m_qualifiedName = area.QualifiedName;
- m_isSource = false;
- }
- else
- {
- AeSourceState source = handle.Node as AeSourceState;
-
- if (source != null)
- {
- m_qualifiedName = source.QualifiedName;
- m_isSource = true;
- }
- }
- }
- #endregion
-
- #region IDisposable Members
- ///
- /// An overrideable version of the Dispose.
- ///
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- Utils.SilentDispose(m_callback);
- m_callback = null;
- }
-
- base.Dispose(disposing);
- }
-
- ///
- /// Releases all references to the server.
- ///
- protected override void ReleaseServer()
- {
- Utils.SilentDispose(m_callback);
- m_callback = null;
- base.ReleaseServer();
- }
- #endregion
-
- #region Public Methods
- ///
- /// The locale id for the subscription.
- ///
- public int LocaleId { get; set; }
-
- ///
- /// Creates the subscription.
- ///
- public void Create()
- {
- ComAeClient client = m_manager.SelectClient(m_defaultContext, false);
-
- // release existing server.
- if (this.Unknown != null)
- {
- ReleaseServer();
- }
-
- // create the subscription.
- this.Unknown = client.CreateEventSubscription();
-
- // select the attributes.
- foreach (KeyValuePair entry in m_cache.Attributes)
- {
- SelectReturnedAttributes(entry.Key, entry.Value);
- }
-
- // set the filter.
- SetFilter(m_qualifiedName, m_isSource);
-
- // set up callback.
- try
- {
- m_callback = new ComAeEventSink(this);
- }
- catch (Exception e)
- {
- Utils.Trace("Could not establish event callback.", e);
- }
- }
-
- ///
- /// Deletes the subscription.
- ///
- public void Delete()
- {
- if (this.Unknown != null)
- {
- ReleaseServer();
- }
- }
-
- ///
- /// Refreshes the conditions monitored by the subscription.
- ///
- /// The events.
- public void Refresh(List events)
- {
- // ensure multiple refreshes cannot occur simutaneously.
- try
- {
- lock (m_refreshLock)
- {
- // save the list for updates.
- lock (m_callbackLock)
- {
- m_refreshEvents = events;
- m_refreshComplete.Reset();
- }
-
- if (m_callback != null)
- {
- if (!Refresh())
- {
- return;
- }
-
- if (!m_refreshComplete.WaitOne(30000))
- {
- CancelRefresh();
- }
- }
- }
- }
- finally
- {
- // all done.
- lock (m_callbackLock)
- {
- m_refreshEvents = null;
- }
- }
- }
-
- ///
- /// Adds an item to a subscription.
- ///
- public void AddItem(MonitoredItem monitoredItem)
- {
- lock (m_monitoredItems)
- {
- m_monitoredItems.Add(monitoredItem);
- }
- }
-
- ///
- /// Removes an item from the subscription.
- ///
- public int RemoveItem(MonitoredItem monitoredItem)
- {
- lock (m_monitoredItems)
- {
- for (int ii = 0; ii < m_monitoredItems.Count; ii++)
- {
- if (m_monitoredItems[ii].Id == monitoredItem.Id)
- {
- m_monitoredItems.RemoveAt(ii);
- break;
- }
- }
-
- return m_monitoredItems.Count;
- }
- }
-
- ///
- /// Called when events arrive from the server.
- ///
- /// The events.
- public void OnEvent(ONEVENTSTRUCT[] events)
- {
- for (int ii = 0; ii < events.Length; ii++)
- {
- BaseEventState e = DispatchEvent(events[ii]);
-
- if (e != null)
- {
- lock (m_monitoredItems)
- {
- for (int jj = 0; jj < m_monitoredItems.Count; jj++)
- {
- m_monitoredItems[jj].QueueEvent(e);
- }
- }
- }
- }
- }
-
- ///
- /// Dispatches the event.
- ///
- private BaseEventState DispatchEvent(ONEVENTSTRUCT e)
- {
- NodeId typeId = AeParsedNodeId.Construct(e.dwEventType, e.dwEventCategory, e.szConditionName, m_namespaceIndex);
-
- // find the type.
- AeEventTypeState eventType = m_cache.FindType(m_defaultContext, typeId);
-
- if (eventType == null)
- {
- return null;
- }
-
- // create a new instance.
- BaseEventState instance = m_cache.CreateInstance(m_defaultContext, eventType);
-
- if (instance == null)
- {
- return null;
- }
-
- // fill in fields.
- UpdateBaseEvent(instance, eventType.EventType, e);
-
- if (instance is AuditEventState)
- {
- UpdateAuditEvent((AuditEventState)instance, eventType.EventType, e);
- }
-
- if (instance is AlarmConditionState)
- {
- UpdateAlarm((AlarmConditionState)instance, eventType.EventType, e);
- }
-
- if (instance is ExclusiveLimitAlarmState)
- {
- UpdateExclusiveLimitAlarm((ExclusiveLimitAlarmState)instance, eventType.EventType, e);
- }
-
- else if (instance is NonExclusiveLimitAlarmState)
- {
- UpdateNonExclusiveLimitAlarm((NonExclusiveLimitAlarmState)instance, eventType.EventType, e);
- }
-
- // process attributes.
- bool ackCommentFound = false;
- object[] values = ComUtils.GetVARIANTs(ref e.pEventAttributes, e.dwNumEventAttrs, false);
-
- for (int ii = 0; ii < eventType.EventType.Attributes.Count; ii++)
- {
- EventAttribute attribute = eventType.EventType.Attributes[ii];
-
- if (ii >= e.dwNumEventAttrs)
- {
- continue;
- }
-
- if (!ackCommentFound && AeTypeCache.IsKnownName(attribute.Description, "ACK COMMENT"))
- {
- ConditionState condition = instance as ConditionState;
-
- if (condition != null)
- {
- condition.Comment = new ConditionVariableState(condition);
- condition.Comment.BrowseName = Opc.Ua.BrowseNames.Comment;
- condition.Comment.Value = new LocalizedText(values[ii] as string);
- }
-
- ackCommentFound = true;
- continue;
- }
-
- PropertyState property = new PropertyState(instance);
-
- property.SymbolicName = attribute.Description;
- property.BrowseName = new QualifiedName(property.SymbolicName, m_namespaceIndex);
- property.Value = values[ii];
-
- instance.AddChild(property);
- }
-
- return instance;
- }
-
- ///
- /// Updates the base event.
- ///
- private void UpdateBaseEvent(BaseEventState instance, EventType eventType, ONEVENTSTRUCT e)
- {
- BinaryEncoder encoder = new BinaryEncoder(ServiceMessageContext.GlobalContext);
-
- encoder.WriteString(null, e.szSource);
- encoder.WriteString(null, e.szConditionName);
- encoder.WriteInt32(null, e.ftActiveTime.dwHighDateTime);
- encoder.WriteInt32(null, e.ftActiveTime.dwLowDateTime);
- encoder.WriteInt32(null, e.dwCookie);
-
- byte[] eventId = encoder.CloseAndReturnBuffer();
- NodeId eventTypeId = AeParsedNodeId.Construct(e.dwEventType, e.dwEventCategory, e.szConditionName, m_namespaceIndex);
- NodeId sourceNode = AeModelUtils.ConstructIdForSource(e.szSource, null, m_namespaceIndex);
- string sourceName = e.szSource;
- DateTime time = ComUtils.GetDateTime(e.ftTime);
- DateTime receiveTime = DateTime.UtcNow;
- LocalizedText message = e.szMessage;
- ushort severity = (ushort)e.dwSeverity;
-
- instance.TypeDefinitionId = eventTypeId;
- instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.EventId, eventId, false);
- instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.EventType, eventTypeId, false);
- instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.SourceNode, sourceNode, false);
- instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.SourceName, sourceName, false);
- instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Time, time, false);
- instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.ReceiveTime, receiveTime, false);
- instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Message, message, false);
- instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Severity, severity, false);
- }
-
- ///
- /// Updates the audit event.
- ///
- private void UpdateAuditEvent(AuditEventState instance, EventType eventType, ONEVENTSTRUCT e)
- {
- instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.ActionTimeStamp, instance.Time.Value, false);
- instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Status, true, false);
- instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.ServerId, m_defaultContext.NamespaceUris.GetString(m_namespaceIndex), false);
- instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.ClientUserId, e.szActorID, false);
- }
-
- ///
- /// Updates the condition event.
- ///
- private void UpdateAlarm(AlarmConditionState instance, EventType eventType, ONEVENTSTRUCT e)
- {
- instance.NodeId = AeParsedNodeId.ConstructIdForCondition(e.szSource, e.dwEventCategory, e.szConditionName, m_namespaceIndex);
-
- // find the condition class.
- NodeId classId = AeParsedNodeId.Construct(e.dwEventType, e.dwEventCategory, null, m_namespaceIndex);
- AeEventTypeState conditionClassType = m_cache.FindType(m_defaultContext, classId);
-
- if (conditionClassType != null)
- {
- instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.ConditionClassId, classId, false);
- instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.ConditionClassName, conditionClassType.EventType.Description, false);
- }
- else
- {
- instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.ConditionClassId, Opc.Ua.ObjectTypeIds.BaseConditionClassType, false);
- instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.ConditionClassName, "BaseConditionClass", false);
- }
-
- instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.ConditionName, e.szConditionName, false); ;
- instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.ClientUserId, e.szActorID, false);
- instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Quality, ComUtils.GetQualityCode(e.wQuality), false);
-
- bool acknowledged = (e.wNewState & Constants.CONDITION_ACKED) != 0;
- bool active = (e.wNewState & Constants.CONDITION_ACTIVE) != 0;
- bool enabled = (e.wNewState & Constants.CONDITION_ENABLED) != 0;
- bool retain = enabled & (active || !acknowledged);
-
- LocalizedText effectiveDisplayName = ConditionStateNames.Inactive;
-
- if (!enabled)
- {
- effectiveDisplayName = ConditionStateNames.Disabled;
- }
- else if (!acknowledged)
- {
- effectiveDisplayName = ConditionStateNames.Unacknowledged;
- }
- else if (active)
- {
- effectiveDisplayName = ConditionStateNames.Active;
- }
-
- instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Retain, true, false);
-
- instance.EnabledState = new TwoStateVariableState(instance);
- instance.EnabledState.BrowseName = Opc.Ua.BrowseNames.EnabledState;
- instance.EnabledState.Value = new LocalizedText((enabled) ? ConditionStateNames.Enabled : ConditionStateNames.Disabled);
- instance.EnabledState.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Id, enabled, false);
- instance.EnabledState.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.EffectiveDisplayName, effectiveDisplayName, false);
-
- instance.AckedState = new TwoStateVariableState(instance);
- instance.AckedState.BrowseName = Opc.Ua.BrowseNames.AckedState;
- instance.AckedState.Value = new LocalizedText((acknowledged) ? ConditionStateNames.Acknowledged : ConditionStateNames.Unacknowledged);
- instance.AckedState.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Id, acknowledged, false);
-
- instance.ActiveState = new TwoStateVariableState(instance);
- instance.ActiveState.BrowseName = Opc.Ua.BrowseNames.ActiveState;
- instance.ActiveState.Value = new LocalizedText((active) ? ConditionStateNames.Active : ConditionStateNames.Inactive);
- instance.ActiveState.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Id, active, false);
- instance.ActiveState.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.TransitionTime, ComUtils.GetDateTime(e.ftActiveTime), false);
-
- if (!String.IsNullOrEmpty(e.szSubconditionName))
- {
- instance.ActiveState.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.EffectiveDisplayName, e.szSubconditionName, false);
- }
- }
-
- ///
- /// Updates the exclusive limit alarm event.
- ///
- private void UpdateExclusiveLimitAlarm(ExclusiveLimitAlarmState instance, EventType eventType, ONEVENTSTRUCT e)
- {
- NodeId state = null;
- string text = null;
-
- if (AeTypeCache.IsKnownName(e.szSubconditionName, "HI HI"))
- {
- state = Opc.Ua.ObjectIds.ExclusiveLimitStateMachineType_HighHigh;
- text = ConditionStateNames.HighHighActive;
- }
-
- if (AeTypeCache.IsKnownName(e.szSubconditionName, "HI"))
- {
- state = Opc.Ua.ObjectIds.ExclusiveLimitStateMachineType_High;
- text = ConditionStateNames.HighActive;
- }
-
- if (AeTypeCache.IsKnownName(e.szSubconditionName, "LO"))
- {
- state = Opc.Ua.ObjectIds.ExclusiveLimitStateMachineType_Low;
- text = ConditionStateNames.LowActive;
- }
-
- if (AeTypeCache.IsKnownName(e.szSubconditionName, "LO LO"))
- {
- state = Opc.Ua.ObjectIds.ExclusiveLimitStateMachineType_LowLow;
- text = ConditionStateNames.LowLowActive;
- }
-
- instance.LimitState = new ExclusiveLimitStateMachineState(instance);
- instance.LimitState.BrowseName = Opc.Ua.BrowseNames.LimitState;
- instance.LimitState.CurrentState = new FiniteStateVariableState(instance.LimitState);
- instance.LimitState.CurrentState.BrowseName = Opc.Ua.BrowseNames.CurrentState;
- instance.LimitState.CurrentState.Value = text;
-
- instance.LimitState.CurrentState.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Id, state, false);
- }
-
- ///
- /// Updates the non-exclusive limit event.
- ///
- private void UpdateNonExclusiveLimitAlarm(NonExclusiveLimitAlarmState instance, EventType eventType, ONEVENTSTRUCT e)
- {
- bool active = (e.wNewState & Constants.CONDITION_ACTIVE) != 0;
- TwoStateVariableState state = null;
-
- if (AeTypeCache.IsKnownName(e.szConditionName, "HI HI"))
- {
- instance.HighHighState = state = new TwoStateVariableState(instance);
- instance.HighHighState.BrowseName = Opc.Ua.BrowseNames.HighHighState;
- }
-
- else if (AeTypeCache.IsKnownName(e.szSubconditionName, "HI") || AeTypeCache.IsKnownName(e.szSubconditionName, "DV HI"))
- {
- instance.HighState = state = new TwoStateVariableState(instance);
- instance.HighState.BrowseName = Opc.Ua.BrowseNames.HighState;
- }
-
- else if (AeTypeCache.IsKnownName(e.szSubconditionName, "LO") || AeTypeCache.IsKnownName(e.szSubconditionName, "DV LO"))
- {
- instance.LowState = state = new TwoStateVariableState(instance);
- instance.LowState.BrowseName = Opc.Ua.BrowseNames.LowState;
- }
-
- else if (AeTypeCache.IsKnownName(e.szSubconditionName, "LO LO"))
- {
- instance.LowLowState = state = new TwoStateVariableState(instance);
- instance.LowLowState.BrowseName = Opc.Ua.BrowseNames.LowLowState;
- }
-
- if (state != null)
- {
- state.Value = new LocalizedText((active) ? ConditionStateNames.Active : ConditionStateNames.Inactive);
- state.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Id, active, false);
- }
- }
-
- ///
- /// Called when refresh events arrive from the server.
- ///
- /// The events.
- /// if set to true if the refresh is complete.
- public void OnRefresh(ONEVENTSTRUCT[] events, bool lastRefresh)
- {
- lock (m_callbackLock)
- {
- // check if refresh was abandoned.
- if (m_refreshEvents == null)
- {
- return;
- }
-
- // dispatch events.
- for (int ii = 0; ii < events.Length; ii++)
- {
- BaseEventState e = DispatchEvent(events[ii]);
-
- if (e != null)
- {
- m_refreshEvents.Add(e);
- }
- }
-
- // signal end of refresh.
- if (lastRefresh)
- {
- m_refreshComplete.Set();
- }
- }
- }
- #endregion
-
- #region Private Methods
- ///
- /// Refreshes all conditions.
- ///
- ///
- private bool Refresh()
- {
- string methodName = "IOPCEventSubscriptionMgt.Refresh";
-
- try
- {
- IOPCEventSubscriptionMgt server = BeginComCall(methodName, true);
- server.Refresh(m_callback.Cookie);
- return true;
- }
- catch (Exception e)
- {
- if (ComUtils.IsUnknownError(e, ResultIds.E_BUSY, ResultIds.E_NOTIMPL))
- {
- ComCallError(methodName, e);
- }
-
- return false;
- }
- finally
- {
- EndComCall(methodName);
- }
- }
-
- ///
- /// Cancels the refresh for all conditions.
- ///
- ///
- private bool CancelRefresh()
- {
- string methodName = "IOPCEventSubscriptionMgt.CancelRefresh";
-
- try
- {
- IOPCEventSubscriptionMgt server = BeginComCall(methodName, true);
- server.CancelRefresh(m_callback.Cookie);
- return true;
- }
- catch (Exception e)
- {
- if (ComUtils.IsUnknownError(e, ResultIds.E_FAIL, ResultIds.E_INVALIDARG, ResultIds.E_NOTIMPL))
- {
- ComCallError(methodName, e);
- }
-
- return false;
- }
- finally
- {
- EndComCall(methodName);
- }
- }
-
- ///
- /// Selects the returned attributes.
- ///
- /// The category id.
- /// The attribute ids.
- ///
- private bool SelectReturnedAttributes(int categoryId, int[] attributeIds)
- {
- string methodName = "IOPCEventSubscriptionMgt.SelectReturnedAttributes";
-
- try
- {
- IOPCEventSubscriptionMgt server = BeginComCall(methodName, true);
- server.SelectReturnedAttributes(categoryId, attributeIds.Length, attributeIds);
- return true;
- }
- catch (Exception e)
- {
- if (ComUtils.IsUnknownError(e, ResultIds.E_FAIL))
- {
- ComCallError(methodName, e);
- }
-
- return false;
- }
- finally
- {
- EndComCall(methodName);
- }
- }
-
- ///
- /// Sets the filter.
- ///
- /// Name of the qualified.
- /// if set to true if filtering by source.
- ///
- private bool SetFilter(string qualifiedName, bool isSource)
- {
- string methodName = "IOPCEventSubscriptionMgt.SetFilter";
-
- try
- {
- IOPCEventSubscriptionMgt server = BeginComCall(methodName, true);
-
- string[] filter = null;
-
- if (!String.IsNullOrEmpty(qualifiedName))
- {
- filter = new string[] { qualifiedName };
-
- // need to use a wild card to include sub-areas.
- if (!String.IsNullOrEmpty(m_separators))
- {
- filter = new string[m_separators.Length+1];
- filter[0] = qualifiedName;
-
- for (int ii = 0; ii < m_separators.Length; ii++)
- {
- filter[ii + 1] = Utils.Format("{0}{1}*", qualifiedName, m_separators[ii]);
- }
- }
- }
- else
- {
- filter = new string[0];
- }
-
- server.SetFilter(
- Constants.ALL_EVENTS,
- 0,
- new int[0],
- 1,
- 1000,
- (isSource)?0:filter.Length,
- filter,
- (!isSource)?0:filter.Length,
- filter);
-
- return true;
- }
- catch (Exception e)
- {
- if (ComUtils.IsUnknownError(e, ResultIds.E_FAIL))
- {
- ComCallError(methodName, e);
- }
-
- return false;
- }
- finally
- {
- EndComCall(methodName);
- }
- }
- #endregion
-
- #region Private Fields
- private ServerSystemContext m_defaultContext;
- private string m_separators;
- private AeTypeCache m_cache;
- private ushort m_namespaceIndex;
- private ComAeClientManager m_manager;
- private string m_qualifiedName;
- private bool m_isSource;
- private ComAeEventSink m_callback;
- private List m_monitoredItems;
- private object m_refreshLock = new object();
- private object m_callbackLock = new object();
- private ManualResetEvent m_refreshComplete;
- private List m_refreshEvents;
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/ComClient.cs b/ComIOP/Common/Client/ComClient.cs
deleted file mode 100644
index 62c5b4879..000000000
--- a/ComIOP/Common/Client/ComClient.cs
+++ /dev/null
@@ -1,315 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading;
-using System.IdentityModel.Selectors;
-using System.IdentityModel.Tokens;
-using System.Security.Principal;
-using OpcRcw.Comn;
-using OpcRcw.Da;
-using OpcRcw.Security;
-using Opc.Ua;
-using Opc.Ua.Com;
-using Opc.Ua.Com.Client;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// Provides access to a COM server.
- ///
- public class ComClient : ComObject
- {
- #region Constructors
- ///
- /// Initializes the object with the ProgID of the server being accessed.
- ///
- public ComClient(ComClientConfiguration configuration)
- {
- if (configuration == null) throw new ArgumentNullException("configuration");
- m_url = configuration.ServerUrl;
- }
- #endregion
-
- #region Public Methods
- ///
- /// A key that combines the user name and locale id.
- ///
- public string Key { get; set; }
-
- ///
- /// The locale id associated with the instance.
- ///
- public int LocaleId { get; set; }
-
- ///
- /// The user identity associated with the instance.
- ///
- public IUserIdentity UserIdentity { get; set; }
-
- ///
- /// Creates an instance of the COM server.
- ///
- public void CreateInstance()
- {
- // multiple calls are not allowed - may block for a while due to network operation.
- lock (m_lock)
- {
- ServerFactory factory = new ServerFactory();
-
- try
- {
- // create the server.
- Unknown = factory.CreateServer(new Uri(m_url), null);
-
- // set the locale.
- SetLocale(LocaleId);
-
- if (UserIdentity != null)
- {
- SetUserIdentity(UserIdentity);
- }
-
- // do any post-connect processing.
- OnConnected();
- }
- catch (Exception e)
- {
- ComUtils.TraceComError(e, "Could not connect to server ({0}).", m_url);
-
- // cleanup on error.
- Close();
- }
- finally
- {
- factory.Dispose();
- }
- }
- }
-
- ///
- /// Fetches the error string from the server.
- ///
- public string GetErrorString(int error)
- {
- string methodName = "IOPCCommon.GetErrorString";
-
- try
- {
- IOPCCommon server = BeginComCall(methodName, true);
- string ppString = null;
- server.GetErrorString(error, out ppString);
- return ppString;
- }
- catch (Exception e)
- {
- ComCallError(methodName, e);
- return null;
- }
- finally
- {
- EndComCall(methodName);
- }
- }
-
- ///
- /// Sets the current locale.
- ///
- public void SetLocale(int localeId)
- {
- string methodName = "IOPCCommon.SetLocaleID";
-
- try
- {
- IOPCCommon server = BeginComCall(methodName, true);
- server.SetLocaleID(localeId);
- }
- catch (Exception e)
- {
- ComCallError(methodName, e);
- }
- finally
- {
- EndComCall(methodName);
- }
- }
-
- ///
- /// Sets the current user identity.
- ///
- public void SetUserIdentity(IUserIdentity identity)
- {
- string methodName = "IOPCSecurityPrivate.Logon";
-
- try
- {
- IOPCSecurityPrivate server = BeginComCall(methodName, true);
-
- if (server != null)
- {
- int bAvailable = 0;
- server.IsAvailablePriv(out bAvailable);
-
- if (bAvailable != 0)
- {
- bool logoff = true;
-
- if (identity != null && identity.TokenType == UserTokenType.UserName)
- {
- UserNameIdentityToken identityToken = identity.GetIdentityToken() as UserNameIdentityToken;
-
- if (identityToken != null)
- {
- server.Logon(identityToken.UserName, identityToken.Password.ToString());
- logoff = false;
- }
- }
-
- if (logoff)
- {
- server.Logoff();
- }
- }
- }
- }
- catch (Exception e)
- {
- ComCallError(methodName, e);
- }
- finally
- {
- EndComCall(methodName);
- }
- }
-
- ///
- /// Fetches the available locales.
- ///
- public int[] QueryAvailableLocales()
- {
- string methodName = "IOPCCommon.QueryAvailableLocales";
-
- try
- {
- IOPCCommon server = BeginComCall(methodName, true);
-
- // query for available locales.
- int count = 0;
- IntPtr pLocaleIDs = IntPtr.Zero;
-
- server.QueryAvailableLocaleIDs(out count, out pLocaleIDs);
-
- // unmarshal results.
- return ComUtils.GetInt32s(ref pLocaleIDs, count, true);
- }
- catch (Exception e)
- {
- ComCallError(methodName, e);
- return null;
- }
- finally
- {
- EndComCall(methodName);
- }
- }
-
- ///
- /// Selects the best matching locale id.
- ///
- public static int SelectLocaleId(IList availableLocaleIds, IList preferredLocales)
- {
- // choose system default if no available locale ids.
- if (availableLocaleIds == null || availableLocaleIds.Count == 0)
- {
- return ComUtils.LOCALE_SYSTEM_DEFAULT;
- }
-
- // choose system default if no preferred locales.
- if (preferredLocales == null || preferredLocales.Count == 0)
- {
- return availableLocaleIds[0];
- }
-
- // look for an exact match.
- for (int ii = 0; ii < preferredLocales.Count; ii++)
- {
- for (int jj = 0; jj < availableLocaleIds.Count; jj++)
- {
- if (ComUtils.CompareLocales(availableLocaleIds[jj], preferredLocales[ii], false))
- {
- return availableLocaleIds[jj];
- }
- }
- }
-
- // look for a match on the language only.
- for (int ii = 0; ii < preferredLocales.Count; ii++)
- {
- for (int jj = 0; jj < availableLocaleIds.Count; jj++)
- {
- if (ComUtils.CompareLocales(availableLocaleIds[jj], preferredLocales[ii], true))
- {
- return availableLocaleIds[jj];
- }
- }
- }
-
- // return the first avialable locale.
- return availableLocaleIds[0];
- }
-
- ///
- /// Gracefully closes the connection to the server.
- ///
- public void Close()
- {
- Dispose();
- }
- #endregion
-
- #region Protected Members
- ///
- /// Called immediately after connecting to the server.
- ///
- protected virtual void OnConnected()
- {
- }
- #endregion
-
- #region Private Methods
- #endregion
-
- #region Private Fields
- private object m_lock = new object();
- private string m_url;
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/ComClientConfiguration.cs b/ComIOP/Common/Client/ComClientConfiguration.cs
deleted file mode 100644
index 2b6ebfeac..000000000
--- a/ComIOP/Common/Client/ComClientConfiguration.cs
+++ /dev/null
@@ -1,160 +0,0 @@
-/* ========================================================================
- * 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;
-using System.ServiceModel;
-using System.Runtime.Serialization;
-using System.Collections.Generic;
-using Opc.Ua.Server;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// Stores the configuration the data access node manager.
- ///
- [KnownType(typeof(ComDaClientConfiguration))]
- [KnownType(typeof(ComAeClientConfiguration))]
- [KnownType(typeof(ComHdaClientConfiguration))]
- [DataContract(Namespace = Namespaces.ComInterop)]
- public class ComClientConfiguration
- {
- #region Constructors
- ///
- /// The default constructor.
- ///
- public ComClientConfiguration()
- {
- Initialize();
- }
-
- ///
- /// Initializes the object during deserialization.
- ///
- [OnDeserializing()]
- private void Initialize(StreamingContext context)
- {
- Initialize();
- }
-
- ///
- /// Sets private members to default values.
- ///
- private void Initialize()
- {
- }
- #endregion
-
- #region Public Properties
- ///
- /// The URL of the COM server which has the form: opc.com://hostname/progid/clsid
- ///
- [DataMember(Order = 1)]
- public string ServerUrl { get; set; }
-
- ///
- /// The name for the server that will used for the root in the UA server address space.
- ///
- [DataMember(Order = 2)]
- public string ServerName { get; set; }
-
- ///
- /// The number of milliseconds to wait between reconnect attempts.
- ///
- [DataMember(Order = 3)]
- public int MaxReconnectWait { get; set; }
-
- ///
- /// A list of characters used in item ids to seperate elements.
- ///
- ///
- /// If specified the wrapper attempts to parse the item ids by looking for the one of these
- /// characters starting from the end of the item id. All text after this character is assumed
- /// to be the name of the item or branch.
- ///
- [DataMember(Order = 4)]
- public string SeperatorChars
- {
- get
- {
- return m_seperatorChars;
- }
-
- set
- {
- if (String.IsNullOrEmpty(value))
- {
- m_seperatorChars = String.Empty;
- return;
- }
-
- m_seperatorChars = value.Trim();
- }
- }
-
- ///
- /// A list of locales supported by the server that should made visible as locales for the UA server.
- ///
- [DataMember(Order = 5)]
- public StringCollection AvailableLocales { get; set; }
-
- ///
- /// Gets or sets the item id parser.
- ///
- /// The item id parser.
- public IItemIdParser ItemIdParser { get; set; }
- #endregion
-
- #region Private Members
- private string m_seperatorChars;
- #endregion
- }
-
- ///
- /// A collection of COM WrapperConfiguration objects.
- ///
- [CollectionDataContract(Name="ListOfComClientConfiguration", Namespace=Namespaces.ComInterop, ItemName="ComClientConfiguration")]
- public partial class ComClientConfigurationCollection : List
- {
- ///
- /// Initializes an empty collection.
- ///
- public ComClientConfigurationCollection() { }
-
- ///
- /// Initializes the collection with the specified capacity.
- ///
- public ComClientConfigurationCollection(int capacity) : base(capacity) { }
-
- ///
- /// Initializes the collection from another collection.
- ///
- /// A collection of used to pre-populate the collection.
- public ComClientConfigurationCollection(IEnumerable collection) : base(collection) { }
- }
-}
diff --git a/ComIOP/Common/Client/ComClientManager.cs b/ComIOP/Common/Client/ComClientManager.cs
deleted file mode 100644
index e538162e6..000000000
--- a/ComIOP/Common/Client/ComClientManager.cs
+++ /dev/null
@@ -1,388 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading;
-using Opc.Ua;
-using Opc.Ua.Server;
-using Opc.Ua.Com;
-using OpcRcw.Da;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// Manages the COM connections used by the UA server.
- ///
- public class ComClientManager : IDisposable
- {
- #region Constructors
- ///
- /// Initializes a new instance of the class.
- ///
- public ComClientManager()
- {
- }
- #endregion
-
- #region IDisposable Members
- ///
- /// Frees any unmanaged resources.
- ///
- public void Dispose()
- {
- Dispose(true);
- }
-
- ///
- /// An overrideable version of the Dispose.
- ///
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- Utils.SilentDispose(m_statusTimer);
- m_statusTimer = null;
-
- Utils.SilentDispose(m_defaultClient);
- m_defaultClient = null;
- }
- }
- #endregion
-
- #region Public Members
- ///
- /// Selects the COM client to use for the current context.
- ///
- /// The context.
- /// The whether to use the default context.
- /// A COM client instance.
- public virtual ComClient SelectClient(ServerSystemContext context, bool useDefault)
- {
- if (useDefault)
- {
- return DefaultClient;
- }
-
- return GetLocalizedClient(context.UserIdentity, context.PreferredLocales);
- }
-
- ///
- /// Initializes the manager by creating the default instance.
- ///
- public void Initialize(
- ServerSystemContext context,
- ComClientConfiguration configuration,
- ComServerStatusState statusNode,
- object statusNodeLock,
- WaitCallback reconnectCallback)
- {
- m_defaultSystemContext = context;
- m_configuration = configuration;
- m_statusNode = statusNode;
- m_statusNodeLock = statusNodeLock;
- m_statusUpdateInterval = m_configuration.MaxReconnectWait;
- m_reconnectCallback = reconnectCallback;
-
- // limit status updates to once per 10 seconds.
- if (m_statusUpdateInterval < 10000)
- {
- m_statusUpdateInterval = 10000;
- }
-
- StartStatusTimer(OnStatusTimerExpired);
- }
-
- ///
- /// Returns a localized client based on the preferred locales.
- ///
- /// The identity to use.
- /// The locales to use.
- /// A localized client.
- public ComClient GetLocalizedClient(IUserIdentity identity, IList preferredLocales)
- {
- return GetLocalizedClient(identity, ComClient.SelectLocaleId(AvailableLocaleIds, preferredLocales));
- }
-
- ///
- /// Returns a localized client for the specified locale id.
- ///
- /// The identity.
- /// The locales id.
- /// A localized client.
- public ComClient GetLocalizedClient(IUserIdentity identity, int localeId)
- {
- // check if a logon is required.
- string userName = null;
-
- if (identity != null && identity.TokenType == UserTokenType.UserName)
- {
- userName = (identity.GetIdentityToken() as UserNameIdentityToken).UserName;
- }
-
- if (String.IsNullOrEmpty(userName) && localeId == ComUtils.LOCALE_SYSTEM_DEFAULT)
- {
- Utils.Trace("COM Client Selected: DEFAULT (no match for locale)");
- return DefaultClient;
- }
-
- // create the key.
- StringBuilder buffer = new StringBuilder();
- buffer.Append(localeId);
-
- if (!String.IsNullOrEmpty(userName))
- {
- buffer.Append(':');
- buffer.Append(userName);
- }
-
- string key = buffer.ToString();
-
- if (m_localizedClients == null)
- {
- m_localizedClients = new Dictionary();
- }
-
- ComClient client = null;
-
- if (!m_localizedClients.TryGetValue(key, out client))
- {
- client = CreateClient();
- client.Key = key;
- client.LocaleId = localeId;
- client.UserIdentity = identity;
- client.CreateInstance();
- m_localizedClients[key] = client;
- }
-
- // Utils.Trace("COM Client Seleted: {0}", key);
- return client;
- }
- #endregion
-
- #region Protected Members
- ///
- /// Gets the default system context.
- ///
- /// The default system context.
- protected ServerSystemContext DefaultSystemContext
- {
- get { return m_defaultSystemContext; }
- }
-
- ///
- /// Gets the configuration.
- ///
- /// The configuration.
- protected ComClientConfiguration Configuration
- {
- get { return m_configuration; }
- }
-
- ///
- /// Gets or sets the default COM client instance.
- ///
- /// The default client.
- protected ComClient DefaultClient
- {
- get { return m_defaultClient; }
- set { m_defaultClient = value; }
- }
-
- ///
- /// The locale ids supported by the server.
- ///
- protected int[] AvailableLocaleIds { get; private set; }
-
- ///
- /// Gets the status node.
- ///
- /// The status node.
- protected ComServerStatusState StatusNode
- {
- get { return m_statusNode; }
- }
-
- ///
- /// Gets the synchronization object for the status node.
- ///
- /// The ynchronization object for the status node.
- protected object StatusNodeLock
- {
- get { return m_statusNodeLock; }
- }
-
- ///
- /// Starts the status timer.
- ///
- /// The callback to use when the timer expires.
- protected void StartStatusTimer(TimerCallback callback)
- {
- if (m_statusTimer != null)
- {
- m_statusTimer.Dispose();
- m_statusTimer = null;
- }
-
- m_statusTimer = new Timer(callback, null, 0, m_statusUpdateInterval);
- }
-
- ///
- /// Creates a new client object.
- ///
- protected virtual ComClient CreateClient()
- {
- return null;
- }
-
- ///
- /// Updates the status node.
- ///
- /// True if the update was successful.
- protected virtual bool UpdateStatus()
- {
- return false;
- }
- #endregion
-
- #region Private Methods
- ///
- /// Called when thes status timer expires.
- ///
- /// The state.
- private void OnStatusTimerExpired(object state)
- {
- try
- {
- // create the client if it has not already been created.
- if (m_defaultClient == null)
- {
- m_defaultClient = CreateClient();
- m_defaultClient.Key = String.Empty;
-
- // set default locale.
- if (AvailableLocaleIds != null && AvailableLocaleIds.Length > 0)
- {
- m_defaultClient.LocaleId = AvailableLocaleIds[0];
- }
- else
- {
- m_defaultClient.LocaleId = ComUtils.LOCALE_SYSTEM_DEFAULT;
- }
-
- m_defaultClient.CreateInstance();
- m_lastStatusUpdate = DateTime.UtcNow;
- }
-
- // check if the last status updates appear to be hanging.
- bool reconnected = false;
-
- if (m_lastStatusUpdate.AddMilliseconds(m_statusUpdateInterval*1.1) < DateTime.UtcNow)
- {
- if (m_reconnecting)
- {
- return;
- }
-
- m_reconnecting = true;
-
- try
- {
- Utils.Trace("Communication with COM server failed. Disposing server and reconnecting.");
-
- // dispose existing client in the background in case it blocks.
- ThreadPool.QueueUserWorkItem(OnDisposeClient, m_defaultClient);
-
- // dispose localized clients.
- if (m_localizedClients != null)
- {
- foreach (ComClient localizedClient in m_localizedClients.Values)
- {
- ThreadPool.QueueUserWorkItem(OnDisposeClient, localizedClient);
- }
-
- m_localizedClients.Clear();
- }
-
- // create a new client.
- m_defaultClient = CreateClient();
- m_defaultClient.CreateInstance();
-
- reconnected = true;
- }
- finally
- {
- m_reconnecting = false;
- }
- }
-
- // fetches the status from the server and updates the status node.
- if (UpdateStatus())
- {
- AvailableLocaleIds = m_defaultClient.QueryAvailableLocales();
- m_lastStatusUpdate = DateTime.UtcNow;
-
- if (reconnected && m_reconnectCallback != null)
- {
- m_reconnectCallback(this);
- }
- }
- }
- catch (Exception e)
- {
- ComUtils.TraceComError(e, "Error fetching status from the COM server.");
- }
- }
-
- ///
- /// Called when a misbehaving client object needs to be disposed.
- ///
- /// The client object.
- private void OnDisposeClient(object state)
- {
- Utils.SilentDispose(state);
- }
- #endregion
-
- #region Private Fields
- private ComClientConfiguration m_configuration;
- private ServerSystemContext m_defaultSystemContext;
- private ComServerStatusState m_statusNode;
- private object m_statusNodeLock;
- private ComClient m_defaultClient;
- private Timer m_statusTimer;
- private DateTime m_lastStatusUpdate;
- private int m_statusUpdateInterval;
- private WaitCallback m_reconnectCallback;
- private bool m_reconnecting;
- private Dictionary m_localizedClients;
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/ComClientNodeManager.cs b/ComIOP/Common/Client/ComClientNodeManager.cs
deleted file mode 100644
index c60271236..000000000
--- a/ComIOP/Common/Client/ComClientNodeManager.cs
+++ /dev/null
@@ -1,190 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using System.Text;
-using System.Diagnostics;
-using System.Xml;
-using System.IO;
-using System.Threading;
-using System.Reflection;
-using Opc.Ua;
-using Opc.Ua.Server;
-using Opc.Ua.Com;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// A node manager for a server that exposes several variables.
- ///
- public class ComClientNodeManager : CustomNodeManager2
- {
- #region Constructors
- ///
- /// Initializes the node manager.
- ///
- public ComClientNodeManager(IServerInternal server, string namespaceUri, bool ownsTypeModel)
- :
- base(server)
- {
- // check if this node manager owns the COM Interop type model.
- if (ownsTypeModel)
- {
- SetNamespaces(namespaceUri, Namespaces.ComInterop);
- }
- else
- {
- SetNamespaces(namespaceUri);
- }
- }
- #endregion
-
- #region IDisposable Members
- ///
- /// An overrideable version of the Dispose.
- ///
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- Utils.SilentDispose(m_metadataUpdateTimer);
- m_metadataUpdateTimer = null;
- }
-
- base.Dispose(disposing);
- }
- #endregion
-
- #region Protected Methods
- ///
- /// Updates the type cache.
- ///
- protected void StartMetadataUpdates(WaitCallback callback, object callbackData, int initialDelay, int period)
- {
- lock (Lock)
- {
- if (m_metadataUpdateTimer != null)
- {
- m_metadataUpdateTimer.Dispose();
- m_metadataUpdateTimer = null;
- }
-
- m_metadataUpdateCallback = callback;
- m_metadataUpdateTimer = new Timer(DoMetadataUpdate, callbackData, initialDelay, period);
- }
- }
- #endregion
-
- #region Private Methods
- ///
- /// Updates the metadata cached for the server.
- ///
- private void DoMetadataUpdate(object state)
- {
- try
- {
- if (!Server.IsRunning)
- {
- return;
- }
-
- ComClientManager system = (ComClientManager)SystemContext.SystemHandle;
- ComClient client = (ComClient)system.SelectClient(SystemContext, true);
-
- int[] availableLocales = client.QueryAvailableLocales();
-
- if (availableLocales != null)
- {
- lock (Server.DiagnosticsLock)
- {
- // check if the server is running.
- if (!Server.IsRunning)
- {
- return;
- }
-
- // get the LocaleIdArray property.
- BaseVariableState localeArray = Server.DiagnosticsNodeManager.Find(Opc.Ua.VariableIds.Server_ServerCapabilities_LocaleIdArray) as BaseVariableState;
-
- List locales = new List();
-
- // preserve any existing locales.
- string[] existingLocales = localeArray.Value as string[];
-
- if (existingLocales != null)
- {
- locales.AddRange(existingLocales);
- }
-
- for (int ii = 0; ii < availableLocales.Length; ii++)
- {
- if (availableLocales[ii] == 0 || availableLocales[ii] == ComUtils.LOCALE_SYSTEM_DEFAULT || availableLocales[ii] == ComUtils.LOCALE_USER_DEFAULT)
- {
- continue;
- }
-
- try
- {
- System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.GetCultureInfo(availableLocales[ii]);
-
- if (!locales.Contains(culture.Name))
- {
- locales.Add(culture.Name);
- }
- }
- catch (Exception e)
- {
- Utils.Trace(e, "Can't process an invalid locale id: {0:X4}.", availableLocales[ii]);
- }
- }
-
- localeArray.Value = locales.ToArray();
- }
- }
-
- // invoke callback.
- if (m_metadataUpdateCallback != null)
- {
- m_metadataUpdateCallback(state);
- }
- }
- catch (Exception e)
- {
- Utils.Trace(e, "Unexpected error updating HDA server metadata.");
- }
- }
- #endregion
-
- #region Private Fields
- private Timer m_metadataUpdateTimer;
- private WaitCallback m_metadataUpdateCallback;
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/ComConnectionPoint.cs b/ComIOP/Common/Client/ComConnectionPoint.cs
deleted file mode 100644
index 9ccba429c..000000000
--- a/ComIOP/Common/Client/ComConnectionPoint.cs
+++ /dev/null
@@ -1,140 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Runtime.InteropServices;
-using OpcRcw.Comn;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// Manages a connection point with a COM server.
- ///
- public class ConnectionPoint : IDisposable
- {
- #region Constructors
- ///
- /// Initializes the object by finding the specified connection point.
- ///
- public ConnectionPoint(object server, Guid iid)
- {
- OpcRcw.Comn.IConnectionPointContainer cpc = server as OpcRcw.Comn.IConnectionPointContainer;
-
- if (cpc == null)
- {
- throw ServiceResultException.Create(StatusCodes.BadCommunicationError, "Server does not support the IConnectionPointContainer interface.");
- }
-
- cpc.FindConnectionPoint(ref iid, out m_server);
- }
-
- ///
- /// Sets private members to default values.
- ///
- private void Initialize()
- {
- m_server = null;
- m_cookie = 0;
- m_refs = 0;
- }
- #endregion
-
- #region IDisposable Members
- ///
- /// The finializer implementation.
- ///
- ~ConnectionPoint()
- {
- Dispose(false);
- }
-
- ///
- /// Frees any unmanaged resources.
- ///
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- ///
- /// An overrideable version of the Dispose.
- ///
- protected virtual void Dispose(bool disposing)
- {
- object server = System.Threading.Interlocked.Exchange(ref m_server, null);
-
- if (server != null)
- {
- ComUtils.ReleaseServer(server);
- }
- }
- #endregion
-
- #region Public Properties
- ///
- /// The cookie returned by the server.
- ///
- public int Cookie
- {
- get { return m_cookie; }
- }
- #endregion
-
- #region IConnectionPoint Members
- ///
- /// Establishes a connection, if necessary and increments the reference count.
- ///
- public int Advise(object callback)
- {
- if (m_refs++ == 0)
- {
- m_server.Advise(callback, out m_cookie);
- }
-
- return m_refs;
- }
-
- ///
- /// Decrements the reference count and closes the connection if no more references.
- ///
- public int Unadvise()
- {
- if (--m_refs == 0) m_server.Unadvise(m_cookie);
- return m_refs;
- }
- #endregion
-
- #region Private Members
- private OpcRcw.Comn.IConnectionPoint m_server;
- private int m_cookie;
- private int m_refs;
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/ComEnumString.cs b/ComIOP/Common/Client/ComEnumString.cs
deleted file mode 100644
index a3e8e8810..000000000
--- a/ComIOP/Common/Client/ComEnumString.cs
+++ /dev/null
@@ -1,257 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Runtime.InteropServices;
-using OpcRcw.Comn;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// A wrapper for the COM IEnumString interface.
- ///
- public class EnumString : IDisposable
- {
- #region Constructors
- ///
- /// Initializes the object with an enumerator.
- ///
- public EnumString(object enumerator, int bufferLength)
- {
- m_enumerator = enumerator as IEnumString;
-
- if (m_enumerator == null)
- {
- throw new ArgumentNullException("enumerator", "Object does not support IEnumString interface.");
- }
-
- m_buffer = new string[bufferLength];
- m_position = 0;
- m_fetched = 0;
- }
- #endregion
-
- #region IDisposable Members
- ///
- /// The finializer implementation.
- ///
- ~EnumString()
- {
- Dispose(false);
- }
-
- ///
- /// Frees any unmanaged resources.
- ///
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- ///
- /// An overrideable version of the Dispose.
- ///
- protected virtual void Dispose(bool disposing)
- {
- object enumerator = System.Threading.Interlocked.Exchange(ref m_enumerator, null);
-
- if (enumerator != null)
- {
- ComUtils.ReleaseServer(enumerator);
- }
- }
- #endregion
-
- #region IEnumString Members
- ///
- /// Fetches the next string (returns null if no more data).
- ///
- public string Next()
- {
- // return null if at end of list.
- if (m_fetched == -1)
- {
- return null;
- }
-
- // see if next item is available.
- if (m_position < m_fetched)
- {
- return m_buffer[m_position++];
- }
-
- m_position = 0;
-
- try
- {
- // fetch next batch.
- m_fetched = 0;
-
- IntPtr pBuffer = Marshal.AllocCoTaskMem(IntPtr.Size*m_buffer.Length);
-
- try
- {
- int error = m_enumerator.RemoteNext(m_buffer.Length, pBuffer, out m_fetched);
-
- if (error < 0 || m_fetched == 0)
- {
- return null;
- }
-
- IntPtr[] pStrings = new IntPtr[m_fetched];
- Marshal.Copy(pBuffer, pStrings, 0, m_fetched);
-
- for (int ii = 0; ii < m_fetched; ii++)
- {
- m_buffer[ii] = Marshal.PtrToStringUni(pStrings[ii]);
- Marshal.FreeCoTaskMem(pStrings[ii]);
- }
- }
- finally
- {
- Marshal.FreeCoTaskMem(pBuffer);
- }
-
- // check if end of list.
- if (m_fetched == 0)
- {
- m_fetched = -1;
- return null;
- }
-
- // return first item.
- return m_buffer[m_position++];
- }
- catch (Exception e)
- {
- if (ComUtils.IsUnknownError(e, ResultIds.E_FAIL))
- {
- throw ComUtils.CreateException(e, "IEnumString.RemoteNext");
- }
-
- // some (incorrect) implementations return E_FAIL at the end of the list.
- m_fetched = -1;
- return null;
- }
- }
-
- ///
- /// Fetches the next group of strings.
- ///
- public int Next(string[] buffer, int count)
- {
- // can't use simple interface after calling this method.
- m_fetched = -1;
-
- try
- {
- int fetched = 0;
-
- IntPtr pBuffer = Marshal.AllocCoTaskMem(IntPtr.Size*count);
-
- try
- {
- int error = m_enumerator.RemoteNext(
- count,
- pBuffer,
- out fetched);
-
- if (error >= 0 && fetched > 0)
- {
- IntPtr[] pStrings = new IntPtr[m_fetched];
- Marshal.Copy(pBuffer, pStrings, 0, fetched);
-
- for (int ii = 0; ii < fetched; ii++)
- {
- m_buffer[ii] = Marshal.PtrToStringUni(pStrings[ii]);
- Marshal.FreeCoTaskMem(pStrings[ii]);
- }
- }
-
- return fetched;
- }
- finally
- {
- Marshal.FreeCoTaskMem(pBuffer);
- }
- }
- catch (Exception e)
- {
- // some (incorrect) implementations return E_FAIL at the end of the list.
- if (Marshal.GetHRForException(e) == ResultIds.E_FAIL)
- {
- return 0;
- }
-
- throw ComUtils.CreateException(e, "IEnumString.RemoteNext");
- }
- }
-
- ///
- /// Skips a number of strings.
- ///
- public void Skip(int count)
- {
- m_enumerator.Skip(count);
-
- // can't use simple interface after calling this method.
- m_fetched = -1;
- }
-
- ///
- /// Sets pointer to the start of the list.
- ///
- public void Reset()
- {
- m_enumerator.Reset();
-
- // can't use simple interface after calling this method.
- m_fetched = -1;
- }
-
- ///
- /// Clones the enumerator.
- ///
- public EnumString Clone()
- {
- IEnumString enumerator = null;
- m_enumerator.Clone(out enumerator);
- return new EnumString(enumerator, m_buffer.Length);
- }
- #endregion
-
- #region Private Members
- private OpcRcw.Comn.IEnumString m_enumerator;
- private string[] m_buffer;
- private int m_position;
- private int m_fetched;
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/ComItemIdParser.cs b/ComIOP/Common/Client/ComItemIdParser.cs
deleted file mode 100644
index 2785cc794..000000000
--- a/ComIOP/Common/Client/ComItemIdParser.cs
+++ /dev/null
@@ -1,107 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using System.Text;
-using System.Diagnostics;
-using System.Xml;
-using System.IO;
-using System.Threading;
-using System.Reflection;
-using Opc.Ua;
-using Opc.Ua.Server;
-using Opc.Ua.Com;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// An interface to an object that parses item ids.
- ///
- public interface IItemIdParser
- {
- ///
- /// Parses the specified item id.
- ///
- /// The COM server that provided the item id.
- /// The COM wrapper configuration.
- /// The item id to parse.
- /// The name of the item.
- /// True if the item id could be parsed.
- bool Parse(
- ComObject server,
- ComClientConfiguration configuration,
- string itemId,
- out string browseName);
- }
-
- ///
- /// The default item id parser that uses the settings in the configuration.
- ///
- public class ComItemIdParser : IItemIdParser
- {
- #region IItemIdParser Members
- ///
- /// Parses the specified item id.
- ///
- /// The COM server that provided the item id.
- /// The COM wrapper configuration.
- /// The item id to parse.
- /// The name of the item.
- /// True if the item id could be parsed.
- public bool Parse(ComObject server, ComClientConfiguration configuration, string itemId, out string browseName)
- {
- browseName = null;
-
- if (configuration == null || itemId == null)
- {
- return false;
- }
-
- if (String.IsNullOrEmpty(configuration.SeperatorChars))
- {
- return false;
- }
-
- for (int ii = 0; ii < configuration.SeperatorChars.Length; ii++)
- {
- int index = itemId.LastIndexOf(configuration.SeperatorChars[ii]);
-
- if (index >= 0)
- {
- browseName = itemId.Substring(index + 1);
- return true;
- }
- }
-
- return false;
- }
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/ComObject.cs b/ComIOP/Common/Client/ComObject.cs
deleted file mode 100644
index 9c9efb7c1..000000000
--- a/ComIOP/Common/Client/ComObject.cs
+++ /dev/null
@@ -1,226 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using System.Text;
-using System.Globalization;
-using System.Security.Principal;
-using System.Threading;
-using System.Runtime.InteropServices;
-using Opc.Ua;
-using Opc.Ua.Server;
-using Opc.Ua.Com;
-using OpcRcw.Da;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// A base class for COM server wrappers.
- ///
- public class ComObject : IDisposable
- {
- #region IDisposable Members
- ///
- /// The finializer implementation.
- ///
- ~ComObject()
- {
- Dispose(false);
- }
-
- ///
- /// Frees any unmanaged resources.
- ///
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- ///
- /// An overrideable version of the Dispose.
- ///
- protected virtual void Dispose(bool disposing)
- {
- // release references to the server during garbage collection.
- if (!disposing)
- {
- ReleaseServer();
- }
-
- // clean up managed objects if
- if (disposing)
- {
- lock (m_lock)
- {
- m_disposed = true;
-
- // only release server if there are no outstanding calls.
- // if it is not released here it will be released when the last call completes.
- if (m_outstandingCalls <= 0)
- {
- ReleaseServer();
- }
- }
- }
- }
- #endregion
-
- #region Public Properties
- ///
- /// Gets an object which is used to synchronize access to the COM object.
- ///
- /// An object which is used to synchronize access to the COM object.
- public object Lock
- {
- get { return m_lock; }
- }
-
- ///
- /// Gets a value indicating whether this is disposed.
- ///
- /// true if disposed; otherwise, false.
- public bool Disposed
- {
- get { return m_disposed; }
- }
-
- ///
- /// Gets or sets the COM server.
- ///
- /// The COM server.
- public object Unknown
- {
- get { return m_unknown; }
- set { m_unknown = value; }
- }
- #endregion
-
- #region Protected Members
- ///
- /// Releases all references to the server.
- ///
- protected virtual void ReleaseServer()
- {
- lock (m_lock)
- {
- ComUtils.ReleaseServer(m_unknown);
- m_unknown = null;
- }
- }
-
- ///
- /// Checks if the server supports the specified interface.
- ///
- /// The interface to check.
- /// True if the server supports the interface.
- protected bool SupportsInterface() where T : class
- {
- lock (m_lock)
- {
- return m_unknown is T;
- }
- }
-
- ///
- /// Must be called before any COM call.
- ///
- /// The interface to used when making the call.
- /// Name of the method.
- /// if set to true an exception is thrown on error.
- ///
- protected T BeginComCall(string methodName, bool throwOnError) where T : class
- {
- Utils.Trace(Utils.TraceMasks.ExternalSystem, "{0} called.", methodName);
-
- lock (m_lock)
- {
- m_outstandingCalls++;
-
- if (m_disposed)
- {
- if (throwOnError)
- {
- throw new ObjectDisposedException("The COM server has been disposed.");
- }
-
- return null;
- }
-
- T server = m_unknown as T;
-
- if (throwOnError && server == null)
- {
- throw new NotSupportedException(Utils.Format("COM interface '{0}' is not supported by server.", typeof(T).Name));
- }
-
- return server;
- }
- }
-
- ///
- /// Must called if a COM call returns an unexpected exception.
- ///
- /// Name of the method.
- /// The exception.
- /// Note that some COM calls are expected to return errors.
- protected void ComCallError(string methodName, Exception e)
- {
- ComUtils.TraceComError(e, methodName);
- }
-
- ///
- /// Must be called in the finally block after making a COM call.
- ///
- /// Name of the method.
- protected void EndComCall(string methodName)
- {
- Utils.Trace(Utils.TraceMasks.ExternalSystem, "{0} completed.", methodName);
-
- lock (m_lock)
- {
- m_outstandingCalls--;
-
- if (m_disposed && m_outstandingCalls <= 0)
- {
- ComUtils.ReleaseServer(m_unknown);
- }
- }
- }
- #endregion
-
- #region Private Fields
- private object m_lock = new object();
- private int m_outstandingCalls;
- private bool m_disposed;
- private object m_unknown;
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/ComShutdownCallback.cs b/ComIOP/Common/Client/ComShutdownCallback.cs
deleted file mode 100644
index 0084ccdaf..000000000
--- a/ComIOP/Common/Client/ComShutdownCallback.cs
+++ /dev/null
@@ -1,117 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// A class that implements the IOPCShutdown interface.
- ///
- public class ShutdownCallback : OpcRcw.Comn.IOPCShutdown, IDisposable
- {
- #region Constructors
- ///
- /// Initializes the object with the containing subscription object.
- ///
- public ShutdownCallback(object server, ServerShutdownEventHandler handler)
- {
- try
- {
- m_server = server;
- m_handler = handler;
-
- // create connection point.
- m_connectionPoint = new ConnectionPoint(server, typeof(OpcRcw.Comn.IOPCShutdown).GUID);
-
- // advise.
- m_connectionPoint.Advise(this);
- }
- catch (Exception e)
- {
- throw new ServiceResultException(e, StatusCodes.BadOutOfService);
- }
- }
- #endregion
-
- #region IDisposable Members
- ///
- /// Frees any unmanaged resources.
- ///
- public void Dispose()
- {
- Dispose(true);
- }
-
- ///
- /// An overrideable version of the Dispose.
- ///
- protected virtual void Dispose(bool disposing)
- {
- if (m_connectionPoint != null)
- {
- m_connectionPoint.Dispose();
- m_connectionPoint = null;
- }
- }
- #endregion
-
- #region IOPCShutdown Members
- ///
- /// Called when a data changed event is received.
- ///
- public void ShutdownRequest(string szReason)
- {
- try
- {
- if (m_handler != null)
- {
- m_handler(m_server, szReason);
- }
- }
- catch (Exception e)
- {
- Utils.Trace(e, "Unexpected error processing callback.");
- }
- }
- #endregion
-
- #region Private Members
- private object m_server;
- private ServerShutdownEventHandler m_handler;
- private ConnectionPoint m_connectionPoint;
- #endregion
- }
-
- ///
- /// A delegate used to receive server shutdown events.
- ///
- public delegate void ServerShutdownEventHandler(object sender, string reason);
-}
diff --git a/ComIOP/Common/Client/ComWrapperServer.cs b/ComIOP/Common/Client/ComWrapperServer.cs
deleted file mode 100644
index 91c4bd6e8..000000000
--- a/ComIOP/Common/Client/ComWrapperServer.cs
+++ /dev/null
@@ -1,322 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using System.Globalization;
-using Opc.Ua.Server;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// Implements a basic UA Data Access Server.
- ///
- ///
- /// Each server instance must have one instance of a StandardServer object which is
- /// responsible for reading the configuration file, creating the endpoints and dispatching
- /// incoming requests to the appropriate handler.
- ///
- /// This sub-class specifies non-configurable metadata such as Product Name and initializes
- /// the DataAccessServerNodeManager which provides access to the data exposed by the Server.
- ///
- public partial class ComWrapperServer : ReverseConnectServer
- {
- #region Public Interface
- ///
- /// Returns the current server instance.
- ///
- public IServerInternal ServerInstance
- {
- get { return this.ServerInternal; }
- }
-
- ///
- /// Returns the UserNameValidator.
- ///
- public UserNameValidator UserNameValidator
- {
- get { return m_userNameValidator; }
- }
-
- #endregion
-
- #region Overridden Methods
- ///
- /// Creates the node managers for the server.
- ///
- ///
- /// This method allows the sub-class create any additional node managers which it uses. The SDK
- /// always creates a CoreNodeManager which handles the built-in nodes defined by the specification.
- /// Any additional NodeManagers are expected to handle application specific nodes.
- ///
- protected override MasterNodeManager CreateMasterNodeManager(IServerInternal server, ApplicationConfiguration configuration)
- {
- List nodeManagers = new List();
- m_availableLocales = new List();
-
- // get the configuration for the wrapper.
- ComWrapperServerConfiguration wrapperConfiguration = configuration.ParseExtension();
-
- if (wrapperConfiguration != null && wrapperConfiguration.WrappedServers != null)
- {
- // create a new node manager for each wrapped COM server.
- bool loadTypeModel = true;
- Dictionary namespaceUris = new Dictionary();
-
- foreach (ComClientConfiguration clientConfiguration in wrapperConfiguration.WrappedServers)
- {
- // add the available locales.
- if (clientConfiguration.AvailableLocales != null && clientConfiguration.AvailableLocales.Count > 0)
- {
- foreach (string locale in clientConfiguration.AvailableLocales)
- {
- try
- {
- CultureInfo culture = CultureInfo.GetCultureInfo(locale);
-
- if (!m_availableLocales.Contains(culture.Name))
- {
- m_availableLocales.Add(culture.Name);
- }
- }
- catch (Exception e)
- {
- Utils.Trace(e, "Can't process an invalid locale: {0}.", locale);
- }
- }
- }
-
- string namespaceUri = clientConfiguration.ServerUrl;
-
- if (clientConfiguration is ComDaClientConfiguration)
- {
- namespaceUri += "/DA";
-
- if (namespaceUris.ContainsKey(namespaceUri))
- {
- Utils.Trace("COM server has already been wrapped {0}.", namespaceUri);
- continue;
- }
-
- namespaceUris.Add(namespaceUri, clientConfiguration);
-
- ComDaClientNodeManager manager = new ComDaClientNodeManager(
- server,
- namespaceUri,
- (ComDaClientConfiguration)clientConfiguration,
- loadTypeModel);
-
- nodeManagers.Add(manager);
- loadTypeModel = false;
- continue;
- }
-
- if (clientConfiguration is ComAeClientConfiguration)
- {
- namespaceUri += "/AE";
-
- if (namespaceUris.ContainsKey(namespaceUri))
- {
- Utils.Trace("COM server has already been wrapped {0}.", namespaceUri);
- continue;
- }
-
- namespaceUris.Add(namespaceUri, clientConfiguration);
-
- ComAeClientNodeManager manager = new ComAeClientNodeManager(
- server,
- namespaceUri,
- (ComAeClientConfiguration)clientConfiguration,
- loadTypeModel);
-
- nodeManagers.Add(manager);
- loadTypeModel = false;
- continue;
- }
-
- if (clientConfiguration is ComHdaClientConfiguration)
- {
- namespaceUri += "/HDA";
-
- if (namespaceUris.ContainsKey(namespaceUri))
- {
- Utils.Trace("COM server has already been wrapped {0}.", namespaceUri);
- continue;
- }
-
- namespaceUris.Add(namespaceUri, clientConfiguration);
-
- ComHdaClientNodeManager manager = new ComHdaClientNodeManager(
- server,
- namespaceUri,
- (ComHdaClientConfiguration)clientConfiguration,
- loadTypeModel);
-
- nodeManagers.Add(manager);
- loadTypeModel = false;
- continue;
- }
- }
- }
-
- // create master node manager.
- return new MasterNodeManager(server, configuration, null, nodeManagers.ToArray());
- }
-
- ///
- /// Loads the non-configurable properties for the application.
- ///
- ///
- /// These properties are exposed by the server but cannot be changed by administrators.
- ///
- protected override ServerProperties LoadServerProperties()
- {
- ServerProperties properties = new ServerProperties();
-
- properties.ManufacturerName = "OPC Foundation";
- properties.ProductName = "OPC UA Quickstarts";
- properties.ProductUri = "http://opcfoundation.org/Quickstarts/ComDataAccessServer/v1.0";
- properties.SoftwareVersion = Utils.GetAssemblySoftwareVersion();
- properties.BuildNumber = Utils.GetAssemblyBuildNumber();
- properties.BuildDate = Utils.GetAssemblyTimestamp();
-
- // TBD - All applications have software certificates that need to added to the properties.
-
- return properties;
- }
-
- ///
- /// Called after the node managers have started.
- ///
- protected override void OnNodeManagerStarted(IServerInternal server)
- {
- // check if wrapped server locales need to be added to the UA server locale list.
- if (m_availableLocales != null && m_availableLocales.Count > 0)
- {
- lock (ServerInstance.DiagnosticsNodeManager.Lock)
- {
- // get the LocaleIdArray property.
- BaseVariableState variable = ServerInstance.DiagnosticsNodeManager.Find(Opc.Ua.VariableIds.Server_ServerCapabilities_LocaleIdArray) as BaseVariableState;
-
- if (variable != null)
- {
- List locales = new List();
-
- // preserve any existing locales.
- string[] existingLocales = variable.Value as string[];
-
- if (existingLocales != null)
- {
- locales.AddRange(existingLocales);
- }
-
- // add locales from the wrapped servers.
- foreach (string availableLocale in m_availableLocales)
- {
- if (!locales.Contains(availableLocale))
- {
- locales.Add(availableLocale);
- }
- }
-
- // update the locale array.
- variable.Value = locales.ToArray();
- }
- }
- }
-
- m_userNameValidator = new UserNameValidator(Configuration.ApplicationName);
-
- base.OnNodeManagerStarted(server);
- }
-
- ///
- /// Handles an error when validating the application instance certificate provided by a client.
- ///
- /// The client certificate.
- /// The result.
- protected override void OnApplicationCertificateError(byte[] clientCertificate, ServiceResult result)
- {
- throw new ServiceResultException(new ServiceResult(StatusCodes.BadCertificateUriInvalid));
- }
-
- ///
- /// Called after the server has been started.
- ///
- /// The server.
- protected override void OnServerStarted(IServerInternal server)
- {
- base.OnServerStarted(server);
- // verify session
- this.ServerInstance.SessionManager.ImpersonateUser += SessionManager_ImpersonateUser;
- }
-
- ///
- /// Check whether it is an acceptable session.
- ///
- /// The session.
- /// IdentityToken.
- void SessionManager_ImpersonateUser(Session session, ImpersonateEventArgs args)
- {
- switch (args.UserTokenPolicy.TokenType)
- {
- case UserTokenType.UserName:
-
- UserNameIdentityToken token = args.NewIdentity as UserNameIdentityToken;
-
- if (!m_userNameValidator.Validate(token))
- { // Bad user access denied.
- // construct translation object with default text.
- TranslationInfo info = new TranslationInfo(
- "InvalidUserInformation",
- "en-US",
- "Specified user information are not valid. UserName='{0}'.",
- token.UserName);
-
- // create an exception with a vendor defined sub-code.
- throw new ServiceResultException(new ServiceResult(
- StatusCodes.BadUserAccessDenied,
- "InvalidUserInformation",
- "http://opcfoundation.org",
- new LocalizedText(info)));
- }
- break;
- default:
- break;
- }
- }
-
- #endregion
-
- #region Private Fields
- private List m_availableLocales;
- private UserNameValidator m_userNameValidator;
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/ComWrapperServerConfiguration.cs b/ComIOP/Common/Client/ComWrapperServerConfiguration.cs
deleted file mode 100644
index d851c499f..000000000
--- a/ComIOP/Common/Client/ComWrapperServerConfiguration.cs
+++ /dev/null
@@ -1,86 +0,0 @@
-/* ========================================================================
- * 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;
-using System.ServiceModel;
-using System.Runtime.Serialization;
-using System.Collections.Generic;
-using Opc.Ua.Server;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// Stores the configuration for UA that wraps a COM server.
- ///
- [DataContract(Namespace = Namespaces.ComInterop)]
- public class ComWrapperServerConfiguration
- {
- #region Constructors
- ///
- /// The default constructor.
- ///
- public ComWrapperServerConfiguration()
- {
- Initialize();
- }
-
- ///
- /// Initializes the object during deserialization.
- ///
- [OnDeserializing()]
- private void Initialize(StreamingContext context)
- {
- Initialize();
- }
-
- ///
- /// Sets private members to default values.
- ///
- private void Initialize()
- {
- }
- #endregion
-
- #region Public Properties
- ///
- /// The list of COM servers wrapped by the UA server.
- ///
- [DataMember(Order=1)]
- public ComClientConfigurationCollection WrappedServers
- {
- get { return m_wrappedServers; }
- set { m_wrappedServers = value; }
- }
- #endregion
-
- #region Private Members
- private ComClientConfigurationCollection m_wrappedServers;
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/Da/ComDaClient.cs b/ComIOP/Common/Client/Da/ComDaClient.cs
deleted file mode 100644
index 677d475e7..000000000
--- a/ComIOP/Common/Client/Da/ComDaClient.cs
+++ /dev/null
@@ -1,1864 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using System.Text;
-using System.Runtime.InteropServices;
-using OpcRcw.Comn;
-using OpcRcw.Da;
-using Opc.Ua;
-using Opc.Ua.Server;
-using Opc.Ua.Com;
-using Opc.Ua.Com.Client;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// Provides access to a COM DA server.
- ///
- public class ComDaClient : ComClient
- {
- #region Constructors
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- public ComDaClient(ComDaClientConfiguration configuration) : base(configuration)
- {
- m_cache = new Dictionary();
- m_configuration = configuration;
- }
- #endregion
-
- #region Public Methods
- ///
- /// Finds the branch or item.
- ///
- /// The item id.
- /// The metadata for the branch.
- public DaElement FindElement(string itemId)
- {
- if (String.IsNullOrEmpty(itemId))
- {
- return null;
- }
-
- // check the cache.
- DaElement element = null;
-
- lock (m_cache)
- {
- if (m_cache.TryGetValue(itemId, out element))
- {
- return element;
- }
- }
-
- // try extracting the name by parsing the item id.
- string name = null;
-
- if (m_configuration.ItemIdParser.Parse(this, m_configuration, itemId, out name))
- {
- element = CreateElement(itemId, name, null);
- }
-
- // need to do it the hard way by searching the address space.
- else
- {
- IDaElementBrowser browser = CreateBrowser(itemId);
- element = browser.Find(itemId, false);
- browser.Dispose();
- }
-
- // save element in the cache.
- if (element != null)
- {
- SaveElementInCache(element);
- }
-
- return element;
- }
-
- ///
- /// Finds the property metadata for the specified item id.
- ///
- /// The item id.
- /// The property id.
- /// The metadata for the property.
- public DaProperty FindProperty(string itemId, int propertyId)
- {
- if (String.IsNullOrEmpty(itemId))
- {
- return null;
- }
-
- // check the cache.
- DaElement element = null;
-
- lock (m_cache)
- {
- if (m_cache.TryGetValue(itemId, out element))
- {
- if (element.Properties != null)
- {
- for (int ii = 0; ii < element.Properties.Length; ii++)
- {
- if (element.Properties[ii].PropertyId == propertyId)
- {
- return element.Properties[ii];
- }
- }
- }
- }
- }
-
- // check if the element has to be loaded.
- if (element == null)
- {
- element = FindElement(itemId);
-
- if (element == null)
- {
- return null;
- }
- }
-
- // update the property list.
- element.Properties = ReadAvailableProperties(itemId, false);
-
- if (element.Properties != null)
- {
- for (int ii = 0; ii < element.Properties.Length; ii++)
- {
- if (element.Properties[ii].PropertyId == propertyId)
- {
- return element.Properties[ii];
- }
- }
- }
-
- // not found.
- return null;
- }
-
- ///
- /// Finds the item id for the parent of the element.
- ///
- /// The item id.
- /// The item id for the parent of the element.
- public string FindElementParentId(string itemId)
- {
- if (String.IsNullOrEmpty(itemId))
- {
- return null;
- }
-
- // check in cache.
- DaElement element = null;
-
- lock (m_cache)
- {
- if (m_cache.TryGetValue(itemId, out element))
- {
- if (element.ParentId != null)
- {
- return element.ParentId;
- }
- }
- }
-
- // check if the element is a branch.
- if (!ChangeBrowsePosition(OPCBROWSEDIRECTION.OPC_BROWSE_TO, itemId))
- {
- return null;
- }
-
- // need to fetch list of branches to search.
- EnumString enumerator = CreateEnumerator(true);
-
- if (enumerator == null)
- {
- return null;
- }
-
- // find the child with the same item id.
- try
- {
- // process all branches.
- string name = null;
-
- do
- {
- name = enumerator.Next();
-
- // a null indicates the end of list.
- if (name == null)
- {
- break;
- }
-
- // fetch the item id.
- string targetId = GetItemId(name);
-
- // check if target found.
- if (targetId == itemId)
- {
- return GetItemId(String.Empty);
- }
- }
- while (name != null);
-
- }
- finally
- {
- enumerator.Dispose();
- }
-
- return null;
- }
-
- ///
- /// Creates a browser.
- ///
- /// The item id.
- /// The browser object.
- public IDaElementBrowser CreateBrowser(string itemId)
- {
- // check if DA3 browse interface is supported.
- if (SupportsInterface())
- {
- return new Da20ElementBrowser(this, itemId, m_configuration.BrowseToNotSupported);
- }
-
- return new Da20ElementBrowser(this, itemId, m_configuration.BrowseToNotSupported);
- }
-
- ///
- /// Creates a new instance of the client with the same configuration.
- ///
- /// The copy of the client.
- public ComDaClient CloneClient()
- {
- ComDaClient clone = new ComDaClient(m_configuration);
- clone.LocaleId = this.LocaleId;
- clone.UserIdentity = this.UserIdentity;
- clone.Key = this.Key;
- return clone;
- }
-
- ///
- /// Reads the status from the server.
- ///
- public OPCSERVERSTATUS? GetStatus()
- {
- string methodName = "IOPCServer.GetStatus";
-
- try
- {
- IOPCServer server = BeginComCall(methodName, true);
-
- IntPtr ppServerStatus;
- server.GetStatus(out ppServerStatus);
-
- if (ppServerStatus == IntPtr.Zero)
- {
- return null;
- }
-
- OpcRcw.Da.OPCSERVERSTATUS pStatus = (OpcRcw.Da.OPCSERVERSTATUS)Marshal.PtrToStructure(ppServerStatus, typeof(OpcRcw.Da.OPCSERVERSTATUS));
-
- Marshal.DestroyStructure(ppServerStatus, typeof(OpcRcw.Da.OPCSERVERSTATUS));
- Marshal.FreeCoTaskMem(ppServerStatus);
-
- return pStatus;
- }
- catch (Exception e)
- {
- ComCallError(methodName, e);
- return null;
- }
- finally
- {
- EndComCall(methodName);
- }
- }
-
- ///
- /// Reads the item and property values from the server.
- ///
- /// The requests.
- public void Read(ReadRequestCollection requests)
- {
- if (m_supportsIOPCItemIO)
- {
- Da30ReadItemValues(requests);
- }
- else
- {
- Da20ReadItemValues(requests);
- }
-
- ReadPropertyValues(requests);
- }
-
- ///
- /// Writes the item and property values to the server.
- ///
- /// The requests.
- public void Write(WriteRequestCollection requests)
- {
- if (m_supportsIOPCItemIO)
- {
- Da30WriteItemValues(requests);
- }
- else
- {
- Da20WriteItemValues(requests);
- }
- }
-
- #region Group Management
- ///
- /// Creates a group.
- ///
- public object CreateGroup(
- int groupId,
- int samplingInterval,
- float deadband,
- out int groupHandle,
- out int revisedSamplingInterval)
- {
- groupHandle = 0;
- revisedSamplingInterval = 0;
- GCHandle hDeadband = GCHandle.Alloc(deadband, GCHandleType.Pinned);
-
- string methodName = "IOPCServer.AddGroup";
-
- try
- {
- IOPCServer server = BeginComCall(methodName, true);
-
- object group = null;
- Guid iid = typeof(OpcRcw.Da.IOPCItemMgt).GUID;
-
- server.AddGroup(
- String.Empty,
- 1,
- samplingInterval,
- 0,
- IntPtr.Zero,
- hDeadband.AddrOfPinnedObject(),
- LocaleId,
- out groupHandle,
- out revisedSamplingInterval,
- ref iid,
- out group);
-
- return group;
- }
- catch (Exception e)
- {
- ComUtils.TraceComError(e, methodName);
- return null;
- }
- finally
- {
- EndComCall(methodName);
- hDeadband.Free();
- }
- }
-
- ///
- /// Removes a group.
- ///
- public void RemoveGroup(int groupHandle)
- {
- string methodName = "IOPCServer.RemoveGroup";
-
- try
- {
- IOPCServer server = BeginComCall(methodName, true);
- server.RemoveGroup(groupHandle, 0);
- }
- catch (Exception e)
- {
- ComUtils.TraceComError(e, methodName);
- return;
- }
- finally
- {
- EndComCall(methodName);
- }
- }
- #endregion
-
- ///
- /// Reads the property values and stores the results in the request objects.
- ///
- /// The requests.
- public void ReadPropertyValues(List requests)
- {
- for (int ii = 0; ii < requests.Count; ii++)
- {
- ReadRequest request = requests[ii];
-
- if (request != null && request.PropertyIds != null)
- {
- request.PropertyValues = ReadPropertyValues(
- request.ItemId,
- request.PropertyIds.ToArray());
- }
- }
- }
-
- ///
- /// Read the available non-built in properties from the server.
- ///
- /// The item id.
- /// if set to true the cache is updated.
- /// The array of properties.
- public DaProperty[] ReadAvailableProperties(string itemId, bool updateCache)
- {
- string methodName = "IOPCItemProperties.QueryAvailableProperties";
-
- // query for available properties.
- int count = 0;
-
- IntPtr pPropertyIds = IntPtr.Zero;
- IntPtr pDescriptions = IntPtr.Zero;
- IntPtr pDataTypes = IntPtr.Zero;
-
- try
- {
- IOPCItemProperties server = BeginComCall(methodName, true);
-
- server.QueryAvailableProperties(
- itemId,
- out count,
- out pPropertyIds,
- out pDescriptions,
- out pDataTypes);
- }
- catch (Exception e)
- {
- if (ComUtils.IsUnknownError(e, ResultIds.E_FAIL, ResultIds.E_INVALIDARG, ResultIds.E_UNKNOWNITEMID, ResultIds.E_INVALIDITEMID))
- {
- ComUtils.TraceComError(e, methodName);
- }
-
- return null;
- }
- finally
- {
- EndComCall(methodName);
- }
-
- // unmarshal results.
- int[] propertyIds = ComUtils.GetInt32s(ref pPropertyIds, count, true);
- string[] descriptions = ComUtils.GetUnicodeStrings(ref pDescriptions, count, true);
- short[] datatype = ComUtils.GetInt16s(ref pDataTypes, count, true);
-
- List properties = new List();
-
- for (int ii = 0; ii < count; ii++)
- {
- // do not return any of the built in properties.
- if (propertyIds[ii] <= PropertyIds.TimeZone)
- {
- continue;
- }
-
- DaProperty property = new DaProperty();
-
- property.PropertyId = propertyIds[ii];
- property.Name = descriptions[ii];
- property.DataType = datatype[ii];
-
- properties.Add(property);
- }
-
- // fetch the item ids.
- if (properties.Count > 0)
- {
- DaProperty[] array = properties.ToArray();
-
- GetPropertyItemIds(itemId, array);
-
- // update the cache.
- if (updateCache)
- {
- lock (m_cache)
- {
- DaElement element = null;
-
- if (m_cache.TryGetValue(itemId, out element))
- {
- element.Properties = array;
- }
- }
- }
-
- return array;
- }
-
- return null;
- }
- #endregion
-
- #region Private Methods
- ///
- /// Saves the element in cache.
- ///
- /// The element.
- private void SaveElementInCache(DaElement element)
- {
- lock (m_cache)
- {
- m_cache[element.ItemId] = element;
- }
- }
-
- ///
- /// Creates a new element.
- ///
- /// The item id.
- /// The name.
- /// The parent id.
- /// The element.
- private DaElement CreateElement(string itemId, string name, string parentId)
- {
- DaElement element = new DaElement();
- element.ItemId = itemId;
- UpdateElement(element, name, parentId);
- return element;
- }
-
- ///
- /// Updates a element.
- ///
- /// The element.
- /// The name.
- /// The parent id.
- private void UpdateElement(DaElement element, string name, string parentId)
- {
- // only update the name if specified.
- if (name != null)
- {
- element.Name = name;
- }
-
- // same for the parent id.
- if (parentId != null)
- {
- element.ParentId = parentId;
- }
-
- // read item property values.
- DaValue[] values = ReadPropertyValues(element.ItemId, m_CoreProperties);
-
- // handle errors gracefully.
- if (values == null || values.Length == 0)
- {
- element.ElementType = DaElementType.Branch;
- return;
- }
-
- // must be an item if the data type property exists.
- if (values[0].Error >= 0)
- {
- element.ElementType = DaElementType.Item;
- element.DataType = values[0].GetValue();
- element.AccessRights = values[1].GetValue();
- element.ScanRate = values[2].GetValue();
- element.Description = values[3].GetValue();
- element.EngineeringUnits = values[4].GetValue();
- element.EuInfo = values[5].GetValue();
- element.EuType = values[6].GetValue();
- element.HighEU = values[7].GetValue();
- element.LowEU = values[8].GetValue();
- element.OpenLabel = values[9].GetValue();
- element.CloseLabel = values[10].GetValue();
- element.HighIR = values[11].GetValue();
- element.LowIR = values[12].GetValue();
-
- // check if the time zone is specified.
- if (values[13].Error >= 0)
- {
- element.TimeZone = values[13].GetValue();
- }
-
- // check for analog item (checks for HighEU if EuType property not supported).
- if ((values[6].Error < 0 && values[7].Error >= 0) || element.EuType == (int)OPCEUTYPE.OPC_ANALOG)
- {
- element.ElementType = DaElementType.AnalogItem;
- }
-
- // check for enumerated item.
- else if (element.EuType == (int)OPCEUTYPE.OPC_ENUMERATED)
- {
- element.ElementType = DaElementType.EnumeratedItem;
- }
-
- // check for digital item (checks for CloseLabel property).
- else if (values[10].Error >= 0)
- {
- element.ElementType = DaElementType.DigitalItem;
- }
- }
-
- // the element must be a branch.
- else
- {
- element.ElementType = DaElementType.Branch;
-
- // branches could have description property.
- element.Description = values[3].GetValue();
- }
- }
-
- ///
- /// Finds the element and updates the name if it is not already cached.
- ///
- /// The item id.
- /// The name.
- /// The parent id.
- /// The element.
- private DaElement FindElement(string itemId, string name, string parentId)
- {
- if (String.IsNullOrEmpty(itemId))
- {
- return null;
- }
-
- // look in cache for existing element.
- DaElement element = null;
-
- lock (m_cache)
- {
- if (!m_cache.TryGetValue(itemId, out element))
- {
- element = null;
- }
- }
-
- // create a new element.
- if (element == null)
- {
- element = CreateElement(itemId, name, parentId);
- SaveElementInCache(element);
- }
-
- // update the element.
- element.Name = name;
- element.ParentId = parentId;
-
- return element;
- }
-
- ///
- /// The core properties used to determine an item type.
- ///
- private static readonly int[] m_CoreProperties = new int[]
- {
- PropertyIds.DataType,
- PropertyIds.AccessRights,
- PropertyIds.ScanRate,
- PropertyIds.Description,
- PropertyIds.EngineeringUnits,
- PropertyIds.EuInfo,
- PropertyIds.EuType,
- PropertyIds.HighEU,
- PropertyIds.LowEU,
- PropertyIds.OpenLabel,
- PropertyIds.CloseLabel,
- PropertyIds.HighIR,
- PropertyIds.LowIR,
- PropertyIds.TimeZone
- };
-
- ///
- /// Changes the browse position.
- ///
- /// The direction.
- /// The name.
- /// True if the operation was successful.
- private bool ChangeBrowsePosition(OPCBROWSEDIRECTION direction, string name)
- {
- string methodName = "IOPCBrowseServerAddressSpace.ChangeBrowsePosition";
-
- if (name == null)
- {
- name = String.Empty;
- }
-
- try
- {
- IOPCBrowseServerAddressSpace server = BeginComCall(methodName, true);
- server.ChangeBrowsePosition(direction, name);
- }
- catch (Exception e)
- {
- if (ComUtils.IsUnknownError(e, ResultIds.E_FAIL, ResultIds.E_INVALIDARG))
- {
- ComCallError(methodName, e);
- }
-
- return false;
- }
- finally
- {
- EndComCall(methodName);
- }
-
- return true;
- }
-
- ///
- /// Creates an enumerator for the current browse position.
- ///
- /// if set to true then branches are enumerated.
- /// The wrapped enumerator.
- private EnumString CreateEnumerator(bool branches)
- {
- IEnumString unknown = null;
-
- string methodName = "IOPCBrowseServerAddressSpace.BrowseOPCItemIDs";
-
- try
- {
- IOPCBrowseServerAddressSpace server = BeginComCall(methodName, true);
-
- OPCBROWSETYPE browseType = OPCBROWSETYPE.OPC_BRANCH;
-
- if (!branches)
- {
- browseType = OPCBROWSETYPE.OPC_LEAF;
- }
-
- server.BrowseOPCItemIDs(browseType, String.Empty, 0, 0, out unknown);
- }
- catch (Exception e)
- {
- ComCallError(methodName, e);
- return null;
- }
- finally
- {
- EndComCall(methodName);
- }
-
- // wrapper the enumrator. hardcoding a buffer size of 256.
- return new EnumString(unknown, 256);
- }
-
- ///
- /// Looks up the item id for the node relative to the current browse position.
- ///
- /// Name of the element to lookup.
- /// The item id. Null if an error occurs.
- private string GetItemId(string browseName)
- {
- string methodName = "IOPCBrowseServerAddressSpace.GetItemID";
-
- try
- {
- IOPCBrowseServerAddressSpace server = BeginComCall(methodName, true);
- string itemId = null;
- server.GetItemID(browseName, out itemId);
- return itemId;
- }
- catch (Exception e)
- {
- if (ComUtils.IsUnknownError(e, ResultIds.E_FAIL))
- {
- ComCallError(methodName, e);
- }
-
- return null;
- }
- finally
- {
- EndComCall(methodName);
- }
- }
-
- ///
- /// Reads the values of the properties from the server.
- ///
- /// The item id.
- /// The list of property ids to read. All properties are read if null.
- /// True if the element has properies.
- private DaValue[] ReadPropertyValues(string itemId, params int[] propertyIds)
- {
- string methodName = "IOPCItemProperties.GetItemProperties";
-
- // check for trivial case.
- if (propertyIds == null)
- {
- return null;
- }
-
- int count = propertyIds.Length;
- DaValue[] results = new DaValue[count];
-
- // check for empty list.
- if (count == 0)
- {
- return results;
- }
-
- // get the values from the server.
- IntPtr pValues = IntPtr.Zero;
- IntPtr pErrors = IntPtr.Zero;
-
- try
- {
- IOPCItemProperties server = BeginComCall(methodName, true);
-
- server.GetItemProperties(
- itemId,
- count,
- propertyIds,
- out pValues,
- out pErrors);
- }
- catch (Exception e)
- {
- if (ComUtils.IsUnknownError(e, ResultIds.E_FAIL, ResultIds.E_INVALIDARG, ResultIds.E_UNKNOWNITEMID, ResultIds.E_INVALIDITEMID))
- {
- ComUtils.TraceComError(e, methodName);
- return null;
- }
-
- for (int ii = 0; ii < count; ii++)
- {
- DaValue result = results[ii] = new DaValue();
- result.Value = null;
- result.Quality = OpcRcw.Da.Qualities.OPC_QUALITY_GOOD;
- result.Timestamp = DateTime.UtcNow;
- result.Error = Marshal.GetHRForException(e);
- }
-
- return results;
- }
- finally
- {
- EndComCall(methodName);
- }
-
- // unmarshal results.
- object[] values = ComUtils.GetVARIANTs(ref pValues, count, true);
- int[] errors = ComUtils.GetInt32s(ref pErrors, count, true);
-
- for (int ii = 0; ii < count; ii++)
- {
- DaValue result = results[ii] = new DaValue();
-
- Variant convertedValue;
- result.Error = ComDaClientNodeManager.RemoteToLocalValue(values[ii], out convertedValue);
-
- if (result.Error < 0)
- {
- continue;
- }
-
- result.Value = convertedValue.Value;
- result.Quality = OpcRcw.Da.Qualities.OPC_QUALITY_GOOD;
- result.Timestamp = DateTime.UtcNow;
- result.Error = errors[ii];
- }
-
- return results;
- }
-
- ///
- /// Gets the property item ids.
- ///
- /// The item id.
- /// The properties to update.
- private void GetPropertyItemIds(string itemId, DaProperty[] properties)
- {
- string methodName = "IOPCItemProperties.LookupItemIDs";
-
- int count = properties.Length;
-
- // get list of ids to request.
- int[] propertyIds = new int[count];
-
- for (int ii = 0; ii < propertyIds.Length; ii++)
- {
- propertyIds[ii] = properties[ii].PropertyId;
- }
-
- // request the item ids.
- IntPtr pItemIds = IntPtr.Zero;
- IntPtr pErrors = IntPtr.Zero;
-
- try
- {
- IOPCItemProperties server = BeginComCall(methodName, true);
-
- server.LookupItemIDs(
- itemId,
- count,
- propertyIds,
- out pItemIds,
- out pErrors);
- }
- catch (Exception e)
- {
- if (ComUtils.IsUnknownError(e, ResultIds.E_FAIL, ResultIds.E_UNKNOWNITEMID, ResultIds.E_INVALIDITEMID))
- {
- ComUtils.TraceComError(e, methodName);
- }
-
- return;
- }
- finally
- {
- EndComCall(methodName);
- }
-
- // unmarshal results.
- string[] itemIds = ComUtils.GetUnicodeStrings(ref pItemIds, count, true);
- int[] errors = ComUtils.GetInt32s(ref pErrors, count, true);
-
- // update the objects.
- for (int ii = 0; ii < count; ii++)
- {
- if (errors[ii] >= 0)
- {
- properties[ii].ItemId = itemIds[ii];
- }
- else
- {
- properties[ii].ItemId = null;
- }
- }
- }
-
- //private ComDaGroup m_group = null;
- //private object m_groupLock = new object();
-
- ///
- /// An overrideable version of the Dispose.
- ///
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- //lock (m_groupLock)
- //{
- // if (m_group != null)
- // {
- // Utils.SilentDispose(m_group);
- // m_group = null;
- // }
- //}
- }
-
- base.Dispose(disposing);
- }
-
- ///
- /// Reads the item values and stores the results in the request object.
- ///
- /// The requests.
- private void Da20ReadItemValues(List requests)
- {
- // lock (m_groupLock)
- {
- // if (m_group == null)
- //{
- ComDaGroup m_group = new ComDaGroup(this, false);
- //}
-
- try
- {
- int count1 = 0;
- GroupItem[] items = new GroupItem[requests.Count];
- ReadRequest[] addItemRequests = new ReadRequest[requests.Count];
-
- // create the items in the temporary group.
- for (int ii = 0; ii < requests.Count; ii++)
- {
- ReadRequest request = requests[ii];
-
- if (request == null)
- {
- continue;
- }
-
- if (!request.ValueRequired)
- {
- continue;
- }
-
- // add the item.
- items[count1] = m_group.CreateItem(request.ItemId, 0, 0, true);
- addItemRequests[count1] = request;
- count1++;
- }
-
- // create the items on the server.
- m_group.ApplyChanges();
-
- // build the list of values to write.
- int count2 = 0;
- int[] serverHandles = new int[count1];
- ReadRequest[] readRequests = new ReadRequest[count1];
-
- for (int ii = 0; ii < count1; ii++)
- {
- // check for error on create.
- GroupItem item = items[ii];
- ReadRequest request = addItemRequests[ii];
-
- if (item.ErrorId < 0)
- {
- request.Value = new DaValue();
- request.Value.Error = item.ErrorId;
- continue;
- }
-
- serverHandles[count2] = item.ServerHandle;
- readRequests[count2] = request;
- count2++;
- }
-
- if (count2 > 0)
- {
- // write values to the server.
- DaValue[] values = m_group.SyncRead(serverHandles, count2);
-
- // read the values.
- for (int ii = 0; ii < count2; ii++)
- {
- if (values != null && values.Length > ii)
- {
- readRequests[ii].Value = values[ii];
- }
- else
- {
- readRequests[ii].Value = new DaValue() { Error = ResultIds.E_FAIL, Timestamp = DateTime.UtcNow };
- }
- }
-
- // delete the items.
- for (int ii = 0; ii < count1; ii++)
- {
- GroupItem item = items[ii];
-
- if (item.ErrorId >= 0)
- {
- m_group.RemoveItem(item);
- }
- }
-
- m_group.ApplyChanges();
- }
- }
- finally
- {
- // delete the group and items.
- m_group.Delete();
- }
- }
- }
-
- ///
- /// Writes the item values to servers.
- ///
- /// The requests.
- private void Da20WriteItemValues(List requests)
- {
- //lock (m_groupLock)
- {
- //if (m_group == null)
- //{
- ComDaGroup m_group = new ComDaGroup(this, false);
- //}
-
- try
- {
- int count1 = 0;
- GroupItem[] items = new GroupItem[requests.Count];
- WriteRequest[] addItemRequests = new WriteRequest[requests.Count];
- object[] convertedValues = new object[requests.Count];
-
- // create the items in the temporary group.
- for (int ii = 0; ii < requests.Count; ii++)
- {
- WriteRequest request = requests[ii];
-
- if (request == null)
- {
- continue;
- }
-
- // status code writes not supported.
- if (request.Value.StatusCode != StatusCodes.Good)
- {
- request.Error = ResultIds.E_NOTSUPPORTED;
- continue;
- }
-
- // timestamp writes not supported.
- if (request.Value.ServerTimestamp != DateTime.MinValue)
- {
- request.Error = ResultIds.E_NOTSUPPORTED;
- continue;
- }
-
- // timestamp writes not supported.
- if (request.Value.SourceTimestamp != DateTime.MinValue)
- {
- request.Error = ResultIds.E_NOTSUPPORTED;
- continue;
- }
-
- // convert to a DA compatible type.
- object convertedValue = null;
- request.Error = ComDaClientNodeManager.LocalToRemoteValue(request.Value.WrappedValue, out convertedValue);
-
- if (request.Error < 0)
- {
- continue;
- }
-
- // add the item.
- items[count1] = m_group.CreateItem(request.ItemId, 0, 0, true);
- addItemRequests[count1] = request;
- convertedValues[count1] = convertedValue;
- count1++;
- }
-
- // create the items on the server.
- m_group.ApplyChanges();
-
- // build the list of values to write.
- int count2 = 0;
- int[] serverHandles = new int[count1];
- object[] values = new object[count1];
- WriteRequest[] writeRequests = new WriteRequest[count1];
-
- for (int ii = 0; ii < count1; ii++)
- {
- // check for error on create.
- GroupItem item = items[ii];
- WriteRequest request = addItemRequests[ii];
-
- if (item.ErrorId < 0)
- {
- request.Error = item.ErrorId;
- continue;
- }
-
- serverHandles[count2] = item.ServerHandle;
- values[count2] = convertedValues[ii];
- writeRequests[count2] = request;
- count2++;
- }
-
- if (count2 > 0)
- {
- // write values to the server.
- int[] errors = m_group.SyncWrite(serverHandles, values, count2);
-
- // read the errors.
- for (int ii = 0; ii < count2; ii++)
- {
- if (errors != null && errors.Length > ii)
- {
- writeRequests[ii].Error = errors[ii];
- }
- else
- {
- writeRequests[ii].Error = ResultIds.E_FAIL;
- }
- }
-
- // delete the items.
- for (int ii = 0; ii < count1; ii++)
- {
- GroupItem item = items[ii];
-
- if (item.ErrorId >= 0)
- {
- m_group.RemoveItem(item);
- }
- }
-
- m_group.ApplyChanges();
- }
- }
- finally
- {
- // delete the group and items.
- m_group.Delete();
- }
- }
- }
-
- ///
- /// Reads the values using the DA3 interfaces.
- ///
- /// The requests.
- private void Da30ReadItemValues(List requests)
- {
- string[] itemIds = new string[requests.Count];
- int[] maxAge = new int[requests.Count];
- List requestIndexes = new List();
-
- int count = 0;
-
- for (int ii = 0; ii < requests.Count; ii++)
- {
- if (!requests[ii].ValueRequired)
- {
- continue;
- }
-
- itemIds[count] = requests[ii].ItemId;
- maxAge[count] = 0;
- requestIndexes.Add(ii);
- count++;
- }
-
- if (count <= 0)
- {
- return;
- }
-
- IntPtr ppValues = IntPtr.Zero;
- IntPtr ppQualities = IntPtr.Zero;
- IntPtr ppTimeStamps = IntPtr.Zero;
- IntPtr ppErrors = IntPtr.Zero;
-
- string methodName = "IOPCItemIO.Read";
-
- try
- {
- IOPCItemIO server = BeginComCall(methodName, true);
-
- server.Read(
- requestIndexes.Count,
- itemIds,
- maxAge,
- out ppValues,
- out ppQualities,
- out ppTimeStamps,
- out ppErrors);
- }
- catch (Exception e)
- {
- ComUtils.TraceComError(e, methodName);
- return;
- }
- finally
- {
- EndComCall(methodName);
- }
-
- System.Runtime.InteropServices.ComTypes.FILETIME[] timeStamps = ComUtils.GetFILETIMEs(ref ppTimeStamps, requestIndexes.Count);
- object[] values = ComUtils.GetVARIANTs(ref ppValues, count, true);
- short[] qualities = ComUtils.GetInt16s(ref ppQualities, count, true);
- int[] errors = ComUtils.GetInt32s(ref ppErrors, count, true);
-
- DaValue[] daValues = ComDaGroup.GetItemValues(count, values, qualities, timeStamps, errors);
-
- for (int ii = 0; ii < requestIndexes.Count; ii++)
- {
- requests[requestIndexes[ii]].Value = daValues[ii];
- }
- }
-
- ///
- /// Writes the values using the DA3 interfaces.
- ///
- /// The requests.
- private void Da30WriteItemValues(List requests)
- {
- int count = 0;
- string[] itemIDs = new string[requests.Count];
- OpcRcw.Da.OPCITEMVQT[] values = new OpcRcw.Da.OPCITEMVQT[requests.Count];
- WriteRequest[] writeRequests = new WriteRequest[requests.Count];
-
- for (int ii = 0; ii < requests.Count; ii++)
- {
- WriteRequest request = requests[ii];
-
- if (request == null)
- {
- continue;
- }
-
- // convert to a DA compatible type.
- object convertedValue = null;
- request.Error = ComDaClientNodeManager.LocalToRemoteValue(request.Value.WrappedValue, out convertedValue);
-
- if (request.Error < 0)
- {
- continue;
- }
-
- itemIDs[count] = request.ItemId;
-
- values[count].vDataValue = convertedValue;
- values[count].bQualitySpecified = 0;
- values[count].bTimeStampSpecified = 0;
-
- // check for quality.
- values[count].wQuality = ComUtils.GetQualityCode(request.Value.StatusCode);
-
- if (values[count].wQuality != Qualities.OPC_QUALITY_GOOD)
- {
- values[count].bQualitySpecified = 1;
- }
-
- // check for server timestamp.
- if (request.Value.ServerTimestamp != DateTime.MinValue)
- {
- values[count].ftTimeStamp = ComUtils.GetFILETIME(request.Value.ServerTimestamp);
- values[count].bTimeStampSpecified = 1;
- }
-
- // ignore server timestamp if source timestamp is provided.
- if (request.Value.SourceTimestamp != DateTime.MinValue)
- {
- values[count].ftTimeStamp = ComUtils.GetFILETIME(request.Value.SourceTimestamp);
- values[count].bTimeStampSpecified = 1;
- }
-
- writeRequests[count] = request;
- count++;
- }
-
- IntPtr ppErrors = IntPtr.Zero;
- string methodName = "IOPCItemIO.WriteVQT";
-
- try
- {
- IOPCItemIO server = BeginComCall(methodName, true);
-
- server.WriteVQT(
- count,
- itemIDs,
- values,
- out ppErrors);
- }
- catch (Exception e)
- {
- ComUtils.TraceComError(e, methodName);
- return;
- }
- finally
- {
- EndComCall(methodName);
- }
-
- int[] errors = ComUtils.GetInt32s(ref ppErrors, count, true);
-
- for (int ii = 0; ii < count; ii++)
- {
- writeRequests[ii].Error = errors[ii];
- }
- }
-
- ///
- /// Called immediately after connecting to the server.
- ///
- protected override void OnConnected()
- {
- m_supportsIOPCItemIO = SupportsInterface();
- }
- #endregion
-
- #region Da20ElementBrowser Class
- ///
- /// Browses for DA elements using the DA 2.0 interfaces.
- ///
- private class Da20ElementBrowser : IDaElementBrowser
- {
- #region Constructors
- ///
- /// Initializes a new instance of the class.
- ///
- /// The client.
- /// The item id.
- /// if set to true BROWSE_TO not supported.
- public Da20ElementBrowser(
- ComDaClient client,
- string itemId,
- bool browseToNotSupported)
- {
- m_client = client;
- m_itemId = itemId;
- m_branches = false;
- m_browseToNotSupported = browseToNotSupported;
- }
- #endregion
-
- #region IDisposable Members
- ///
- /// Frees any unmanaged resources.
- ///
- public void Dispose()
- {
- Dispose(true);
- }
-
- ///
- /// An overrideable version of the Dispose.
- ///
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- Utils.SilentDispose(m_enumerator);
- m_enumerator = null;
-
- Utils.SilentDispose(m_clone);
- m_clone = null;
- }
- }
- #endregion
-
- ///
- /// Sets the browse position using the BROWSE_DOWN operator.
- ///
- /// The item id.
- /// True if the item id was found.
- private bool SearchAndSetBrowsePosition(string itemId)
- {
- EnumString enumerator = m_clone.CreateEnumerator(true);
-
- // a null indicates an error.
- if (enumerator == null)
- {
- return false;
- }
-
- // collect names.
- Queue names = new Queue();
-
- try
- {
- do
- {
- // fetch the next name.
- string name = enumerator.Next();
-
- // a null indicates the end of list.
- if (name == null)
- {
- break;
- }
-
- // fetch the item id.
- string branchId = m_clone.GetItemId(name);
-
- if (branchId == itemId)
- {
- return m_clone.ChangeBrowsePosition(OPCBROWSEDIRECTION.OPC_BROWSE_DOWN, name);
- }
-
- names.Enqueue(name);
- }
- while (true);
- }
- finally
- {
- enumerator.Dispose();
- }
-
- // recursively search tree.
- while (names.Count > 0)
- {
- string name = names.Dequeue();
-
- if (!m_clone.ChangeBrowsePosition(OPCBROWSEDIRECTION.OPC_BROWSE_DOWN, name))
- {
- continue;
- }
-
- if (SearchAndSetBrowsePosition(itemId))
- {
- return true;
- }
-
- m_clone.ChangeBrowsePosition(OPCBROWSEDIRECTION.OPC_BROWSE_UP, null);
- }
-
- // not found anywhere.
- return false;
- }
-
- ///
- /// Sets the browse position.
- ///
- /// The item id.
- /// True if the item id was found.
- private bool SetBrowsePosition(string itemId)
- {
- // go directly to item id.
- if (m_clone.ChangeBrowsePosition(OPCBROWSEDIRECTION.OPC_BROWSE_TO, itemId))
- {
- return true;
- }
-
- // nothing more to do isf browse to supported.
- if (!m_browseToNotSupported)
- {
- return false;
- }
-
- // do it the hard way.
- while (m_clone.ChangeBrowsePosition(OPCBROWSEDIRECTION.OPC_BROWSE_UP, null))
- {
- // skip to root.
- }
-
- // nothing more to do at root.
- if (String.IsNullOrEmpty(itemId))
- {
- return true;
- }
-
- // find item id in tree.
- return SearchAndSetBrowsePosition(itemId);
- }
-
- #region IDaElementBrowser Members
- ///
- /// Returns the next DA element.
- ///
- /// A DA element. Null if nothing left to browse.
- public DaElement Next()
- {
- // check if already completed.
- if (m_completed)
- {
- return null;
- }
-
- // create the enumerator if not already created.
- if (m_enumerator == null)
- {
- // need to clone the client since ChangeBrowsePosition prevents multiple
- // simultaneous browse operations.
- m_clone = m_client.CloneClient();
- m_clone.CreateInstance();
-
- // nothing to browse if change browse position failed.
- if (!SetBrowsePosition(m_itemId))
- {
- return null;
- }
-
- m_enumerator = m_clone.CreateEnumerator(false);
- m_branches = false;
-
- // a null indicates an error.
- if (m_enumerator == null)
- {
- m_completed = true;
- return null;
- }
- }
-
- // need a loop in case errors occur fetching element metadata.
- DaElement element = null;
-
- do
- {
- // fetch the next name.
- string name = m_enumerator.Next();
-
- // a null indicates the end of list.
- if (name == null)
- {
- if (!m_branches)
- {
- m_branches = true;
- m_enumerator.Dispose();
- m_enumerator = m_clone.CreateEnumerator(true);
- continue;
- }
-
- m_completed = true;
- return null;
- }
-
- // suppress duplicates when a item is also a branch.
- if (m_branches)
- {
- if (m_itemNames != null)
- {
- if (m_itemNames.ContainsKey(name))
- {
- continue;
- }
- }
- }
-
- // save the item name to allow checks for duplicates.
- else
- {
- if (m_itemNames == null)
- {
- m_itemNames = new Dictionary();
- }
-
- m_itemNames[name] = null;
- }
-
- // fetch the item id.
- string itemId = m_clone.GetItemId(name);
-
- // fetch the metadata.
- element = m_client.FindElement(itemId, name, m_itemId);
- }
- while (element == null);
-
- // return element.
- return element;
- }
-
- ///
- /// Finds the element with the specified item id.
- ///
- /// The target id.
- /// if set to true [is item].
- /// The element if found.
- public DaElement Find(string targetId, bool isItem)
- {
- // check for root.
- if (String.IsNullOrEmpty(targetId))
- {
- m_client.FindElement(targetId, String.Empty, String.Empty);
- }
-
- // create the clone used to find the item.
- if (m_clone == null)
- {
- m_clone = m_client.CloneClient();
- m_clone.CreateInstance();
- }
-
- bool recursive = false;
-
- // check if it is possible to browse to the item.
- if (m_clone.ChangeBrowsePosition(OPCBROWSEDIRECTION.OPC_BROWSE_TO, targetId))
- {
- if (!m_clone.ChangeBrowsePosition(OPCBROWSEDIRECTION.OPC_BROWSE_UP, String.Empty))
- {
- return null;
- }
- }
-
- // need to do it the hard way from the root of the hierarchy.
- else
- {
- while (m_clone.ChangeBrowsePosition(OPCBROWSEDIRECTION.OPC_BROWSE_UP, String.Empty));
- recursive = true;
- }
-
- // get the item id for the parent.
- string parentId = m_clone.GetItemId(String.Empty);
-
- // find the target.
- return Find(parentId, targetId, false, recursive);
- }
-
- ///
- /// Finds the element with the specified item id.
- ///
- /// The parent id.
- /// The target id.
- /// if set to true the element is a item.
- /// if set to true [recursive].
- /// The element if found.
- public DaElement Find(string parentId, string targetId, bool isItem, bool recursive)
- {
- // create the enumerator if not already created.
- m_enumerator = m_clone.CreateEnumerator(false);
-
- // a null indicates an error.
- if (m_enumerator == null)
- {
- return null;
- }
-
- string name = null;
-
- // process all items.
- do
- {
- // fetch the next name.
- name = m_enumerator.Next();
-
- // a null indicates the end of list.
- if (name == null)
- {
- break;
- }
-
- // fetch the item id.
- string itemId = m_clone.GetItemId(name);
-
- // fetch the metadata.
- DaElement element = m_client.FindElement(itemId, name, parentId);
-
- // check if target found.
- if (targetId == itemId)
- {
- return element;
- }
- }
- while (true);
-
- m_enumerator.Dispose();
- m_enumerator = null;
-
- List branches = new List();
-
- // fetch the branches of the target is a branch or if a recursive search is required.
- if (!isItem || recursive)
- {
- // need to fetch list of branches to search.
- m_enumerator = m_clone.CreateEnumerator(true);
-
- if (m_enumerator == null)
- {
- return null;
- }
-
- // process all branches.
- do
- {
- name = m_enumerator.Next();
-
- // a null indicates the end of list.
- if (name == null)
- {
- break;
- }
-
- // fetch the item id.
- string itemId = m_clone.GetItemId(name);
-
- // fetch the metadata.
- DaElement element = m_client.FindElement(itemId, name, parentId);
-
- // save branch for recursive search if not found at this level.
- if (recursive)
- {
- branches.Add(element);
- }
-
- // check if target found.
- if (targetId == itemId)
- {
- return element;
- }
- }
- while (name != null);
-
- m_enumerator.Dispose();
- m_enumerator = null;
- }
-
- // all done if not doing a recursive search.
- if (!recursive)
- {
- return null;
- }
-
- // recursively search hierarchy.
- for (int ii = 0; ii < branches.Count; ii++)
- {
- m_clone.ChangeBrowsePosition(OPCBROWSEDIRECTION.OPC_BROWSE_DOWN, branches[ii].Name);
-
- DaElement element = Find(branches[ii].ItemId, targetId, isItem, recursive);
-
- if (element != null)
- {
- return element;
- }
-
- m_clone.ChangeBrowsePosition(OPCBROWSEDIRECTION.OPC_BROWSE_UP, String.Empty);
- }
-
- // not found.
- return null;
- }
- #endregion
-
- #region Private Fields
- private ComDaClient m_client;
- private ComDaClient m_clone;
- private string m_itemId;
- private Opc.Ua.Com.Client.EnumString m_enumerator;
- private bool m_branches;
- private bool m_completed;
- private Dictionary m_itemNames;
- private bool m_browseToNotSupported;
- #endregion
- }
- #endregion
-
- #region Private Fields
- private Dictionary m_cache;
- private ComDaClientConfiguration m_configuration;
- private bool m_supportsIOPCItemIO;
- #endregion
- }
-
- ///
- /// An interface to an object that browses a DA COM server.
- ///
- public interface IDaElementBrowser : IDisposable
- {
- ///
- /// Returns the next element.
- ///
- /// The next element. Null if nothing found or an error occurs.
- DaElement Next();
-
- ///
- /// Finds the element with the specified item id.
- ///
- /// The target id.
- /// if set to true the element is a branch.
- /// The element if found.
- DaElement Find(string targetId, bool isBranch);
- }
-}
diff --git a/ComIOP/Common/Client/Da/ComDaClientConfiguration.cs b/ComIOP/Common/Client/Da/ComDaClientConfiguration.cs
deleted file mode 100644
index 6ce1fa408..000000000
--- a/ComIOP/Common/Client/Da/ComDaClientConfiguration.cs
+++ /dev/null
@@ -1,86 +0,0 @@
-/* ========================================================================
- * 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;
-using System.ServiceModel;
-using System.Runtime.Serialization;
-using System.Collections.Generic;
-using Opc.Ua.Server;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// Stores the configuration the data access node manager.
- ///
- [DataContract(Namespace = Namespaces.ComInterop)]
- public class ComDaClientConfiguration : ComClientConfiguration
- {
- #region Constructors
- ///
- /// The default constructor.
- ///
- public ComDaClientConfiguration()
- {
- Initialize();
- }
-
- ///
- /// Initializes the object during deserialization.
- ///
- [OnDeserializing()]
- private void Initialize(StreamingContext context)
- {
- Initialize();
- }
-
- ///
- /// Sets private members to default values.
- ///
- private void Initialize()
- {
- }
- #endregion
-
- #region Public Properties
- ///
- /// Get or sets a value indicating whether BROWSE_TO is supported by the COM Server.
- ///
- [DataMember(Order = 2)]
- public bool BrowseToNotSupported
- {
- get { return m_browseToNotSupported; }
- set { m_browseToNotSupported = value; }
- }
- #endregion
-
- #region Private Members
- private bool m_browseToNotSupported;
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/Da/ComDaClientManager.cs b/ComIOP/Common/Client/Da/ComDaClientManager.cs
deleted file mode 100644
index aaea5b711..000000000
--- a/ComIOP/Common/Client/Da/ComDaClientManager.cs
+++ /dev/null
@@ -1,141 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading;
-using Opc.Ua;
-using Opc.Ua.Server;
-using Opc.Ua.Com;
-using OpcRcw.Da;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// Manages the DA COM connections used by the UA server.
- ///
- public class ComDaClientManager : ComClientManager
- {
- #region Constructors
- ///
- /// Initializes a new instance of the class.
- ///
- public ComDaClientManager()
- {
- }
- #endregion
-
- #region Public Members
- ///
- /// Selects the DA COM client to use for the current context.
- ///
- /// The context.
- /// True if the the default instance should be returned.
- /// A DA COM client instance.
- public new ComDaClient SelectClient(ServerSystemContext context, bool useDefault)
- {
- return (ComDaClient)base.SelectClient(context, useDefault);
- }
- #endregion
-
- #region Protected Members
- ///
- /// Gets or sets the default COM client instance.
- ///
- /// The default client.
- protected new ComDaClient DefaultClient
- {
- get { return base.DefaultClient as ComDaClient; }
- set { base.DefaultClient = value; }
- }
-
- ///
- /// Gets the configuration.
- ///
- /// The configuration.
- protected new ComDaClientConfiguration Configuration
- {
- get { return base.Configuration as ComDaClientConfiguration; }
- }
-
- ///
- /// Creates a new client object.
- ///
- protected override ComClient CreateClient()
- {
- return new ComDaClient(Configuration);
- }
-
- ///
- /// Updates the status node.
- ///
- protected override bool UpdateStatus()
- {
- // get the status from the server.
- ComDaClient client = DefaultClient;
- OPCSERVERSTATUS? status = client.GetStatus();
-
- // check the client has been abandoned.
- if (!Object.ReferenceEquals(client, DefaultClient))
- {
- return false;
- }
-
- // update the server status.
- lock (StatusNodeLock)
- {
- StatusNode.ServerUrl.Value = Configuration.ServerUrl;
-
- if (status != null)
- {
- StatusNode.SetStatusCode(DefaultSystemContext, StatusCodes.Good, DateTime.UtcNow);
-
- StatusNode.ServerState.Value = Utils.Format("{0}", status.Value.dwServerState);
- StatusNode.CurrentTime.Value = ComUtils.GetDateTime(status.Value.ftCurrentTime);
- StatusNode.LastUpdateTime.Value = ComUtils.GetDateTime(status.Value.ftLastUpdateTime);
- StatusNode.StartTime.Value = ComUtils.GetDateTime(status.Value.ftStartTime);
- StatusNode.VendorInfo.Value = status.Value.szVendorInfo;
- StatusNode.SoftwareVersion.Value = Utils.Format("{0}.{1}.{2}", status.Value.wMajorVersion, status.Value.wMinorVersion, status.Value.wBuildNumber);
- }
- else
- {
- StatusNode.SetStatusCode(DefaultSystemContext, StatusCodes.BadOutOfService, DateTime.UtcNow);
- }
-
- StatusNode.ClearChangeMasks(DefaultSystemContext, true);
- return status != null;
- }
- }
- #endregion
-
- #region Private Fields
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/Da/ComDaClientNodeManager.cs b/ComIOP/Common/Client/Da/ComDaClientNodeManager.cs
deleted file mode 100644
index 89497a1f2..000000000
--- a/ComIOP/Common/Client/Da/ComDaClientNodeManager.cs
+++ /dev/null
@@ -1,947 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using System.Text;
-using System.Diagnostics;
-using System.Xml;
-using System.IO;
-using System.Threading;
-using System.Reflection;
-using System.Globalization;
-using Opc.Ua;
-using Opc.Ua.Server;
-using Opc.Ua.Com;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// A node manager for a server that exposes several variables.
- ///
- public class ComDaClientNodeManager : ComClientNodeManager
- {
- #region Constructors
- ///
- /// Initializes the node manager.
- ///
- public ComDaClientNodeManager(IServerInternal server, string namespaceUri, ComDaClientConfiguration configuration, bool ownsTypeModel)
- :
- base(server, namespaceUri, ownsTypeModel)
- {
- SystemContext.SystemHandle = m_system = new ComDaClientManager();
- SystemContext.NodeIdFactory = this;
-
- // save the configuration for the node manager.
- m_configuration = configuration;
-
- // set the alias root.
- AliasRoot = m_configuration.ServerName;
-
- if (String.IsNullOrEmpty(AliasRoot))
- {
- AliasRoot = "DA";
- }
-
- // set the default parser if none provided.
- if (configuration.ItemIdParser == null)
- {
- configuration.ItemIdParser = new ComItemIdParser();
- }
-
- // create the list of subscriptions.
- m_subscriptionManagers = new Dictionary();
- m_subscriptionManagers[String.Empty] = new SubscribeRequestManager(SystemContext, null, 1000);
- m_monitoredItems = new Dictionary();
- }
- #endregion
-
- #region IDisposable Members
- ///
- /// An overrideable version of the Dispose.
- ///
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- m_system.Dispose();
- }
-
- base.Dispose(disposing);
- }
- #endregion
-
- #region INodeIdFactory Members
- ///
- /// Creates the NodeId for the specified node.
- ///
- /// The context.
- /// The node.
- /// The new NodeId.
- ///
- /// This method is called by the NodeState.Create() method which initializes a Node from
- /// the type model. During initialization a number of child nodes are created and need to
- /// have NodeIds assigned to them. This implementation constructs NodeIds by constructing
- /// strings. Other implementations could assign unique integers or Guids and save the new
- /// Node in a dictionary for later lookup.
- ///
- public override NodeId New(ISystemContext context, NodeState node)
- {
- // do not assign node id to server state nodes.
- if (node is ComServerStatusState)
- {
- return node.NodeId;
- }
-
- return DaModelUtils.ConstructIdForComponent(node, NamespaceIndex);
- }
- #endregion
-
- #region INodeManager Members
- ///
- /// Does any initialization required before the address space can be used.
- ///
- ///
- /// The externalReferences is an out parameter that allows the node manager to link to nodes
- /// in other node managers. For example, the 'Objects' node is managed by the CoreNodeManager and
- /// should have a reference to the root folder node(s) exposed by this node manager.
- ///
- public override void CreateAddressSpace(IDictionary> externalReferences)
- {
- lock (Lock)
- {
- // check if the type model needs to be loaded.
- if (NamespaceIndexes.Length > 1)
- {
- LoadPredefinedNodes(SystemContext, externalReferences);
- }
-
- // create the root node.
- string serverName = m_configuration.ServerName;
-
- if (String.IsNullOrEmpty(serverName))
- {
- serverName = "ComDaServer";
- }
-
- DaElement element = new DaElement();
- element.ItemId = String.Empty;
- element.Name = serverName;
- element.ElementType = DaElementType.Branch;
-
- DaBranchState root = new DaBranchState(SystemContext, element, NamespaceIndex);
- root.AddReference(ReferenceTypeIds.Organizes, true, ObjectIds.ObjectsFolder);
-
- // link root to objects folder.
- IList references = null;
-
- if (!externalReferences.TryGetValue(ObjectIds.ObjectsFolder, out references))
- {
- externalReferences[ObjectIds.ObjectsFolder] = references = new List();
- }
-
- references.Add(new NodeStateReference(ReferenceTypeIds.Organizes, false, root.NodeId));
-
- // create the status node.
- ComServerStatusState status = new ComServerStatusState(root);
- status.ReferenceTypeId = ReferenceTypeIds.Organizes;
-
- // get the type namepace for the browse name.
- int typeNamepaceIndex = Server.NamespaceUris.GetIndex(Namespaces.ComInterop);
-
- if (typeNamepaceIndex < 0)
- {
- typeNamepaceIndex = NamespaceIndex;
- }
-
- status.Create(
- SystemContext,
- DaModelUtils.ConstructIdForInternalNode("ServerStatus", NamespaceIndex),
- new QualifiedName("ServerStatus", (ushort)typeNamepaceIndex),
- null,
- true);
-
- root.AddChild(status);
-
- // store root folder in the pre-defined nodes.
- AddPredefinedNode(SystemContext, root);
-
- // create the COM server.
- m_system.Initialize(SystemContext, m_configuration, status, Lock, OnServerReconnected);
- StartMetadataUpdates(null, null, 5000, m_configuration.MaxReconnectWait);
- }
- }
-
- ///
- /// Frees any resources allocated for the address space.
- ///
- public override void DeleteAddressSpace()
- {
- lock (Lock)
- {
- base.DeleteAddressSpace();
- }
- }
-
- ///
- /// Called when client manager has reconnected to the COM server.
- ///
- public void OnServerReconnected(object state)
- {
- try
- {
- foreach (SubscribeRequestManager manager in m_subscriptionManagers.Values)
- {
- try
- {
- manager.RecreateItems();
- }
- catch (Exception e)
- {
- Utils.Trace(e, "Could not re-create subscription after reconnect for locale {0}.", new CultureInfo(manager.LocaleId).DisplayName);
- }
- }
- }
- catch (Exception e)
- {
- Utils.Trace(e, "Could not re-create subscription after reconnect.");
- }
- }
-
- ///
- /// Returns a unique handle for the node.
- ///
- protected override NodeHandle GetManagerHandle(ServerSystemContext context, NodeId nodeId, IDictionary cache)
- {
- lock (Lock)
- {
- // quickly exclude nodes that are not in the namespace.
- if (!IsNodeIdInNamespace(nodeId))
- {
- return null;
- }
-
- // check for predefined nodes.
- if (PredefinedNodes != null)
- {
- NodeState node = null;
-
- if (PredefinedNodes.TryGetValue(nodeId, out node))
- {
- NodeHandle handle = new NodeHandle();
-
- handle.NodeId = nodeId;
- handle.Validated = true;
- handle.Node = node;
-
- return handle;
- }
- }
-
- // parse the identifier.
- DaParsedNodeId parsedNodeId = DaParsedNodeId.Parse(nodeId);
-
- if (parsedNodeId != null)
- {
- NodeHandle handle = new NodeHandle();
-
- handle.NodeId = nodeId;
- handle.Validated = false;
- handle.Node = null;
- handle.ParsedNodeId = parsedNodeId;
-
- return handle;
- }
-
- return null;
- }
- }
-
- ///
- /// Verifies that the specified node exists.
- ///
- protected override NodeState ValidateNode(
- ServerSystemContext context,
- NodeHandle handle,
- IDictionary cache)
- {
- // not valid if no root.
- if (handle == null)
- {
- return null;
- }
-
- // check if previously validated.
- if (handle.Validated)
- {
- return handle.Node;
- }
-
- NodeState target = null;
-
- // check if already in the cache.
- if (cache != null)
- {
- if (cache.TryGetValue(handle.NodeId, out target))
- {
- // nulls mean a NodeId which was previously found to be invalid has been referenced again.
- if (target == null)
- {
- return null;
- }
-
- handle.Node = target;
- handle.Validated = true;
- return handle.Node;
- }
-
- target = null;
- }
-
- try
- {
- // check if the node id has been parsed.
- DaParsedNodeId parsedNodeId = handle.ParsedNodeId as DaParsedNodeId;
-
- if (parsedNodeId == null)
- {
- return null;
- }
-
- NodeState root = null;
- DaElement element = null;
- ComDaClient client = m_system.SelectClient(context, false);
-
- // validate a branch or item.
- if (parsedNodeId.RootType == DaModelUtils.DaElement)
- {
- element = client.FindElement(parsedNodeId.RootId);
-
- // branch does not exist.
- if (element == null)
- {
- return null;
- }
-
- // create a temporary object to use for the operation.
- root = DaModelUtils.ConstructElement(context, element, NamespaceIndex);
- root.Handle = element;
-
- AddAdditionalElementReferences(SystemContext, root);
- }
-
- // validate an property.
- else if (parsedNodeId.RootType == DaModelUtils.DaProperty)
- {
- element = client.FindElement(parsedNodeId.RootId);
-
- // branch does not exist.
- if (element == null)
- {
- return null;
- }
-
- // validate the property.
- DaProperty property = client.FindProperty(parsedNodeId.RootId, parsedNodeId.PropertyId);
-
- // property does not exist.
- if (property == null)
- {
- return null;
- }
-
- // create a temporary object to use for the operation.
- root = DaModelUtils.ConstructProperty(context, element.ItemId, property, NamespaceIndex);
- root.Handle = property;
-
- AddAdditionalElementReferences(SystemContext, root);
- }
-
- // unknown root type.
- else
- {
- return null;
- }
-
- // all done if no components to validate.
- if (String.IsNullOrEmpty(parsedNodeId.ComponentPath))
- {
- handle.Validated = true;
- handle.Node = target = root;
- return handle.Node;
- }
-
- // validate component.
- NodeState component = root.FindChildBySymbolicName(context, parsedNodeId.ComponentPath);
-
- // component does not exist.
- if (component == null)
- {
- return null;
- }
-
- // found a valid component.
- handle.Validated = true;
- handle.Node = target = component;
- return handle.Node;
- }
- finally
- {
- // store the node in the cache to optimize subsequent lookups.
- if (cache != null)
- {
- cache.Add(handle.NodeId, target);
- }
- }
- }
-
- ///
- /// Allows sub-class to add additional references to a element node after validation.
- ///
- protected virtual void AddAdditionalElementReferences(ServerSystemContext context, NodeState node)
- {
- // TBD
- }
-
- ///
- /// Validates the nodes and reads the values from the underlying source.
- ///
- /// The context.
- /// The nodes to read.
- /// The values.
- /// The errors.
- /// The nodes to validate.
- /// The cache.
- protected override void Read(
- ServerSystemContext context,
- IList nodesToRead,
- IList values,
- IList errors,
- List nodesToValidate,
- IDictionary cache)
- {
- ComDaClientManager system = (ComDaClientManager)this.SystemContext.SystemHandle;
- ComDaClient client = system.SelectClient((ServerSystemContext)SystemContext, false);
-
- ReadRequestCollection requests = new ReadRequestCollection();
-
- for (int ii = 0; ii < nodesToValidate.Count; ii++)
- {
- NodeHandle handle = nodesToValidate[ii];
-
- lock (Lock)
- {
- NodeState source = ValidateNode(context, handle, cache);
-
- if (source == null)
- {
- continue;
- }
-
- DataValue value = values[handle.Index];
- ReadValueId nodeToRead = nodesToRead[handle.Index];
-
- // determine if request can be sent to the server.
- bool queued = false;
- errors[handle.Index] = requests.Add(source, nodeToRead, value, out queued);
-
- if (queued)
- {
- continue;
- }
-
- // read built-in metadata.
- errors[handle.Index] = source.ReadAttribute(
- context,
- nodeToRead.AttributeId,
- nodeToRead.ParsedIndexRange,
- nodeToRead.DataEncoding,
- value);
- }
- }
-
- // read the values from the server.
- client.Read(requests);
-
- // extract the values from the results.
- for (int ii = 0; ii < nodesToValidate.Count; ii++)
- {
- NodeHandle handle = nodesToValidate[ii];
- DataValue value = values[handle.Index];
- ReadValueId nodeToRead = nodesToRead[handle.Index];
-
- lock (Lock)
- {
- if (!requests.HasResult(nodeToRead))
- {
- continue;
- }
-
- errors[handle.Index] = requests.GetResult(context, handle.Node, nodeToRead, value, context.DiagnosticsMask);
- }
- }
- }
-
- ///
- /// Validates the nodes and writes the value to the underlying system.
- ///
- /// The context.
- /// The nodes to write.
- /// The errors.
- /// The nodes to validate.
- /// The cache.
- protected override void Write(
- ServerSystemContext context,
- IList nodesToWrite,
- IList errors,
- List nodesToValidate,
- IDictionary cache)
- {
- ComDaClientManager system = (ComDaClientManager)this.SystemContext.SystemHandle;
- ComDaClient client = system.SelectClient((ServerSystemContext)SystemContext, false);
-
- WriteRequestCollection requests = new WriteRequestCollection();
-
- // validates the nodes and queues an write requests.
- for (int ii = 0; ii < nodesToValidate.Count; ii++)
- {
- NodeHandle handle = nodesToValidate[ii];
-
- lock (Lock)
- {
- // validate node.
- NodeState source = ValidateNode(context, handle, cache);
-
- if (source == null)
- {
- continue;
- }
-
- // determine if request can be sent to the server.
- bool queued = false;
- WriteValue nodeToWrite = nodesToWrite[handle.Index];
- errors[handle.Index] = requests.Add(source, nodeToWrite, handle.Index, out queued);
-
- if (queued)
- {
- continue;
- }
-
- // write the attribute value.
- errors[handle.Index] = source.WriteAttribute(
- context,
- nodeToWrite.AttributeId,
- nodeToWrite.ParsedIndexRange,
- nodeToWrite.Value);
-
- // updates to source finished - report changes to monitored items.
- source.ClearChangeMasks(context, false);
- }
- }
-
- // write to the server.
- client.Write(requests);
-
- // get the results from the requests sent to the server.
- for (int ii = 0; ii < requests.Count; ii++)
- {
- WriteRequest request = requests[ii];
- errors[request.Index] = request.GetResult();
- }
- }
- #endregion
-
- #region Overridden Methods
- ///
- /// Loads a node set from a file or resource and addes them to the set of predefined nodes.
- ///
- protected override NodeStateCollection LoadPredefinedNodes(ISystemContext context)
- {
- NodeStateCollection predefinedNodes = new NodeStateCollection();
- predefinedNodes.LoadFromBinaryResource(context, "Opc.Ua.Com.Common.Opc.Ua.Com.PredefinedNodes.uanodes", Assembly.GetAssembly(this.GetType()), true);
- return predefinedNodes;
- }
-
- ///
- /// Called when a batch of monitored items has been created.
- ///
- protected override void OnCreateMonitoredItemsComplete(ServerSystemContext context, IList monitoredItems)
- {
- ComDaClientManager system = (ComDaClientManager)this.SystemContext.SystemHandle;
- ComDaClient client = system.SelectClient(context, false);
-
- // use locale for session to find a subscription manager.
- SubscribeRequestManager manager = null;
-
- if (!m_subscriptionManagers.TryGetValue(client.Key, out manager))
- {
- m_subscriptionManagers[client.Key] = manager = new SubscribeRequestManager(context, client, 1000);
- }
-
- manager.CreateItems(context, monitoredItems);
-
- for (int ii = 0; ii < monitoredItems.Count; ii++)
- {
- m_monitoredItems[monitoredItems[ii].Id] = manager;
- }
- }
-
- ///
- /// Called when a batch of monitored items has been modified.
- ///
- protected override void OnModifyMonitoredItemsComplete(ServerSystemContext context, IList monitoredItems)
- {
- ComDaClientManager system = (ComDaClientManager)this.SystemContext.SystemHandle;
- ComDaClient client = system.SelectClient(context, false);
-
- // sort monitored items by the locale id used to create them.
- Dictionary> monitoredItemsByLocaleId = new Dictionary>();
-
- for (int ii = 0; ii < monitoredItems.Count; ii++)
- {
- // look up the manager that was previously used to create the monitor item.
- SubscribeRequestManager manager = null;
-
- if (!m_monitoredItems.TryGetValue(monitoredItems[ii].Id, out manager))
- {
- manager = m_subscriptionManagers[client.Key];
- }
-
- // add monitored item to a list of items for the locale of the manager.
- List subset = null;
-
- if (!monitoredItemsByLocaleId.TryGetValue(manager.Key, out subset))
- {
- monitoredItemsByLocaleId[manager.Key] = subset = new List();
- }
-
- subset.Add(monitoredItems[ii]);
- }
-
- // modify the the item.
- foreach (KeyValuePair> entry in monitoredItemsByLocaleId)
- {
- SubscribeRequestManager manager = null;
-
- if (m_subscriptionManagers.TryGetValue(entry.Key, out manager))
- {
- manager.ModifyItems(context, entry.Value);
- }
- }
- }
-
- ///
- /// Called when a batch of monitored items has been deleted.
- ///
- protected override void OnDeleteMonitoredItemsComplete(ServerSystemContext context, IList monitoredItems)
- {
- ComDaClientManager system = (ComDaClientManager)this.SystemContext.SystemHandle;
- ComDaClient client = system.SelectClient(context, false);
-
- // sort monitored items by the locale id used to create them.
- Dictionary> monitoredItemsByLocaleId = new Dictionary>();
-
- for (int ii = 0; ii < monitoredItems.Count; ii++)
- {
- // look up the manager that was previously used to create the monitor item.
- SubscribeRequestManager manager = null;
-
- if (!m_monitoredItems.TryGetValue(monitoredItems[ii].Id, out manager))
- {
- manager = m_subscriptionManagers[client.Key];
- }
-
- // add monitored item to a list of items for the locale of the manager.
- List subset = null;
-
- if (!monitoredItemsByLocaleId.TryGetValue(manager.Key, out subset))
- {
- monitoredItemsByLocaleId[manager.Key] = subset = new List();
- }
-
- subset.Add(monitoredItems[ii]);
- }
-
- // delete the items.
- foreach (KeyValuePair> entry in monitoredItemsByLocaleId)
- {
- SubscribeRequestManager manager = null;
-
- if (m_subscriptionManagers.TryGetValue(entry.Key, out manager))
- {
- manager.DeleteItems(context, entry.Value);
- }
- }
- }
-
- ///
- /// Called when a batch of monitored items has their monitoring mode changed.
- ///
- protected override void OnSetMonitoringModeComplete(ServerSystemContext context, IList monitoredItems)
- {
- OnModifyMonitoredItemsComplete(context, monitoredItems);
- }
-
- ///
- /// Creates a new set of monitored items for a set of variables.
- ///
- ///
- /// This method only handles data change subscriptions. Event subscriptions are created by the SDK.
- ///
- protected override ServiceResult CreateMonitoredItem(ServerSystemContext context, NodeHandle handle, uint subscriptionId, double publishingInterval, DiagnosticsMasks diagnosticsMasks, TimestampsToReturn timestampsToReturn, MonitoredItemCreateRequest itemToCreate, ref long globalIdCounter, out MonitoringFilterResult filterResult, out IMonitoredItem monitoredItem)
- {
- filterResult = null;
- monitoredItem = null;
-
- // validate parameters.
- MonitoringParameters parameters = itemToCreate.RequestedParameters;
-
- // validate attribute.
- if (!Attributes.IsValid(handle.Node.NodeClass, itemToCreate.ItemToMonitor.AttributeId))
- {
- return StatusCodes.BadAttributeIdInvalid;
- }
-
- NodeState cachedNode = AddNodeToComponentCache(context, handle, handle.Node);
-
- // check if the node is already being monitored.
- MonitoredNode2 monitoredNode = null;
-
- if (!MonitoredNodes.TryGetValue(handle.Node.NodeId, out monitoredNode))
- {
- MonitoredNodes[handle.Node.NodeId] = monitoredNode = new MonitoredNode2(this, cachedNode);
- }
-
- handle.Node = monitoredNode.Node;
- handle.MonitoredNode = monitoredNode;
-
- // create a globally unique identifier.
- uint monitoredItemId = Utils.IncrementIdentifier(ref globalIdCounter);
-
- // determine the sampling interval.
- double samplingInterval = itemToCreate.RequestedParameters.SamplingInterval;
-
- if (samplingInterval < 0)
- {
- samplingInterval = publishingInterval;
- }
-
- // ensure minimum sampling interval is not exceeded.
- if (itemToCreate.ItemToMonitor.AttributeId == Attributes.Value)
- {
- BaseVariableState variable = handle.Node as BaseVariableState;
-
- if (variable != null && samplingInterval < variable.MinimumSamplingInterval)
- {
- samplingInterval = variable.MinimumSamplingInterval;
- }
- }
-
- // put a large upper limit on sampling.
- if (samplingInterval == Double.MaxValue)
- {
- samplingInterval = 365 * 24 * 3600 * 1000.0;
- }
-
- // put an upper limit on queue size.
- uint queueSize = itemToCreate.RequestedParameters.QueueSize;
-
- if (queueSize > MaxQueueSize)
- {
- queueSize = MaxQueueSize;
- }
-
- // validate the monitoring filter.
- Range euRange = null;
- MonitoringFilter filterToUse = null;
-
- ServiceResult error = ValidateMonitoringFilter(
- context,
- handle,
- itemToCreate.ItemToMonitor.AttributeId,
- samplingInterval,
- queueSize,
- parameters.Filter,
- out filterToUse,
- out euRange,
- out filterResult);
-
- if (ServiceResult.IsBad(error))
- {
- return error;
- }
-
- // create the item.
- MonitoredItem datachangeItem = new ComMonitoredItem(
- Server,
- this,
- handle,
- subscriptionId,
- monitoredItemId,
- context.OperationContext.Session,
- itemToCreate.ItemToMonitor,
- diagnosticsMasks,
- timestampsToReturn,
- itemToCreate.MonitoringMode,
- itemToCreate.RequestedParameters.ClientHandle,
- filterToUse,
- filterToUse,
- euRange,
- samplingInterval,
- queueSize,
- itemToCreate.RequestedParameters.DiscardOldest,
- 0);
-
- // report the initial value.
- ReadInitialValue(context, handle, datachangeItem);
-
- // update monitored item list.
- monitoredItem = datachangeItem;
-
- // save the monitored item.
- monitoredNode.Add(datachangeItem);
-
- // report change.
- OnMonitoredItemCreated(context, handle, datachangeItem);
-
- return error;
- }
-
- #endregion
-
- #region Conversion Functions
- ///
- /// Converts a value to something the DA server can accept.
- ///
- /// The source value.
- /// The converted value.
- /// Any error from the conversion.
- public static int LocalToRemoteValue(Variant srcValue, out object dstValue)
- {
- dstValue = null;
-
- TypeInfo srcType = srcValue.TypeInfo;
-
- if (srcType == null)
- {
- srcType = TypeInfo.Construct(srcValue.Value);
- }
-
- if (srcType.BuiltInType <= BuiltInType.DateTime
- || srcType.BuiltInType == BuiltInType.ByteString) // OPC UA specification ver 1.02 compliant.
- {
- dstValue = srcValue.Value;
- return ResultIds.S_OK;
- }
-
- try
- {
- if (srcType.BuiltInType == BuiltInType.Variant && srcType.ValueRank >= 0)
- {
- dstValue = TypeInfo.CastArray((Array)srcValue.Value, BuiltInType.Variant, BuiltInType.Null, LocalToRemoteValue);
- return ResultIds.S_OK;
- }
- }
- catch (Exception)
- {
- return ResultIds.E_BADTYPE;
- }
-
- return ResultIds.E_BADTYPE;
- }
-
- ///
- /// Converts a DA value to a UA compatible type.
- ///
- /// The source value.
- /// The converted value.
- /// Any error from the conversion.
- public static int RemoteToLocalValue(object srcValue, out Variant dstValue)
- {
- object value = RemoteToLocalValue(srcValue, BuiltInType.Null, BuiltInType.Null);
- dstValue = new Variant(value);
- return ResultIds.S_OK;
- }
-
- ///
- /// Converts a UA value to something the DA server will accept.
- ///
- private static object LocalToRemoteValue(object srcValue, BuiltInType srcType, BuiltInType dstType)
- {
- if (srcType <= BuiltInType.DateTime)
- {
- return srcValue;
- }
-
- if (srcType == BuiltInType.Variant)
- {
- TypeInfo typeInfo = TypeInfo.Construct(srcValue);
- srcType = typeInfo.BuiltInType;
-
- if (typeInfo.ValueRank != ValueRanks.Scalar)
- {
- return TypeInfo.CastArray((Array)srcValue, srcType, BuiltInType.Null, LocalToRemoteValue);
- }
-
- return LocalToRemoteValue(srcValue, srcType, dstType);
- }
-
- throw new ServiceResultException(StatusCodes.BadTypeMismatch);
- }
-
- ///
- /// Converts a value to something the UA client can accept.
- ///
- private static object RemoteToLocalValue(object srcValue, BuiltInType srcType, BuiltInType dstType)
- {
- if (typeof(decimal).IsInstanceOfType(srcValue))
- {
- return ((decimal)srcValue).ToString();
- }
-
- if (typeof(decimal[]).IsInstanceOfType(srcValue))
- {
- return TypeInfo.CastArray((Array)srcValue, BuiltInType.Null, BuiltInType.String, RemoteToLocalValue);
- }
-
- return srcValue;
- }
- #endregion
-
- #region Private Methods
- #endregion
-
- #region Private Fields
- private ComDaClientManager m_system;
- private ComDaClientConfiguration m_configuration;
- private Dictionary m_subscriptionManagers;
- private Dictionary m_monitoredItems;
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/Da/ComDaDataCallback.cs b/ComIOP/Common/Client/Da/ComDaDataCallback.cs
deleted file mode 100644
index a84e33c40..000000000
--- a/ComIOP/Common/Client/Da/ComDaDataCallback.cs
+++ /dev/null
@@ -1,205 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using Opc.Ua;
-using Opc.Ua.Server;
-using Opc.Ua.Com;
-using Opc.Ua.Com.Client;
-using OpcRcw.Da;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// A class that implements the IOPCDataCallback interface.
- ///
- internal class ComDaDataCallback : OpcRcw.Da.IOPCDataCallback, IDisposable
- {
- #region Constructors
- ///
- /// Initializes the object with the containing subscription object.
- ///
- public ComDaDataCallback(ComDaGroup group)
- {
- // save group.
- m_group = group;
-
- // create connection point.
- m_connectionPoint = new ConnectionPoint(group.Unknown, typeof(OpcRcw.Da.IOPCDataCallback).GUID);
-
- // advise.
- m_connectionPoint.Advise(this);
- }
- #endregion
-
- #region IDisposable Members
- ///
- /// Frees any unmanaged resources.
- ///
- public void Dispose()
- {
- Dispose(true);
- }
-
- ///
- /// An overrideable version of the Dispose.
- ///
- protected virtual void Dispose(bool disposing)
- {
- if (m_connectionPoint != null)
- {
- if (disposing)
- {
- m_connectionPoint.Dispose();
- m_connectionPoint = null;
- }
- }
- }
- #endregion
-
- #region Public Properties
- ///
- /// Whether the callback is connected.
- ///
- public bool Connected
- {
- get
- {
- return m_connectionPoint != null;
- }
- }
- #endregion
-
- #region IOPCDataCallback Members
- ///
- /// Called when a data changed event is received.
- ///
- public void OnDataChange(
- int dwTransid,
- int hGroup,
- int hrMasterquality,
- int hrMastererror,
- int dwCount,
- int[] phClientItems,
- object[] pvValues,
- short[] pwQualities,
- System.Runtime.InteropServices.ComTypes.FILETIME[] pftTimeStamps,
- int[] pErrors)
- {
- try
- {
- // unmarshal item values.
- DaValue[] values = ComDaGroup.GetItemValues(
- dwCount,
- pvValues,
- pwQualities,
- pftTimeStamps,
- pErrors);
-
- // invoke the callback.
- m_group.OnDataChange(phClientItems, values);
- }
- catch (Exception e)
- {
- Utils.Trace(e, "Unexpected error processing OnDataChange callback.");
- }
- }
-
- ///
- /// Called when an asynchronous read operation completes.
- ///
- public void OnReadComplete(
- int dwTransid,
- int hGroup,
- int hrMasterquality,
- int hrMastererror,
- int dwCount,
- int[] phClientItems,
- object[] pvValues,
- short[] pwQualities,
- System.Runtime.InteropServices.ComTypes.FILETIME[] pftTimeStamps,
- int[] pErrors)
- {
- try
- {
- // unmarshal item values.
- DaValue[] values = ComDaGroup.GetItemValues(
- dwCount,
- pvValues,
- pwQualities,
- pftTimeStamps,
- pErrors);
-
- // invoke the callback.
- m_group.OnReadComplete(dwTransid, phClientItems, values);
- }
- catch (Exception e)
- {
- Utils.Trace(e, "Unexpected error processing OnReadComplete callback.");
- }
- }
-
- ///
- /// Called when an asynchronous write operation completes.
- ///
- public void OnWriteComplete(
- int dwTransid,
- int hGroup,
- int hrMastererror,
- int dwCount,
- int[] phClientItems,
- int[] pErrors)
- {
- try
- {
- m_group.OnWriteComplete(dwTransid, phClientItems, pErrors);
- }
- catch (Exception e)
- {
- Utils.Trace(e, "Unexpected error processing OnWriteComplete callback.");
- }
- }
-
- ///
- /// Called when an asynchronous operation is cancelled.
- ///
- public void OnCancelComplete(
- int dwTransid,
- int hGroup)
- {
- }
- #endregion
-
- #region Private Members
- private ComDaGroup m_group;
- private ConnectionPoint m_connectionPoint;
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/Da/ComDaGroup.cs b/ComIOP/Common/Client/Da/ComDaGroup.cs
deleted file mode 100644
index 43e3a8874..000000000
--- a/ComIOP/Common/Client/Da/ComDaGroup.cs
+++ /dev/null
@@ -1,1079 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using System.Text;
-using System.Globalization;
-using System.Security.Principal;
-using System.Threading;
-using System.Runtime.InteropServices;
-using Opc.Ua;
-using Opc.Ua.Server;
-using Opc.Ua.Com;
-using OpcRcw.Da;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// A wrapper for COM-DA group.
- ///
- internal class ComDaGroup : ComObject
- {
- #region Constructor
- ///
- /// Creates an empty group.
- ///
- /// The server that the group belongs to.
- /// if set to true if the group will received callbacks.
- public ComDaGroup(ComDaClient server, bool callbacksRequired)
- {
- m_server = server;
- m_clientHandle = Utils.IncrementIdentifier(ref m_groupCounter);
- m_serverHandle = 0;
- m_items = new List();
-
- if (callbacksRequired)
- {
- m_monitoredItems = new Dictionary();
- }
-
- // Utils.Trace("GROUP {0}", m_clientHandle);
- }
- #endregion
-
- #region IDisposable Members
- ///
- /// An overrideable version of the Dispose.
- ///
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- Utils.SilentDispose(m_callback);
- m_callback = null;
- }
-
- base.Dispose(disposing);
- }
-
- ///
- /// Releases all references to the server.
- ///
- protected override void ReleaseServer()
- {
- Utils.SilentDispose(m_callback);
- m_callback = null;
- base.ReleaseServer();
- }
- #endregion
-
- #region Public Properties
- ///
- /// Gets the group's client handle.
- ///
- /// The client handle.
- public int ClientHandle
- {
- get { return m_clientHandle; }
- }
-
- ///
- /// Gets the group's server handle.
- ///
- /// The server handle.
- public int ServerHandle
- {
- get { return m_serverHandle; }
- }
-
- ///
- /// The requested sampling interval for the group.
- ///
- public int SamplingInterval
- {
- get { return m_samplingInterval; }
- }
-
- ///
- /// The actual sampling interval for the group.
- ///
- public int ActualSamplingInterval
- {
- get { return m_actualSamplingInterval; }
- }
-
- ///
- /// The deadband applied to the group.
- ///
- public float Deadband
- {
- get { return m_deadband; }
- }
- #endregion
-
- ///
- /// Sets the monitored items associated with the item.
- ///
- /// The item.
- /// The monitored items.
- public void SetMonitoredItems(GroupItem item, MonitoredItem[] monitoredItems)
- {
- // check if callbacks are enabled.
- if (item == null || m_monitoredItems == null)
- {
- return;
- }
-
- // save the monitored items.
- lock (m_monitoredItems)
- {
- DataChangeInfo info = null;
-
- if (!m_monitoredItems.TryGetValue(item.ClientHandle, out info))
- {
- m_monitoredItems[item.ClientHandle] = info = new DataChangeInfo();
- }
-
- info.MonitoredItems = monitoredItems;
-
- // resend the last cached value.
- if (info.LastError != null || info.LastValue != null)
- {
- for (int ii = 0; ii < monitoredItems.Length; ii++)
- {
- monitoredItems[ii].QueueValue(info.LastValue, info.LastError);
- }
- }
- }
- }
-
- ///
- /// Stores the information used to report data changes.
- ///
- private class DataChangeInfo
- {
- public MonitoredItem[] MonitoredItems;
- public DataValue LastValue;
- public ServiceResult LastError;
- }
-
- ///
- /// Called when a data change event arrives.
- ///
- /// The client handles.
- /// The values.
- internal void OnDataChange(int[] clientHandles, DaValue[] values)
- {
- // check if callbacks are enabled.
- if (m_monitoredItems == null)
- {
- return;
- }
-
- // lookup client handle a report change directly to monitored item.
- lock (m_monitoredItems)
- {
- for (int ii = 0; ii < clientHandles.Length; ii++)
- {
- DataChangeInfo info = null;
-
- if (!m_monitoredItems.TryGetValue(clientHandles[ii], out info))
- {
- continue;
- }
-
- MonitoredItem[] monitoredItems = info.MonitoredItems;
-
- // convert the value to a UA value.
- info.LastValue = new DataValue();
- info.LastError = ReadRequest.GetItemValue(values[ii], info.LastValue, DiagnosticsMasks.All);
- info.LastValue.ServerTimestamp = DateTime.UtcNow;
-
- // queue the values.
- for (int jj = 0; jj < monitoredItems.Length; jj++)
- {
-
- if (info.LastValue.Value != null
- && info.LastValue.Value.GetType().IsArray
- && monitoredItems[jj].IndexRange.Count != info.LastValue.Value.GetType().GetArrayRank()
- && StatusCode.IsBad(info.LastValue.StatusCode))
- {
- info.LastValue.StatusCode = StatusCodes.BadIndexRangeNoData;
- }
-
- monitoredItems[jj].QueueValue(info.LastValue, info.LastError);
- }
- }
- }
- }
-
- ///
- /// Called when a asynchronous read completes.
- ///
- /// The request id.
- /// The client handles.
- /// The values.
- internal void OnReadComplete(int requestId, int[] clientHandles, DaValue[] values)
- {
- }
-
- ///
- /// Called when a asynchronous write completes.
- ///
- /// The request id.
- /// The client handles.
- /// The errors.
- internal void OnWriteComplete(int requestId, int[] clientHandles, int[] errors)
- {
- }
-
- ///
- /// Creates the group on the server if not already created.
- ///
- public void Create()
- {
- // Utils.Trace("CREATE");
-
- if (Unknown != null)
- {
- return;
- }
-
- int serverHandle = 0;
- int actualSamplingInterval = 0;
-
- object unknown = m_server.CreateGroup(
- m_clientHandle,
- m_samplingInterval,
- m_deadband,
- out serverHandle,
- out actualSamplingInterval);
-
- Unknown = unknown;
- m_serverHandle = serverHandle;
- m_actualSamplingInterval = actualSamplingInterval;
-
- // Utils.Trace(
- // "Group {0}/{1} Created({5}) {2}/{3}ms {4}%",
- // m_clientHandle,
- // m_serverHandle,
- // m_samplingInterval,
- // m_actualSamplingInterval,
- // m_deadband,
- // m_items.Count);
-
- // set up data change callback.
- if (m_monitoredItems != null)
- {
- try
- {
- m_callback = new ComDaDataCallback(this);
- }
- catch (Exception e)
- {
- Utils.Trace("Could not establish IOPCDataCallback.", e);
- }
- }
- }
-
- ///
- /// Deletes the group on the server if it has been created.
- ///
- public void Delete()
- {
- // Utils.Trace("DELETE");
-
- if (Unknown == null)
- {
- return;
- }
-
- // Utils.Trace(
- // "Group {0}/{1} Deleted({5}) {2}/{3}ms {4}%",
- // m_clientHandle,
- // m_serverHandle,
- // m_samplingInterval,
- // m_actualSamplingInterval,
- // m_deadband,
- // m_items.Count);
-
- m_server.RemoveGroup(m_serverHandle);
- ReleaseServer();
- }
-
- ///
- /// Modifies the group.
- ///
- /// The error. S_OK on success.
- public int ModifyGroup()
- {
- m_actualSamplingInterval = 0;
-
- int localeId = m_server.LocaleId;
-
- GCHandle hSamplingInterval = GCHandle.Alloc(m_samplingInterval, GCHandleType.Pinned);
- GCHandle hDeadband = GCHandle.Alloc(m_deadband, GCHandleType.Pinned);
-
- string methodName = "IOPCGroupStateMgt.SetState";
-
- try
- {
- IOPCGroupStateMgt server = BeginComCall(methodName, true);
-
- server.SetState(
- hSamplingInterval.AddrOfPinnedObject(),
- out m_actualSamplingInterval,
- IntPtr.Zero,
- IntPtr.Zero,
- hDeadband.AddrOfPinnedObject(),
- IntPtr.Zero,
- IntPtr.Zero);
-
- /*
- Utils.Trace(
- "Group {0} Modified({4}) {1}/{2}ms {3}%",
- m_clientHandle,
- m_samplingInterval,
- m_actualSamplingInterval,
- m_deadband,
- m_items.Count);
- */
-
- return ResultIds.S_OK;
- }
- catch (Exception e)
- {
- ComUtils.TraceComError(e, methodName);
- return Marshal.GetHRForException(e);
- }
- finally
- {
- EndComCall(methodName);
- hSamplingInterval.Free();
- hDeadband.Free();
- }
- }
-
- ///
- /// Creates the item.
- ///
- /// The item id.
- /// The sampling interval.
- /// The deadband.
- /// if set to true [active].
- ///
- /// The item that was added to the group. Null if the item could not be added.
- ///
- public GroupItem CreateItem(string itemId, int samplingInterval, float deadband, bool active)
- {
- // set the group parameters if this is the first item.
- if (m_items.Count == 0)
- {
- m_samplingInterval = samplingInterval;
- m_deadband = deadband;
- }
-
- // check if the item can be added to the group.
- if (m_samplingInterval != samplingInterval || m_deadband != deadband)
- {
- return null;
- }
-
- // create the item.
- GroupItem item = new GroupItem();
-
- item.ItemId = itemId;
- item.ClientHandle = Utils.IncrementIdentifier(ref m_itemCounter);
- item.ServerHandle = 0;
- item.Active = active;
- item.ActiveChanged = false;
- item.Deleted = false;
- item.Created = false;
- item.ErrorId = 0;
-
- lock (Lock)
- {
- m_items.Add(item);
- }
-
- return item;
- }
-
- ///
- /// Modifies the item.
- ///
- /// The item.
- /// The sampling interval.
- /// The deadband.
- /// if set to true [active].
- /// True if the item is in the group.
- public bool ModifyItem(GroupItem item, int samplingInterval, float deadband, bool active)
- {
- // check if the item can be added to the group.
- if (m_samplingInterval != samplingInterval || m_deadband != deadband)
- {
- // check if the item needs to be removed from the group.
- if (m_items.Count > 1)
- {
- item.Deleted = true;
- return false;
- }
-
- // update active state.
- item.ActiveChanged = active != item.Active;
- item.Active = active;
-
- // update the group parameters.
- m_samplingInterval = samplingInterval;
- m_deadband = deadband;
- m_updateRequired = true;
-
- return true;
- }
-
- // undelete the item.
- item.Deleted = false;
-
- // update active state.
- item.ActiveChanged = active != item.Active;
- item.Active = active;
-
- // nothing to do - the group matches the item.
- return true;
- }
-
- ///
- /// Removes the item from the group.
- ///
- /// The item.
- /// True if the item exists.
- public bool RemoveItem(GroupItem item)
- {
- // add the item if it does not exist.
- if (item == null)
- {
- return false;
- }
-
- // flag the item as deleted.
- item.Deleted = true;
- return true;
- }
-
- ///
- /// Adds all items to the group that have not already been added.
- ///
- public void AddItems()
- {
- // count the number of items to add.
- List itemsToAdd = new List();
-
- lock (Lock)
- {
- for (int ii = 0; ii < m_items.Count; ii++)
- {
- if (!m_items[ii].Created)
- {
- itemsToAdd.Add(m_items[ii]);
- }
- }
- }
-
- // check if nothing to do.
- if (itemsToAdd.Count == 0)
- {
- return;
- }
-
- // create item definitions.
- int count = itemsToAdd.Count;
- OpcRcw.Da.OPCITEMDEF[] definitions = new OpcRcw.Da.OPCITEMDEF[count];
-
- for (int ii = 0; ii < count; ii++)
- {
- definitions[ii] = new OpcRcw.Da.OPCITEMDEF();
-
- definitions[ii].szItemID = itemsToAdd[ii].ItemId;
- definitions[ii].bActive = (itemsToAdd[ii].Active) ? 1 : 0;
- definitions[ii].szAccessPath = String.Empty;
- definitions[ii].vtRequestedDataType = (short)VarEnum.VT_EMPTY;
- definitions[ii].hClient = itemsToAdd[ii].ClientHandle;
- }
-
- // initialize output parameters.
- IntPtr pResults = IntPtr.Zero;
- IntPtr pErrors = IntPtr.Zero;
-
- // add items to group.
- string methodName = "IOPCItemMgt.AddItems";
-
- try
- {
- IOPCItemMgt server = BeginComCall(methodName, true);
-
- server.AddItems(
- count,
- definitions,
- out pResults,
- out pErrors);
- }
- catch (Exception e)
- {
- ComUtils.TraceComError(e, methodName);
-
- for (int ii = 0; ii < itemsToAdd.Count; ii++)
- {
- itemsToAdd[ii].ErrorId = Marshal.GetHRForException(e);
- }
-
- return;
- }
- finally
- {
- EndComCall(methodName);
- }
-
- // unmarshal output parameters.
- int[] serverHandles = GetItemResults(ref pResults, count, true);
- int[] errors = ComUtils.GetInt32s(ref pErrors, count, true);
-
- // save handles and error codes.
- for (int ii = 0; ii < count; ii++)
- {
- GroupItem item = itemsToAdd[ii];
-
- item.ServerHandle = serverHandles[ii];
- item.ErrorId = errors[ii];
-
- if (item.ErrorId >= 0)
- {
- itemsToAdd[ii].Created = true;
- }
- }
-
- /*
- Utils.Trace(
- "Group {0} AddItems({4}/{5}) {1}/{2}ms {3}%",
- m_clientHandle,
- m_samplingInterval,
- m_actualSamplingInterval,
- m_deadband,
- itemsToAdd.Count,
- m_items.Count);
- */
- }
-
- ///
- /// Sets the active state for a set of items in a group.
- ///
- public void ActivateItems(bool active)
- {
- // count the number of items to activate.
- List itemsToActivate = new List();
-
- lock (Lock)
- {
- for (int ii = 0; ii < m_items.Count; ii++)
- {
- if (m_items[ii].ActiveChanged && m_items[ii].Active == active && m_items[ii].Created)
- {
- itemsToActivate.Add(m_items[ii]);
- }
- }
- }
-
- // check if nothing to do.
- if (itemsToActivate.Count == 0)
- {
- return;
- }
-
- // build list of items to remove.
- int count = itemsToActivate.Count;
- int[] serverHandles = new int[count];
-
- for (int ii = 0; ii < itemsToActivate.Count; ii++)
- {
- serverHandles[ii] = itemsToActivate[ii].ServerHandle;
- }
-
- // initialize output parameters.
- IntPtr pErrors = IntPtr.Zero;
-
- string methodName = "IOPCItemMgt.SetActiveState";
-
- try
- {
- IOPCItemMgt server = BeginComCall(methodName, true);
-
- server.SetActiveState(
- count,
- serverHandles,
- (active) ? 1 : 0,
- out pErrors);
- }
- catch (Exception e)
- {
- ComUtils.TraceComError(e, methodName);
-
- for (int ii = 0; ii < itemsToActivate.Count; ii++)
- {
- itemsToActivate[ii].ActiveChanged = false;
- itemsToActivate[ii].ErrorId = Marshal.GetHRForException(e);
- }
- }
- finally
- {
- EndComCall(methodName);
- }
-
- // free returned error array.
- int[] errors = ComUtils.GetInt32s(ref pErrors, count, true);
-
- // save error codes.
- for (int ii = 0; ii < count; ii++)
- {
- itemsToActivate[ii].ActiveChanged = false;
- itemsToActivate[ii].ErrorId = errors[ii];
- }
-
- /*
- Utils.Trace(
- "Group {0} ActivateItems({4}/{5}) {1}/{2}ms {3}%",
- m_clientHandle,
- m_samplingInterval,
- m_actualSamplingInterval,
- m_deadband,
- active,
- itemsToActivate.Count);
- */
- }
-
- ///
- /// Removes the items from the group that have been marked as deleted.
- ///
- public void RemoveItems()
- {
- // count the number of items to remove.
- List itemsToRemove = new List();
-
- lock (Lock)
- {
- List itemsToKeep = new List();
-
- for (int ii = 0; ii < m_items.Count; ii++)
- {
- if (m_items[ii].Deleted && m_items[ii].Created)
- {
- itemsToRemove.Add(m_items[ii]);
- continue;
- }
-
- itemsToKeep.Add(m_items[ii]);
- }
-
- m_items = itemsToKeep;
- }
-
- // check if nothing to do.
- if (itemsToRemove.Count == 0)
- {
- return;
- }
-
- // build list of items to remove.
- int count = itemsToRemove.Count;
- int[] serverHandles = new int[count];
-
- for (int ii = 0; ii < itemsToRemove.Count; ii++)
- {
- serverHandles[ii] = itemsToRemove[ii].ServerHandle;
-
- // remove the associated monitored items.
- if (m_monitoredItems != null)
- {
- lock (m_monitoredItems)
- {
- m_monitoredItems.Remove(itemsToRemove[ii].ClientHandle);
- }
- }
- }
-
- IntPtr pErrors = IntPtr.Zero;
-
- string methodName = "IOPCItemMgt.RemoveItems";
-
- try
- {
- IOPCItemMgt server = BeginComCall(methodName, true);
-
- // remove items.
- server.RemoveItems(
- count,
- serverHandles,
- out pErrors);
- }
- catch (Exception e)
- {
- ComUtils.TraceComError(e, methodName);
-
- for (int ii = 0; ii < itemsToRemove.Count; ii++)
- {
- itemsToRemove[ii].Created = false;
- itemsToRemove[ii].ErrorId = Marshal.GetHRForException(e);
- }
-
- return;
- }
- finally
- {
- EndComCall(methodName);
- }
-
- // free returned error array.
- int[] errors = ComUtils.GetInt32s(ref pErrors, count, true);
-
- // save error codes.
- for (int ii = 0; ii < count; ii++)
- {
- itemsToRemove[ii].Created = false;
- itemsToRemove[ii].ErrorId = errors[ii];
- }
-
- /*
- Utils.Trace(
- "Group {0} RemoveItems({4}/{5}) {1}/{2}ms {3}%",
- m_clientHandle,
- m_samplingInterval,
- m_actualSamplingInterval,
- m_deadband,
- itemsToRemove.Count,
- m_items.Count);
- */
- }
-
- ///
- /// Reads the values for a set of items.
- ///
- public DaValue[] SyncRead(int[] serverHandles, int count)
- {
- // initialize output parameters.
- IntPtr pValues = IntPtr.Zero;
- IntPtr pErrors = IntPtr.Zero;
-
- if (count > 0)
- {
- string methodName = "IOPCSyncIO.Read";
-
- try
- {
- IOPCSyncIO server = BeginComCall(methodName, true);
-
- server.Read(
- OPCDATASOURCE.OPC_DS_DEVICE,
- count,
- serverHandles,
- out pValues,
- out pErrors);
- }
- catch (Exception e)
- {
- ComUtils.TraceComError(e, methodName);
- return null;
- }
- finally
- {
- EndComCall(methodName);
- }
- }
-
- // unmarshal output parameters.
- DaValue[] values = GetItemValues(ref pValues, count, true);
-
- int[] errors = ComUtils.GetInt32s(ref pErrors, count, true);
-
- // save error codes.
- for (int ii = 0; ii < count; ii++)
- {
- values[ii].Error = errors[ii];
- }
-
- return values;
- }
-
- ///
- /// Writes the values for a set of items.
- ///
- public int[] SyncWrite(int[] serverHandles, object[] values, int count)
- {
- // initialize output parameters.
- IntPtr pErrors = IntPtr.Zero;
-
- string methodName = "IOPCSyncIO.Write";
-
- try
- {
- IOPCSyncIO server = BeginComCall(methodName, true);
-
- server.Write(
- count,
- serverHandles,
- values,
- out pErrors);
- }
- catch (Exception e)
- {
- ComUtils.TraceComError(e, methodName);
- return null;
- }
- finally
- {
- EndComCall(methodName);
- }
-
- // unmarshal output parameters.
- return ComUtils.GetInt32s(ref pErrors, count, true);
- }
-
- #region Public Members
- ///
- /// Applys any changes to the group.
- ///
- /// True if the group contains a valid item.
- public bool ApplyChanges()
- {
- // create the group if it does not already exist.
- if (Unknown == null)
- {
- Create();
- }
-
- if (m_updateRequired)
- {
- ModifyGroup();
- m_updateRequired = false;
- }
-
- RemoveItems();
- AddItems();
- ActivateItems(true);
- ActivateItems(false);
-
- // check if at least one valid item.
- lock (Lock)
- {
- List clientHandles = new List();
- List values = new List();
-
- bool result = false;
-
- for (int ii = 0; ii < m_items.Count; ii++)
- {
- if (m_items[ii].Created)
- {
- result = true;
- }
-
- if (m_items[ii].ErrorId < 0)
- {
- if (clientHandles == null)
- {
- clientHandles = new List();
- values = new List();
- }
-
- clientHandles.Add(m_items[ii].ClientHandle);
- values.Add(new DaValue() { Error = m_items[ii].ErrorId, Timestamp = DateTime.UtcNow });
- }
-
- if (clientHandles != null)
- {
- OnDataChange(clientHandles.ToArray(), values.ToArray());
- }
- }
-
- return result;
- }
- }
- #endregion
-
- #region Private Methods
- ///
- /// Unmarshals and deallocates a OPCITEMRESULT structures.
- ///
- internal static int[] GetItemResults(ref IntPtr pInput, int count, bool deallocate)
- {
- int[] output = null;
-
- if (pInput != IntPtr.Zero && count > 0)
- {
- output = new int[count];
-
- IntPtr pos = pInput;
-
- for (int ii = 0; ii < count; ii++)
- {
- OpcRcw.Da.OPCITEMRESULT result = (OpcRcw.Da.OPCITEMRESULT)Marshal.PtrToStructure(pos, typeof(OpcRcw.Da.OPCITEMRESULT));
-
- output[ii] = result.hServer;
-
- if (deallocate)
- {
- if (result.pBlob != IntPtr.Zero)
- {
- Marshal.FreeCoTaskMem(result.pBlob);
- result.pBlob = IntPtr.Zero;
- result.dwBlobSize = 0;
- }
-
- Marshal.DestroyStructure(pos, typeof(OpcRcw.Da.OPCITEMRESULT));
- }
-
- pos = (IntPtr)(pos.ToInt32() + Marshal.SizeOf(typeof(OpcRcw.Da.OPCITEMRESULT)));
- }
-
- if (deallocate)
- {
- Marshal.FreeCoTaskMem(pInput);
- pInput = IntPtr.Zero;
- }
- }
-
- return output;
- }
-
- ///
- /// Unmarshals and deallocates a OPCITEMSTATE structures.
- ///
- internal static DaValue[] GetItemValues(ref IntPtr pInput, int count, bool deallocate)
- {
- DaValue[] output = null;
-
- if (pInput != IntPtr.Zero && count > 0)
- {
- output = new DaValue[count];
-
- IntPtr pos = pInput;
-
- for (int ii = 0; ii < count; ii++)
- {
- OpcRcw.Da.OPCITEMSTATE result = (OpcRcw.Da.OPCITEMSTATE)Marshal.PtrToStructure(pos, typeof(OpcRcw.Da.OPCITEMSTATE));
-
- DaValue value = new DaValue();
-
- value.Value = ComUtils.ProcessComValue(result.vDataValue);
- value.Quality = result.wQuality;
- value.Timestamp = ComUtils.GetDateTime(result.ftTimeStamp);
-
- output[ii] = value;
-
- if (deallocate)
- {
- Marshal.DestroyStructure(pos, typeof(OpcRcw.Da.OPCITEMSTATE));
- }
-
- pos = (IntPtr)(pos.ToInt32() + Marshal.SizeOf(typeof(OpcRcw.Da.OPCITEMSTATE)));
- }
-
- if (deallocate)
- {
- Marshal.FreeCoTaskMem(pInput);
- pInput = IntPtr.Zero;
- }
- }
-
- return output;
- }
-
- ///
- /// Creates an array of item value result objects from the callback data.
- ///
- internal static DaValue[] GetItemValues(
- int dwCount,
- object[] pvValues,
- short[] pwQualities,
- System.Runtime.InteropServices.ComTypes.FILETIME[] pftTimeStamps,
- int[] pErrors)
- {
- // contruct the item value results.
- DaValue[] values = new DaValue[dwCount];
-
- for (int ii = 0; ii < dwCount; ii++)
- {
- DaValue value = values[ii] = new DaValue();
-
- value.Error = pErrors[ii];
-
- if (pErrors[ii] >= 0)
- {
- value.Value = ComUtils.ProcessComValue(pvValues[ii]);
- value.Quality = pwQualities[ii];
- value.Timestamp = ComUtils.GetDateTime(pftTimeStamps[ii]);
- }
- }
-
- // return results
- return values;
- }
- #endregion
-
- #region Private Fields
- private static int m_groupCounter = 0;
- private static int m_itemCounter = 0;
- private ComDaClient m_server;
- private int m_clientHandle;
- private int m_serverHandle;
- private int m_samplingInterval;
- private int m_actualSamplingInterval;
- private float m_deadband;
- private bool m_updateRequired;
- private List m_items;
- private ComDaDataCallback m_callback;
- private Dictionary m_monitoredItems;
- #endregion
- }
-
- #region GroupItem Class
- ///
- /// An item that belongs to group.
- ///
- internal class GroupItem
- {
- public string ItemId;
- public int ServerHandle;
- public int ClientHandle;
- public int ErrorId;
- public bool Created;
- public bool Deleted;
- public bool Active;
- public bool ActiveChanged;
- }
- #endregion
-}
diff --git a/ComIOP/Common/Client/Da/ComMonitoredItem.cs b/ComIOP/Common/Client/Da/ComMonitoredItem.cs
deleted file mode 100644
index 3e77a4794..000000000
--- a/ComIOP/Common/Client/Da/ComMonitoredItem.cs
+++ /dev/null
@@ -1,104 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Opc.Ua.Server;
-
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// A handle that describes how to access a node/attribute via an i/o manager.
- ///
- public class ComMonitoredItem : MonitoredItem
- {
- #region Constructors
- ///
- /// Initializes the object with its node type.
- ///
- public ComMonitoredItem(
- IServerInternal server,
- INodeManager nodeManager,
- object mangerHandle,
- uint subscriptionId,
- uint id,
- Session session,
- ReadValueId itemToMonitor,
- DiagnosticsMasks diagnosticsMasks,
- TimestampsToReturn timestampsToReturn,
- MonitoringMode monitoringMode,
- uint clientHandle,
- MonitoringFilter originalFilter,
- MonitoringFilter filterToUse,
- Range range,
- double samplingInterval,
- uint queueSize,
- bool discardOldest,
- double sourceSamplingInterval)
- : base(server,
- nodeManager,
- mangerHandle,
- subscriptionId,
- id,
- itemToMonitor,
- diagnosticsMasks,
- timestampsToReturn,
- monitoringMode,
- clientHandle,
- originalFilter,
- filterToUse,
- range,
- samplingInterval,
- queueSize,
- discardOldest,
- sourceSamplingInterval)
- {
- }
- #endregion
-
- #region Private Methods
- ///
- /// Publishes a single data change notifications.
- ///
- protected override bool Publish(OperationContext context,
- Queue notifications,
- Queue diagnostics,
- DataValue value,
- ServiceResult error)
- {
- bool result = base.Publish(context, notifications, diagnostics, value, error);
- return result;
- }
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/Da/DaBranchState.cs b/ComIOP/Common/Client/Da/DaBranchState.cs
deleted file mode 100644
index 9d1967757..000000000
--- a/ComIOP/Common/Client/Da/DaBranchState.cs
+++ /dev/null
@@ -1,164 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using System.Xml;
-using System.IO;
-using System.Reflection;
-using System.Threading;
-using Opc.Ua;
-using Opc.Ua.Server;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// A object which maps a segment to a UA object.
- ///
- public partial class DaBranchState : FolderState
- {
- #region Constructors
- ///
- /// Initializes a new instance of the class.
- ///
- /// The context.
- /// The element.
- /// Index of the namespace.
- public DaBranchState(
- ISystemContext context,
- DaElement element,
- ushort namespaceIndex)
- :
- base(null)
- {
- this.TypeDefinitionId = Opc.Ua.ObjectTypeIds.FolderType;
- this.Description = null;
- this.WriteMask = 0;
- this.UserWriteMask = 0;
- this.EventNotifier = EventNotifiers.None;
-
- if (element != null)
- {
- Initialize(context, element, namespaceIndex);
- }
- }
- #endregion
-
- #region Public Interface
- ///
- /// Gets the item id.
- ///
- /// The item id.
- public string ItemId
- {
- get
- {
- if (m_element != null)
- {
- return m_element.ItemId;
- }
-
- return null;
- }
- }
-
- ///
- /// Gets the element.
- ///
- /// The element.
- public DaElement Element
- {
- get { return m_element; }
- }
-
- ///
- /// Initializes the node from the element.
- ///
- /// The context.
- /// The element.
- /// Index of the namespace.
- public void Initialize(ISystemContext context, DaElement element, ushort namespaceIndex)
- {
- m_element = element;
-
- if (element == null)
- {
- return;
- }
-
- this.NodeId = DaModelUtils.ConstructIdForDaElement(element.ItemId, -1, namespaceIndex);
- this.BrowseName = new QualifiedName(element.Name, namespaceIndex);
- this.DisplayName = new LocalizedText(element.Name);
- }
-
- ///
- /// Creates a browser that finds the references to the branch.
- ///
- /// The system context to use.
- /// The view which may restrict the set of references/nodes found.
- /// The type of references being followed.
- /// Whether subtypes of the reference type are followed.
- /// Which way the references are being followed.
- /// The browse name of a specific target (used when translating browse paths).
- /// Any additional references that should be included.
- /// If true the browser should not making blocking calls to external systems.
- /// The browse object (must be disposed).
- public override INodeBrowser CreateBrowser(
- ISystemContext context,
- ViewDescription view,
- NodeId referenceType,
- bool includeSubtypes,
- BrowseDirection browseDirection,
- QualifiedName browseName,
- IEnumerable additionalReferences,
- bool internalOnly)
- {
- NodeBrowser browser = new DaElementBrowser(
- context,
- view,
- referenceType,
- includeSubtypes,
- browseDirection,
- browseName,
- additionalReferences,
- internalOnly,
- this.ItemId,
- this.NodeId.NamespaceIndex);
-
- PopulateBrowser(context, browser);
-
- return browser;
- }
- #endregion
-
- #region Private Fields
- private DaElement m_element;
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/Da/DaElement.cs b/ComIOP/Common/Client/Da/DaElement.cs
deleted file mode 100644
index abdd89cdf..000000000
--- a/ComIOP/Common/Client/Da/DaElement.cs
+++ /dev/null
@@ -1,324 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using Opc.Ua;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// Stores information an element in the DA server address space.
- ///
- public class DaElement
- {
- #region Public Members
- ///
- /// Initializes a new instance of the class.
- ///
- public DaElement()
- {
- }
- #endregion
-
- #region Public Members
- ///
- /// Gets or sets the item id.
- ///
- /// The item id.
- public string ItemId
- {
- get { return m_itemId; }
- set { m_itemId = value; }
- }
-
- ///
- /// Gets or sets the name.
- ///
- /// The name.
- public string Name
- {
- get { return m_name; }
- set { m_name = value; }
- }
-
- ///
- /// Gets or sets the parent item id.
- ///
- /// The parent item id.
- public string ParentId
- {
- get { return m_parentId; }
- set { m_parentId = value; }
- }
-
- ///
- /// Gets or sets the type of the element.
- ///
- /// The type of the element.
- public DaElementType ElementType
- {
- get { return m_elementType; }
- set { m_elementType = value; }
- }
-
- ///
- /// Gets or sets the properties available for the element.
- ///
- /// The available properties.
- public DaProperty[] Properties
- {
- get { return m_properties; }
- set { m_properties = value; }
- }
-
- ///
- /// Gets or sets the COM data type for the value.
- ///
- /// The COM data type for the value.
- public short DataType
- {
- get { return m_dataType; }
- set { m_dataType = value; }
- }
-
- ///
- /// Gets or sets the access rights for the item.
- ///
- /// The access rights.
- public int AccessRights
- {
- get { return m_accessRights; }
- set { m_accessRights = value; }
- }
-
- ///
- /// Gets or sets the scan rate.
- ///
- /// The scan rate.
- public float ScanRate
- {
- get { return m_scanRate; }
- set { m_scanRate = value; }
- }
-
- ///
- /// Gets or sets the description.
- ///
- /// The description.
- public string Description
- {
- get { return m_description; }
- set { m_description = value; }
- }
-
- ///
- /// Gets or sets the engineering units.
- ///
- /// The engineering units.
- public string EngineeringUnits
- {
- get { return m_engineeringUnits; }
- set { m_engineeringUnits = value; }
- }
-
- ///
- /// Gets or sets EUType forthe item.
- ///
- /// The EUType for the item.
- public int EuType
- {
- get { return m_euType; }
- set { m_euType = value; }
- }
-
- ///
- /// Gets or sets the EU information for the item.
- ///
- /// The EU information for the item.
- public string[] EuInfo
- {
- get { return m_euInfo; }
- set { m_euInfo = value; }
- }
-
- ///
- /// Gets or sets the high EU value.
- ///
- /// The high EU value.
- public double HighEU
- {
- get { return m_highEU; }
- set { m_highEU = value; }
- }
-
- ///
- /// Gets or sets the low EU value.
- ///
- /// The low EU value.
- public double LowEU
- {
- get { return m_lowEU; }
- set { m_lowEU = value; }
- }
-
- ///
- /// Gets or sets the high IR value.
- ///
- /// The high IR value.
- public double HighIR
- {
- get { return m_highIR; }
- set { m_highIR = value; }
- }
-
- ///
- /// Gets or sets the low IR value.
- ///
- /// The low IR value.
- public double LowIR
- {
- get { return m_lowIR; }
- set { m_lowIR = value; }
- }
-
- ///
- /// Gets or sets the open label.
- ///
- /// The open label.
- public string OpenLabel
- {
- get { return m_openLabel; }
- set { m_openLabel = value; }
- }
-
- ///
- /// Gets or sets the close label.
- ///
- /// The close label.
- public string CloseLabel
- {
- get { return m_closeLabel; }
- set { m_closeLabel = value; }
- }
-
- ///
- /// Gets or sets the time zone for the item.
- ///
- /// The time zone.
- public int? TimeZone
- {
- get { return m_timeZone; }
- set { m_timeZone = value; }
- }
-
- ///
- /// Returns true if the element supports the specified property.
- ///
- /// The property id.
- /// Rrue if the element supports the specified property.
- public bool SupportsProperty(int propertyId)
- {
- if (m_properties != null)
- {
- for (int ii = 0; ii < m_properties.Length; ii++)
- {
- if (propertyId == m_properties[ii].PropertyId)
- {
- return true;
- }
- }
- }
-
- return false;
- }
- #endregion
-
- #region Private Methods
- #endregion
-
- #region Private Fields
- private string m_itemId;
- private string m_name;
- private string m_parentId;
- private DaElementType m_elementType;
- private DaProperty[] m_properties;
- private short m_dataType;
- private int m_accessRights;
- private float m_scanRate;
- private string m_description;
- private string m_engineeringUnits;
- private int m_euType;
- private string[] m_euInfo;
- private double m_highEU;
- private double m_lowEU;
- private double m_highIR;
- private double m_lowIR;
- private string m_openLabel;
- private string m_closeLabel;
- private int? m_timeZone;
- #endregion
- }
-
- ///
- /// The possible type of elements.
- ///
- public enum DaElementType
- {
- ///
- /// Unknown element type.
- ///
- Undefined = 0,
-
- ///
- /// A branch
- ///
- Branch = 1,
-
- ///
- /// An item.
- ///
- Item = 2,
-
- ///
- /// An analog item.
- ///
- AnalogItem = 3,
-
- ///
- /// An enumerated item.
- ///
- EnumeratedItem = 4,
-
- ///
- /// An digital item.
- ///
- DigitalItem = 5
- }
-}
diff --git a/ComIOP/Common/Client/Da/DaElementBrowser.cs b/ComIOP/Common/Client/Da/DaElementBrowser.cs
deleted file mode 100644
index f499f4da2..000000000
--- a/ComIOP/Common/Client/Da/DaElementBrowser.cs
+++ /dev/null
@@ -1,361 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using System.Xml;
-using System.IO;
-using System.Reflection;
-using System.Threading;
-using Opc.Ua;
-using Opc.Ua.Server;
-using Opc.Ua.Com;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// Browses the children of a segment.
- ///
- public class DaElementBrowser : NodeBrowser
- {
- #region Constructors
- ///
- /// Creates a new browser object with a set of filters.
- ///
- /// The system context to use.
- /// The view which may restrict the set of references/nodes found.
- /// The type of references being followed.
- /// Whether subtypes of the reference type are followed.
- /// Which way the references are being followed.
- /// The browse name of a specific target (used when translating browse paths).
- /// Any additional references that should be included.
- /// If true the browser should not making blocking calls to external systems.
- /// The item id.
- /// Index of the namespace.
- public DaElementBrowser(
- ISystemContext context,
- ViewDescription view,
- NodeId referenceType,
- bool includeSubtypes,
- BrowseDirection browseDirection,
- QualifiedName browseName,
- IEnumerable additionalReferences,
- bool internalOnly,
- string itemId,
- ushort namespaceIndex)
- :
- base(
- context,
- view,
- referenceType,
- includeSubtypes,
- browseDirection,
- browseName,
- additionalReferences,
- internalOnly)
- {
- m_itemId = itemId;
- m_namespaceIndex = namespaceIndex;
- m_stage = Stage.Begin;
- }
- #endregion
-
- #region Overridden Methods
- ///
- /// An overrideable version of the Dispose.
- ///
- /// True if being called explicitly
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- Utils.SilentDispose(m_browser);
- m_browser = null;
- }
-
- base.Dispose(disposing);
- }
-
- ///
- /// Returns the next reference.
- ///
- /// The next reference that meets the browse criteria.
- public override IReference Next()
- {
- lock (DataLock)
- {
- IReference reference = null;
-
- // enumerate pre-defined references.
- // always call first to ensure any pushed-back references are returned first.
- reference = base.Next();
-
- if (reference != null)
- {
- return reference;
- }
-
- // don't start browsing huge number of references when only internal references are requested.
- if (InternalOnly)
- {
- return null;
- }
-
- // fetch references from the server.
- do
- {
- // fetch next reference.
- reference = NextChild();
-
- if (reference != null)
- {
- return reference;
- }
-
- // go to the next stage.
- NextStage();
- }
- while (m_stage != Stage.Done);
-
- // all done.
- return null;
- }
- }
- #endregion
-
- #region Private Methods
- ///
- /// Returns the next child.
- ///
- private IReference NextChild()
- {
- // check if a specific browse name is requested.
- if (QualifiedName.IsNull(base.BrowseName))
- {
- return NextChild(m_stage);
- }
-
- // keep fetching references until a matching browse name if found.
- NodeStateReference reference = null;
-
- do
- {
- reference = NextChild(m_stage);
-
- if (reference != null)
- {
- // need to let the caller look up the browse name.
- if (reference.Target == null)
- {
- return reference;
- }
-
- // check for browse name match.
- if (reference.Target.BrowseName == base.BrowseName)
- {
- return reference;
- }
- }
- }
- while (reference != null);
-
- // no match - need to go onto the next stage.
- return null;
- }
-
- ///
- /// Returns the next child.
- ///
- private NodeStateReference NextChild(Stage stage)
- {
- ComDaClientManager system = (ComDaClientManager)this.SystemContext.SystemHandle;
- ComDaClient client = system.SelectClient((ServerSystemContext)SystemContext, false);
-
- DaElement element = null;
-
- if (stage == Stage.Children)
- {
- if (m_browser == null)
- {
- return null;
- }
-
- element = m_browser.Next();
-
- if (element == null)
- {
- return null;
- }
-
- // construct the node.
- NodeState node = DaModelUtils.ConstructElement(SystemContext, element, m_namespaceIndex);
-
- // return the reference.
- return new NodeStateReference(ReferenceTypeIds.Organizes, false, node);
- }
-
- if (stage == Stage.Properties)
- {
- if (m_properties == null)
- {
- return null;
- }
-
- for (int ii = m_position; ii < m_properties.Length; ii++)
- {
- if (m_properties[ii].PropertyId <= PropertyIds.TimeZone)
- {
- continue;
- }
-
- m_position = ii+1;
-
- // construct the node.
- NodeState node = DaModelUtils.ConstructProperty(SystemContext, m_itemId, m_properties[ii], m_namespaceIndex);
-
- // return the reference.
- return new NodeStateReference(ReferenceTypeIds.HasProperty, false, node);
- }
-
- // all done.
- return null;
- }
-
- if (stage == Stage.Parents)
- {
- if (m_parentId != null)
- {
- NodeId parentId = DaModelUtils.ConstructIdForDaElement(m_parentId, -1, m_namespaceIndex);
- m_parentId = null;
- return new NodeStateReference(ReferenceTypeIds.Organizes, true, parentId);
- }
- }
-
- return null;
- }
-
- ///
- /// Initializes the next stage of browsing.
- ///
- private void NextStage()
- {
- ComDaClientManager system = (ComDaClientManager)this.SystemContext.SystemHandle;
- ComDaClient client = system.SelectClient((ServerSystemContext)SystemContext, false);
-
- // determine which stage is next based on the reference types requested.
- for (Stage next = m_stage+1; next <= Stage.Done; next++)
- {
- if (next == Stage.Children)
- {
- if (IsRequired(ReferenceTypeIds.Organizes, false))
- {
- m_stage = next;
- break;
- }
- }
-
- else if (next == Stage.Properties)
- {
- if (IsRequired(ReferenceTypeIds.HasProperty, false))
- {
- m_stage = next;
- break;
- }
- }
-
- else if (next == Stage.Parents)
- {
- if (IsRequired(ReferenceTypeIds.Organizes, true))
- {
- m_stage = next;
- break;
- }
- }
-
- else if (next == Stage.Done)
- {
- m_stage = next;
- break;
- }
- }
-
- m_position = 0;
-
- // start enumerating branches.
- if (m_stage == Stage.Children)
- {
- m_browser = client.CreateBrowser(m_itemId);
- return;
- }
-
- // start enumerating properties.
- if (m_stage == Stage.Properties)
- {
- m_properties = client.ReadAvailableProperties(m_itemId, true);
- m_position = 0;
- return;
- }
-
- // start enumerating parents.
- if (m_stage == Stage.Parents)
- {
- m_parentId = client.FindElementParentId(m_itemId);
- return;
- }
-
- // all done.
- }
-
- #endregion
-
- #region Stage Enumeration
- ///
- /// The stages available in a browse operation.
- ///
- private enum Stage
- {
- Begin,
- Children,
- Properties,
- Parents,
- Done
- }
- #endregion
-
- #region Private Fields
- private Stage m_stage;
- private string m_itemId;
- private ushort m_namespaceIndex;
- private DaProperty[] m_properties;
- private int m_position;
- private string m_parentId;
- private IDaElementBrowser m_browser;
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/Da/DaItemState.cs b/ComIOP/Common/Client/Da/DaItemState.cs
deleted file mode 100644
index b91bf7e8e..000000000
--- a/ComIOP/Common/Client/Da/DaItemState.cs
+++ /dev/null
@@ -1,281 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using System.Xml;
-using System.IO;
-using System.Reflection;
-using System.Threading;
-using Opc.Ua;
-using Opc.Ua.Server;
-using Opc.Ua.Com;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// A object which maps a COM DA item to a UA variable.
- ///
- public partial class DaItemState : BaseDataVariableState
- {
- #region Constructors
- ///
- /// Initializes a new instance of the class.
- ///
- /// The context.
- /// The element.
- /// Index of the namespace.
- public DaItemState(
- ISystemContext context,
- DaElement element,
- ushort namespaceIndex)
- :
- base(null)
- {
- this.TypeDefinitionId = Opc.Ua.VariableTypeIds.DataItemType;
- this.Description = null;
- this.WriteMask = 0;
- this.UserWriteMask = 0;
-
- if (element != null)
- {
- Initialize(context, element, namespaceIndex);
- }
- }
- #endregion
-
- #region Public Interface
- ///
- /// Gets the item id.
- ///
- /// The item id.
- public string ItemId
- {
- get
- {
- if (m_element != null)
- {
- return m_element.ItemId;
- }
-
- return null;
- }
- }
-
- ///
- /// Gets the element.
- ///
- /// The element.
- public DaElement Element
- {
- get { return m_element; }
- }
-
- ///
- /// Initializes the node from the element.
- ///
- /// The context.
- /// The element.
- /// Index of the namespace.
- public void Initialize(ISystemContext context, DaElement element, ushort namespaceIndex)
- {
- m_element = element;
-
- if (element == null)
- {
- return;
- }
-
- this.NodeId = DaModelUtils.ConstructIdForDaElement(element.ItemId, -1, namespaceIndex);
- this.BrowseName = new QualifiedName(element.Name, namespaceIndex);
- this.DisplayName = new LocalizedText(element.Name);
-
- // check if TimeZone is supported.
- if (element.TimeZone != null)
- {
- PropertyState property = this.AddProperty(Opc.Ua.BrowseNames.LocalTime, DataTypeIds.TimeZoneDataType, ValueRanks.Scalar);
- property.NodeId = DaModelUtils.ConstructIdForComponent(property, namespaceIndex);
- property.Value = new Range(element.HighIR, element.LowIR);
- }
-
- // set the TypeDefinition based on the ElementType.
- switch (element.ElementType)
- {
- case DaElementType.AnalogItem:
- {
- this.TypeDefinitionId = Opc.Ua.VariableTypeIds.AnalogItemType;
-
- // EURange is always present.
- PropertyState property = this.AddProperty(Opc.Ua.BrowseNames.EURange, DataTypeIds.Range, ValueRanks.Scalar);
- property.NodeId = DaModelUtils.ConstructIdForComponent(property, namespaceIndex);
- property.Value = new Range(element.HighEU, element.LowEU);
-
- // check if InstrumentRange is supported.
- if (element.HighIR != 0 || element.LowIR != 0)
- {
- property = this.AddProperty(Opc.Ua.BrowseNames.InstrumentRange, DataTypeIds.Range, ValueRanks.Scalar);
- property.NodeId = DaModelUtils.ConstructIdForComponent(property, namespaceIndex);
- property.Value = new Range(element.HighIR, element.LowIR);
- }
-
- // check if EngineeringUnits is supported.
- if (element.EngineeringUnits != null)
- {
- property = this.AddProperty(Opc.Ua.BrowseNames.EngineeringUnits, DataTypeIds.EUInformation, ValueRanks.Scalar);
- property.NodeId = DaModelUtils.ConstructIdForComponent(property, namespaceIndex);
-
- // use the server's namespace uri to qualify the engineering units.
- string namespaceUri = context.NamespaceUris.GetString(namespaceIndex);
- property.Value = new EUInformation(element.EngineeringUnits, namespaceUri);
- }
-
- break;
- }
-
- case DaElementType.DigitalItem:
- {
- this.TypeDefinitionId = Opc.Ua.VariableTypeIds.TwoStateDiscreteType;
-
- // check if CloseLabel is supported.
- if (element.CloseLabel != null)
- {
- PropertyState property = this.AddProperty(Opc.Ua.BrowseNames.TrueState, DataTypeIds.LocalizedText, ValueRanks.Scalar);
- property.NodeId = DaModelUtils.ConstructIdForComponent(property, namespaceIndex);
- property.Value = element.CloseLabel;
- }
-
- // check if OpenLabel is supported.
- if (element.OpenLabel != null)
- {
- PropertyState property = this.AddProperty(Opc.Ua.BrowseNames.FalseState, DataTypeIds.LocalizedText, ValueRanks.Scalar);
- property.NodeId = DaModelUtils.ConstructIdForComponent(property, namespaceIndex);
- property.Value = element.OpenLabel;
- }
-
- break;
- }
-
- case DaElementType.EnumeratedItem:
- {
- this.TypeDefinitionId = Opc.Ua.VariableTypeIds.MultiStateDiscreteType;
-
- // check if EuInfo is supported.
- if (element.EuInfo != null)
- {
- PropertyState property = this.AddProperty(Opc.Ua.BrowseNames.EnumStrings, DataTypeIds.LocalizedText, ValueRanks.OneDimension);
- property.NodeId = DaModelUtils.ConstructIdForComponent(property, namespaceIndex);
-
- LocalizedText[] strings = new LocalizedText[element.EuInfo.Length];
-
- for (int ii = 0; ii < strings.Length; ii++)
- {
- strings[ii] = element.EuInfo[ii];
- }
-
- property.Value = strings;
- }
-
- break;
- }
- }
-
- if (element.Description != null)
- {
- this.Description = element.Description;
- }
-
- this.Value = null;
- this.StatusCode = StatusCodes.BadWaitingForInitialData;
- this.Timestamp = DateTime.UtcNow;
-
- bool isArray = false;
- this.DataType = ComUtils.GetDataTypeId(element.DataType, out isArray);
- this.ValueRank = (isArray)?ValueRanks.OneOrMoreDimensions:ValueRanks.Scalar;
-
- this.AccessLevel = AccessLevels.None;
-
- if ((element.AccessRights & OpcRcw.Da.Constants.OPC_READABLE) != 0)
- {
- this.AccessLevel |= AccessLevels.CurrentRead;
- }
-
- if ((element.AccessRights & OpcRcw.Da.Constants.OPC_WRITEABLE) != 0)
- {
- this.AccessLevel |= AccessLevels.CurrentWrite;
- }
-
- this.UserAccessLevel = this.AccessLevel;
- this.MinimumSamplingInterval = element.ScanRate;
- }
-
- ///
- /// Creates a browser that finds the references to the branch.
- ///
- /// The system context to use.
- /// The view which may restrict the set of references/nodes found.
- /// The type of references being followed.
- /// Whether subtypes of the reference type are followed.
- /// Which way the references are being followed.
- /// The browse name of a specific target (used when translating browse paths).
- /// Any additional references that should be included.
- /// If true the browser should not making blocking calls to external systems.
- /// The browse object (must be disposed).
- public override INodeBrowser CreateBrowser(
- ISystemContext context,
- ViewDescription view,
- NodeId referenceType,
- bool includeSubtypes,
- BrowseDirection browseDirection,
- QualifiedName browseName,
- IEnumerable additionalReferences,
- bool internalOnly)
- {
- NodeBrowser browser = new DaElementBrowser(
- context,
- view,
- referenceType,
- includeSubtypes,
- browseDirection,
- browseName,
- additionalReferences,
- internalOnly,
- this.ItemId,
- this.NodeId.NamespaceIndex);
-
- PopulateBrowser(context, browser);
-
- return browser;
- }
- #endregion
-
- #region Private Fields
- private DaElement m_element;
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/Da/DaModelUtils.cs b/ComIOP/Common/Client/Da/DaModelUtils.cs
deleted file mode 100644
index 248af068f..000000000
--- a/ComIOP/Common/Client/Da/DaModelUtils.cs
+++ /dev/null
@@ -1,141 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using System.Text;
-using Opc.Ua;
-using Opc.Ua.Server;
-using Opc.Ua.Com;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// A class that builds NodeIds used by the DataAccess NodeManager
- ///
- public static class DaModelUtils
- {
- ///
- /// The RootType for a DA Branch or Item.
- ///
- public const int DaElement = 0;
-
- ///
- /// The RootType for a DA Property identified by its property id.
- ///
- public const int DaProperty = 2;
-
- ///
- /// The RootType for a node defined by the UA server.
- ///
- public const int InternalNode = 3;
-
- ///
- /// Constructs a NodeId from the BrowseName of an internal node.
- ///
- /// The browse name.
- /// Index of the namespace.
- /// The node id.
- public static NodeId ConstructIdForInternalNode(QualifiedName browseName, ushort namespaceIndex)
- {
- ParsedNodeId parsedNodeId = new ParsedNodeId();
-
- parsedNodeId.RootId = browseName.Name;
- parsedNodeId.NamespaceIndex = namespaceIndex;
- parsedNodeId.RootType = InternalNode;
-
- return parsedNodeId.Construct();
- }
-
- ///
- /// Constructs a NodeId from the ItemId for a DA branch.
- ///
- /// The item id.
- /// The property id.
- /// Index of the namespace.
- /// The node id.
- public static NodeId ConstructIdForDaElement(string itemId, int propertyId, ushort namespaceIndex)
- {
- DaParsedNodeId parsedNodeId = new DaParsedNodeId();
-
- parsedNodeId.RootId = itemId;
- parsedNodeId.NamespaceIndex = namespaceIndex;
- parsedNodeId.RootType = DaElement;
-
- if (propertyId >= 0)
- {
- parsedNodeId.PropertyId = propertyId;
- parsedNodeId.RootType = DaProperty;
- }
-
- return parsedNodeId.Construct();
- }
-
- ///
- /// Constructs the node identifier for a component.
- ///
- /// The component.
- /// Index of the namespace.
- /// The node identifier for a component.
- public static NodeId ConstructIdForComponent(NodeState component, ushort namespaceIndex)
- {
- return ParsedNodeId.ConstructIdForComponent(component, namespaceIndex);
- }
-
- ///
- /// Constructs a branch or item node from a DaElement returned from the COM server.
- ///
- /// The context.
- /// The element.
- /// Index of the namespace for the NodeId.
- /// The node.
- public static NodeState ConstructElement(ISystemContext context, DaElement element, ushort namespaceIndex)
- {
- if (element.ElementType == DaElementType.Branch)
- {
- return new DaBranchState(context, element, namespaceIndex);
- }
-
- return new DaItemState(context, element, namespaceIndex);
- }
-
- ///
- /// Constructs a property node for a DA property.
- ///
- /// The context.
- /// The parent id.
- /// The property.
- /// Index of the namespace.
- /// The property node.
- public static PropertyState ConstructProperty(ISystemContext context, string parentId, DaProperty property, ushort namespaceIndex)
- {
- return new DaPropertyState(context, parentId, property, namespaceIndex);
- }
- }
-}
diff --git a/ComIOP/Common/Client/Da/DaParseNodeId.cs b/ComIOP/Common/Client/Da/DaParseNodeId.cs
deleted file mode 100644
index 1a36c9650..000000000
--- a/ComIOP/Common/Client/Da/DaParseNodeId.cs
+++ /dev/null
@@ -1,239 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Text;
-using System.Collections.Generic;
-using System.Reflection;
-using Opc.Ua;
-using Opc.Ua.Server;
-
-namespace Opc.Ua.Com.Client
-{
- #region DaParsedNodeId Class
- ///
- /// Stores the elements of a NodeId after it is parsed.
- ///
- ///
- /// The NodeIds used by the samples are strings with an optional path appended.
- /// The RootType identifies the type of Root Node. The RootId is the unique identifier
- /// for the Root Node. The ComponentPath is constructed from the SymbolicNames
- /// of one or more children of the Root Node.
- ///
- public class DaParsedNodeId : ParsedNodeId
- {
- #region Public Interface
- ///
- /// The identifier for the property identifier.
- ///
- public int PropertyId
- {
- get { return m_propertyId; }
- set { m_propertyId = value; }
- }
-
- ///
- /// Parses the specified node identifier.
- ///
- /// The node identifier.
- /// The parsed node identifier. Null if the identifier cannot be parsed.
- public static new DaParsedNodeId Parse(NodeId nodeId)
- {
- // can only parse non-null string node identifiers.
- if (NodeId.IsNull(nodeId))
- {
- return null;
- }
-
- string identifier = nodeId.Identifier as string;
-
- if (String.IsNullOrEmpty(identifier))
- {
- return null;
- }
-
- DaParsedNodeId parsedNodeId = new DaParsedNodeId();
- parsedNodeId.NamespaceIndex = nodeId.NamespaceIndex;
-
- // extract the type of identifier.
- parsedNodeId.RootType = 0;
-
- int start = 0;
-
- for (int ii = 0; ii < identifier.Length; ii++)
- {
- if (!Char.IsDigit(identifier[ii]))
- {
- start = ii;
- break;
- }
-
- parsedNodeId.RootType *= 10;
- parsedNodeId.RootType += (byte)(identifier[ii] - '0');
- }
-
- if (start >= identifier.Length || identifier[start] != ':')
- {
- return null;
- }
-
- // extract any component path.
- StringBuilder buffer = new StringBuilder();
-
- int index = start+1;
- int end = identifier.Length;
-
- bool escaped = false;
-
- while (index < end)
- {
- char ch = identifier[index++];
-
- // skip any escape character but keep the one after it.
- if (ch == '&')
- {
- escaped = true;
- continue;
- }
-
- if (!escaped && ch == '?')
- {
- end = index;
- break;
- }
-
- buffer.Append(ch);
- escaped = false;
- }
-
- // extract any component.
- parsedNodeId.RootId = buffer.ToString();
- parsedNodeId.ComponentPath = null;
-
- if (parsedNodeId.RootType == DaModelUtils.DaProperty)
- {
- // must have the property id.
- if (end >= identifier.Length)
- {
- return null;
- }
-
- // extract the property id.
- for (int ii = end; ii < identifier.Length; ii++)
- {
- end++;
-
- if (!Char.IsDigit(identifier[ii]))
- {
- // check for terminator.
- if (identifier[ii] != ':')
- {
- return null;
- }
-
- break;
- }
-
- parsedNodeId.PropertyId *= 10;
- parsedNodeId.PropertyId += (byte)(identifier[ii] - '0');
- }
- }
-
- // extract the component path.
- if (end < identifier.Length)
- {
- parsedNodeId.ComponentPath = identifier.Substring(end);
- }
-
- return parsedNodeId;
- }
-
- ///
- /// Constructs a node identifier.
- ///
- /// The node identifier.
- public new NodeId Construct()
- {
- StringBuilder buffer = new StringBuilder();
-
- // add the root type.
- buffer.Append(RootType);
- buffer.Append(':');
-
- // add the root identifier.
- if (this.RootId != null)
- {
- for (int ii = 0; ii < this.RootId.Length; ii++)
- {
- char ch = this.RootId[ii];
-
- // escape any special characters.
- if (ch == '&' || ch == '?')
- {
- buffer.Append('&');
- }
-
- buffer.Append(ch);
- }
- }
-
- // add property id.
- if (this.RootType == DaModelUtils.DaProperty)
- {
- buffer.Append('?');
- buffer.Append(this.PropertyId);
-
- // add the component path.
- if (!String.IsNullOrEmpty(this.ComponentPath))
- {
- buffer.Append(':');
- buffer.Append(this.ComponentPath);
- }
- }
- else
- {
- // add the component path.
- if (!String.IsNullOrEmpty(this.ComponentPath))
- {
- buffer.Append('?');
- buffer.Append(this.ComponentPath);
- }
- }
-
- // construct the node id with the namespace index provided.
- return new NodeId(buffer.ToString(), this.NamespaceIndex);
- }
- #endregion
-
- #region Private Fields
- private int m_propertyId;
- #endregion
- }
- #endregion
-}
diff --git a/ComIOP/Common/Client/Da/DaProperty.cs b/ComIOP/Common/Client/Da/DaProperty.cs
deleted file mode 100644
index a83ae7539..000000000
--- a/ComIOP/Common/Client/Da/DaProperty.cs
+++ /dev/null
@@ -1,99 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using Opc.Ua;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// Stores information an element in the DA server address space.
- ///
- public class DaProperty
- {
- #region Public Members
- ///
- /// Initializes a new instance of the class.
- ///
- public DaProperty()
- {
- }
- #endregion
-
- #region Public Members
- ///
- /// Gets or sets the property id.
- ///
- /// The property id.
- public int PropertyId
- {
- get { return m_propertyId; }
- set { m_propertyId = value; }
- }
-
- ///
- /// Gets or sets the name.
- ///
- /// The name.
- public string Name
- {
- get { return m_name; }
- set { m_name = value; }
- }
-
- ///
- /// Gets or sets the item id.
- ///
- /// The item id.
- public string ItemId
- {
- get { return m_itemId; }
- set { m_itemId = value; }
- }
-
- ///
- /// Gets or sets the COM data type.
- ///
- /// The COM data type for the property.
- public short DataType
- {
- get { return m_dataType; }
- set { m_dataType = value; }
- }
- #endregion
-
- #region Private Fields
- private int m_propertyId;
- private string m_name;
- private string m_itemId;
- private short m_dataType;
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/Da/DaPropertyState.cs b/ComIOP/Common/Client/Da/DaPropertyState.cs
deleted file mode 100644
index 1fe3c3016..000000000
--- a/ComIOP/Common/Client/Da/DaPropertyState.cs
+++ /dev/null
@@ -1,169 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using System.Xml;
-using System.IO;
-using System.Reflection;
-using System.Threading;
-using Opc.Ua;
-using Opc.Ua.Server;
-using Opc.Ua.Com;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// A object which maps a COM DA item to a UA variable.
- ///
- public partial class DaPropertyState : PropertyState
- {
- #region Constructors
- ///
- /// Initializes a new instance of the class.
- ///
- /// The context.
- /// The item id.
- /// The property.
- /// Index of the namespace.
- public DaPropertyState(
- ISystemContext context,
- string itemId,
- DaProperty property,
- ushort namespaceIndex)
- :
- base(null)
- {
- this.TypeDefinitionId = Opc.Ua.VariableTypeIds.DataItemType;
- this.Description = null;
- this.WriteMask = 0;
- this.UserWriteMask = 0;
-
- if (property != null)
- {
- Initialize(context, itemId, property, namespaceIndex);
- }
- }
- #endregion
-
- #region Public Interface
- ///
- /// Gets the item id.
- ///
- /// The item id.
- public string ItemId
- {
- get
- {
- return m_itemId;
- }
- }
-
- ///
- /// Gets the property id.
- ///
- /// The property id.
- public int PropertyId
- {
- get
- {
- if (m_property != null)
- {
- return m_property.PropertyId;
- }
-
- return -1;
- }
- }
-
- ///
- /// Gets the property description.
- ///
- /// The property description.
- public DaProperty Property
- {
- get { return m_property; }
- }
-
- ///
- /// Initializes the node from the element.
- ///
- /// The context.
- /// The item id.
- /// The property.
- /// Index of the namespace.
- public void Initialize(ISystemContext context, string itemId, DaProperty property, ushort namespaceIndex)
- {
- m_itemId = itemId;
- m_property = property;
-
- if (property == null)
- {
- return;
- }
-
- this.NodeId = DaModelUtils.ConstructIdForDaElement(m_itemId, property.PropertyId, namespaceIndex);
- this.BrowseName = new QualifiedName(property.Name, namespaceIndex);
- this.DisplayName = new LocalizedText(property.Name);
- this.TypeDefinitionId = Opc.Ua.VariableTypeIds.PropertyType;
- this.Value = null;
- this.StatusCode = StatusCodes.BadWaitingForInitialData;
- this.Timestamp = DateTime.UtcNow;
-
- bool isArray = false;
- this.DataType = ComUtils.GetDataTypeId(property.DataType, out isArray);
- this.ValueRank = (isArray)?ValueRanks.OneOrMoreDimensions:ValueRanks.Scalar;
- this.ArrayDimensions = null;
-
- // assume that properties with item ids are writeable. the server may still reject the write.
- if (String.IsNullOrEmpty(property.ItemId))
- {
- this.AccessLevel = AccessLevels.CurrentRead;
- }
- else
- {
- this.AccessLevel = AccessLevels.CurrentReadOrWrite;
- }
-
- this.UserAccessLevel = this.AccessLevel;
- this.MinimumSamplingInterval = MinimumSamplingIntervals.Indeterminate;
- this.Historizing = false;
-
- // add a reference to the parent node.
- NodeId parentNodeId = DaModelUtils.ConstructIdForDaElement(itemId, -1, namespaceIndex);
- this.AddReference(ReferenceTypeIds.HasProperty, true, parentNodeId);
- }
- #endregion
-
- #region Private Fields
- private string m_itemId;
- private DaProperty m_property;
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/Da/DaValue.cs b/ComIOP/Common/Client/Da/DaValue.cs
deleted file mode 100644
index 3d7e7d457..000000000
--- a/ComIOP/Common/Client/Da/DaValue.cs
+++ /dev/null
@@ -1,119 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using Opc.Ua;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// Stores information an element in the DA server address space.
- ///
- public class DaValue
- {
- #region Constructors
- ///
- /// Initializes a new instance of the class.
- ///
- public DaValue()
- {
- }
- #endregion
-
- #region Public Members
- ///
- /// Gets or sets the value.
- ///
- /// The value.
- public object Value
- {
- get { return m_value; }
- set { m_value = value; }
- }
-
- ///
- /// Gets or sets the timestamp.
- ///
- /// The timestamp.
- public DateTime Timestamp
- {
- get { return m_timestamp; }
- set { m_timestamp = value; }
- }
-
- ///
- /// Gets or sets the quality.
- ///
- /// The quality.
- public short Quality
- {
- get { return m_quality; }
- set { m_quality = value; }
- }
-
- ///
- /// Gets or sets the COM error.
- ///
- /// The COM error.
- public int Error
- {
- get { return m_error; }
- set { m_error = value; }
- }
-
- ///
- /// Gets the value.
- ///
- /// The type of value to return.
- /// The value if no error and a valid value exists. The default value for the type otherwise.
- public T GetValue()
- {
- if (m_error < 0)
- {
- return default(T);
- }
-
- if (typeof(T).IsInstanceOfType(m_value))
- {
- return (T)m_value;
- }
-
- return default(T);
- }
- #endregion
-
- #region Private Fields
- private object m_value;
- private short m_quality;
- private DateTime m_timestamp;
- private int m_error;
- #endregion
- }
-}
diff --git a/ComIOP/Common/Client/Da/ReadRequest.cs b/ComIOP/Common/Client/Da/ReadRequest.cs
deleted file mode 100644
index b475c98a3..000000000
--- a/ComIOP/Common/Client/Da/ReadRequest.cs
+++ /dev/null
@@ -1,1016 +0,0 @@
-/* ========================================================================
- * 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;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading;
-using OpcRcw.Comn;
-using OpcRcw.Da;
-using Opc.Ua;
-using Opc.Ua.Server;
-using Opc.Ua.Com;
-using Opc.Ua.Com.Client;
-
-namespace Opc.Ua.Com.Client
-{
- ///
- /// Stores the parameters and results for a COM DA read operation.
- ///
- public class ReadRequest
- {
- #region Private Feilds
-
- ///
- /// 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
-
- #region Constructors
- ///
- /// Initializes a new instance of the class.
- ///
- /// The item id.
- public ReadRequest(string itemId)
- {
- m_itemId = itemId;
- }
- #endregion
-
- #region Public Properties
- ///
- /// Gets the item id to read.
- ///
- /// The item id.
- public string ItemId
- {
- get { return m_itemId; }
- }
-
- ///
- /// Gets the property ids to read.
- ///
- /// The property ids.
- public List PropertyIds
- {
- get { return m_propertyIds; }
- }
-
- ///
- /// Gets or sets a value indicating whether the item value must be read.
- ///
- /// true if the item value must be read; otherwise, false.
- public bool ValueRequired
- {
- get { return m_valueRequired; }
- set { m_valueRequired = value; }
- }
-
- ///
- /// Gets or sets the item value returned from the server.
- ///
- /// The value.
- public DaValue Value
- {
- get { return m_value; }
- set { m_value = value; }
- }
-
- ///
- /// Gets or sets the property values returned from the server.
- ///
- /// The property values.
- public DaValue[] PropertyValues
- {
- get { return m_propertyValues; }
- set { m_propertyValues = value; }
- }
- #endregion
-
- #region Public Methods
- ///
- /// Adds the property to the request.
- ///
- /// The property ids.
- public void AddProperty(params int[] propertyIds)
- {
- if (m_propertyIds == null)
- {
- m_propertyIds = new List();
- }
-
- if (propertyIds != null)
- {
- for (int ii = 0; ii < propertyIds.Length; ii++)
- {
- bool found = false;
-
- for (int jj = 0; jj < PropertyIds.Count; jj++)
- {
- if (PropertyIds[jj] == propertyIds[ii])
- {
- found = true;
- break;
- }
- }
-
- if (!found)
- {
- PropertyIds.Add(propertyIds[ii]);
- }
- }
- }
- }
-
- ///
- /// Gets the item value.
- ///
- /// The da value.
- /// The ua value.
- /// The diagnostics masks.
- ///
- public static ServiceResult GetItemValue(DaValue daValue, DataValue uaValue, DiagnosticsMasks diagnosticsMasks)
- {
- ServiceResult result = null;
-
- uaValue.Value = null;
-
- if (daValue == null)
- {
- result = uaValue.StatusCode = StatusCodes.BadOutOfService;
- return result;
- }
-
- uaValue.SourceTimestamp = daValue.Timestamp;
-
- if (daValue.Error < 0)
- {
- result = MapReadErrorToServiceResult(daValue.Error, diagnosticsMasks);
- uaValue.StatusCode = result.StatusCode;
- return result;
- }
-
- if (daValue.Quality != OpcRcw.Da.Qualities.OPC_QUALITY_GOOD)
- {
- uaValue.StatusCode = ComUtils.GetQualityCode(daValue.Quality);
- }
-
- if (StatusCode.IsBad(uaValue.StatusCode))
- {
- result = uaValue.StatusCode;
- return result;
- }
-
- uaValue.Value = daValue.Value;
-
- return result;
- }
-
- ///
- /// Gets the property value.
- ///
- /// The expected type for the property value.
- /// The property id.
- /// The value to update.
- /// if set to true if the property is required for the value attribute of a node.
- /// The value cast to the type T.
- ///
- /// This method sets the StatusCode in the DataValue if an error occurs and returns default(T).
- /// The DataValue.Value property is set to the value cast to type T.
- ///
- public T GetPropertyValue(int propertyId, DataValue value, bool isValue)
- {
- value.Value = null;
-
- // find the property value.
- DaValue result = null;
-
- if (PropertyIds != null && PropertyValues != null)
- {
- for (int ii = 0; ii < PropertyIds.Count; ii++)
- {
- if (PropertyIds[ii] == propertyId)
- {
- if (PropertyValues != null && PropertyValues.Length > ii)
- {
- result = PropertyValues[ii];
- }
-
- break;
- }
- }
- }
-
- // set the appropriate error code if no value found.
- if (result == null || result.Error < 0)
- {
- value.StatusCode = StatusCodes.BadNotFound;
- return default(T);
- }
-
- // update the source timestamp if a value is being read.
- if (isValue)
- {
- value.SourceTimestamp = result.Timestamp;
- }
-
- // save the value and return the result.
- value.Value = (T)result.Value;
- return (T)result.Value;
- }
-
- ///
- /// Gets the result for the read operayoin.
- ///
- /// The context.
- /// The item.
- /// The node to read.
- /// The value.
- /// The diagnostics masks.
- ///
- public ServiceResult GetResult(
- ISystemContext context,
- DaItemState item,
- ReadValueId nodeToRead,
- DataValue value,
- DiagnosticsMasks diagnosticsMasks)
- {
- if (nodeToRead.AttributeId == Attributes.Value)
- {
- ServiceResult result = GetItemValue(m_value, value, diagnosticsMasks);
-
- if (ServiceResult.IsBad(result))
- {
- return result;
- }
-
- return ApplyIndexRangeAndDataEncoding(context, nodeToRead, value);
- }
-
- switch (nodeToRead.AttributeId)
- {
- case Attributes.Description:
- {
- string description = this.GetPropertyValue(Opc.Ua.Com.PropertyIds.Description, value, false);
-
- if (StatusCode.IsGood(value.StatusCode))
- {
- value.Value = new LocalizedText(description);
- }
-
- break;
- }
-
- case Attributes.DataType:
- {
- short datatype = this.GetPropertyValue(Opc.Ua.Com.PropertyIds.DataType, value, false);
-
- if (StatusCode.IsGood(value.StatusCode))
- {
- value.Value = ComUtils.GetDataTypeId(datatype);
- }
-
- break;
- }
-
- case Attributes.ValueRank:
- {
- short datatype = this.GetPropertyValue(Opc.Ua.Com.PropertyIds.DataType, value, false);
-
- if (StatusCode.IsGood(value.StatusCode))
- {
- value.Value = ComUtils.GetValueRank(datatype);
- }
-
- break;
- }
-
- case Attributes.AccessLevel:
- case Attributes.UserAccessLevel:
- {
- int accessRights = this.GetPropertyValue(Opc.Ua.Com.PropertyIds.AccessRights, value, false);
-
- if (StatusCode.IsGood(value.StatusCode))
- {
- value.Value = (byte)accessRights;
- }
-
- break;
- }
-
- case Attributes.MinimumSamplingInterval:
- {
- float scanRate = this.GetPropertyValue(Opc.Ua.Com.PropertyIds.ScanRate, value, false);
-
- if (StatusCode.IsGood(value.StatusCode))
- {
- value.Value = (double)scanRate;
- }
-
- break;
- }
-
- default:
- {
- return StatusCodes.BadAttributeIdInvalid;
- }
- }
-
- // check if the property value is missing.
- if (value.StatusCode == StatusCodes.BadNotFound)
- {
- return StatusCodes.BadAttributeIdInvalid;
- }
-
- return ApplyIndexRangeAndDataEncoding(context, nodeToRead, value);
- }
-
- private ServiceResult ApplyIndexRangeAndDataEncoding(
- ISystemContext context,
- ReadValueId nodeToRead,
- DataValue value)
- {
- if (StatusCode.IsBad(value.StatusCode))
- {
- return value.StatusCode;
- }
-
- if (nodeToRead.ParsedIndexRange != NumericRange.Empty || !QualifiedName.IsNull(nodeToRead.DataEncoding))
- {
- if (nodeToRead.AttributeId != Attributes.Value && !QualifiedName.IsNull(nodeToRead.DataEncoding))
- {
- return StatusCodes.BadDataEncodingInvalid;
- }
-
- object valueToUpdate = value.Value;
-
- ServiceResult result = BaseVariableState.ApplyIndexRangeAndDataEncoding(
- context,
- nodeToRead.ParsedIndexRange,
- nodeToRead.DataEncoding,
- ref valueToUpdate);
-
- if (ServiceResult.IsBad(result))
- {
- bool useXml = nodeToRead.DataEncoding.Name == DefaultXml;
-
- if (!useXml
- && !string.IsNullOrEmpty(nodeToRead.DataEncoding.Name)
- && nodeToRead.DataEncoding.Name != DefaultBinary)
- {
- result = StatusCodes.BadDataEncodingInvalid;
- }
-
- value.Value = null;
- value.StatusCode = result.StatusCode;
- return result;
- }
-
- value.Value = valueToUpdate;
- }
-
- return value.StatusCode;
- }
-
- ///
- /// Gets the result for the read operation.
- ///
- /// The context.
- /// The property.
- /// The node to read.
- /// The value.
- /// The diagnostics masks.
- ///
- public ServiceResult GetResult(
- ISystemContext context,
- DaPropertyState property,
- ReadValueId nodeToRead,
- DataValue value,
- DiagnosticsMasks diagnosticsMasks)
- {
- ServiceResult result = null;
-
- switch (nodeToRead.AttributeId)
- {
- case Attributes.Value:
- {
- if (!String.IsNullOrEmpty(property.Property.ItemId))
- {
- result = GetItemValue(m_value, value, diagnosticsMasks);
- }
- else
- {
- this.GetPropertyValue