/// <summary> /// This Service returns the Endpoints supported by a Server and all of the configuration information required to establish a SecureChannel and a Session. /// </summary> /// <param name="request">a request.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public static async Task <GetEndpointsResponse> GetEndpointsAsync(GetEndpointsRequest request) { if (request == null) { throw new ArgumentNullException("request"); } var client = new UaTcpDiscoveryClient( new EndpointDescription { EndpointUrl = request.EndpointUrl, SecurityMode = MessageSecurityMode.None, SecurityPolicyUri = SecurityPolicyUris.None }); try { await client.OpenAsync().ConfigureAwait(false); var response = await client.innerChannel.RequestAsync(request).ConfigureAwait(false); await client.CloseAsync().ConfigureAwait(false); return((GetEndpointsResponse)response); } catch (Exception) { await client.AbortAsync().ConfigureAwait(false); throw; } }
/// <summary> /// This Service returns the Endpoints supported by a Server and all of the configuration information required to establish a SecureChannel and a Session. /// </summary> /// <param name="request">a request.</param> /// <param name="loggerFactory">The logger factory.</param> /// <param name="options">The secure channel options.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> /// <seealso href="https://reference.opcfoundation.org/v104/Core/docs/Part4/5.4.4/">OPC UA specification Part 4: Services, 5.4.4</seealso> public static async Task <GetEndpointsResponse> GetEndpointsAsync(GetEndpointsRequest request, ILoggerFactory?loggerFactory = null, UaApplicationOptions?options = null) { if (request == null) { throw new ArgumentNullException(nameof(request)); } var client = new UaTcpDiscoveryService( new EndpointDescription { EndpointUrl = request.EndpointUrl, SecurityMode = MessageSecurityMode.None, SecurityPolicyUri = SecurityPolicyUris.None }, loggerFactory, options); try { await client.OpenAsync().ConfigureAwait(false); var response = await client.innerChannel.RequestAsync(request).ConfigureAwait(false); await client.CloseAsync().ConfigureAwait(false); return((GetEndpointsResponse)response); } catch (Exception) { await client.AbortAsync().ConfigureAwait(false); throw; } }
private static async Task <EndpointDescription> GetEndpointAsync(string endpointUrl, bool preferPerformance = false) { EndpointDescription endpointDescription; var endpointUri = new Uri(endpointUrl.Split(new[] { ' ' }, 1)[0]); var discoveryUri = new UriBuilder(endpointUri); var profileUris = new string[0]; switch (endpointUri.Scheme) { case "opc.tcp": profileUris = new[] { Profiles.UaTcpTransport }; break; case "https": discoveryUri.Path += "/discovery"; profileUris = new[] { Profiles.HttpsBinaryTransport, Profiles.HttpsXmlOrBinaryTransport, Profiles.HttpsXmlTransport }; break; case "http": discoveryUri.Path += "/discovery"; profileUris = new[] { Profiles.WsHttpXmlOrBinaryTransport, Profiles.WsHttpXmlTransport }; break; } using (var discoveryClient = UaDiscoveryClient.Create(discoveryUri.Uri)) { discoveryClient.OperationTimeout = 5000; var request = new GetEndpointsRequest { EndpointUrl = discoveryClient.Endpoint.EndpointUrl, ProfileUris = profileUris }; var response = await discoveryClient.GetEndpointsAsync(request).ConfigureAwait(false); endpointDescription = preferPerformance ? response.Endpoints.OrderBy(ed => profileUris.ToList().IndexOf(ed.TransportProfileUri)).ThenBy(ed => ed.SecurityLevel).First() : response.Endpoints.OrderBy(ed => profileUris.ToList().IndexOf(ed.TransportProfileUri)).ThenByDescending(ed => ed.SecurityLevel).First(); } return(endpointDescription); }
/// <inheritdoc/> protected override async Task OnOpeningAsync(CancellationToken token = default) { if (RemoteEndpoint.Server == null) { // If specific endpoint is not provided, use discovery to select endpoint with highest // security level. var endpointUrl = RemoteEndpoint.EndpointUrl; var securityPolicyUri = RemoteEndpoint.SecurityPolicyUri; try { _logger?.LogInformation($"Discovering endpoints of '{endpointUrl}'."); var getEndpointsRequest = new GetEndpointsRequest { EndpointUrl = endpointUrl, ProfileUris = new[] { TransportProfileUris.UaTcpTransport } }; var getEndpointsResponse = await UaTcpDiscoveryService.GetEndpointsAsync(getEndpointsRequest, _loggerFactory).ConfigureAwait(false); if (getEndpointsResponse.Endpoints == null || getEndpointsResponse.Endpoints.Length == 0) { throw new InvalidOperationException($"'{endpointUrl}' returned no endpoints."); } var selectedEndpoint = getEndpointsResponse.Endpoints .OfType <EndpointDescription>() .Where(e => string.IsNullOrEmpty(securityPolicyUri) || e.SecurityPolicyUri == securityPolicyUri) .OrderBy(e => e.SecurityLevel) .LastOrDefault(); if (selectedEndpoint is null) { throw new InvalidOperationException($"'{endpointUrl}' returned no endpoint for the requested security policy '{securityPolicyUri}'."); } RemoteEndpoint.Server = selectedEndpoint.Server; RemoteEndpoint.ServerCertificate = selectedEndpoint.ServerCertificate; RemoteEndpoint.SecurityMode = selectedEndpoint.SecurityMode; RemoteEndpoint.SecurityPolicyUri = selectedEndpoint.SecurityPolicyUri; RemoteEndpoint.UserIdentityTokens = selectedEndpoint.UserIdentityTokens; RemoteEndpoint.TransportProfileUri = selectedEndpoint.TransportProfileUri; RemoteEndpoint.SecurityLevel = selectedEndpoint.SecurityLevel; _logger?.LogTrace($"Success discovering endpoints of '{endpointUrl}'."); } catch (Exception ex) { _logger?.LogError($"Error discovering endpoints of '{endpointUrl}'. {ex.Message}"); throw; } } // Ask for user identity. May show dialog. if (UserIdentityProvider != null) { UserIdentity = await UserIdentityProvider(RemoteEndpoint); } await base.OnOpeningAsync(token); }
public async Task SessionTimeoutCausesFault() { // discover available endpoints of server. var getEndpointsRequest = new GetEndpointsRequest { EndpointUrl = EndpointUrl, ProfileUris = new[] { TransportProfileUris.UaTcpTransport } }; Console.WriteLine($"Discovering endpoints of '{getEndpointsRequest.EndpointUrl}'."); var getEndpointsResponse = await UaTcpDiscoveryService.GetEndpointsAsync(getEndpointsRequest); var selectedEndpoint = getEndpointsResponse.Endpoints.OrderBy(e => e.SecurityLevel).Last(); var selectedTokenType = selectedEndpoint.UserIdentityTokens[0].TokenType; IUserIdentity selectedUserIdentity; switch (selectedTokenType) { case UserTokenType.UserName: selectedUserIdentity = new UserNameIdentity("root", "secret"); break; default: selectedUserIdentity = new AnonymousIdentity(); break; } var channel = new UaTcpSessionChannel( this.localDescription, this.certificateStore, selectedUserIdentity, selectedEndpoint, loggerFactory: this.loggerFactory, options: new UaTcpSessionChannelOptions { SessionTimeout = 10000 }); 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($"Activated session '{channel.SessionId}'."); // server should close session due to inactivity await Task.Delay(20000); // should throw exception var readRequest = new ReadRequest { NodesToRead = new[] { new ReadValueId { NodeId = NodeId.Parse(VariableIds.Server_ServerStatus_CurrentTime), AttributeId = AttributeIds.Value } } }; await channel.ReadAsync(readRequest); Console.WriteLine($"Closing session '{channel.SessionId}'."); await channel.CloseAsync(); }
public async Task ConnnectToAllEndpoints() { // discover available endpoints of server. var getEndpointsRequest = new GetEndpointsRequest { EndpointUrl = EndpointUrl, ProfileUris = new[] { TransportProfileUris.UaTcpTransport } }; Console.WriteLine($"Discovering endpoints of '{getEndpointsRequest.EndpointUrl}'."); var getEndpointsResponse = await UaTcpDiscoveryService.GetEndpointsAsync(getEndpointsRequest); // for each endpoint and user identity type, try creating a session and reading a few nodes. foreach (var selectedEndpoint in getEndpointsResponse.Endpoints.OrderBy(e => e.SecurityLevel)) { foreach (var selectedTokenPolicy in selectedEndpoint.UserIdentityTokens) { IUserIdentity selectedUserIdentity; switch (selectedTokenPolicy.TokenType) { case UserTokenType.UserName: selectedUserIdentity = new UserNameIdentity("root", "secret"); break; //case UserTokenType.Certificate: // selectedUserIdentity = new X509Identity(localCertificate); // break; case UserTokenType.Anonymous: selectedUserIdentity = new AnonymousIdentity(); break; default: continue; } var channel = new UaTcpSessionChannel( this.localDescription, this.certificateStore, async e => selectedUserIdentity, selectedEndpoint, loggerFactory: this.loggerFactory, options: new UaTcpSessionChannelOptions { TimeoutHint = 60000 }); 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}'."); Console.WriteLine($"Closing session '{channel.SessionId}'."); await channel.CloseAsync(); } } }
public static LogEntry For(GetEndpointsRequest request) { LogEntry entry = new LogEntry("GetEndpointsRequest"); entry.Add("RequestHeader", For(request.RequestHeader)); entry.Add("EndpointURL", For(request.EndpointUrl)); entry.Add("LocaleIds", For(request.LocaleIds)); entry.Add("ProfileURIs", For(request.ProfileUris)); return(entry); }
public async Task ConnnectToEndpointsWithNoSecurityAndWithNoCertificate() { // discover available endpoints of server. var getEndpointsRequest = new GetEndpointsRequest { EndpointUrl = this.endpointUrl, ProfileUris = new[] { TransportProfileUris.UaTcpTransport } }; Console.WriteLine($"Discovering endpoints of '{getEndpointsRequest.EndpointUrl}'."); var getEndpointsResponse = await UaTcpDiscoveryClient.GetEndpointsAsync(getEndpointsRequest); // for each endpoint and user identity type, try creating a session and reading a few nodes. foreach (var selectedEndpoint in getEndpointsResponse.Endpoints.Where(e => e.SecurityMode == MessageSecurityMode.None)) { foreach (var selectedTokenPolicy in selectedEndpoint.UserIdentityTokens) { IUserIdentity selectedUserIdentity; switch (selectedTokenPolicy.TokenType) { case UserTokenType.UserName: selectedUserIdentity = new UserNameIdentity("root", "secret"); break; //case UserTokenType.Certificate: // selectedUserIdentity = new X509Identity(localCertificate); // break; case UserTokenType.Anonymous: selectedUserIdentity = new AnonymousIdentity(); break; default: continue; } var channel = new UaTcpSessionChannel( this.localDescription, null, selectedUserIdentity, selectedEndpoint, loggerFactory: this.loggerFactory); Console.WriteLine($"Creating session with endpoint '{channel.RemoteEndpoint.EndpointUrl}'."); Console.WriteLine($"SecurityPolicy: '{channel.RemoteEndpoint.SecurityPolicyUri}'."); Console.WriteLine($"SecurityMode: '{channel.RemoteEndpoint.SecurityMode}'."); Console.WriteLine($"UserIdentityToken: '{channel.UserIdentity}'."); await channel.OpenAsync(); Console.WriteLine($"Closing session '{channel.SessionId}'."); await channel.CloseAsync(); } } }
public IObservable <EndpointDescription[]> GetEndpoints(string url) { var request = new GetEndpointsRequest { EndpointUrl = url, }; return(Observable.FromAsync(async() => { var respones = await UaTcpDiscoveryService.GetEndpointsAsync(request); return respones .Endpoints; })); }
protected override void OnStartup(StartupEventArgs e) { // Setup a logger. this.loggerFactory = new LoggerFactory(); this.loggerFactory.AddDebug(LogLevel.Trace); // discover available endpoints of server. var getEndpointsRequest = new GetEndpointsRequest { EndpointUrl = StatusHmi.Properties.Settings.Default.EndpointUrl, ProfileUris = new[] { TransportProfileUris.UaTcpTransport } }; var getEndpointsResponse = UaTcpDiscoveryClient.GetEndpointsAsync(getEndpointsRequest).Result; var endpoint = getEndpointsResponse.Endpoints .Where(d => d.SecurityPolicyUri == SecurityPolicyUris.Basic256 && d.SecurityMode == MessageSecurityMode.SignAndEncrypt) .First(); // Create the session client for the app. this.session = new UaTcpSessionClient( new ApplicationDescription() { ApplicationName = "Workstation.StatusHmi", ApplicationUri = $"urn:{System.Net.Dns.GetHostName()}:Workstation.StatusHmi", ApplicationType = ApplicationType.Client }, new DirectoryStore( Environment.ExpandEnvironmentVariables(@"%LOCALAPPDATA%\Workstation.StatusHmi\pki"), loggerFactory: this.loggerFactory), this.ProvideUserIdentity, endpoint, this.loggerFactory); // Create the main view model. var viewModel = new MainViewModel(this.session); // Create and show the main view. var view = new MainView { DataContext = viewModel }; view.Show(); base.OnStartup(e); }
public async Task TestSubscription() { // get or add application certificate. var localCertificate = this.localDescription.GetCertificate(); if (localCertificate == null) { throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "Application certificate is missing."); } // discover available endpoints of server. var getEndpointsRequest = new GetEndpointsRequest { EndpointUrl = this.endpointUrl, ProfileUris = new[] { TransportProfileUris.UaTcpTransport } }; Console.WriteLine($"Discovering endpoints of '{getEndpointsRequest.EndpointUrl}'."); var getEndpointsResponse = await UaTcpDiscoveryClient.GetEndpointsAsync(getEndpointsRequest); var selectedEndpoint = getEndpointsResponse.Endpoints.OrderBy(e => e.SecurityLevel).Last(); IUserIdentity selectedUserIdentity = new UserNameIdentity("root", "secret"); var session = new UaTcpSessionClient( this.localDescription, localCertificate, selectedUserIdentity, selectedEndpoint); Console.WriteLine($"Creating session with endpoint '{session.RemoteEndpoint.EndpointUrl}'."); Console.WriteLine($"SecurityPolicy: '{session.RemoteEndpoint.SecurityPolicyUri}'."); Console.WriteLine($"SecurityMode: '{session.RemoteEndpoint.SecurityMode}'."); var sub = new MySubscription(session); Console.WriteLine($"Created subscription."); await Task.Delay(5000); session.Dispose(); Assert.IsTrue(sub.CurrentTime != DateTime.MinValue); Assert.IsTrue(sub.CurrentTimeAsDataValue != null); Assert.IsTrue(sub.CurrentTimeQueue.Count > 0); }
public async Task TestSubscription() { // discover available endpoints of server. var getEndpointsRequest = new GetEndpointsRequest { EndpointUrl = this.endpointUrl, ProfileUris = new[] { TransportProfileUris.UaTcpTransport } }; Console.WriteLine($"Discovering endpoints of '{getEndpointsRequest.EndpointUrl}'."); var getEndpointsResponse = await UaTcpDiscoveryClient.GetEndpointsAsync(getEndpointsRequest); var selectedEndpoint = getEndpointsResponse.Endpoints.OrderBy(e => e.SecurityLevel).Last(); var session = new UaTcpSessionClient( this.localDescription, this.certificateStore, ed => Task.FromResult <IUserIdentity>(new UserNameIdentity("root", "secret")), selectedEndpoint, loggerFactory: this.loggerFactory); Console.WriteLine($"Creating session with endpoint '{session.RemoteEndpoint.EndpointUrl}'."); Console.WriteLine($"SecurityPolicy: '{session.RemoteEndpoint.SecurityPolicyUri}'."); Console.WriteLine($"SecurityMode: '{session.RemoteEndpoint.SecurityMode}'."); var sub = new MySubscription(); session.Subscribe(sub); Console.WriteLine($"Created subscription."); await Task.Delay(5000); session.Dispose(); Assert.IsTrue(sub.CurrentTime != DateTime.MinValue, "CurrentTime"); Assert.IsTrue(sub.CurrentTimeAsDataValue != null, "CurrentTimeAsDataValue"); Assert.IsTrue(sub.CurrentTimeQueue.Count > 0, "CurrentTimeQueue"); }
public async Task <GetEndpointsResponse> GetEndpointsAsync(GetEndpointsRequest getEndpointsRequest) { UpdateRequestHeader(getEndpointsRequest, true, "GetEndpoints"); GetEndpointsResponse getEndpointsResponse = null; try { if (UseTransportChannel) { var serviceResponse = await Task <IServiceResponse> .Factory.FromAsync(TransportChannel.BeginSendRequest, TransportChannel.EndSendRequest, getEndpointsRequest, null).ConfigureAwait(false); if (serviceResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } ValidateResponse(serviceResponse.ResponseHeader); getEndpointsResponse = (GetEndpointsResponse)serviceResponse; } else { var getEndpointsResponseMessage = await Task <GetEndpointsResponseMessage> .Factory.FromAsync(InnerChannel.BeginGetEndpoints, InnerChannel.EndGetEndpoints, new GetEndpointsMessage(getEndpointsRequest), null).ConfigureAwait(false); if (getEndpointsResponseMessage == null || getEndpointsResponseMessage.GetEndpointsResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } getEndpointsResponse = getEndpointsResponseMessage.GetEndpointsResponse; ValidateResponse(getEndpointsResponse.ResponseHeader); } } finally { RequestCompleted(getEndpointsRequest, getEndpointsResponse, "GetEndpoints"); } return(getEndpointsResponse); }
public async Task SessionTimeoutCausesFault() { // get or add application certificate. var localCertificate = this.localDescription.GetCertificate(); if (localCertificate == null) { throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "Application certificate is missing."); } // discover available endpoints of server. var getEndpointsRequest = new GetEndpointsRequest { EndpointUrl = this.endpointUrl, ProfileUris = new[] { TransportProfileUris.UaTcpTransport } }; Console.WriteLine($"Discovering endpoints of '{getEndpointsRequest.EndpointUrl}'."); var getEndpointsResponse = await UaTcpDiscoveryClient.GetEndpointsAsync(getEndpointsRequest); var selectedEndpoint = getEndpointsResponse.Endpoints.OrderBy(e => e.SecurityLevel).Last(); var selectedTokenType = selectedEndpoint.UserIdentityTokens[0].TokenType; IUserIdentity selectedUserIdentity; switch (selectedTokenType) { case UserTokenType.UserName: selectedUserIdentity = new UserNameIdentity("root", "secret"); break; case UserTokenType.Certificate: selectedUserIdentity = new X509Identity(localCertificate); break; default: selectedUserIdentity = new AnonymousIdentity(); break; } var channel = new UaTcpSessionChannel( this.localDescription, localCertificate, selectedUserIdentity, selectedEndpoint, sessionTimeout: 10000); Console.WriteLine($"Creating session with endpoint '{channel.RemoteEndpoint.EndpointUrl}'."); Console.WriteLine($"SecurityPolicy: '{channel.RemoteEndpoint.SecurityPolicyUri}'."); Console.WriteLine($"SecurityMode: '{channel.RemoteEndpoint.SecurityMode}'."); await channel.OpenAsync(); Console.WriteLine($"Activated session '{channel.SessionId}'."); // server should close session due to inactivity await Task.Delay(20000); // should throw exception var readRequest = new ReadRequest { NodesToRead = new[] { new ReadValueId { NodeId = NodeId.Parse(VariableIds.Server_ServerStatus_CurrentTime), AttributeId = AttributeIds.Value } } }; await channel.ReadAsync(readRequest); Console.WriteLine($"Closing session '{channel.SessionId}'."); await channel.CloseAsync(); }
public static async Task ReadSubscribed(CancellationToken token = default(CancellationToken)) { { // setup logger var loggerFactory = new LoggerFactory(); loggerFactory.AddConsole(LogLevel.Information); //var logger = loggerFactory?.CreateLogger<Program>(); // Describe this app. var appDescription = new ApplicationDescription() { ApplicationName = "DataLoggingConsole", ApplicationUri = $"urn:{System.Net.Dns.GetHostName()}:DataLoggingConsole", ApplicationType = ApplicationType.Client, }; // Create a certificate store on disk. // Create array of NodeIds to log. while (!token.IsCancellationRequested) { try { // Discover endpoints. var getEndpointsRequest = new GetEndpointsRequest { EndpointUrl = discoveryUrl, ProfileUris = new[] { TransportProfileUris.UaTcpTransport } }; var getEndpointsResponse = await UaTcpDiscoveryService.GetEndpointsAsync(getEndpointsRequest) .ConfigureAwait(false); if (getEndpointsResponse.Endpoints == null || getEndpointsResponse.Endpoints.Length == 0) { throw new InvalidOperationException($"'{discoveryUrl}' returned no endpoints."); } // Choose the endpoint with highest security level. var remoteEndpoint = getEndpointsResponse.Endpoints.OrderBy(e => e.SecurityLevel).Last(); // Create a session with the server. var channel = new UaTcpSessionChannel(appDescription, certificateStore, async e => GetIUserIdentity(remoteEndpoint).GetAwaiter().GetResult(), remoteEndpoint, loggerFactory); try { await channel.OpenAsync(); var subscriptionRequest = new CreateSubscriptionRequest { RequestedPublishingInterval = 1000, RequestedMaxKeepAliveCount = 10, RequestedLifetimeCount = 30, PublishingEnabled = true }; var subscriptionResponse = await channel.CreateSubscriptionAsync(subscriptionRequest); var id = subscriptionResponse.SubscriptionId; var itemsToCreate = new MonitoredItemCreateRequest[] { #region MonitoredItems new MonitoredItemCreateRequest { ItemToMonitor = new ReadValueId { NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Admin.ProdProcessedCount"), AttributeId = AttributeIds.Value }, //ProdProcessedCount MonitoringMode = MonitoringMode.Reporting, RequestedParameters = new MonitoringParameters { ClientHandle = 1, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true } }, new MonitoredItemCreateRequest { ItemToMonitor = new ReadValueId { NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Command.Parameter[0].Value"), AttributeId = AttributeIds.Value }, //Next batch ID MonitoringMode = MonitoringMode.Reporting, RequestedParameters = new MonitoringParameters { ClientHandle = 2, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true } }, new MonitoredItemCreateRequest { ItemToMonitor = new ReadValueId { NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Command.Parameter[1].Value"), AttributeId = AttributeIds.Value }, //Next product ID MonitoringMode = MonitoringMode.Reporting, RequestedParameters = new MonitoringParameters { ClientHandle = 3, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true } }, new MonitoredItemCreateRequest { ItemToMonitor = new ReadValueId { NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Command.Parameter[2].Value"), AttributeId = AttributeIds.Value }, //Amount of product in next batch MonitoringMode = MonitoringMode.Reporting, RequestedParameters = new MonitoringParameters { ClientHandle = 4, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true } }, new MonitoredItemCreateRequest { ItemToMonitor = new ReadValueId { NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Status.Parameter[2].Value"), AttributeId = AttributeIds.Value }, //Humidity MonitoringMode = MonitoringMode.Reporting, RequestedParameters = new MonitoringParameters { ClientHandle = 5, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true } }, new MonitoredItemCreateRequest { ItemToMonitor = new ReadValueId { NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Status.Parameter[3].Value"), AttributeId = AttributeIds.Value }, //Temperature MonitoringMode = MonitoringMode.Reporting, RequestedParameters = new MonitoringParameters { ClientHandle = 6, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true } }, new MonitoredItemCreateRequest { ItemToMonitor = new ReadValueId { NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Status.Parameter[4].Value"), AttributeId = AttributeIds.Value }, //Vibration MonitoringMode = MonitoringMode.Reporting, RequestedParameters = new MonitoringParameters { ClientHandle = 7, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true } }, new MonitoredItemCreateRequest { ItemToMonitor = new ReadValueId { NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Status.MachSpeed"), AttributeId = AttributeIds.Value }, //MachineSpeed MonitoringMode = MonitoringMode.Reporting, RequestedParameters = new MonitoringParameters { ClientHandle = 8, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true } }, new MonitoredItemCreateRequest { ItemToMonitor = new ReadValueId { NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Status.StateCurrent"), AttributeId = AttributeIds.Value }, //state MonitoringMode = MonitoringMode.Reporting, RequestedParameters = new MonitoringParameters { ClientHandle = 9, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true } }, new MonitoredItemCreateRequest { ItemToMonitor = new ReadValueId { NodeId = NodeId.Parse("ns=6;s=::Program:Cube.Status.StateCurrent"), AttributeId = AttributeIds.Value }, //cmdCtrln MonitoringMode = MonitoringMode.Reporting, RequestedParameters = new MonitoringParameters { ClientHandle = 10, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true } } #endregion }; var itemsRequest = new CreateMonitoredItemsRequest { SubscriptionId = id, ItemsToCreate = itemsToCreate, }; var itemsResponse = await channel.CreateMonitoredItemsAsync(itemsRequest); var subToken = channel.Where(pr => pr.SubscriptionId == id).Subscribe(pr => { // loop through all the data change notifications var dcns = pr.NotificationMessage.NotificationData.OfType <DataChangeNotification>(); foreach (var dcn in dcns) { foreach (var min in dcn.MonitoredItems) { switch (min.ClientHandle) { case 1: prodProc = (int)min.Value.Value; time = (DateTime)min.Value.ServerTimestamp; break; case 2: time = (DateTime)min.Value.ServerTimestamp; nextBatchID = (float)min.Value.Value; break; case 3: time = (DateTime)min.Value.ServerTimestamp; nextProductID = (float)min.Value.Value; break; case 4: time = (DateTime)min.Value.ServerTimestamp; nextProductAmount = (float)min.Value.Value; break; case 5: time = (DateTime)min.Value.ServerTimestamp; humidity = (float)min.Value.Value; break; case 6: time = (DateTime)min.Value.ServerTimestamp; temperature = (float)min.Value.Value; break; case 7: time = (DateTime)min.Value.ServerTimestamp; vibration = (float)min.Value.Value; break; case 8: time = (DateTime)min.Value.ServerTimestamp; machinespeed = (float)min.Value.Value; break; case 9: time = (DateTime)min.Value.ServerTimestamp; State = (int)min.Value.Value; break; case 10: cmdctrl = (int)min.Value.Value; time = (DateTime)min.Value.ServerTimestamp; break; } } } }); while (!token.IsCancellationRequested) { await Task.Delay(500); } } catch { } } catch (Exception ex) { } //try //{ // await Task.Delay(cycleTime, token); //} //catch //{ //} } } }
/// <summary> /// Initializes the message with the body. /// </summary> public GetEndpointsMessage(GetEndpointsRequest GetEndpointsRequest) { this.GetEndpointsRequest = GetEndpointsRequest; }
/// <summary> /// Begins an asynchronous invocation of the GetEndpoints service. /// </summary> public IAsyncResult BeginGetEndpoints( RequestHeader requestHeader, string endpointUrl, StringCollection localeIds, StringCollection profileUris, AsyncCallback callback, object asyncState) { GetEndpointsRequest request = new GetEndpointsRequest(); request.RequestHeader = requestHeader; request.EndpointUrl = endpointUrl; request.LocaleIds = localeIds; request.ProfileUris = profileUris; UpdateRequestHeader(request, requestHeader == null, "GetEndpoints"); if (UseTransportChannel) { return TransportChannel.BeginSendRequest(request, callback, asyncState); } return InnerChannel.BeginGetEndpoints(new GetEndpointsMessage(request), callback, asyncState); }
private static async Task Write(List <NodeId> nodesIds, DataValue dataval) { // setup logger var loggerFactory = new LoggerFactory(); loggerFactory.AddDebug(LogLevel.Debug); // Describe this app. var appDescription = new ApplicationDescription() { ApplicationName = "DataLoggingConsole", ApplicationUri = $"urn:{System.Net.Dns.GetHostName()}:DataLoggingConsole", ApplicationType = ApplicationType.Client, }; // Create a certificate store on disk. // Create array of NodeIds to log. var nodeIds = nodesIds.ToArray(); try { // Discover endpoints. var getEndpointsRequest = new GetEndpointsRequest { EndpointUrl = discoveryUrl, ProfileUris = new[] { TransportProfileUris.UaTcpTransport } }; var getEndpointsResponse = await UaTcpDiscoveryService.GetEndpointsAsync(getEndpointsRequest).ConfigureAwait(false); if (getEndpointsResponse.Endpoints == null || getEndpointsResponse.Endpoints.Length == 0) { throw new InvalidOperationException($"'{discoveryUrl}' returned no endpoints."); } // Choose the endpoint with highest security level. var remoteEndpoint = getEndpointsResponse.Endpoints.OrderBy(e => e.SecurityLevel).Last(); // Create a session with the server. var session = new UaTcpSessionChannel(appDescription, certificateStore, async e => GetIUserIdentity(remoteEndpoint).GetAwaiter().GetResult(), remoteEndpoint, loggerFactory); try { await session.OpenAsync(); RegisterNodesResponse registerNodesResponse = null; if (true) // True registers the nodeIds to improve performance of the server. { // Register array of nodes to read. var registerNodesRequest = new RegisterNodesRequest { NodesToRegister = nodeIds }; registerNodesResponse = await session.RegisterNodesAsync(registerNodesRequest); } WriteRequest writeRequest = new WriteRequest(); writeRequest.NodesToWrite = new WriteValue[1] { new WriteValue() { NodeId = nodeIds[0], AttributeId = AttributeIds.Value, Value = dataval } }; WriteRequest request = writeRequest; StatusCode statusCode; // write the nodes. statusCode = (await session.WriteAsync(request).ConfigureAwait(false)).Results[0];; } catch { await session.AbortAsync(); throw; } await session.AbortAsync(); } catch (Exception e) { // ignored } }
/// <summary> /// Opens a session with the remote endpoint. /// </summary> /// <param name="token">A cancellation token.</param> /// <returns>A task.</returns> private async Task OpenAsync(CancellationToken token = default(CancellationToken)) { await this.semaphore.WaitAsync(token).ConfigureAwait(false); try { if (this.RemoteEndpoint == null) { // If specific endpoint is not provided, use discovery to select endpoint with highest // security level. try { Trace.TraceInformation($"UaTcpSessionClient discovering endpoints of '{this.discoveryUrl}'."); var getEndpointsRequest = new GetEndpointsRequest { EndpointUrl = this.discoveryUrl, ProfileUris = new[] { TransportProfileUris.UaTcpTransport } }; var getEndpointsResponse = await UaTcpDiscoveryClient.GetEndpointsAsync(getEndpointsRequest).ConfigureAwait(false); if (getEndpointsResponse.Endpoints == null || getEndpointsResponse.Endpoints.Length == 0) { throw new InvalidOperationException($"'{this.discoveryUrl}' returned no endpoints."); } this.RemoteEndpoint = getEndpointsResponse.Endpoints.OrderBy(e => e.SecurityLevel).Last(); } catch (Exception ex) { Trace.TraceWarning($"UaTcpSessionClient error discovering endpoints of '{this.discoveryUrl}'. {ex.Message}"); throw; } } // throw here to exit state machine. token.ThrowIfCancellationRequested(); try { this.linkToken?.Dispose(); Trace.TraceInformation($"UaTcpSessionClient opening channel with endpoint '{this.RemoteEndpoint.EndpointUrl}'."); this.innerChannel = new UaTcpSessionChannel( this.LocalDescription, this.LocalCertificate, this.UserIdentity, this.RemoteEndpoint, this.SessionTimeout, this.TimeoutHint, this.DiagnosticsHint, this.LocalReceiveBufferSize, this.LocalSendBufferSize, this.LocalMaxMessageSize, this.LocalMaxChunkCount); await this.innerChannel.OpenAsync(token).ConfigureAwait(false); this.linkToken = this.pendingRequests.LinkTo(this.innerChannel); // create an internal subscription. this.publishEvent.Subscribe(this.OnPublishResponse, ThreadOption.PublisherThread, false); var subscriptionRequest = new CreateSubscriptionRequest { RequestedPublishingInterval = DefaultPublishingInterval, RequestedMaxKeepAliveCount = DefaultKeepaliveCount, RequestedLifetimeCount = (uint)(this.SessionTimeout / DefaultPublishingInterval), PublishingEnabled = true, Priority = 0 }; var subscriptionResponse = await this.CreateSubscriptionAsync(subscriptionRequest).ConfigureAwait(false); this.subscriptionId = subscriptionResponse.SubscriptionId; } catch (Exception ex) { Trace.TraceWarning($"UaTcpSessionClient error opening channel with endpoint '{this.RemoteEndpoint.EndpointUrl}'. {ex.Message}"); throw; } } finally { this.semaphore.Release(); } }
/// <summary> /// Invokes the GetEndpoints service. /// </summary> public virtual ResponseHeader GetEndpoints( RequestHeader requestHeader, string endpointUrl, StringCollection localeIds, StringCollection profileUris, out EndpointDescriptionCollection endpoints) { GetEndpointsRequest request = new GetEndpointsRequest(); GetEndpointsResponse response = null; request.RequestHeader = requestHeader; request.EndpointUrl = endpointUrl; request.LocaleIds = localeIds; request.ProfileUris = profileUris; UpdateRequestHeader(request, requestHeader == null, "GetEndpoints"); try { if (UseTransportChannel) { IServiceResponse genericResponse = TransportChannel.SendRequest(request); if (genericResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } ValidateResponse(genericResponse.ResponseHeader); response = (GetEndpointsResponse)genericResponse; } else { GetEndpointsResponseMessage responseMessage = InnerChannel.GetEndpoints(new GetEndpointsMessage(request)); if (responseMessage == null || responseMessage.GetEndpointsResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } response = responseMessage.GetEndpointsResponse; ValidateResponse(response.ResponseHeader); } endpoints = response.Endpoints; } finally { RequestCompleted(request, response, "GetEndpoints"); } return response.ResponseHeader; }
private static async Task TestAsync(CancellationToken token = default(CancellationToken)) { var discoveryUrl = $"opc.tcp://localhost:26543"; var cycleTime = 5000; // setup logger var loggerFactory = new LoggerFactory(); loggerFactory.AddConsole(LogLevel.Information); var logger = loggerFactory?.CreateLogger <Program>(); // Describe this app. var appDescription = new ApplicationDescription() { ApplicationName = "DataLoggingConsole", ApplicationUri = $"urn:{System.Net.Dns.GetHostName()}:DataLoggingConsole", ApplicationType = ApplicationType.Client, }; // Create a certificate store on disk. var certificateStore = new DirectoryStore( Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "DataLoggingConsole", "pki")); // Create array of NodeIds to log. var nodeIds = new[] { NodeId.Parse("i=2258") }; while (!token.IsCancellationRequested) { try { // Discover endpoints. var getEndpointsRequest = new GetEndpointsRequest { EndpointUrl = discoveryUrl, ProfileUris = new[] { TransportProfileUris.UaTcpTransport } }; var getEndpointsResponse = await UaTcpDiscoveryService.GetEndpointsAsync(getEndpointsRequest).ConfigureAwait(false); if (getEndpointsResponse.Endpoints == null || getEndpointsResponse.Endpoints.Length == 0) { throw new InvalidOperationException($"'{discoveryUrl}' returned no endpoints."); } // Choose the endpoint with highest security level. var remoteEndpoint = getEndpointsResponse.Endpoints.OrderBy(e => e.SecurityLevel).Last(); // Choose a User Identity. IUserIdentity userIdentity = null; if (remoteEndpoint.UserIdentityTokens.Any(p => p.TokenType == UserTokenType.Anonymous)) { userIdentity = new AnonymousIdentity(); } else if (remoteEndpoint.UserIdentityTokens.Any(p => p.TokenType == UserTokenType.UserName)) { // If a username / password is requested, provide from .config file. userIdentity = new UserNameIdentity("root", "secret"); } else { throw new InvalidOperationException("Server must accept Anonymous or UserName identity."); } // Create a session with the server. var session = new UaTcpSessionChannel(appDescription, certificateStore, async e => userIdentity, remoteEndpoint, loggerFactory); try { await session.OpenAsync(); RegisterNodesResponse registerNodesResponse = null; if (true) // True registers the nodeIds to improve performance of the server. { // Register array of nodes to read. var registerNodesRequest = new RegisterNodesRequest { NodesToRegister = nodeIds }; registerNodesResponse = await session.RegisterNodesAsync(registerNodesRequest); } // Prepare read request. var readRequest = new ReadRequest { NodesToRead = (registerNodesResponse?.RegisteredNodeIds ?? nodeIds) .Select(n => new ReadValueId { NodeId = n, AttributeId = AttributeIds.Value }) .ToArray() }; while (!token.IsCancellationRequested) { // Read the nodes. var readResponse = await session.ReadAsync(readRequest).ConfigureAwait(false); // Write the results. for (int i = 0; i < readRequest.NodesToRead.Length; i++) { logger?.LogInformation($"{nodeIds[i]}; value: {readResponse.Results[i]}"); } try { await Task.Delay(cycleTime, token); } catch { } } await session.CloseAsync(); } catch { await session.AbortAsync(); throw; } } catch (Exception ex) { logger?.LogError(ex.Message); } try { await Task.Delay(cycleTime, token); } catch { } } }
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 } }
public async Task ConnnectToAllEndpoints() { // get or add application certificate. var localCertificate = this.localDescription.GetCertificate(); if (localCertificate == null) { throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "Application certificate is missing."); } // discover available endpoints of server. var getEndpointsRequest = new GetEndpointsRequest { EndpointUrl = this.endpointUrl, ProfileUris = new[] { TransportProfileUris.UaTcpTransport } }; Console.WriteLine($"Discovering endpoints of '{getEndpointsRequest.EndpointUrl}'."); var getEndpointsResponse = await UaTcpDiscoveryClient.GetEndpointsAsync(getEndpointsRequest); // for each endpoint and user identity type, try creating a session and reading a few nodes. foreach (var selectedEndpoint in getEndpointsResponse.Endpoints.OrderBy(e => e.SecurityLevel)) { foreach (var selectedTokenPolicy in selectedEndpoint.UserIdentityTokens) { IUserIdentity selectedUserIdentity; switch (selectedTokenPolicy.TokenType) { case UserTokenType.UserName: selectedUserIdentity = new UserNameIdentity("root", "secret"); break; case UserTokenType.Certificate: selectedUserIdentity = new X509Identity(localCertificate); break; default: selectedUserIdentity = new AnonymousIdentity(); break; } var channel = new UaTcpSessionChannel( this.localDescription, localCertificate, selectedUserIdentity, selectedEndpoint); Console.WriteLine($"Creating session with endpoint '{channel.RemoteEndpoint.EndpointUrl}'."); Console.WriteLine($"SecurityPolicy: '{channel.RemoteEndpoint.SecurityPolicyUri}'."); Console.WriteLine($"SecurityMode: '{channel.RemoteEndpoint.SecurityMode}'."); Console.WriteLine($"UserIdentityToken: '{channel.UserIdentity}'."); try { await channel.OpenAsync(); Console.WriteLine($"Closing session '{channel.SessionId}'."); await channel.CloseAsync(); } catch (Exception ex) { Console.WriteLine($"Error opening session '{channel.SessionId}'. {ex.Message}"); } } } }
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); } }
private static async Task TestAsync() { var discoveryUrl = "opc.tcp://*****:*****@"%LOCALAPPDATA%\Workstation.ConsoleApp\pki")), userIdentity, remoteEndpoint)) { try { await session.OpenAsync(); } catch (ServiceResultException ex) { if ((uint)ex.HResult == StatusCodes.BadSecurityChecksFailed) { Console.WriteLine("Error connecting to endpoint. Did the server reject our certificate?"); } throw ex; } Console.WriteLine("Step 5 - Browse the server namespace."); Console.WriteLine("+ Root"); BrowseRequest browseRequest = new BrowseRequest { NodesToBrowse = new BrowseDescription[] { new BrowseDescription { NodeId = NodeId.Parse(ObjectIds.RootFolder), BrowseDirection = BrowseDirection.Forward, ReferenceTypeId = NodeId.Parse(ReferenceTypeIds.HierarchicalReferences), NodeClassMask = (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, IncludeSubtypes = true, ResultMask = (uint)BrowseResultMask.All } }, }; BrowseResponse browseResponse = await session.BrowseAsync(browseRequest); foreach (var rd1 in browseResponse.Results[0].References ?? new ReferenceDescription[0]) { Console.WriteLine(" + {0}: {1}, {2}", rd1.DisplayName, rd1.BrowseName, rd1.NodeClass); browseRequest = new BrowseRequest { NodesToBrowse = new BrowseDescription[] { new BrowseDescription { NodeId = ExpandedNodeId.ToNodeId(rd1.NodeId, session.NamespaceUris), BrowseDirection = BrowseDirection.Forward, ReferenceTypeId = NodeId.Parse(ReferenceTypeIds.HierarchicalReferences), NodeClassMask = (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, IncludeSubtypes = true, ResultMask = (uint)BrowseResultMask.All } }, }; browseResponse = await session.BrowseAsync(browseRequest); foreach (var rd2 in browseResponse.Results[0].References ?? new ReferenceDescription[0]) { Console.WriteLine(" + {0}: {1}, {2}", rd2.DisplayName, rd2.BrowseName, rd2.NodeClass); browseRequest = new BrowseRequest { NodesToBrowse = new BrowseDescription[] { new BrowseDescription { NodeId = ExpandedNodeId.ToNodeId(rd2.NodeId, session.NamespaceUris), BrowseDirection = BrowseDirection.Forward, ReferenceTypeId = NodeId.Parse(ReferenceTypeIds.HierarchicalReferences), NodeClassMask = (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, IncludeSubtypes = true, ResultMask = (uint)BrowseResultMask.All } }, }; browseResponse = await session.BrowseAsync(browseRequest); foreach (var rd3 in browseResponse.Results[0].References ?? new ReferenceDescription[0]) { Console.WriteLine(" + {0}: {1}, {2}", rd3.DisplayName, rd3.BrowseName, rd3.NodeClass); } } } Console.WriteLine("Press any key to continue..."); Console.ReadKey(true); Console.WriteLine("Step 6 - Create a subscription."); var subscriptionRequest = new CreateSubscriptionRequest { RequestedPublishingInterval = 1000, RequestedMaxKeepAliveCount = 10, RequestedLifetimeCount = 30, PublishingEnabled = true }; var subscriptionResponse = await session.CreateSubscriptionAsync(subscriptionRequest).ConfigureAwait(false); var id = subscriptionResponse.SubscriptionId; Console.WriteLine("Step 7 - Add items to the subscription."); var itemsToCreate = new MonitoredItemCreateRequest[] { new MonitoredItemCreateRequest { ItemToMonitor = new ReadValueId { NodeId = NodeId.Parse("i=2258"), AttributeId = AttributeIds.Value }, MonitoringMode = MonitoringMode.Reporting, RequestedParameters = new MonitoringParameters { ClientHandle = 12345, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true } } }; var itemsRequest = new CreateMonitoredItemsRequest { SubscriptionId = id, ItemsToCreate = itemsToCreate, }; var itemsResponse = await session.CreateMonitoredItemsAsync(itemsRequest).ConfigureAwait(false); Console.WriteLine("Step 8 - Publish the subscription."); var publishRequest = new PublishRequest { SubscriptionAcknowledgements = new SubscriptionAcknowledgement[0] }; Console.WriteLine("Press any key to delete the subscription..."); while (!Console.KeyAvailable) { var publishResponse = await session.PublishAsync(publishRequest).ConfigureAwait(false); // loop thru all the data change notifications var dcns = publishResponse.NotificationMessage.NotificationData.OfType <DataChangeNotification>(); foreach (var dcn in dcns) { foreach (var min in dcn.MonitoredItems) { Console.WriteLine($"clientHandle: {min.ClientHandle}; value: {min.Value}"); } } publishRequest = new PublishRequest { SubscriptionAcknowledgements = new[] { new SubscriptionAcknowledgement { SequenceNumber = publishResponse.NotificationMessage.SequenceNumber, SubscriptionId = publishResponse.SubscriptionId } } }; } Console.ReadKey(true); Console.WriteLine("Step 9 - Delete the subscription."); var request = new DeleteSubscriptionsRequest { SubscriptionIds = new uint[] { id } }; await session.DeleteSubscriptionsAsync(request).ConfigureAwait(false); Console.WriteLine("Press any key to close the session..."); Console.ReadKey(true); Console.WriteLine("Step 10 - Close the session."); await session.CloseAsync(); } }
/// <summary> /// Opens a session with the remote endpoint. /// </summary> /// <param name="token">A cancellation token.</param> /// <returns>A task.</returns> private async Task OpenAsync(CancellationToken token = default(CancellationToken)) { await this.semaphore.WaitAsync(token).ConfigureAwait(false); try { if (this.RemoteEndpoint == null) { // If specific endpoint is not provided, use discovery to select endpoint with highest // security level. try { this.Logger?.LogInformation($"Discovering endpoints of '{this.discoveryUrl}'."); var getEndpointsRequest = new GetEndpointsRequest { EndpointUrl = this.discoveryUrl, ProfileUris = new[] { TransportProfileUris.UaTcpTransport } }; var getEndpointsResponse = await UaTcpDiscoveryClient.GetEndpointsAsync(getEndpointsRequest).ConfigureAwait(false); if (getEndpointsResponse.Endpoints == null || getEndpointsResponse.Endpoints.Length == 0) { throw new InvalidOperationException($"'{this.discoveryUrl}' returned no endpoints."); } this.RemoteEndpoint = getEndpointsResponse.Endpoints.OrderBy(e => e.SecurityLevel).Last(); this.Logger?.LogTrace($"Success discovering endpoints of '{this.discoveryUrl}'."); } catch (Exception ex) { this.Logger?.LogError($"Error discovering endpoints of '{this.discoveryUrl}'. {ex.Message}"); throw; } } // throw here to exit state machine. token.ThrowIfCancellationRequested(); // evaluate the user identity provider (may show a dialog). var userIdentity = await this.UserIdentityProvider(this.RemoteEndpoint); try { this.linkToken?.Dispose(); if (this.innerChannel != null && this.innerChannel.State != CommunicationState.Closed) { await this.innerChannel.AbortAsync(); } this.innerChannel = new UaTcpSessionChannel( this.LocalDescription, this.CertificateStore, userIdentity, this.RemoteEndpoint, this.loggerFactory, this.SessionTimeout, this.TimeoutHint, this.DiagnosticsHint, this.LocalReceiveBufferSize, this.LocalSendBufferSize, this.LocalMaxMessageSize, this.LocalMaxChunkCount); await this.innerChannel.OpenAsync(token).ConfigureAwait(false); this.linkToken = this.pendingRequests.LinkTo(this.innerChannel); //// create an internal subscription. //var subscriptionRequest = new CreateSubscriptionRequest //{ // RequestedPublishingInterval = DefaultPublishingInterval, // RequestedMaxKeepAliveCount = DefaultKeepaliveCount, // RequestedLifetimeCount = (uint)(this.SessionTimeout / DefaultPublishingInterval), // PublishingEnabled = true, // Priority = 0 //}; //var subscriptionResponse = await this.CreateSubscriptionAsync(subscriptionRequest).ConfigureAwait(false); //this.subscriptionId = subscriptionResponse.SubscriptionId; } catch (Exception ex) { this.Logger?.LogError($"Error opening channel with endpoint '{this.RemoteEndpoint.EndpointUrl}'. {ex.Message}"); throw; } } finally { this.semaphore.Release(); } }
public async Task TransferSubscriptions() { // get or add application certificate. var localCertificate = this.localDescription.GetCertificate(); if (localCertificate == null) { throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "Application certificate is missing."); } // discover available endpoints of server. var getEndpointsRequest = new GetEndpointsRequest { EndpointUrl = this.endpointUrl, ProfileUris = new[] { TransportProfileUris.UaTcpTransport } }; Console.WriteLine($"Discovering endpoints of '{getEndpointsRequest.EndpointUrl}'."); var getEndpointsResponse = await UaTcpDiscoveryClient.GetEndpointsAsync(getEndpointsRequest); var selectedEndpoint = getEndpointsResponse.Endpoints.OrderBy(e => e.SecurityLevel).Last(); IUserIdentity selectedUserIdentity = new UserNameIdentity("root", "secret"); var channel = new UaTcpSessionChannel( this.localDescription, localCertificate, selectedUserIdentity, selectedEndpoint); Console.WriteLine($"Creating session with endpoint '{channel.RemoteEndpoint.EndpointUrl}'."); Console.WriteLine($"SecurityPolicy: '{channel.RemoteEndpoint.SecurityPolicyUri}'."); Console.WriteLine($"SecurityMode: '{channel.RemoteEndpoint.SecurityMode}'."); await channel.OpenAsync(); Console.WriteLine($"Activated session '{channel.SessionId}'."); var req = new CreateSubscriptionRequest { RequestedPublishingInterval = 1000, RequestedMaxKeepAliveCount = 20, PublishingEnabled = true }; var res = await channel.CreateSubscriptionAsync(req); Console.WriteLine($"Created subscription '{res.SubscriptionId}'."); Console.WriteLine($"Aborting session '{channel.SessionId}'."); await channel.AbortAsync(); var channel2 = new UaTcpSessionChannel( this.localDescription, localCertificate, selectedUserIdentity, selectedEndpoint); await channel2.OpenAsync(); Console.WriteLine($"Activated session '{channel2.SessionId}'."); var req2 = new TransferSubscriptionsRequest { SubscriptionIds = new[] { res.SubscriptionId } }; var res2 = await channel2.TransferSubscriptionsAsync(req2); Console.WriteLine($"Transferred subscription result '{res2.Results[0].StatusCode}'."); Console.WriteLine($"Closing session '{channel2.SessionId}'."); await channel2.CloseAsync(); Assert.IsTrue(StatusCode.IsGood(res2.Results[0].StatusCode)); }