/// <summary> /// Fetches the subtypes for the node. /// </summary> private List<ReferenceDescription> BrowseSubTypes(Opc.Ua.Client.Session client, 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.HasSubtype; nodeToBrowse.IncludeSubtypes = true; nodeToBrowse.BrowseDirection = BrowseDirection.Forward; 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 = client.Browse( null, null, 0, 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 = client.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; }