コード例 #1
0
ファイル: AreaBrowser.cs プロジェクト: OPCFoundation/UA-.NET
        /// <summary>
        /// Creates a new browser object with a set of filters.
        /// </summary>
        public AreaBrowser(
            ISystemContext context,
            ViewDescription view,
            NodeId referenceType,
            bool includeSubtypes,
            BrowseDirection browseDirection,
            QualifiedName browseName,
            IEnumerable<IReference> additionalReferences,
            bool internalOnly,
            AreaState area)
        :
            base(
                context,
                view,
                referenceType,
                includeSubtypes,
                browseDirection,
                browseName,
                additionalReferences,
                internalOnly)
        {
            m_stage = Stage.Begin;

            if (area != null)
            {
                m_area = AreaState.GetDirectory(context, area.NodeId);
                m_isRoot = area.IsRoot;
            }
        }
コード例 #2
0
ファイル: QualifiedName.cs プロジェクト: yuriik83/UA-.NET
        /// <summary>
        /// Creates a deep copy of the value.
        /// </summary>
        /// <remarks>
        /// Creates a deep copy of the value.
        /// </remarks>
        /// <param name="value">The qualified name to copy</param>
        /// <exception cref="ArgumentNullException">Thrown if the provided value is null</exception>
        public QualifiedName(QualifiedName value)
        {            
            if (value == null) throw new ArgumentNullException("value");

            Name = value.Name;
            NamespaceIndex = value.NamespaceIndex;
        }
コード例 #3
0
 /// <summary>
 /// Sets the value for a child. Adds it if it does not already exist.
 /// </summary>
 /// <param name="browseName">The BrowseName.</param>
 /// <param name="nodeClass">The node class.</param>
 /// <param name="value">The value.</param>
 public void SetChildValue(
     QualifiedName browseName,
     NodeClass nodeClass,
     object value)
 {
     SetChildValue(m_snapshot, browseName, nodeClass, value);
 }
コード例 #4
0
ファイル: Browser.cs プロジェクト: yuriik83/UA-.NET
 /// <summary>
 /// Creates a new browser object with a set of filters.
 /// </summary>
 public Browser(
     ISystemContext context,
     ViewDescription view,
     NodeId referenceType,
     bool includeSubtypes,
     BrowseDirection browseDirection,
     QualifiedName browseName,
     IEnumerable<IReference> additionalReferences,
     bool internalOnly,
     Opc.Ua.Client.Session client,
     NamespaceMapper mapper,
     NodeState source,
     NodeId rootId)
 :
     base(
         context,
         view,
         referenceType,
         includeSubtypes,
         browseDirection,
         browseName,
         additionalReferences,
         internalOnly)
 {
     m_client = client;
     m_mapper = mapper;
     m_source = source;
     m_rootId = rootId;
     m_stage = Stage.Begin;
 }
コード例 #5
0
        /// <summary>
        /// Initializes a memory tag for a buffer.
        /// </summary>
        /// <param name="parent">The buffer that owns the tag.</param>
        /// <param name="offet">The offset of the tag address in the memory buffer.</param>
        public MemoryTagState(MemoryBufferState parent, uint offet) : base(parent)
        {
            // these objects are created an discarded during each operation. 
            // the metadata is derived from the parameters passed to constructors.
            NodeId = new NodeId(Utils.Format("{0}[{1}]", parent.SymbolicName, offet), parent.NodeId.NamespaceIndex);
            BrowseName = new QualifiedName(Utils.Format("{1:X8}", parent.SymbolicName, offet), parent.TypeDefinitionId.NamespaceIndex);
            DisplayName = BrowseName.Name;
            Description = null;
            WriteMask = AttributeWriteMask.None;
            UserWriteMask = AttributeWriteMask.None;
            ReferenceTypeId = Opc.Ua.ReferenceTypeIds.HasComponent;
            TypeDefinitionId = new NodeId(VariableTypes.MemoryTagType, parent.TypeDefinitionId.NamespaceIndex);
            ModellingRuleId = null;
            NumericId = offet;
            DataType = new NodeId((uint)parent.ElementType);
            ValueRank = ValueRanks.Scalar;
            ArrayDimensions = null;
            AccessLevel = AccessLevels.CurrentReadOrWrite;
            UserAccessLevel = AccessLevels.CurrentReadOrWrite;
            MinimumSamplingInterval = parent.MaximumScanRate;
            Historizing = false;

            // re-direct read and write operations to the parent.
            OnReadValue = parent.ReadTagValue;
            OnWriteValue = parent.WriteTagValue;

            m_offset = offet;
        }
コード例 #6
0
ファイル: DaElementBrowser.cs プロジェクト: yuriik83/UA-.NET
 /// <summary>
 /// Creates a new browser object with a set of filters.
 /// </summary>
 /// <param name="context">The system context to use.</param>
 /// <param name="view">The view which may restrict the set of references/nodes found.</param>
 /// <param name="referenceType">The type of references being followed.</param>
 /// <param name="includeSubtypes">Whether subtypes of the reference type are followed.</param>
 /// <param name="browseDirection">Which way the references are being followed.</param>
 /// <param name="browseName">The browse name of a specific target (used when translating browse paths).</param>
 /// <param name="additionalReferences">Any additional references that should be included.</param>
 /// <param name="internalOnly">If true the browser should not making blocking calls to external systems.</param>
 /// <param name="itemId">The item id.</param>
 /// <param name="namespaceIndex">Index of the namespace.</param>
 public DaElementBrowser(
     ISystemContext context,
     ViewDescription view,
     NodeId referenceType,
     bool includeSubtypes,
     BrowseDirection browseDirection,
     QualifiedName browseName,
     IEnumerable<IReference> 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;
 }
コード例 #7
0
        /// <summary>
        /// Creates a new browser object with a set of filters.
        /// </summary>
        public NodeBrowser(
            ISystemContext context,
            ViewDescription view,
            NodeId referenceType,
            bool includeSubtypes,
            BrowseDirection browseDirection,
            QualifiedName browseName,
            IEnumerable<IReference> additionalReferences,
            bool internalOnly)
        {
            m_context = context;
            m_view = view;
            m_referenceType = referenceType;
            m_includeSubtypes = includeSubtypes;
            m_browseDirection = browseDirection;
            m_browseName = browseName;
            m_internalOnly = internalOnly;
            m_references = new List<IReference>();
            m_index = 0;

            // add any additional references if they meet the criteria.
            if (additionalReferences != null)
            {
                foreach (IReference reference in additionalReferences)
                {
                    if (IsRequired(reference.ReferenceTypeId, reference.IsInverse))
                    {
                        m_references.Add(reference);
                    }
                }
            }
        }
コード例 #8
0
        internal static QualifiedName GetQualifiedName(Opc.Ua.QualifiedName qm, NamespaceTable namespaceTable)
        {
            var url = namespaceTable.GetString(qm.NamespaceIndex);

            return(new QualifiedName()
            {
                name = qm.Name, namespaceUrl = url
            });
        }
コード例 #9
0
ファイル: DaModelUtils.cs プロジェクト: OPCFoundation/UA-.NET
        /// <summary>
        /// Constructs a NodeId from the BrowseName of an internal node.
        /// </summary>
        /// <param name="browseName">The browse name.</param>
        /// <param name="namespaceIndex">Index of the namespace.</param>
        /// <returns>The node id.</returns>
        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();
        }
コード例 #10
0
        public static Opc.Ua.QualifiedName[] GetBrowsePath(QualifiedName[] browsePath, NamespaceTable namespaceTable)
        {
            var qms = new Opc.Ua.QualifiedName[browsePath.Length];

            for (int i = 0; i < browsePath.Length; i++)
            {
                var bp    = browsePath[i];
                var nsIdx = string.IsNullOrWhiteSpace(bp.namespaceUrl) ? 0 : namespaceTable.GetIndex(bp.namespaceUrl);
                qms[i] = new Opc.Ua.QualifiedName(bp.name, (ushort)nsIdx);;
            }
            return(qms);
        }
コード例 #11
0
 /// <summary>
 /// Initializes the instance with the default values.
 /// </summary>
 protected override void Initialize(ISystemContext context)
 {
     SymbolicName = "View1";
     NodeId = null;
     BrowseName = new QualifiedName(SymbolicName, 1);
     DisplayName = SymbolicName;
     Description = null;
     WriteMask = AttributeWriteMask.None;
     UserWriteMask = AttributeWriteMask.None;
     EventNotifier = EventNotifiers.None;
     ContainsNoLoops = false;
 }
コード例 #12
0
 /// <summary>
 /// Initializes the instance with the default values.
 /// </summary>
 protected override void Initialize(ISystemContext context)
 {
     SymbolicName = Utils.Format("{0}_Instance1", Opc.Ua.BrowseNames.BaseObjectType);
     NodeId = null;
     BrowseName = new QualifiedName(SymbolicName, 1);
     DisplayName = SymbolicName;
     Description = null;
     WriteMask = AttributeWriteMask.None;
     UserWriteMask = AttributeWriteMask.None;
     TypeDefinitionId = GetDefaultTypeDefinitionId(context.NamespaceUris);
     NumericId = Opc.Ua.ObjectTypes.BaseObjectType;
     EventNotifier = EventNotifiers.None;
 }
コード例 #13
0
        /// <summary>
        /// Creates a relative path to follow the forward reference type to find the specified browse name.
        /// </summary>
        public RelativePath(NodeId referenceTypeId, bool isInverse, bool includeSubtypes, QualifiedName browseName)
        {
            Initialize();

            RelativePathElement element = new RelativePathElement();

            element.ReferenceTypeId = referenceTypeId;
            element.IsInverse       = isInverse;
            element.IncludeSubtypes = includeSubtypes;
            element.TargetName      = browseName;

            m_elements.Add(element);
        }                 
コード例 #14
0
ファイル: DataSource.cs プロジェクト: neobox3000/UA-.NET
        /// <summary>
        /// Imports a QualifiedName
        /// </summary>
        private Opc.Ua.QualifiedName ImportQualifiedName(string source, NamespaceTable namespaceUris)
        {
            if (String.IsNullOrEmpty(source))
            {
                return(Opc.Ua.QualifiedName.Null);
            }

            Opc.Ua.QualifiedName qname = Opc.Ua.QualifiedName.Parse(source);

            if (qname.NamespaceIndex > 0)
            {
                ushort namespaceIndex = ImportNamespaceIndex(qname.NamespaceIndex, namespaceUris);
                qname = new Opc.Ua.QualifiedName(qname.Name, namespaceIndex);
            }

            return(qname);
        }
コード例 #15
0
 /// <summary>
 /// Creates a new browser object with a set of filters.
 /// </summary>
 /// <param name="context">The system context to use.</param>
 /// <param name="view">The view which may restrict the set of references/nodes found.</param>
 /// <param name="referenceType">The type of references being followed.</param>
 /// <param name="includeSubtypes">Whether subtypes of the reference type are followed.</param>
 /// <param name="browseDirection">Which way the references are being followed.</param>
 /// <param name="browseName">The browse name of a specific target (used when translating browse paths).</param>
 /// <param name="additionalReferences">Any additional references that should be included.</param>
 /// <param name="internalOnly">If true the browser should not making blocking calls to external systems.</param>
 /// <param name="source">The segment being accessed.</param>
 public ArchiveFolderBrowser(
     ISystemContext context,
     ViewDescription view,
     NodeId referenceType,
     bool includeSubtypes,
     BrowseDirection browseDirection,
     QualifiedName browseName,
     IEnumerable<IReference> additionalReferences,
     bool internalOnly,
     ArchiveFolderState source)
 :
     base(
         context,
         view,
         referenceType,
         includeSubtypes,
         browseDirection,
         browseName,
         additionalReferences,
         internalOnly)
 {
     m_source = source;
     m_stage = Stage.Begin;
 }
コード例 #16
0
 /// <summary>
 /// Creates a new browser object with a set of filters.
 /// </summary>
 public MemoryBufferBrowser(
     ISystemContext context,
     ViewDescription view,
     NodeId referenceType,
     bool includeSubtypes,
     BrowseDirection browseDirection,
     QualifiedName browseName,
     IEnumerable<IReference> additionalReferences,
     bool internalOnly,
     MemoryBufferState buffer)
 :
     base(
         context,
         view,
         referenceType,
         includeSubtypes,
         browseDirection,
         browseName,
         additionalReferences,
         internalOnly)
 {
     m_buffer = buffer;
     m_stage = Stage.Begin;
 }
コード例 #17
0
        /// <summary>
        /// Called to create the browser for the item configuration.
        /// </summary>
        private NodeBrowser OnCreateItemConfigurationBrowser(
            ISystemContext context,
            NodeState node,
            ViewDescription view,
            NodeId referenceType,
            bool includeSubtypes,
            BrowseDirection browseDirection,
            QualifiedName browseName,
            IEnumerable<IReference> additionalReferences,
            bool internalOnly)
        {
            HdaParsedNodeId nodeId = HdaParsedNodeId.Parse(node.NodeId);

            if (nodeId == null)
            {
                return null;
            }

            return new HdaElementBrower(
                context,
                view,
                referenceType,
                includeSubtypes,
                browseDirection,
                browseName,
                additionalReferences,
                internalOnly,
                nodeId.RootId,
                Opc.Ua.ObjectTypeIds.HistoricalDataConfigurationType,
                Opc.Ua.BrowseNames.HAConfiguration,
                NamespaceIndex);
        }
コード例 #18
0
        /// <summary>
        /// Finds the child with the specified browse name.
        /// </summary>
        protected override BaseInstanceState FindChild(
            ISystemContext context,
            QualifiedName browseName,
            bool createOrReplace,
            BaseInstanceState replacement)
        {
            if (QualifiedName.IsNull(browseName))
            {
                return null;
            }

            BaseInstanceState instance = null;

            switch (browseName.Name)
            {
                case MemoryBuffer.BrowseNames.StartAddress:
                {
                    if (createOrReplace)
                    {
                        if (StartAddress == null)
                        {
                            if (replacement == null)
                            {
                                StartAddress = new PropertyState<uint>(this);
                            }
                            else
                            {
                                StartAddress = (PropertyState<uint>)replacement;
                            }
                        }
                    }

                    instance = StartAddress;
                    break;
                }

                case MemoryBuffer.BrowseNames.SizeInBytes:
                {
                    if (createOrReplace)
                    {
                        if (SizeInBytes == null)
                        {
                            if (replacement == null)
                            {
                                SizeInBytes = new PropertyState<uint>(this);
                            }
                            else
                            {
                                SizeInBytes = (PropertyState<uint>)replacement;
                            }
                        }
                    }

                    instance = SizeInBytes;
                    break;
                }
            }

            if (instance != null)
            {
                return instance;
            }

            return base.FindChild(context, browseName, createOrReplace, replacement);
        }
コード例 #19
0
        /// <summary>
        /// Creates a relative path to follow the forward reference type to find the specified browse name.
        /// </summary>
        public RelativePath(NodeId referenceTypeId, bool isInverse, bool includeSubtypes, QualifiedName browseName)
        {
            Initialize();

            RelativePathElement element = new RelativePathElement();

            element.ReferenceTypeId = referenceTypeId;
            element.IsInverse       = isInverse;
            element.IncludeSubtypes = includeSubtypes;
            element.TargetName      = browseName;

            m_elements.Add(element);
        }
コード例 #20
0
        /// <summary>
        /// Finds the child with the specified browse name.
        /// </summary>
        protected override BaseInstanceState FindChild(
            ISystemContext context,
            QualifiedName browseName,
            bool createOrReplace,
            BaseInstanceState replacement)
        {
            if (QualifiedName.IsNull(browseName))
            {
                return null;
            }

            BaseInstanceState instance = null;

            switch (browseName.Name)
            {
                case FileSystem.BrowseNames.Temperature:
                {
                    if (createOrReplace)
                    {
                        if (Temperature == null)
                        {
                            if (replacement == null)
                            {
                                Temperature = new AnalogItemState<double>(this);
                            }
                            else
                            {
                                Temperature = (AnalogItemState<double>)replacement;
                            }
                        }
                    }

                    instance = Temperature;
                    break;
                }

                case FileSystem.BrowseNames.TemperatureSetPoint:
                {
                    if (createOrReplace)
                    {
                        if (TemperatureSetPoint == null)
                        {
                            if (replacement == null)
                            {
                                TemperatureSetPoint = new AnalogItemState<double>(this);
                            }
                            else
                            {
                                TemperatureSetPoint = (AnalogItemState<double>)replacement;
                            }
                        }
                    }

                    instance = TemperatureSetPoint;
                    break;
                }

                case FileSystem.BrowseNames.State:
                {
                    if (createOrReplace)
                    {
                        if (State == null)
                        {
                            if (replacement == null)
                            {
                                State = new BaseDataVariableState<int>(this);
                            }
                            else
                            {
                                State = (BaseDataVariableState<int>)replacement;
                            }
                        }
                    }

                    instance = State;
                    break;
                }

                case FileSystem.BrowseNames.PowerConsumption:
                {
                    if (createOrReplace)
                    {
                        if (PowerConsumption == null)
                        {
                            if (replacement == null)
                            {
                                PowerConsumption = new DataItemState<double>(this);
                            }
                            else
                            {
                                PowerConsumption = (DataItemState<double>)replacement;
                            }
                        }
                    }

                    instance = PowerConsumption;
                    break;
                }

                case FileSystem.BrowseNames.Start:
                {
                    if (createOrReplace)
                    {
                        if (Start == null)
                        {
                            if (replacement == null)
                            {
                                Start = new MethodState(this);
                            }
                            else
                            {
                                Start = (MethodState)replacement;
                            }
                        }
                    }

                    instance = Start;
                    break;
                }

                case FileSystem.BrowseNames.Stop:
                {
                    if (createOrReplace)
                    {
                        if (Stop == null)
                        {
                            if (replacement == null)
                            {
                                Stop = new MethodState(this);
                            }
                            else
                            {
                                Stop = (MethodState)replacement;
                            }
                        }
                    }

                    instance = Stop;
                    break;
                }
            }

            if (instance != null)
            {
                return instance;
            }

            return base.FindChild(context, browseName, createOrReplace, replacement);
        }
コード例 #21
0
ファイル: EncodableObject.cs プロジェクト: neobox3000/UA-.NET
        /// <summary>
        /// Applies the data encoding to the value.
        /// </summary>
        public static ServiceResult ApplyDataEncoding(ServiceMessageContext context, QualifiedName dataEncoding, ref object value)
        {
            // check if nothing to do.
            if (QualifiedName.IsNull(dataEncoding) || value == null)
            {
                return(ServiceResult.Good);
            }

            // check for supported encoding type.
            if (dataEncoding.NamespaceIndex != 0)
            {
                return(StatusCodes.BadDataEncodingUnsupported);
            }

            bool useXml = dataEncoding.Name == DefaultXml;

            if (!useXml && dataEncoding.Name != DefaultBinary)
            {
                return(StatusCodes.BadDataEncodingUnsupported);
            }

            try
            {
                // check for array of encodeables.
                IList <IEncodeable> encodeables = value as IList <IEncodeable>;

                if (encodeables == null)
                {
                    // check for array of extension objects.
                    IList <ExtensionObject> extensions = value as IList <ExtensionObject>;

                    if (extensions != null)
                    {
                        // convert extension objects to encodeables.
                        encodeables = new IEncodeable[extensions.Count];

                        for (int ii = 0; ii < encodeables.Count; ii++)
                        {
                            if (ExtensionObject.IsNull(extensions[ii]))
                            {
                                encodeables[ii] = null;
                                continue;
                            }

                            IEncodeable element = extensions[ii].Body as IEncodeable;

                            if (element == null)
                            {
                                return(StatusCodes.BadTypeMismatch);
                            }

                            encodeables[ii] = element;
                        }
                    }
                }

                // apply data encoding to the array.
                if (encodeables != null)
                {
                    ExtensionObject[] extensions = new ExtensionObject[encodeables.Count];

                    for (int ii = 0; ii < extensions.Length; ii++)
                    {
                        extensions[ii] = Encode(context, encodeables[ii], useXml);
                    }

                    value = extensions;
                    return(ServiceResult.Good);
                }

                // check for scalar value.
                IEncodeable encodeable = value as IEncodeable;

                if (encodeable == null)
                {
                    ExtensionObject extension = value as ExtensionObject;

                    if (extension == null)
                    {
                        return(StatusCodes.BadDataEncodingUnsupported);
                    }

                    encodeable = extension.Body as IEncodeable;
                }

                if (encodeable == null)
                {
                    return(StatusCodes.BadDataEncodingUnsupported);
                }

                // do conversion.
                value = Encode(context, encodeable, useXml);
                return(ServiceResult.Good);
            }
            catch (Exception e)
            {
                return(ServiceResult.Create(e, StatusCodes.BadTypeMismatch, "Could not convert value to requested format."));
            }
        }
コード例 #22
0
        /// <summary>
        /// Converts a value to a QualifiedName
        /// </summary>
        private static object ToQualifiedName(object value, BuiltInType sourceType)
        {            
            // check for array conversions.
            Array array = value as Array;

            if (array != null)
            {
                QualifiedName[] output = new QualifiedName[array.Length];

                for (int ii = 0; ii < array.Length; ii++)
                {
                    output[ii] = (QualifiedName)Cast(array.GetValue(ii), BuiltInType.QualifiedName);
                }

                return output;
            }
            
            // handle for supported conversions.
            switch (sourceType)
            {
                case BuiltInType.QualifiedName:
                {
                    return (QualifiedName)value; 
                }

                case BuiltInType.String:
                {
                    return QualifiedName.Parse((string)value);
                }
            }
            
            // conversion not supported.
            return null;
        }
コード例 #23
0
        /// <summary>
        /// Updates the namespace table with URI used in the relative path.
        /// </summary>
        /// <param name="currentTable">The current table.</param>
        /// <param name="targetTable">The target table.</param>
        public void UpdateNamespaceTable(NamespaceTable currentTable, NamespaceTable targetTable)
        {
            // build mapping table.
            int[] mappings = new int[currentTable.Count];
            mappings[0] = 0;

            if (mappings.Length > 0)
            {
                mappings[1] = 1;
            }

            // ensure a placeholder for the local namespace.
            if (targetTable.Count <= 1)
            {
                targetTable.Append("---");
            }

            string[] uris = new string[mappings.Length];

            for (int ii = 2; ii < mappings.Length; ii++)
            {
                uris[ii] = currentTable.GetString((uint)ii);

                if (uris[ii] != null)
                {
                    mappings[ii] = targetTable.GetIndex(uris[ii]);
                }
            }

            // update each element.
            foreach (Element element in m_elements)
            {
                // check reference type name.
                QualifiedName qname = element.ReferenceTypeName;

                if (qname != null && qname.NamespaceIndex > 1)
                {
                    if (qname.NamespaceIndex < mappings.Length)
                    {
                        if (mappings[qname.NamespaceIndex] == -1)
                        {
                            mappings[qname.NamespaceIndex] = targetTable.GetIndexOrAppend(uris[qname.NamespaceIndex]);
                        }
                    }
                }

                // check target name.
                qname = element.TargetName;

                if (qname != null && qname.NamespaceIndex > 1)
                {
                    if (qname.NamespaceIndex < mappings.Length)
                    {
                        if (mappings[qname.NamespaceIndex] == -1)
                        {
                            mappings[qname.NamespaceIndex] = targetTable.GetIndexOrAppend(uris[qname.NamespaceIndex]);
                        }
                    }
                }
            }
        }
コード例 #24
0
        /// <summary>
        /// Finds the child with the specified browse name.
        /// </summary>
        protected override BaseInstanceState FindChild(
            ISystemContext context,
            QualifiedName browseName,
            bool createOrReplace,
            BaseInstanceState replacement)
        {
            if (QualifiedName.IsNull(browseName))
            {
                return null;
            }

            BaseInstanceState instance = null;

            switch (browseName.Name)
            {
                case FileSystem.BrowseNames.Humidity:
                {
                    if (createOrReplace)
                    {
                        if (Humidity == null)
                        {
                            if (replacement == null)
                            {
                                Humidity = new AnalogItemState<double>(this);
                            }
                            else
                            {
                                Humidity = (AnalogItemState<double>)replacement;
                            }
                        }
                    }

                    instance = Humidity;
                    break;
                }

                case FileSystem.BrowseNames.HumiditySetPoint:
                {
                    if (createOrReplace)
                    {
                        if (HumiditySetPoint == null)
                        {
                            if (replacement == null)
                            {
                                HumiditySetPoint = new AnalogItemState<double>(this);
                            }
                            else
                            {
                                HumiditySetPoint = (AnalogItemState<double>)replacement;
                            }
                        }
                    }

                    instance = HumiditySetPoint;
                    break;
                }
            }

            if (instance != null)
            {
                return instance;
            }

            return base.FindChild(context, browseName, createOrReplace, replacement);
        }
コード例 #25
0
        /// <summary>
        /// Initializes the instance from an event notification.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="fields">The fields selected for the event notification.</param>
        /// <param name="e">The event notification.</param>
        /// <remarks>
        /// This method creates components based on the browse paths in the event field and sets
        /// the NodeId or Value based on values in the event notification.
        /// </remarks>
        public void Update(
            ISystemContext context,
            SimpleAttributeOperandCollection fields,
            EventFieldList e)
        {
            for (int ii = 0; ii < fields.Count; ii++)
            {
                SimpleAttributeOperand field = fields[ii];
                object value = e.EventFields[ii].Value;

                // check if value provided.
                if (value == null)
                {
                    continue;
                }

                // extract the NodeId for the event.
                if (field.BrowsePath.Count == 0)
                {
                    if (field.AttributeId == Attributes.NodeId)
                    {
                        this.NodeId = value as NodeId;
                        continue;
                    }
                }

                // extract the type definition for the event.
                if (field.BrowsePath.Count == 1)
                {
                    if (field.AttributeId == Attributes.Value)
                    {
                        if (field.BrowsePath[0] == BrowseNames.EventType)
                        {
                            m_typeDefinitionId = value as NodeId;
                            continue;
                        }
                    }
                }

                // save value for child node.
                NodeState parent = this;

                for (int jj = 0; jj < field.BrowsePath.Count; jj++)
                {
                    // find a predefined child identified by the browse name.
                    BaseInstanceState child = parent.CreateChild(context, field.BrowsePath[jj]);

                    // create a placeholder for unknown children.
                    if (child == null)
                    {
                        if (field.AttributeId == Attributes.Value)
                        {
                            child = new BaseDataVariableState(parent);
                        }
                        else
                        {
                            child = new BaseObjectState(parent);
                        }

                        parent.AddChild(child);
                    }

                    // ensure the browse name is set.
                    if (QualifiedName.IsNull(child.BrowseName))
                    {
                        child.BrowseName = field.BrowsePath[jj];
                    }

                    // ensure the display name is set.
                    if (LocalizedText.IsNullOrEmpty(child.DisplayName))
                    {
                        child.DisplayName = child.BrowseName.Name;
                    }

                    // process next element in path.
                    if (jj < field.BrowsePath.Count - 1)
                    {
                        parent = child;
                        continue;
                    }

                    // save the variable value.
                    if (field.AttributeId == Attributes.Value)
                    {
                        BaseVariableState variable = child as BaseVariableState;

                        if (variable != null && field.AttributeId == Attributes.Value)
                        {
                            try
                            {
                                variable.WrappedValue = e.EventFields[ii];
                            }
                            catch (Exception)
                            {
                                variable.Value = null;
                            }
                        }

                        break;
                    }

                    // save the node id.
                    child.NodeId = value as NodeId;
                }
            }
        }
コード例 #26
0
 /// <summary>
 /// Creates a relative path to follow any hierarchial references to find the specified browse name.
 /// </summary>
 public RelativePath(QualifiedName browseName) : this(ReferenceTypeIds.HierarchicalReferences, false, true, browseName)
 {
 }
コード例 #27
0
 /// <summary>
 /// Creates a relative path to follow the forward reference type to find the specified browse name.
 /// </summary>
 public RelativePath(NodeId referenceTypeId, QualifiedName browseName) : this(referenceTypeId, false, true, browseName)
 {
 }
コード例 #28
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="connection"></param>
        /// <param name="id"></param>
        /// <param name="nsTable"></param>
        /// <returns></returns>
        private QualifiedName[] FindBrowsePath(Session connection, NodeId id, NodeId rootId, Opc.Ua.QualifiedName browseName, NamespaceTable nsTable)
        {
            HashSet <NodeId> set = new HashSet <NodeId>();
            var browsePath       = new List <QualifiedName>();

            set.Add(id);
            browsePath.Add(Converter.GetQualifiedName(browseName, nsTable));
            bool moreParents = true;

            while (moreParents)
            {
                connection.Browse(null, null, id, 1,
                                  BrowseDirection.Inverse,
                                  ReferenceTypeIds.HierarchicalReferences,
                                  true,
                                  0xFF,
                                  out byte[] contpoint,
                                  out ReferenceDescriptionCollection referenceDescriptions);

                moreParents = referenceDescriptions.Count > 0;
                if (moreParents)
                {
                    var refDesc = referenceDescriptions[0];
                    var nodeId  = ExpandedNodeId.ToNodeId(refDesc.NodeId, nsTable);
                    if (!rootId.Equals(nodeId))
                    {
                        id = nodeId;
                        if (set.Contains(nodeId))
                        {
                            _log.LogError("Loop detected");
                            throw new ArgumentException("Loop detected!");
                        }
                        set.Add(id);
                        browsePath.Add(Converter.GetQualifiedName(refDesc.BrowseName, nsTable));
                    }
                    else
                    {
                        moreParents = false;
                    }
                }
            }
            return(browsePath.Reverse <QualifiedName>().ToArray());
        }
コード例 #29
0
ファイル: ContentFilter.cs プロジェクト: yuriik83/UA-.NET
        /// <summary>
        /// Constructs an operand from a value.
        /// </summary>
        /// <param name="nodeId">The node identifier.</param>
        /// <param name="browsePath">The browse path.</param>
        public AttributeOperand(
            NodeId nodeId,
            QualifiedName browsePath)
        {
            m_nodeId = nodeId;
            m_attributeId = Attributes.Value;

            m_browsePath = new RelativePath();

            RelativePathElement element = new RelativePathElement();

            element.ReferenceTypeId = ReferenceTypeIds.Aggregates;
            element.IsInverse = false;
            element.IncludeSubtypes = true;
            element.TargetName = browsePath;

            m_browsePath.Elements.Add(element);
        }
コード例 #30
0
        /// <summary>
        /// Creates a new instance and assigns unique identifiers to all children.
        /// </summary>
        /// <param name="context">The operation context.</param>
        /// <param name="parentId">An optional parent identifier.</param>
        /// <param name="referenceTypeId">The reference type from the parent.</param>
        /// <param name="browseName">The browse name.</param>
        /// <param name="instance">The instance to create.</param>
        /// <returns>The new node id.</returns>
        public NodeId CreateNode(
            ServerSystemContext context,
            NodeId parentId,
            NodeId referenceTypeId,
            QualifiedName browseName,
            BaseInstanceState instance)
        {
            ServerSystemContext contextToUse = (ServerSystemContext)m_systemContext.Copy(context);

            lock (Lock)
            {
                if (m_predefinedNodes == null)
                {
                    m_predefinedNodes = new NodeIdDictionary<NodeState>();
                }

                instance.ReferenceTypeId = referenceTypeId;

                NodeState parent = null;

                if (parentId != null)
                {
                    if (!m_predefinedNodes.TryGetValue(parentId, out parent))
                    {
                        throw ServiceResultException.Create(
                            StatusCodes.BadNodeIdUnknown,
                            "Cannot find parent with id: {0}",
                            parentId);
                    }

                    parent.AddChild(instance);
                }

                instance.Create(contextToUse, null, browseName, null, true);
                AddPredefinedNode(contextToUse, instance);

                return instance.NodeId;
            }
        }
コード例 #31
0
        /// <summary>
        /// Writes an QualifiedName to the stream.
        /// </summary>
        public void WriteQualifiedName(string fieldName, QualifiedName value)
        {
            if (BeginField(fieldName, value == null, true))
            {
                PushNamespace(Namespaces.OpcUaXsd);

                ushort namespaceIndex = value.NamespaceIndex;

                if (m_namespaceMappings != null && m_namespaceMappings.Length > namespaceIndex)
                {
                    namespaceIndex = m_namespaceMappings[namespaceIndex];
                }

                if (value != null)
                {
                    WriteUInt16("NamespaceIndex", namespaceIndex);
                    WriteString("Name", value.Name);
                }

                PopNamespace();
                
                EndField(fieldName);
            }
        }
コード例 #32
0
ファイル: MemoryBufferState.cs プロジェクト: yuriik83/UA-.NET
        /// <summary>
        /// Handles the read operation for an invidual tag.
        /// </summary>
        public ServiceResult ReadTagValue(
            ISystemContext context,
            NodeState node,
            NumericRange indexRange,
            QualifiedName dataEncoding,
            ref object value,
            ref StatusCode statusCode,
            ref DateTime timestamp)
        {
            MemoryTagState tag = node as MemoryTagState;

            if (tag == null)
            {
                return StatusCodes.BadNodeIdUnknown;
            }

            if (NumericRange.Empty != indexRange)
            {
                return StatusCodes.BadIndexRangeInvalid;
            }

            if (!QualifiedName.IsNull(dataEncoding))
            {
                return StatusCodes.BadDataEncodingInvalid;
            }

            int offset = (int)tag.Offset;

            lock (m_dataLock)
            {
                if (offset < 0 || offset >= m_buffer.Length)
                {
                    return StatusCodes.BadNodeIdUnknown;
                }

                if (m_buffer == null)
                {
                    return StatusCodes.BadOutOfService;
                }

                value = GetValueAtOffset(offset).Value;
            }

            statusCode = StatusCodes.Good;
            timestamp = m_lastScanTime;

            return ServiceResult.Good;
        }
コード例 #33
0
        /// <summary>
        /// Creates a browser that finds the references to the branch.
        /// </summary>
        /// <param name="context">The system context to use.</param>
        /// <param name="view">The view which may restrict the set of references/nodes found.</param>
        /// <param name="referenceType">The type of references being followed.</param>
        /// <param name="includeSubtypes">Whether subtypes of the reference type are followed.</param>
        /// <param name="browseDirection">Which way the references are being followed.</param>
        /// <param name="browseName">The browse name of a specific target (used when translating browse paths).</param>
        /// <param name="additionalReferences">Any additional references that should be included.</param>
        /// <param name="internalOnly">If true the browser should not making blocking calls to external systems.</param>
        /// <returns>The browse object (must be disposed).</returns>
        public override INodeBrowser CreateBrowser(
            ISystemContext context, 
            ViewDescription view, 
            NodeId referenceType, 
            bool includeSubtypes, 
            BrowseDirection browseDirection, 
            QualifiedName browseName,
            IEnumerable<IReference> 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;
        }
コード例 #34
0
ファイル: MemoryBufferState.cs プロジェクト: yuriik83/UA-.NET
        /// <summary>
        /// Handles a write operation for an individual tag.
        /// </summary>
        public ServiceResult WriteTagValue(
            ISystemContext context,
            NodeState node,
            NumericRange indexRange,
            QualifiedName dataEncoding,
            ref object value,
            ref StatusCode statusCode,
            ref DateTime timestamp)
        {
            MemoryTagState tag = node as MemoryTagState;

            if (tag == null)
            {
                return StatusCodes.BadNodeIdUnknown;
            }

            if (NumericRange.Empty != indexRange)
            {
                return StatusCodes.BadIndexRangeInvalid;
            }

            if (!QualifiedName.IsNull(dataEncoding))
            {
                return StatusCodes.BadDataEncodingInvalid;
            }

            if (statusCode != StatusCodes.Good)
            {
                return StatusCodes.BadWriteNotSupported;
            }

            if (timestamp != DateTime.MinValue)
            {
                return StatusCodes.BadWriteNotSupported;
            }

            bool changed = false;
            int offset = (int)tag.Offset;

            lock (m_dataLock)
            {
                if (offset < 0 || offset >= m_buffer.Length)
                {
                    return StatusCodes.BadNodeIdUnknown;
                }

                if (m_buffer == null)
                {
                    return StatusCodes.BadOutOfService;
                }

                byte[] bytes = null;

                switch (m_elementType)
                {
                    case BuiltInType.UInt32:
                    {
                        uint? valueToWrite = value as uint?;

                        if (valueToWrite == null)
                        {
                            return StatusCodes.BadTypeMismatch;
                        }

                        bytes = BitConverter.GetBytes(valueToWrite.Value);
                        break;
                    }

                    case BuiltInType.Double:
                    {
                        double? valueToWrite = value as double?;

                        if (valueToWrite == null)
                        {
                            return StatusCodes.BadTypeMismatch;
                        }

                        bytes = BitConverter.GetBytes(valueToWrite.Value);
                        break;
                    }

                    default:
                    {
                        return StatusCodes.BadNodeIdUnknown;
                    }
                }

                for (int ii = 0; ii < bytes.Length; ii++)
                {
                    if (!changed)
                    {
                        if (m_buffer[offset + ii] != bytes[ii])
                        {
                            changed = true;
                        }
                    }

                    m_buffer[offset + ii] = bytes[ii];
                }
            }

            if (changed)
            {
                OnBufferChanged(offset);
            }

            return ServiceResult.Good;
        }
コード例 #35
0
        /// <summary>
        /// Finds the child with the specified browse name.
        /// </summary>
        protected override BaseInstanceState FindChild(
            ISystemContext context,
            QualifiedName browseName,
            bool createOrReplace,
            BaseInstanceState replacement)
        {
            if (QualifiedName.IsNull(browseName))
            {
                return null;
            }

            BaseInstanceState instance = null;

            switch (browseName.Name)
            {
                case BrowseNames.InputArguments:
                {
                    if (createOrReplace)
                    {
                        if (InputArguments == null)
                        {
                            if (replacement == null)
                            {
                                InputArguments = new PropertyState<Argument[]>(this);
                            }
                            else
                            {
                                InputArguments = (PropertyState<Argument[]>)replacement;
                            }
                        }
                    }

                    instance = InputArguments;
                    break;
                }

                case BrowseNames.OutputArguments:
                {
                    if (createOrReplace)
                    {
                        if (OutputArguments == null)
                        {
                            if (replacement == null)
                            {
                                OutputArguments = new PropertyState<Argument[]>(this);
                            }
                            else
                            {
                                OutputArguments = (PropertyState<Argument[]>)replacement;
                            }
                        }
                    }

                    instance = OutputArguments;
                    break;
                }
            }

            if (instance != null)
            {
                return instance;
            }

            return base.FindChild(context, browseName, createOrReplace, replacement);
        }
コード例 #36
0
        private ServiceResult OnUserScalarValue2(
            ISystemContext context,
            MethodState method,
            NodeId objectId,
            DateTime dateTimeIn,
            Uuid guidIn,
            byte[] byteStringIn,
            XmlElement xmlElementIn,
            NodeId nodeIdIn,
            ExpandedNodeId expandedNodeIdIn,
            QualifiedName qualifiedNameIn,
            LocalizedText localizedTextIn,
            StatusCode statusCodeIn,
            object variantIn,
            ref DateTime dateTimeOut,
            ref Uuid guidOut,
            ref byte[] byteStringOut,
            ref XmlElement xmlElementOut,
            ref NodeId nodeIdOut,
            ref ExpandedNodeId expandedNodeIdOut,
            ref QualifiedName qualifiedNameOut,
            ref LocalizedText localizedTextOut,
            ref StatusCode statusCodeOut,
            ref object variantOut)
        {
            dateTimeOut = dateTimeIn;
            guidOut = guidIn;
            byteStringOut = byteStringIn;
            xmlElementOut = xmlElementIn;
            nodeIdOut = nodeIdIn;
            expandedNodeIdOut = expandedNodeIdIn;
            qualifiedNameOut = qualifiedNameIn;
            localizedTextOut = localizedTextIn;
            statusCodeOut = statusCodeIn;
            variantOut = variantIn;

            return ServiceResult.Good;
        }
コード例 #37
0
        /// <summary>
        /// Finds the child with the specified browse name.
        /// </summary>
        protected override BaseInstanceState FindChild(
            ISystemContext context,
            QualifiedName browseName,
            bool createOrReplace,
            BaseInstanceState replacement)
        {
            if (QualifiedName.IsNull(browseName))
            {
                return null;
            }

            BaseInstanceState instance = null;

            switch (browseName.Name)
            {
                case FileSystem.BrowseNames.LastUpdateTime:
                {
                    if (createOrReplace)
                    {
                        if (LastUpdateTime == null)
                        {
                            if (replacement == null)
                            {
                                LastUpdateTime = new PropertyState<DateTime>(this);
                            }
                            else
                            {
                                LastUpdateTime = (PropertyState<DateTime>)replacement;
                            }
                        }
                    }

                    instance = LastUpdateTime;
                    break;
                }

                case FileSystem.BrowseNames.CreateController:
                {
                    if (createOrReplace)
                    {
                        if (CreateController == null)
                        {
                            if (replacement == null)
                            {
                                CreateController = new CreateControllerMethodState(this);
                            }
                            else
                            {
                                CreateController = (CreateControllerMethodState)replacement;
                            }
                        }
                    }

                    instance = CreateController;
                    break;
                }
            }

            if (instance != null)
            {
                return instance;
            }

            return base.FindChild(context, browseName, createOrReplace, replacement);
        }
コード例 #38
0
        private ServiceResult OnUserArrayValue2(
            ISystemContext context,
            MethodState method,
            NodeId objectId,
            DateTime[] dateTimeIn,
            Uuid[] guidIn,
            byte[][] byteStringIn,
            XmlElement[] xmlElementIn,
            NodeId[] nodeIdIn,
            ExpandedNodeId[] expandedNodeIdIn,
            QualifiedName[] qualifiedNameIn,
            LocalizedText[] localizedTextIn,
            StatusCode[] statusCodeIn,
            Variant[] variantIn,
            ref DateTime[] dateTimeOut,
            ref Uuid[] guidOut,
            ref byte[][] byteStringOut,
            ref XmlElement[] xmlElementOut,
            ref NodeId[] nodeIdOut,
            ref ExpandedNodeId[] expandedNodeIdOut,
            ref QualifiedName[] qualifiedNameOut,
            ref LocalizedText[] localizedTextOut,
            ref StatusCode[] statusCodeOut,
            ref Variant[] variantOut)
        {
            dateTimeOut = dateTimeIn;
            guidOut = guidIn;
            byteStringOut = byteStringIn;
            xmlElementOut = xmlElementIn;
            nodeIdOut = nodeIdIn;
            expandedNodeIdOut = expandedNodeIdIn;
            qualifiedNameOut = qualifiedNameIn;
            localizedTextOut = localizedTextIn;
            statusCodeOut = statusCodeIn;
            variantOut = variantIn;

            return ServiceResult.Good;
        }
コード例 #39
0
        /// <summary>
        /// Finds the child with the specified browse name.
        /// </summary>
        protected override BaseInstanceState FindChild(
            ISystemContext context,
            QualifiedName browseName,
            bool createOrReplace,
            BaseInstanceState replacement)
        {
            if (QualifiedName.IsNull(browseName))
            {
                return null;
            }

            BaseInstanceState instance = null;

            switch (browseName.Name)
            {
                case FileSystem.BrowseNames.GasFlow:
                {
                    if (createOrReplace)
                    {
                        if (GasFlow == null)
                        {
                            if (replacement == null)
                            {
                                GasFlow = new DataItemState<double>(this);
                            }
                            else
                            {
                                GasFlow = (DataItemState<double>)replacement;
                            }
                        }
                    }

                    instance = GasFlow;
                    break;
                }
            }

            if (instance != null)
            {
                return instance;
            }

            return base.FindChild(context, browseName, createOrReplace, replacement);
        }
コード例 #40
0
        /// <summary>
        /// Creates a new instance.
        /// </summary>
        /// <param name="context">The current context.</param>
        /// <param name="parent">The parent.</param>
        /// <param name="nodeClass">The node class.</param>
        /// <param name="browseName">The browse name.</param>
        /// <param name="referenceTypeId">The reference type between the parent and the node.</param>
        /// <param name="typeDefinitionId">The type definition.</param>
        /// <returns>Returns null if the type is not known.</returns>
        public virtual NodeState CreateInstance(
            ISystemContext context,
            NodeState parent,
            NodeClass nodeClass,
            QualifiedName browseName,
            NodeId referenceTypeId,
            NodeId typeDefinitionId)
        {
            NodeState child = null;

            if (m_types != null && !NodeId.IsNull(typeDefinitionId))
            {
                Type type = null;

                if (m_types.TryGetValue(typeDefinitionId, out type))
                {
                    return(Activator.CreateInstance(type, parent) as NodeState);
                }
            }

            switch (nodeClass)
            {
            case NodeClass.Variable:
            {
                if (context.TypeTable != null && context.TypeTable.IsTypeOf(referenceTypeId, ReferenceTypeIds.HasProperty))
                {
                    child = new PropertyState(parent);
                    break;
                }

                child = new BaseDataVariableState(parent);
                break;
            }

            case NodeClass.Object:
            {
                child = new BaseObjectState(parent);
                break;
            }

            case NodeClass.Method:
            {
                child = new MethodState(parent);
                break;
            }

            case NodeClass.ReferenceType:
            {
                child = new ReferenceTypeState();
                break;
            }

            case NodeClass.ObjectType:
            {
                child = new BaseObjectTypeState();
                break;
            }

            case NodeClass.VariableType:
            {
                child = new BaseDataVariableTypeState();
                break;
            }

            case NodeClass.DataType:
            {
                child = new DataTypeState();
                break;
            }

            case NodeClass.View:
            {
                child = new ViewState();
                break;
            }

            default:
            {
                child = null;
                break;
            }
            }

            return(child);
        }
コード例 #41
0
        /// <summary>
        /// Finds the child with the specified browse name.
        /// </summary>
        protected override BaseInstanceState FindChild(
            ISystemContext context,
            QualifiedName browseName,
            bool createOrReplace,
            BaseInstanceState replacement)
        {
            if (QualifiedName.IsNull(browseName))
            {
                return null;
            }

            BaseInstanceState instance = null;

            switch (browseName.Name)
            {
                case FileSystem.BrowseNames.Temperature:
                {
                    if (createOrReplace)
                    {
                        if (Temperature == null)
                        {
                            if (replacement == null)
                            {
                                Temperature = new PropertyState<double>(this);
                            }
                            else
                            {
                                Temperature = (PropertyState<double>)replacement;
                            }
                        }
                    }

                    instance = Temperature;
                    break;
                }

                case FileSystem.BrowseNames.State:
                {
                    if (createOrReplace)
                    {
                        if (State == null)
                        {
                            if (replacement == null)
                            {
                                State = new PropertyState<int>(this);
                            }
                            else
                            {
                                State = (PropertyState<int>)replacement;
                            }
                        }
                    }

                    instance = State;
                    break;
                }
            }

            if (instance != null)
            {
                return instance;
            }

            return base.FindChild(context, browseName, createOrReplace, replacement);
        }
コード例 #42
0
ファイル: NodeTable.cs プロジェクト: martycav/UANodeSet
        /// <summary>
        /// Adds a set of nodes to the table.
        /// </summary>
        /// <param name="nodeSet">The node set.</param>
        /// <param name="externalReferences">The external references.</param>
        /// <returns></returns>
        public List <Node> Import(NodeSet nodeSet, IDictionary <NodeId, IList <IReference> > externalReferences)
        {
            List <Node> importedNodes = new List <Node>();

            if (nodeSet == null)
            {
                return(importedNodes);
            }

            // add the nodes.
            foreach (Node nodeToImport in nodeSet.Nodes)
            {
                // ignore empty nodes.
                if (nodeToImport == null || NodeId.IsNull(nodeToImport.NodeId))
                {
                    continue;
                }

                Node node = nodeSet.Copy(nodeToImport, m_namespaceUris, m_serverUris);

                // assign a browse name.
                if (QualifiedName.IsNull(node.BrowseName))
                {
                    node.BrowseName = new QualifiedName(node.NodeId.ToString(), 1);
                }

                // assign a display name.
                if (LocalizedText.IsNullOrEmpty(node.DisplayName))
                {
                    node.DisplayName = new LocalizedText(node.BrowseName.Name);
                }

                // index references (the node ids in the references were translated by the Copy() call above).
                foreach (ReferenceNode reference in node.References)
                {
                    // ignore invalid references.
                    if (NodeId.IsNull(reference.ReferenceTypeId) || NodeId.IsNull(reference.TargetId))
                    {
                        continue;
                    }

                    // ignore missing targets.
                    ExpandedNodeId targetId = reference.TargetId;

                    if (NodeId.IsNull(targetId))
                    {
                        continue;
                    }

                    // index reference.
                    node.ReferenceTable.Add(reference.ReferenceTypeId, reference.IsInverse, targetId);

                    // see if a remote node needs to be created.
                    if (targetId.ServerIndex != 0)
                    {
                        RemoteNode remoteNode = Find(targetId) as RemoteNode;

                        if (remoteNode == null)
                        {
                            remoteNode = new RemoteNode(this, targetId);
                            InternalAdd(remoteNode);
                        }

                        remoteNode.AddRef();
                    }
                }

                // clear imported references.
                node.References.Clear();

                // add the node.
                InternalAdd(node);
                importedNodes.Add(node);
            }

            // import the nodes.
            foreach (Node node in importedNodes)
            {
                // ignore invalid nodes.
                if (node == null || NodeId.IsNull(node.NodeId))
                {
                    continue;
                }

                // add reverse references.
                foreach (IReference reference in node.ReferenceTable)
                {
                    Node targetNode = Find(reference.TargetId) as Node;

                    if (targetNode == null)
                    {
                        if (reference.TargetId.ServerIndex != 0)
                        {
                            continue;
                        }

                        // return the reverse reference to a node outside the table.
                        if (externalReferences != null)
                        {
                            NodeId targetId = ExpandedNodeId.ToNodeId(reference.TargetId, m_namespaceUris);

                            if (targetId == null)
                            {
                                continue;
                            }

                            IList <IReference> referenceList = null;

                            if (!externalReferences.TryGetValue(targetId, out referenceList))
                            {
                                externalReferences[targetId] = referenceList = new List <IReference>();
                            }

                            ReferenceNode reverseReference = new ReferenceNode();

                            reverseReference.ReferenceTypeId = reference.ReferenceTypeId;
                            reverseReference.IsInverse       = !reference.IsInverse;
                            reverseReference.TargetId        = node.NodeId;

                            referenceList.Add(reverseReference);
                        }

                        continue;
                    }

                    // type definition and modelling rule references are one way.
                    if (reference.ReferenceTypeId != ReferenceTypeIds.HasTypeDefinition && reference.ReferenceTypeId != ReferenceTypeIds.HasModellingRule)
                    {
                        targetNode.ReferenceTable.Add(reference.ReferenceTypeId, !reference.IsInverse, node.NodeId);
                    }
                }

                // see if it is a type.
                if (m_typeTree != null)
                {
                    m_typeTree.Add(node);
                }
            }

            return(importedNodes);
        }