Example #1
0
        /// <summary>
        /// Browses the children of the node and updates the tree.
        /// </summary>
        private bool BrowseChildren(TreeNode parent)
        {
            ReferenceDescription reference = parent.Tag as ReferenceDescription;

            if (reference == null)
            {
                return(false);
            }

            parent.Nodes.Clear();

            if (reference.NodeId.IsAbsolute)
            {
                return(false);
            }

            BrowseDescription nodeToBrowse = new BrowseDescription();

            nodeToBrowse.NodeId          = (NodeId)reference.NodeId;
            nodeToBrowse.BrowseDirection = m_browseDirection;
            nodeToBrowse.ReferenceTypeId = m_referenceTypeId;
            nodeToBrowse.IncludeSubtypes = true;
            nodeToBrowse.NodeClassMask   = 0;
            nodeToBrowse.ResultMask      = (uint)(int)BrowseResultMask.All;

            BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection();

            nodesToBrowse.Add(nodeToBrowse);

            ViewDescription view = null;

            if (NodeId.IsNull(m_viewId))
            {
                view             = new ViewDescription();
                view.ViewId      = m_viewId;
                view.Timestamp   = DateTime.MinValue;
                view.ViewVersion = 0;
            }

            BrowseResultCollection   results         = null;
            DiagnosticInfoCollection diagnosticInfos = null;

            m_session.Browse(
                null,
                view,
                0,
                nodesToBrowse,
                out results,
                out diagnosticInfos);

            if (results.Count != 1 || StatusCode.IsBad(results[0].StatusCode))
            {
                return(false);
            }

            UpdateNode(parent, results[0].References);

            while (results[0].ContinuationPoint != null && results[0].ContinuationPoint.Length > 0)
            {
                ByteStringCollection continuationPoints = new ByteStringCollection();
                continuationPoints.Add(results[0].ContinuationPoint);

                m_session.BrowseNext(
                    null,
                    parent == null,
                    continuationPoints,
                    out results,
                    out diagnosticInfos);

                if (results.Count != 1 || StatusCode.IsBad(results[0].StatusCode))
                {
                    return(false);
                }

                UpdateNode(parent, results[0].References);
            }

            return(true);
        }
        /// <summary>
        /// Worker function to browse the full address space of a server.
        /// </summary>
        /// <param name="services">The service interface.</param>
        /// <param name="operationLimits">The operation limits.</param>
        public static ReferenceDescriptionCollection BrowseFullAddressSpaceWorker(
            IServerTestServices services,
            RequestHeader requestHeader,
            OperationLimits operationLimits     = null,
            BrowseDescription browseDescription = null)
        {
            operationLimits         = operationLimits ?? new OperationLimits();
            requestHeader.Timestamp = DateTime.UtcNow;

            // Browse template
            var startingNode   = Objects.RootFolder;
            var browseTemplate = browseDescription ?? new BrowseDescription {
                NodeId          = startingNode,
                BrowseDirection = BrowseDirection.Forward,
                ReferenceTypeId = ReferenceTypeIds.HierarchicalReferences,
                IncludeSubtypes = true,
                NodeClassMask   = 0,
                ResultMask      = (uint)BrowseResultMask.All
            };
            var browseDescriptionCollection = ServerFixtureUtils.CreateBrowseDescriptionCollectionFromNodeId(
                new NodeIdCollection(new NodeId[] { Objects.RootFolder }),
                browseTemplate);

            // Browse
            ResponseHeader response = null;
            uint           requestedMaxReferencesPerNode = operationLimits.MaxNodesPerBrowse;
            bool           verifyMaxNodesPerBrowse       = operationLimits.MaxNodesPerBrowse > 0;
            var            referenceDescriptions         = new ReferenceDescriptionCollection();

            // Test if server responds with BadNothingToDo
            {
                var sre = Assert.Throws <ServiceResultException>(() =>
                                                                 _ = services.Browse(requestHeader, null,
                                                                                     0, browseDescriptionCollection.Take(0).ToArray(),
                                                                                     out var results, out var infos));
                Assert.AreEqual(StatusCodes.BadNothingToDo, sre.StatusCode);
            }

            while (browseDescriptionCollection.Any())
            {
                BrowseResultCollection allResults = new BrowseResultCollection();
                if (verifyMaxNodesPerBrowse &&
                    browseDescriptionCollection.Count > operationLimits.MaxNodesPerBrowse)
                {
                    verifyMaxNodesPerBrowse = false;
                    // Test if server responds with BadTooManyOperations
                    var sre = Assert.Throws <ServiceResultException>(() =>
                                                                     _ = services.Browse(requestHeader, null,
                                                                                         0, browseDescriptionCollection,
                                                                                         out var results, out var infos));
                    Assert.AreEqual(StatusCodes.BadTooManyOperations, sre.StatusCode);

                    // Test if server responds with BadTooManyOperations
                    var tempBrowsePath = browseDescriptionCollection.Take((int)operationLimits.MaxNodesPerBrowse + 1).ToArray();
                    sre = Assert.Throws <ServiceResultException>(() =>
                                                                 _ = services.Browse(requestHeader, null,
                                                                                     0, tempBrowsePath,
                                                                                     out var results, out var infos));
                    Assert.AreEqual(StatusCodes.BadTooManyOperations, sre.StatusCode);
                }

                bool repeatBrowse;
                var  maxNodesPerBrowse = operationLimits.MaxNodesPerBrowse;
                BrowseResultCollection   browseResultCollection = new BrowseResultCollection();
                DiagnosticInfoCollection diagnosticsInfoCollection;
                do
                {
                    var browseCollection = (maxNodesPerBrowse == 0) ?
                                           browseDescriptionCollection :
                                           browseDescriptionCollection.Take((int)maxNodesPerBrowse).ToArray();
                    repeatBrowse = false;
                    try
                    {
                        requestHeader.Timestamp = DateTime.UtcNow;
                        response = services.Browse(requestHeader, null,
                                                   requestedMaxReferencesPerNode, browseCollection,
                                                   out browseResultCollection, out diagnosticsInfoCollection);
                        ServerFixtureUtils.ValidateResponse(response);
                        ServerFixtureUtils.ValidateDiagnosticInfos(diagnosticsInfoCollection, browseCollection);

                        allResults.AddRange(browseResultCollection);
                    }
                    catch (ServiceResultException sre)
                    {
                        if (sre.StatusCode == StatusCodes.BadEncodingLimitsExceeded ||
                            sre.StatusCode == StatusCodes.BadResponseTooLarge)
                        {
                            // try to address by overriding operation limit
                            maxNodesPerBrowse = maxNodesPerBrowse == 0 ?
                                                (uint)browseCollection.Count / 2 : maxNodesPerBrowse / 2;
                            repeatBrowse = true;
                        }
                        else
                        {
                            throw;
                        }
                    }
                } while (repeatBrowse);

                if (maxNodesPerBrowse == 0)
                {
                    browseDescriptionCollection.Clear();
                }
                else
                {
                    browseDescriptionCollection = browseDescriptionCollection.Skip((int)maxNodesPerBrowse).ToArray();
                }

                // Browse next
                var continuationPoints = ServerFixtureUtils.PrepareBrowseNext(browseResultCollection);
                while (continuationPoints.Any())
                {
                    requestHeader.Timestamp = DateTime.UtcNow;
                    response = services.BrowseNext(requestHeader, false, continuationPoints,
                                                   out var browseNextResultCollection, out diagnosticsInfoCollection);
                    ServerFixtureUtils.ValidateResponse(response);
                    ServerFixtureUtils.ValidateDiagnosticInfos(diagnosticsInfoCollection, continuationPoints);
                    allResults.AddRange(browseNextResultCollection);
                    continuationPoints = ServerFixtureUtils.PrepareBrowseNext(browseNextResultCollection);
                }

                // Build browse request for next level
                var browseTable = new NodeIdCollection();
                foreach (var result in allResults)
                {
                    referenceDescriptions.AddRange(result.References);
                    foreach (var reference in result.References)
                    {
                        browseTable.Add(ExpandedNodeId.ToNodeId(reference.NodeId, null));
                    }
                }
                browseDescriptionCollection = ServerFixtureUtils.CreateBrowseDescriptionCollectionFromNodeId(browseTable, browseTemplate);
            }

            referenceDescriptions.Sort((x, y) => (x.NodeId.CompareTo(y.NodeId)));

            TestContext.Out.WriteLine("Found {0} references on server.", referenceDescriptions.Count);
            foreach (var reference in referenceDescriptions)
            {
                TestContext.Out.WriteLine("NodeId {0} {1} {2}", reference.NodeId, reference.NodeClass, reference.BrowseName);
            }
            return(referenceDescriptions);
        }
Example #3
0
        /// <summary>
        /// Collects the fields for the instance node.
        /// </summary>
        /// <param name="session">The session.</param>
        /// <param name="nodeId">The node id.</param>
        /// <param name="parentPath">The parent path.</param>
        /// <param name="fields">The event fields.</param>
        /// <param name="fieldNodeIds">The node id for the declaration of the field.</param>
        /// <param name="foundNodes">The table of found nodes.</param>
        private static void CollectFields(
            Session session,
            NodeId nodeId,
            QualifiedNameCollection parentPath,
            SimpleAttributeOperandCollection fields,
            List <NodeId> fieldNodeIds,
            Dictionary <NodeId, QualifiedNameCollection> foundNodes)
        {
            // find all of the children of the field.
            BrowseDescription nodeToBrowse = new BrowseDescription();

            nodeToBrowse.NodeId          = nodeId;
            nodeToBrowse.BrowseDirection = BrowseDirection.Forward;
            nodeToBrowse.ReferenceTypeId = ReferenceTypeIds.Aggregates;
            nodeToBrowse.IncludeSubtypes = true;
            nodeToBrowse.NodeClassMask   = (uint)(NodeClass.Object | NodeClass.Variable);
            nodeToBrowse.ResultMask      = (uint)BrowseResultMask.All;

            ReferenceDescriptionCollection children = FormUtils.Browse(session, nodeToBrowse, false);

            if (children == null)
            {
                return;
            }

            // process the children.
            for (int ii = 0; ii < children.Count; ii++)
            {
                ReferenceDescription child = children[ii];

                if (child.NodeId.IsAbsolute)
                {
                    continue;
                }

                // construct browse path.
                QualifiedNameCollection browsePath = new QualifiedNameCollection(parentPath);
                browsePath.Add(child.BrowseName);

                // check if the browse path is already in the list.
                int index = ContainsPath(fields, browsePath);

                if (index < 0)
                {
                    SimpleAttributeOperand field = new SimpleAttributeOperand();

                    field.TypeDefinitionId = ObjectTypeIds.BaseEventType;
                    field.BrowsePath       = browsePath;
                    field.AttributeId      = (child.NodeClass == NodeClass.Variable) ? Attributes.Value : Attributes.NodeId;

                    fields.Add(field);
                    fieldNodeIds.Add((NodeId)child.NodeId);
                }

                // recusively find all of the children.
                NodeId targetId = (NodeId)child.NodeId;

                // need to guard against loops.
                if (!foundNodes.ContainsKey(targetId))
                {
                    foundNodes.Add(targetId, browsePath);
                    CollectFields(session, (NodeId)child.NodeId, browsePath, fields, fieldNodeIds, foundNodes);
                }
            }
        }
Example #4
0
        /// <summary>
        /// Displays the attributes and properties in the attributes view.
        /// </summary>
        /// <param name="sourceId">The NodeId of the Node to browse.</param>
        private void DisplayAttributes(NodeId sourceId)
        {
            try
            {
                AttributesLV.Items.Clear();

                ReadValueIdCollection nodesToRead = new ReadValueIdCollection();

                // attempt to read all possible attributes.
                for (uint ii = Attributes.NodeClass; ii <= Attributes.UserExecutable; ii++)
                {
                    ReadValueId nodeToRead = new ReadValueId();
                    nodeToRead.NodeId      = sourceId;
                    nodeToRead.AttributeId = ii;
                    nodesToRead.Add(nodeToRead);
                }

                int startOfProperties = nodesToRead.Count;

                // find all of the pror of the node.
                BrowseDescription nodeToBrowse1 = new BrowseDescription();

                nodeToBrowse1.NodeId          = sourceId;
                nodeToBrowse1.BrowseDirection = BrowseDirection.Forward;
                nodeToBrowse1.ReferenceTypeId = ReferenceTypeIds.HasProperty;
                nodeToBrowse1.IncludeSubtypes = true;
                nodeToBrowse1.NodeClassMask   = 0;
                nodeToBrowse1.ResultMask      = (uint)BrowseResultMask.All;

                BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection();
                nodesToBrowse.Add(nodeToBrowse1);

                // fetch property references from the server.
                ReferenceDescriptionCollection references = FormUtils.Browse(m_session, nodesToBrowse, false);

                if (references == null)
                {
                    return;
                }

                for (int ii = 0; ii < references.Count; ii++)
                {
                    // ignore external references.
                    if (references[ii].NodeId.IsAbsolute)
                    {
                        continue;
                    }

                    ReadValueId nodeToRead = new ReadValueId();
                    nodeToRead.NodeId      = (NodeId)references[ii].NodeId;
                    nodeToRead.AttributeId = Attributes.Value;
                    nodesToRead.Add(nodeToRead);
                }

                // read all values.
                DataValueCollection      results         = null;
                DiagnosticInfoCollection diagnosticInfos = null;

                m_session.Read(
                    null,
                    0,
                    TimestampsToReturn.Neither,
                    nodesToRead,
                    out results,
                    out diagnosticInfos);

                ClientBase.ValidateResponse(results, nodesToRead);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);

                // process results.
                for (int ii = 0; ii < results.Count; ii++)
                {
                    string name     = null;
                    string datatype = null;
                    string value    = null;

                    // process attribute value.
                    if (ii < startOfProperties)
                    {
                        // ignore attributes which are invalid for the node.
                        if (results[ii].StatusCode == StatusCodes.BadAttributeIdInvalid)
                        {
                            continue;
                        }

                        // get the name of the attribute.
                        name = Attributes.GetBrowseName(nodesToRead[ii].AttributeId);

                        // display any unexpected error.
                        if (StatusCode.IsBad(results[ii].StatusCode))
                        {
                            datatype = Utils.Format("{0}", Attributes.GetDataTypeId(nodesToRead[ii].AttributeId));
                            value    = Utils.Format("{0}", results[ii].StatusCode);
                        }

                        // display the value.
                        else
                        {
                            TypeInfo typeInfo = TypeInfo.Construct(results[ii].Value);

                            datatype = typeInfo.BuiltInType.ToString();

                            if (typeInfo.ValueRank >= ValueRanks.OneOrMoreDimensions)
                            {
                                datatype += "[]";
                            }

                            value = Utils.Format("{0}", results[ii].Value);
                        }
                    }

                    // process property value.
                    else
                    {
                        // ignore properties which are invalid for the node.
                        if (results[ii].StatusCode == StatusCodes.BadNodeIdUnknown)
                        {
                            continue;
                        }

                        // get the name of the property.
                        name = Utils.Format("{0}", references[ii - startOfProperties]);

                        // display any unexpected error.
                        if (StatusCode.IsBad(results[ii].StatusCode))
                        {
                            datatype = String.Empty;
                            value    = Utils.Format("{0}", results[ii].StatusCode);
                        }

                        // display the value.
                        else
                        {
                            TypeInfo typeInfo = TypeInfo.Construct(results[ii].Value);

                            datatype = typeInfo.BuiltInType.ToString();

                            if (typeInfo.ValueRank >= ValueRanks.OneOrMoreDimensions)
                            {
                                datatype += "[]";
                            }

                            value = Utils.Format("{0}", results[ii].Value);
                        }
                    }

                    // add the attribute name/value to the list view.
                    ListViewItem item = new ListViewItem(name);
                    item.SubItems.Add(datatype);
                    item.SubItems.Add(value);
                    AttributesLV.Items.Add(item);
                }

                // adjust width of all columns.
                for (int ii = 0; ii < AttributesLV.Columns.Count; ii++)
                {
                    AttributesLV.Columns[ii].Width = -2;
                }
            }
            catch (Exception exception)
            {
                ClientUtils.HandleException(this.Text, exception);
            }
        }
Example #5
0
        /// <summary>
        /// Browses the address space and returns the references found.
        /// </summary>
        /// <param name="session">The session.</param>
        /// <param name="nodeToBrowse">The NodeId for the starting node.</param>
        /// <param name="throwOnError">if set to <c>true</c> a exception will be thrown on an error.</param>
        /// <returns>
        /// The references found. Null if an error occurred.
        /// </returns>
        public static ReferenceDescriptionCollection Browse(Session session, BrowseDescription nodeToBrowse, bool throwOnError)
        {
            try
            {
                ReferenceDescriptionCollection references = new ReferenceDescriptionCollection();

                // construct browse request.
                BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection();
                nodesToBrowse.Add(nodeToBrowse);

                // start the browse operation.
                BrowseResultCollection   results         = null;
                DiagnosticInfoCollection diagnosticInfos = null;

                session.Browse(
                    null,
                    null,
                    0,
                    nodesToBrowse,
                    out results,
                    out diagnosticInfos);

                ClientBase.ValidateResponse(results, nodesToBrowse);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToBrowse);

                do
                {
                    // check for error.
                    if (StatusCode.IsBad(results[0].StatusCode))
                    {
                        throw new ServiceResultException(results[0].StatusCode);
                    }

                    // process results.
                    for (int ii = 0; ii < results[0].References.Count; ii++)
                    {
                        references.Add(results[0].References[ii]);
                    }

                    // check if all references have been fetched.
                    if (results[0].References.Count == 0 || results[0].ContinuationPoint == null)
                    {
                        break;
                    }

                    // continue browse operation.
                    ByteStringCollection continuationPoints = new ByteStringCollection();
                    continuationPoints.Add(results[0].ContinuationPoint);

                    session.BrowseNext(
                        null,
                        false,
                        continuationPoints,
                        out results,
                        out diagnosticInfos);

                    ClientBase.ValidateResponse(results, continuationPoints);
                    ClientBase.ValidateDiagnosticInfos(diagnosticInfos, continuationPoints);
                }while (true);

                //return complete list.
                return(references);
            }
            catch (Exception exception)
            {
                if (throwOnError)
                {
                    throw new ServiceResultException(exception, StatusCodes.BadUnexpectedError);
                }

                return(null);
            }
        }
        /// <summary>
        /// Reads the arguments for the method.
        /// </summary>
        private void ReadArguments(NodeId nodeId)
        {
            m_inputArguments  = null;
            m_outputArguments = null;

            // build list of references to browse.
            BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection();

            BrowseDescription nodeToBrowse = new BrowseDescription();

            nodeToBrowse.NodeId          = nodeId;
            nodeToBrowse.BrowseDirection = BrowseDirection.Forward;
            nodeToBrowse.ReferenceTypeId = Opc.Ua.ReferenceTypeIds.HasProperty;
            nodeToBrowse.IncludeSubtypes = true;
            nodeToBrowse.NodeClassMask   = (uint)NodeClass.Variable;
            nodeToBrowse.ResultMask      = (uint)BrowseResultMask.BrowseName;

            nodesToBrowse.Add(nodeToBrowse);

            // find properties.
            ReferenceDescriptionCollection references = ClientUtils.Browse(m_session, null, nodesToBrowse, false);

            // build list of properties to read.
            ReadValueIdCollection nodesToRead = new ReadValueIdCollection();

            for (int ii = 0; references != null && ii < references.Count; ii++)
            {
                ReferenceDescription reference = references[ii];

                // ignore out of server references.
                if (reference.NodeId.IsAbsolute)
                {
                    continue;
                }

                // ignore other properties.
                if (reference.BrowseName != Opc.Ua.BrowseNames.InputArguments && reference.BrowseName != Opc.Ua.BrowseNames.OutputArguments)
                {
                    continue;
                }

                ReadValueId nodeToRead = new ReadValueId();
                nodeToRead.NodeId      = (NodeId)reference.NodeId;
                nodeToRead.AttributeId = Attributes.Value;
                nodeToRead.Handle      = reference;
                nodesToRead.Add(nodeToRead);
            }

            // method has no arguments.
            if (nodesToRead.Count == 0)
            {
                return;
            }

            // read the arguments.
            DataValueCollection      results         = null;
            DiagnosticInfoCollection diagnosticInfos = null;

            m_session.Read(
                null,
                0,
                TimestampsToReturn.Neither,
                nodesToRead,
                out results,
                out diagnosticInfos);

            ClientBase.ValidateResponse(results, nodesToRead);
            ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);

            // save the results.
            for (int ii = 0; ii < results.Count; ii++)
            {
                ReferenceDescription reference = (ReferenceDescription)nodesToRead[ii].Handle;

                if (StatusCode.IsGood(results[ii].StatusCode))
                {
                    if (reference.BrowseName == Opc.Ua.BrowseNames.InputArguments)
                    {
                        m_inputArguments = (Argument[])ExtensionObject.ToArray(results[ii].GetValue <ExtensionObject[]>(null), typeof(Argument));
                    }

                    if (reference.BrowseName == Opc.Ua.BrowseNames.OutputArguments)
                    {
                        m_outputArguments = (Argument[])ExtensionObject.ToArray(results[ii].GetValue <ExtensionObject[]>(null), typeof(Argument));
                    }
                }
            }

            // set default values for input arguments.
            if (m_inputArguments != null)
            {
                foreach (Argument argument in m_inputArguments)
                {
                    argument.Value = TypeInfo.GetDefaultValue(argument.DataType, argument.ValueRank, m_session.TypeTree);
                }
            }
        }
        /// <summary>
        /// Reads the properties for the node.
        /// </summary>
        private void ReadProperties(NodeId nodeId)
        {
            // build list of references to browse.
            BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection();

            BrowseDescription nodeToBrowse = new BrowseDescription();

            nodeToBrowse.NodeId          = nodeId;
            nodeToBrowse.BrowseDirection = BrowseDirection.Forward;
            nodeToBrowse.ReferenceTypeId = Opc.Ua.ReferenceTypeIds.HasProperty;
            nodeToBrowse.IncludeSubtypes = true;
            nodeToBrowse.NodeClassMask   = (uint)NodeClass.Variable;
            nodeToBrowse.ResultMask      = (uint)BrowseResultMask.All;

            nodesToBrowse.Add(nodeToBrowse);

            // find properties.
            ReferenceDescriptionCollection references = ClientUtils.Browse(m_session, View, nodesToBrowse, false);

            // build list of properties to read.
            ReadValueIdCollection nodesToRead = new ReadValueIdCollection();

            for (int ii = 0; references != null && ii < references.Count; ii++)
            {
                ReferenceDescription reference = references[ii];

                // ignore out of server references.
                if (reference.NodeId.IsAbsolute)
                {
                    continue;
                }

                ReadValueId nodeToRead = new ReadValueId();
                nodeToRead.NodeId      = (NodeId)reference.NodeId;
                nodeToRead.AttributeId = Attributes.Value;
                nodeToRead.Handle      = reference;
                nodesToRead.Add(nodeToRead);
            }

            if (nodesToRead.Count == 0)
            {
                return;
            }

            // read the properties.
            DataValueCollection      results         = null;
            DiagnosticInfoCollection diagnosticInfos = null;

            m_session.Read(
                null,
                0,
                TimestampsToReturn.Neither,
                nodesToRead,
                out results,
                out diagnosticInfos);

            ClientBase.ValidateResponse(results, nodesToRead);
            ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);

            // add the results to the display.
            for (int ii = 0; ii < results.Count; ii++)
            {
                ReferenceDescription reference = (ReferenceDescription)nodesToRead[ii].Handle;

                TypeInfo typeInfo = TypeInfo.Construct(results[ii].Value);

                // add the metadata for the attribute.
                ListViewItem item = new ListViewItem(reference.ToString());
                item.SubItems.Add(typeInfo.BuiltInType.ToString());

                if (typeInfo.ValueRank >= 0)
                {
                    item.SubItems[1].Text += "[]";
                }

                // add the value.
                if (StatusCode.IsBad(results[ii].StatusCode))
                {
                    item.SubItems.Add(results[ii].StatusCode.ToString());
                }
                else
                {
                    item.SubItems.Add(results[ii].WrappedValue.ToString());
                }

                item.Tag = new AttributeInfo()
                {
                    NodeToRead = nodesToRead[ii], Value = results[ii]
                };
                item.ImageIndex = ClientUtils.GetImageIndex(m_session, NodeClass.Variable, Opc.Ua.VariableTypeIds.PropertyType, false);

                // display in list.
                AttributesLV.Items.Add(item);
            }
        }
Example #8
0
        /// <summary>
        /// Recursively populates the event types table.
        /// </summary>
        private void IndexTypesFromServer(NodeId baseTypeId, int eventType)
        {
            // check if event type needs to be revised.
            if (baseTypeId == Opc.Ua.ObjectTypeIds.ConditionType)
            {
                eventType = OpcRcw.Ae.Constants.CONDITION_EVENT;
            }

            else if (baseTypeId == Opc.Ua.ObjectTypeIds.AuditEventType)
            {
                eventType = OpcRcw.Ae.Constants.TRACKING_EVENT;
            }

            else if (baseTypeId == Opc.Ua.ObjectTypeIds.BaseEventType)
            {
                eventType = OpcRcw.Ae.Constants.SIMPLE_EVENT;
            }

            // browse for subtypes.
            BrowseDescription nodeToBrowse = new BrowseDescription();
            nodeToBrowse.NodeId = baseTypeId;
            nodeToBrowse.BrowseDirection = BrowseDirection.Forward;
            nodeToBrowse.ReferenceTypeId = Opc.Ua.ReferenceTypeIds.HasSubtype;
            nodeToBrowse.IncludeSubtypes = false;
            nodeToBrowse.NodeClassMask = (uint)NodeClass.ObjectType;
            nodeToBrowse.ResultMask = (uint)(BrowseResultMask.BrowseName | BrowseResultMask.DisplayName | BrowseResultMask.NodeClass);

            ReferenceDescriptionCollection references = ComAeUtils.Browse(
                m_session,
                nodeToBrowse,
                false);

            for (int ii = 0; ii < references.Count; ii++)
            {
                // these types have t
                if (references[ii].NodeId.IsAbsolute)
                {
                    continue;
                }

                NodeId typeId = (NodeId)references[ii].NodeId;

                if (!m_eventTypes.ContainsKey(typeId))
                {
                    // collection the instances declared by the type.
                    List<AeEventAttribute> declarations = new List<AeEventAttribute>();
                    Dictionary<string, AeEventAttribute> map = new Dictionary<string, AeEventAttribute>();

                    ComAeUtils.CollectInstanceDeclarations(
                        m_session,
                        this,
                        (NodeId)references[ii].NodeId,
                        null,
                        declarations,
                        map);

                    AeEventCategory declaration = new AeEventCategory();
                    declaration.TypeId = (NodeId)references[ii].NodeId;
                    declaration.SuperTypeId = baseTypeId;
                    declaration.EventType = eventType;
                    declaration.Description = (LocalizedText.IsNullOrEmpty(references[ii].DisplayName)) ? references[ii].BrowseName.Name : references[ii].DisplayName.Text;
                    declaration.Attributes = declarations;
                    m_eventTypes[declaration.TypeId] = declaration;
                }

                // recursively look for subtypes.
                IndexTypesFromServer(typeId, eventType);
            }
        }
Example #9
0
        /// <summary>
        /// Verifies the reference type id.
        /// </summary>
        private bool VerifyReferenceTypeId(Node node, BrowseDescription description, ReferenceDescription reference)
        {      
            // check if field was not requested.
            if ((description.ResultMask & (uint)BrowseResultMask.ReferenceTypeId) == 0)
            {
                if (!NodeId.IsNull(reference.ReferenceTypeId))
                {
                    Log("Returned unexpected non-null ReferenceTypeId when Browsing Node '{0}'. NodeId = {1}", node, node.NodeId);
                    return false;
                }

                return true;
            }
            
            // check for null.
            if (NodeId.IsNull(reference.ReferenceTypeId))
            {
                Log("Returned unexpected null ReferenceTypeId when Browsing Node '{0}'. NodeId = {1}", node, node.NodeId);
                return false;
            }

            // check for valid reference.
            IReferenceType referenceType = Session.NodeCache.Find(reference.ReferenceTypeId) as IReferenceType;
            
            if (NodeId.IsNull(reference.ReferenceTypeId))
            {
                Log("Returned invalid ReferenceTypeId when Browsing Node '{0}'. NodeId = {1}, ReferenceTypeId = {2}", node, node.NodeId, reference.ReferenceTypeId);
                return false;
            }
            
            // check for valid subtype.
            if (!Session.TypeTree.IsTypeOf(referenceType.NodeId, description.ReferenceTypeId))
            {                
                string expectedName = description.ReferenceTypeId.ToString();
                
                IReferenceType expectedType = Session.NodeCache.Find(description.ReferenceTypeId) as IReferenceType;

                if (expectedType != null)
                {
                    expectedName = Utils.Format("{0}", expectedType.DisplayName);
                }
            
                Log("ReferenceType {2} is not a subtype of {3} when browsing Node '{0}'. NodeId = {1}", node, node.NodeId, referenceType.DisplayName, expectedName);
                return false;
            }

            return true;
        }
Example #10
0
        /// <summary>
        /// Finds an element identified by the path from the root.
        /// </summary>
        private AeBrowseElement Find(Session session, string itemId, AeBrowseElement root, Stack<string> names, bool isArea)
        {
            string browseText = null;

            BrowsePath browsePath = new BrowsePath();
            browsePath.StartingNode = root.NodeId;

            while (names.Count > 0)
            {
                RelativePathElement path = new RelativePathElement();

                path.ReferenceTypeId = Opc.Ua.ReferenceTypeIds.HasNotifier;
                path.IsInverse = false;
                path.IncludeSubtypes = true;

                // final hop can be HasEventSource for sources.
                if (!isArea && names.Count == 1)
                {
                    path.ReferenceTypeId = Opc.Ua.ReferenceTypeIds.HasEventSource;
                }

                browseText = names.Pop();
                path.TargetName = m_mapper.GetRemoteBrowseName(browseText);
                browsePath.RelativePath.Elements.Add(path);
            }

            BrowsePathCollection browsePaths = new BrowsePathCollection();
            browsePaths.Add(browsePath);

            // make the call to the server.
            BrowsePathResultCollection results;
            DiagnosticInfoCollection diagnosticInfos;

            ResponseHeader responseHeader = session.TranslateBrowsePathsToNodeIds(
                null,
                browsePaths,
                out results,
                out diagnosticInfos);

            // ensure that the server returned valid results.
            Session.ValidateResponse(results, browsePaths);
            Session.ValidateDiagnosticInfos(diagnosticInfos, browsePaths);

            // check if the start node actually exists.
            if (StatusCode.IsBad(results[0].StatusCode))
            {
                return null;
            }

            // must be exact one target.
            if (results[0].Targets.Count != 1)
            {
                return null;
            }

            // can't be an external reference.
            BrowsePathTarget target = results[0].Targets[0];

            if (target.RemainingPathIndex != UInt32.MaxValue)
            {
                return null;
            }

            // need to check if at the end of the tree.
            BrowseDescription nodeToBrowse = new BrowseDescription();
            nodeToBrowse.NodeId = (NodeId)target.TargetId;
            nodeToBrowse.ReferenceTypeId = Opc.Ua.ReferenceTypeIds.HasEventSource;
            nodeToBrowse.BrowseDirection = BrowseDirection.Forward;
            nodeToBrowse.IncludeSubtypes = true;

            ReferenceDescriptionCollection children = ComAeUtils.Browse(session, nodeToBrowse, false);

            if (!isArea)
            {
                if (children != null && children.Count > 0)
                {
                    return null;
                }
            }
            else
            {
                if (children == null || children.Count == 0)
                {
                    return null;
                }
            }

            // construct the element.
            AeBrowseElement element = new AeBrowseElement();
            element.NodeId = (NodeId)target.TargetId;
            element.ItemId = itemId;
            element.BrowseText = browseText;
            element.IsArea = isArea;

            return element;
        }
Example #11
0
        /// <summary>
        /// Browses the references for the specified node.
        /// </summary>
        public void Browse(
            BrowseDescription request,
            BrowseResult result,
            DiagnosticInfo diagnosticInfo)
        {
            lock (m_lock)
            {
                // find the starting nodes.
                Node source = m_nodes.Find(request.NodeId);

                if (source == null)
                {
                    result.StatusCode = new StatusCode(StatusCodes.BadNodeIdUnknown);
                    return;
                }

                result.References = new ListOfReferenceDescription();

                // return all of the references that meet the filter criteria.
                foreach (ReferenceNode reference in source.References)
                {
                    if (reference.IsInverse && request.BrowseDirection == BrowseDirection.Forward_0)
                    {
                        continue;
                    }

                    if (!reference.IsInverse && request.BrowseDirection == BrowseDirection.Inverse_1)
                    {
                        continue;
                    }

                    // the reference type filter can be an exact match or it can be for any subtype.
                    if (reference.ReferenceTypeId != request.ReferenceTypeId)
                    {
                        if (!request.IncludeSubtypes)
                        {
                            continue;
                        }

                        if (!IsTypeOf(reference.ReferenceTypeId, request.ReferenceTypeId))
                        {
                            continue;
                        }
                    }

                    // need to look up the target to find the attributes.
                    // note that the result filter mask is being ignored. production servers only need to 
                    // look up the attributes requested by the client.
                    Node target = m_nodes.Find(reference.TargetId);

                    if (target != null)
                    {
                        ReferenceDescription description = new ReferenceDescription();

                        description.NodeId = reference.TargetId;
                        description.IsForward = !reference.IsInverse;
                        description.ReferenceTypeId = reference.ReferenceTypeId;
                        description.BrowseName = target.BrowseName;
                        description.DisplayName = target.DisplayName;
                        description.NodeClass = target.NodeClass;
                        description.TypeDefinition = GetTypeDefinition(target);

                        result.References.Add(description);
                    }
                }
            }
        }
Example #12
0
        /// <summary>
        /// Fetches the children from the server.
        /// </summary>
        private List<AeBrowseElement> Browse(Session session, AeBrowseElement start, bool isArea)
        {
            // browse for notifiers and sources.
            BrowseDescription nodeToBrowse = new BrowseDescription();
            nodeToBrowse.NodeId = start.NodeId;
            nodeToBrowse.BrowseDirection = BrowseDirection.Forward;
            nodeToBrowse.ResultMask = (uint)(BrowseResultMask.BrowseName);
            nodeToBrowse.NodeClassMask = (uint)0;

            if (isArea)
            {
                nodeToBrowse.ReferenceTypeId = Opc.Ua.ReferenceTypeIds.HasNotifier;
                nodeToBrowse.IncludeSubtypes = true;
            }
            else
            {
                nodeToBrowse.ReferenceTypeId = Opc.Ua.ReferenceTypeIds.HasEventSource;
                nodeToBrowse.IncludeSubtypes = true;
            }

            ReferenceDescriptionCollection references = ComAeUtils.Browse(
                session,
                nodeToBrowse,
                false);

            if (references == null)
            {
                throw ComUtils.CreateComException(ResultIds.E_FAIL);
            }

            List<AeBrowseElement> hits = new List<AeBrowseElement>();

            for (int ii = 0; ii < references.Count; ii++)
            {
                // ignore remote references.
                if (references[ii].NodeId.IsAbsolute)
                {
                    continue;
                }

                // need to check if at the end of the tree.
                if (references[ii].ReferenceTypeId != ReferenceTypeIds.HasEventSource)
                {
                    nodeToBrowse.NodeId = (NodeId)references[ii].NodeId;

                    ReferenceDescriptionCollection children = ComAeUtils.Browse(session, nodeToBrowse, false);

                    if (!isArea)
                    {
                        if (children != null && children.Count > 0)
                        {
                            continue;
                        }
                    }
                    else
                    {
                        if (children == null || children.Count == 0)
                        {
                            continue;
                        }
                    }
                }

                string browseText = m_mapper.GetLocalBrowseName(references[ii].BrowseName);

                // check for duplicate browse names.
                for (int jj = 0; jj < hits.Count; jj++)
                {
                    if (hits[jj].BrowseText == browseText)
                    {
                        hits[jj].Duplicated = true;
                        browseText = null;
                        break;
                    }
                }

                // add new element.
                if (browseText != null)
                {
                    AeBrowseElement element = new AeBrowseElement();
                    element.Parent = start;
                    element.NodeId = (NodeId)references[ii].NodeId;
                    element.BrowseText = m_mapper.GetLocalBrowseName(references[ii].BrowseName);
                    element.IsArea = isArea;
                    hits.Add(element);

                    StringBuilder itemId = new StringBuilder();
                    itemId.Append(start.ItemId);
                    itemId.Append('/');
                    itemId.Append(element.BrowseText);
                    element.ItemId = itemId.ToString();
                }
            }

            // remove any duplicates.
            for (int ii = 0; ii < hits.Count;)
            {
                if (hits[ii].Duplicated)
                {
                    hits.RemoveAt(ii);
                    continue;
                }

                ii++;
            }

            return hits;
        }
Example #13
0
        /// <summary>
        /// Verifies that the server does no ignore the BrowseResultMask.
        /// </summary>
        private bool DoBrowseResultMaskTest()
        {
            // follow tree from each starting node.
            bool success = true;
                     
            double increment = MaxProgress/AvailableNodes.Count;
            double position  = 0;
            
            Log("Starting BrowseResultMaskTest for {0} Nodes ({1}% Coverage)", AvailableNodes.Values.Count, Configuration.Coverage);
            
            int counter = 0;

            foreach (Node node in AvailableNodes.Values)
            {          
                if (!CheckCoverage(ref counter))
                {
                    continue;
                }
                
                try
                {
                    BrowseDescription nodeToBrowse = new BrowseDescription();
                    
                    nodeToBrowse.NodeId = node.NodeId;
                    nodeToBrowse.BrowseDirection = BrowseDirection.Both;
                    nodeToBrowse.IncludeSubtypes = true;
                    nodeToBrowse.NodeClassMask = 0;
                    nodeToBrowse.ReferenceTypeId = ReferenceTypeIds.References;
                    nodeToBrowse.ResultMask = (uint)BrowseResultMask.None;
                    
                    ReferenceDescriptionCollection references = new ReferenceDescriptionCollection();
                    
                    if (!Browse(node, nodeToBrowse, references))
                    {
                        success = false;
                        break;
                    }
                }
                catch (Exception e)
                {
                    success = false;
                    Log(e, "BrowseResultMaskTest Failed for Node '{0}'. NodeId = {1}", node, node.NodeId);
                }

                position += increment;
                ReportProgress(position);
            }   
         
            return success;
        }
Example #14
0
        /// <summary>
        /// Begins an asynchronous invocation of the Browse service.
        /// </summary>
        /// <param name="requestHeader">The request header.</param>
        /// <param name="view">The view to browse.</param>
        /// <param name="nodeToBrowse">The node to browse.</param>
        /// <param name="maxResultsToReturn">The maximum number of returned values..</param>
        /// <param name="browseDirection">The browse direction.</param>
        /// <param name="referenceTypeId">The reference type id.</param>
        /// <param name="includeSubtypes">If set to <c>true</c> the subtypes of the ReferenceType will be included in the browse.</param>
        /// <param name="nodeClassMask">The node class mask.</param>
        /// <param name="callback">The callback.</param>
        /// <param name="asyncState"></param>
        /// <returns></returns>
        public IAsyncResult BeginBrowse(
            RequestHeader requestHeader,
            ViewDescription view,
            NodeId nodeToBrowse,
            uint maxResultsToReturn,
            BrowseDirection browseDirection,
            NodeId referenceTypeId,
            bool includeSubtypes,
            uint nodeClassMask,
            AsyncCallback callback,
            object asyncState)
        {
            BrowseDescription description = new BrowseDescription();

            description.NodeId = nodeToBrowse;
            description.BrowseDirection = browseDirection;
            description.ReferenceTypeId = referenceTypeId;
            description.IncludeSubtypes = includeSubtypes;
            description.NodeClassMask = nodeClassMask;
            description.ResultMask = (uint)BrowseResultMask.All;

            BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection();
            nodesToBrowse.Add(description);

            return BeginBrowse(
                requestHeader,
                view,
                maxResultsToReturn,
                nodesToBrowse,
                callback,
                asyncState);
        }
Example #15
0
        /// <summary>
        /// Browses the node and returns the references found.
        /// </summary>
        protected virtual bool Browse(
            Node node,
            BrowseDescription nodeToBrowse, 
            ReferenceDescriptionCollection references)
        {            
            BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection();
            nodesToBrowse.Add(nodeToBrowse);

            BrowseResultCollection results;
            DiagnosticInfoCollection diagnosticInfos;
            
            RequestHeader requestHeader = new RequestHeader();
            requestHeader.ReturnDiagnostics = 0;

            Session.Browse(
                requestHeader,
                new ViewDescription(),
                0,
                nodesToBrowse,
                out results,
                out diagnosticInfos);
            
            ClientBase.ValidateResponse(results, nodesToBrowse);
            ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToBrowse);
            
            // check diagnostics.
            if (diagnosticInfos != null && diagnosticInfos.Count > 0)
            {
                Log("Returned non-empty DiagnosticInfos array during Browse.");
                return false;
            }
            
            // process results.
            ByteStringCollection continuationPoints = new ByteStringCollection();

            for (int ii = 0; ii < results.Count; ii++)
            {
                // check status code.
                if (StatusCode.IsBad(results[ii].StatusCode))
                {
                    Log(
                        "Browse Failed for Node '{0}'. Status = {2}, NodeId = {1}", 
                        node, 
                        node.NodeId, 
                        results[ii].StatusCode);

                    return false;
                }
                
                // save references.
                references.AddRange(results[ii].References);

                if (results[ii].ContinuationPoint != null)
                {
                    continuationPoints.Add(results[ii].ContinuationPoint);
                }
            }
            
            // process continuation points.
            while (continuationPoints.Count > 0)
            {                       
                requestHeader = new RequestHeader();
                requestHeader.ReturnDiagnostics = 0;

                Session.BrowseNext(
                    requestHeader,
                    false,
                    continuationPoints,
                    out results,
                    out diagnosticInfos);
                
                ClientBase.ValidateResponse(results, continuationPoints);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, continuationPoints);

                // check diagnostics.
                if (diagnosticInfos != null && diagnosticInfos.Count > 0)
                {
                    Log("Returned non-empty DiagnosticInfos array during BrowseNext.");
                    return false;
                }
                
                continuationPoints.Clear();

                // process results.
                for (int ii = 0; ii < results.Count; ii++)
                {
                    // check status code.
                    if (StatusCode.IsBad(results[ii].StatusCode))
                    {
                        Log(
                            "BrowseNext Failed for Node '{0}'. Status = {2}, NodeId = {1}", 
                            node, 
                            node.NodeId, 
                            results[ii].StatusCode);

                        return false;
                    }

                    // save references.
                    references.AddRange(results[ii].References);

                    if (results[ii].ContinuationPoint != null)
                    {
                        // check max references.
                        if (results[ii].References.Count == 0)
                        {
                            Log(
                                "No references returned with a continuation point for Node '{0}'. NodeId = {1}",
                                node, 
                                node.NodeId);
                           
                            return false;
                        }

                        continuationPoints.Add(results[ii].ContinuationPoint);
                    }
                }
            }
            
            return true;
        }
Example #16
0
        /// <summary>
        /// Browses the address space and returns all of the supertypes of the specified type node.
        /// </summary>
        /// <param name="session">The session.</param>
        /// <param name="typeId">The NodeId for a type node in the address space.</param>
        /// <param name="throwOnError">if set to <c>true</c> a exception will be thrown on an error.</param>
        /// <returns>
        /// The references found. Null if an error occurred.
        /// </returns>
        public static ReferenceDescriptionCollection BrowseSuperTypes(Session session, NodeId typeId, bool throwOnError)
        {
            ReferenceDescriptionCollection supertypes = new ReferenceDescriptionCollection();

            try
            {
                // find all of the children of the field.
                BrowseDescription nodeToBrowse = new BrowseDescription();

                nodeToBrowse.NodeId = typeId;
                nodeToBrowse.BrowseDirection = BrowseDirection.Inverse;
                nodeToBrowse.ReferenceTypeId = ReferenceTypeIds.HasSubtype;
                nodeToBrowse.IncludeSubtypes = false; // more efficient to use IncludeSubtypes=False when possible.
                nodeToBrowse.NodeClassMask = 0; // the HasSubtype reference already restricts the targets to Types. 
                nodeToBrowse.ResultMask = (uint)BrowseResultMask.All;

                ReferenceDescriptionCollection references = Browse(session, nodeToBrowse, throwOnError);

                while (references != null && references.Count > 0)
                {
                    // should never be more than one supertype.
                    supertypes.Add(references[0]);

                    // only follow references within this server.
                    if (references[0].NodeId.IsAbsolute)
                    {
                        break;
                    }

                    // get the references for the next level up.
                    nodeToBrowse.NodeId = (NodeId)references[0].NodeId;
                    references = Browse(session, nodeToBrowse, throwOnError);
                }

                // return complete list.
                return supertypes;
            }
            catch (Exception exception)
            {
                if (throwOnError)
                {
                    throw new ServiceResultException(exception, StatusCodes.BadUnexpectedError);
                }

                return null;
            }
        }
Example #17
0
        /// <summary>
        /// Finds the targets for the specified reference.
        /// </summary>
        private static List<NodeId> FindTargetOfReference(Session session, List<NodeId> nodeIds, NodeId referenceTypeId, bool throwOnError)
        {
            try
            {
                // construct browse request.
                BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection();

                for (int ii = 0; ii < nodeIds.Count; ii++)
                {
                    BrowseDescription nodeToBrowse = new BrowseDescription();
                    nodeToBrowse.NodeId = nodeIds[ii];
                    nodeToBrowse.BrowseDirection = BrowseDirection.Forward;
                    nodeToBrowse.ReferenceTypeId = referenceTypeId;
                    nodeToBrowse.IncludeSubtypes = false;
                    nodeToBrowse.NodeClassMask = 0;
                    nodeToBrowse.ResultMask = (uint)BrowseResultMask.None;
                    nodesToBrowse.Add(nodeToBrowse);
                }

                // start the browse operation.
                BrowseResultCollection results = null;
                DiagnosticInfoCollection diagnosticInfos = null;

                session.Browse(
                    null,
                    null,
                    1,
                    nodesToBrowse,
                    out results,
                    out diagnosticInfos);

                ClientBase.ValidateResponse(results, nodesToBrowse);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToBrowse);

                List<NodeId> targetIds = new List<NodeId>();
                ByteStringCollection continuationPoints = new ByteStringCollection();

                for (int ii = 0; ii < nodeIds.Count; ii++)
                {
                    targetIds.Add(null);

                    // check for error.
                    if (StatusCode.IsBad(results[ii].StatusCode))
                    {
                        continue;
                    }

                    // check for continuation point.
                    if (results[ii].ContinuationPoint != null && results[ii].ContinuationPoint.Length > 0)
                    {
                        continuationPoints.Add(results[ii].ContinuationPoint);
                    }

                    // get the node id.
                    if (results[ii].References.Count > 0)
                    {
                        if (NodeId.IsNull(results[ii].References[0].NodeId) || results[ii].References[0].NodeId.IsAbsolute)
                        {
                            continue;
                        }

                        targetIds[ii] = (NodeId)results[ii].References[0].NodeId;
                    }
                }

                // release continuation points.
                if (continuationPoints.Count > 0)
                {
                    session.BrowseNext(
                        null,
                        true,
                        continuationPoints,
                        out results,
                        out diagnosticInfos);

                    ClientBase.ValidateResponse(results, nodesToBrowse);
                    ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToBrowse);
                }

                //return complete list.
                return targetIds;
            }
            catch (Exception exception)
            {
                if (throwOnError)
                {
                    throw new ServiceResultException(exception, StatusCodes.BadUnexpectedError);
                }

                return null;
            }
        }
Example #18
0
        /// <summary>
        /// Verifies the references returned for a node.
        /// </summary>
        private bool VerifyReferences(
            Node node, 
            BrowseDescription description, 
            ReferenceDescriptionCollection references)
        {
            bool success = true;
                 
            for (int ii = 0; ii < references.Count; ii++)
            {
                ReferenceDescription reference = references[ii];

                if (reference == null)
                {
                    Log("Returned null ReferenceDescription when Browsing Node '{0}'. NodeId = {1}", node, node.NodeId);
                    success = false;
                    continue;
                }

                if (!VerifyTargetId(node, description, reference))
                {
                    success = false;
                    continue;
                }

                if (!VerifyReferenceTypeId(node, description, reference))
                {
                    success = false;
                    continue;
                }

                if (!VerifyIsForward(node, description, reference))
                {
                    success = false;
                    continue;
                }
            }

            // read the attributes to verify the reference is correct. 
            try
            {
                if (!VerifyTargetAttributes(node, description, references))
                {
                    return false;
                }
            }
            catch (Exception e)
            {
                Log(e, "Could not verify target attributes when Browsing Node '{0}'. NodeId = {1}", node, node.NodeId);
                return false;
            }
   
            // verify type definitions.
            try
            {
                if (!VerifyTypeDefinitions(node, description, references))
                {
                    return false;
                }
            }
            catch (Exception e)
            {
                Log(e, "Could not verify type definitions when Browsing Node '{0}'. NodeId = {1}", node, node.NodeId);
                return false;
            }
   
            return success;   
        }
Example #19
0
        /// <summary>
        /// Verifies the target.
        /// </summary>
        private bool VerifyTargetId(Node node, BrowseDescription description, ReferenceDescription reference)
        {     
            // check for null.
            if (NodeId.IsNull(reference.NodeId))
            {
                Log("Returned unexpected null NodeId when Browsing Node '{0}'. NodeId = {1}", node, node.NodeId);
                return false;
            }

            // check for local id.
            if (reference.NodeId.ServerIndex == 0)
            {
                if (!String.IsNullOrEmpty(reference.NodeId.NamespaceUri))
                {
                    Log("Returned NamespaceUri for local node when Browsing Node '{0}'. NodeId = {1}, TargetId = {2}", node, node.NodeId, reference.NodeId);
                    return false;
                }
            }
                
            return true;
        }
Example #20
0
        /// <summary>
        /// Creates a browse description for a node class test.
        /// </summary>
        private void AddReferenceTypeTest(
            Node node, 
            NodeId referenceTypeId,
            bool isInverse,
            bool includeSubtypes,
            List<Node> nodes,
            BrowseDescriptionCollection nodesToBrowse, 
            List<ReferenceDescriptionCollection> references,
            bool clearLists)
        {
            if (clearLists)
            {
                nodes.Clear();
                nodesToBrowse.Clear();
                references.Clear();
            }

            nodes.Add(node);

            BrowseDescription nodeToBrowse = new BrowseDescription();

            nodeToBrowse.NodeId = node.NodeId;
            nodeToBrowse.ReferenceTypeId = referenceTypeId;
            nodeToBrowse.IncludeSubtypes = includeSubtypes;
            nodeToBrowse.BrowseDirection = (isInverse)?BrowseDirection.Inverse:BrowseDirection.Forward;
            nodeToBrowse.NodeClassMask = (uint)NodeClass.Unspecified;
            nodeToBrowse.ResultMask = (uint)(BrowseResultMask.DisplayName | BrowseResultMask.NodeClass | BrowseResultMask.ReferenceTypeId | BrowseResultMask.IsForward);

            nodesToBrowse.Add(nodeToBrowse);

            references.Add(new ReferenceDescriptionCollection());
        }
Example #21
0
        /// <summary>
        /// Verifies the results of a browse filter.
        /// </summary>
        private bool VerifyFilterResults(
            Node node, 
            BrowseDescription description,
            ReferenceDescriptionCollection actualList)
        {
            NodeId referenceTypeId = description.ReferenceTypeId; 
            BrowseDirection browseDirection = description.BrowseDirection;
            bool includeSubtypes = description.IncludeSubtypes;
            NodeClass nodeClassMask = (NodeClass)description.NodeClassMask;

            // nothing to verify if no master list.
            ReferenceDescriptionCollection masterList = node.Handle as ReferenceDescriptionCollection;

            if (masterList == null)
            {
                return true;
            }

            // cannot verify filter if filter criteria not returned.
            BrowseResultMask requiredMask = (BrowseResultMask.ReferenceTypeId | BrowseResultMask.IsForward | BrowseResultMask.NodeClass);

            if ((description.ResultMask & (uint)requiredMask) != (uint)requiredMask)
            {
                return true;
            }
            
            bool success = true;

            // look for missing references.
            for (int ii = 0; ii < masterList.Count; ii++)
            {
                ReferenceDescription reference = masterList[ii];
                
                if (nodeClassMask != NodeClass.Unspecified && (reference.NodeClass & nodeClassMask) == 0)
                {
                    continue;
                }

                if ((browseDirection == BrowseDirection.Inverse && reference.IsForward) || (browseDirection == BrowseDirection.Forward && !reference.IsForward))
                {
                    continue;
                }

                if (reference.ReferenceTypeId != referenceTypeId)
                {
                    if (!includeSubtypes)
                    {
                        continue;
                    }

                    if (!Session.TypeTree.IsTypeOf(reference.ReferenceTypeId, referenceTypeId))
                    {
                        continue;
                    }
                }
                
                bool found = false;

                for (int jj = 0; jj < actualList.Count; jj++)
                {
                    if (actualList[jj].NodeId == reference.NodeId && actualList[jj].IsForward == reference.IsForward && actualList[jj].ReferenceTypeId == reference.ReferenceTypeId)
                    {
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    Log(
                        "Did not return expected target when browsing  Node '{0}'. NodeId = {1}, NodeClassMask = {2}, ReferenceFilter = {3}, TargetName = {4}, NodeClass = {5}, ReferenceType = {6}, TargetId = {7}.",
                        node, 
                        node.NodeId,
                        nodeClassMask,
                        Session.TypeTree.FindReferenceTypeName(referenceTypeId),
                        reference.DisplayName,
                        reference.NodeClass,
                        Session.TypeTree.FindReferenceTypeName(reference.ReferenceTypeId),
                        reference.NodeId);

                    success = false;
                }
            }
            
            // look for extra references.
            for (int ii = 0; ii < actualList.Count; ii++)
            {                
                bool found = false;

                for (int jj = 0; jj < masterList.Count; jj++)
                {
                    ReferenceDescription reference = masterList[jj];
                    
                    if (nodeClassMask != NodeClass.Unspecified && (reference.NodeClass & nodeClassMask) == 0)
                    {
                        continue;
                    }

                    if (actualList[ii].NodeId != reference.NodeId || actualList[ii].IsForward != reference.IsForward || actualList[ii].ReferenceTypeId != reference.ReferenceTypeId)
                    {
                        continue;
                    }
                                    
                    if ((browseDirection != BrowseDirection.Inverse && reference.IsForward) || (browseDirection != BrowseDirection.Forward && !reference.IsForward))
                    {
                        if (!includeSubtypes)
                        {
                            if (reference.ReferenceTypeId == referenceTypeId)
                            {
                                found = true;
                                break;
                            }
                        }
                        else
                        {
                            if (Session.TypeTree.IsTypeOf(reference.ReferenceTypeId, referenceTypeId))
                            {
                                found = true;
                                break;
                            }
                        }
                    }

                    Log(
                        "Returned invalid target when browsing Node '{0}'. NodeId = {1}, NodeClassMask = {2}, ReferenceFilter = {3}, TargetName = {4}, NodeClass = {5}, ReferenceType = {6}, TargetId = {7}.",
                        node, 
                        node.NodeId,
                        nodeClassMask,
                        Session.TypeTree.FindReferenceTypeName(referenceTypeId),
                        reference.DisplayName,
                        reference.NodeClass,
                        Session.TypeTree.FindReferenceTypeName(reference.ReferenceTypeId),
                        reference.NodeId);

                    success = false;
                    break;
                }

                if (!found)
                {
                    Log(
                        "Returned unexpected target when browsing Node '{0}'. NodeId = {1}, NodeClassMask = {2}, ReferenceFilter = {3}, TargetName = {4}, NodeClass = {5}, ReferenceType = {6}, TargetId = {7}.",
                        node, 
                        node.NodeId,
                        nodeClassMask,
                        Session.TypeTree.FindReferenceTypeName(referenceTypeId),
                        actualList[ii].DisplayName,
                        actualList[ii].NodeClass,
                        Session.TypeTree.FindReferenceTypeName(actualList[ii].ReferenceTypeId),
                        actualList[ii].NodeId);

                    success = false;
                    continue;
                }
            }

            return success;
        }         
Example #22
0
        /// <summary>
        /// Creates a browse description for a node class test.
        /// </summary>
        private void AddNodeClassTest(
            Node node, 
            NodeClass nodeClassMask,            
            List<Node> nodes,
            BrowseDescriptionCollection nodesToBrowse, 
            List<ReferenceDescriptionCollection> references,
            bool clearLists)
        {
            if (clearLists)
            {
                nodes.Clear();
                nodesToBrowse.Clear();
                references.Clear();
            }

            nodes.Add(node);

            BrowseDescription nodeToBrowse = new BrowseDescription();

            nodeToBrowse.NodeId = node.NodeId;
            nodeToBrowse.ReferenceTypeId = ReferenceTypeIds.References;
            nodeToBrowse.IncludeSubtypes = true;
            nodeToBrowse.BrowseDirection = BrowseDirection.Both;
            nodeToBrowse.NodeClassMask = (uint)nodeClassMask;
            nodeToBrowse.ResultMask = (uint)(BrowseResultMask.DisplayName | BrowseResultMask.NodeClass | BrowseResultMask.ReferenceTypeId | BrowseResultMask.IsForward);

            nodesToBrowse.Add(nodeToBrowse);

            references.Add(new ReferenceDescriptionCollection());
        }
Example #23
0
        /// <summary>
        /// Browses the node and verifies the results.
        /// </summary>
        protected override bool Browse(
            Node node,
            BrowseDescription nodeToBrowse, 
            ReferenceDescriptionCollection references)
        {            
            List<Node> nodes = new List<Node>();
            BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection();
            List<ReferenceDescriptionCollection> referenceLists = new List<ReferenceDescriptionCollection>();
            
            nodes.Add(node);
            nodesToBrowse.Add(nodeToBrowse);
            referenceLists.Add(references);

            return Browse(nodes, nodesToBrowse, referenceLists);
        }
Example #24
0
        /// <summary>
        /// Reads the attribute values in order to compare them to the returned results.
        /// </summary>
        private bool VerifyTypeDefinitions(
            Node node, 
            BrowseDescription description, 
            ReferenceDescriptionCollection references)
        {
            // check if nothing to do.
            if (references.Count == 0)
            {
                return true;
            }

            bool success = true;

            BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection();
            
            for (int ii = 0; ii < references.Count; ii++)
            {
                ReferenceDescription reference = references[ii];

                if ((description.ResultMask & (uint)BrowseResultMask.TypeDefinition) == 0)
                {
                    if (!NodeId.IsNull(reference.TypeDefinition))
                    {
                        success = false;

                        Log(
                            "Unexpected TypeDefinition returned for Node '{0}'. NodeId = {1}, TargetId = {2}, TypeDefinition = {3}",
                            node, 
                            node.NodeId, 
                            reference.NodeId,
                            reference.TypeDefinition);
                    }

                    continue;
                }

                // ignore invalid or external references.
                if (reference == null || reference.NodeId == null || reference.NodeId.IsAbsolute)
                {
                    continue;
                }

                BrowseDescription nodeToBrowse = new BrowseDescription();
                
                nodeToBrowse.NodeId = (NodeId)reference.NodeId;
                nodeToBrowse.BrowseDirection = BrowseDirection.Forward;
                nodeToBrowse.IncludeSubtypes = false;
                nodeToBrowse.NodeClassMask = 0;
                nodeToBrowse.ReferenceTypeId = ReferenceTypeIds.HasTypeDefinition;
                nodeToBrowse.ResultMask = (uint)BrowseResultMask.None;
                nodeToBrowse.Handle = references[ii];
                
                nodesToBrowse.Add(nodeToBrowse);
            }

            // nothing more to do if no type definitions requested.
            if ((description.ResultMask & (uint)BrowseResultMask.TypeDefinition) == 0)
            {
                return success;
            }

            // browse.
            BrowseResultCollection results;
            DiagnosticInfoCollection diagnosticInfos;
            
            RequestHeader requestHeader = new RequestHeader();
            requestHeader.ReturnDiagnostics = 0;

            Session.Browse(
                null,
                m_view,
                0,
                nodesToBrowse,
                out results,
                out diagnosticInfos);
            
            ClientBase.ValidateResponse(results, nodesToBrowse);
            ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToBrowse);
            
            // check diagnostics.
            if (diagnosticInfos != null && diagnosticInfos.Count > 0)
            {
                Log("Returned non-empty DiagnosticInfos array when Browsing TypeDefinition while Browsing Node '{0}'. NodeId = {1}", node, node.NodeId);
                return false;
            }

            bool error = false;

            for (int ii = 0; ii < nodesToBrowse.Count; ii++)
            {
                BrowseResult result = results[ii];
                
                if (StatusCode.IsBad(result.StatusCode))
                {
                    error = true;

                    Log(
                        "Browse TypeDefinition Failed for Node '{0}'. NodeId = {1}, TargetId = {2}, Status = {3}",
                        node, 
                        node.NodeId, 
                        nodesToBrowse[ii].NodeId,
                        results[0].StatusCode);
                    
                    continue;
                }

                ReferenceDescription reference = (ReferenceDescription)nodesToBrowse[ii].Handle;

                if (result.References.Count == 0)
                {
                    if (!NodeId.IsNull(reference.TypeDefinition))
                    {
                        error = true;

                        Log(
                            "Unexpected TypeDefinition returned for Node '{0}'. NodeId = {1}, TargetId = {2}, TypeDefinition = {3}",
                            node, 
                            node.NodeId, 
                            nodesToBrowse[ii].NodeId,
                            reference.TypeDefinition);
                    
                        continue;
                    }
                }
                else
                {
                    if (result.References.Count != 1)
                    {
                        error = true;

                        Log(
                            "Too many TypeDefinitions returned for Node '{0}'. NodeId = {1}, TargetId = {2}, Count = {3}",
                            node, 
                            node.NodeId, 
                            nodesToBrowse[ii].NodeId,
                            result.References.Count);
                    
                        continue;
                    }

                    if (result.References[0].NodeId != reference.TypeDefinition)
                    {
                        error = true;

                        Log(
                            "Incorrect TypeDefinition returned for Node '{0}'. NodeId = {1}, TargetId = {2}, Expected = {3}, Actual = {4}",
                            node, 
                            node.NodeId, 
                            nodesToBrowse[ii].NodeId,
                            result.References[0].NodeId,
                            reference.TypeDefinition);
                    
                        continue;
                    }
                }
            }

            return !error;
        }
Example #25
0
        /// <summary>
        /// Returns the set of references that meet the filter criteria.
        /// </summary>
        private ServiceResult Browse(
            OperationContext  context,
            ViewDescription   view,
            uint              maxReferencesPerNode,
            bool              assignContinuationPoint,
            BrowseDescription nodeToBrowse,
            BrowseResult      result)
        {
            Debug.Assert(context != null);
            Debug.Assert(nodeToBrowse != null);
            Debug.Assert(result != null);

            // find node manager that owns the node.
            INodeManager nodeManager = null; 
               
            object handle = GetManagerHandle(nodeToBrowse.NodeId, out nodeManager);

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

            if (!NodeId.IsNull(nodeToBrowse.ReferenceTypeId) && !m_server.TypeTree.IsKnown(nodeToBrowse.ReferenceTypeId))
            {
                return StatusCodes.BadReferenceTypeIdInvalid;
            }

            if (nodeToBrowse.BrowseDirection < BrowseDirection.Forward || nodeToBrowse.BrowseDirection > BrowseDirection.Both)
            {
                return StatusCodes.BadBrowseDirectionInvalid;
            }
        
            // create a continuation point.
            ContinuationPoint cp = new ContinuationPoint();

            cp.Manager            = nodeManager;
            cp.View               = view;
            cp.NodeToBrowse       = handle;
            cp.MaxResultsToReturn = maxReferencesPerNode;
            cp.BrowseDirection    = nodeToBrowse.BrowseDirection;
            cp.ReferenceTypeId    = nodeToBrowse.ReferenceTypeId;
            cp.IncludeSubtypes    = nodeToBrowse.IncludeSubtypes;
            cp.NodeClassMask      = nodeToBrowse.NodeClassMask;
            cp.ResultMask         = (BrowseResultMask)nodeToBrowse.ResultMask;
            cp.Index              = 0;
            cp.Data               = null;

            // check if reference type left unspecified.
            if (NodeId.IsNull(cp.ReferenceTypeId))
            {
                cp.ReferenceTypeId = ReferenceTypeIds.References;
                cp.IncludeSubtypes = true;
            }

            // loop until browse is complete or max results.
            ReferenceDescriptionCollection references = result.References;
            ServiceResult error = FetchReferences(context, assignContinuationPoint, ref cp, ref references);
            result.References = references;

            // save continuation point.
            if (cp != null)
            {
                result.StatusCode = StatusCodes.Good;
                result.ContinuationPoint = cp.Id.ToByteArray();
            }

            // all is good.
            return error;
        }
Example #26
0
        /// <summary>
        /// 读取一个节点的所有属性
        /// </summary>
        /// <param name="tag">节点值</param>
        /// <returns>所有的数据</returns>
        public DataValue[] ReadNoteDataValueAttributes(string tag)
        {
            NodeId sourceId = new NodeId(tag);
            ReadValueIdCollection nodesToRead = new ReadValueIdCollection();

            // attempt to read all possible attributes.
            // 尝试着去读取所有可能的特性
            for (uint ii = Attributes.NodeId; ii <= Attributes.UserExecutable; ii++)
            {
                ReadValueId nodeToRead = new ReadValueId();
                nodeToRead.NodeId      = sourceId;
                nodeToRead.AttributeId = ii;
                nodesToRead.Add(nodeToRead);
            }

            int startOfProperties = nodesToRead.Count;

            // find all of the pror of the node.
            BrowseDescription nodeToBrowse1 = new BrowseDescription();

            nodeToBrowse1.NodeId          = sourceId;
            nodeToBrowse1.BrowseDirection = BrowseDirection.Forward;
            nodeToBrowse1.ReferenceTypeId = ReferenceTypeIds.HasProperty;
            nodeToBrowse1.IncludeSubtypes = true;
            nodeToBrowse1.NodeClassMask   = 0;
            nodeToBrowse1.ResultMask      = (uint)BrowseResultMask.All;

            BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection();

            nodesToBrowse.Add(nodeToBrowse1);

            // fetch property references from the server.
            ReferenceDescriptionCollection references = FormUtils.Browse(m_session, nodesToBrowse, false);

            if (references == null)
            {
                return(new DataValue[0]);
            }

            for (int ii = 0; ii < references.Count; ii++)
            {
                // ignore external references.
                if (references[ii].NodeId.IsAbsolute)
                {
                    continue;
                }

                ReadValueId nodeToRead = new ReadValueId();
                nodeToRead.NodeId      = (NodeId)references[ii].NodeId;
                nodeToRead.AttributeId = Attributes.Value;
                nodesToRead.Add(nodeToRead);
            }

            // read all values.
            DataValueCollection      results         = null;
            DiagnosticInfoCollection diagnosticInfos = null;

            m_session.Read(
                null,
                0,
                TimestampsToReturn.Neither,
                nodesToRead,
                out results,
                out diagnosticInfos);

            ClientBase.ValidateResponse(results, nodesToRead);
            ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);

            return(results.ToArray());
        }
Example #27
0
        /// <summary>
        /// Browses the address space and returns the references found.
        /// </summary>
        /// <param name="session">The session.</param>
        /// <param name="nodeToBrowse">The NodeId for the starting node.</param>
        /// <param name="throwOnError">if set to <c>true</c> a exception will be thrown on an error.</param>
        /// <returns>
        /// The references found. Null if an error occurred.
        /// </returns>
        public static ReferenceDescriptionCollection Browse(Session session, BrowseDescription nodeToBrowse, bool throwOnError)
        {
            try
            {
                ReferenceDescriptionCollection references = new ReferenceDescriptionCollection();

                // construct browse request.
                BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection();
                nodesToBrowse.Add(nodeToBrowse);

                // start the browse operation.
                BrowseResultCollection results = null;
                DiagnosticInfoCollection diagnosticInfos = null;

                session.Browse(
                    null,
                    null,
                    0,
                    nodesToBrowse,
                    out results,
                    out diagnosticInfos);

                ClientBase.ValidateResponse(results, nodesToBrowse);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToBrowse);

                do
                {
                    // check for error.
                    if (StatusCode.IsBad(results[0].StatusCode))
                    {
                        throw new ServiceResultException(results[0].StatusCode);
                    }

                    // process results.
                    for (int ii = 0; ii < results[0].References.Count; ii++)
                    {
                        references.Add(results[0].References[ii]);
                    }

                    // check if all references have been fetched.
                    if (results[0].References.Count == 0 || results[0].ContinuationPoint == null)
                    {
                        break;
                    }

                    // continue browse operation.
                    ByteStringCollection continuationPoints = new ByteStringCollection();
                    continuationPoints.Add(results[0].ContinuationPoint);

                    session.BrowseNext(
                        null,
                        false,
                        continuationPoints,
                        out results,
                        out diagnosticInfos);

                    ClientBase.ValidateResponse(results, continuationPoints);
                    ClientBase.ValidateDiagnosticInfos(diagnosticInfos, continuationPoints);
                }
                while (true);

                //return complete list.
                return references;
            }
            catch (Exception exception)
            {
                if (throwOnError)
                {
                    throw new ServiceResultException(exception, StatusCodes.BadUnexpectedError);
                }

                return null;
            }
        }
Example #28
0
        /// <summary>
        /// Verifies the isforward flag.
        /// </summary>
        private bool VerifyIsForward(Node node, BrowseDescription description, ReferenceDescription reference)
        {      
            // check if field was not requested.
            if ((description.ResultMask & (uint)BrowseResultMask.IsForward) == 0)
            {
                if (reference.IsForward)
                {
                    Log("Returned unexpected IsForward=True when Browsing Node '{0}'. NodeId = {1}", node, node.NodeId);
                    return false;
                }

                return true;
            }

            if (reference.IsForward)
            {
                if (description.BrowseDirection == BrowseDirection.Inverse)
                {
                    Log("Returned unexpected IsForward=False when Browsing Node '{0}'. NodeId = {1}", node, node.NodeId);
                    return false;
                }
            }
            else
            {
                if (description.BrowseDirection == BrowseDirection.Forward)
                {
                    Log("Returned unexpected IsForward=True when Browsing Node '{0}'. NodeId = {1}", node, node.NodeId);
                    return false;
                }
            }
                
            return true;
        }
Example #29
0
        /// <summary>
        /// Collects instance declarations nodes from with a type.
        /// </summary>
        public static void CollectInstanceDeclarations(
            Session session,
            ComNamespaceMapper mapper,
            NodeId typeId,
            AeEventAttribute parent,
            List<AeEventAttribute> instances,
            IDictionary<string, AeEventAttribute> map)
        {
            // find the children.
            BrowseDescription nodeToBrowse = new BrowseDescription();

            if (parent == null)
            {
                nodeToBrowse.NodeId = typeId;
            }
            else
            {
                nodeToBrowse.NodeId = parent.NodeId;
            }

            nodeToBrowse.BrowseDirection = BrowseDirection.Forward;
            nodeToBrowse.ReferenceTypeId = ReferenceTypeIds.HasChild;
            nodeToBrowse.IncludeSubtypes = true;
            nodeToBrowse.NodeClassMask = (uint)(NodeClass.Object | NodeClass.Variable);
            nodeToBrowse.ResultMask = (uint)BrowseResultMask.All;

            // ignore any browsing errors.
            ReferenceDescriptionCollection references = Browse(session, nodeToBrowse, false);

            if (references == null)
            {
                return;
            }

            // process the children.
            List<NodeId> nodeIds = new List<NodeId>();
            List<AeEventAttribute> children = new List<AeEventAttribute>();

            for (int ii = 0; ii < references.Count; ii++)
            {
                ReferenceDescription reference = references[ii];

                if (reference.NodeId.IsAbsolute)
                {
                    continue;
                }

                // create a new declaration.
                AeEventAttribute child = new AeEventAttribute();

                child.RootTypeId = typeId;
                child.NodeId = (NodeId)reference.NodeId;
                child.BrowseName = reference.BrowseName;
                child.NodeClass = reference.NodeClass;

                if (!LocalizedText.IsNullOrEmpty(reference.DisplayName))
                {
                    child.DisplayName = reference.DisplayName.Text;
                }
                else
                {
                    child.DisplayName = reference.BrowseName.Name;
                }

                if (parent != null)
                {
                    child.BrowsePath = new QualifiedNameCollection(parent.BrowsePath);
                    child.BrowsePathDisplayText = Utils.Format("{0}/{1}", parent.BrowsePathDisplayText, mapper.GetLocalBrowseName(reference.BrowseName));
                    child.DisplayPath = Utils.Format("{0}/{1}", parent.DisplayPath, reference.DisplayName);
                }
                else
                {
                    child.BrowsePath = new QualifiedNameCollection();
                    child.BrowsePathDisplayText = Utils.Format("{0}", reference.BrowseName);
                    child.DisplayPath = Utils.Format("{0}", reference.DisplayName);
                }

                child.BrowsePath.Add(reference.BrowseName);

                // check if reading an overridden declaration.
                AeEventAttribute overriden = null;

                if (map.TryGetValue(child.BrowsePathDisplayText, out overriden))
                {
                    child.OverriddenDeclaration = overriden;
                }

                map[child.BrowsePathDisplayText] = child;

                // add to list.
                children.Add(child);
                nodeIds.Add(child.NodeId);
            }

            // check if nothing more to do.
            if (children.Count == 0)
            {
                return;
            }

            // find the modelling rules.
            List<NodeId> modellingRules = FindTargetOfReference(session, nodeIds, Opc.Ua.ReferenceTypeIds.HasModellingRule, false);

            if (modellingRules != null)
            {
                for (int ii = 0; ii < nodeIds.Count; ii++)
                {
                    children[ii].ModellingRule = modellingRules[ii];

                    // if the modelling rule is null then the instance is not part of the type declaration.
                    if (NodeId.IsNull(modellingRules[ii]))
                    {
                        map.Remove(children[ii].BrowsePathDisplayText);
                    }
                }
            }

            // update the descriptions.
            UpdateInstanceDescriptions(session, children, false);

            // recusively collect instance declarations for the tree below.
            for (int ii = 0; ii < children.Count; ii++)
            {
                if (!NodeId.IsNull(children[ii].ModellingRule))
                {
                    instances.Add(children[ii]);
                    CollectInstanceDeclarations(session, mapper, typeId, children[ii], instances, map);
                }
            }
        }
Example #30
0
        /// <summary>
        /// Browses the children of the node and updates the tree.
        /// </summary>
        private bool BrowseChildren(TreeNode parent)
        {
            ReferenceDescription reference = parent.Tag as ReferenceDescription;

            if (reference == null)
            {
                return false;
            }

            parent.Nodes.Clear();

            if (reference.NodeId.IsAbsolute)
            {
                return false;
            }

            BrowseDescription nodeToBrowse = new BrowseDescription();

            nodeToBrowse.NodeId = (NodeId)reference.NodeId;
            nodeToBrowse.BrowseDirection = m_browseDirection;
            nodeToBrowse.ReferenceTypeId = m_referenceTypeId;
            nodeToBrowse.IncludeSubtypes = true;
            nodeToBrowse.NodeClassMask = 0;
            nodeToBrowse.ResultMask = (uint)(int)BrowseResultMask.All;
            
            BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection();
            nodesToBrowse.Add(nodeToBrowse);

            ViewDescription view = null;

            if (NodeId.IsNull(m_viewId))
            {
                view = new ViewDescription();
                view.ViewId = m_viewId;
                view.Timestamp = DateTime.MinValue;
                view.ViewVersion = 0;
            }
        
            BrowseResultCollection results = null;
            DiagnosticInfoCollection diagnosticInfos = null;

            m_session.Browse(
                null,
                view,
                0,
                nodesToBrowse,
                out results,
                out diagnosticInfos);

            if (results.Count != 1 || StatusCode.IsBad(results[0].StatusCode))
            {
                return false;
            }

            UpdateNode(parent, results[0].References);

            while (results[0].ContinuationPoint != null && results[0].ContinuationPoint.Length > 0)
            {
                ByteStringCollection continuationPoints = new ByteStringCollection();
                continuationPoints.Add(results[0].ContinuationPoint);

                m_session.BrowseNext(
                    null,
                    parent == null,
                    continuationPoints,
                    out results,
                    out diagnosticInfos);

                if (results.Count != 1 || StatusCode.IsBad(results[0].StatusCode))
                {
                    return false;
                }
            
                UpdateNode(parent, results[0].References);
            }

            return true;
        }
Example #31
0
        /// <summary>
        /// Invokes the Browse service.
        /// </summary>
        /// <param name="requestHeader">The request header.</param>
        /// <param name="view">The view to browse.</param>
        /// <param name="nodeToBrowse">The node to browse.</param>
        /// <param name="maxResultsToReturn">The maximum number of returned values.</param>
        /// <param name="browseDirection">The browse direction.</param>
        /// <param name="referenceTypeId">The reference type id.</param>
        /// <param name="includeSubtypes">If set to <c>true</c> the subtypes of the ReferenceType will be included in the browse.</param>
        /// <param name="nodeClassMask">The node class mask.</param>
        /// <param name="continuationPoint">The continuation point.</param>
        /// <param name="references">The list of node references.</param>
        /// <returns></returns>
        public virtual ResponseHeader Browse(
            RequestHeader requestHeader,
            ViewDescription view,
            NodeId nodeToBrowse,
            uint maxResultsToReturn,
            BrowseDirection browseDirection,
            NodeId referenceTypeId,
            bool includeSubtypes,
            uint nodeClassMask,
            out byte[] continuationPoint,
            out ReferenceDescriptionCollection references)
        {
            BrowseDescription description = new BrowseDescription();

            description.NodeId = nodeToBrowse;
            description.BrowseDirection = browseDirection;
            description.ReferenceTypeId = referenceTypeId;
            description.IncludeSubtypes = includeSubtypes;
            description.NodeClassMask = nodeClassMask;
            description.ResultMask = (uint)BrowseResultMask.All;

            BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection();
            nodesToBrowse.Add(description);

            BrowseResultCollection results;
            DiagnosticInfoCollection diagnosticInfos;

            ResponseHeader responseHeader = Browse(
                requestHeader,
                view,
                maxResultsToReturn,
                nodesToBrowse,
                out results,
                out diagnosticInfos);

            ClientBase.ValidateResponse(results, nodesToBrowse);
            ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToBrowse);

            if (StatusCode.IsBad(results[0].StatusCode))
            {
                throw new ServiceResultException(new ServiceResult(results[0].StatusCode, 0, diagnosticInfos, responseHeader.StringTable));
            }

            continuationPoint = results[0].ContinuationPoint;
            references = results[0].References;

            return responseHeader;
        }
Example #32
0
        /// <summary>
        /// Prepares a browse request for the children of a node.
        /// </summary>
        /// <param name="nodeId">The node id.</param>
        /// <param name="nodesToBrowse">The nodes to browse.</param>
        private int PrepareBrowseElementBrowseRequest(
            NodeId nodeId,
            BrowseDescriptionCollection nodesToBrowse)
        {
            int index = nodesToBrowse.Count;

            BrowseDescription nodeToBrowse = new BrowseDescription();

            nodeToBrowse.NodeId = nodeId;
            nodeToBrowse.BrowseDirection = BrowseDirection.Forward;
            nodeToBrowse.ReferenceTypeId = Opc.Ua.ReferenceTypeIds.Organizes;
            nodeToBrowse.IncludeSubtypes = true;
            nodeToBrowse.NodeClassMask = (uint)(NodeClass.Object | NodeClass.Variable);
            nodeToBrowse.ResultMask = (uint)(BrowseResultMask.DisplayName | BrowseResultMask.BrowseName | BrowseResultMask.NodeClass);

            nodesToBrowse.Add(nodeToBrowse);

            nodeToBrowse = new BrowseDescription();

            nodeToBrowse.NodeId = nodeId;
            nodeToBrowse.BrowseDirection = BrowseDirection.Forward;
            nodeToBrowse.ReferenceTypeId = Opc.Ua.ReferenceTypeIds.HasChild;
            nodeToBrowse.IncludeSubtypes = true;
            nodeToBrowse.NodeClassMask = (uint)(NodeClass.Object | NodeClass.Variable);
            nodeToBrowse.ResultMask = (uint)(BrowseResultMask.DisplayName | BrowseResultMask.BrowseName | BrowseResultMask.NodeClass);

            nodesToBrowse.Add(nodeToBrowse);

            return index;
        }
        /// <summary>
        /// Browses the specified node.
        /// </summary>
        public ReferenceDescriptionCollection Browse(NodeId nodeId)
        {
            if (m_session == null)
            {
                throw new ServiceResultException(StatusCodes.BadServerNotConnected, "Cannot browse if not connected to a server.");
            }
            
            try
            {
                m_browseInProgress = true;

                // construct request.
                BrowseDescription nodeToBrowse = new BrowseDescription();

                nodeToBrowse.NodeId = nodeId;
                nodeToBrowse.BrowseDirection = m_browseDirection;
                nodeToBrowse.ReferenceTypeId = m_referenceTypeId;
                nodeToBrowse.IncludeSubtypes = m_includeSubtypes;
                nodeToBrowse.NodeClassMask = m_nodeClassMask;
                nodeToBrowse.ResultMask = m_resultMask;

                BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection();
                nodesToBrowse.Add(nodeToBrowse);

                // make the call to the server.
                BrowseResultCollection results;
                DiagnosticInfoCollection diagnosticInfos;

                ResponseHeader responseHeader = m_session.Browse(
                    null,
                    m_view,
                    m_maxReferencesReturned,
                    nodesToBrowse,
                    out results,
                    out diagnosticInfos);

                // ensure that the server returned valid results.
                Session.ValidateResponse(results, nodesToBrowse);
                Session.ValidateDiagnosticInfos(diagnosticInfos, nodesToBrowse);

                // check if valid.
                if (StatusCode.IsBad(results[0].StatusCode))
                {
                    throw ServiceResultException.Create(results[0].StatusCode, 0, diagnosticInfos, responseHeader.StringTable);
                }

                // fetch initial set of references.
                byte[] continuationPoint = results[0].ContinuationPoint;
                ReferenceDescriptionCollection references = results[0].References;

                // process any continuation point.
                while (continuationPoint != null)
                {
                    ReferenceDescriptionCollection additionalReferences;

                    if (!m_continueUntilDone && m_MoreReferences != null)
                    {
                        BrowserEventArgs args = new BrowserEventArgs(references);
                        m_MoreReferences(this, args);

                        // cancel browser and return the references fetched so far.
                        if (args.Cancel)
                        {
                            BrowseNext(ref continuationPoint, true);
                            return references;
                        }

                        m_continueUntilDone = args.ContinueUntilDone;
                    }
                    
                    additionalReferences = BrowseNext(ref continuationPoint, false);
                    references.AddRange(additionalReferences);
                }

                // return the results.
                return references;
            }
            finally
            {
                m_browseInProgress = false;
            }
        }
Example #34
0
        /// <summary>
        /// Gets the list of references to follow.
        /// </summary>
        private BrowseDescriptionCollection CreateNodesToBrowse()
        {
            BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection();

            if (ReferenceTypeIds != null && ReferenceTypeIds.Length > 0)
            {
                for (int ii = 0; ii < ReferenceTypeIds.Length; ii++)
                {
                    BrowseDescription nodeToBrowse = new BrowseDescription();

                    nodeToBrowse.NodeId = NodeId;
                    nodeToBrowse.BrowseDirection = BrowseDirection;
                    nodeToBrowse.ReferenceTypeId = ReferenceTypeIds[ii];
                    nodeToBrowse.IncludeSubtypes = true;
                    nodeToBrowse.NodeClassMask = 0;
                    nodeToBrowse.ResultMask = (uint)BrowseResultMask.All;

                    nodesToBrowse.Add(nodeToBrowse);
                }
            }
            else
            {
                BrowseDescription nodeToBrowse = new BrowseDescription();

                nodeToBrowse.NodeId = NodeId;
                nodeToBrowse.BrowseDirection = BrowseDirection;
                nodeToBrowse.ReferenceTypeId = Opc.Ua.ReferenceTypeIds.References;
                nodeToBrowse.IncludeSubtypes = true;
                nodeToBrowse.NodeClassMask = 0;
                nodeToBrowse.ResultMask = (uint)BrowseResultMask.All;

                nodesToBrowse.Add(nodeToBrowse);
            }

            return nodesToBrowse;
        }
Example #35
0
        /// <summary>
        /// Browses the node and verifies the results.
        /// </summary>
        private bool Browse(Node node, double start, double range)
        {
            // watch for circular references.
            if (m_availableNodes.ContainsKey(node.NodeId))
            {
                return true;
            }

            // get the master list of references.
            BrowseDescription nodeToBrowse = new BrowseDescription();
            
            nodeToBrowse.NodeId = node.NodeId;
            nodeToBrowse.BrowseDirection = BrowseDirection.Both;
            nodeToBrowse.IncludeSubtypes = true;
            nodeToBrowse.NodeClassMask = 0;
            nodeToBrowse.ReferenceTypeId = ReferenceTypeIds.References;
            nodeToBrowse.ResultMask = (uint)BrowseResultMask.All;
            
            ReferenceDescriptionCollection references = new ReferenceDescriptionCollection();
            
            if (!Browse(node, nodeToBrowse, references))
            {
                return false;
            }

            // save references.
            node.Handle = references;
            
            // add to dictionary.
            m_availableNodes.Add(node.NodeId, node);

            // build list of hierachial targets.
            List<Node> targets = new List<Node>();

            for (int ii = 0; ii < references.Count; ii++)
            {
                ReferenceDescription reference = references[ii];

                if (!reference.IsForward)
                {
                    continue;
                }

                if (!Session.TypeTree.IsTypeOf(reference.ReferenceTypeId, ReferenceTypeIds.HierarchicalReferences))
                {
                    continue;
                }

                Node target = Node.Copy(new Node(reference));
                targets.Add(target);
            }
                        
            // recursively follow sub-tree.
            if (targets.Count > 0)
            {
                double increment = range/targets.Count;
                double position  = start;

                for (int ii = 0; ii < targets.Count; ii++)
                {
                    if (range == MaxProgress)
                    {
                        Log("Browsing children of '{0}'. NodeId = {1}", targets[ii], targets[ii].NodeId);
                    }

                    Browse(targets[ii], position, increment);

                    position += increment;
                    ReportProgress(position);
                }
            }

            return true;
        }
Example #36
0
        /// <summary>
        /// Follows hierarchial references from the current node and updates the tree.
        /// </summary>
        private void Browse(TreeNode parent)
        {
            parent.Nodes.Clear();

            ReferenceDescription start = parent.Tag as ReferenceDescription;

            ListOfBrowseDescription nodesToBrowse = new ListOfBrowseDescription();

            BrowseDescription nodeToBrowse = new BrowseDescription();

            nodeToBrowse.NodeId = new NodeId(start.NodeId);
            nodeToBrowse.BrowseDirection = BrowseDirection.Forward_0;
            nodeToBrowse.ReferenceTypeId = new NodeId(ReferenceTypes.HierarchicalReferences);
            nodeToBrowse.IncludeSubtypes = true;
            nodeToBrowse.ResultMask = (uint)DataTypes.EnumToMask(BrowseResultMask.All_63);
            nodeToBrowse.NodeClassMask = 0;

            nodesToBrowse.Add(nodeToBrowse);

            ListOfBrowseResult results;
            ListOfDiagnosticInfo diagnosticInfos;

            m_client.Browse(
                m_client.CreateRequestHeader(),
                null,
                0,
                nodesToBrowse,
                out results,
                out diagnosticInfos);

            if (results != null && results.Count > 0)
            {
                BrowseResult result = results[0];

                if (result.References != null)
                {
                    foreach (ReferenceDescription reference in result.References)
                    {
                        TreeNode child = new TreeNode(reference.DisplayName.Text);
                        child.Tag = reference;
                        child.Nodes.Add(new TreeNode());
                        parent.Nodes.Add(child);
                    }
                }
            }
        }
Example #37
0
        /// <summary>
        /// 读取一个节点的所有属性
        /// </summary>
        /// <param name="tag">节点信息</param>
        /// <returns>节点的特性值</returns>
        public OpcNodeAttribute[] ReadNoteAttributes(string tag)
        {
            NodeId sourceId = new NodeId(tag);
            ReadValueIdCollection nodesToRead = new ReadValueIdCollection();

            // attempt to read all possible attributes.
            // 尝试着去读取所有可能的特性
            for (uint ii = Attributes.NodeClass; ii <= Attributes.UserExecutable; ii++)
            {
                ReadValueId nodeToRead = new ReadValueId();
                nodeToRead.NodeId      = sourceId;
                nodeToRead.AttributeId = ii;
                nodesToRead.Add(nodeToRead);
            }

            int startOfProperties = nodesToRead.Count;

            // find all of the pror of the node.
            BrowseDescription nodeToBrowse1 = new BrowseDescription();

            nodeToBrowse1.NodeId          = sourceId;
            nodeToBrowse1.BrowseDirection = BrowseDirection.Forward;
            nodeToBrowse1.ReferenceTypeId = ReferenceTypeIds.HasProperty;
            nodeToBrowse1.IncludeSubtypes = true;
            nodeToBrowse1.NodeClassMask   = 0;
            nodeToBrowse1.ResultMask      = (uint)BrowseResultMask.All;

            BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection();

            nodesToBrowse.Add(nodeToBrowse1);

            // fetch property references from the server.
            ReferenceDescriptionCollection references = FormUtils.Browse(m_session, nodesToBrowse, false);

            if (references == null)
            {
                return(new OpcNodeAttribute[0]);
            }

            for (int ii = 0; ii < references.Count; ii++)
            {
                // ignore external references.
                if (references[ii].NodeId.IsAbsolute)
                {
                    continue;
                }

                ReadValueId nodeToRead = new ReadValueId();
                nodeToRead.NodeId      = (NodeId)references[ii].NodeId;
                nodeToRead.AttributeId = Attributes.Value;
                nodesToRead.Add(nodeToRead);
            }

            // read all values.
            DataValueCollection      results         = null;
            DiagnosticInfoCollection diagnosticInfos = null;

            m_session.Read(
                null,
                0,
                TimestampsToReturn.Neither,
                nodesToRead,
                out results,
                out diagnosticInfos);

            ClientBase.ValidateResponse(results, nodesToRead);
            ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);

            // process results.


            List <OpcNodeAttribute> nodeAttribute = new List <OpcNodeAttribute>();

            for (int ii = 0; ii < results.Count; ii++)
            {
                OpcNodeAttribute item = new OpcNodeAttribute();

                // process attribute value.
                if (ii < startOfProperties)
                {
                    // ignore attributes which are invalid for the node.
                    if (results[ii].StatusCode == StatusCodes.BadAttributeIdInvalid)
                    {
                        continue;
                    }

                    // get the name of the attribute.
                    item.Name = Attributes.GetBrowseName(nodesToRead[ii].AttributeId);

                    // display any unexpected error.
                    if (StatusCode.IsBad(results[ii].StatusCode))
                    {
                        item.Type  = Utils.Format("{0}", Attributes.GetDataTypeId(nodesToRead[ii].AttributeId));
                        item.Value = Utils.Format("{0}", results[ii].StatusCode);
                    }

                    // display the value.
                    else
                    {
                        TypeInfo typeInfo = TypeInfo.Construct(results[ii].Value);

                        item.Type = typeInfo.BuiltInType.ToString();

                        if (typeInfo.ValueRank >= ValueRanks.OneOrMoreDimensions)
                        {
                            item.Type += "[]";
                        }

                        item.Value = results[ii].Value;//Utils.Format("{0}", results[ii].Value);
                    }
                }

                // process property value.
                else
                {
                    // ignore properties which are invalid for the node.
                    if (results[ii].StatusCode == StatusCodes.BadNodeIdUnknown)
                    {
                        continue;
                    }

                    // get the name of the property.
                    item.Name = Utils.Format("{0}", references[ii - startOfProperties]);

                    // display any unexpected error.
                    if (StatusCode.IsBad(results[ii].StatusCode))
                    {
                        item.Type  = String.Empty;
                        item.Value = Utils.Format("{0}", results[ii].StatusCode);
                    }

                    // display the value.
                    else
                    {
                        TypeInfo typeInfo = TypeInfo.Construct(results[ii].Value);

                        item.Type = typeInfo.BuiltInType.ToString();

                        if (typeInfo.ValueRank >= ValueRanks.OneOrMoreDimensions)
                        {
                            item.Type += "[]";
                        }

                        item.Value = results[ii].Value; //Utils.Format("{0}", results[ii].Value);
                    }
                }

                nodeAttribute.Add(item);
            }

            return(nodeAttribute.ToArray());
        }
Example #38
-1
        /// <summary>
        /// Reads the attribute values in order to compare them to the returned results.
        /// </summary>
        private bool VerifyTargetAttributes(
            Node node, 
            BrowseDescription description, 
            ReferenceDescriptionCollection references)
        {
            // check if nothing to do.
            if (references.Count == 0)
            {
                return true;
            }
            
            bool error = false;

            // build list of values to read.
            ReadValueIdCollection valuesToRead = new ReadValueIdCollection();

            for (int ii = 0; ii < references.Count; ii++)
            {
                ReferenceDescription reference = references[ii];

                // ignore invalid or external references.
                if (reference == null || reference.NodeId == null || reference.NodeId.IsAbsolute)
                {
                    continue;
                }

                ReadValueId valueToRead = new ReadValueId();

                valueToRead.NodeId = (NodeId)reference.NodeId;
                valueToRead.AttributeId = Attributes.NodeId;
                valueToRead.Handle = reference;

                valuesToRead.Add(valueToRead);
                                
                if ((description.ResultMask & (uint)BrowseResultMask.NodeClass) != 0)
                {
                    valueToRead = new ReadValueId();

                    valueToRead.NodeId = (NodeId)reference.NodeId;
                    valueToRead.AttributeId = Attributes.NodeClass;
                    valueToRead.Handle = reference;

                    valuesToRead.Add(valueToRead);
                }
                else
                {
                    if (reference.NodeClass != 0)
                    {
                        error = true;
                        
                        Log(
                            "Unexpected NodeClass when Browsing Node '{0}'. NodeId = {1}, TargetId = {2}, NodeClass = {3}", 
                            node, 
                            node.NodeId, 
                            reference.NodeId, 
                            reference.NodeClass);

                        continue;
                    }
                }
                                
                if ((description.ResultMask & (uint)BrowseResultMask.BrowseName) != 0)
                {
                    valueToRead = new ReadValueId();

                    valueToRead.NodeId = (NodeId)reference.NodeId;
                    valueToRead.AttributeId = Attributes.BrowseName;
                    valueToRead.Handle = reference;

                    valuesToRead.Add(valueToRead);
                }
                else
                {
                    if (!QualifiedName.IsNull(reference.BrowseName))
                    {
                        error = true;
                        
                        Log(
                            "Unexpected BrowseName when Browsing Node '{0}'. NodeId = {1}, TargetId = {2}, BrowseName = {3}", 
                            node, 
                            node.NodeId, 
                            reference.NodeId, 
                            reference.BrowseName);

                        continue;
                    }
                }
                                
                if ((description.ResultMask & (uint)BrowseResultMask.DisplayName) != 0)
                {
                    valueToRead = new ReadValueId();

                    valueToRead.NodeId = (NodeId)reference.NodeId;
                    valueToRead.AttributeId = Attributes.DisplayName;
                    valueToRead.Handle = reference;

                    valuesToRead.Add(valueToRead);
                }
                else
                {
                    if (!LocalizedText.IsNullOrEmpty(reference.DisplayName))
                    {
                        error = true;
                        
                        Log(
                            "Unexpected DisplayName when Browsing Node '{0}'. NodeId = {1}, TargetId = {2}, DisplayName = {3}", 
                            node, 
                            node.NodeId, 
                            reference.NodeId, 
                            reference.DisplayName);

                        continue;
                    }
                }
            }
            
            // halt if errors occured.
            if (error)
            {
                return false;
            }

            // read values from server.
            DataValueCollection results;
            DiagnosticInfoCollection diagnosticInfos;

            RequestHeader requestHeader = new RequestHeader();
            requestHeader.ReturnDiagnostics = 0;

            Session.Read(
                requestHeader,
                0,
                TimestampsToReturn.Neither,
                valuesToRead,
                out results,
                out diagnosticInfos);
            
            ClientBase.ValidateResponse(results, valuesToRead);
            ClientBase.ValidateDiagnosticInfos(diagnosticInfos, valuesToRead);
            
            // check diagnostics.
            if (diagnosticInfos != null && diagnosticInfos.Count > 0)
            {
                Log("Returned non-empty DiagnosticInfos array when Reading Attributes while Browsing Node '{0}'. NodeId = {1}", node, node.NodeId);
                return false;
            }

            for (int ii = 0; ii < valuesToRead.Count; ii++)
            {
                if (results[ii].StatusCode != StatusCodes.Good)
                {
                    error = true;
                    
                    Log(
                        "Could not read {2} when Browsing Node '{0}'. NodeId = {1}, TargetId = {3}, Status = {4}", 
                        node, 
                        node.NodeId, 
                        Attributes.GetBrowseName(valuesToRead[ii].AttributeId), 
                        valuesToRead[ii].NodeId,
                        results[ii].StatusCode);

                    continue;
                }
                
                ReferenceDescription reference = (ReferenceDescription)valuesToRead[ii].Handle;

                if (valuesToRead[ii].AttributeId == Attributes.NodeId)
                {
                    NodeId expectedId = results[ii].Value as NodeId;

                    if (expectedId != reference.NodeId)
                    {
                        error = true;
                        
                        Log(
                            "Incorrect NodeId Browsing Node '{0}'. NodeId = {1}, TargetId = {2}, Expected = {3}, Actual = {4}", 
                            node, 
                            node.NodeId, 
                            reference.NodeId,
                            expectedId,
                            reference.NodeId);
                    }

                    continue;
                }
                
                if (valuesToRead[ii].AttributeId == Attributes.NodeClass)
                {
                    int? expectedClass = results[ii].Value as int?;

                    if (expectedClass == null || expectedClass.Value != (int)reference.NodeClass)
                    {
                        error = true;
                        
                        Log(
                            "Incorrect NodeClass Browsing Node '{0}'. NodeId = {1}, TargetId = {2}, Expected = {3}, Actual = {4}", 
                            node, 
                            node.NodeId, 
                            reference.NodeId,
                            expectedClass,
                            reference.NodeClass);
                    }

                    continue;
                }

                if (valuesToRead[ii].AttributeId == Attributes.BrowseName)
                {
                    QualifiedName expectedName = results[ii].Value as QualifiedName;

                    if (expectedName != reference.BrowseName)
                    {
                        error = true;
                        
                        Log(
                            "Incorrect BrowseName Browsing Node '{0}'. NodeId = {1}, TargetId = {2}, Expected = {3}, Actual = {4}", 
                            node, 
                            node.NodeId, 
                            reference.NodeId,
                            expectedName,
                            reference.BrowseName);
                    }

                    continue;
                }

                if (valuesToRead[ii].AttributeId == Attributes.DisplayName)
                {
                    LocalizedText expectedName = results[ii].Value as LocalizedText;

                    if (expectedName != reference.DisplayName)
                    {
                        error = true;
                        
                        Log(
                            "Incorrect DisplayName Browsing Node '{0}'. NodeId = {1}, TargetId = {2}, Expected = {3}, Actual = {4}", 
                            node, 
                            node.NodeId, 
                            reference.NodeId,
                            expectedName,
                            reference.DisplayName);
                    }

                    continue;
                }
            }

            return !error;
        }