public static ReferenceDescriptionCollection Browse(Session session, BrowseDescription nodeToBrowse, bool throwOnError) { try { var descriptionCollection = new ReferenceDescriptionCollection(); var nodesToBrowse = new BrowseDescriptionCollection { nodeToBrowse }; BrowseResultCollection results; DiagnosticInfoCollection diagnosticInfos; session.Browse(null, null, 0U, nodesToBrowse, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToBrowse); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToBrowse); while (!StatusCode.IsBad(results[0].StatusCode)) { for (var index = 0; index < results[0].References.Count; ++index) descriptionCollection.Add(results[0].References[index]); if (results[0].References.Count == 0 || results[0].ContinuationPoint == null) return descriptionCollection; var 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); } throw new ServiceResultException(results[0].StatusCode); } catch (Exception ex) { if (throwOnError) throw new ServiceResultException(ex, 2147549184U); return null; } }
/// <summary> /// Fetches the next batch of references. /// </summary> /// <param name="continuationPoint">The continuation point.</param> /// <param name="cancel">if set to <c>true</c> the browse operation is cancelled.</param> /// <returns>The next batch of references</returns> private ReferenceDescriptionCollection BrowseNext(ref byte[] continuationPoint, bool cancel) { ByteStringCollection continuationPoints = new ByteStringCollection(); continuationPoints.Add(continuationPoint); // make the call to the server. BrowseResultCollection results; DiagnosticInfoCollection diagnosticInfos; ResponseHeader responseHeader = m_session.BrowseNext( null, cancel, continuationPoints, out results, out diagnosticInfos); // ensure that the server returned valid results. Session.ValidateResponse(results, continuationPoints); Session.ValidateDiagnosticInfos(diagnosticInfos, continuationPoints); // check if valid. if (StatusCode.IsBad(results[0].StatusCode)) { throw ServiceResultException.Create(results[0].StatusCode, 0, diagnosticInfos, responseHeader.StringTable); } // update continuation point. continuationPoint = results[0].ContinuationPoint; // return references. return(results[0].References); }
private X509Certificate2Collection CreateCertCollection(ByteStringCollection certList) { var result = new X509Certificate2Collection(); foreach (var rawCert in certList) { result.Add(new X509Certificate2(rawCert)); } return(result); }
public TrustListDataType GetTrustLists() { ByteStringCollection trusted = new ByteStringCollection(); ByteStringCollection trustedCrls = new ByteStringCollection(); ByteStringCollection issuers = new ByteStringCollection(); ByteStringCollection issuersCrls = new ByteStringCollection(); foreach (DataGridViewRow row in CertificateListGridView.Rows) { DataRowView source = row.DataBoundItem as DataRowView; Status status = (Status)source.Row[4]; X509Certificate2 certificate = source.Row[7] as X509Certificate2; List <X509CRL> crls = source.Row[9] as List <X509CRL>; if (certificate != null) { if (status == Status.Trusted) { trusted.Add(certificate.RawData); if (crls != null) { foreach (var crl in crls) { trustedCrls.Add(crl.RawData); } } } else if (status == Status.Issuer) { issuers.Add(certificate.RawData); if (crls != null) { foreach (var crl in crls) { issuersCrls.Add(crl.RawData); } } } } } TrustListDataType trustList = new TrustListDataType() { SpecifiedLists = (uint)(TrustListMasks.All), TrustedCertificates = trusted, TrustedCrls = trustedCrls, IssuerCertificates = issuers, IssuerCrls = issuersCrls }; return(trustList); }
public ResponseHeader BrowseNext( RequestHeader requestHeader, bool releaseContinuationPoints, ByteStringCollection continuationPoints, out BrowseResultCollection results, out DiagnosticInfoCollection diagnosticInfos) { return(m_session.BrowseNext(requestHeader, releaseContinuationPoints, continuationPoints, out results, out diagnosticInfos)); }
/// <summary> /// Create the continuation point collection from the browse result /// collection for the BrowseNext service. /// </summary> /// <param name="browseResultCollection">The browse result collection to use.</param> /// <returns>The collection of continuation points for the BrowseNext service.</returns> public static ByteStringCollection PrepareBrowseNext(BrowseResultCollection browseResultCollection) { var continuationPoints = new ByteStringCollection(); foreach (var browseResult in browseResultCollection) { if (browseResult.ContinuationPoint != null) { continuationPoints.Add(browseResult.ContinuationPoint); } } return(continuationPoints); }
private async Task LoadChildren(ReferenceDescriptionViewModel viewModel) { if (_session == null || _session.Disposed) { return; } try { if (!_session.Connected) { await _session.ConnectAsync(); } var browseRequest = new BrowseRequest { NodesToBrowse = { new BrowseDescription { NodeId = ExpandedNodeId.ToNodeId(viewModel.NodeId, _session.NamespaceUris), ReferenceTypeId = ReferenceTypeIds.HierarchicalReferences, ResultMask = (uint)BrowseResultMask.All, NodeClassMask = (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, BrowseDirection = BrowseDirection.Forward } } }; var browseResponse = await _session.BrowseAsync(browseRequest); foreach (var description in browseResponse.Results.SelectMany(result => result.References)) { viewModel.Children.Add(new ReferenceDescriptionViewModel(description, viewModel, LoadChildren)); await Task.Delay(50); } var continuationPoints = new ByteStringCollection(browseResponse.Results.Select(br => br.ContinuationPoint).Where(cp => null != cp)); while (continuationPoints.Count > 0) { var browseNextRequest = new BrowseNextRequest { ContinuationPoints = continuationPoints, ReleaseContinuationPoints = false }; var browseNextResponse = await _session.BrowseNextAsync(browseNextRequest); foreach (var description in browseNextResponse.Results.SelectMany(result => result.References)) { viewModel.Children.Add(new ReferenceDescriptionViewModel(description, viewModel, LoadChildren)); await Task.Delay(50); } continuationPoints = new ByteStringCollection(browseNextResponse.Results.Select(br => br.ContinuationPoint).Where(cp => null != cp)); } } catch (OperationCanceledException) { } }
/// <summary> /// Fetches the next batch of references. /// </summary> private bool BrowseNext() { if (m_continuationPoint != null) { ByteStringCollection continuationPoints = new ByteStringCollection(); continuationPoints.Add(m_continuationPoint); // start the browse operation. BrowseResultCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; ResponseHeader responseHeader = m_client.BrowseNext( null, false, continuationPoints, out results, out diagnosticInfos); // these do sanity checks on the result - make sure response matched the request. ClientBase.ValidateResponse(results, continuationPoints); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, continuationPoints); m_position = 0; m_references = null; m_continuationPoint = null; // check status. if (StatusCode.IsGood(results[0].StatusCode)) { m_references = results[0].References; m_continuationPoint = results[0].ContinuationPoint; } return(m_references != null || m_references.Count > 0); } return(false); }
/// <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> /// Browses the address space and returns the references found. /// </summary> public static ReferenceDescriptionCollection Browse(Session session, ViewDescription view, 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, view, 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 a byte string array from the stream. /// </summary> public ByteStringCollection ReadByteStringArray(string fieldName) { bool isNil = false; ByteStringCollection values = new ByteStringCollection(); if (BeginField(fieldName, true, out isNil)) { PushNamespace(Namespaces.OpcUaXsd); while (MoveToElement("ByteString")) { values.Add(ReadByteString("ByteString")); } // check the length. if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count) { throw new ServiceResultException(StatusCodes.BadEncodingLimitsExceeded); } PopNamespace(); EndField(fieldName); return values; } if (isNil) { return null; } return values; }
/// <summary> /// Browses the node and verifies the results. /// </summary> private bool Browse( List<Node> nodes, BrowseDescriptionCollection nodesToBrowse, List<ReferenceDescriptionCollection> references) { BrowseResultCollection results; DiagnosticInfoCollection diagnosticInfos; RequestHeader requestHeader = new RequestHeader(); requestHeader.ReturnDiagnostics = 0; Session.Browse( requestHeader, m_view, m_maxReferencesPerNode, 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; } List<Node> originalNodes = nodes; BrowseDescriptionCollection originalNodesToBrowse = nodesToBrowse; List<ReferenceDescriptionCollection> originalReferences = references; List<Node> remainingNodes = new List<Node>(); BrowseDescriptionCollection remainingNodesToBrowse = new BrowseDescriptionCollection(); List<ReferenceDescriptionCollection> remainingReferences = new List<ReferenceDescriptionCollection>(); ByteStringCollection continuationPoints = new ByteStringCollection(); // process results. for (int ii = 0; ii < results.Count; ii++) { // check status code. if (StatusCode.IsBad(results[ii].StatusCode)) { Log( "HierarchicalBrowseTest Failed for Node '{0}'. Status = {2}, NodeId = {1}", nodes[ii], nodes[ii].NodeId, results[ii].StatusCode); return false; } // check max references. if (m_maxReferencesPerNode > 0 && m_maxReferencesPerNode < results[ii].References.Count) { Log( "Too many references returned for Node '{0}'. NodeId = {1}, Expected = {2}, Actual = {3}", nodes[ii], nodes[ii].NodeId, m_maxReferencesPerNode, results[ii].References.Count); return false; } // verify references returned. if (!VerifyReferences(nodes[ii], nodesToBrowse[ii], results[ii].References)) { return false; } // save references. references[ii].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}, Expected = {2}", nodes[ii], nodes[ii].NodeId, m_maxReferencesPerNode); return false; } // add to list to rebrowse. remainingNodes.Add(nodes[ii]); remainingNodesToBrowse.Add(nodesToBrowse[ii]); remainingReferences.Add(references[ii]); 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; } nodes = remainingNodes; nodesToBrowse = remainingNodesToBrowse; references = remainingReferences; // process results. remainingNodes = new List<Node>(); remainingNodesToBrowse = new BrowseDescriptionCollection(); remainingReferences = new List<ReferenceDescriptionCollection>(); continuationPoints = new ByteStringCollection(); 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}", nodes[ii], nodes[ii].NodeId, results[ii].StatusCode); return false; } // check max references. if (m_maxReferencesPerNode > 0 && m_maxReferencesPerNode < results[ii].References.Count) { Log( "Too many references returned for Node '{0}'. NodeId = {1}, Expected = {2}, Actual = {3}", nodes[ii], nodes[ii].NodeId, m_maxReferencesPerNode, results[ii].References.Count); return false; } // verify references returned. if (!VerifyReferences(nodes[ii], nodesToBrowse[ii], results[ii].References)) { return false; } // save references. references[ii].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}, Expected = {2}", nodes[ii], nodes[ii].NodeId, m_maxReferencesPerNode); return false; } // add to list to rebrowse. remainingNodes.Add(nodes[ii]); remainingNodesToBrowse.Add(nodesToBrowse[ii]); remainingReferences.Add(references[ii]); continuationPoints.Add(results[ii].ContinuationPoint); } } } // verify filters. for (int ii = 0; ii < originalNodes.Count; ii++) { if (!VerifyFilterResults(originalNodes[ii], originalNodesToBrowse[ii], originalReferences[ii])) { return false; } } return true; }
/// <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> /// Browses the address space and returns the references found. /// </summary> public static ReferenceDescriptionCollection Browse(Session session, ViewDescription view, 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, view, 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> /// Continues a browse operation that was previously halted. /// </summary> public virtual void BrowseNext( OperationContext context, bool releaseContinuationPoints, ByteStringCollection continuationPoints, out BrowseResultCollection results, out DiagnosticInfoCollection diagnosticInfos) { if (context == null) throw new ArgumentNullException("context"); if (continuationPoints == null) throw new ArgumentNullException("continuationPoints"); bool diagnosticsExist = false; results = new BrowseResultCollection(continuationPoints.Count); diagnosticInfos = new DiagnosticInfoCollection(continuationPoints.Count); uint continuationPointsAssigned = 0; for (int ii = 0; ii < continuationPoints.Count; ii++) { ContinuationPoint cp = null; // check if request has timed out or been cancelled. if (StatusCode.IsBad(context.OperationStatus)) { // release all allocated continuation points. foreach (BrowseResult current in results) { if (current != null && current.ContinuationPoint != null && current.ContinuationPoint.Length > 0) { cp = context.Session.RestoreContinuationPoint(current.ContinuationPoint); cp.Dispose(); } } throw new ServiceResultException(context.OperationStatus); } // find the continuation point. cp = context.Session.RestoreContinuationPoint(continuationPoints[ii]); // initialize result. BrowseResult result = new BrowseResult(); result.StatusCode = StatusCodes.Good; results.Add(result); // check if simply releasing the continuation point. if (releaseContinuationPoints) { if (cp != null) { cp.Dispose(); cp = null; } continue; } ServiceResult error = null; // check if continuation point has expired. if (cp == null) { error = StatusCodes.BadContinuationPointInvalid; } if (cp != null) { // need to trap unexpected exceptions to handle bugs in the node managers. try { ReferenceDescriptionCollection references = result.References; error = FetchReferences( context, continuationPointsAssigned < m_maxContinuationPointsPerBrowse, ref cp, ref references); result.References = references; } catch (Exception e) { error = ServiceResult.Create(e, StatusCodes.BadUnexpectedError, "Unexpected error browsing node."); } // check for continuation point. if (result.ContinuationPoint != null && result.ContinuationPoint.Length > 0) { continuationPointsAssigned++; } } // check for error. result.StatusCode = error.StatusCode; if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { DiagnosticInfo diagnosticInfo = null; if (error != null && error.Code != StatusCodes.Good) { diagnosticInfo = ServerUtils.CreateDiagnosticInfo(m_server, context, error); diagnosticsExist = true; } diagnosticInfos.Add(diagnosticInfo); } // check for continuation point. if (cp != null) { result.StatusCode = StatusCodes.Good; result.ContinuationPoint = cp.Id.ToByteArray(); continue; } } // clear the diagnostics array if no diagnostics requested or no errors occurred. UpdateDiagnostics(context, diagnosticsExist, ref diagnosticInfos); }
/// <summary> /// Sends the browse request to the server. /// </summary> /// <param name="session">The session.</param> /// <param name="nodesToBrowse">The nodes to browse.</param> /// <returns></returns> private BrowseResultCollection BrowseBlock(Session session, BrowseDescriptionCollection nodesToBrowse) { try { // Utils.Trace("Browsing {0} Nodes", nodesToBrowse.Count); ViewDescription view = new ViewDescription(); Dictionary<int,BrowseResult> combinedResults = new Dictionary<int, BrowseResult>(); // initialize the table of indexes used to correlate results. BrowseDescriptionCollection browseOperations = nodesToBrowse; List<int> browseIndexes = new List<int>(); for (int ii = 0; ii < nodesToBrowse.Count; ii++) { browseIndexes.Add(ii); } BrowseDescriptionCollection unprocessedOperations = new BrowseDescriptionCollection(); List<int> unprocessedBrowseIndexes = new List<int>(); while (browseOperations.Count > 0) { // start the browse operation. BrowseResultCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; session.Browse( null, view, 0, browseOperations, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, browseOperations); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, browseOperations); unprocessedOperations.Clear(); unprocessedBrowseIndexes.Clear(); ByteStringCollection continuationPoints = new ByteStringCollection(); List<int> continuationPointIndexes = new List<int>(); for (int ii = 0; ii < browseOperations.Count; ii++) { int index = browseIndexes[ii]; // Utils.Trace("{0}/{1}/{2}", browseOperations[ii].NodeId, browseOperations[ii].ReferenceTypeId, results[ii].References.Count); // look up results. BrowseResult combinedResult = null; if (!combinedResults.TryGetValue(index, out combinedResult)) { combinedResults[index] = combinedResult = new BrowseResult(); } // check for error. if (StatusCode.IsBad(results[ii].StatusCode)) { // this error indicates that the server does not have enough simultaneously active // continuation points. This request will need to be resent after the other operations // have been completed and their continuation points released. if (results[ii].StatusCode == StatusCodes.BadNoContinuationPoints) { unprocessedOperations.Add(browseOperations[ii]); unprocessedBrowseIndexes.Add(index); continue; } // save error. if (StatusCode.IsGood(combinedResult.StatusCode)) { combinedResult.StatusCode = results[ii].StatusCode; } continue; } // check if all references have been fetched. if (results[ii].References.Count == 0) { continue; } // save results. combinedResult.References.AddRange(results[ii].References); // check for continuation point. if (results[ii].ContinuationPoint != null && results[ii].ContinuationPoint.Length > 0) { continuationPoints.Add(results[ii].ContinuationPoint); continuationPointIndexes.Add(index); } } // process continuation points. ByteStringCollection revisedContinuationPoints = new ByteStringCollection(); List<int> revisedContinuationPointIndexes = new List<int>(); while (continuationPoints.Count > 0) { bool releaseContinuationPoints = false; // continue browse operation. session.BrowseNext( null, releaseContinuationPoints, continuationPoints, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, continuationPoints); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, continuationPoints); revisedContinuationPoints.Clear(); revisedContinuationPointIndexes.Clear(); for (int ii = 0; ii < continuationPoints.Count; ii++) { int index = continuationPointIndexes[ii]; // look up results. BrowseResult combinedResult = null; if (!combinedResults.TryGetValue(index, out combinedResult)) { combinedResults[index] = new BrowseResult(); } // check for error. if (StatusCode.IsBad(results[ii].StatusCode)) { // save error. if (StatusCode.IsGood(combinedResult.StatusCode)) { combinedResult.StatusCode = results[ii].StatusCode; } continue; } // check if all references have been fetched. if (results[ii].References.Count == 0) { continue; } // save results. combinedResult.References.AddRange(results[ii].References); // check for continuation point. if (results[ii].ContinuationPoint != null && results[ii].ContinuationPoint.Length > 0) { revisedContinuationPoints.Add(results[ii].ContinuationPoint); revisedContinuationPointIndexes.Add(index); } } // check if browsing must continue; continuationPoints = revisedContinuationPoints; continuationPointIndexes = revisedContinuationPointIndexes; } // check if unprocessed results exist. browseOperations = unprocessedOperations; browseIndexes = unprocessedBrowseIndexes; } // reconstruct list of combined results. BrowseResultCollection finalResults = new BrowseResultCollection(); for (int ii = 0; ii < nodesToBrowse.Count; ii++) { BrowseResult combinedResult = null; if (!combinedResults.TryGetValue(ii, out combinedResult)) { combinedResult = new BrowseResult(); } finalResults.Add(combinedResult); } // return complete list. return finalResults; } catch (Exception e) { throw ComUtils.CreateComException(e, ResultIds.E_FAIL); } }
/// <summary> /// Reads a byte string array from the stream. /// </summary> public ByteStringCollection ReadByteStringArray(string fieldName) { int length = ReadArrayLength(); if (length == -1) { return null; } ByteStringCollection values = new ByteStringCollection(length); for (int ii = 0; ii < length; ii++) { values.Add(ReadByteString(null)); } return values; }
/// <summary> /// Fetches the references for the node. /// </summary> private List <ReferenceDescription> Browse(Session session, NodeId nodeId) { List <ReferenceDescription> references = new List <ReferenceDescription>(); // specify the references to follow and the fields to return. BrowseDescription nodeToBrowse = new BrowseDescription(); nodeToBrowse.NodeId = nodeId; nodeToBrowse.ReferenceTypeId = ReferenceTypeIds.References; nodeToBrowse.IncludeSubtypes = true; nodeToBrowse.BrowseDirection = BrowseDirection.Both; nodeToBrowse.NodeClassMask = 0; nodeToBrowse.ResultMask = (uint)BrowseResultMask.All; BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection(); nodesToBrowse.Add(nodeToBrowse); // start the browse operation. BrowseResultCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; ResponseHeader responseHeader = session.Browse( null, null, 2, nodesToBrowse, out results, out diagnosticInfos); // these do sanity checks on the result - make sure response matched the request. ClientBase.ValidateResponse(results, nodesToBrowse); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToBrowse); // check status. if (StatusCode.IsBad(results[0].StatusCode)) { // embed the diagnostic information in a exception. throw ServiceResultException.Create(results[0].StatusCode, 0, diagnosticInfos, responseHeader.StringTable); } // add first batch. references.AddRange(results[0].References); // check if server limited the results. while (results[0].ContinuationPoint != null && results[0].ContinuationPoint.Length > 0) { ByteStringCollection continuationPoints = new ByteStringCollection(); continuationPoints.Add(results[0].ContinuationPoint); // continue browse operation. responseHeader = session.BrowseNext( null, false, continuationPoints, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, continuationPoints); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, continuationPoints); // check status. if (StatusCode.IsBad(results[0].StatusCode)) { // embed the diagnostic information in a exception. throw ServiceResultException.Create(results[0].StatusCode, 0, diagnosticInfos, responseHeader.StringTable); } // add next batch. references.AddRange(results[0].References); } return(references); }
/// <summary> /// Fetches the references for the node. /// </summary> private List<ReferenceDescription> Browse(Session session, NodeId nodeId) { List<ReferenceDescription> references = new List<ReferenceDescription>(); // specify the references to follow and the fields to return. BrowseDescription nodeToBrowse = new BrowseDescription(); nodeToBrowse.NodeId = nodeId; nodeToBrowse.ReferenceTypeId = ReferenceTypeIds.References; nodeToBrowse.IncludeSubtypes = true; nodeToBrowse.BrowseDirection = BrowseDirection.Both; nodeToBrowse.NodeClassMask = 0; nodeToBrowse.ResultMask = (uint)BrowseResultMask.All; BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection(); nodesToBrowse.Add(nodeToBrowse); // start the browse operation. BrowseResultCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; ResponseHeader responseHeader = session.Browse( null, null, 2, nodesToBrowse, out results, out diagnosticInfos); // these do sanity checks on the result - make sure response matched the request. ClientBase.ValidateResponse(results, nodesToBrowse); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToBrowse); // check status. if (StatusCode.IsBad(results[0].StatusCode)) { // embed the diagnostic information in a exception. throw ServiceResultException.Create(results[0].StatusCode, 0, diagnosticInfos, responseHeader.StringTable); } // add first batch. references.AddRange(results[0].References); // check if server limited the results. while (results[0].ContinuationPoint != null && results[0].ContinuationPoint.Length > 0) { ByteStringCollection continuationPoints = new ByteStringCollection(); continuationPoints.Add(results[0].ContinuationPoint); // continue browse operation. responseHeader = session.BrowseNext( null, false, continuationPoints, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, continuationPoints); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, continuationPoints); // check status. if (StatusCode.IsBad(results[0].StatusCode)) { // embed the diagnostic information in a exception. throw ServiceResultException.Create(results[0].StatusCode, 0, diagnosticInfos, responseHeader.StringTable); } // add next batch. references.AddRange(results[0].References); } return references; }
/// <summary> /// Begins an asynchronous invocation of the BrowseNext service. /// </summary> public IAsyncResult BeginBrowseNext( RequestHeader requestHeader, bool releaseContinuationPoints, ByteStringCollection continuationPoints, AsyncCallback callback, object asyncState) { BrowseNextRequest request = new BrowseNextRequest(); request.RequestHeader = requestHeader; request.ReleaseContinuationPoints = releaseContinuationPoints; request.ContinuationPoints = continuationPoints; UpdateRequestHeader(request, requestHeader == null, "BrowseNext"); if (UseTransportChannel) { return TransportChannel.BeginSendRequest(request, callback, asyncState); } return InnerChannel.BeginBrowseNext(new BrowseNextMessage(request), callback, asyncState); }
/// <summary> /// Invokes the BrowseNext service. /// </summary> public virtual ResponseHeader BrowseNext( RequestHeader requestHeader, bool releaseContinuationPoints, ByteStringCollection continuationPoints, out BrowseResultCollection results, out DiagnosticInfoCollection diagnosticInfos) { BrowseNextRequest request = new BrowseNextRequest(); BrowseNextResponse response = null; request.RequestHeader = requestHeader; request.ReleaseContinuationPoints = releaseContinuationPoints; request.ContinuationPoints = continuationPoints; UpdateRequestHeader(request, requestHeader == null, "BrowseNext"); try { if (UseTransportChannel) { IServiceResponse genericResponse = TransportChannel.SendRequest(request); if (genericResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } ValidateResponse(genericResponse.ResponseHeader); response = (BrowseNextResponse)genericResponse; } else { BrowseNextResponseMessage responseMessage = InnerChannel.BrowseNext(new BrowseNextMessage(request)); if (responseMessage == null || responseMessage.BrowseNextResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } response = responseMessage.BrowseNextResponse; ValidateResponse(response.ResponseHeader); } results = response.Results; diagnosticInfos = response.DiagnosticInfos; } finally { RequestCompleted(request, response, "BrowseNext"); } return response.ResponseHeader; }
/// <summary> /// Reads a byte string array from the stream. /// </summary> public ByteStringCollection ReadByteStringArray(string fieldName) { var values = new ByteStringCollection(); List<object> token = null; if (!ReadArrayField(fieldName, out token)) { return values; } for (int ii = 0; ii < token.Count; ii++) { try { m_stack.Push(token[ii]); var element = ReadByteString(null); values.Add(element); } finally { m_stack.Pop(); } } return values; }
/// <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); }
/// <summary> /// Invokes the BrowseNext service. /// </summary> /// <param name="requestHeader">The request header.</param> /// <param name="releaseContinuationPoints">if set to <c>true</c> the continuation points are released.</param> /// <param name="continuationPoints">A list of continuation points returned in a previous Browse or BrewseNext call.</param> /// <param name="results">The list of resulted references for browse.</param> /// <param name="diagnosticInfos">The diagnostic information for the results.</param> /// <returns> /// Returns a <see cref="ResponseHeader"/> object /// </returns> public override ResponseHeader BrowseNext( RequestHeader requestHeader, bool releaseContinuationPoints, ByteStringCollection continuationPoints, out BrowseResultCollection results, out DiagnosticInfoCollection diagnosticInfos) { results = null; diagnosticInfos = null; OperationContext context = ValidateRequest(requestHeader, RequestType.BrowseNext); try { if (continuationPoints == null || continuationPoints.Count == 0) { throw new ServiceResultException(StatusCodes.BadNothingToDo); } m_serverInternal.NodeManager.BrowseNext( context, releaseContinuationPoints, continuationPoints, out results, out diagnosticInfos); return CreateResponse(requestHeader, context.StringTable); } catch (ServiceResultException e) { lock (ServerInternal.DiagnosticsLock) { ServerInternal.ServerDiagnostics.RejectedRequestsCount++; if (IsSecurityError(e.StatusCode)) { ServerInternal.ServerDiagnostics.SecurityRejectedRequestsCount++; } } throw TranslateException(context, e); } finally { OnRequestComplete(context); } }
/// <summary> /// Fetches the next batch of references. /// </summary> private bool BrowseNext() { if (m_continuationPoint != null) { ByteStringCollection continuationPoints = new ByteStringCollection(); continuationPoints.Add(m_continuationPoint); // start the browse operation. BrowseResultCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; ResponseHeader responseHeader = m_client.BrowseNext( null, false, continuationPoints, out results, out diagnosticInfos); // these do sanity checks on the result - make sure response matched the request. ClientBase.ValidateResponse(results, continuationPoints); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, continuationPoints); m_position = 0; m_references = null; m_continuationPoint = null; // check status. if (StatusCode.IsGood(results[0].StatusCode)) { m_references = results[0].References; m_continuationPoint = results[0].ContinuationPoint; } return m_references != null || m_references.Count > 0; } return false; }
/// <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; }
/// <summary> /// Invokes the BrowseNext service. /// </summary> public virtual ResponseHeader BrowseNext( RequestHeader requestHeader, bool releaseContinuationPoint, byte[] continuationPoint, out byte[] revisedContinuationPoint, out ReferenceDescriptionCollection references) { ByteStringCollection continuationPoints = new ByteStringCollection(); continuationPoints.Add(continuationPoint); BrowseResultCollection results; DiagnosticInfoCollection diagnosticInfos; ResponseHeader responseHeader = BrowseNext( requestHeader, releaseContinuationPoint, continuationPoints, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, continuationPoints); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, continuationPoints); if (StatusCode.IsBad(results[0].StatusCode)) { throw new ServiceResultException(new ServiceResult(results[0].StatusCode, 0, diagnosticInfos, responseHeader.StringTable)); } revisedContinuationPoint = results[0].ContinuationPoint; references = results[0].References; return responseHeader; }
/// <summary> /// Browses the address space and returns the references found. /// </summary> public static ReferenceDescriptionCollection Browse(Session session, ViewDescription view, BrowseDescriptionCollection nodesToBrowse, bool throwOnError) { try { ReferenceDescriptionCollection references = new ReferenceDescriptionCollection(); BrowseDescriptionCollection unprocessedOperations = new BrowseDescriptionCollection(); while (nodesToBrowse.Count > 0) { // start the browse operation. BrowseResultCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; session.Browse( null, view, 0, nodesToBrowse, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToBrowse); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToBrowse); ByteStringCollection continuationPoints = new ByteStringCollection(); for (int ii = 0; ii < nodesToBrowse.Count; ii++) { // check for error. if (StatusCode.IsBad(results[ii].StatusCode)) { // this error indicates that the server does not have enough simultaneously active // continuation points. This request will need to be resent after the other operations // have been completed and their continuation points released. if (results[ii].StatusCode == StatusCodes.BadNoContinuationPoints) { unprocessedOperations.Add(nodesToBrowse[ii]); } continue; } // check if all references have been fetched. if (results[ii].References.Count == 0) { continue; } // save results. references.AddRange(results[ii].References); // check for continuation point. if (results[ii].ContinuationPoint != null) { continuationPoints.Add(results[ii].ContinuationPoint); } } // process continuation points. ByteStringCollection revisedContiuationPoints = new ByteStringCollection(); while (continuationPoints.Count > 0) { // continue browse operation. session.BrowseNext( null, false, continuationPoints, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, continuationPoints); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, continuationPoints); for (int ii = 0; ii < continuationPoints.Count; ii++) { // check for error. if (StatusCode.IsBad(results[ii].StatusCode)) { continue; } // check if all references have been fetched. if (results[ii].References.Count == 0) { continue; } // save results. references.AddRange(results[ii].References); // check for continuation point. if (results[ii].ContinuationPoint != null) { revisedContiuationPoints.Add(results[ii].ContinuationPoint); } } // check if browsing must continue; revisedContiuationPoints = continuationPoints; } // check if unprocessed results exist. nodesToBrowse = unprocessedOperations; } // return complete list. return(references); } catch (Exception exception) { if (throwOnError) { throw new ServiceResultException(exception, StatusCodes.BadUnexpectedError); } return(null); } }
/// <summary> /// Begins an asynchronous invocation of the BrowseNext service. /// </summary> public IAsyncResult BeginBrowseNext( RequestHeader requestHeader, bool releaseContinuationPoint, byte[] continuationPoint, AsyncCallback callback, object asyncState) { ByteStringCollection continuationPoints = new ByteStringCollection(); continuationPoints.Add(continuationPoint); return BeginBrowseNext( requestHeader, releaseContinuationPoint, continuationPoints, callback, asyncState); }
/// <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); } }
/// <summary> /// Fetches the next batch of references. /// </summary> /// <param name="continuationPoint">The continuation point.</param> /// <param name="cancel">if set to <c>true</c> the browse operation is cancelled.</param> /// <returns>The next batch of references</returns> private ReferenceDescriptionCollection BrowseNext(ref byte[] continuationPoint, bool cancel) { ByteStringCollection continuationPoints = new ByteStringCollection(); continuationPoints.Add(continuationPoint); // make the call to the server. BrowseResultCollection results; DiagnosticInfoCollection diagnosticInfos; ResponseHeader responseHeader = m_session.BrowseNext( null, cancel, continuationPoints, out results, out diagnosticInfos); // ensure that the server returned valid results. Session.ValidateResponse(results, continuationPoints); Session.ValidateDiagnosticInfos(diagnosticInfos, continuationPoints); // check if valid. if (StatusCode.IsBad(results[0].StatusCode)) { throw ServiceResultException.Create(results[0].StatusCode, 0, diagnosticInfos, responseHeader.StringTable); } // update continuation point. continuationPoint = results[0].ContinuationPoint; // return references. return results[0].References; }
/// <summary> /// Invokes the BrowseNext service. /// </summary> public virtual ResponseHeader BrowseNext( RequestHeader requestHeader, bool releaseContinuationPoints, ByteStringCollection continuationPoints, out BrowseResultCollection results, out DiagnosticInfoCollection diagnosticInfos) { results = null; diagnosticInfos = null; ValidateRequest(requestHeader); // Insert implementation. return CreateResponse(requestHeader, StatusCodes.BadServiceUnsupported); }
/// <summary> /// Browses the address space and returns the references found. /// </summary> public static ReferenceDescriptionCollection Browse(Session session, ViewDescription view, BrowseDescriptionCollection nodesToBrowse, bool throwOnError) { try { ReferenceDescriptionCollection references = new ReferenceDescriptionCollection(); BrowseDescriptionCollection unprocessedOperations = new BrowseDescriptionCollection(); while (nodesToBrowse.Count > 0) { // start the browse operation. BrowseResultCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; session.Browse( null, view, 0, nodesToBrowse, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToBrowse); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToBrowse); ByteStringCollection continuationPoints = new ByteStringCollection(); for (int ii = 0; ii < nodesToBrowse.Count; ii++) { // check for error. if (StatusCode.IsBad(results[ii].StatusCode)) { // this error indicates that the server does not have enough simultaneously active // continuation points. This request will need to be resent after the other operations // have been completed and their continuation points released. if (results[ii].StatusCode == StatusCodes.BadNoContinuationPoints) { unprocessedOperations.Add(nodesToBrowse[ii]); } continue; } // check if all references have been fetched. if (results[ii].References.Count == 0) { continue; } // save results. references.AddRange(results[ii].References); // check for continuation point. if (results[ii].ContinuationPoint != null) { continuationPoints.Add(results[ii].ContinuationPoint); } } // process continuation points. ByteStringCollection revisedContiuationPoints = new ByteStringCollection(); while (continuationPoints.Count > 0) { // continue browse operation. session.BrowseNext( null, false, continuationPoints, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, continuationPoints); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, continuationPoints); for (int ii = 0; ii < continuationPoints.Count; ii++) { // check for error. if (StatusCode.IsBad(results[ii].StatusCode)) { continue; } // check if all references have been fetched. if (results[ii].References.Count == 0) { continue; } // save results. references.AddRange(results[ii].References); // check for continuation point. if (results[ii].ContinuationPoint != null) { revisedContiuationPoints.Add(results[ii].ContinuationPoint); } } // check if browsing must continue; revisedContiuationPoints = continuationPoints; } // check if unprocessed results exist. nodesToBrowse = unprocessedOperations; } // return complete list. return references; } catch (Exception exception) { if (throwOnError) { throw new ServiceResultException(exception, StatusCodes.BadUnexpectedError); } return null; } }
/// <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; } }
/// <summary> /// Removes all expired continuation points. /// </summary> private void CleanupContinuationPoints(object state) { ByteStringCollection continuationPoints = new ByteStringCollection(); lock (m_lock) { LinkedListNode<ContinuationPoint> node = m_continuationPoints.First; while (node != null) { if (DateTime.UtcNow.Ticks - node.Value.Timestamp.Ticks > TimeSpan.TicksPerMinute*10) { if (node.Value.LastCP != null) { continuationPoints.Add(node.Value.LastCP); } LinkedListNode<ContinuationPoint> next = node.Next; m_continuationPoints.Remove(node); node = next; continue; } node = node.Next; } // start a 5 minute timer to check for expired continuation points. if (m_continuationPoints.Count > 0) { if (m_continuationPointTimer != null) { m_continuationPointTimer.Dispose(); } m_continuationPointTimer = new Timer(CleanupContinuationPoints, null, 600000, Timeout.Infinite); } } // release the continuation points on the server. if (continuationPoints.Count > 0) { try { BrowseResultCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; m_session.BrowseNext( null, true, continuationPoints, out results, out diagnosticInfos); } catch (Exception e) { Utils.Trace(e, "Error releasing continuation points."); } } }