Пример #1
0
        /// <summary>
        /// Displays the dialog.
        /// </summary>
        public ConfiguredEndpoint ShowDialog(ApplicationConfiguration configuration, bool createNew)
        {
            m_configuration = configuration;
            m_endpoint = null;

            // create a default collection if none provided.
            if (createNew)
            {
                ApplicationDescription server = new DiscoveredServerListDlg().ShowDialog(null, m_configuration);

                if (server != null)
                {
                    return new ConfiguredEndpoint(server, EndpointConfiguration.Create(configuration));
                }

                return null;
            }
            
            ServersCTRL.Initialize(null, configuration);
            
            OkBTN.Enabled = false;

            if (ShowDialog() != DialogResult.OK)
            {
                return null;
            }
  
            return m_endpoint;
        }
Пример #2
0
        private void ConfigureEndpoint(ConfiguredEndpoint endpoint)
        {
            EndpointComIdentity comIdentity = endpoint.ComIdentity;

            if (comIdentity == null)
            {
                comIdentity = new EndpointComIdentity();
                comIdentity.Specification = ComSpecification.DA;
                endpoint.ComIdentity = comIdentity;
            }

            string oldProgId = PseudoComServer.CreateProgIdFromUrl(endpoint.ComIdentity.Specification, endpoint.EndpointUrl.ToString());

            endpoint = new ConfiguredServerDlg().ShowDialog(endpoint, m_configuration);

            if (endpoint == null)
            {
                return;
            }

            if (String.IsNullOrEmpty(comIdentity.ProgId) || oldProgId == comIdentity.ProgId)
            {
                comIdentity.ProgId = PseudoComServer.CreateProgIdFromUrl(endpoint.ComIdentity.Specification, endpoint.EndpointUrl.ToString());

                if (comIdentity.Clsid == Guid.Empty)
                {
                    comIdentity.Clsid = Guid.NewGuid();
                }
            }

            m_endpoint = endpoint;
            EndpointTB.Text = m_endpoint.EndpointUrl.ToString();
        }
Пример #3
0
        /// <summary>
        /// Displays the dialog.
        /// </summary>
        public EndpointComIdentity ShowDialog(ConfiguredEndpoint endpoint)
        {
            if (endpoint == null) throw new ArgumentNullException("endpoint");

            m_comIdentity = endpoint.ComIdentity;

            // assign a default prog id/clsid.
            if (String.IsNullOrEmpty(m_comIdentity.ProgId))
            {
                m_comIdentity.ProgId = PseudoComServer.CreateProgIdFromUrl(ComSpecification.DA, endpoint.EndpointUrl.ToString());
                m_comIdentity.Clsid = ConfigUtils.CLSIDFromProgID(m_comIdentity.ProgId);

                if (m_comIdentity.Clsid == Guid.Empty)
                {
                    m_comIdentity.Clsid = Guid.NewGuid();
                }
            }

            SpecificationCB.SelectedItem = m_comIdentity.Specification;
            ClsidTB.Text  = m_comIdentity.Clsid.ToString();
            ProgIdTB.Text = m_comIdentity.ProgId;

            if (ShowDialog() != DialogResult.OK)
            {
                return null;
            }
                        
            return m_comIdentity;      
        }
        /// <summary>
        /// Displays the dialog.
        /// </summary>
        public ConfiguredEndpoint ShowDialog(ApplicationConfiguration configuration, bool createNew)
        {
            m_configuration = configuration;
            m_endpoint = null;

            // create a default collection if none provided.
            if (createNew)
            {
                ApplicationDescription server = new DiscoveredServerListDlg().ShowDialog(null, m_configuration);

                if (server != null)
                {
                    return new ConfiguredEndpoint(server, EndpointConfiguration.Create(configuration));
                }

                return null;
            }
            
            ServersCTRL.Initialize(null, configuration);
            
            OkBTN.IsEnabled = false;

            Popup myPopup = new Popup();
            myPopup.Child = this;
            myPopup.IsOpen = true;

            return m_endpoint;
        }
Пример #5
0
 /// <summary>
 /// Constructs a new instance of the session.
 /// </summary>
 /// <param name="channel">The channel used to communicate with the server.</param>
 /// <param name="configuration">The configuration for the client application.</param>
 /// <param name="endpoint">The endpoint use to initialize the channel.</param>
 public Session(
     ISessionChannel channel,
     ApplicationConfiguration configuration,
     ConfiguredEndpoint endpoint)
 :
     this(channel as ITransportChannel, configuration, endpoint, null)
 {
 }
Пример #6
0
 /// <summary>
 /// Constructs a new instance of the session.
 /// </summary>
 /// <param name="channel">The channel used to communicate with the server.</param>
 /// <param name="configuration">The configuration for the client application.</param>
 /// <param name="endpoint">The endpoint use to initialize the channel.</param>
 /// <param name="clientCertificate">The certificate to use for the client.</param>
 /// <remarks>
 /// The application configuration is used to look up the certificate if none is provided.
 /// The clientCertificate must have the private key. This will require that the certificate
 /// be loaded from a certicate store. Converting a DER encoded blob to a X509Certificate2
 /// will not include a private key.
 /// </remarks>
 public Session(
     ITransportChannel        channel, 
     ApplicationConfiguration configuration,
     ConfiguredEndpoint       endpoint,
     X509Certificate2         clientCertificate)
 :
     base(channel)
 {
     Initialize(channel, configuration, endpoint, clientCertificate); 
 }
Пример #7
0
        /// <summary>
        /// Loads the endpoint information from the registry.
        /// </summary>
        public static ConfiguredEndpoint Load(Guid clsid)
        {
            // load the configuration.
            ConfiguredEndpoint endpoint = LoadConfiguredEndpoint(clsid);

            // create a dummy configuration.
            if (endpoint == null)
            {
                ApplicationDescription server = new ApplicationDescription();

                server.ApplicationName = "(Missing Configuration File)";
                server.ApplicationType = ApplicationType.Server;
                server.ApplicationUri  = clsid.ToString();

                endpoint = new ConfiguredEndpoint(server, null);
            }

            // update the COM identity based on what is actually in the registry.
            endpoint.ComIdentity = new EndpointComIdentity();
            endpoint.ComIdentity.Clsid  = clsid;
            endpoint.ComIdentity.ProgId = ConfigUtils.ProgIDFromCLSID(clsid);
            
            List<Guid> categories = ConfigUtils.GetImplementedCategories(clsid);

            for (int ii = 0; ii < categories.Count; ii++)
            {
                if (categories[ii] == ConfigUtils.CATID_OPCDAServer20)
                {
                    endpoint.ComIdentity.Specification = ComSpecification.DA;
                    break;
                }

                if (categories[ii] == ConfigUtils.CATID_OPCDAServer30)
                {
                    endpoint.ComIdentity.Specification = ComSpecification.DA;
                    break;
                }

                if (categories[ii] == ConfigUtils.CATID_OPCAEServer10)
                {
                    endpoint.ComIdentity.Specification = ComSpecification.AE;
                    break;
                }

                if (categories[ii] == ConfigUtils.CATID_OPCHDAServer10)
                {
                    endpoint.ComIdentity.Specification = ComSpecification.HDA;
                    break;
                }
            }

            return endpoint;
        }
Пример #8
0
        /// <summary>
        /// Displays the dialog.
        /// </summary>
        public ConfiguredEndpoint ShowDialog(ApplicationConfiguration configuration, ConfiguredEndpoint endpoint)
        {
            m_configuration = configuration;
            m_endpoint = endpoint;

            if (ShowDialog() != DialogResult.OK)
            {
                return null;
            }

            return m_endpoint;
        }
Пример #9
0
        /// <summary>
        /// Initializes the node manager.
        /// </summary>
        public AggregationNodeManager(IServerInternal server, ApplicationConfiguration configuration, ConfiguredEndpoint endpoint, bool ownsTypeModel)
        :
            base(server, configuration, Namespaces.Aggregation, AggregationModel.Namespaces.Aggregation)
        {
            SystemContext.NodeIdFactory = this;

            m_configuration = configuration;
            m_endpoint = endpoint;
            m_ownsTypeModel = ownsTypeModel;
            m_clients = new Dictionary<NodeId, Opc.Ua.Client.Session>();
            m_mapper = new NamespaceMapper();
        }
        /// <summary>
        /// Displays the dialog.
        /// </summary>
        public ConfiguredEndpoint ShowDialog(ApplicationConfiguration configuration)
        {
            m_configuration = configuration;
            m_endpoint = null;

            ServersCTRL.Initialize(configuration);
            
            OkBTN.Enabled = false;
            ButtonsPN.Visible = true;
            
            if (ShowDialog() != DialogResult.OK)
            {
                return null;
            }
  
            return m_endpoint;
        }
Пример #11
0
        /// <summary>
        /// Connects the session if it is disconnected.
        /// </summary>
        public async Task ConnectSessionAsync(CancellationToken ct)
        {
            bool sessionLocked = false;

            try
            {
                EndpointDescription selectedEndpoint   = null;
                ConfiguredEndpoint  configuredEndpoint = null;
                sessionLocked = await LockSessionAsync();

                // if the session is already connected or connecting or shutdown in progress, return
                if (!sessionLocked || ct.IsCancellationRequested || State == SessionState.Connected || State == SessionState.Connecting)
                {
                    return;
                }

                Logger.Information($"Connect and monitor session and nodes on endpoint '{EndpointUrl.AbsoluteUri}'.");
                State = SessionState.Connecting;
                try
                {
                    // release the session to not block for high network timeouts.
                    ReleaseSession();
                    sessionLocked = false;

                    // start connecting
                    selectedEndpoint   = CoreClientUtils.SelectEndpoint(EndpointUrl.AbsoluteUri, UseSecurity);
                    configuredEndpoint = new ConfiguredEndpoint(null, selectedEndpoint, EndpointConfiguration.Create(OpcApplicationConfiguration));
                    uint timeout = SessionTimeout * ((UnsuccessfulConnectionCount >= OpcSessionCreationBackoffMax) ? OpcSessionCreationBackoffMax : UnsuccessfulConnectionCount + 1);
                    Logger.Information($"Create {(UseSecurity ? "secured" : "unsecured")} session for endpoint URI '{EndpointUrl.AbsoluteUri}' with timeout of {timeout} ms.");
                    OpcUaClientSession = await Session.Create(
                        OpcApplicationConfiguration,
                        configuredEndpoint,
                        true,
                        false,
                        OpcApplicationConfiguration.ApplicationName,
                        timeout,
                        new UserIdentity(new AnonymousIdentityToken()),
                        null);
                }
                catch (Exception e)
                {
                    Logger.Error(e, $"Session creation to endpoint '{EndpointUrl.AbsoluteUri}' failed {++UnsuccessfulConnectionCount} time(s). Please verify if server is up and {ProgramName} configuration is correct.");
                    State = SessionState.Disconnected;
                    OpcUaClientSession = null;
                    return;
                }
                finally
                {
                    if (OpcUaClientSession != null)
                    {
                        sessionLocked = await LockSessionAsync();

                        if (sessionLocked)
                        {
                            Logger.Information($"Session successfully created with Id {OpcUaClientSession.SessionId}.");
                            if (!selectedEndpoint.EndpointUrl.Equals(configuredEndpoint.EndpointUrl.AbsoluteUri, StringComparison.OrdinalIgnoreCase))
                            {
                                Logger.Information($"the Server has updated the EndpointUrl to '{selectedEndpoint.EndpointUrl}'");
                            }

                            // init object state and install keep alive
                            UnsuccessfulConnectionCount          = 0;
                            OpcUaClientSession.KeepAliveInterval = OpcKeepAliveIntervalInSec * 1000;
                            OpcUaClientSession.KeepAlive        += StandardClient_KeepAlive;

                            // fetch the namespace array and cache it. it will not change as long the session exists.
                            DataValue namespaceArrayNodeValue = OpcUaClientSession.ReadValue(VariableIds.Server_NamespaceArray);
                            _namespaceTable.Update(namespaceArrayNodeValue.GetValue <string[]>(null));

                            // show the available namespaces
                            Logger.Information($"The session to endpoint '{selectedEndpoint.EndpointUrl}' has {_namespaceTable.Count} entries in its namespace array:");
                            int i = 0;
                            foreach (var ns in _namespaceTable.ToArray())
                            {
                                Logger.Information($"Namespace index {i++}: {ns}");
                            }

                            // fetch the minimum supported item sampling interval from the server.
                            DataValue minSupportedSamplingInterval = OpcUaClientSession.ReadValue(VariableIds.Server_ServerCapabilities_MinSupportedSampleRate);
                            _minSupportedSamplingInterval = minSupportedSamplingInterval.GetValue(0);
                            Logger.Information($"The server on endpoint '{selectedEndpoint.EndpointUrl}' supports a minimal sampling interval of {_minSupportedSamplingInterval} ms.");
                            State = SessionState.Connected;
                        }
                        else
                        {
                            State = SessionState.Disconnected;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Logger.Error(e, "Error in ConnectSessions.");
            }
            finally
            {
                if (sessionLocked)
                {
                    ReleaseSession();
                }
            }
        }
Пример #12
0
        static async Task ConsoleSampleClient(string endpointURL, Op op, int count)
        {
            Console.WriteLine("1 - Create an Application Configuration.");
            var config = new ApplicationConfiguration {
                ApplicationName       = "UA Core Sample Client",
                ApplicationType       = ApplicationType.Client,
                ApplicationUri        = "urn:" + Utils.GetHostName() + ":OPCFoundation:CoreSampleClient",
                SecurityConfiguration = new SecurityConfiguration {
                    ApplicationCertificate = new CertificateIdentifier {
                        StoreType   = "Directory",
                        StorePath   = "OPC Foundation/CertificateStores/MachineDefault",
                        SubjectName = "UA Core Sample Client"
                    },
                    TrustedPeerCertificates = new CertificateTrustList {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/UA Applications",
                    },
                    TrustedIssuerCertificates = new CertificateTrustList {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/UA Certificate Authorities",
                    },
                    RejectedCertificateStore = new CertificateTrustList {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/RejectedCertificates",
                    },
                    NonceLength = 32,
                    AutoAcceptUntrustedCertificates = true
                },
                TransportConfigurations = new TransportConfigurationCollection(),
                TransportQuotas         = new TransportQuotas {
                    OperationTimeout = 120000
                },
                ClientConfiguration = new ClientConfiguration {
                    DefaultSessionTimeout = 120000
                }
            };

            await config.Validate(ApplicationType.Client);

            var haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null;

            if (!haveAppCertificate)
            {
                Console.WriteLine("    INFO: Creating new application certificate: {0}", config.ApplicationName);

                var certificate = CertificateFactory.CreateCertificate(
                    config.SecurityConfiguration.ApplicationCertificate.StoreType,
                    config.SecurityConfiguration.ApplicationCertificate.StorePath,
                    null,
                    config.ApplicationUri,
                    config.ApplicationName,
                    config.SecurityConfiguration.ApplicationCertificate.SubjectName,
                    null,
                    CertificateFactory.defaultKeySize,
                    DateTime.UtcNow - TimeSpan.FromDays(1),
                    CertificateFactory.defaultLifeTime,
                    CertificateFactory.defaultHashSize,
                    false,
                    null,
                    null
                    );

                config.SecurityConfiguration.ApplicationCertificate.Certificate = certificate;
            }

            haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null;

            if (haveAppCertificate)
            {
                config.ApplicationUri = Utils.GetApplicationUriFromCertificate(
                    config.SecurityConfiguration.ApplicationCertificate.Certificate);

                if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates)
                {
                    config.CertificateValidator.CertificateValidation += CertificateValidator_CertificateValidation;
                }
            }
            else
            {
                Console.WriteLine("    WARN: missing application certificate, using unsecure connection.");
            }

            var reconnectLoops = op == Op.All ? 1 : count;

            for (var i = 1; i <= reconnectLoops; i++)
            {
                Console.WriteLine("2 - Discover endpoints of {0}.", endpointURL);
                var endpointURI        = new Uri(endpointURL);
                var endpointCollection = DiscoverEndpoints(config, endpointURI, 10);
                var selectedEndpoint   = SelectUaTcpEndpoint(endpointCollection, haveAppCertificate);
                Console.WriteLine("    Selected endpoint uses: {0}",
                                  selectedEndpoint.SecurityPolicyUri.Substring(selectedEndpoint.SecurityPolicyUri.LastIndexOf('#') + 1));

                Console.WriteLine("3 - Create session with OPC UA server.");
                var endpointConfiguration = EndpointConfiguration.Create(config);
                var endpoint = new ConfiguredEndpoint(selectedEndpoint.Server, endpointConfiguration);
                endpoint.Update(selectedEndpoint);
                var session = await CreateSessionAsync(config, endpoint);

                if (op == Op.All || op == Op.Browse)
                {
                    Console.WriteLine("4 - Browse the OPC UA server namespace.");
                    var j = 0;

                    while (true)
                    {
                        var w = Stopwatch.StartNew();

                        var stack = new Stack <Tuple <string, ReferenceDescription> >();
                        session.Browse(
                            null,
                            null,
                            ObjectIds.ObjectsFolder,
                            0u,
                            BrowseDirection.Forward,
                            ReferenceTypeIds.HierarchicalReferences,
                            true,
                            (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method,
                            out var continuationPoint,
                            out var references);

                        Console.WriteLine(" DisplayName, BrowseName, NodeClass");
                        references.Reverse();
                        foreach (var rd in references)
                        {
                            stack.Push(Tuple.Create("", rd));
                        }

                        while (stack.Count > 0)
                        {
                            var browsed = stack.Pop();
                            session.Browse(
                                null,
                                null,
                                ExpandedNodeId.ToNodeId(browsed.Item2.NodeId, session.NamespaceUris),
                                0u,
                                BrowseDirection.Forward,
                                ReferenceTypeIds.HierarchicalReferences,
                                true,
                                (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method,
                                out continuationPoint,
                                out references);

                            references.Reverse();
                            foreach (var rd in references)
                            {
                                stack.Push(Tuple.Create(browsed.Item1 + "   ", rd));
                            }
                            Console.WriteLine($"{browsed.Item1}{(references.Count == 0 ? "-" : "+")} " +
                                              $"{browsed.Item2.DisplayName}, {browsed.Item2.BrowseName}, {browsed.Item2.NodeClass}");
                        }
                        Console.WriteLine($"   ....        took {w.ElapsedMilliseconds} ms...");
                        if (++j <= count)
                        {
                            break;
                        }

                        // Reconnect
                        session.Close();
                        session = await CreateSessionAsync(config, endpoint);
                    }
                }

                if (op == Op.All || op == Op.Subscribe)
                {
                    Console.WriteLine("5 - Create a subscription with publishing interval of 1 second.");
                    var subscription = new Subscription(session.DefaultSubscription)
                    {
                        PublishingInterval = 1000
                    };

                    Console.WriteLine("6 - Add a list of items (server current time and status) to the subscription.");
                    var list = new List <MonitoredItem> {
                        new MonitoredItem(subscription.DefaultItem)
                        {
                            DisplayName = "ServerStatusCurrentTime", StartNodeId = "i=2258"
                        }
                    };
                    list.ForEach(m => m.Notification += OnNotification);
                    subscription.AddItems(list);

                    Console.WriteLine("7 - Add the subscription to the session.");
                    session.AddSubscription(subscription);
                    subscription.Create();

                    await Task.Delay(1000 *(count + 1));

                    subscription.Delete(false);
                    subscription.Dispose();
                }

                session.Close();
            }
        }
Пример #13
0
        public static async Task ConsoleSampleClient(string endpointURL)
        {
            Console.WriteLine("1 - Create an Application Configuration.");
            var config = new ApplicationConfiguration()
            {
                ApplicationName       = "UA Sample Client",
                ApplicationType       = ApplicationType.Client,
                ApplicationUri        = "urn:localhost:OPCFoundation:SampleClient",
                SecurityConfiguration = new SecurityConfiguration
                {
                    ApplicationCertificate = new CertificateIdentifier
                    {
                        StoreType   = "Directory",
                        StorePath   = "./OPC Foundation/CertificateStores/MachineDefault",
                        SubjectName = Utils.Format("CN={0}, DC={1}", "UA Sample Client", Utils.GetHostName())
                    },
                    TrustedPeerCertificates = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "./OPC Foundation/CertificateStores/UA Applications",
                    },
                    TrustedIssuerCertificates = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "./OPC Foundation/CertificateStores/UA Certificate Authorities",
                    },
                    RejectedCertificateStore = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "./OPC Foundation/CertificateStores/RejectedCertificates",
                    },
                    NonceLength = 32,
                    AutoAcceptUntrustedCertificates = true
                },
                TransportConfigurations = new TransportConfigurationCollection(),
                TransportQuotas         = new TransportQuotas {
                    OperationTimeout = 15000
                },
                ClientConfiguration = new ClientConfiguration {
                    DefaultSessionTimeout = 60000
                }
            };
            await config.Validate(ApplicationType.Client);

            bool haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null;

            if (haveAppCertificate && config.SecurityConfiguration.AutoAcceptUntrustedCertificates)
            {
                config.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);
            }

            if (!haveAppCertificate)
            {
                Console.WriteLine("    WARN: missing application certificate, using unsecure connection.");
            }

            Console.WriteLine("2 - Discover endpoints of {0}.", endpointURL);
            Uri endpointURI        = new Uri(endpointURL);
            var endpointCollection = DiscoverEndpoints(config, endpointURI, 10);
            var selectedEndpoint   = SelectUaTcpEndpoint(endpointCollection, haveAppCertificate);

            Console.WriteLine("3 - Create a session with OPC UA server.");
            var endpointConfiguration = EndpointConfiguration.Create(config);
            var endpoint = new ConfiguredEndpoint(selectedEndpoint.Server, endpointConfiguration);

            endpoint.Update(selectedEndpoint);
            var session = await Session.Create(config, endpoint, true, ".Net Core OPC UA Console Client", 60000, null, null);

            Console.WriteLine("4 - Browse the OPC UA server namespace.");
            ReferenceDescriptionCollection references;

            Byte[] continuationPoint;

            references = session.FetchReferences(ObjectIds.ObjectsFolder);

            session.Browse(
                null,
                null,
                ObjectIds.ObjectsFolder,
                0u,
                BrowseDirection.Forward,
                ReferenceTypeIds.HierarchicalReferences,
                true,
                (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method,
                out continuationPoint,
                out references);

            Console.WriteLine(" DisplayName, BrowseName, NodeClass");
            foreach (var rd in references)
            {
                Console.WriteLine(" {0}, {1}, {2}", rd.DisplayName, rd.BrowseName, rd.NodeClass);
                ReferenceDescriptionCollection nextRefs;
                byte[] nextCp;
                session.Browse(
                    null,
                    null,
                    ExpandedNodeId.ToNodeId(rd.NodeId, session.NamespaceUris),
                    0u,
                    BrowseDirection.Forward,
                    ReferenceTypeIds.HierarchicalReferences,
                    true,
                    (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method,
                    out nextCp,
                    out nextRefs);

                foreach (var nextRd in nextRefs)
                {
                    Console.WriteLine("   + {0}, {1}, {2}", nextRd.DisplayName, nextRd.BrowseName, nextRd.NodeClass);
                }
            }

            Console.WriteLine("5 - Create a subscription with publishing interval of 1 second.");
            var subscription = new Subscription(session.DefaultSubscription)
            {
                PublishingInterval = 1000
            };

            Console.WriteLine("6 - Add a list of items (server current time and status) to the subscription.");
            var list = new List <MonitoredItem> {
                new MonitoredItem(subscription.DefaultItem)
                {
                    DisplayName = "ServerStatusCurrentTime", StartNodeId = "i=2258"
                }
            };

            list.ForEach(i => i.Notification += OnNotification);
            subscription.AddItems(list);

            Console.WriteLine("7 - Add the subscription to the session.");
            session.AddSubscription(subscription);
            subscription.Create();

            Console.WriteLine("8 - Running...Press any key to exit...");
            Console.ReadKey(true);
        }
Пример #14
0
 /// <summary>
 /// Saves the UA endpoint information associated the CLSID.
 /// </summary>
 /// <param name="clsid">The CLSID used to activate the COM server.</param>
 /// <param name="endpoint">The endpoint.</param>
 private static void SaveConfiguredEndpoint(Guid clsid, ConfiguredEndpoint endpoint)
 {
     SaveConfiguredEndpointToFile(clsid, endpoint);
 }
        private async void ConnectButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // get selected endpoint.
                ConfiguredEndpoint endpoint = SelectedEndpoint;

                if (endpoint == null)
                {
                    return;
                }

                // raise event.
                if (m_ConnectEndpoint != null)
                {
                    ConnectEndpointEventArgs args = new ConnectEndpointEventArgs(endpoint, true);

                    await m_ConnectEndpoint(this, args);

                    // save endpoint in drop down.
                    if (args.UpdateControl)
                    {
                        // must update the control because the display text may have changed.
                        Initialize(m_endpoints, m_configuration);
                        SelectedEndpoint = endpoint;
                    }
                }
            }
            catch (Exception exception)
            {
                GuiUtils.HandleException(String.Empty, GuiUtils.CallerName(), exception);
            }
        }
Пример #16
0
        /// <summary>
        /// Runs the test in a background thread.
        /// </summary>
        private void DoTest(ConfiguredEndpoint endpoint)
        {
            PerformanceTestResult result = new PerformanceTestResult(endpoint, 100);

            result.Results.Add(1, -1);
            result.Results.Add(10, -1);
            result.Results.Add(50, -1);
            result.Results.Add(100, -1);
            result.Results.Add(250, -1);
            result.Results.Add(500, -1);

            try
            {
                // update the endpoint.
                if (endpoint.UpdateBeforeConnect)
                {
                    BindingFactory bindingFactory = BindingFactory.Create(m_configuration, m_messageContext);
                    endpoint.UpdateFromServer(bindingFactory);
                }

                SessionClient client = null;

                Uri url = new Uri(endpoint.Description.EndpointUrl);

                ITransportChannel channel = SessionChannel.Create(
                    m_configuration,
                    endpoint.Description,
                    endpoint.Configuration,
                    m_clientCertificate,
                    m_messageContext);

                client = new SessionClient(channel);

                List <int> requestSizes = new List <int>(result.Results.Keys);

                for (int ii = 0; ii < requestSizes.Count; ii++)
                {
                    // update the progress indicator.
                    TestProgress((ii * 100) / requestSizes.Count);

                    lock (m_lock)
                    {
                        if (!m_running)
                        {
                            break;
                        }
                    }

                    int count = requestSizes[ii];

                    // initialize request.
                    RequestHeader requestHeader = new RequestHeader();
                    requestHeader.ReturnDiagnostics = 5000;

                    ReadValueIdCollection nodesToRead = new ReadValueIdCollection(count);

                    for (int jj = 0; jj < count; jj++)
                    {
                        ReadValueId item = new ReadValueId();

                        item.NodeId      = new NodeId((uint)jj, 1);
                        item.AttributeId = Attributes.Value;

                        nodesToRead.Add(item);
                    }

                    // ensure valid connection.
                    DataValueCollection      results         = null;
                    DiagnosticInfoCollection diagnosticInfos = null;

                    client.Read(
                        requestHeader,
                        0,
                        TimestampsToReturn.Both,
                        nodesToRead,
                        out results,
                        out diagnosticInfos);

                    if (results.Count != count)
                    {
                        throw new ServiceResultException(StatusCodes.BadUnknownResponse);
                    }

                    // do test.
                    DateTime start = DateTime.UtcNow;

                    for (int jj = 0; jj < result.Iterations; jj++)
                    {
                        client.Read(
                            requestHeader,
                            0,
                            TimestampsToReturn.Both,
                            nodesToRead,
                            out results,
                            out diagnosticInfos);

                        if (results.Count != count)
                        {
                            throw new ServiceResultException(StatusCodes.BadUnknownResponse);
                        }
                    }

                    DateTime finish = DateTime.UtcNow;

                    long    totalTicks          = finish.Ticks - start.Ticks;
                    decimal averageMilliseconds = ((((decimal)totalTicks) / ((decimal)result.Iterations))) / ((decimal)TimeSpan.TicksPerMillisecond);
                    result.Results[requestSizes[ii]] = (double)averageMilliseconds;
                }
            }
            finally
            {
                TestComplete(result);
            }
        }
Пример #17
0
        private async Task <bool> Connect()
        {
            try
            {
                string  path = config.ServerPath;
                Boolean cert = config.UseCertificate;


                var configSert = new ApplicationConfiguration()
                {
                    ApplicationName       = "ScadaCommSvc",
                    ApplicationUri        = "urn:MAIN:OPCUA:SimulationServer",
                    ApplicationType       = ApplicationType.Client,
                    SecurityConfiguration = new SecurityConfiguration
                    {
                        ApplicationCertificate = new CertificateIdentifier {
                            StoreType = @"Directory", StorePath = @"%CommonApplicationData%\OPC Foundation\CertificateStores\MachineDefault", SubjectName = "CN=SimulationServer, C=FR, O= Prosys OPC, DC=MAIN"
                        },
                        TrustedIssuerCertificates = new CertificateTrustList {
                            StoreType = @"Directory", StorePath = @"%CommonApplicationData%\OPC Foundation\CertificateStores\UA Certificate Authorities"
                        },
                        TrustedPeerCertificates = new CertificateTrustList {
                            StoreType = @"Directory", StorePath = @"%CommonApplicationData%\OPC Foundation\CertificateStores\UA Applications"
                        },
                        RejectedCertificateStore = new CertificateTrustList {
                            StoreType = @"Directory", StorePath = @"%CommonApplicationData%\OPC Foundation\CertificateStores\RejectedCertificates"
                        },
                        AutoAcceptUntrustedCertificates = true,
                        AddAppCertToTrustedStore        = true
                    },
                    TransportConfigurations = new TransportConfigurationCollection(),
                    TransportQuotas         = new TransportQuotas {
                        OperationTimeout = 15000
                    },
                    ClientConfiguration = new ClientConfiguration {
                        DefaultSessionTimeout = 60000
                    },
                    TraceConfiguration = new TraceConfiguration()
                };
                configSert.Validate(ApplicationType.Client).GetAwaiter().GetResult();
                if (configSert.SecurityConfiguration.AutoAcceptUntrustedCertificates)
                {
                    configSert.CertificateValidator.CertificateValidation += (s, e) => { e.Accept = (e.Error.StatusCode == StatusCodes.BadCertificateUntrusted); };
                }

                var application = new ApplicationInstance
                {
                    ApplicationName          = "ScadaCommSvc",
                    ApplicationType          = ApplicationType.Client,
                    ApplicationConfiguration = configSert
                };
                application.CheckApplicationInstanceCertificate(false, 2048).GetAwaiter().GetResult();


                if (string.IsNullOrEmpty(path))
                {
                    throw new Exception(Localization.UseRussian ? "сервер не задан" : "server is undefined");
                }

                EndpointDescription   selectedEndpoint      = CoreClientUtils.SelectEndpoint(path, cert, 15000);
                EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(configSert /*m_configuration*/);
                ConfiguredEndpoint    endpoint = new ConfiguredEndpoint(null, selectedEndpoint, endpointConfiguration);

                m_session = await Opc.Ua.Client.Session.Create(/*m_configuration*/ configSert, endpoint, false, "KpOpcUA Demo", 60000, /*new UserIdentity(new AnonymousIdentityToken())*/ null, null);

                m_session.KeepAlive += Client_KeepAlive;

                return(true);
            }
            catch (Exception ex)
            {
                WriteToLog((Localization.UseRussian ?
                            "Ошибка при соединении с OPC-сервером: " :
                            "Error connecting to OPC UA server: ") + ex.Message);
                return(false);
            }
        }
Пример #18
0
        /// <summary>
        /// Creates a session with the endpoint.
        /// </summary>
        public Session Connect(ConfiguredEndpoint endpoint)
        {
            if (endpoint == null)
            {
                throw new ArgumentNullException("endpoint");
            }

            EndpointDescriptionCollection availableEndpoints = null;

            // check if the endpoint needs to be updated.
            if (endpoint.UpdateBeforeConnect)
            {
                ConfiguredServerDlg configurationDialog = new ConfiguredServerDlg();
                endpoint = configurationDialog.ShowDialog(endpoint, m_configuration);

                if (endpoint == null)
                {
                    return(null);
                }
                availableEndpoints = configurationDialog.AvailableEnpoints;
            }

            m_endpoint = endpoint;

            // copy the message context.
            m_messageContext = m_configuration.CreateMessageContext();


            X509Certificate2           clientCertificate      = null;
            X509Certificate2Collection clientCertificateChain = null;

            if (endpoint.Description.SecurityPolicyUri != SecurityPolicies.None)
            {
                if (m_configuration.SecurityConfiguration.ApplicationCertificate == null)
                {
                    throw ServiceResultException.Create(StatusCodes.BadConfigurationError, "ApplicationCertificate must be specified.");
                }

                clientCertificate = m_configuration.SecurityConfiguration.ApplicationCertificate.Find(true);

                if (clientCertificate == null)
                {
                    throw ServiceResultException.Create(StatusCodes.BadConfigurationError, "ApplicationCertificate cannot be found.");
                }

                //load certificate chain
                //clientCertificateChain = new X509Certificate2Collection(clientCertificate);
                //List<CertificateIdentifier> issuers = new List<CertificateIdentifier>();
                //m_configuration.CertificateValidator.GetIssuers(clientCertificate, issuers);
                //for (int i = 0; i < issuers.Count; i++)
                //{
                //    clientCertificateChain.Add(issuers[i].Certificate);
                //}
            }

            // create the channel.
            ITransportChannel channel = SessionChannel.Create(
                m_configuration,
                endpoint.Description,
                endpoint.Configuration,
                //clientCertificateChain,
                clientCertificate,
                m_messageContext);

            // create the session.
            return(Connect(endpoint, channel, availableEndpoints));
        }
Пример #19
0
        /// <summary>
        /// Checks if there is an active OPC UA session for the provided browser session. If the persisted OPC UA session does not exist,
        /// a new OPC UA session to the given endpoint URL is established.
        /// </summary>
        public async Task <Session> GetSessionAsync(string sessionID, string endpointURL)
        {
            if (string.IsNullOrEmpty(sessionID) || string.IsNullOrEmpty(endpointURL))
            {
                return(null);
            }

            OpcSessionCacheData entry;

            if (OpcSessionCache.TryGetValue(sessionID, out entry))
            {
                if (entry.OPCSession != null)
                {
                    if (entry.OPCSession.Connected)
                    {
                        return(entry.OPCSession);
                    }

                    try
                    {
                        entry.OPCSession.Close(500);
                    }
                    catch
                    {
                    }
                    entry.OPCSession = null;
                }
            }
            else
            {
                // create a new entry
                OpcSessionCacheData newEntry = new OpcSessionCacheData {
                    EndpointURL = endpointURL
                };
                OpcSessionCache.TryAdd(sessionID, newEntry);
            }

            Uri endpointURI = new Uri(endpointURL);
            EndpointDescriptionCollection endpointCollection    = DiscoverEndpoints(_configuration, endpointURI, 10);
            EndpointDescription           selectedEndpoint      = SelectUaTcpEndpoint(endpointCollection);
            EndpointConfiguration         endpointConfiguration = EndpointConfiguration.Create(_configuration);
            ConfiguredEndpoint            endpoint = new ConfiguredEndpoint(selectedEndpoint.Server, endpointConfiguration);

            endpoint.Update(selectedEndpoint);

            // Check if we have a cached endpoint with the same URL and use that one instead
            foreach (ConfiguredEndpoint cachedEndpoint in OpcCachedEndpoints)
            {
                if (cachedEndpoint.EndpointUrl.AbsoluteUri.Equals(endpointURL, StringComparison.InvariantCultureIgnoreCase))
                {
                    endpoint = cachedEndpoint;
                    break;
                }
            }

            Session session = await Session.Create(
                _configuration,
                endpoint,
                true,
                false,
                sessionID,
                60000,
                new UserIdentity(new AnonymousIdentityToken()),
                null);

            if (session != null)
            {
                session.KeepAlive += new KeepAliveEventHandler(StandardClient_KeepAlive);

                // Update our cache data
                if (OpcSessionCache.TryGetValue(sessionID, out entry))
                {
                    if (string.Equals(entry.EndpointURL, endpointURL, StringComparison.InvariantCultureIgnoreCase))
                    {
                        OpcSessionCacheData newValue = new OpcSessionCacheData
                        {
                            CertThumbprint = entry.CertThumbprint,
                            EndpointURL    = entry.EndpointURL,
                            Trusted        = entry.Trusted,
                            OPCSession     = session
                        };
                        OpcSessionCache.TryUpdate(sessionID, newValue, entry);
                    }
                }
            }

            return(session);
        }
Пример #20
0
        /// <summary>
        /// Determines whether the endpoint is selected.
        /// </summary>
        /// <param name="endpoint">The endpoint.</param>
        /// <param name="selection">The selection.</param>
        /// <param name="useXml">if set to <c>true</c> then the XML encoding is used..</param>
        /// <returns>
        ///     <c>true</c> if the endpoint selected; otherwise, <c>false</c>.
        /// </returns>
        private bool IsEndpointSelected(ConfiguredEndpoint endpoint, EndpointSelection selection, bool useXml)
        {
            if (selection == EndpointSelection.Single)
            {
                return(true);
            }

            // don't allow pipes when testing across a network.
            if (endpoint.EndpointUrl.Scheme == Utils.UriSchemeNetPipe)
            {
                if (!String.Equals(endpoint.EndpointUrl.DnsSafeHost, System.Net.Dns.GetHostName(),
                                   StringComparison.OrdinalIgnoreCase))
                {
                    if (!String.Equals(endpoint.EndpointUrl.DnsSafeHost, "localhost",
                                       StringComparison.OrdinalIgnoreCase))
                    {
                        return(false);
                    }
                }
            }

            if (selection == EndpointSelection.All)
            {
                return(true);
            }

            switch (selection)
            {
            case EndpointSelection.AllEncryptAndSign: {
                if (endpoint.Description.SecurityMode == MessageSecurityMode.SignAndEncrypt)
                {
                    return(true);
                }

                return(false);
            }

            case EndpointSelection.AllSign: {
                if (endpoint.Description.SecurityMode == MessageSecurityMode.Sign)
                {
                    return(true);
                }

                return(false);
            }

            case EndpointSelection.AllNoSecurity: {
                if (endpoint.Description.SecurityMode == MessageSecurityMode.None)
                {
                    return(true);
                }

                return(false);
            }

            case EndpointSelection.AllHttpBinary: {
                if (!useXml && endpoint.EndpointUrl.Scheme != Utils.UriSchemeOpcTcp)
                {
                    return(true);
                }

                return(false);
            }

            case EndpointSelection.AllHttpXml: {
                if (useXml && endpoint.EndpointUrl.Scheme != Utils.UriSchemeOpcTcp)
                {
                    return(true);
                }

                return(false);
            }

            case EndpointSelection.AllUaTcp: {
                if (endpoint.EndpointUrl.Scheme == Utils.UriSchemeOpcTcp)
                {
                    return(true);
                }

                return(false);
            }
            }

            return(true);
        }
Пример #21
0
        static void callMethod()
        {
            EndpointConfiguration ec = new EndpointConfiguration();
            EndpointDescription   endpointDescription = new EndpointDescription("opc.tcp://localhost:58710/PCoUaServer");

            configuredEndpoint = new ConfiguredEndpoint(new ConfiguredEndpointCollection(), endpointDescription);
            configuredEndpoint.Configuration.UseBinaryEncoding = true;
            configuredEndpoint.Description.UserIdentityTokens.Add(new UserTokenPolicy(UserTokenType.Anonymous));

            applicationConfiguration = new ApplicationConfiguration();
            applicationConfiguration.ApplicationType = ApplicationType.Client;
            applicationConfiguration.ApplicationName = "SAPClientSession";
            applicationConfiguration.ApplicationUri  = "SAPClientSession";
            SecurityConfiguration secConfig = new SecurityConfiguration();

            secConfig.ApplicationCertificate = GetPCoDefaultCertificate();
            applicationConfiguration.SecurityConfiguration = secConfig;
            TransportQuotas transportQuotas = new TransportQuotas();

            applicationConfiguration.TransportQuotas = transportQuotas;
            ClientConfiguration clientConfiguration = new ClientConfiguration();

            applicationConfiguration.ClientConfiguration = clientConfiguration;
            applicationConfiguration.Validate(ApplicationType.Client);

            CertificateValidationOptions certOptions = applicationConfiguration.SecurityConfiguration.TrustedPeerCertificates.ValidationOptions;

            certOptions |= CertificateValidationOptions.SuppressCertificateExpired;
            certOptions |= CertificateValidationOptions.SuppressHostNameInvalid;

            securelyUpdateEndpointConfiguration(configuredEndpoint, applicationConfiguration);
            applicationConfiguration.CertificateValidator.CertificateValidation += CertificateValidator_CertificateValidation;

            clientSession = Session.Create(
                applicationConfiguration,
                configuredEndpoint,
                false, false,
                sessionName,
                sessionTimeout,
                identity,
                null, null);

            clientSession.ReturnDiagnostics = DiagnosticsMasks.All;

            clientSession.KeepAliveInterval = 2 * 1000;

            try
            {
                int maxNodesPerReadRuntimeInformation = Convert.ToInt32(clientSession.ReadValue(Opc.Ua.VariableIds.Server_ServerCapabilities_OperationLimits_MaxNodesPerRead).Value);
                //if (tracer.Switch.ShouldTrace(TraceEventType.Verbose))
                {
                    String message = String.Format("Retrieved operation limits for reading ({0}) from server", maxNodesPerReadRuntimeInformation);
                    //TraceUtility.LogData(tracer, TraceUtility.EventId.E2718, TraceEventType.Verbose, message);
                }
            }
            catch (Exception)
            {
                // the value is not supplied or an error occured.
                {
                    String message = String.Format("Could not retrieve operation limits for reading from server");
                }
            }

            //NodeId nodeiD = clientSession.ReadNode();
            var v11 = clientSession.Call((NodeId)("ns=2;s=348259fa-527e-4d5e-bde1-f5e1ccf01d61"), (NodeId)("ns=2;s=aef01ad4-3fe3-4836-83d0-cc808735f530"), new object[] { });

            //BrowseResultCollection browseResultCollection;
            //DiagnosticInfoCollection diagnosticInfos;
            //NodeId currentNode = FindCurrentNode(null, clientSession, configuredEndpoint);
            //uint nodeClassMask = (uint)(NodeClass.Object | NodeClass.Method);
            //BrowseDescriptionCollection nodesToBrowse = PrepareBrowseDescriptionCollection(currentNode, nodeClassMask);
            //clientSession.Browse(
            //        null,
            //        null,
            //        100,
            //        nodesToBrowse,
            //        out browseResultCollection,
            //        out diagnosticInfos);

            //var app_Base_To_method = clientSession.ReadNode((NodeId)(browseResultCollection[0].References[1].NodeId.ToString()));

            //ClientBase.ValidateResponse(browseResultCollection, nodesToBrowse);
            //ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToBrowse);
            //ReferenceDescriptionCollection references;

            ////int resultLength = 0;

            //foreach (BrowseResult br in browseResultCollection)
            //{
            //    /// TODO: Store the continuation point as member of UaBrowser (new class) and
            //    /// use it when we are called with BrowseNext mode.
            //    byte[] continuationPoint = br.ContinuationPoint;
            //    while (continuationPoint != null)
            //    {
            //        byte[] revisedContinuationPoint;
            //        ResponseHeader rc = clientSession.BrowseNext(
            //            null,
            //            false,
            //            continuationPoint,
            //            out revisedContinuationPoint,
            //            out references);
            //        br.References.AddRange(references);
            //        //resultLength += br.References.Count;
            //        if (br.References.Count >= 100)
            //        {
            //            //int removeCount = br.References.Count - maxRows;
            //            br.References.RemoveRange((int)100, (int)br.References.Count - (int)100);
            //            continuationPoint = revisedContinuationPoint;
            //            if (continuationPoint != null)
            //            {
            //                // release continuation point on server
            //                rc = clientSession.BrowseNext(
            //                        null,
            //                        true, // <- release cp
            //                        continuationPoint,
            //                        out revisedContinuationPoint,
            //                        out references);
            //            }
            //            break;

            //        }
            //        continuationPoint = revisedContinuationPoint;
            //    }
            //}

            ////ns=2;s=a72e725d-6be7-4a17-bcd4-0be67b6cbfbe
            ////browseResultCollection[0].References[1].NodeId;


            //var vrere = clientSession.ReadNode((NodeId)("ns=2;s=50bcabac-623b-43ea-8f69-17b12d533166"));

            //nodesToBrowse = PrepareBrowseDescriptionCollection
            //    ((NodeId)(browseResultCollection[0].References[1].NodeId.ToString()), nodeClassMask);
            //clientSession.Browse(
            //        null,
            //        null,
            //        100,
            //        nodesToBrowse,
            //        out browseResultCollection,
            //        out diagnosticInfos);

            //var application_method = clientSession.ReadNode((NodeId)(browseResultCollection[1].References[0].NodeId.ToString()));
            //var v1 = clientSession.FetchReferences((NodeId)(browseResultCollection[1].References[0].NodeId.ToString()));
            ////var v2 = clientSession.ReadValue((NodeId)(browseResultCollection[1].References[0].NodeId.ToString()));

            //nodesToBrowse = PrepareBrowseDescriptionCollection
            //    ((NodeId)(browseResultCollection[1].References[0].NodeId.ToString()), nodeClassMask);
            //clientSession.Browse(null, null, 100, nodesToBrowse, out browseResultCollection, out diagnosticInfos);

            //var v = clientSession.ReadNode((NodeId)(browseResultCollection[5].References[0].NodeId.ToString()));
            //v1 = clientSession.FetchReferences((NodeId)(browseResultCollection[5].References[0].NodeId.ToString()));
            ////v2 = clientSession.ReadValue((NodeId)(browseResultCollection[5].References[0].NodeId.ToString()));


            ////TypeInfo.GetSystemType(dataType, clientSession.Factory);
            //nodeClassMask = (uint)(NodeClass.Object | NodeClass.Method | NodeClass.View |
            //    NodeClass.VariableType | NodeClass.Variable | NodeClass.ObjectType);
            //nodesToBrowse = PrepareBrowseDescriptionCollection
            //    ((NodeId)(browseResultCollection[5].References[0].NodeId.ToString()), nodeClassMask);
            //var v5 = clientSession.ReadNode((NodeId)(browseResultCollection[5].References[0].NodeId.ToString()));
            //clientSession.Browse(null, null, 100, nodesToBrowse, out browseResultCollection, out diagnosticInfos);


            //BrowsePathCollection pathsToArgs = new BrowsePathCollection();

            //BrowsePath pathToInputArgs = new BrowsePath();
            //pathToInputArgs.StartingNode = application_method.NodeId;
            //pathToInputArgs.RelativePath = new RelativePath(ReferenceTypeIds.HasProperty, false, true, new QualifiedName("InputArguments"));

            //pathsToArgs.Add(pathToInputArgs);

            //BrowsePath pathToOutputArgs = new BrowsePath();
            //pathToOutputArgs.StartingNode = application_method.NodeId;
            //pathToOutputArgs.RelativePath = new RelativePath(ReferenceTypeIds.HasProperty, false, true, new QualifiedName("OutputArguments"));

            //pathsToArgs.Add(pathToOutputArgs);

            //BrowsePathResultCollection results = null;
            //// Get the nodeId of the input argument
            //ResponseHeader responseHeader = clientSession.TranslateBrowsePathsToNodeIds(
            //    null,
            //    pathsToArgs,
            //    out results,
            //    out diagnosticInfos
            //    );

            //ArgumentCollection[] arguments = new ArgumentCollection[2];
            //for (int i = 0; i < 2; i++)
            //{
            //    arguments[i] = new ArgumentCollection();
            //    foreach (BrowsePathTarget bptarget in results[i].Targets)
            //    {
            //        DataValueCollection readResults = null;

            //        ReadValueId nodeToRead = new ReadValueId();
            //        nodeToRead.NodeId = (NodeId)bptarget.TargetId;
            //        nodeToRead.AttributeId = Attributes.Value;
            //        ReadValueIdCollection nodesToRead = new ReadValueIdCollection();
            //        nodesToRead.Add(nodeToRead);

            //        DiagnosticInfoCollection readDiagnoistcInfos = null;

            //        clientSession.Read(
            //            null,
            //            0,
            //            TimestampsToReturn.Neither,
            //            nodesToRead,
            //            out readResults,
            //            out readDiagnoistcInfos
            //            );

            //        ExtensionObject[] exts = (ExtensionObject[])readResults[0].Value;
            //        for (int j = 0; j < exts.Length; ++j)
            //        {
            //            ExtensionObject ext = exts[j];
            //            arguments[i].Add((Argument)ext.Body);
            //        }

            //    }
            //}
            // establish keep-alive
            //clientSession.KeepAlive += new KeepAliveEventHandler(clientSession_KeepAlive);
        }
Пример #22
0
        /// <summary>
        /// Runs the testcases against the endpoint.
        /// </summary>
        /// <param name="endpoint">The endpoint to test.</param>
        /// <param name="testcases">The testcases to run.</param>
        public void Run(ConfiguredEndpoint endpoint, ServerTestConfiguration testConfiguration)
        {
            // save the test configuration.
            m_testConfiguration = testConfiguration;
            m_stopped           = false;

            // create the binding factory.
            m_bindingFactory = BindingFactory.Create(m_configuration, m_messageContext);

            while (!m_stopped)
            {
                try {
                    Report("Test run started.");

                    // update from server.
                    if (endpoint.UpdateBeforeConnect)
                    {
                        endpoint.UpdateFromServer(m_bindingFactory);
                        Report("Updated endpoint from the discovery endpoint.");
                    }

                    // validate the server certificate.
                    byte[] certificateData = endpoint.Description.ServerCertificate;

                    try {
                        X509Certificate2 certificate = CertificateFactory.Create(certificateData, true);
                        m_configuration.CertificateValidator.Validate(certificate);
                    } catch (ServiceResultException e) {
                        if (e.StatusCode != StatusCodes.BadCertificateUntrusted)
                        {
                            throw new ServiceResultException(e, StatusCodes.BadCertificateInvalid);
                        }

                        // automatically trust the certificate if it is untrusted.
                        m_configuration.CertificateValidator.Update(m_configuration.SecurityConfiguration);
                    }

                    m_defaultEndpoint = endpoint;

                    // fetch all endpoints from the server.
                    m_endpoints = GetEndpoints(endpoint);
                    Report("Fetched all endpoints supported by the server.");
                } catch (Exception e) {
                    Report(e, "Could not connect to server");
                    return;
                }

                m_endpointCount       = 0;
                m_totalEndpointCount  = 0;
                m_testCount           = 0;
                m_failedTestCount     = 0;
                m_iterationCount      = 0;
                m_totalIterationCount = 0;

                uint totalCount    = 0;
                uint failedCount   = 0;
                uint endpointCount = 0;

                if (m_testConfiguration.EndpointSelection != EndpointSelection.Single)
                {
                    EndpointSelection selection = m_testConfiguration.EndpointSelection;

                    foreach (ConfiguredEndpoint current in m_endpoints.Endpoints)
                    {
                        if (IsEndpointSelected(current, selection, false))
                        {
                            m_totalEndpointCount++;
                        }

                        if (current.Description.EncodingSupport == BinaryEncodingSupport.Optional)
                        {
                            if (IsEndpointSelected(current, selection, true))
                            {
                                m_totalEndpointCount++;
                            }
                        }
                    }

                    foreach (ConfiguredEndpoint current in m_endpoints.Endpoints)
                    {
                        if (IsEndpointSelected(current, selection, false))
                        {
                            m_endpointCount++;

                            // check if test stopped.
                            if (m_stopped)
                            {
                                break;
                            }

                            DoTestForEndpoint(current, ref totalCount, ref failedCount);
                            endpointCount++;
                        }

                        if (current.Description.EncodingSupport == BinaryEncodingSupport.Optional)
                        {
                            if (IsEndpointSelected(current, selection, true))
                            {
                                m_endpointCount++;

                                // check if test stopped.
                                if (m_stopped)
                                {
                                    break;
                                }

                                current.Configuration.UseBinaryEncoding = !current.Configuration.UseBinaryEncoding;
                                DoTestForEndpoint(current, ref totalCount, ref failedCount);
                                endpointCount++;
                            }
                        }
                    }
                }
                else
                {
                    m_endpointCount++;
                    m_totalEndpointCount = 1;

                    DoTestForEndpoint(m_defaultEndpoint, ref totalCount, ref failedCount);
                    endpointCount++;
                }

                if (failedCount > 0)
                {
                    Report("WARNING: {0} tests failed. {1} tests run.", failedCount, totalCount);
                }
                else
                {
                    Report("{0} tests completed successfully for {1} endpoints.", totalCount, endpointCount);
                    DumpPerfData();
                }

                if (!m_testConfiguration.Continuous)
                {
                    break;
                }
            }
        }
Пример #23
0
        /// <summary>Establishes the connection to an OPC UA server.</summary>
        /// <param name="url">The Url of the endpoint.</param>
        /// <returns>Result code.</returns>
        /// <exception cref="Exception">Throws and forwards any exception with short error description.</exception>
        public void Connect(string Url)
        {
            try
            {
                // Create the configuration.
                ApplicationConfiguration configuration = Helpers.CreateClientConfiguration();

                // Create the endpoint description.
                EndpointDescription endpointDescription = Helpers.CreateEndpointDescription(Url);

                // Create the endpoint configuration (use the application configuration to provide default values).
                EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(configuration);

                // The default timeout for a requests sent using the channel.
                endpointConfiguration.OperationTimeout = 300000;

                // Use the pure binary encoding on the wire.
                endpointConfiguration.UseBinaryEncoding = true;

                // Create the endpoint.
                ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration);

                // Create the binding factory.
                BindingFactory bindingFactory = BindingFactory.Create(configuration, new ServiceMessageContext());


                // Update endpoint description using the discovery endpoint.
                if (endpoint.UpdateBeforeConnect)
                {
                    endpoint.UpdateFromServer(bindingFactory);
                    endpointDescription   = endpoint.Description;
                    endpointConfiguration = endpoint.Configuration;
                }

                X509Certificate2 clientCertificate = configuration.SecurityConfiguration.ApplicationCertificate.Find();

                // Set up a callback to handle certificate validation errors.
                configuration.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);

                // Initialize the channel which will be created with the server.
                SessionChannel channel = SessionChannel.Create(
                    configuration,
                    endpointDescription,
                    endpointConfiguration,
                    bindingFactory,
                    clientCertificate,
                    null);

                // Wrap the channel with the session object.
                // This call will fail if the server does not trust the client certificate.
                m_Session = new Session(channel, configuration, endpoint);
                m_Session.ReturnDiagnostics = DiagnosticsMasks.All;

                // Register keep alive callback.
                m_Session.KeepAlive += new KeepAliveEventHandler(Session_KeepAlive);

                UserIdentity identity = new UserIdentity();

                // Create the session. This actually connects to the server.
                // Passing null for the user identity will create an anonymous session.
                m_Session.Open("pdmRead", identity);
            }
            catch (Exception e)
            {
                throw e;
            }
        }
Пример #24
0
        static void Main(string[] args)
        {
            VariableBrowsePaths = new List <string>();
            VariableBrowsePaths.Add("/6:Data/6:Dynamic/6:Scalar/6:Int32Value");
            // VariableBrowsePaths.Add("/7:MatrikonOpc Sim Server/7:Simulation Items/7:Bucket Brigade/7:Int1");
            // VariableBrowsePaths.Add("/7:MatrikonOPC Sim Server/7:Simulation Items/7:Bucket Brigade/7:Int2");


            try {
                // create the configuration.
                ApplicationConfiguration configuration = Helpers.CreateClientConfiguration();

                // create the endpoint description.
                EndpointDescription endpointDescription = Helpers.CreateEndpointDescription();

                // create the endpoint configuration (use the application configuration to provide default values).
                EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(configuration);

                // the default timeout for a requests sent using the channel.
                endpointConfiguration.OperationTimeout = 600000;

                // use the pure XML encoding on the wire.
                endpointConfiguration.UseBinaryEncoding = true;

                // create the endpoint.
                ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration);

                // create the binding factory.
                ServiceMessageContext messageContext = configuration.CreateMessageContext();
                BindingFactory        bindingFactory = BindingFactory.Create(configuration, messageContext);

                // update endpoint description using the discovery endpoint.
                if (endpoint.UpdateBeforeConnect)
                {
                    endpoint.UpdateFromServer(bindingFactory);

                    Console.WriteLine("Updated endpoint description for url: {0}", endpointDescription.EndpointUrl);

                    endpointDescription   = endpoint.Description;
                    endpointConfiguration = endpoint.Configuration;
                }

                X509Certificate2 clientCertificate = configuration.SecurityConfiguration.ApplicationCertificate.Find();

                // set up a callback to handle certificate validation errors.
                configuration.CertificateValidator.CertificateValidation +=
                    new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);

                // Initialize the channel which will be created with the server.
                ITransportChannel channel = SessionChannel.Create(
                    configuration,
                    endpointDescription,
                    endpointConfiguration,
                    clientCertificate,
                    messageContext);

                // Wrap the channel with the session object.
                // This call will fail if the server does not trust the client certificate.
                Session session = new Session(channel, configuration, endpoint, null);

                session.ReturnDiagnostics = DiagnosticsMasks.All;

                // register keep alive callback.
                // session.KeepAlive += new KeepAliveEventHandler(Session_KeepAlive);

                // passing null for the user identity will create an anonymous session.
                UserIdentity identity = null; // new UserIdentity("iamuser", "password");

                // create the session. This actually connects to the server.
                session.Open("My Session Name", identity);

                //Read some history values:
                string str = "";
                do
                {
                    Console.WriteLine("Select action from the menu:\n");
                    Console.WriteLine("\t 0 - Browse");
                    Console.WriteLine("\t 1 - Update");
                    Console.WriteLine("\t 2 - ReadRaw");
                    Console.WriteLine("\t 3 - ReadProcessed");
                    Console.WriteLine("\t 4 - ReadAtTime");
                    Console.WriteLine("\t 5 - ReadAttributes");
                    Console.WriteLine("\t 6 - DeleteAtTime");
                    Console.WriteLine("\t 7 - DeleteRaw");


                    Console.WriteLine("\n\tQ - exit\n\n");

                    str = Console.ReadLine();
                    Console.WriteLine("\n");

                    try {
                        if (str == "0")
                        {
                            Browse(session);
                        }
                        else if (str == "1")
                        {
                            HistoryUpdate(session);
                        }
                        else if (str == "2")
                        {
                            HistoryReadRaw(session);
                        }
                        else if (str == "3")
                        {
                            HistoryReadProcessed(session);
                        }
                        else if (str == "4")
                        {
                            HistoryReadAtTime(session);
                        }
                        else if (str == "5")
                        {
                            HistoryReadAttributes(session);
                        }
                        else if (str == "6")
                        {
                            HistoryDeleteAtTime(session);
                        }
                        else if (str == "7")
                        {
                            HistoryDeleteRaw(session);
                        }
                    } catch (Exception e) {
                        Console.WriteLine("Exception occured: " + e.Message);
                    }
                } while (str != "Q" && str != "q");


                // Display some friendly info to the console and then wait for the ENTER key to be pressed.
                Console.WriteLine("Connected to {0}.\nPress ENTER to disconnect to end.", DefaultServerUrl);
                Console.ReadLine();

                // Close and Dispose of our session, effectively disconnecting us from the UA Server.
                session.Close();
                session.Dispose();
            } catch (Exception e) {
                Console.WriteLine("Unexpected exception: {0}.\nPress ENTER to disconnect to end.", e.Message);
                Console.ReadLine();
                Console.WriteLine();
                Console.WriteLine(
                    "========================================================================================");
                Console.WriteLine();
            }
        }
Пример #25
0
        /// <summary>
        /// Creates a new communication session with a server by invoking the CreateSession service
        /// </summary>
        /// <param name="configuration">The configuration for the client application.</param>
        /// <param name="endpoint">The endpoint for the server.</param>
        /// <param name="updateBeforeConnect">If set to <c>true</c> the discovery endpoint is used to update the endpoint description before connecting.</param>
        /// <param name="checkDomain">If set to <c>true</c> then the domain in the certificate must match the endpoint used.</param>
        /// <param name="sessionName">The name to assign to the session.</param>
        /// <param name="sessionTimeout">The timeout period for the session.</param>
        /// <param name="identity">The user identity to associate with the session.</param>
        /// <param name="preferredLocales">The preferred locales.</param>
        /// <returns>The new session object.</returns>
        public static Session Create( 
            ApplicationConfiguration configuration,
            ConfiguredEndpoint       endpoint,
            bool                     updateBeforeConnect,
            bool                     checkDomain,
            string                   sessionName,
            uint                     sessionTimeout,
            IUserIdentity            identity,
            IList<string>            preferredLocales)
        {
            endpoint.UpdateBeforeConnect = updateBeforeConnect;

            EndpointDescription endpointDescription = endpoint.Description;

            // create the endpoint configuration (use the application configuration to provide default values).
            EndpointConfiguration endpointConfiguration = endpoint.Configuration;
            
            if (endpointConfiguration == null)
            {
                endpoint.Configuration = endpointConfiguration = EndpointConfiguration.Create(configuration);
            }

            // create message context.
            ServiceMessageContext messageContext = configuration.CreateMessageContext();
            
            // update endpoint description using the discovery endpoint.
            if (endpoint.UpdateBeforeConnect)
            {
                BindingFactory bindingFactory = BindingFactory.Create(configuration, messageContext);
                endpoint.UpdateFromServer(bindingFactory);

                endpointDescription = endpoint.Description;
                endpointConfiguration = endpoint.Configuration;
            }

            // checks the domains in the certificate.
            if (checkDomain && endpoint.Description.ServerCertificate != null && endpoint.Description.ServerCertificate.Length > 0)
            {
                CheckCertificateDomain(endpoint);
            }

            X509Certificate2 clientCertificate = null;
			//X509Certificate2Collection clientCertificateChain = null;

            if (endpointDescription.SecurityPolicyUri != SecurityPolicies.None)
            {
                if (configuration.SecurityConfiguration.ApplicationCertificate == null)
                {
                    throw ServiceResultException.Create( StatusCodes.BadConfigurationError, "ApplicationCertificate must be specified." );
                }

                clientCertificate = configuration.SecurityConfiguration.ApplicationCertificate.Find( true );

				if( clientCertificate == null )
				{
                    throw ServiceResultException.Create( StatusCodes.BadConfigurationError, "ApplicationCertificate cannot be found." );
                }

                //load certificate chain
                //clientCertificateChain = new X509Certificate2Collection(clientCertificate);
                //List<CertificateIdentifier> issuers = new List<CertificateIdentifier>();
                //configuration.CertificateValidator.GetIssuers(clientCertificate, issuers);
                //for (int i = 0; i < issuers.Count; i++)
                //{
                //    clientCertificateChain.Add(issuers[i].Certificate);
                //}
            }

            // initialize the channel which will be created with the server.
            ITransportChannel channel = SessionChannel.Create(
                 configuration,
                 endpointDescription,
                 endpointConfiguration,
                 //clientCertificateChain,
                 clientCertificate,
                 messageContext);

            // create the session object.
            Session session = new Session(channel, configuration, endpoint, null);

            // create the session.
			try
			{
				session.Open( sessionName, sessionTimeout, identity, preferredLocales, checkDomain );
			}
			catch
			{
				session.Dispose();
				throw;
			}

            return session;
        }
Пример #26
0
        /// <summary>
        /// Creates a session with the endpoint.
        /// </summary>
        ///
        public async void OPCConnect(ApplicationInstance application, ConfiguredEndpoint endpoint)
        {
            if (endpoint == null)
            {
                return;
            }
            // load the application configuration.
            ApplicationConfiguration config = await application.LoadApplicationConfiguration(false);

            // check the application certificate.
            bool haveAppCertificate = await application.CheckApplicationInstanceCertificate(false, 0);

            if (!haveAppCertificate)
            {
                throw new Exception("Application instance certificate invalid!");
            }
            else if (haveAppCertificate)
            {
                config.ApplicationUri = Utils.GetApplicationUriFromCertificate(config.SecurityConfiguration.ApplicationCertificate.Certificate);
                if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates)
                {
                    autoAccept = true;
                }
                config.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);
            }
            //Checks if endpoint URL selected is same as retained endpoint URL
            string endpointURL      = endpoint.EndpointUrl.ToString();
            string retainedEndpoint = null;
            bool   retainSession    = false;

            retainedEndpoint = await LoadSessionAsync(endpointURL);

            try
            {
                if (retainedEndpoint == null || !retainSession)
                {
                    selectedEndpoint = CoreClientUtils.SelectEndpoint(endpointURL, haveAppCertificate, 15000);
                }
                else
                {
                    selectedEndpoint = CoreClientUtils.SelectEndpoint(retainedEndpoint, haveAppCertificate, 15000);
                }
                //Select endpoint after discovery.
                //Creates session with OPC Server
                sessionEndpoint          = selectedEndpoint.EndpointUrl;
                m_endpoint_configuration = EndpointConfiguration.Create(config);
                m_endpoint = new ConfiguredEndpoint(null, selectedEndpoint, m_endpoint_configuration);
                m_session  = await Session.Create(config, m_endpoint, false, "OpcEdgeClient", 60000, new UserIdentity(new AnonymousIdentityToken()), null);

                // Open dialog to declare Session name.
                if (new SessionOpenDlg().ShowDialog(m_session, opcSession.PreferredLocales) == false)
                {
                    return;
                }
                // Deletes the existing session.
                opcSession.Close();
                // Adds session to tree.
                opcSession.AddNode(m_session);
                //Checks if service has a session connected and disconnects if connected.
                if (client.CheckConnected())
                {
                    client.OPCDisconnect();
                }
                // Passes endpointURL to service for connection.
                client.OPCConnect(selectedEndpoint.EndpointUrl);

                if (m_session != null)
                {
                    // stop any reconnect operation.
                    if (m_reconnectHandler != null)
                    {
                        m_reconnectHandler.Dispose();
                        m_reconnectHandler = null;
                    }
                    //Register keep alive handler & sets view
                    m_session.KeepAlive += new KeepAliveEventHandler(StandardClient_KeepAlive);
                    opcBrowse.SetView(m_session, BrowseViewType.Objects, null);
                    StandardClient_KeepAlive(m_session, null);

                    //Saves session endpoint URL.
                    m_session.SessionName = "My Session";
                    await SaveSessionAsync(m_session);

                    //Recreates prior session's subscriptions and monitored items.
                    if (retainedEndpoint == endpointURL)
                    {
                        RecreateSession(m_session);
                    }
                }
                OpcConnectionLabel.Text = "Currently Connected to: " + selectedEndpoint.EndpointUrl;
            }
            catch (Exception ex)
            {
                // Log the exception.
                MessageBox.Show(ex.Message);
            }
        }
Пример #27
0
        private static void CheckCertificateDomain(ConfiguredEndpoint endpoint)
        {
            bool domainFound = false;

            X509Certificate2 serverCertificate = new X509Certificate2(endpoint.Description.ServerCertificate);

            // check the certificate domains.
            IList<string> domains = Utils.GetDomainsFromCertficate(serverCertificate);

            if (domains != null)
            {
                string hostname = endpoint.EndpointUrl.DnsSafeHost;

                if (hostname == "localhost" || hostname == "127.0.0.1")
                {
                    hostname = System.Net.Dns.GetHostName();
                }

                for (int ii = 0; ii < domains.Count; ii++)
                {
                    if (String.Compare(hostname, domains[ii], StringComparison.InvariantCultureIgnoreCase) == 0)
                    {
                        domainFound = true;
                        break;
                    }
                }
            }

            if (!domainFound)
            {
                throw new ServiceResultException(StatusCodes.BadCertificateHostNameInvalid);
            }
        }
Пример #28
0
        //Initializes OPC Application instance.
        public async void InitializeClients()
        {
            //Creates directory for retained information in case it was deleted somehow.
            createDirectories();

            //Initialize OPC Application Instance
            application = new ApplicationInstance
            {
                ApplicationName   = "MQTT-OPC Broker",
                ApplicationType   = ApplicationType.ClientAndServer,
                ConfigSectionName = "Opc.Ua.SampleClient"
            };
            // load the application configuration.
            application.LoadApplicationConfiguration(false).Wait();
            // check the application certificate.
            application.CheckApplicationInstanceCertificate(false, 0).Wait();
            m_configuration = app_configuration = application.ApplicationConfiguration;
            // get list of cached endpoints.
            m_endpoints = m_configuration.LoadCachedEndpoints(true);
            m_endpoints.DiscoveryUrls = app_configuration.ClientConfiguration.WellKnownDiscoveryUrls;
            if (!app_configuration.SecurityConfiguration.AutoAcceptUntrustedCertificates)
            {
                app_configuration.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);
            }
            sessionEndpoint = client.SessionEndpoint();
            //If service is currently connected to a OPC endpoint, recreate the connection on the client.
            if (sessionEndpoint != null)
            {
                sessionEndpoint = Regex.Replace(sessionEndpoint, "\\\\|\"", "");
                // load the application configuration.
                ApplicationConfiguration config = await application.LoadApplicationConfiguration(false);

                // check the application certificate.
                bool haveAppCertificate = await application.CheckApplicationInstanceCertificate(false, 0);

                if (!haveAppCertificate)
                {
                    throw new Exception("Application instance certificate invalid!");
                }
                else if (haveAppCertificate)
                {
                    config.ApplicationUri = Utils.GetApplicationUriFromCertificate(config.SecurityConfiguration.ApplicationCertificate.Certificate);
                    if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates)
                    {
                        autoAccept = true;
                    }
                    config.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);
                }
                try
                {
                    //Creates session with OPC Server
                    selectedEndpoint         = CoreClientUtils.SelectEndpoint(sessionEndpoint, haveAppCertificate, 15000);
                    m_endpoint_configuration = EndpointConfiguration.Create(config);
                    m_endpoint = new ConfiguredEndpoint(null, selectedEndpoint, m_endpoint_configuration);
                    m_session  = await Session.Create(config, m_endpoint, false, "OpcEdgeClient", 60000, new UserIdentity(new AnonymousIdentityToken()), null);

                    // Open dialog to declare Session name.
                    //new SessionOpenDlg().ShowDialog(m_session, opcSession.PreferredLocales);
                    // Deletes the existing session.
                    opcSession.Close();
                    // Adds session to tree.
                    opcSession.AddNode(m_session);
                    //Checks if service has a session connected and disconnects if connected.
                    if (client.CheckConnected())
                    {
                        client.OPCDisconnect();
                    }
                    // Passes endpointURL to service for connection.
                    client.OPCConnect(selectedEndpoint.EndpointUrl);

                    if (m_session != null)
                    {
                        // stop any reconnect operation.
                        if (m_reconnectHandler != null)
                        {
                            m_reconnectHandler.Dispose();
                            m_reconnectHandler = null;
                        }
                        //Register keep alive handler & sets view
                        m_session.KeepAlive += new KeepAliveEventHandler(StandardClient_KeepAlive);
                        opcBrowse.SetView(m_session, BrowseViewType.Objects, null);
                        StandardClient_KeepAlive(m_session, null);

                        //Saves session endpoint URL.
                        m_session.SessionName = "My Session";
                        await SaveSessionAsync(m_session);

                        //Recreates prior session's subscriptions and monitored items.
                        string retainedEndpoint = await LoadSessionAsync(selectedEndpoint.EndpointUrl);

                        if (sessionEndpoint == retainedEndpoint)
                        {
                            RecreateSession(m_session);
                        }
                    }
                    OpcConnectionLabel.Text = "Currently Connected to: " + selectedEndpoint.EndpointUrl;
                }
                catch (Exception ex)
                {
                    // Log the exception.
                    MessageBox.Show(ex.Message);
                }
            }
        }
Пример #29
0
 public OpcUaSession(ApplicationConfiguration configuration, ConfiguredEndpoint endpoint, bool updateBeforeConnect, bool checkDomain, string sessionName, uint sessionTimeout, IUserIdentity identity, IList <string> preferredLocales) =>
Пример #30
0
            private async Task ConsoleClient()
            {
                failed = false;
                Log(conn_name + " - " + "Create an Application Configuration...");
                exitCode = ExitCode.ErrorCreateApplication;

                ApplicationInstance application = new ApplicationInstance
                {
                    ApplicationName   = "JSON-SCADA OPC-UA Client",
                    ApplicationType   = ApplicationType.Client,
                    ConfigSectionName = "",
                };

                bool haveAppCertificate         = false;
                ApplicationConfiguration config = null;

                try
                {
                    // load the application configuration.
                    Log(conn_name + " - " + "Load config from " + OPCUA_conn.configFileName);
                    config = await application.LoadApplicationConfiguration(OPCUA_conn.configFileName, false);

                    // config.SecurityConfiguration.AutoAcceptUntrustedCertificates = true;

                    // check the application certificate.
                    haveAppCertificate = await application.CheckApplicationInstanceCertificate(false, 0);

                    if (!haveAppCertificate)
                    {
                        Log(conn_name + " - " + "FATAL: Application instance certificate invalid!", LogLevelNoLog);
                        Environment.Exit(1);
                    }

                    if (haveAppCertificate)
                    {
                        config.ApplicationUri = X509Utils.GetApplicationUriFromCertificate(config.SecurityConfiguration.ApplicationCertificate.Certificate);
                        if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates)
                        {
                            autoAccept = true;
                        }
                        config.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);
                    }
                    else
                    {
                        Log(conn_name + " - " + "WARN: missing application certificate, using unsecure connection.");
                    }
                }
                catch (Exception e)
                {
                    Log(conn_name + " - WARN: " + e.Message);
                }

                if (config == null)
                {
                    Log(conn_name + " - " + "FATAL: error in XML config file!", LogLevelNoLog);
                    Environment.Exit(1);
                }

                try
                {
                    Log(conn_name + " - " + "Discover endpoints of " + OPCUA_conn.endpointURLs[0]);
                    exitCode = ExitCode.ErrorDiscoverEndpoints;
                    var selectedEndpoint = CoreClientUtils.SelectEndpoint(OPCUA_conn.endpointURLs[0], haveAppCertificate && OPCUA_conn.useSecurity, 15000);
                    Log(conn_name + " - " + "Selected endpoint uses: " +
                        selectedEndpoint.SecurityPolicyUri.Substring(selectedEndpoint.SecurityPolicyUri.LastIndexOf('#') + 1));

                    Log(conn_name + " - " + "Create a session with OPC UA server.");
                    exitCode = ExitCode.ErrorCreateSession;
                    var endpointConfiguration = EndpointConfiguration.Create(config);
                    var endpoint = new ConfiguredEndpoint(null, selectedEndpoint, endpointConfiguration);

                    await Task.Delay(50);

                    session = await Session.Create(config, endpoint, false, "OPC UA Console Client", 60000, new UserIdentity(new AnonymousIdentityToken()), null);

                    // Log("" + session.KeepAliveInterval); // default is 5000
                    session.KeepAliveInterval = System.Convert.ToInt32(OPCUA_conn.timeoutMs);

                    // register keep alive handler
                    session.KeepAlive += Client_KeepAlive;
                }
                catch (Exception e)
                {
                    Log(conn_name + " - WARN: " + e.Message);
                }

                if (session == null)
                {
                    Log(conn_name + " - " + "FATAL: error creating session!", LogLevelNoLog);
                    failed = true;
                    // Environment.Exit(1);
                    return;
                }

                Log(conn_name + " - " + "Browsing the OPC UA server namespace.");
                exitCode = ExitCode.ErrorBrowseNamespace;

                if (OPCUA_conn.autoCreateTags)
                {
                    await FindObjects(session, ObjectIds.ObjectsFolder);

                    await Task.Delay(50);

                    Log(conn_name + " - " + "Add a list of items (server current time and status) to the subscription.");
                    exitCode = ExitCode.ErrorMonitoredItem;
                    ListMon.ForEach(i => i.Notification += OnNotification);
                    //ListMon.ForEach(i => i.SamplingInterval = System.Convert.ToInt32(System.Convert.ToDouble(OPCUA_conn.autoCreateTagSamplingInterval) * 1000);
                    // ListMon.ForEach(i => Log(conn_name + " - " + i.DisplayName));
                    Log(conn_name + " - " + ListMon.Count + " Objects found");

                    Log(conn_name + " - " + "Create a subscription with publishing interval of " + System.Convert.ToDouble(OPCUA_conn.autoCreateTagPublishingInterval) + "seconds");
                    exitCode = ExitCode.ErrorCreateSubscription;
                    var subscription =
                        new Subscription(session.DefaultSubscription)
                    {
                        PublishingInterval = System.Convert.ToInt32(System.Convert.ToDouble(OPCUA_conn.autoCreateTagPublishingInterval) * 1000),
                        PublishingEnabled  = true
                    };

                    await Task.Delay(50);

                    subscription.AddItems(ListMon);

                    await Task.Delay(50);

                    Log(conn_name + " - " + "Add the subscription to the session.");
                    Log(conn_name + " - " + subscription.MonitoredItemCount + " Monitored items");
                    exitCode = ExitCode.ErrorAddSubscription;
                    session.AddSubscription(subscription);
                    subscription.Create();

                    subscription.ApplyChanges();
                }

                Log(conn_name + " - " + "Running...");
                exitCode = ExitCode.ErrorRunning;
            }
Пример #31
0
        /// <summary>
        /// Returns the UA COM Pseudo-servers registered on the local computer.
        /// </summary>
        public static List <ConfiguredEndpoint> Enumerate()
        {
            // enumerate server clsids.
            List <Guid> clsids = ConfigUtils.EnumClassesInCategory(ConfigUtils.CATID_PseudoComServers);

            // initialize server objects.
            List <ConfiguredEndpoint> servers = new List <ConfiguredEndpoint>();

            for (int ii = 0; ii < clsids.Count; ii++)
            {
                ConfiguredEndpoint server = null;

                try
                {
                    server = Load(clsids[ii]);
                    servers.Add(server);
                }
                catch (Exception e)
                {
                    Utils.Trace(e, "Unexpected error loading psuedo-server: {0}", clsids[ii]);
                    continue;
                }

                // ensure the Pseudo-server points to the correct host process.
                Guid hostClsid = Guid.Empty;

                if (server.ComIdentity != null)
                {
                    hostClsid = GetServerHostClsid(server.ComIdentity.Specification);
                }

                string hostPath = ConfigUtils.GetExecutablePath(hostClsid);

                if (String.IsNullOrEmpty(hostPath))
                {
                    continue;
                }

                RegistryKey key = Registry.ClassesRoot.OpenSubKey(String.Format(@"CLSID\{{{0}}}\LocalServer32", clsids[ii]), false);

                if (key != null)
                {
                    if (hostPath != (string)key.GetValue(null, ""))
                    {
                        try
                        {
                            key.Close();
                            key = Registry.ClassesRoot.OpenSubKey(String.Format(@"CLSID\{{{0}}}\LocalServer32", clsids[ii]), true);
                            key.SetValue(null, hostPath);
                        }
                        catch (Exception)
                        {
                            Utils.Trace("Could not update COM proxy server path for {0}.", server.ComIdentity.ProgId);
                        }
                    }

                    key.Close();
                }
            }

            return(servers);
        }
Пример #32
0
        public static async Task ConsoleSampleClient(string endpointURL)
        {
            Console.WriteLine("1 - Create an Application Configuration.");
            var config = new ApplicationConfiguration()
            {
                ApplicationName = "UA Core Sample Client",
                ApplicationType = ApplicationType.Client,
                ApplicationUri = "urn:"+Utils.GetHostName()+":OPCFoundation:CoreSampleClient",
                SecurityConfiguration = new SecurityConfiguration
                {
                    ApplicationCertificate = new CertificateIdentifier
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/MachineDefault",
                        SubjectName = "UA Core Sample Client"
                    },
                    TrustedPeerCertificates = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/UA Applications",
                    },
                    TrustedIssuerCertificates = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/UA Certificate Authorities",
                    },
                    RejectedCertificateStore = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/RejectedCertificates",
                    },
                    NonceLength = 32,
                    AutoAcceptUntrustedCertificates = true
                },
                TransportConfigurations = new TransportConfigurationCollection(),
                TransportQuotas = new TransportQuotas { OperationTimeout = 15000 },
                ClientConfiguration = new ClientConfiguration { DefaultSessionTimeout = 60000 }
            };

            await config.Validate(ApplicationType.Client);

            bool haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null;

            if (!haveAppCertificate)
            {
                Console.WriteLine("    INFO: Creating new application certificate: {0}", config.ApplicationName);

                X509Certificate2 certificate = CertificateFactory.CreateCertificate(
                    config.SecurityConfiguration.ApplicationCertificate.StoreType,
                    config.SecurityConfiguration.ApplicationCertificate.StorePath,
                    config.ApplicationUri,
                    config.ApplicationName,
                    config.SecurityConfiguration.ApplicationCertificate.SubjectName
                    );

                config.SecurityConfiguration.ApplicationCertificate.Certificate = certificate;

            }

            haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null;

            if (haveAppCertificate)
            {
                config.ApplicationUri = Utils.GetApplicationUriFromCertificate(config.SecurityConfiguration.ApplicationCertificate.Certificate);

                if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates)
                {
                    config.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);
                }
            }
            else
            {
                Console.WriteLine("    WARN: missing application certificate, using unsecure connection.");
            }

#if PERF
    while(true) {
        try {
            // Console.Clear();
#endif
            Console.WriteLine("2 - Discover endpoints of {0}.", endpointURL);
            Uri endpointURI = new Uri(endpointURL);
            var endpointCollection = DiscoverEndpoints(config, endpointURI, 10);
            var selectedEndpoint = SelectUaTcpEndpoint(endpointCollection, haveAppCertificate);
            Console.WriteLine("    Selected endpoint uses: {0}", 
                selectedEndpoint.SecurityPolicyUri.Substring(selectedEndpoint.SecurityPolicyUri.LastIndexOf('#') + 1));

            Console.WriteLine("3 - Create a session with OPC UA server.");
            var endpointConfiguration = EndpointConfiguration.Create(config);
            var endpoint = new ConfiguredEndpoint(selectedEndpoint.Server, endpointConfiguration);
            endpoint.Update(selectedEndpoint);
            var session = await Session.Create(config, endpoint, true, ".Net Core OPC UA Console Client", 60000, null, null);

            // Access underlying proxy socket
            var channel = session.TransportChannel as IMessageSocketChannel;
            var socket = channel.Socket as ProxyMessageSocket;
            var proxySocket = socket.ProxySocket;
            Console.WriteLine("    Connected through proxy {0}.", proxySocket.LocalEndPoint.ToString());

            ReferenceDescriptionCollection references;
            Byte[] continuationPoint;

            references = session.FetchReferences(ObjectIds.ObjectsFolder);
#if PERF
            Stopwatch w = Stopwatch.StartNew();
            for (int i = 1; i <= 5; i++) {
                // Console.Clear();
                Console.WriteLine($"4 - Browse the OPC UA server namespace ({i}).");
#else
                Console.WriteLine($"4 - Browse the OPC UA server namespace.");
#endif
            session.Browse(
                null,
                null,
                ObjectIds.ObjectsFolder,
                0u,
                BrowseDirection.Forward,
                ReferenceTypeIds.HierarchicalReferences,
                true,
                (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method,
                out continuationPoint,
                out references);

            Console.WriteLine(" DisplayName, BrowseName, NodeClass");
            foreach (var rd in references)
            {
                Console.WriteLine(" {0}, {1}, {2}", rd.DisplayName, rd.BrowseName, rd.NodeClass);
                ReferenceDescriptionCollection nextRefs;
                byte[] nextCp;
                session.Browse(
                    null,
                    null,
                    ExpandedNodeId.ToNodeId(rd.NodeId, session.NamespaceUris),
                    0u,
                    BrowseDirection.Forward,
                    ReferenceTypeIds.HierarchicalReferences,
                    true,
                    (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method,
                    out nextCp,
                    out nextRefs);

                foreach (var nextRd in nextRefs)
                {
                    Console.WriteLine("   + {0}, {1}, {2}", nextRd.DisplayName, nextRd.BrowseName, nextRd.NodeClass);
                }
            }
#if PERF
            }
            Console.WriteLine($" ....        took {w.ElapsedMilliseconds} ms...");
            session.Close();
        }
        catch (Exception e) {
            Console.WriteLine(e.ToString());
        }
    }
#else

            Console.WriteLine("5 - Create a subscription with publishing interval of 1 second.");
            var subscription = new Subscription(session.DefaultSubscription) { PublishingInterval = 1000 };

            Console.WriteLine("6 - Add a list of items (server current time and status) to the subscription.");
            var list = new List<MonitoredItem> {
                new MonitoredItem(subscription.DefaultItem)
                {
                    DisplayName = "ServerStatusCurrentTime", StartNodeId = "i=2258"
                }
            };
            list.ForEach(i => i.Notification += OnNotification);
            subscription.AddItems(list);

            Console.WriteLine("7 - Add the subscription to the session.");
            session.AddSubscription(subscription);
            subscription.Create();

            Console.WriteLine("8 - Running...Press any key to exit...");
            Console.ReadKey(true);
#endif
        }
Пример #33
0
        /// <summary>
        /// Connects to a server.
        /// </summary>
        private void Server_ConnectMI_Click(object sender, EventArgs e)
        {
            try
            {
                // disconnect any existing session.
                Server_DisconnectMI_Click(sender, e);

                InitialStateTB.Text = "1";
                FinalStateTB.Text   = "100";

                // create the session.
                EndpointDescription   endpointDescription   = SelectEndpoint();
                EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration);
                ConfiguredEndpoint    endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration);

                m_session = Session.Create(
                    m_configuration,
                    endpoint,
                    true,
                    m_configuration.ApplicationName,
                    60000,
                    null,
                    null);

                // set up keep alive callback.
                m_session.KeepAliveInterval = 2000;
                m_session.KeepAlive        += new KeepAliveEventHandler(Session_KeepAlive);

                // this client has built-in knowledge of the information model used by the server.
                NamespaceTable wellKnownNamespaceUris = new NamespaceTable();
                wellKnownNamespaceUris.Append(Namespaces.Methods);

                string[] browsePaths = new string[]
                {
                    "1:My Process/1:State",
                    "1:My Process",
                    "1:My Process/1:Start"
                };

                List <NodeId> nodes = FormUtils.TranslateBrowsePaths(
                    m_session,
                    ObjectIds.ObjectsFolder,
                    wellKnownNamespaceUris,
                    browsePaths);

                // subscribe to the state if available.
                if (nodes.Count > 0 && !NodeId.IsNull(nodes[0]))
                {
                    m_subscription = new Subscription();

                    m_subscription.PublishingEnabled          = true;
                    m_subscription.PublishingInterval         = 1000;
                    m_subscription.Priority                   = 1;
                    m_subscription.KeepAliveCount             = 10;
                    m_subscription.LifetimeCount              = 20;
                    m_subscription.MaxNotificationsPerPublish = 1000;

                    m_session.AddSubscription(m_subscription);
                    m_subscription.Create();

                    MonitoredItem monitoredItem = new MonitoredItem();
                    monitoredItem.StartNodeId   = nodes[0];
                    monitoredItem.AttributeId   = Attributes.Value;
                    monitoredItem.Notification += new MonitoredItemNotificationEventHandler(MonitoredItem_Notification);
                    m_subscription.AddItem(monitoredItem);

                    m_subscription.ApplyChanges();
                }

                // save the object/method
                if (nodes.Count > 2)
                {
                    m_objectNode = nodes[1];
                    m_methodNode = nodes[2];
                }

                ConnectedLB.Text         = "Connected";
                ServerUrlLB.Text         = endpointDescription.EndpointUrl;
                LastKeepAliveTimeLB.Text = "---";
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
Пример #34
0
        /// <summary>
        /// Connects the specified endpoint.
        /// </summary>
        /// <param name="endpoint">The endpoint.</param>
        public async void Connect(ConfiguredEndpoint endpoint)
        {
            if (endpoint != null && m_endpoint != null && endpoint.EndpointUrl != m_endpoint.EndpointUrl)
            {
                m_adminCredentials = null;
            }

            if (endpoint == null)
            {
                endpoint = m_endpoint;

                if (endpoint == null)
                {
                    throw new ArgumentNullException("endpoint");
                }
            }

            if (m_session != null)
            {
                m_session.Dispose();
                m_session = null;
            }

            m_session = await Session.Create(
                m_application.ApplicationConfiguration,
                endpoint,
                true,
                false,
                m_application.ApplicationName,
                60000,
                null,
                m_preferredLocales);

            m_endpoint = m_session.ConfiguredEndpoint;

            if (m_session.Factory.GetSystemType(Opc.Ua.DataTypeIds.TrustListDataType) == null)
            {
                m_session.Factory.AddEncodeableTypes(typeof(Opc.Ua.DataTypeIds).Assembly);
            }

            RaiseConnectionStatusChangedEvent();

            m_session.ReturnDiagnostics = DiagnosticsMasks.SymbolicIdAndText;
            m_session.KeepAlive        += Session_KeepAlive;

            Subscription subscription = new Subscription();

            subscription.Handle                     = this;
            subscription.DisplayName                = null;
            subscription.PublishingInterval         = 1000;
            subscription.KeepAliveCount             = 10;
            subscription.LifetimeCount              = 100;
            subscription.MaxNotificationsPerPublish = 1000;
            subscription.PublishingEnabled          = true;
            subscription.TimestampsToReturn         = TimestampsToReturn.Neither;

            m_session.AddSubscription(subscription);
            subscription.Create();

            MonitoredItem monitoredItem = new MonitoredItem();

            monitoredItem.StartNodeId      = Opc.Ua.VariableIds.Server_ServerStatus;
            monitoredItem.AttributeId      = Attributes.Value;
            monitoredItem.SamplingInterval = 1000;
            monitoredItem.QueueSize        = 0;
            monitoredItem.DiscardOldest    = true;
            monitoredItem.Handle           = typeof(ServerStatusDataType);

            monitoredItem.Notification += ServerStatus_Notification;

            subscription.AddItem(monitoredItem);
            subscription.ApplyChanges();
        }
 private void InputTB_LostFocus(object sender, RoutedEventArgs e)
 {
     try
     {
         InputTB.Visibility = Visibility.Collapsed;
         EndpointCB.Visibility = Visibility.Visible;
         ConfiguredEndpoint endpoint = EndpointCB.SelectedValue as ConfiguredEndpoint;
         if (endpoint == null ||
             InputTB.Text != endpoint.ToString())
         {
             endpoint = m_endpoints.Create(InputTB.Text);
             SelectedEndpoint = endpoint;
         }
     }
     catch (Exception exception)
     {
         GuiUtils.HandleException(String.Empty, GuiUtils.CallerName(), exception);
     }
 }
        private void DiscoveryTreeView_AfterSelect(object sender, TreeViewEventArgs e)
        {
            try
            {
                if (RootFolders.LocalMachine.Equals(e.Node.Tag))
                {
                    ServersTable.Rows.Clear();
                    ShowPanel(true);

                    if (e.Node.Nodes.Count == 1 && String.IsNullOrEmpty(e.Node.Nodes[0].Text))
                    {
                        e.Node.Nodes.Clear();

                        m_lds.BeginFindServers(
                            OnFindServersComplete,
                            new ExpandNodeData()
                        {
                            Parent = e.Node, Lds = m_lds
                        });
                    }
                    else
                    {
                        ShowApplicationDescriptions(e.Node.Nodes);
                    }

                    return;
                }

                if (RootFolders.LocalNetwork.Equals(e.Node.Tag))
                {
                    ServersTable.Rows.Clear();
                    ShowPanel(true);

                    if (e.Node.Nodes.Count == 1 && String.IsNullOrEmpty(e.Node.Nodes[0].Text))
                    {
                        e.Node.Nodes.Clear();

                        m_lds.BeginFindServersOnNetwork(
                            0,
                            1000,
                            OnFindServersOnNetworkComplete,
                            new ExpandNodeData()
                        {
                            Parent = e.Node, Lds = m_lds
                        });
                    }
                    else
                    {
                        ShowServerOnNetworks(e.Node.Nodes);
                    }

                    return;
                }

                if (RootFolders.GlobalDiscovery.Equals(e.Node.Tag))
                {
                    ServersTable.Rows.Clear();
                    ShowPanel(true);

                    if (e.Node.Nodes.Count == 1 && String.IsNullOrEmpty(e.Node.Nodes[0].Text))
                    {
                        e.Node.Nodes.Clear();

                        var servers = new ViewServersOnNetworkDialog(m_gds).ShowDialog(this, ref m_filters);

                        if (servers != null)
                        {
                            foreach (var server in servers)
                            {
                                TreeNode node = new TreeNode(String.Format("{0}", server.ServerName));
                                node.SelectedImageIndex = node.ImageIndex = ImageIndex.Server;
                                node.Tag = server;
                                node.Nodes.Add(new TreeNode());
                                e.Node.Nodes.Add(node);
                            }
                        }
                    }

                    ShowServerOnNetworks(e.Node.Nodes);

                    return;
                }

                if (RootFolders.CustomDiscovery.Equals(e.Node.Tag))
                {
                    ServersTable.Rows.Clear();
                    ShowPanel(true);
                    return;
                }

                if (e.Node.Tag is ApplicationDescription)
                {
                    EndpointsTable.Rows.Clear();
                    ShowPanel(false);

                    ApplicationDescription application = (ApplicationDescription)e.Node.Tag;

                    ApplicationNameTextBox.Text = (LocalizedText.IsNullOrEmpty(application.ApplicationName))?"---":application.ApplicationName.Text;
                    ApplicationTypeTextBox.Text = application.ApplicationType.ToString();
                    ApplicationUriTextBox.Text  = application.ApplicationUri;
                    ProductUriTextBox.Text      = application.ProductUri;

                    string discoveryUrl = SelectDiscoveryUrl(application);

                    if (discoveryUrl != null)
                    {
                        m_lds.BeginGetEndpoints(
                            discoveryUrl,
                            null,
                            OnGetEndpointsComplete,
                            new GetEndpointsData()
                        {
                            Parent = e.Node, Lds = m_lds
                        });
                    }
                }

                if (e.Node.Tag is ServerOnNetwork)
                {
                    EndpointsTable.Rows.Clear();
                    ShowPanel(false);

                    ServerOnNetwork server = (ServerOnNetwork)e.Node.Tag;

                    ApplicationNameTextBox.Text = server.ServerName;
                    ApplicationTypeTextBox.Text = "---";
                    ApplicationUriTextBox.Text  = "---";
                    ProductUriTextBox.Text      = "---";

                    try
                    {
                        Cursor = Cursors.WaitCursor;

                        m_lds.BeginGetEndpoints(
                            server.DiscoveryUrl,
                            null,
                            OnGetEndpointsComplete,
                            new GetEndpointsData()
                        {
                            Parent = e.Node, Lds = m_lds
                        });
                    }
                    finally
                    {
                        Cursor = Cursors.Default;
                    }
                }

                if (e.Node.Tag is ConfiguredEndpoint)
                {
                    EndpointsTable.Rows.Clear();
                    ShowPanel(false);

                    ConfiguredEndpoint server = (ConfiguredEndpoint)e.Node.Tag;

                    ApplicationNameTextBox.Text = "---";
                    ApplicationTypeTextBox.Text = "---";
                    ApplicationUriTextBox.Text  = "---";
                    ProductUriTextBox.Text      = "---";

                    m_lds.BeginGetEndpoints(
                        server.EndpointUrl.ToString(),
                        null,
                        OnGetEndpointsComplete,
                        new GetEndpointsData()
                    {
                        Parent = e.Node, Lds = m_lds
                    });
                }
            }
            catch (Exception ex)
            {
                Opc.Ua.Client.Controls.ExceptionDlg.Show(Text, ex);
            }
        }
Пример #37
0
        private static async Task <Session> CreateSessionAsync(ApplicationConfiguration config, ConfiguredEndpoint endpoint)
        {
            var session = await Session.Create(config, endpoint, true,
                                               _clientName, 60000, null, null);

            // Access underlying proxy socket
            var channel     = session.TransportChannel as IMessageSocketChannel;
            var socket      = channel.Socket as ProxyMessageSocket;
            var proxySocket = socket.ProxySocket;

            Console.WriteLine("    Connected through proxy {0}.", proxySocket.LocalEndPoint.ToString());
            return(session);
        }
        /// <summary>
        /// Connects to a server.
        /// </summary>
        public async Task<bool> Connect(ConfiguredEndpoint endpoint)
        {
            bool result = false;
            if (endpoint == null)
            {
                return false;
            }

            // connect dialogs
            Session session = await SessionsCTRL.Connect(endpoint);

            if (session != null)
            {
                //hook up new session
                session.KeepAlive += new KeepAliveEventHandler(StandardClient_KeepAlive);
                StandardClient_KeepAlive(session, null);

               // BrowseCTRL.SetView(session, BrowseViewType.Objects, null);
                result = true;
            }

            return result;
        }
Пример #39
0
        /// <summary>
        /// Initializes the channel.
        /// </summary>
        private void Initialize(
            ITransportChannel        channel, 
            ApplicationConfiguration configuration, 
            ConfiguredEndpoint       endpoint,
            X509Certificate2         clientCertificate)
        {
            Initialize();

            // save configuration information.
            m_configuration = configuration;
            m_endpoint = endpoint;
            
            // update the default subscription. 
            m_defaultSubscription.MinLifetimeInterval = (uint)configuration.ClientConfiguration.MinSubscriptionLifetime;

            if (m_endpoint.Description.SecurityPolicyUri != SecurityPolicies.None)
            {
                // update client certificate.
                m_instanceCertificate = clientCertificate;

                if (clientCertificate == null)
                {
                    // load the application instance certificate.
                    if (m_configuration.SecurityConfiguration.ApplicationCertificate == null)
                    {
                        throw new ServiceResultException(
                            StatusCodes.BadConfigurationError,
                            "The client configuration does not specify an application instance certificate.");
                    }

                    m_instanceCertificate = m_configuration.SecurityConfiguration.ApplicationCertificate.Find(true);
                }

                // check for valid certificate.
                if (m_instanceCertificate == null)
                {
                    throw ServiceResultException.Create(
                        StatusCodes.BadConfigurationError,
                        "Cannot find the application instance certificate. Store={0}, SubjectName={1}, Thumbprint={2}.",
                        m_configuration.SecurityConfiguration.ApplicationCertificate.StorePath,
                        m_configuration.SecurityConfiguration.ApplicationCertificate.SubjectName,
                        m_configuration.SecurityConfiguration.ApplicationCertificate.Thumbprint);
                }

                // check for private key.
                if (!m_instanceCertificate.HasPrivateKey)
                {
                    throw ServiceResultException.Create(
                        StatusCodes.BadConfigurationError,
                        "Do not have a privat key for the application instance certificate. Subject={0}, Thumbprint={1}.",
                        m_instanceCertificate.Subject,
                        m_instanceCertificate.Thumbprint);
                }

                //load certificate chain
                /*m_instanceCertificateChain = new X509Certificate2Collection(m_instanceCertificate);
                List<CertificateIdentifier> issuers = new List<CertificateIdentifier>();
                configuration.CertificateValidator.GetIssuers(m_instanceCertificate, issuers);
                for (int i = 0; i < issuers.Count; i++)
                {
                    m_instanceCertificateChain.Add(issuers[i].Certificate);
                }*/
            }

            // initialize the message context.
            ServiceMessageContext messageContext = channel.MessageContext;

            if (messageContext != null)
            {
                m_namespaceUris = messageContext.NamespaceUris;
                m_serverUris    = messageContext.ServerUris;
                m_factory       = messageContext.Factory;
            }    
            else
            {
                m_namespaceUris = new NamespaceTable();
                m_serverUris    = new StringTable();
                m_factory       = ServiceMessageContext.GlobalContext.Factory;
            }

            // set the default preferred locales.
            m_preferredLocales = new string[] { CultureInfo.CurrentCulture.Name };

            // create a context to use.
            m_systemContext = new SystemContext();

            m_systemContext.SystemHandle = this;
            m_systemContext.EncodeableFactory = m_factory;
            m_systemContext.NamespaceUris = m_namespaceUris;
            m_systemContext.ServerUris = m_serverUris;
            m_systemContext.TypeTable = this.TypeTree;
            m_systemContext.PreferredLocales = null;
            m_systemContext.SessionId = null;
            m_systemContext.UserIdentity = null;
        }
        private void NewMI_Click(object sender, EventArgs e)
        {
            try
            {
                ApplicationDescription server = new DiscoveredServerListDlg().ShowDialog(null, m_configuration);

                if (server == null)
                {
                    return;
                }

                ConfiguredEndpoint endpoint = new ConfiguredEndpoint(server, null);

                endpoint.ComIdentity = new EndpointComIdentity();
                endpoint.ComIdentity.Specification = ComSpecification.DA;

                endpoint = new ConfiguredServerDlg().ShowDialog(endpoint, m_configuration);

                if (endpoint == null)
                {
                    return;
                }
                
                EndpointComIdentity comIdentity = new PseudoComServerDlg().ShowDialog(endpoint);

                if (comIdentity == null)
                {
                    return;
                }

                endpoint.ComIdentity = comIdentity;
                PseudoComServer.Save(endpoint);

                AddItem(endpoint);
                AdjustColumns();
            }
            catch (Exception exception)
            {
                GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
            }
        }
Пример #41
0
 /// <summary>
 /// Creates a new communication session with a server by invoking the CreateSession service
 /// </summary>
 /// <param name="configuration">The configuration for the client application.</param>
 /// <param name="endpoint">The endpoint for the server.</param>
 /// <param name="updateBeforeConnect">If set to <c>true</c> the discovery endpoint is used to update the endpoint description before connecting.</param>
 /// <param name="sessionName">The name to assign to the session.</param>
 /// <param name="sessionTimeout">The timeout period for the session.</param>
 /// <param name="identity">The identity.</param>
 /// <param name="preferredLocales">The user identity to associate with the session.</param>
 /// <returns>The new session object</returns>
 public static Session Create(
     ApplicationConfiguration configuration,
     ConfiguredEndpoint endpoint,
     bool updateBeforeConnect,
     string sessionName,
     uint sessionTimeout,
     IUserIdentity identity,
     IList<string> preferredLocales)
 {
     return Create(configuration, endpoint, updateBeforeConnect, false, sessionName, sessionTimeout, identity, preferredLocales);
 }
Пример #42
0
 /// <summary>
 /// Initializes the object.
 /// </summary>
 public ConnectEndpointEventArgs(ConfiguredEndpoint endpoint, bool updateControl)
 {
     m_endpoint  = endpoint;
     m_updateControl = updateControl;
 }
Пример #43
0
        /// <summary>
        /// Create a session with the given UA server
        /// </summary>
        /// <param name="discoveryUrl"></param>
        /// <param name="configSection"></param>
        /// <returns></returns>
        public static Session CreateSession(string discoveryUrl, string configSection)
        {
            // Step 1 -- Load configuration
            var configFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, configSection + ".Config.xml");
            var configFileInfo = new FileInfo(configFilePath);
            ApplicationConfiguration configuration = ApplicationConfiguration.Load(configFileInfo, ApplicationType.Client, null).Result;

            //ApplicationConfiguration configuration = ApplicationConfiguration.Load(configSection, ApplicationType.Client).Result;
            ClientUtils.CheckApplicationInstanceCertificate(configuration);

            // Step 2 -- Select an endpoint
            // create the endpoint description
            EndpointDescription endpointDescription = ClientUtils.SelectEndpoint(discoveryUrl, false);

            endpointDescription.SecurityMode      = MessageSecurityMode.None;
            endpointDescription.SecurityPolicyUri = @"http://opcfoundation.org/UA/SecurityPolicy#None";

            // create the endpoint configuration
            EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(configuration);

            // the default timeout for a requests sent using the channel.
            endpointConfiguration.OperationTimeout = 600000;
            // create the endpoint.
            ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration);

            // choose the encoding strategy: true: BinaryEncoding; false: XmlEncoding
            endpoint.Configuration.UseBinaryEncoding = true;

            //// create the binding factory.
            //BindingFactory bindingFactory = BindingFactory.Create(configuration, configuration.CreateMessageContext());

            //// update endpoint description using the discovery endpoint.
            //if (endpoint.UpdateBeforeConnect)
            //{
            //    endpoint.UpdateFromServer(bindingFactory);

            //    //Console.Error.WriteLine("Updated endpoint description for url: {0}\n", endpointDescription.EndpointUrl);

            //    endpointDescription = endpoint.Description;
            //    endpointConfiguration = endpoint.Configuration;
            //}

            X509Certificate2 clientCertificate = configuration.SecurityConfiguration.ApplicationCertificate.Find().Result;

            configuration.SecurityConfiguration.RejectSHA1SignedCertificates = false;
            ushort minimumKeySize = CertificateFactory.defaultKeySize / 2;

            configuration.SecurityConfiguration.MinimumCertificateKeySize = minimumKeySize;
            configuration.CertificateValidator.Update(configuration.SecurityConfiguration);

            // set up a callback to handle certificate validation errors.
            configuration.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);

            // Step 3 -- Initialize the channel which will be created with the server.
            var channel = SessionChannel.Create(
                configuration,
                endpointDescription,
                endpointConfiguration,
                //bindingFactory,
                clientCertificate,
                new ServiceMessageContext());

            // Step 4 -- Create a session
            Session session = new Session(channel, configuration, endpoint, clientCertificate)
            {
                ReturnDiagnostics = DiagnosticsMasks.All
            };
            string       sessionName = "SenderSession";
            UserIdentity identity    = new UserIdentity(); // anonymous

            session.KeepAlive += new KeepAliveEventHandler(Session_KeepAlive);
            session.Open(sessionName, identity);
            return(session);
        }
Пример #44
0
        private async Task RunClient(string endpointURL)
        {
            //Create an Application Configuration
            Utils.SetTraceOutput(Utils.TraceOutput.DebugAndFile);
            var config = new ApplicationConfiguration()
            {
                ApplicationName       = "UA Core Sample Client",
                ApplicationType       = ApplicationType.Client,
                ApplicationUri        = "urn:" + Utils.GetHostName() + ":OPCFoundation:CoreSampleClient",
                SecurityConfiguration = new SecurityConfiguration
                {
                    ApplicationCertificate = new CertificateIdentifier
                    {
                        StoreType   = "X509Store",
                        StorePath   = "CurrentUser\\UA_MachineDefault",
                        SubjectName = "UA Core Sample Client"
                    },
                    TrustedPeerCertificates = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/UA Applications",
                    },
                    TrustedIssuerCertificates = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/UA Certificate Authorities",
                    },
                    RejectedCertificateStore = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/RejectedCertificates",
                    },
                    NonceLength = 32,
                    AutoAcceptUntrustedCertificates = true
                },
                TransportConfigurations = new TransportConfigurationCollection(),
                TransportQuotas         = new TransportQuotas {
                    OperationTimeout = 15000
                },
                ClientConfiguration = new ClientConfiguration {
                    DefaultSessionTimeout = 60000
                }
            };

            await config.Validate(ApplicationType.Client);

            bool haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null;

            if (!haveAppCertificate)
            {
                Console.WriteLine("    INFO: Creating new application certificate: {0}", config.ApplicationName);

                X509Certificate2 certificate = CertificateFactory.CreateCertificate(
                    config.SecurityConfiguration.ApplicationCertificate.StoreType,
                    config.SecurityConfiguration.ApplicationCertificate.StorePath,
                    null,
                    config.ApplicationUri,
                    config.ApplicationName,
                    config.SecurityConfiguration.ApplicationCertificate.SubjectName,
                    null,
                    CertificateFactory.defaultKeySize,
                    DateTime.UtcNow - TimeSpan.FromDays(1),
                    CertificateFactory.defaultLifeTime,
                    CertificateFactory.defaultHashSize,
                    false,
                    null,
                    null
                    );

                config.SecurityConfiguration.ApplicationCertificate.Certificate = certificate;
            }

            haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null;

            if (haveAppCertificate)
            {
                config.ApplicationUri = Utils.GetApplicationUriFromCertificate(config.SecurityConfiguration.ApplicationCertificate.Certificate);

                if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates)
                {
                    config.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);
                }
            }
            else
            {
                //TODO: throw EX: missing application certificate, using unsecure connection
            }

            // Discover endpoints
            var selectedEndpoint = CoreClientUtils.SelectEndpoint(endpointURL, haveAppCertificate);

            //Create a session with OPC UA server
            var endpointConfiguration = EndpointConfiguration.Create(config);
            var endpoint = new ConfiguredEndpoint(null, selectedEndpoint, endpointConfiguration);
            var session  = await Session.Create(config, endpoint, false, ".Net Core OPC UA Console Client", 60000, new UserIdentity(new AnonymousIdentityToken()), null);

            Session = session;
        }
Пример #45
0
        public Session(
            ITransportChannel channel,
            ApplicationConfiguration configuration,
            ConfiguredEndpoint endpoint,
            X509Certificate2 clientCertificate,
            EndpointDescriptionCollection availableEndpoints)
            :
                base(channel)
        {
            Initialize(channel, configuration, endpoint, clientCertificate);

            m_expectedServerEndpoints = availableEndpoints;
        }
Пример #46
0
        /// <summary>
        /// Saves the UA endpoint information associated the CLSID.
        /// </summary>
        /// <param name="clsid">The CLSID used to activate the COM server.</param>
        /// <param name="endpoint">The endpoint.</param>
        private static void SaveConfiguredEndpointToFile(Guid clsid, ConfiguredEndpoint endpoint)
        {
            try
            {
                string relativePath = Utils.Format("{0}\\{1}.xml", ComPseudoServersDirectory, clsid);
                string absolutePath = Utils.GetAbsoluteFilePath(relativePath, false, false, true);

                // oops - nothing found.
                if (absolutePath == null)
                {
                    absolutePath = Utils.GetAbsoluteFilePath(relativePath, true, false, true);
                }

                // open the file.
                FileStream ostrm = File.Open(absolutePath, FileMode.Create, FileAccess.ReadWrite);

                using (XmlTextWriter writer = new XmlTextWriter(ostrm, System.Text.Encoding.UTF8))
                {
                    DataContractSerializer serializer = new DataContractSerializer(typeof(ConfiguredEndpoint));
                    serializer.WriteObject(writer, endpoint);
                }
            }
            catch (Exception e)
            {
                Utils.Trace(e, "Unexpected error saving endpoint configuration for COM Proxy with CLSID={0}.", clsid);
            }
        }
Пример #47
0
        /// <summary>
        /// Create session against endpoint
        /// </summary>
        /// <param name="endpointUrl"></param>
        /// <param name="id"></param>
        /// <param name="wrapper"></param>
        /// <returns></returns>
        private async Task <Session> CreateSessionAsync(string endpointUrl, ConnectionIdentifier id,
                                                        SessionWrapper wrapper)
        {
            var sessionName = $"Azure IIoT {id}";

            var endpointDescription = SelectEndpoint(endpointUrl,
                                                     id.Connection.Endpoint.SecurityMode, id.Connection.Endpoint.SecurityPolicy,
                                                     (int)(id.Connection.OperationTimeout.HasValue ?
                                                           id.Connection.OperationTimeout.Value.TotalMilliseconds :
                                                           kDefaultOperationTimeout));

            if (endpointDescription == null)
            {
                throw new EndpointNotAvailableException(endpointUrl,
                                                        id.Connection.Endpoint.SecurityMode, id.Connection.Endpoint.SecurityPolicy);
            }

            if (id.Connection.Endpoint.SecurityMode.HasValue &&
                id.Connection.Endpoint.SecurityMode != SecurityMode.None &&
                endpointDescription.SecurityMode == MessageSecurityMode.None)
            {
                _logger.Warning("Although the use of security was configured, " +
                                "there was no security-enabled endpoint available at url " +
                                "{endpointUrl}. An endpoint with no security will be used.",
                                endpointUrl);
            }

            var configuredEndpoint = new ConfiguredEndpoint(
                null, endpointDescription, _endpointConfiguration);

            _logger.Information("Creating session '{id}' for endpoint '{endpointUrl}'...", id, endpointUrl);
            using (new PerfMarker(_logger, sessionName)) {
                var userIdentity = id.Connection.User.ToStackModel() ??
                                   new UserIdentity(new AnonymousIdentityToken());
                var session = await Session.Create(
                    _applicationConfiguration, configuredEndpoint,
                    true, sessionName, _clientConfig.DefaultSessionTimeout,
                    userIdentity, null).ConfigureAwait(false);

                session.Handle  = wrapper;
                wrapper.Session = session;

                session.KeepAliveInterval = _clientConfig.KeepAliveInterval > 0 ?
                                            _clientConfig.KeepAliveInterval : kDefaultOperationTimeout;

                session.KeepAlive    += Session_KeepAlive;
                session.Notification += Session_Notification;


                // TODO - store the created session id (node id)?
                if (sessionName != session.SessionName)
                {
                    _logger.Warning("Session '{id}' created with a revised name '{name}'",
                                    id, session.SessionName);
                }
                _logger.Information("Session '{id}' created, loading complex type system ... ", id);
                try {
                    var complexTypeSystem = new ComplexTypeSystem(session);
                    await complexTypeSystem.Load().ConfigureAwait(false);

                    _logger.Information("Session '{id}' complex type system loaded", id);
                }
                catch (Exception ex) {
                    _logger.Error(ex, "Failed to load complex type system for session '{id}'", id);
                }

                return(session);
            }
        }
 /// <summary>
 /// Initializes the object.
 /// </summary>
 public ConnectEndpointEventArgs(ConfiguredEndpoint endpoint, bool updateControl)
 {
     m_endpoint      = endpoint;
     m_updateControl = updateControl;
 }
Пример #49
0
        /// <summary>
        /// Connects to a server.
        /// </summary>
        public void Connect(ConfiguredEndpoint endpoint)
        {
            if (endpoint == null)
            {
                return;
            }

            Session session = SessionsCTRL.Connect(endpoint);

            if (session != null)
            {
                // stop any reconnect operation.
                if (m_reconnectHandler != null)
                {
                    m_reconnectHandler.Dispose();
                    m_reconnectHandler = null;
                }

                m_session = session;
                m_session.KeepAlive += new KeepAliveEventHandler(StandardClient_KeepAlive);
                BrowseCTRL.SetView(m_session, BrowseViewType.Objects, null);
                StandardClient_KeepAlive(m_session, null);
            }
        }
        /// <summary>
        /// Displays the form.
        /// </summary>
        public void Show(ApplicationConfiguration configuration)
        {
            m_configuration = configuration;
            m_endpoint = null;

            ServersCTRL.Initialize(configuration);
            
            ButtonsPN.Visible = false;

            Show();
        }
Пример #51
0
        static void Main(string[] args)
        {
            VariableBrowsePaths = new List<string>();
            VariableBrowsePaths.Add("/6:Data/6:Dynamic/6:Scalar/6:Int32Value");
            // VariableBrowsePaths.Add("/7:MatrikonOpc Sim Server/7:Simulation Items/7:Bucket Brigade/7:Int1");
            // VariableBrowsePaths.Add("/7:MatrikonOPC Sim Server/7:Simulation Items/7:Bucket Brigade/7:Int2");


            try
            { 
                // create the configuration.     
                ApplicationConfiguration configuration = Helpers.CreateClientConfiguration();

                // create the endpoint description.
                EndpointDescription endpointDescription = Helpers.CreateEndpointDescription();

                // create the endpoint configuration (use the application configuration to provide default values).
                EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(configuration);

                // the default timeout for a requests sent using the channel.
                endpointConfiguration.OperationTimeout = 600000;

                // use the pure XML encoding on the wire.
                endpointConfiguration.UseBinaryEncoding = true;

                // create the endpoint.
                ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration);

                // create the binding factory.
                ServiceMessageContext messageContext = configuration.CreateMessageContext();
                BindingFactory bindingFactory = BindingFactory.Create(configuration, messageContext);

                // update endpoint description using the discovery endpoint.
                if (endpoint.UpdateBeforeConnect)
                {
                    endpoint.UpdateFromServer(bindingFactory);

                    Console.WriteLine("Updated endpoint description for url: {0}", endpointDescription.EndpointUrl);

                    endpointDescription = endpoint.Description;
                    endpointConfiguration = endpoint.Configuration;
                }

                X509Certificate2 clientCertificate = configuration.SecurityConfiguration.ApplicationCertificate.Find();

                // set up a callback to handle certificate validation errors.
                configuration.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);

                // Initialize the channel which will be created with the server.
                ITransportChannel channel = SessionChannel.Create(
                    configuration,
                    endpointDescription,
                    endpointConfiguration,
                    clientCertificate,
                    messageContext);

                // Wrap the channel with the session object.
                // This call will fail if the server does not trust the client certificate.
                Session session = new Session(channel, configuration, endpoint, null);
                
                session.ReturnDiagnostics = DiagnosticsMasks.All;

                // register keep alive callback.
                // session.KeepAlive += new KeepAliveEventHandler(Session_KeepAlive);

                // passing null for the user identity will create an anonymous session.
                UserIdentity identity = null; // new UserIdentity("iamuser", "password");        

                // create the session. This actually connects to the server.
                session.Open("My Session Name", identity);

                //Read some history values:
                string str = "";
                do
                {
                    Console.WriteLine("Select action from the menu:\n");
                    Console.WriteLine("\t 0 - Browse");
                    Console.WriteLine("\t 1 - Update");
                    Console.WriteLine("\t 2 - ReadRaw");
                    Console.WriteLine("\t 3 - ReadProcessed");
                    Console.WriteLine("\t 4 - ReadAtTime");
                    Console.WriteLine("\t 5 - ReadAttributes");
                    Console.WriteLine("\t 6 - DeleteAtTime");
                    Console.WriteLine("\t 7 - DeleteRaw");


                    Console.WriteLine("\n\tQ - exit\n\n");

                    str = Console.ReadLine();
                    Console.WriteLine("\n");

                    try
                    {
                        if (str == "0")
                        {
                            Browse(session);
                        }
                        else if (str == "1")
                            HistoryUpdate(session);
                        else if (str == "2")
                            HistoryReadRaw(session);
                        else if (str == "3")
                            HistoryReadProcessed(session);
                        else if (str == "4")
                            HistoryReadAtTime(session);
                        else if (str == "5")
                            HistoryReadAttributes(session);
                        else if (str == "6")
                            HistoryDeleteAtTime(session);
                        else if (str == "7")
                            HistoryDeleteRaw(session);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Exception occured: " + e.Message);
                    }

                } while (str != "Q" && str != "q");


                // Display some friendly info to the console and then wait for the ENTER key to be pressed.
                Console.WriteLine( "Connected to {0}.\nPress ENTER to disconnect to end.", DefaultServerUrl);
                Console.ReadLine();

                // Close and Dispose of our session, effectively disconnecting us from the UA Server.
                session.Close();
                session.Dispose();
            }
            catch (Exception e)
            {
                Console.WriteLine( "Unexpected exception: {0}.\nPress ENTER to disconnect to end.", e.Message);
                Console.ReadLine();
                Console.WriteLine();
                Console.WriteLine("========================================================================================");
                Console.WriteLine();
            }
        }
        /// <summary>
        /// Runs the test in a background thread.
        /// </summary>
        private void DoTest(ConfiguredEndpoint endpoint)
        {
            PerformanceTestResult result = new PerformanceTestResult(endpoint, 100);

            result.Results.Add(1, -1);
            result.Results.Add(10, -1);
            result.Results.Add(50, -1);
            result.Results.Add(100, -1);
            result.Results.Add(250, -1);
            result.Results.Add(500, -1);

            try
            {
                // update the endpoint.
                if (endpoint.UpdateBeforeConnect)
                {
                    endpoint.UpdateFromServer();
                }

                SessionClient client = null;

                Uri url = new Uri(endpoint.Description.EndpointUrl);

                ITransportChannel channel = SessionChannel.Create(
                    m_configuration,
                    endpoint.Description,
                    endpoint.Configuration,
                    m_clientCertificate,
                    m_messageContext);

                client = new SessionClient(channel);

                List<int> requestSizes = new List<int>(result.Results.Keys);

                for (int ii = 0; ii < requestSizes.Count; ii++)
                {
                    // update the progress indicator.
                    TestProgress((ii * 100) / requestSizes.Count);

                    lock (m_lock)
                    {
                        if (!m_running)
                        {
                            break;
                        }
                    }

                    int count = requestSizes[ii];

                    // initialize request.
                    RequestHeader requestHeader = new RequestHeader();
                    requestHeader.ReturnDiagnostics = 5000;

                    ReadValueIdCollection nodesToRead = new ReadValueIdCollection(count);

                    for (int jj = 0; jj < count; jj++)
                    {
                        ReadValueId item = new ReadValueId();

                        item.NodeId = new NodeId((uint)jj, 1);
                        item.AttributeId = Attributes.Value;

                        nodesToRead.Add(item);
                    }

                    // ensure valid connection.
                    DataValueCollection results = null;
                    DiagnosticInfoCollection diagnosticInfos = null;

                    client.Read(
                        requestHeader,
                        0,
                        TimestampsToReturn.Both,
                        nodesToRead,
                        out results,
                        out diagnosticInfos);

                    if (results.Count != count)
                    {
                        throw new ServiceResultException(StatusCodes.BadUnknownResponse);
                    }

                    // do test.
                    DateTime start = DateTime.UtcNow;

                    for (int jj = 0; jj < result.Iterations; jj++)
                    {
                        client.Read(
                            requestHeader,
                            0,
                            TimestampsToReturn.Both,
                            nodesToRead,
                            out results,
                            out diagnosticInfos);

                        if (results.Count != count)
                        {
                            throw new ServiceResultException(StatusCodes.BadUnknownResponse);
                        }
                    }

                    DateTime finish = DateTime.UtcNow;

                    long totalTicks = finish.Ticks - start.Ticks;
                    decimal averageMilliseconds = ((((decimal)totalTicks) / ((decimal)result.Iterations))) / ((decimal)TimeSpan.TicksPerMillisecond);
                    result.Results[requestSizes[ii]] = (double)averageMilliseconds;
                }
            }
            finally
            {
                TestComplete(result);
            }
        }
Пример #53
0
        private void ConnectButton_Click(object sender, EventArgs e)
        {
            try
            {
                // get selected endpoint.
                ConfiguredEndpoint endpoint = SelectedEndpoint;

                if (endpoint == null)
                {
                    return;
                }

                // raise event.
                if (m_ConnectEndpoint != null)
                {
                    ConnectEndpointEventArgs args = new ConnectEndpointEventArgs(endpoint, true);

                    m_ConnectEndpoint(this, args);

                    // save endpoint in drop down.
                    if (args.UpdateControl)
                    {
                        // must update the control because the display text may have changed.
                        Initialize(m_endpoints, m_configuration);
                        SelectedEndpoint = endpoint;
                    }
                }              
            }
            catch (Exception exception)
            {
				GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
            }
        }
        /// <summary>
        /// Initializes the object with the endpoint being tested an the number of iterations.
        /// </summary>
        public PerformanceTestResult(ConfiguredEndpoint endpoint, int iterations)
        {
            Initialize();

            m_endpoint   = endpoint;
            m_iterations = iterations;
        }
Пример #55
0
        /// <summary>
		/// Saves the endpoint information in the registry.
		/// </summary>
		public static void Save(ConfiguredEndpoint endpoint)
		{
            if (endpoint == null) throw new ArgumentNullException("endpoint");

			if (endpoint.ComIdentity == null)
			{
				throw new ApplicationException("Endpoint does not have a COM identity specified.");
			}
            
            // choose the clsid for the host process.
            Guid hostClsid = GetServerHostClsid(endpoint.ComIdentity.Specification);
            
            // check of COM host process registered.
            string wrapperPath = ConfigUtils.GetExecutablePath(hostClsid);

            if (String.IsNullOrEmpty(wrapperPath))
            {
				throw new ApplicationException("The UA COM Host process is not registered on the machine.");
            }

			// verify prog id.
			string progId = endpoint.ComIdentity.ProgId;

			if (String.IsNullOrEmpty(progId))
			{
				throw new ApplicationException("Endpoint does not have a valid ProgId.");
			}

            // remove existing CLSID.
            Guid existingClsid = ConfigUtils.CLSIDFromProgID(progId);

            if (existingClsid != Guid.Empty)
            {
                ConfigUtils.UnregisterComServer(existingClsid);
            }

            // determine CLSID to use.
            Guid clsid = endpoint.ComIdentity.Clsid;

            if (clsid == Guid.Empty)
            {
                clsid = existingClsid;

                if (clsid == Guid.Empty)
                {
                    clsid = Guid.NewGuid();
                }

                endpoint.ComIdentity.Clsid = clsid;
            }
            
            // remove existing clsid.
            ConfigUtils.UnregisterComServer(clsid);

			string clsidKey = String.Format(@"CLSID\{{{0}}}", clsid.ToString().ToUpper());

			// create new entries.					
			RegistryKey key = Registry.ClassesRoot.CreateSubKey(clsidKey);
			
			if (key == null)
			{
				throw new ApplicationException("Could not create key: " + clsidKey);
			}

			// save description.
            if (endpoint.Description.Server.ApplicationName != null)
            {
                key.SetValue(null, endpoint.Description.Server.ApplicationName);
            }

			try
			{
				// create local server key.
				RegistryKey subkey = key.CreateSubKey("LocalServer32");

				if (subkey == null)
				{
					throw new ApplicationException("Could not create key: LocalServer32");
				}

				subkey.SetValue(null, wrapperPath);
				subkey.Close();

				// create prog id key.
				subkey = key.CreateSubKey("ProgId");

				if (subkey == null)
				{
					throw new ApplicationException("Could not create key: ProgId");
				}

				subkey.SetValue(null, progId);
				subkey.Close();
			}
			finally
			{
				key.Close();
			} 

            // save the configuration.
            SaveConfiguredEndpoint(clsid, endpoint);

			// create prog id key.
			key = Registry.ClassesRoot.CreateSubKey(progId);
			
			if (key == null)
			{
				throw new ApplicationException("Could not create key: " + progId);
			}

			try
			{	
				// create clsid key.
				RegistryKey subkey = key.CreateSubKey("CLSID");

				if (subkey == null)
				{
					throw new ApplicationException("Could not create key: CLSID");
				}

				subkey.SetValue(null, String.Format("{{{0}}}", clsid.ToString().ToUpper()));
				subkey.Close();

				// create the OPC key use with DA 2.0 servers.
                if (endpoint.ComIdentity.Specification == ComSpecification.DA)
                {
				    subkey = key.CreateSubKey("OPC");

				    if (subkey == null)
				    {
					    throw new ApplicationException("Could not create key: OPC");
				    }

				    subkey.Close();
                }
			}
			finally
			{
				key.Close();
			} 

			// register as wrapper server.
            ConfigUtils.RegisterClassInCategory(clsid, ConfigUtils.CATID_PseudoComServers, "OPC UA COM Pseudo-Servers");

            // register in OPC component categories.
            if (endpoint.ComIdentity.Specification == ComSpecification.DA)
            {
			    ConfigUtils.RegisterClassInCategory(clsid, ConfigUtils.CATID_OPCDAServer20);
#if !OPCUA_NODA3_SUPPORT
			    ConfigUtils.RegisterClassInCategory(clsid, ConfigUtils.CATID_OPCDAServer30);
#endif
            }
             
            else if (endpoint.ComIdentity.Specification == ComSpecification.AE)
            {
			    ConfigUtils.RegisterClassInCategory(clsid, ConfigUtils.CATID_OPCAEServer10);
            }
            
            else if (endpoint.ComIdentity.Specification == ComSpecification.HDA)
            {
			    ConfigUtils.RegisterClassInCategory(clsid, ConfigUtils.CATID_OPCHDAServer10);
            }
		}
Пример #56
0
        /// <summary>
        /// Runs the test in a console.
        /// </summary>
        private static void RunInConsole(string endpointUrl)
        {
            ApplicationConfiguration m_configuration =
                GuiUtils.DoStartupChecks("Opc.Ua.ServerTestTool", ApplicationType.Client, null, true);

            if (m_configuration == null)
            {
                return;
            }

            GuiUtils.OverrideUaTcpImplementation(m_configuration);

            m_configuration.CertificateValidator.CertificateValidation +=
                new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);
            ServerTestConfiguration m_testConfiguration = ServerTestConfiguration.Load(m_configuration.Extensions);

            m_testConfiguration.Coverage              = 30;
            m_testConfiguration.EndpointSelection     = EndpointSelection.All;
            m_testConfiguration.ConnectToAllEndpoints = true;

            // initialize the log file.
            m_logFilePath = null;

            if (m_configuration.TraceConfiguration != null)
            {
                m_logFilePath = Utils.GetAbsoluteFilePath(m_configuration.TraceConfiguration.OutputFilePath, true,
                                                          false, true);
                FileInfo file = new FileInfo(m_logFilePath);
                m_logFilePath  = file.DirectoryName;
                m_logFilePath += "\\Opc.Ua.ServerTestTool";
            }

            if (String.IsNullOrEmpty(m_logFilePath))
            {
                m_logFilePath = m_configuration.SourceFilePath;
            }

            if (!String.IsNullOrEmpty(m_logFilePath))
            {
                try {
                    m_logFilePath += ".";
                    m_logFilePath += Utils.GetAssemblyBuildNumber();
                    m_logFilePath += ".log.txt";

                    using (StreamWriter logWriter = new StreamWriter(File.Open(m_logFilePath, FileMode.Create))) {
                        logWriter.WriteLine(Utils.Format("Logging Started at {0:HH:mm:ss}", DateTime.Now));
                    }
                } catch (Exception exception) {
                    Console.WriteLine(exception.Message);
                }
            }

            // create the test client.
            ServerTestClient testClient = new ServerTestClient(m_configuration);

            ConfiguredEndpointCollection collection = new ConfiguredEndpointCollection();
            ConfiguredEndpoint           endpoint   = collection.Create(endpointUrl);

            testClient.ReportResult +=
                new EventHandler <ServerTestClient.ReportResultEventArgs>(TestClient_ReportTestResult);
            testClient.Run(endpoint, m_testConfiguration);
        }
Пример #57
0
 /// <summary>
 /// Saves the UA endpoint information associated the CLSID.
 /// </summary>
 /// <param name="clsid">The CLSID used to activate the COM server.</param>
 /// <param name="endpoint">The endpoint.</param>
 private static void SaveConfiguredEndpoint(Guid clsid, ConfiguredEndpoint endpoint)
 {
     SaveConfiguredEndpointToFile(clsid, endpoint);
 }
Пример #58
0
        public static async Task ConsoleSampleClient(string endpointURL)
        {
            Console.WriteLine("1 - Create an Application Configuration.");
            Utils.SetTraceOutput(Utils.TraceOutput.DebugAndFile);
            var config = new ApplicationConfiguration()
            {
                ApplicationName       = "UA Core Sample Client",
                ApplicationType       = ApplicationType.Client,
                ApplicationUri        = "urn:" + Utils.GetHostName() + ":OPCFoundation:CoreSampleClient",
                SecurityConfiguration = new SecurityConfiguration
                {
                    ApplicationCertificate = new CertificateIdentifier
                    {
                        StoreType   = "X509Store",
                        StorePath   = "CurrentUser\\UA_MachineDefault",
                        SubjectName = "UA Core Sample Client"
                    },
                    TrustedPeerCertificates = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/UA Applications",
                    },
                    TrustedIssuerCertificates = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/UA Certificate Authorities",
                    },
                    RejectedCertificateStore = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/RejectedCertificates",
                    },
                    NonceLength = 32,
                    AutoAcceptUntrustedCertificates = true
                },
                TransportConfigurations = new TransportConfigurationCollection(),
                TransportQuotas         = new TransportQuotas {
                    OperationTimeout = 15000
                },
                ClientConfiguration = new ClientConfiguration {
                    DefaultSessionTimeout = 60000
                }
            };

            await config.Validate(ApplicationType.Client);

            bool haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null;

            if (!haveAppCertificate)
            {
                Console.WriteLine("    INFO: Creating new application certificate: {0}", config.ApplicationName);

                X509Certificate2 certificate = CertificateFactory.CreateCertificate(
                    config.SecurityConfiguration.ApplicationCertificate.StoreType,
                    config.SecurityConfiguration.ApplicationCertificate.StorePath,
                    null,
                    config.ApplicationUri,
                    config.ApplicationName,
                    config.SecurityConfiguration.ApplicationCertificate.SubjectName,
                    null,
                    CertificateFactory.defaultKeySize,
                    DateTime.UtcNow - TimeSpan.FromDays(1),
                    CertificateFactory.defaultLifeTime,
                    CertificateFactory.defaultHashSize,
                    false,
                    null,
                    null
                    );

                config.SecurityConfiguration.ApplicationCertificate.Certificate = certificate;
            }

            haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null;

            if (haveAppCertificate)
            {
                config.ApplicationUri = Utils.GetApplicationUriFromCertificate(config.SecurityConfiguration.ApplicationCertificate.Certificate);

                if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates)
                {
                    config.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);
                }
            }
            else
            {
                Console.WriteLine("    WARN: missing application certificate, using unsecure connection.");
            }

            Console.WriteLine("2 - Discover endpoints of {0}.", endpointURL);
            var selectedEndpoint = CoreClientUtils.SelectEndpoint(endpointURL, haveAppCertificate);

            Console.WriteLine("    Selected endpoint uses: {0}",
                              selectedEndpoint.SecurityPolicyUri.Substring(selectedEndpoint.SecurityPolicyUri.LastIndexOf('#') + 1));

            Console.WriteLine("3 - Create a session with OPC UA server.");
            var endpointConfiguration = EndpointConfiguration.Create(config);
            var endpoint = new ConfiguredEndpoint(null, selectedEndpoint, endpointConfiguration);
            var session  = await Session.Create(config, endpoint, false, ".Net Core OPC UA Console Client", 60000, new UserIdentity(new AnonymousIdentityToken()), null);

            Console.WriteLine("4 - Browse the OPC UA server namespace.");
            ReferenceDescriptionCollection references;

            Byte[] continuationPoint;

            references = session.FetchReferences(ObjectIds.ObjectsFolder);

            session.Browse(
                null,
                null,
                ObjectIds.ObjectsFolder,
                0u,
                BrowseDirection.Forward,
                ReferenceTypeIds.HierarchicalReferences,
                true,
                (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method,
                out continuationPoint,
                out references);

            Console.WriteLine(" DisplayName, BrowseName, NodeClass");
            foreach (var rd in references)
            {
                Console.WriteLine(" {0}, {1}, {2}", rd.DisplayName, rd.BrowseName, rd.NodeClass);
                ReferenceDescriptionCollection nextRefs;
                byte[] nextCp;
                session.Browse(
                    null,
                    null,
                    ExpandedNodeId.ToNodeId(rd.NodeId, session.NamespaceUris),
                    0u,
                    BrowseDirection.Forward,
                    ReferenceTypeIds.HierarchicalReferences,
                    true,
                    (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method,
                    out nextCp,
                    out nextRefs);

                foreach (var nextRd in nextRefs)
                {
                    Console.WriteLine("   + {0}, {1}, {2}", nextRd.DisplayName, nextRd.BrowseName, nextRd.NodeClass);
                }
            }

            Console.WriteLine("5 - Create a subscription with publishing interval of 1 second.");
            var subscription = new Subscription(session.DefaultSubscription)
            {
                PublishingInterval = 1000
            };

            Console.WriteLine("6 - Add a list of items (server current time and status) to the subscription.");
            var list = new List <MonitoredItem> {
                new MonitoredItem(subscription.DefaultItem)
                {
                    DisplayName = "ServerStatusCurrentTime", StartNodeId = "i=2258"
                }
            };

            list.ForEach(i => i.Notification += OnNotification);
            subscription.AddItems(list);

            Console.WriteLine("7 - Add the subscription to the session.");
            session.AddSubscription(subscription);
            subscription.Create();

            Console.WriteLine("8 - Running...Press any key to exit...");
            Console.ReadKey(true);
        }
Пример #59
0
        /// <summary>
        /// Saves the ConfiguredEndpoint from the registry.
        /// </summary>
        private static void SaveConfiguredEndpointToRegistry(Guid clsid, ConfiguredEndpoint endpoint)
        {
            // serialize the object.
            MemoryStream ostrm = new MemoryStream();
            XmlTextWriter writer = new XmlTextWriter(ostrm, System.Text.Encoding.UTF8);

            try
            {
                DataContractSerializer serializer = new DataContractSerializer(typeof(ConfiguredEndpoint));
                serializer.WriteObject(writer, endpoint);
            }
            finally
            {
                writer.Close();
            }

            // save it in the registry key.
			RegistryKey key = Registry.ClassesRoot.CreateSubKey(String.Format(@"CLSID\{{{0}}}\{1}", clsid, "Endpoint"));

			if (key != null)
			{              
				try
				{
                    key.SetValue(null, ostrm.ToArray(), RegistryValueKind.Binary);
				}
				finally
				{
					key.Close();
				}
            }

            // save it in the registry key.
            key = Registry.LocalMachine.OpenSubKey(String.Format(@"SOFTWARE\Wow6432Node\Classes\CLSID\{{{0}}}\{1}", clsid, "Endpoint"), true);

			if (key != null)
			{              
				try
				{
                    key.SetValue(null, ostrm.ToArray(), RegistryValueKind.Binary);
				}
				finally
				{
					key.Close();
				}
            }
		}
Пример #60
0
        /// <summary>
        /// Saves the endpoint information in the registry.
        /// </summary>
        public static void Save(ConfiguredEndpoint endpoint)
        {
            if (endpoint == null)
            {
                throw new ArgumentNullException("endpoint");
            }

            if (endpoint.ComIdentity == null)
            {
                throw new ApplicationException("Endpoint does not have a COM identity specified.");
            }

            // choose the clsid for the host process.
            Guid hostClsid = GetServerHostClsid(endpoint.ComIdentity.Specification);

            // check of COM host process registered.
            string wrapperPath = ConfigUtils.GetExecutablePath(hostClsid);

            if (String.IsNullOrEmpty(wrapperPath))
            {
                throw new ApplicationException("The UA COM Host process is not registered on the machine.");
            }

            // verify prog id.
            string progId = endpoint.ComIdentity.ProgId;

            if (String.IsNullOrEmpty(progId))
            {
                throw new ApplicationException("Endpoint does not have a valid ProgId.");
            }

            // remove existing CLSID.
            Guid existingClsid = ConfigUtils.CLSIDFromProgID(progId);

            if (existingClsid != Guid.Empty)
            {
                ConfigUtils.UnregisterComServer(existingClsid);
            }

            // determine CLSID to use.
            Guid clsid = endpoint.ComIdentity.Clsid;

            if (clsid == Guid.Empty)
            {
                clsid = existingClsid;

                if (clsid == Guid.Empty)
                {
                    clsid = Guid.NewGuid();
                }

                endpoint.ComIdentity.Clsid = clsid;
            }

            // remove existing clsid.
            ConfigUtils.UnregisterComServer(clsid);

            string clsidKey = String.Format(@"CLSID\{{{0}}}", clsid.ToString().ToUpper());

            // create new entries.
            RegistryKey key = Registry.ClassesRoot.CreateSubKey(clsidKey);

            if (key == null)
            {
                throw new ApplicationException("Could not create key: " + clsidKey);
            }

            // save description.
            if (endpoint.Description.Server.ApplicationName != null)
            {
                key.SetValue(null, endpoint.Description.Server.ApplicationName);
            }

            try
            {
                // create local server key.
                RegistryKey subkey = key.CreateSubKey("LocalServer32");

                if (subkey == null)
                {
                    throw new ApplicationException("Could not create key: LocalServer32");
                }

                subkey.SetValue(null, wrapperPath);
                subkey.Close();

                // create prog id key.
                subkey = key.CreateSubKey("ProgId");

                if (subkey == null)
                {
                    throw new ApplicationException("Could not create key: ProgId");
                }

                subkey.SetValue(null, progId);
                subkey.Close();
            }
            finally
            {
                key.Close();
            }

            // save the configuration.
            SaveConfiguredEndpoint(clsid, endpoint);

            // create prog id key.
            key = Registry.ClassesRoot.CreateSubKey(progId);

            if (key == null)
            {
                throw new ApplicationException("Could not create key: " + progId);
            }

            try
            {
                // create clsid key.
                RegistryKey subkey = key.CreateSubKey("CLSID");

                if (subkey == null)
                {
                    throw new ApplicationException("Could not create key: CLSID");
                }

                subkey.SetValue(null, String.Format("{{{0}}}", clsid.ToString().ToUpper()));
                subkey.Close();

                // create the OPC key use with DA 2.0 servers.
                if (endpoint.ComIdentity.Specification == ComSpecification.DA)
                {
                    subkey = key.CreateSubKey("OPC");

                    if (subkey == null)
                    {
                        throw new ApplicationException("Could not create key: OPC");
                    }

                    subkey.Close();
                }
            }
            finally
            {
                key.Close();
            }

            // register as wrapper server.
            ConfigUtils.RegisterClassInCategory(clsid, ConfigUtils.CATID_PseudoComServers, "OPC UA COM Pseudo-Servers");

            // register in OPC component categories.
            if (endpoint.ComIdentity.Specification == ComSpecification.DA)
            {
                ConfigUtils.RegisterClassInCategory(clsid, ConfigUtils.CATID_OPCDAServer20);
#if !OPCUA_NODA3_SUPPORT
                ConfigUtils.RegisterClassInCategory(clsid, ConfigUtils.CATID_OPCDAServer30);
#endif
            }

            else if (endpoint.ComIdentity.Specification == ComSpecification.AE)
            {
                ConfigUtils.RegisterClassInCategory(clsid, ConfigUtils.CATID_OPCAEServer10);
            }

            else if (endpoint.ComIdentity.Specification == ComSpecification.HDA)
            {
                ConfigUtils.RegisterClassInCategory(clsid, ConfigUtils.CATID_OPCHDAServer10);
            }
        }