Ejemplo n.º 1
0
        /// <summary>
        /// Updates the object with the results of a translate browse path request.
        /// </summary>
        public void SetResolvePathResult(
            BrowsePathResult result,
            int index,
            DiagnosticInfoCollection diagnosticInfos,
            ResponseHeader responseHeader)
        {
            ServiceResult error = null;

            if (StatusCode.IsBad(result.StatusCode))
            {
                error = ClientBase.GetResult(result.StatusCode, index, diagnosticInfos, responseHeader);
            }
            else
            {
                ResolvedNodeId = NodeId.Null;

                // update the node id.
                if (result.Targets.Count > 0)
                {
                    ResolvedNodeId = ExpandedNodeId.ToNodeId(result.Targets[0].TargetId,
                                                             m_subscription.Session.NamespaceUris);
                }
            }

            m_status.SetResolvePathResult(result, error);
        }
Ejemplo n.º 2
0
        public BrowsePathResult GetBrowseResultForOneNode(string nodeId)
        {
            var result = new BrowsePathResult {
                StatusCode = StatusCodes.Bad
            };

            try
            {
                SysLog.Debug($"Trying to locate {nodeId}.\n");
                //This call is a synchronous call (Polling). This type of call for some nodes it is too quickly
                var node = this._session?.ReadNode(nodeId);

                var target = new BrowsePathTarget
                {
                    TargetId = node?.NodeId
                };

                result.StatusCode = node?.NodeId is null ? StatusCodes.Bad : StatusCodes.Good;

                result.Targets.Add(target);
            }
            catch (ServiceResultException ex)
            {
                if (StatusCodes.BadNodeIdUnknown == ex.StatusCode || StatusCodes.BadNodeIdInvalid == ex.StatusCode)
                {
                    //We know the nodeId does not exist because the OPC server has reported that
                    if (SysLog.IsDebugEnabled)
                    {
                        SysLog.Error($"Failed to retrieve node id for item {nodeId}. ");
                    }
                    result.StatusCode = ex.StatusCode;
                }
                //We know the Node is not bad because the OPC Server has not report that .
                //We continue searching for the Node.
                SysLog.Debug($"Node {nodeId} was not located in a normal way.\n");
            }
            catch (Exception ex)
            {
                SysLog.Error($"Failed to retrieve node id for item {nodeId}. ", ex);
            }

            return(result);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Returns the target nodes found by following a browse path from a starting node.
        /// </summary>
        public TranslateBrowsePathsToNodeIdsResponseMessage TranslateBrowsePathsToNodeIds(TranslateBrowsePathsToNodeIdsMessage request)
        {
            try
            {
                lock (m_lock)
                {
                    // verify that the session is still valid.
                    VerifySession(request.RequestHeader, false);

                    // process each path being followed.
                    ListOfBrowsePathResult results         = new ListOfBrowsePathResult();
                    ListOfDiagnosticInfo   diagnosticInfos = new ListOfDiagnosticInfo();

                    for (int ii = 0; ii < request.BrowsePaths.Count; ii++)
                    {
                        BrowsePathResult result         = new BrowsePathResult();
                        DiagnosticInfo   diagnosticInfo = new DiagnosticInfo();

                        m_nodeManager.TranslateBrowsePath(
                            request.BrowsePaths[ii],
                            result,
                            diagnosticInfo);

                        results.Add(result);
                        diagnosticInfos.Add(diagnosticInfo);
                    }

                    // return the response.
                    TranslateBrowsePathsToNodeIdsResponseMessage response = new TranslateBrowsePathsToNodeIdsResponseMessage();

                    response.ResponseHeader  = CreateResponseHeader(request.RequestHeader);
                    response.Results         = results;
                    response.DiagnosticInfos = diagnosticInfos;

                    return(response);
                }
            }
            catch (Exception e)
            {
                throw CreateSoapFault(request.RequestHeader, e);
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Returns the target nodes found by following a browse path from a starting node.
        /// </summary>
        public TranslateBrowsePathsToNodeIdsResponseMessage TranslateBrowsePathsToNodeIds(TranslateBrowsePathsToNodeIdsMessage request)
        {
            try
            {
                lock (m_lock)
                {
                    // verify that the session is still valid. 
                    VerifySession(request.RequestHeader, false);

                    // process each path being followed.
                    ListOfBrowsePathResult results = new ListOfBrowsePathResult();
                    ListOfDiagnosticInfo diagnosticInfos = new ListOfDiagnosticInfo();

                    for (int ii = 0; ii < request.BrowsePaths.Count; ii++)
                    {
                        BrowsePathResult result = new BrowsePathResult();
                        DiagnosticInfo diagnosticInfo = new DiagnosticInfo();

                        m_nodeManager.TranslateBrowsePath(
                            request.BrowsePaths[ii],
                            result,
                            diagnosticInfo);

                        results.Add(result);
                        diagnosticInfos.Add(diagnosticInfo);
                    }

                    // return the response.
                    TranslateBrowsePathsToNodeIdsResponseMessage response = new TranslateBrowsePathsToNodeIdsResponseMessage();

                    response.ResponseHeader = CreateResponseHeader(request.RequestHeader);
                    response.Results = results;
                    response.DiagnosticInfos = diagnosticInfos;

                    return response;
                }
            }
            catch (Exception e)
            {
                throw CreateSoapFault(request.RequestHeader, e);
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Updates the EUInfo for the items.
        /// </summary>
        /// <param name="group">The group.</param>
        /// <param name="items">The items. Null entries are ignored.</param>
        public void UpdateItemEuInfo(
            ComDaGroup group,
            IList <ComDaGroupItem> items)
        {
            // get the session to use for the operation.
            Session session = m_session;

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

            // build list of properties that need to be read.
            BrowsePathCollection browsePaths = new BrowsePathCollection();

            for (int ii = 0; ii < items.Count; ii++)
            {
                ComDaGroupItem item = (ComDaGroupItem)items[ii];

                // ignore invalid items or items which have already checked their EU type.
                if (item == null || item.EuType >= 0)
                {
                    continue;
                }

                BrowsePath browsePath = new BrowsePath();
                browsePath.StartingNode = item.NodeId;
                RelativePathElement element = new RelativePathElement();
                element.ReferenceTypeId = ReferenceTypeIds.HasProperty;
                element.IsInverse       = false;
                element.IncludeSubtypes = false;
                element.TargetName      = Opc.Ua.BrowseNames.EURange;
                browsePath.RelativePath.Elements.Add(element);
                browsePath.Handle = item;
                browsePaths.Add(browsePath);

                browsePath = new BrowsePath();
                browsePath.StartingNode = item.NodeId;
                element = new RelativePathElement();
                element.ReferenceTypeId = ReferenceTypeIds.HasProperty;
                element.IsInverse       = false;
                element.IncludeSubtypes = false;
                element.TargetName      = Opc.Ua.BrowseNames.EnumStrings;
                browsePath.RelativePath.Elements.Add(element);
                browsePath.Handle = item;
                browsePaths.Add(browsePath);
            }

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

            // translate browse paths.
            BrowsePathResultCollection results         = null;
            DiagnosticInfoCollection   diagnosticInfos = null;

            try
            {
                session.TranslateBrowsePathsToNodeIds(
                    null,
                    browsePaths,
                    out results,
                    out diagnosticInfos);

                ClientBase.ValidateResponse(results, browsePaths);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, browsePaths);
            }
            catch (Exception)
            {
                for (int ii = 0; ii < browsePaths.Count; ii++)
                {
                    ComDaGroupItem item = (ComDaGroupItem)browsePaths[ii].Handle;
                    item.EuType = 0;
                }

                return;
            }

            // build list of properties that need to be read.
            ReadValueIdCollection propertiesToRead = new ReadValueIdCollection();

            for (int ii = 0; ii < results.Count; ii++)
            {
                ComDaGroupItem   item   = (ComDaGroupItem)browsePaths[ii].Handle;
                BrowsePathResult result = results[ii];

                if (StatusCode.IsBad(result.StatusCode))
                {
                    if (item.EuType < 0 && result.StatusCode == StatusCodes.BadNoMatch)
                    {
                        item.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_NOENUM;
                    }

                    continue;
                }

                if (result.Targets.Count == 0 || result.Targets[0].TargetId.IsAbsolute)
                {
                    if (item.EuType < 0)
                    {
                        item.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_NOENUM;
                    }

                    continue;
                }

                ReadValueId propertyToRead = new ReadValueId();
                propertyToRead.NodeId      = (NodeId)result.Targets[0].TargetId;
                propertyToRead.AttributeId = Attributes.Value;
                propertyToRead.Handle      = item;
                propertiesToRead.Add(propertyToRead);

                if (browsePaths[ii].RelativePath.Elements[0].TargetName.Name == Opc.Ua.BrowseNames.EURange)
                {
                    item.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_ANALOG;
                }
                else
                {
                    item.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_ENUMERATED;
                }
            }

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

            // read attribute values from the server.
            DataValueCollection values = null;

            try
            {
                session.Read(
                    null,
                    0,
                    TimestampsToReturn.Neither,
                    propertiesToRead,
                    out values,
                    out diagnosticInfos);

                ClientBase.ValidateResponse(values, propertiesToRead);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, propertiesToRead);
            }
            catch (Exception)
            {
                for (int ii = 0; ii < propertiesToRead.Count; ii++)
                {
                    ComDaGroupItem item = (ComDaGroupItem)propertiesToRead[ii].Handle;
                    item.EuType = 0;
                }

                return;
            }

            // process results.
            for (int ii = 0; ii < values.Count; ii++)
            {
                ComDaGroupItem item = (ComDaGroupItem)propertiesToRead[ii].Handle;

                if (StatusCode.IsBad(values[ii].StatusCode))
                {
                    item.EuType = 0;
                    continue;
                }

                if (item.EuType == (int)OpcRcw.Da.OPCEUTYPE.OPC_ANALOG)
                {
                    Range range = (Range)values[ii].GetValue <Range>(null);

                    if (range == null)
                    {
                        item.EuType = 0;
                        continue;
                    }

                    item.EuInfo = new double[] { range.Low, range.High };
                    continue;
                }

                if (item.EuType == (int)OpcRcw.Da.OPCEUTYPE.OPC_ENUMERATED)
                {
                    LocalizedText[] texts = (LocalizedText[])values[ii].GetValue <LocalizedText[]>(null);

                    if (texts == null)
                    {
                        item.EuType = 0;
                        continue;
                    }

                    string[] strings = new string[texts.Length];

                    for (int jj = 0; jj < strings.Length; jj++)
                    {
                        if (!LocalizedText.IsNullOrEmpty(texts[jj]))
                        {
                            strings[jj] = texts[jj].Text;
                        }
                    }

                    item.EuInfo = strings;
                    continue;
                }
            }
        }
 /// <summary>
 /// Updates the object with the results of a translate browse paths request.
 /// </summary>
 internal void SetResolvePathResult(
     BrowsePathResult result,
     ServiceResult error)
 {
     m_error = error;
 }
Ejemplo n.º 7
0
        /// <summary>
        /// Verifies that the timestamps match the requested filter.
        /// </summary>
        private bool VerifyPaths(
            Node node,
            BrowsePath request,
            BrowsePathResult result)
        {
            // check empty path.
            if (request.RelativePath.Elements == null || request.RelativePath.Elements.Count == 0)
            {
                if (result.StatusCode != StatusCodes.BadBrowseNameInvalid)
                {
                    Log(
                        "Unexpected error returned during translate for Node '{0}'. NodeId = {1}, Expected = {2}, Actual = {3}",
                        node,
                        node.NodeId,
                        (StatusCode)StatusCodes.BadBrowseNameInvalid,
                        result.StatusCode);

                    return(false);
                }
            }

            BrowsePathResult expectedResult = new BrowsePathResult();

            GetTargets(node, request.RelativePath.Elements, 0, expectedResult);

            if (result.StatusCode == StatusCodes.BadNoMatch)
            {
                if (expectedResult.Targets.Count > 0)
                {
                    Log(
                        "Translate returned BadNoMatch when targets expected '{0}'. NodeId = {1}, Path = {2}, ExpectedCount = {3}",
                        node,
                        node.NodeId,
                        GetRelativePath(request.RelativePath.Elements),
                        expectedResult.Targets.Count);


                    return(false);
                }

                if (result.Targets.Count > 0)
                {
                    Log(
                        "Translate returned targets with a BadNoMatch code '{0}'. NodeId = {1}, Path = {2}, ActualCount = {3}",
                        node,
                        node.NodeId,
                        GetRelativePath(request.RelativePath.Elements),
                        result.Targets.Count);

                    return(false);
                }

                return(true);
            }

            if (expectedResult.Targets.Count == 0)
            {
                Log(
                    "Translate returned invalided error code when no targets exist '{0}'. NodeId = {1}, Path = {2}, StatusCode = {3}",
                    node,
                    node.NodeId,
                    GetRelativePath(request.RelativePath.Elements),
                    (StatusCode)result.StatusCode);

                return(false);
            }

            // check status code.
            if (result.StatusCode != StatusCodes.Good)
            {
                Log(
                    "Translate returned an error for Node '{0}'. NodeId = {1}, Path = {2}, StatusCode = {3}",
                    node,
                    node.NodeId,
                    GetRelativePath(request.RelativePath.Elements),
                    (StatusCode)result.StatusCode);

                return(false);
            }

            // check for expected targets.
            for (int ii = 0; ii < expectedResult.Targets.Count; ii++)
            {
                BrowsePathTarget expectedTarget = expectedResult.Targets[ii];

                bool found = false;

                for (int jj = 0; jj < result.Targets.Count; jj++)
                {
                    BrowsePathTarget actualTarget = result.Targets[jj];

                    if (actualTarget.TargetId != expectedTarget.TargetId)
                    {
                        continue;
                    }

                    found = true;

                    if (actualTarget.RemainingPathIndex != expectedTarget.RemainingPathIndex)
                    {
                        Log(
                            "Translate did not return correct remaining path index for target Node '{0}'. NodeId = {1}, Path = {2}, Expected = {3}, Actual = {4}",
                            node,
                            node.NodeId,
                            GetRelativePath(request.RelativePath.Elements),
                            expectedTarget.RemainingPathIndex,
                            actualTarget.RemainingPathIndex);

                        return(false);
                    }

                    break;
                }

                if (!found)
                {
                    Log(
                        "Translate did not return expected target Node '{0}'. NodeId = {1}, Path = {2}, TargetId = {3}",
                        node,
                        node.NodeId,
                        GetRelativePath(request.RelativePath.Elements),
                        expectedTarget.TargetId);

                    return(false);
                }
            }

            // check for unexpected targets.
            for (int ii = 0; ii < result.Targets.Count; ii++)
            {
                BrowsePathTarget actualTarget = result.Targets[ii];

                bool found = false;

                for (int jj = 0; jj < expectedResult.Targets.Count; jj++)
                {
                    BrowsePathTarget expectedTarget = expectedResult.Targets[jj];

                    if (actualTarget.TargetId == expectedTarget.TargetId)
                    {
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    Log(
                        "Translate returned unexpected target Node '{0}'. NodeId = {1}, Path = {2}, TargetId = {3}",
                        node,
                        node.NodeId,
                        GetRelativePath(request.RelativePath.Elements),
                        actualTarget.TargetId);

                    return(false);
                }
            }

            // all ok.
            return(true);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Recursively finds the targets of the specified path.
        /// </summary>
        private void GetTargets(Node start, IList <RelativePathElement> path, int index, BrowsePathResult result)
        {
            // check for invalid parameters.
            if (index >= path.Count)
            {
                return;
            }

            // look for list of references for node.
            ReferenceDescriptionCollection references = start.Handle as ReferenceDescriptionCollection;

            if (references == null || references.Count == 0)
            {
                return;
            }

            RelativePathElement element = path[index];

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

                // check for a reference match.
                if (element.IsInverse == reference.IsForward)
                {
                    continue;
                }

                if (element.ReferenceTypeId != reference.ReferenceTypeId)
                {
                    if (!element.IncludeSubtypes)
                    {
                        continue;
                    }

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

                // check for a browse name match.
                if (element.TargetName != reference.BrowseName)
                {
                    continue;
                }

                // check for end of list.
                if (index == path.Count - 1)
                {
                    BrowsePathTarget item = new BrowsePathTarget();
                    item.TargetId           = reference.NodeId;
                    item.RemainingPathIndex = UInt32.MaxValue;
                    result.Targets.Add(item);
                    continue;
                }

                // check for external reference.
                if (reference.NodeId.IsAbsolute)
                {
                    BrowsePathTarget item = new BrowsePathTarget();
                    item.TargetId           = reference.NodeId;
                    item.RemainingPathIndex = (uint)index + 1;
                    result.Targets.Add(item);
                    continue;
                }

                // check for targets.
                Node target = null;

                if (!AvailableNodes.TryGetValue((NodeId)reference.NodeId, out target))
                {
                    BrowsePathTarget item = new BrowsePathTarget();
                    item.TargetId           = reference.NodeId;
                    item.RemainingPathIndex = (uint)index + 1;
                    result.Targets.Add(item);
                    continue;
                }

                // recursively follow targets.
                GetTargets(target, path, index + 1, result);
            }
        }
        /// <summary>
        /// Updates the object with the results of a translate browse path request.
        /// </summary>
        public void SetResolvePathResult( 
            BrowsePathResult          result,
            int                       index,
            DiagnosticInfoCollection  diagnosticInfos,         
            ResponseHeader            responseHeader)
        {
            ServiceResult error = null;

            if (StatusCode.IsBad(result.StatusCode))
            {
                error = ClientBase.GetResult(result.StatusCode, index, diagnosticInfos, responseHeader);
            }
            else
            {
                ResolvedNodeId = NodeId.Null;

                // update the node id.
                if (result.Targets.Count > 0)
                {
                    ResolvedNodeId = ExpandedNodeId.ToNodeId(result.Targets[0].TargetId, m_subscription.Session.NamespaceUris);
                }
            }

            m_status.SetResolvePathResult(result, error);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Verifies that the timestamps match the requested filter.
        /// </summary>
        private bool VerifyPaths(
            Node node, 
            BrowsePath request, 
            BrowsePathResult result)
        {
            // check empty path.
            if (request.RelativePath.Elements == null || request.RelativePath.Elements.Count == 0)
            {  
                if (result.StatusCode != StatusCodes.BadBrowseNameInvalid)
                {
                    Log(
                        "Unexpected error returned during translate for Node '{0}'. NodeId = {1}, Expected = {2}, Actual = {3}",
                        node,
                        node.NodeId,
                        (StatusCode)StatusCodes.BadBrowseNameInvalid,
                        result.StatusCode);

                    return false;
                }
            }
                      
            BrowsePathResult expectedResult = new BrowsePathResult();
            GetTargets(node, request.RelativePath.Elements, 0, expectedResult);

            if (result.StatusCode == StatusCodes.BadNoMatch)
            {
                if (expectedResult.Targets.Count > 0)
                {
                    Log(
                        "Translate returned BadNoMatch when targets expected '{0}'. NodeId = {1}, Path = {2}, ExpectedCount = {3}",
                        node,
                        node.NodeId,
                        GetRelativePath(request.RelativePath.Elements),
                        expectedResult.Targets.Count);

                 
                    return false;
                }

                if (result.Targets.Count > 0)
                {
                    Log(
                        "Translate returned targets with a BadNoMatch code '{0}'. NodeId = {1}, Path = {2}, ActualCount = {3}",
                        node,
                        node.NodeId,
                        GetRelativePath(request.RelativePath.Elements),
                        result.Targets.Count);

                    return false;
                }

                return true;
            }

            if (expectedResult.Targets.Count == 0)
            {
                Log(
                    "Translate returned invalided error code when no targets exist '{0}'. NodeId = {1}, Path = {2}, StatusCode = {3}",
                    node,
                    node.NodeId,
                    GetRelativePath(request.RelativePath.Elements),
                    (StatusCode)result.StatusCode);

                return false;
            }

            // check status code.
            if (result.StatusCode != StatusCodes.Good)
            {
                Log(
                    "Translate returned an error for Node '{0}'. NodeId = {1}, Path = {2}, StatusCode = {3}",
                    node,
                    node.NodeId,
                    GetRelativePath(request.RelativePath.Elements),
                    (StatusCode)result.StatusCode);

                return false;
            }

            // check for expected targets.
            for (int ii = 0; ii < expectedResult.Targets.Count; ii++)
            {
                BrowsePathTarget expectedTarget = expectedResult.Targets[ii];

                bool found = false;

                for (int jj = 0; jj < result.Targets.Count; jj++)
                {
                    BrowsePathTarget actualTarget = result.Targets[jj];

                    if (actualTarget.TargetId != expectedTarget.TargetId)
                    {
                        continue;
                    }
                    
                    found = true;

                    if (actualTarget.RemainingPathIndex != expectedTarget.RemainingPathIndex)
                    {
                        Log(
                            "Translate did not return correct remaining path index for target Node '{0}'. NodeId = {1}, Path = {2}, Expected = {3}, Actual = {4}",
                            node,
                            node.NodeId,
                            GetRelativePath(request.RelativePath.Elements),
                            expectedTarget.RemainingPathIndex,
                            actualTarget.RemainingPathIndex);

                        return false;
                    }
                        
                    break;
                }

                if (!found)
                {
                    Log(
                        "Translate did not return expected target Node '{0}'. NodeId = {1}, Path = {2}, TargetId = {3}",
                        node,
                        node.NodeId,
                        GetRelativePath(request.RelativePath.Elements),
                        expectedTarget.TargetId);

                    return false;
                }
            }
            
            // check for unexpected targets.
            for (int ii = 0; ii < result.Targets.Count; ii++)
            {
                BrowsePathTarget actualTarget = result.Targets[ii];

                bool found = false;

                for (int jj = 0; jj < expectedResult.Targets.Count; jj++)
                {
                    BrowsePathTarget expectedTarget = expectedResult.Targets[jj];

                    if (actualTarget.TargetId == expectedTarget.TargetId)
                    {
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    Log(
                        "Translate returned unexpected target Node '{0}'. NodeId = {1}, Path = {2}, TargetId = {3}",
                        node,
                        node.NodeId,
                        GetRelativePath(request.RelativePath.Elements),
                        actualTarget.TargetId);

                    return false;
                }
            }

            // all ok.
            return true;
        }        
Ejemplo n.º 11
0
        /// <summary>
        /// Recursively finds the targets of the specified path.
        /// </summary>
        private void GetTargets(Node start, IList<RelativePathElement> path, int index, BrowsePathResult result)
        {
            // check for invalid parameters.
            if (index >= path.Count)
            {
                return;
            }

            // look for list of references for node.
            ReferenceDescriptionCollection references = start.Handle as ReferenceDescriptionCollection;

            if (references == null || references.Count == 0)
            {
                return;
            }

            RelativePathElement element = path[index];

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

                // check for a reference match.
                if (element.IsInverse == reference.IsForward)
                {
                    continue;
                }

                if (element.ReferenceTypeId != reference.ReferenceTypeId)
                {
                    if (!element.IncludeSubtypes)
                    {
                        continue;
                    }

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

                // check for a browse name match.
                if (element.TargetName != reference.BrowseName)
                {
                    continue;
                }
                
                // check for end of list.
                if (index == path.Count-1)
                {
                    BrowsePathTarget item = new BrowsePathTarget();
                    item.TargetId = reference.NodeId;
                    item.RemainingPathIndex = UInt32.MaxValue;
                    result.Targets.Add(item);
                    continue;
                }

                // check for external reference.
                if (reference.NodeId.IsAbsolute)
                {
                    BrowsePathTarget item = new BrowsePathTarget();
                    item.TargetId = reference.NodeId;
                    item.RemainingPathIndex = (uint)index+1;
                    result.Targets.Add(item);
                    continue;
                }

                // check for targets.
                Node target = null;

                if (!AvailableNodes.TryGetValue((NodeId)reference.NodeId, out target))
                {
                    BrowsePathTarget item = new BrowsePathTarget();
                    item.TargetId = reference.NodeId;
                    item.RemainingPathIndex = (uint)index+1;
                    result.Targets.Add(item);
                    continue;
                }

                // recursively follow targets.
                GetTargets(target, path, index+1, result);
            }
        }
Ejemplo n.º 12
0
        private async Task <bool> TryConnect()
        {
            if (connection != null)
            {
                return(true);
            }

            if (string.IsNullOrEmpty(config.Address))
            {
                return(false);
            }

            try {
                var getEndpointsRequest = new GetEndpointsRequest {
                    EndpointUrl = config.Address,
                    ProfileUris = new[] { TransportProfileUris.UaTcpTransport }
                };

                GetEndpointsResponse endpoints = await UaTcpDiscoveryService.GetEndpointsAsync(getEndpointsRequest);

                EndpointDescription[] noSecurityEndpoints = endpoints.Endpoints.Where(e => e.SecurityPolicyUri == SecurityPolicyUris.None).ToArray();

                var(endpoint, userIdentity) = FirstEndpointWithLogin(noSecurityEndpoints);

                if (endpoint == null || userIdentity == null)
                {
                    throw new Exception("No matching endpoint");
                }

                var channel = new UaTcpSessionChannel(
                    this.appDescription,
                    null,
                    userIdentity,
                    endpoint,
                    loggerFactory);

                await channel.OpenAsync();

                this.connection = channel;

                PrintLine($"Opened session with endpoint '{channel.RemoteEndpoint.EndpointUrl}'.");
                PrintLine($"SecurityPolicy: '{channel.RemoteEndpoint.SecurityPolicyUri}'.");
                PrintLine($"SecurityMode: '{channel.RemoteEndpoint.SecurityMode}'.");
                PrintLine($"UserIdentityToken: '{channel.UserIdentity}'.");

                ItemInfo[] nodesNeedingResolve = mapId2Info.Values.Where(n => n.Node == null).ToArray();
                if (nodesNeedingResolve.Length > 0)
                {
                    PrintLine($"Resolving node ids for {nodesNeedingResolve.Length} items...");

                    TranslateBrowsePathsToNodeIdsRequest req = new TranslateBrowsePathsToNodeIdsRequest()
                    {
                        BrowsePaths = nodesNeedingResolve.Select(n => new BrowsePath()
                        {
                            StartingNode = n.StartingNode,
                            RelativePath = n.RelativePath
                        }).ToArray()
                    };
                    TranslateBrowsePathsToNodeIdsResponse resp = await connection.TranslateBrowsePathsToNodeIdsAsync(req);

                    if (resp.Results.Length != nodesNeedingResolve.Length)
                    {
                        LogWarn("Mismatch", "TranslateBrowsePathsToNodeIds failed");
                    }
                    else
                    {
                        for (int i = 0; i < resp.Results.Length; ++i)
                        {
                            BrowsePathResult x = resp.Results[i];
                            if (StatusCode.IsGood(x.StatusCode) && x.Targets.Length > 0)
                            {
                                NodeId id = x.Targets[0].TargetId.NodeId;
                                nodesNeedingResolve[i].Node = id;
                                PrintLine($"Resolved item '{nodesNeedingResolve[i].Name}' => {id}");
                            }
                            else
                            {
                                PrintLine($"Could not resolve item '{nodesNeedingResolve[i].Name}'!");
                            }
                        }
                    }
                }
                return(true);
            }
            catch (Exception exp) {
                Exception baseExp = exp.GetBaseException() ?? exp;
                LogWarn("OpenChannel", "Open channel error: " + baseExp.Message, dataItem: null, details: baseExp.StackTrace);
                await CloseChannel();

                return(false);
            }
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Translates a browse path.
        /// </summary>
        protected ServiceResult TranslateBrowsePath(
            OperationContext context,
            BrowsePath       browsePath, 
            BrowsePathResult result)
        {
            Debug.Assert(browsePath != null);
            Debug.Assert(result != null);
            
            // check for valid start node.
            INodeManager nodeManager = null;              
  
            object sourceHandle = GetManagerHandle(browsePath.StartingNode, out nodeManager);

            if (sourceHandle == null)
            {
                return StatusCodes.BadNodeIdUnknown;
            }
            
            // check the relative path.
            RelativePath relativePath = browsePath.RelativePath;

            if (relativePath.Elements == null || relativePath.Elements.Count == 0)
            {
                return StatusCodes.BadNothingToDo;
            }

            for (int ii = 0; ii < relativePath.Elements.Count; ii++)
            {
                RelativePathElement element = relativePath.Elements[ii];

                if (element == null || QualifiedName.IsNull(relativePath.Elements[ii].TargetName))
                {
                    return StatusCodes.BadBrowseNameInvalid;
                }

                if (NodeId.IsNull(element.ReferenceTypeId))
                {
                    element.ReferenceTypeId = ReferenceTypeIds.References;
                }
            }

            // translate path.
            TranslateBrowsePath(
                context,
                nodeManager,
                sourceHandle,
                relativePath,
                result.Targets,
                0);

            return ServiceResult.Good;
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Translates a start node id plus a relative paths into a node id.
        /// </summary>
        public virtual void TranslateBrowsePathsToNodeIds(
            OperationContext               context,
            BrowsePathCollection           browsePaths, 
            out BrowsePathResultCollection results, 
            out DiagnosticInfoCollection   diagnosticInfos)
        {
            if (browsePaths == null)throw new ArgumentNullException("browsePaths");
            
            bool diagnosticsExist = false;
            results = new BrowsePathResultCollection(browsePaths.Count);
            diagnosticInfos = new DiagnosticInfoCollection(browsePaths.Count);

            for (int ii = 0; ii < browsePaths.Count; ii++)
            {
                // check if request has timed out or been cancelled.
                if (StatusCode.IsBad(context.OperationStatus))
                {
                    throw new ServiceResultException(context.OperationStatus);
                }

                BrowsePath browsePath = browsePaths[ii];

                BrowsePathResult result = new BrowsePathResult();
                result.StatusCode = StatusCodes.Good;
                results.Add(result);
                
                ServiceResult error = null;
               
                // need to trap unexpected exceptions to handle bugs in the node managers.
                try
                {
                    error = TranslateBrowsePath(context, browsePath, result);
                }
                catch (Exception e)
                {
                    error = ServiceResult.Create(e, StatusCodes.BadUnexpectedError, "Unexpected error translating browse path.");
                }
                
                if (ServiceResult.IsGood(error))
                {                
                    // check for no match.
                    if (result.Targets.Count == 0)
                    {
                        error = StatusCodes.BadNoMatch;
                    }

                    // put a placeholder for diagnostics.
                    else if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
                    {
                        diagnosticInfos.Add(null);
                    }
                }

                // check for error.
                if (error != null && error.Code != StatusCodes.Good)
                {                
                    result.StatusCode = error.StatusCode;
                    
                    if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
                    {
                        DiagnosticInfo diagnosticInfo = ServerUtils.CreateDiagnosticInfo(m_server, context, error);
                        diagnosticInfos.Add(diagnosticInfo);
                        diagnosticsExist = true;
                    }
                }
            }

            // clear the diagnostics array if no diagnostics requested or no errors occurred.
            UpdateDiagnostics(context, diagnosticsExist, ref diagnosticInfos);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Follows the browse path and returns any targets found.
        /// </summary>
        public void TranslateBrowsePath(
            BrowsePath request,
            BrowsePathResult result,
            DiagnosticInfo diagnosticInfo)
        {
            lock (m_lock)
            {
                // find the starting node.
                Node source = m_nodes.Find(request.StartingNode);

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

                // check if there is nothing to do.
                if (request.RelativePath.Elements == null || request.RelativePath.Elements.Count == 0)
                {
                    result.StatusCode = new StatusCode(StatusCodes.BadNothingToDo);
                    return;
                }

                result.Targets = new ListOfBrowsePathTarget();
                
                Node current = source;

                // follow each element in the browse path.
                for (int ii = 0; ii < request.RelativePath.Elements.Count; ii++)
                {
                    RelativePathElement element = request.RelativePath.Elements[ii];

                    bool found = false;

                    // need to find any matching reference.
                    foreach (ReferenceNode reference in current.References)
                    {                        
                        // inverse is a quick check - do that first.
                        if (reference.IsInverse != element.IsInverse)
                        {
                            continue;
                        }

                        // check for reference type matches.
                        if (reference.ReferenceTypeId != element.ReferenceTypeId)
                        {
                            if (!element.IncludeSubtypes)
                            {
                                continue;
                            }

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

                        // The UA type model requires that the browse names of all targets of hierarchial references
                        // be unique within a parent. This means most browse paths will point to no more than one node.
                        // However, instances are allowed to add additional nodes with duplicate browse names. If the server
                        // allows this it must keep track of the child that matches the type model and return it as the
                        // first target. 

                        // need to find the target to check the browse name.
                        Node target = m_nodes.Find(reference.TargetId);

                        if (target != null)
                        {
                            if (element.TargetName == target.BrowseName)
                            {
                                found = true;
                                current = target;
                                break;
                            }
                        }
                    }

                    if (found)
                    {
                        // check if the complete path has been followed.
                        if (ii == request.RelativePath.Elements.Count - 1)
                        {
                            BrowsePathTarget item = new BrowsePathTarget();
                            item.TargetId = new ExpandedNodeId(current.NodeId);
                            item.RemainingPathIndex = UInt32.MaxValue;
                            result.Targets.Add(item);
                        }
                    }
                }
            }
        }
Ejemplo n.º 16
0
 /// <summary>
 /// Updates the object with the results of a translate browse paths request.
 /// </summary>
 internal void SetResolvePathResult(   
     BrowsePathResult result,
     ServiceResult    error)
 {
     m_error = error;
 }
Ejemplo n.º 17
0
        /// <summary>
        /// Follows the browse path and returns any targets found.
        /// </summary>
        public void TranslateBrowsePath(
            BrowsePath request,
            BrowsePathResult result,
            DiagnosticInfo diagnosticInfo)
        {
            lock (m_lock)
            {
                // find the starting node.
                Node source = m_nodes.Find(request.StartingNode);

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

                // check if there is nothing to do.
                if (request.RelativePath.Elements == null || request.RelativePath.Elements.Count == 0)
                {
                    result.StatusCode = new StatusCode(StatusCodes.BadNothingToDo);
                    return;
                }

                result.Targets = new ListOfBrowsePathTarget();

                Node current = source;

                // follow each element in the browse path.
                for (int ii = 0; ii < request.RelativePath.Elements.Count; ii++)
                {
                    RelativePathElement element = request.RelativePath.Elements[ii];

                    bool found = false;

                    // need to find any matching reference.
                    foreach (ReferenceNode reference in current.References)
                    {
                        // inverse is a quick check - do that first.
                        if (reference.IsInverse != element.IsInverse)
                        {
                            continue;
                        }

                        // check for reference type matches.
                        if (reference.ReferenceTypeId != element.ReferenceTypeId)
                        {
                            if (!element.IncludeSubtypes)
                            {
                                continue;
                            }

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

                        // The UA type model requires that the browse names of all targets of hierarchial references
                        // be unique within a parent. This means most browse paths will point to no more than one node.
                        // However, instances are allowed to add additional nodes with duplicate browse names. If the server
                        // allows this it must keep track of the child that matches the type model and return it as the
                        // first target.

                        // need to find the target to check the browse name.
                        Node target = m_nodes.Find(reference.TargetId);

                        if (target != null)
                        {
                            if (element.TargetName == target.BrowseName)
                            {
                                found   = true;
                                current = target;
                                break;
                            }
                        }
                    }

                    if (found)
                    {
                        // check if the complete path has been followed.
                        if (ii == request.RelativePath.Elements.Count - 1)
                        {
                            BrowsePathTarget item = new BrowsePathTarget();
                            item.TargetId           = new ExpandedNodeId(current.NodeId);
                            item.RemainingPathIndex = UInt32.MaxValue;
                            result.Targets.Add(item);
                        }
                    }
                }
            }
        }