Пример #1
0
        /// <summary>
        /// Checks if the item id identified by the is a valid area or source.
        /// </summary>
        public bool IsValidQualifiedName(string itemId, bool isArea)
        {
            Session session = m_server.Session;

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

            lock (m_lock)
            {
                // find the root.
                Stack <string>  names = new Stack <string>();
                AeBrowseElement root  = FindRoot(itemId, names);

                // find the target.
                AeBrowseElement target = Find(session, itemId, root, names, isArea);

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

                return(true);
            }
        }
Пример #2
0
        /// <summary>
        /// Finds the area/source with the specified identifier.
        /// </summary>
        private AeBrowseElement Find(Session session, string itemId, bool isArea)
        {
            // check if it has been cached.
            AeBrowseElement target = null;

            if (m_cache.TryGetValue(itemId, out target))
            {
                if (target.IsArea == isArea)
                {
                    return(target);
                }

                return(null);
            }

            // find the first parent that is already cached.
            Stack <string>  names = new Stack <string>();
            AeBrowseElement root  = FindRoot(itemId, names);

            // browse for the node in the server.
            try
            {
                return(Find(session, itemId, root, names, isArea));
            }
            catch
            {
                return(null);
            }
        }
Пример #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ComHdaBrowser"/> class.
        /// </summary>
        public ComAe2Browser(ComAe2Proxy server, ComAe2ProxyConfiguration configuration, ComAeNamespaceMapper mapper)
        {
            m_server = server;
            m_configuration = configuration;
            m_mapper = mapper;

            m_cache = new Dictionary<string, AeBrowseElement>();

            AeBrowseElement root = new AeBrowseElement();
            root.NodeId = Opc.Ua.ObjectIds.Server;
            root.ItemId = String.Empty;
            root.BrowseText = String.Empty;
            root.IsArea = true;
            root.Duplicated = false;

            m_cache[String.Empty] = root;
            m_position = root;
        }
Пример #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ComHdaBrowser"/> class.
        /// </summary>
        public ComAe2Browser(ComAe2Proxy server, ComAe2ProxyConfiguration configuration, ComAeNamespaceMapper mapper)
        {
            m_server        = server;
            m_configuration = configuration;
            m_mapper        = mapper;

            m_cache = new Dictionary <string, AeBrowseElement>();

            AeBrowseElement root = new AeBrowseElement();

            root.NodeId     = Opc.Ua.ObjectIds.Server;
            root.ItemId     = String.Empty;
            root.BrowseText = String.Empty;
            root.IsArea     = true;
            root.Duplicated = false;

            m_cache[String.Empty] = root;
            m_position            = root;
        }
Пример #5
0
        /// <summary>
        /// Parses the item if looking for a known root element.
        /// </summary>
        private AeBrowseElement FindRoot(string itemId, Stack <string> names)
        {
            // parse the item id looking for a known parent.
            AeBrowseElement root      = null;
            string          currentId = itemId;

            while (!String.IsNullOrEmpty(currentId))
            {
                string parentId = null;
                string itemName = currentId;

                int index = currentId.LastIndexOf('/');

                if (index >= 0)
                {
                    parentId = currentId.Substring(0, index);
                    itemName = currentId.Substring(index + 1);
                }

                // save time by using an intermediate parent if it has already been cached.
                if (!String.IsNullOrEmpty(parentId))
                {
                    if (m_cache.TryGetValue(parentId, out root))
                    {
                        names.Push(itemName);
                        break;
                    }
                }

                currentId = parentId;
                names.Push(itemName);
                root = null;
            }

            if (root == null)
            {
                root = m_cache[String.Empty];
            }

            return(root);
        }
Пример #6
0
        /// <summary>
        /// Finds the children that match the pattern (updates cache if required).
        /// </summary>
        private List <AeBrowseElement> Browse(Session session, AeBrowseElement start, string pattern, bool isArea)
        {
            // check cache.
            List <AeBrowseElement> targets = (isArea)?start.Areas:start.Sources;

            if (targets == null)
            {
                // fetch from server.
                targets = Browse(session, start, isArea);

                // update cache.
                if (isArea)
                {
                    start.Areas = targets;
                }
                else
                {
                    start.Sources = targets;
                }
            }

            // check if all matched.
            if (String.IsNullOrEmpty(pattern) || pattern == "*")
            {
                return(targets);
            }

            // apply filter.
            List <AeBrowseElement> hits = new List <AeBrowseElement>();

            for (int ii = 0; ii < targets.Count; ii++)
            {
                if (ComUtils.Match(targets[ii].BrowseText, pattern, false))
                {
                    hits.Add(targets[ii]);
                }
            }

            return(hits);
        }
Пример #7
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;
        }
Пример #8
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;
        }
Пример #9
0
        /// <summary>
        /// Finds the children that match the pattern (updates cache if required).
        /// </summary>
        private List<AeBrowseElement> Browse(Session session, AeBrowseElement start, string pattern, bool isArea)
        {
            // check cache.
            List<AeBrowseElement> targets = (isArea)?start.Areas:start.Sources;

            if (targets == null)
            {
                // fetch from server.
                targets = Browse(session, start, isArea);

                // update cache.
                if (isArea)
                {
                    start.Areas = targets;
                }
                else
                {
                    start.Sources = targets;
                }
            }

            // check if all matched.
            if (String.IsNullOrEmpty(pattern) || pattern == "*")
            {
                return targets;
            }
     
            // apply filter.
            List<AeBrowseElement> hits = new List<AeBrowseElement>();

            for (int ii = 0; ii < targets.Count; ii++)
            {
                if (ComUtils.Match(targets[ii].BrowseText, pattern, false))
                {
                    hits.Add(targets[ii]);
                }
            }
            
            return hits;
        }
Пример #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);
        }
Пример #11
0
        /// <summary>
        /// Returns the areas or sources that meet search pattern.
        /// </summary>
        public List <NodeId> SearchByQualifiedName(string pattern, bool isArea)
        {
            Session session = m_server.Session;

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

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

            // check if a wildcard has been specified.
            int start = -1;

            for (int ii = 0; ii < pattern.Length; ii++)
            {
                if (IsWildcardChar(pattern[ii]))
                {
                    start = ii;
                    break;
                }
            }

            lock (m_lock)
            {
                // no wildcard found.
                if (start == -1)
                {
                    AeBrowseElement target = Find(session, pattern, isArea);

                    if (target != null)
                    {
                        hits.Add(target.NodeId);
                    }

                    return(hits);
                }

                // find the root where no wildcards exist.
                int end = start;

                for (int ii = start; ii >= 0; ii--)
                {
                    if (pattern[ii] == '/')
                    {
                        end = ii;
                        break;
                    }
                }

                // check if the root exists.
                string          rootId = pattern.Substring(0, end);
                AeBrowseElement root   = Find(session, rootId, true);

                if (root == null)
                {
                    return(hits);
                }

                // update the pattern to look for children of root.
                pattern = pattern.Substring(end + 1);

                // check if the pattern has multiple levels.
                end = pattern.IndexOf('/');

                if (end == -1)
                {
                    List <AeBrowseElement> children = Browse(session, root, pattern, isArea);

                    // remove any duplicates.
                    for (int ii = 0; ii < children.Count; ii++)
                    {
                        hits.Add(children[ii].NodeId);
                    }

                    return(hits);
                }
            }

            return(hits);
        }
Пример #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);
        }
Пример #13
0
        /// <summary>
        /// Moves the current browse position to the specified item.
        /// </summary>
        public void BrowseTo(string itemId)
        {
            Session session = m_server.Session;

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

            lock (m_lock)
            {
                // check if value has been cached.
                if (itemId == null)
                {
                    itemId = String.Empty;
                }

                AeBrowseElement element = null;

                if (m_cache.TryGetValue(itemId, out element))
                {
                    m_position = element;
                    return;
                }

                // parse the item id looking for a known parent.
                Stack <string>  names     = new Stack <string>();
                AeBrowseElement root      = null;
                string          currentId = itemId;

                while (!String.IsNullOrEmpty(currentId))
                {
                    string parentId = null;
                    string itemName = currentId;

                    int index = currentId.LastIndexOf('/');

                    if (index >= 0)
                    {
                        parentId = currentId.Substring(0, index);
                        itemName = currentId.Substring(index + 1);
                    }

                    // save time by using an intermediate parent if it has already been cached.
                    if (!String.IsNullOrEmpty(parentId))
                    {
                        if (m_cache.TryGetValue(parentId, out root))
                        {
                            names.Push(itemName);
                            break;
                        }
                    }

                    currentId = parentId;
                    names.Push(itemName);
                    root = null;
                }

                // use root if no parent found.
                if (root == null)
                {
                    root = m_cache[String.Empty];
                }

                // find the element.
                element = Find(session, itemId, root, names, true);

                if (element == null)
                {
                    throw ComUtils.CreateComException(ResultIds.E_INVALIDBRANCHNAME);
                }

                // update cache and set position.
                m_cache[itemId] = element;
                m_position      = element;
            }
        }