Пример #1
0
        /// <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;
            }
        }
Пример #2
0
        /// <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;
            }
        }
Пример #3
0
        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);
        }
Пример #5
0
        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();
        }
Пример #6
0
        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();
                }
            }
        }
Пример #7
0
        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);
        }
Пример #8
0
        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();
                }
            }
        }
Пример #9
0
        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;
            }));
        }
Пример #10
0
        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);
        }
Пример #11
0
        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);
        }
Пример #12
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");
        }
Пример #13
0
        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);
        }
Пример #14
0
        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();
        }
Пример #15
0
        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
                    //{
                    //}
                }
            }
        }
Пример #16
0
 /// <summary>
 /// Initializes the message with the body.
 /// </summary>
 public GetEndpointsMessage(GetEndpointsRequest GetEndpointsRequest)
 {
     this.GetEndpointsRequest = GetEndpointsRequest;
 }
Пример #17
0
        /// <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);
        }
Пример #18
0
        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
            }
        }
Пример #19
0
        /// <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();
            }
        }
Пример #20
0
        /// <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;
        }
Пример #21
0
        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
            }
        }
Пример #23
0
        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}");
                    }
                }
            }
        }
Пример #24
0
        private async Task <bool> TryConnect()
        {
            if (connection != null)
            {
                return(true);
            }

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

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

                GetEndpointsResponse endpoints = await UaTcpDiscoveryService.GetEndpointsAsync(getEndpointsRequest);

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

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

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

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

                await channel.OpenAsync();

                this.connection = channel;

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

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

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

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

                return(false);
            }
        }
Пример #25
0
        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();
            }
        }
Пример #26
0
        /// <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();
            }
        }
Пример #27
0
        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));
        }