public static LogEntry For(BrowseNextRequest request) { LogEntry entry = new LogEntry("BrowseNextRequest"); entry.Add("RequestHeader", For(request.RequestHeader)); entry.Add("ReleaseContinuationPoints", For(request.ReleaseContinuationPoints)); return(entry); }
public async Task BrowseNextAsync() { var response = new BrowseNextResponse(); var request = new BrowseNextRequest(); var channel = new TestRequestChannel(response); var ret = await channel.BrowseNextAsync(request); ret .Should().BeSameAs(response); channel.Request .Should().BeSameAs(request); }
public async Task BrowseObjects() { var channel = new UaTcpSessionChannel( localDescription, certificateStore, new AnonymousIdentity(), EndpointUrl, SecurityPolicyUris.None, loggerFactory: loggerFactory); await channel.OpenAsync(); var rds = new List <ReferenceDescription>(); var browseRequest = new BrowseRequest { NodesToBrowse = new[] { new BrowseDescription { NodeId = ExpandedNodeId.ToNodeId(ExpandedNodeId.Parse(ObjectIds.ObjectsFolder), channel.NamespaceUris), ReferenceTypeId = NodeId.Parse(ReferenceTypeIds.HierarchicalReferences), ResultMask = (uint)BrowseResultMask.TargetInfo, NodeClassMask = (uint)NodeClass.Unspecified, BrowseDirection = BrowseDirection.Forward, IncludeSubtypes = true } }, RequestedMaxReferencesPerNode = 1000 }; var browseResponse = await channel.BrowseAsync(browseRequest).ConfigureAwait(false); rds.AddRange(browseResponse.Results.Where(result => result.References != null).SelectMany(result => result.References)); var continuationPoints = browseResponse.Results.Select(br => br.ContinuationPoint).Where(cp => cp != null).ToArray(); while (continuationPoints.Length > 0) { var browseNextRequest = new BrowseNextRequest { ContinuationPoints = continuationPoints, ReleaseContinuationPoints = false }; var browseNextResponse = await channel.BrowseNextAsync(browseNextRequest); rds.AddRange(browseNextResponse.Results.Where(result => result.References != null).SelectMany(result => result.References)); continuationPoints = browseNextResponse.Results.Select(br => br.ContinuationPoint).Where(cp => cp != null).ToArray(); } rds .Should().NotBeEmpty(); logger.LogInformation("+ Objects, 0:Objects, Object"); foreach (var rd in rds) { logger.LogInformation(" + {0}, {1}, {2}", rd.DisplayName, rd.BrowseName, rd.NodeClass); } logger.LogInformation($"Closing session '{channel.SessionId}'."); await channel.CloseAsync(); }
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) { } }
private async Task <IList <ReferenceDescription> > BrowseTree(NodeId tree) { if (connection == null) { return(new ReferenceDescription[0]); } var browseRequest = new BrowseRequest { NodesToBrowse = new[] { new BrowseDescription { NodeId = tree, ReferenceTypeId = NodeId.Parse(ReferenceTypeIds.HierarchicalReferences), ResultMask = (uint)BrowseResultMask.TargetInfo, NodeClassMask = (uint)NodeClass.Object | (int)NodeClass.Variable, BrowseDirection = BrowseDirection.Forward, IncludeSubtypes = true } }, RequestedMaxReferencesPerNode = 1000 }; var rds = new List <ReferenceDescription>(); BrowseResponse browseResponse = await connection.BrowseAsync(browseRequest); Workstation.ServiceModel.Ua.BrowseResult[] results = CleanNulls(browseResponse.Results).ToArray(); rds.AddRange(results.SelectMany(result => CleanNulls(result.References))); var continuationPoints = results.Select(br => br.ContinuationPoint).Where(cp => cp != null).ToArray(); while (continuationPoints.Length > 0 && connection != null) { var browseNextRequest = new BrowseNextRequest { ContinuationPoints = continuationPoints, ReleaseContinuationPoints = false }; var browseNextResponse = await connection.BrowseNextAsync(browseNextRequest); Workstation.ServiceModel.Ua.BrowseResult[] nextResults = CleanNulls(browseNextResponse.Results).ToArray(); rds.AddRange(nextResults.SelectMany(result => CleanNulls(result.References))); continuationPoints = nextResults.Select(br => br.ContinuationPoint).Where(cp => cp != null).ToArray(); } return(rds); }
public async Task BrowseRoot() { var channel = new UaTcpSessionChannel( this.localDescription, this.certificateStore, new AnonymousIdentity(), EndpointUrl, SecurityPolicyUris.None, loggerFactory: this.loggerFactory); await channel.OpenAsync(); var rds = new List <ReferenceDescription>(); var browseRequest = new BrowseRequest { NodesToBrowse = new[] { new BrowseDescription { NodeId = ExpandedNodeId.ToNodeId(ExpandedNodeId.Parse(ObjectIds.RootFolder), channel.NamespaceUris), ReferenceTypeId = NodeId.Parse(ReferenceTypeIds.HierarchicalReferences), ResultMask = (uint)BrowseResultMask.TargetInfo, NodeClassMask = (uint)NodeClass.Unspecified, BrowseDirection = BrowseDirection.Forward, IncludeSubtypes = true } }, RequestedMaxReferencesPerNode = 1000 }; var browseResponse = await channel.BrowseAsync(browseRequest).ConfigureAwait(false); rds.AddRange(browseResponse.Results.Where(result => result.References != null).SelectMany(result => result.References)); var continuationPoints = browseResponse.Results.Select(br => br.ContinuationPoint).Where(cp => cp != null).ToArray(); while (continuationPoints.Length > 0) { var browseNextRequest = new BrowseNextRequest { ContinuationPoints = continuationPoints, ReleaseContinuationPoints = false }; var browseNextResponse = await channel.BrowseNextAsync(browseNextRequest); rds.AddRange(browseNextResponse.Results.Where(result => result.References != null).SelectMany(result => result.References)); continuationPoints = browseNextResponse.Results.Select(br => br.ContinuationPoint).Where(cp => cp != null).ToArray(); } Assert.IsTrue(rds.Count == 3); Console.WriteLine($"Closing session '{channel.SessionId}'."); await channel.CloseAsync(); }
public async Task <BrowseNextResponse> BrowseNextAsync(BrowseNextRequest browseNextRequest) { UpdateRequestHeader(browseNextRequest, true, "BrowseNext"); BrowseNextResponse browseNextResponse = null; try { if (UseTransportChannel) { var serviceResponse = await Task <IServiceResponse> .Factory.FromAsync(TransportChannel.BeginSendRequest, TransportChannel.EndSendRequest, browseNextRequest, null).ConfigureAwait(false); if (serviceResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } ValidateResponse(serviceResponse.ResponseHeader); browseNextResponse = (BrowseNextResponse)serviceResponse; } else { var browseNextResponseMessage = await Task <BrowseNextResponseMessage> .Factory.FromAsync(InnerChannel.BeginBrowseNext, InnerChannel.EndBrowseNext, new BrowseNextMessage(browseNextRequest), null).ConfigureAwait(false); if (browseNextResponseMessage == null || browseNextResponseMessage.BrowseNextResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } browseNextResponse = browseNextResponseMessage.BrowseNextResponse; ValidateResponse(browseNextResponse.ResponseHeader); } } finally { RequestCompleted(browseNextRequest, browseNextResponse, "BrowseNext"); } return(browseNextResponse); }
/// <summary> /// Requests the next set of Browse responses, when the information is too large to be sent in a single response. /// </summary> /// <param name="channel">A instance of <see cref="IRequestChannel"/>.</param> /// <param name="request">A <see cref="BrowseNextRequest"/>.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation that returns a <see cref="BrowseNextResponse"/>.</returns> public static async Task <BrowseNextResponse> BrowseNextAsync(this IRequestChannel channel, BrowseNextRequest request) { if (request == null) { throw new ArgumentNullException(nameof(request)); } return((BrowseNextResponse)await channel.RequestAsync(request).ConfigureAwait(false)); }
/// <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; }
private async Task LoadChildrenAsync(ReferenceDescriptionViewModel parent) { try { var token = this.cts.Token; await [email protected](token); this.NotifyPropertyChanged("IsLoading"); try { parent.Children.Clear(); do { try { if (this.channel == null || this.channel.State != CommunicationState.Opened) { var getEndpointsRequest = new GetEndpointsRequest { EndpointUrl = this.endpointUrl, ProfileUris = new[] { TransportProfileUris.UaTcpTransport } }; var getEndpointsResponse = await UaTcpDiscoveryClient.GetEndpointsAsync(getEndpointsRequest); token.ThrowIfCancellationRequested(); var selectedEndpoint = getEndpointsResponse.Endpoints.OrderBy(e => e.SecurityLevel).First(); if (selectedEndpoint.UserIdentityTokens.Any(p => p.TokenType == UserTokenType.Anonymous)) { this.HideLoginPanel(); this.userIdentity = new AnonymousIdentity(); } else if (selectedEndpoint.UserIdentityTokens.Any(p => p.TokenType == UserTokenType.UserName)) { if (!this.showingLoginPanel) { this.ShowLoginPanel(); return; } else if (!this.ValidateLoginCredentials()) { return; } else { this.userIdentity = new UserNameIdentity(this.userName, this.password); } } else { throw new NotImplementedException("Browser supports only UserName and Anonymous identity, for now."); } dataTypeCache = new Dictionary <ExpandedNodeId, Type>(); this.channel = new UaTcpSessionChannel( this.localDescription, this.CertificateStore, this.userIdentity, selectedEndpoint); await this.channel.OpenAsync(); } token.ThrowIfCancellationRequested(); var rds = new List <ReferenceDescription>(); var browseRequest = new BrowseRequest { NodesToBrowse = new[] { new BrowseDescription { NodeId = ExpandedNodeId.ToNodeId(parent.NodeId, this.channel.NamespaceUris), ReferenceTypeId = NodeId.Parse(ReferenceTypeIds.HierarchicalReferences), ResultMask = (uint)BrowseResultMask.TargetInfo, NodeClassMask = (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, BrowseDirection = BrowseDirection.Forward, IncludeSubtypes = true } } }; var browseResponse = await this.channel.BrowseAsync(browseRequest); rds.AddRange(browseResponse.Results.Where(result => result.References != null).SelectMany(result => result.References)); var continuationPoints = browseResponse.Results.Select(br => br.ContinuationPoint).Where(cp => cp != null).ToArray(); while (continuationPoints.Length > 0) { token.ThrowIfCancellationRequested(); var browseNextRequest = new BrowseNextRequest { ContinuationPoints = continuationPoints, ReleaseContinuationPoints = false }; var browseNextResponse = await this.channel.BrowseNextAsync(browseNextRequest); rds.AddRange(browseResponse.Results.Where(result => result.References != null).SelectMany(result => result.References)); } if (rds.Count == 0) { return; } foreach (var rd in rds) { token.ThrowIfCancellationRequested(); var n = ExpandedNodeId.ToNodeId(rd.NodeId, this.channel.NamespaceUris); Type dataType = null; EventNotifierFlags notifier = EventNotifierFlags.None; AccessLevelFlags accessLevel = AccessLevelFlags.None; if (rd.NodeClass == NodeClass.Variable) { var readRequest = new ReadRequest { NodesToRead = new ReadValueId[] { new ReadValueId { NodeId = n, AttributeId = AttributeIds.DataType }, new ReadValueId { NodeId = n, AttributeId = AttributeIds.ValueRank }, new ReadValueId { NodeId = n, AttributeId = AttributeIds.UserAccessLevel } } }; var readResponse = await this.channel.ReadAsync(readRequest); ExpandedNodeId dataTypeId, origDataTypeId; ReferenceDescription dataTypeRef; var dataTypeNode = readResponse.Results[0].GetValueOrDefault(NodeId.Null); if (dataTypeNode != NodeId.Null) { dataTypeId = origDataTypeId = NodeId.ToExpandedNodeId(dataTypeNode, this.channel.NamespaceUris); if (!this.dataTypeCache.TryGetValue(dataTypeId, out dataType)) { if (!UaTcpSecureChannel.DataTypeIdToTypeDictionary.TryGetValue(dataTypeId, out dataType)) { do { dataTypeNode = ExpandedNodeId.ToNodeId(dataTypeId, this.channel.NamespaceUris); var browseRequest2 = new BrowseRequest { NodesToBrowse = new[] { new BrowseDescription { NodeId = dataTypeNode, ReferenceTypeId = NodeId.Parse(ReferenceTypeIds.HasSubtype), ResultMask = (uint)BrowseResultMask.None, NodeClassMask = (uint)NodeClass.DataType, BrowseDirection = BrowseDirection.Inverse, IncludeSubtypes = false } } }; var browseResponse2 = await this.channel.BrowseAsync(browseRequest2); dataTypeRef = browseResponse2.Results[0].References?.FirstOrDefault(); dataTypeId = dataTypeRef?.NodeId; }while (dataTypeId != null && !UaTcpSecureChannel.DataTypeIdToTypeDictionary.TryGetValue(dataTypeId, out dataType)); if (dataTypeId == null) { dataType = typeof(object); } } this.dataTypeCache.Add(origDataTypeId, dataType); } var valueRank = readResponse.Results[1].GetValueOrDefault(-1); if (valueRank == 1) { dataType = dataType.MakeArrayType(); } if (valueRank > 1) { dataType = dataType.MakeArrayType(valueRank); } } else { dataType = typeof(object); } accessLevel = (AccessLevelFlags)Enum.ToObject(typeof(AccessLevelFlags), readResponse.Results[2].GetValueOrDefault <byte>()); } else if (rd.NodeClass == NodeClass.Object) { var readRequest = new ReadRequest { NodesToRead = new ReadValueId[] { new ReadValueId { NodeId = n, AttributeId = AttributeIds.EventNotifier }, } }; var readResponse = await this.channel.ReadAsync(readRequest); notifier = (EventNotifierFlags)Enum.ToObject(typeof(EventNotifierFlags), readResponse.Results[0].GetValueOrDefault <byte>()); } parent.Children.Add(new ReferenceDescriptionViewModel(rd, dataType, accessLevel, notifier, parent, this.LoadChildrenAsync)); await Task.Yield(); } break; // exit while; } catch (OperationCanceledException ex) { // exit while; } catch (ServiceResultException ex) { Console.WriteLine("ServiceResultException: {0}", ex); if (this.channel != null) { await this.channel.AbortAsync(token); this.channel = null; } if (ex.HResult == unchecked ((int)StatusCodes.BadSessionIdInvalid)) { continue; } } catch (Exception ex) { Console.WriteLine("Exception {0}", ex); if (this.channel != null) { await this.channel.AbortAsync(token); this.channel = null; } } try { await Task.Delay(5000, token); } catch (OperationCanceledException) { } }while (!token.IsCancellationRequested); } catch (Exception ex) { Console.WriteLine("Exception {0}", ex); } finally { [email protected](); this.NotifyPropertyChanged("IsLoading"); } } catch (OperationCanceledException) { // only get here if cancelled while waiting for lock } }
/// <summary> /// Initializes the message with the body. /// </summary> public BrowseNextMessage(BrowseNextRequest BrowseNextRequest) { this.BrowseNextRequest = BrowseNextRequest; }
public async Task BrowseObjectFolder() { // describe this client application. var clientDescription = new ApplicationDescription { ApplicationName = "Workstation.UaClient.FeatureTests", ApplicationUri = $"urn:{System.Net.Dns.GetHostName()}:Workstation.UaClient.FeatureTests", ApplicationType = ApplicationType.Client }; // place to store certificates var certificateStore = new DirectoryStore("./pki"); // create a 'UaTcpSessionChannel', a client-side channel that opens a 'session' with the server. var channel = new UaTcpSessionChannel( clientDescription, certificateStore, new AnonymousIdentity(), "opc.tcp://localhost:48010"); // the endpoint of Unified Automation's UaCPPServer. try { // try opening a session and reading a few nodes. await channel.OpenAsync(); Console.WriteLine($"Opened session with endpoint '{channel.RemoteEndpoint.EndpointUrl}'."); Console.WriteLine($"SecurityPolicy: '{channel.RemoteEndpoint.SecurityPolicyUri}'."); Console.WriteLine($"SecurityMode: '{channel.RemoteEndpoint.SecurityMode}'."); Console.WriteLine($"UserIdentityToken: '{channel.UserIdentity}'."); // build a BrowseRequest. See 'OPC UA Spec Part 4' section 5.8.2 var browseRequest = new BrowseRequest { NodesToBrowse = new[] { new BrowseDescription { // gather references of this nodeid. NodeId = NodeId.Parse(ObjectIds.ObjectsFolder), // include just 'Forward' references BrowseDirection = BrowseDirection.Forward, // include 'HierarchicalReferences' ReferenceTypeId = NodeId.Parse(ReferenceTypeIds.HierarchicalReferences), // include 'HierarchicalReferences' and all subtypes of 'HierarchicalReferences' IncludeSubtypes = true, // include all classes of node NodeClassMask = (uint)NodeClass.Unspecified, // return reference descriptions with all the fields filled out ResultMask = (uint)BrowseResultMask.All, } }, RequestedMaxReferencesPerNode = 1000 }; // send the request to the server var browseResponse = await channel.BrowseAsync(browseRequest).ConfigureAwait(false); Console.WriteLine("\n+ Objects, 0:Objects, Object, i=85"); Assert.IsNotNull(browseResponse.Results[0].References); foreach (var rd in browseResponse.Results[0].References) { Console.WriteLine(" + {0}, {1}, {2}, {3}", rd.DisplayName, rd.BrowseName, rd.NodeClass, rd.NodeId); } // it is good practice to be prepared to receive a continuationPoint. // ContinuationPoints are returned when the server has more information // than can be delivered in current response. // To test this code, you can reduce the above RequestedMaxReferencesPerNode // to 1. var cp = browseResponse.Results[0].ContinuationPoint; while (cp != null) { var browseNextRequest = new BrowseNextRequest { ContinuationPoints = new[] { cp }, ReleaseContinuationPoints = false }; var browseNextResponse = await channel.BrowseNextAsync(browseNextRequest); Assert.IsNotNull(browseNextResponse.Results[0].References); foreach (var rd in browseNextResponse.Results[0].References) { Console.WriteLine(" + {0}, {1}, {2}", rd.DisplayName, rd.BrowseName, rd.NodeClass); } cp = browseNextResponse.Results[0].ContinuationPoint; } Console.WriteLine($"\nClosing session '{channel.SessionId}'."); await channel.CloseAsync(); } catch (Exception ex) { await channel.AbortAsync(); Console.WriteLine(ex.Message); } }