/// <summary> /// Initializes the control with a set of items. /// </summary> public void Initialize(Session session, ExpandedNodeId nodeId) { ItemsLV.Items.Clear(); m_session = session; if (m_session == null) { return; } ILocalNode node = m_session.NodeCache.Find(nodeId) as ILocalNode; if (node == null) { return; } IList<IReference> references = null; references = node.References.Find(ReferenceTypes.NonHierarchicalReferences, false, true, m_session.TypeTree); for (int ii = 0; ii < references.Count; ii++) { AddItem(references[ii]); } references = node.References.Find(ReferenceTypes.NonHierarchicalReferences, true, true, m_session.TypeTree); for (int ii = 0; ii < references.Count; ii++) { AddItem(references[ii]); } AdjustColumns(); }
/// <summary> /// Sets the nodes in the control. /// </summary> public void Initialize(Session session, ExpandedNodeId nodeId) { if (session == null) throw new ArgumentNullException("session"); Clear(); if (nodeId == null) { return; } m_session = session; m_nodeId = (NodeId)nodeId; INode node = m_session.NodeCache.Find(m_nodeId); if (node != null && (node.NodeClass & (NodeClass.Variable | NodeClass.Object)) != 0) { AddReferences(ReferenceTypeIds.HasTypeDefinition, BrowseDirection.Forward); AddReferences(ReferenceTypeIds.HasModellingRule, BrowseDirection.Forward); } AddAttributes(); AddProperties(); }
/// <summary cref="INodeTable.Find(ExpandedNodeId)" /> public INode Find(ExpandedNodeId nodeId) { // check for null. if (NodeId.IsNull(nodeId)) { return null; } // check if node alredy exists. INode node = m_nodes.Find(nodeId); if (node != null) { // do not return temporary nodes created after a Browse(). if (node.GetType() != typeof(Node)) { return node; } } // fetch node from server. try { return FetchNode(nodeId); } catch (Exception e) { Utils.Trace("Could not fetch node from server: NodeId={0}, Reason='{1}'.", nodeId, e.Message); // m_nodes[nodeId] = null; return null; } }
/// <summary> /// Displays the dialog. /// </summary> public void ShowDialog(Session session, ExpandedNodeId nodeId) { if (session == null) throw new ArgumentNullException("session"); if (nodeId == null) throw new ArgumentNullException("nodeId"); m_session = session; m_nodeId = nodeId; AttributesCTRL.Initialize(session, nodeId); if (ShowDialog() != DialogResult.OK) { return; } }
/// <summary> /// Displays the dialog. /// </summary> public ExpandedNodeId ShowDialog(Session session, ExpandedNodeId value) { if (session == null) throw new ArgumentNullException("session"); ValueCTRL.Browser = new Browser(session); ValueCTRL.RootId = Objects.RootFolder; ValueCTRL.Identifier = ExpandedNodeId.ToNodeId(value, session.NamespaceUris); if (ShowDialog() != DialogResult.OK) { return null; } return ValueCTRL.Identifier; }
/// <see cref="INodeManager.GetManagerHandle" /> private object GetManagerHandle(ExpandedNodeId nodeId) { lock (m_lock) { if (nodeId == null || nodeId.IsAbsolute) { return null; } return GetLocalNode(nodeId) as ILocalNode; } }
/// <inheritdoc /> public void WriteExpandedNodeId(string fieldName, ExpandedNodeId value) { _callback?.Invoke(value); _wrapped.WriteExpandedNodeId(fieldName, value); }
/// <summary> /// Fetches a node from the server and updates the cache. /// </summary> public Node FetchNode(ExpandedNodeId nodeId) { NodeId localId = ExpandedNodeId.ToNodeId(nodeId, m_session.NamespaceUris); if (localId == null) { return null; } // fetch node from server. Node source = m_session.ReadNode(localId); try { // fetch references from server. ReferenceDescriptionCollection references = m_session.FetchReferences(localId); foreach (ReferenceDescription reference in references) { // create a placeholder for the node if it does not already exist. if (!m_nodes.Exists(reference.NodeId)) { Node target = new Node(reference); m_nodes.Attach(target); } // add the reference. source.ReferenceTable.Add(reference.ReferenceTypeId, !reference.IsForward, reference.NodeId); } } catch (Exception e) { Utils.Trace("Could not fetch references for valid node with NodeId = {0}. Error = {1}", nodeId, e.Message); } // add to cache. m_nodes.Attach(source); return source; }
/// <summary> /// Returns a display name for a node. /// </summary> public string GetDisplayText(ExpandedNodeId nodeId) { if (NodeId.IsNull(nodeId)) { return String.Empty; } INode node = Find(nodeId); if (node != null) { return GetDisplayText(node); } return Utils.Format("{0}", nodeId); }
/// <summary cref="INodeTable.Find(ExpandedNodeId,NodeId,bool,bool,QualifiedName)" /> public INode Find( ExpandedNodeId sourceId, NodeId referenceTypeId, bool isInverse, bool includeSubtypes, QualifiedName browseName) { // find the source. Node source = Find(sourceId) as Node; if (source == null) { return null; } // find all references. IList<IReference> references = source.ReferenceTable.Find(referenceTypeId, isInverse, includeSubtypes, m_typeTree); foreach (IReference reference in references) { INode target = Find(reference.TargetId); if (target == null) { continue; } if (target.BrowseName == browseName) { return target; } } // target not found. return null; }
/// <summary> /// Returns the immediate subtypes for the type. /// </summary> /// <param name="typeId">The extended type identifier.</param> /// <returns> /// List of type identifiers for <paramref name="typeId"/> /// </returns> public IList<NodeId> FindSubTypes(ExpandedNodeId typeId) { ILocalNode type = Find(typeId) as ILocalNode; if (type == null) { return new List<NodeId>(); } List<NodeId> subtypes = new List<NodeId>(); foreach (IReference reference in type.References.Find(ReferenceTypeIds.HasSubtype, false, true, m_typeTree)) { if (!reference.TargetId.IsAbsolute) { subtypes.Add((NodeId)reference.TargetId); } } return subtypes; }
/// <summary cref="INodeTable.Exists(ExpandedNodeId)" /> public bool Exists(ExpandedNodeId nodeId) { return(Find(nodeId) != null); }
/// <summary> /// Reads the trust list. /// </summary> public TrustListDataType ReadTrustList(TrustListMasks masks = TrustListMasks.All) { if (!IsConnected) { Connect(); } IUserIdentity oldUser = ElevatePermissions(); try { var outputArguments = m_session.Call( ExpandedNodeId.ToNodeId(Opc.Ua.ObjectIds.ServerConfiguration_CertificateGroups_DefaultApplicationGroup_TrustList, m_session.NamespaceUris), ExpandedNodeId.ToNodeId(Opc.Ua.MethodIds.ServerConfiguration_CertificateGroups_DefaultApplicationGroup_TrustList_OpenWithMasks, m_session.NamespaceUris), (uint)masks); uint fileHandle = (uint)outputArguments[0]; MemoryStream ostrm = new MemoryStream(); try { while (true) { int length = 256; outputArguments = m_session.Call( ExpandedNodeId.ToNodeId(Opc.Ua.ObjectIds.ServerConfiguration_CertificateGroups_DefaultApplicationGroup_TrustList, m_session.NamespaceUris), ExpandedNodeId.ToNodeId(Opc.Ua.MethodIds.ServerConfiguration_CertificateGroups_DefaultApplicationGroup_TrustList_Read, m_session.NamespaceUris), fileHandle, length); byte[] bytes = (byte[])outputArguments[0]; ostrm.Write(bytes, 0, bytes.Length); if (length != bytes.Length) { break; } } m_session.Call( ExpandedNodeId.ToNodeId(Opc.Ua.ObjectIds.ServerConfiguration_CertificateGroups_DefaultApplicationGroup_TrustList, m_session.NamespaceUris), ExpandedNodeId.ToNodeId(Opc.Ua.MethodIds.ServerConfiguration_CertificateGroups_DefaultApplicationGroup_TrustList_Close, m_session.NamespaceUris), fileHandle); } catch (Exception) { if (IsConnected) { m_session.Call( ExpandedNodeId.ToNodeId(Opc.Ua.ObjectIds.ServerConfiguration_CertificateGroups_DefaultApplicationGroup_TrustList, m_session.NamespaceUris), ExpandedNodeId.ToNodeId(Opc.Ua.MethodIds.ServerConfiguration_CertificateGroups_DefaultApplicationGroup_TrustList_Close, m_session.NamespaceUris), fileHandle); } throw; } ostrm.Position = 0; BinaryDecoder decoder = new BinaryDecoder(ostrm, m_session.MessageContext); TrustListDataType trustList = new TrustListDataType(); trustList.Decode(decoder); decoder.Close(); ostrm.Close(); return(trustList); } finally { RevertPermissions(oldUser); } }
/// <summary> /// Creates a new instance. /// </summary> internal NodesSelectedEventArgs(ExpandedNodeId sourceId, ReferenceDescriptionCollection references) { m_sourceId = sourceId; m_references = references; }
/// <see cref="BaseTreeCtrl.EnableMenuItems" /> protected override void EnableMenuItems(TreeNode clickedNode) { BrowseOptionsMI.Enabled = true; ShowReferencesMI.Enabled = true; SelectMI.Visible = m_allowPick; SelectSeparatorMI.Visible = m_allowPick; if (clickedNode != null) { // do nothing if an error is detected. if (m_browser.Session.KeepAliveStopped) { return; } SelectMI.Enabled = true; SelectItemMI.Enabled = true; SelectChildrenMI.Enabled = clickedNode.Nodes.Count > 0; BrowseRefreshMI.Enabled = true; ReferenceDescription reference = clickedNode.Tag as ReferenceDescription; if (reference != null) { BrowseMI.Enabled = (reference.NodeId != null && !reference.NodeId.IsAbsolute); ViewAttributesMI.Enabled = true; NodeId nodeId = ExpandedNodeId.ToNodeId(reference.NodeId, m_browser.Session.NamespaceUris); INode node = m_browser.Session.ReadNode(nodeId); byte accessLevel = 0; byte eventNotifier = 0; bool executable = false; VariableNode variableNode = node as VariableNode; if (variableNode != null) { accessLevel = variableNode.UserAccessLevel; } ObjectNode objectNode = node as ObjectNode; if (objectNode != null) { eventNotifier = objectNode.EventNotifier; } ViewNode viewNode = node as ViewNode; if (viewNode != null) { eventNotifier = viewNode.EventNotifier; } MethodNode methodNode = node as MethodNode; if (methodNode != null) { executable = methodNode.UserExecutable; } ReadMI.Visible = false; HistoryReadMI.Visible = false; WriteMI.Visible = false; HistoryUpdateMI.Visible = false; EncodingsMI.Visible = false; SubscribeMI.Visible = false; CallMI.Visible = false; if (accessLevel != 0) { ReadMI.Visible = true; HistoryReadMI.Visible = true; WriteMI.Visible = true; HistoryUpdateMI.Visible = true; EncodingsMI.Visible = true; SubscribeMI.Visible = m_SessionTreeCtrl != null; if ((accessLevel & (byte)AccessLevels.CurrentRead) != 0) { ReadMI.Enabled = true; EncodingsMI.Enabled = true; SubscribeMI.Enabled = true; SubscribeNewMI.Enabled = true; } if ((accessLevel & (byte)AccessLevels.CurrentWrite) != 0) { WriteMI.Enabled = true; EncodingsMI.Enabled = true; } if ((accessLevel & (byte)AccessLevels.HistoryRead) != 0) { HistoryReadMI.Enabled = true; } if ((accessLevel & (byte)AccessLevels.HistoryWrite) != 0) { HistoryUpdateMI.Enabled = true; } } if (eventNotifier != 0) { HistoryReadMI.Visible = true; HistoryUpdateMI.Visible = true; SubscribeMI.Visible = true; if ((eventNotifier & (byte)EventNotifiers.HistoryRead) != 0) { HistoryReadMI.Enabled = true; } if ((eventNotifier & (byte)EventNotifiers.HistoryWrite) != 0) { HistoryUpdateMI.Enabled = true; } SubscribeMI.Enabled = (eventNotifier & (byte)EventNotifiers.SubscribeToEvents) != 0; SubscribeNewMI.Enabled = SubscribeMI.Enabled; } if (methodNode != null) { CallMI.Visible = true; CallMI.Enabled = executable; } if (variableNode != null && EncodingsMI.Enabled) { ReferenceDescriptionCollection encodings = m_browser.Session.ReadAvailableEncodings(variableNode.NodeId); if (encodings.Count == 0) { EncodingsMI.Visible = false; } } if (SubscribeMI.Enabled) { while (SubscribeMI.DropDown.Items.Count > 1) { SubscribeMI.DropDown.Items.RemoveAt(SubscribeMI.DropDown.Items.Count - 1); } foreach (Subscription subscription in m_browser.Session.Subscriptions) { if (subscription.Created) { ToolStripItem item = SubscribeMI.DropDown.Items.Add(subscription.DisplayName); item.Click += new EventHandler(Subscription_Click); item.Tag = subscription; } } } } } }
public void ResendData() { var serverTestServices = new ServerTestServices(m_server); // save old security context, test fixture can only work with one session var securityContext = SecureChannelContext.Current; try { var namespaceUris = m_server.CurrentInstance.NamespaceUris; NodeId[] testSet = CommonTestWorkers.NodeIdTestSetStatic.Select(n => ExpandedNodeId.ToNodeId(n, namespaceUris)).ToArray(); //Re-use method CreateSubscriptionForTransfer to create a subscription CommonTestWorkers.CreateSubscriptionForTransfer(serverTestServices, m_requestHeader, testSet, out var subscriptionIds); RequestHeader resendDataRequestHeader = m_server.CreateAndActivateSession("ResendData"); var resendDataSecurityContext = SecureChannelContext.Current; // After the ResendData call there will be data to publish again MethodState methodStateInstance = (MethodState)m_server.CurrentInstance. DiagnosticsNodeManager.FindPredefinedNode(MethodIds.Server_ResendData, typeof(MethodState)); var nodesToCall = new CallMethodRequestCollection(); nodesToCall.Add(new CallMethodRequest() { ObjectId = ObjectIds.Server, MethodId = MethodIds.Server_ResendData, InputArguments = new VariantCollection() { new Variant(subscriptionIds.Last()) } }); //call ResendData method from the same session context m_requestHeader.Timestamp = DateTime.UtcNow; var response = m_server.Call(m_requestHeader, nodesToCall, out var results, out var diagnosticInfos); Assert.IsTrue(StatusCode.IsGood(results[0].StatusCode)); ServerFixtureUtils.ValidateResponse(response); Thread.Sleep(1000); // Make sure publish queue becomes empty by consuming it Assert.AreEqual(1, subscriptionIds.Count); // Issue a Publish request m_requestHeader.Timestamp = DateTime.UtcNow; var acknoledgements = new SubscriptionAcknowledgementCollection(); response = serverTestServices.Publish(m_requestHeader, acknoledgements, out uint publishedId, out UInt32Collection availableSequenceNumbers, out bool moreNotifications, out NotificationMessage notificationMessage, out StatusCodeCollection _, out diagnosticInfos); Assert.AreEqual(StatusCodes.Good, response.ServiceResult.Code); ServerFixtureUtils.ValidateResponse(response); ServerFixtureUtils.ValidateDiagnosticInfos(diagnosticInfos, acknoledgements); Assert.AreEqual(subscriptionIds[0], publishedId); Assert.AreEqual(1, notificationMessage.NotificationData.Count); // Validate nothing to publish a few times const int timesToCallPublish = 3; for (int i = 0; i < timesToCallPublish; i++) { m_requestHeader.Timestamp = DateTime.UtcNow; response = serverTestServices.Publish(m_requestHeader, acknoledgements, out publishedId, out availableSequenceNumbers, out moreNotifications, out notificationMessage, out StatusCodeCollection _, out diagnosticInfos); Assert.AreEqual(StatusCodes.Good, response.ServiceResult.Code); ServerFixtureUtils.ValidateResponse(response); ServerFixtureUtils.ValidateDiagnosticInfos(diagnosticInfos, acknoledgements); Assert.AreEqual(subscriptionIds[0], publishedId); Assert.AreEqual(0, notificationMessage.NotificationData.Count); } // Validate ResendData method call from same and different session contexts // call ResendData method from different session context resendDataRequestHeader.Timestamp = DateTime.UtcNow; response = m_server.Call(resendDataRequestHeader, nodesToCall, out results, out diagnosticInfos); Assert.AreEqual(StatusCodes.BadUserAccessDenied, results[0].StatusCode.Code); ServerFixtureUtils.ValidateResponse(response); // Still nothing to publish since previous ResendData call did not execute m_requestHeader.Timestamp = DateTime.UtcNow; response = serverTestServices.Publish(m_requestHeader, acknoledgements, out publishedId, out availableSequenceNumbers, out moreNotifications, out notificationMessage, out StatusCodeCollection _, out diagnosticInfos); Assert.AreEqual(StatusCodes.Good, response.ServiceResult.Code); ServerFixtureUtils.ValidateResponse(response); ServerFixtureUtils.ValidateDiagnosticInfos(diagnosticInfos, acknoledgements); Assert.AreEqual(subscriptionIds[0], publishedId); Assert.AreEqual(0, notificationMessage.NotificationData.Count); //call ResendData method from the same session context m_requestHeader.Timestamp = DateTime.UtcNow; response = m_server.Call(m_requestHeader, nodesToCall, out results, out diagnosticInfos); Assert.IsTrue(StatusCode.IsGood(results[0].StatusCode)); ServerFixtureUtils.ValidateResponse(response); // Data should be available for publishing now m_requestHeader.Timestamp = DateTime.UtcNow; response = serverTestServices.Publish(m_requestHeader, acknoledgements, out publishedId, out availableSequenceNumbers, out moreNotifications, out notificationMessage, out StatusCodeCollection _, out diagnosticInfos); Assert.AreEqual(StatusCodes.Good, response.ServiceResult.Code); ServerFixtureUtils.ValidateResponse(response); ServerFixtureUtils.ValidateDiagnosticInfos(diagnosticInfos, acknoledgements); Assert.AreEqual(subscriptionIds[0], publishedId); Assert.AreEqual(1, notificationMessage.NotificationData.Count); // Call ResendData method with invalid subscription Id nodesToCall = new CallMethodRequestCollection(); nodesToCall.Add(new CallMethodRequest() { ObjectId = ObjectIds.Server, MethodId = MethodIds.Server_ResendData, InputArguments = new VariantCollection() { new Variant(subscriptionIds.Last() + 20) } }); m_requestHeader.Timestamp = DateTime.UtcNow; response = m_server.Call(m_requestHeader, nodesToCall, out results, out diagnosticInfos); Assert.AreEqual(StatusCodes.BadSubscriptionIdInvalid, results[0].StatusCode.Code); ServerFixtureUtils.ValidateResponse(response); // Nothing to publish since previous ResendData call did not execute m_requestHeader.Timestamp = DateTime.UtcNow; response = serverTestServices.Publish(m_requestHeader, acknoledgements, out publishedId, out availableSequenceNumbers, out moreNotifications, out notificationMessage, out StatusCodeCollection _, out diagnosticInfos); Assert.AreEqual(StatusCodes.Good, response.ServiceResult.Code); ServerFixtureUtils.ValidateResponse(response); ServerFixtureUtils.ValidateDiagnosticInfos(diagnosticInfos, acknoledgements); Assert.AreEqual(subscriptionIds[0], publishedId); Assert.AreEqual(0, notificationMessage.NotificationData.Count); resendDataRequestHeader.Timestamp = DateTime.UtcNow; SecureChannelContext.Current = resendDataSecurityContext; m_server.CloseSession(resendDataRequestHeader); } finally { //restore security context, that close connection can work SecureChannelContext.Current = securityContext; } }
public void TransferSubscription(bool sendInitialData, bool useSecurity) { var serverTestServices = new ServerTestServices(m_server); // save old security context, test fixture can only work with one session var securityContext = SecureChannelContext.Current; try { var namespaceUris = m_server.CurrentInstance.NamespaceUris; NodeId[] testSet = CommonTestWorkers.NodeIdTestSetStatic.Select(n => ExpandedNodeId.ToNodeId(n, namespaceUris)).ToArray(); CommonTestWorkers.CreateSubscriptionForTransfer(serverTestServices, m_requestHeader, testSet, out var subscriptionIds); RequestHeader transferRequestHeader = m_server.CreateAndActivateSession("TransferSession", useSecurity); var transferSecurityContext = SecureChannelContext.Current; CommonTestWorkers.TransferSubscriptionTest(serverTestServices, transferRequestHeader, subscriptionIds, sendInitialData, !useSecurity); if (useSecurity) { //restore security context SecureChannelContext.Current = securityContext; CommonTestWorkers.VerifySubscriptionTransferred(serverTestServices, m_requestHeader, subscriptionIds, true); } transferRequestHeader.Timestamp = DateTime.UtcNow; SecureChannelContext.Current = transferSecurityContext; m_server.CloseSession(transferRequestHeader); } finally { //restore security context, that close connection can work SecureChannelContext.Current = securityContext; } }
public void TransferSubscriptionSessionClosed(bool sendInitialData, bool useSecurity) { var serverTestServices = new ServerTestServices(m_server); // save old security context, test fixture can only work with one session var securityContext = SecureChannelContext.Current; try { RequestHeader transferRequestHeader = m_server.CreateAndActivateSession("ClosedSession", useSecurity); var transferSecurityContext = SecureChannelContext.Current; var namespaceUris = m_server.CurrentInstance.NamespaceUris; NodeId[] testSet = CommonTestWorkers.NodeIdTestSetStatic.Select(n => ExpandedNodeId.ToNodeId(n, namespaceUris)).ToArray(); transferRequestHeader.Timestamp = DateTime.UtcNow; CommonTestWorkers.CreateSubscriptionForTransfer(serverTestServices, transferRequestHeader, testSet, out var subscriptionIds); transferRequestHeader.Timestamp = DateTime.UtcNow; m_server.CloseSession(transferRequestHeader, false); //restore security context, transfer abandoned subscription SecureChannelContext.Current = securityContext; CommonTestWorkers.TransferSubscriptionTest(serverTestServices, m_requestHeader, subscriptionIds, sendInitialData, !useSecurity); if (useSecurity) { // subscription was deleted, expect 'BadNoSubscription' var sre = Assert.Throws <ServiceResultException>(() => { m_requestHeader.Timestamp = DateTime.UtcNow; CommonTestWorkers.VerifySubscriptionTransferred(serverTestServices, m_requestHeader, subscriptionIds, true); }); Assert.AreEqual(StatusCodes.BadNoSubscription, sre.StatusCode); } } finally { //restore security context, that close connection can work SecureChannelContext.Current = securityContext; } }
/// <summary> /// Adds the reference types to drop down box. /// </summary> private void AddReferenceTypes(ExpandedNodeId referenceTypeId, ReferenceTypeChoice supertype) { if (referenceTypeId == null) throw new ApplicationException("referenceTypeId"); try { // find reference. ReferenceTypeNode node = m_session.NodeCache.Find(referenceTypeId) as ReferenceTypeNode; if (node == null) { return; } // add reference to combobox. ReferenceTypeChoice choice = new ReferenceTypeChoice(); choice.ReferenceType = node; choice.SuperType = supertype; ReferenceTypesCB.Items.Add(choice); // recursively add subtypes. IList<INode> subtypes = m_session.NodeCache.FindReferences(node.NodeId, ReferenceTypeIds.HasSubtype, false, true); foreach (INode subtype in subtypes) { AddReferenceTypes(subtype.NodeId, choice); } } catch (Exception e) { Utils.Trace(e, "Ignoring unknown reference type."); return; } }
/// <summary> /// Updates the trust list. /// </summary> public bool UpdateTrustList(TrustListDataType trustList) { if (!IsConnected) { Connect(); } IUserIdentity oldUser = ElevatePermissions(); try { MemoryStream strm = new MemoryStream(); BinaryEncoder encoder = new BinaryEncoder(strm, m_session.MessageContext); encoder.WriteEncodeable(null, trustList, null); strm.Position = 0; var outputArguments = m_session.Call( ExpandedNodeId.ToNodeId(Opc.Ua.ObjectIds.ServerConfiguration_CertificateGroups_DefaultApplicationGroup_TrustList, m_session.NamespaceUris), ExpandedNodeId.ToNodeId(Opc.Ua.MethodIds.ServerConfiguration_CertificateGroups_DefaultApplicationGroup_TrustList_Open, m_session.NamespaceUris), (byte)(OpenFileMode.Write | OpenFileMode.EraseExisting)); uint fileHandle = (uint)outputArguments[0]; try { bool writing = true; byte[] buffer = new byte[256]; while (writing) { int bytesWritten = strm.Read(buffer, 0, buffer.Length); if (bytesWritten != buffer.Length) { byte[] copy = new byte[bytesWritten]; Array.Copy(buffer, copy, bytesWritten); buffer = copy; writing = false; } m_session.Call( ExpandedNodeId.ToNodeId(Opc.Ua.ObjectIds.ServerConfiguration_CertificateGroups_DefaultApplicationGroup_TrustList, m_session.NamespaceUris), ExpandedNodeId.ToNodeId(Opc.Ua.MethodIds.ServerConfiguration_CertificateGroups_DefaultApplicationGroup_TrustList_Write, m_session.NamespaceUris), fileHandle, buffer); } outputArguments = m_session.Call( ExpandedNodeId.ToNodeId(Opc.Ua.ObjectIds.ServerConfiguration_CertificateGroups_DefaultApplicationGroup_TrustList, m_session.NamespaceUris), ExpandedNodeId.ToNodeId(Opc.Ua.MethodIds.ServerConfiguration_CertificateGroups_DefaultApplicationGroup_TrustList_CloseAndUpdate, m_session.NamespaceUris), fileHandle); return((bool)outputArguments[0]); } catch (Exception) { if (IsConnected) { m_session.Call( ExpandedNodeId.ToNodeId(Opc.Ua.ObjectIds.ServerConfiguration_CertificateGroups_DefaultApplicationGroup_TrustList, m_session.NamespaceUris), ExpandedNodeId.ToNodeId(Opc.Ua.MethodIds.ServerConfiguration_CertificateGroups_DefaultApplicationGroup_TrustList_Close, m_session.NamespaceUris), fileHandle); } throw; } } finally { RevertPermissions(oldUser); } }
public NodeId CreateVariable( NodeId parentId, NodeId referenceTypeId, NodeId nodeId, QualifiedName browseName, VariableAttributes attributes, ExpandedNodeId typeDefinitionId) { return null; }
/// <summary> /// Top level creation functions. Uses the definitions of RootAAS, RootConceptDescriptions, /// RootDataSpecifications to synthesize information model /// </summary> public void CreateAddInstanceObjects(AdminShell.AdministrationShellEnv env) { if (RootAAS == null) { return; } // CDs (build 1st to be "remembered" as targets for "HasDictionaryEntry") if (env.ConceptDescriptions != null && this.RootConceptDescriptions != null) { foreach (var cd in env.ConceptDescriptions) { this.AasTypes.ConceptDescription.CreateAddElements(this.RootConceptDescriptions, AasUaBaseEntity.CreateMode.Instance, cd); } } // AAS if (env.AdministrationShells != null) { foreach (var aas in env.AdministrationShells) { this.AasTypes.AAS.CreateAddInstanceObject(RootAAS, env, aas); } } // go through late actions foreach (var la in this.noteLateActions) { // make a Reference ?? var lax = la as NodeLateActionLinkToReference; // more simple case: AasReference between known entities if (lax != null && lax.actionType == NodeLateActionLinkToReference.ActionType.SetAasReference && lax.uanode != null && this.package != null && this.package.AasEnv != null) { // 1st, take reference and turn it into Referable var targetReferable = this.package.AasEnv.FindReferableByReference(lax.targetReference); if (targetReferable == null) { continue; } // 2nd, try to lookup the Referable and turn it into a uanode var targetNodeRec = this.LookupNodeRecordFromReferable(targetReferable); if (targetNodeRec == null || targetNodeRec.uanode == null) { continue; } // now, we have everything to formulate a reference lax.uanode.AddReference(this.AasTypes.HasAasReference.GetTypeNodeId(), false, targetNodeRec.uanode.NodeId); } // a bit more complicated: could include a "empty reference" to outside concept if (lax != null && lax.actionType == NodeLateActionLinkToReference.ActionType.SetDictionaryEntry && lax.uanode != null && this.package != null && this.package.AasEnv != null) { // tracking var foundAtAll = false; // 1st, take reference and turn it into Referable var targetReferable = this.package.AasEnv.FindReferableByReference(lax.targetReference); if (targetReferable != null) { // 2nd, try to lookup the Referable and turn it into a uanode var targetNodeRec = this.LookupNodeRecordFromReferable(targetReferable); if (targetNodeRec != null && targetNodeRec.uanode != null) { // simple case: have a target node, just make a link lax.uanode.AddReference(this.AasTypes.HasDictionaryEntry.GetTypeNodeId(), false, targetNodeRec.uanode.NodeId); foundAtAll = true; } } // make "empty reference"?? // by definition, this makes only sense if the targetReference has exactly 1 key, as we could // only have one key in a dictionary entry if (!foundAtAll && lax.targetReference.Keys.Count == 1) { // can turn the targetReference to a simple identification var targetId = new AdminShell.Identification(lax.targetReference.Keys[0].idType, lax.targetReference.Keys[0].value); // we might have such an (empty) target already available as uanode var nr = this.LookupNodeRecordFromIdentification(targetId); if (nr != null) { // just create the missing link lax.uanode.AddReference(this.AasTypes.HasDictionaryEntry.GetTypeNodeId(), false, nr.uanode?.NodeId); } else { // create NEW empty reference? if (this.RootMissingDictionaryEntries != null) { // create missing object var miss = this.CreateAddObject( this.RootMissingDictionaryEntries, targetId.id, ReferenceTypeIds.HasComponent, this.AasTypes.ConceptDescription.GetTypeObjectFor(targetId)?.NodeId); // add the reference lax.uanode.AddReference(this.AasTypes.HasDictionaryEntry.GetTypeNodeId(), false, miss?.NodeId); // put it into the NodeRecords, that it can be re-used?? no!! this.AddNodeRecord(new AasEntityBuilder.NodeRecord(miss, targetId)); } else { // just create the missing link // TODO (MIHO, 2020-08-06): check, which namespace shall be used var missingTarget = new ExpandedNodeId("" + targetId.id, 99); lax.uanode.AddReference(this.AasTypes.HasDictionaryEntry.GetTypeNodeId(), false, missingTarget); } } } } } }
/// <summary> /// Determines whether a node id is a known type id. /// </summary> /// <param name="typeId">The type extended identifier.</param> /// <returns> /// <c>true</c> if the specified type id is known; otherwise, <c>false</c>. /// </returns> public bool IsKnown(ExpandedNodeId typeId) { INode type = Find(typeId); if (type == null) { return false; } return m_typeTree.IsKnown(typeId); }
public AasReference(NodeId referenceTypeId, bool isInverse, ExpandedNodeId targetId) { this.referenceTypeId = referenceTypeId; this.isInverse = isInverse; this.targetId = targetId; }
/// <summary> /// Checks if the identifier <paramref name="encodingId"/> represents a that provides encodings /// for the <paramref name="datatypeId "/>. /// </summary> /// <param name="encodingId">The id the encoding node .</param> /// <param name="datatypeId">The id of the DataType node.</param> /// <returns> /// <c>true</c> if <paramref name="encodingId"/> is encoding of the <paramref name="datatypeId"/>; otherwise, <c>false</c>. /// </returns> public bool IsEncodingOf(ExpandedNodeId encodingId, ExpandedNodeId datatypeId) { ILocalNode encoding = Find(encodingId) as ILocalNode; if (encoding == null) { return false; } foreach (IReference reference in encoding.References.Find(ReferenceTypeIds.HasEncoding, true, true, m_typeTree)) { if (reference.TargetId == datatypeId) { return true; } } // no match. return false; }
/// <summary> /// Converts a remote value to a local value. /// </summary> /// <param name="srcValue">The remote value.</param> /// <param name="srcType">The data type of the remote value.</param> /// <param name="dstType">The data type of the local value.</param> /// <returns>The local value.</returns> private object ConvertRemoteToLocal(object srcValue, BuiltInType srcType, BuiltInType dstType) { // check for null. if (srcValue == null) { return(null); } // must determine the type from the source if the containing array is a variant. if (srcType == BuiltInType.Variant) { TypeInfo typeInfo = TypeInfo.Construct(srcValue); srcType = typeInfo.BuiltInType; if (typeInfo.ValueRank != ValueRanks.Scalar) { return(TypeInfo.CastArray((Array)srcValue, srcType, BuiltInType.Null, ConvertRemoteToLocal)); } } // no conversion by default. object dstValue = srcValue; // apply different conversions depending on the data type. switch (srcType) { case BuiltInType.Guid: { dstValue = ((Uuid)srcValue).ToString(); break; } case BuiltInType.XmlElement: { dstValue = ((XmlElement)srcValue).OuterXml; break; } case BuiltInType.NodeId: { dstValue = GetLocalItemId((NodeId)srcValue); break; } case BuiltInType.ExpandedNodeId: { ExpandedNodeId nodeId = GetLocaleExpandedNodeId((ExpandedNodeId)srcValue); dstValue = nodeId.ToString(); break; } case BuiltInType.QualifiedName: { dstValue = GetLocalBrowseName((QualifiedName)srcValue); break; } case BuiltInType.LocalizedText: { dstValue = ((LocalizedText)srcValue).Text; break; } case BuiltInType.StatusCode: { dstValue = ((StatusCode)srcValue).Code; break; } case BuiltInType.ExtensionObject: { BinaryEncoder encoder = new BinaryEncoder(m_localMessageContext); encoder.WriteExtensionObject(null, (ExtensionObject)srcValue); dstValue = encoder.CloseAndReturnBuffer(); break; } case BuiltInType.Variant: { dstValue = ((Variant)srcValue).Value; break; } default: { if (dstType != srcType && dstType != BuiltInType.Variant && dstType != BuiltInType.Null) { throw ComUtils.CreateComException(ResultIds.E_BADTYPE); } break; } } // all done. return(dstValue); }
/// <summary> /// Returns the references of the specified node that meet the criteria specified. /// </summary> public IList<INode> FindReferences( ExpandedNodeId nodeId, NodeId referenceTypeId, bool isInverse, bool includeSubtypes) { IList<INode> targets = new List<INode>(); Node source = Find(nodeId) as Node; if (source == null) { return targets; } IList<IReference> references = source.ReferenceTable.Find( referenceTypeId, isInverse, includeSubtypes, m_typeTree); foreach (IReference reference in references) { INode target = Find(reference.TargetId); if (target != null) { targets.Add(target); } } return targets; }
/// <summary> /// Converts a local value to a remote value. /// </summary> /// <param name="srcValue">The local value.</param> /// <param name="srcType">The data type of the local value.</param> /// <param name="dstType">The data type of the remote value.</param> /// <returns>The remote value.</returns> private object ConvertLocalToRemote(object srcValue, BuiltInType srcType, BuiltInType dstType) { // must determine the type from the source if the containing array is a variant. if (srcType == BuiltInType.Variant) { TypeInfo typeInfo = TypeInfo.Construct(srcValue); srcType = typeInfo.BuiltInType; } // no conversion by default. object dstValue = srcValue; // apply different conversions depending on the data type. switch (dstType) { case BuiltInType.Guid: { dstValue = new Uuid((string)srcValue); break; } case BuiltInType.XmlElement: { XmlDocument document = new XmlDocument(); document.InnerXml = (string)srcValue; dstValue = document.DocumentElement; break; } case BuiltInType.NodeId: { dstValue = GetRemoteNodeId((string)srcValue); break; } case BuiltInType.ExpandedNodeId: { ExpandedNodeId nodeId = ExpandedNodeId.Parse((string)srcValue); dstValue = GetRemoteExpandedNodeId(nodeId); break; } case BuiltInType.QualifiedName: { dstValue = GetRemoteBrowseName((string)srcValue); break; } case BuiltInType.LocalizedText: { dstValue = new LocalizedText((string)srcValue); break; } case BuiltInType.StatusCode: { dstValue = new StatusCode((uint)srcValue); break; } case BuiltInType.ExtensionObject: { BinaryDecoder decoder = new BinaryDecoder((byte[])srcValue, m_localMessageContext); dstValue = decoder.ReadExtensionObject(null); decoder.Close(); break; } default: { if (dstType != srcType && dstType != BuiltInType.Variant && dstType != BuiltInType.Null) { throw ComUtils.CreateComException(ResultIds.E_BADTYPE); } break; } } // all done. return(dstValue); }
/// <summary> /// Read and parse the publisher node configuration file. /// </summary> /// <returns></returns> public async Task <bool> ReadConfigAsync() { // get information on the nodes to publish and validate the json by deserializing it. try { await PublisherNodeConfigurationSemaphore.WaitAsync().ConfigureAwait(false); if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_GW_PNFP"))) { Logger.Information("Publishing node configuration file path read from environment."); PublisherNodeConfigurationFilename = Environment.GetEnvironmentVariable("_GW_PNFP"); } Logger.Information($"The name of the configuration file for published nodes is: {PublisherNodeConfigurationFilename}"); // if the file exists, read it, if not just continue if (File.Exists(PublisherNodeConfigurationFilename)) { Logger.Information($"Attemtping to load node configuration from: {PublisherNodeConfigurationFilename}"); try { await PublisherNodeConfigurationFileSemaphore.WaitAsync().ConfigureAwait(false); var json = File.ReadAllText(PublisherNodeConfigurationFilename); _configurationFileEntries = JsonConvert.DeserializeObject <List <ConfigurationFileEntryLegacyModel> >(json); } finally { PublisherNodeConfigurationFileSemaphore.Release(); } if (_configurationFileEntries != null) { Logger.Information($"Loaded {_configurationFileEntries.Count} config file entry/entries."); foreach (var publisherConfigFileEntryLegacy in _configurationFileEntries) { if (publisherConfigFileEntryLegacy.NodeId == null) { // new node configuration syntax. foreach (var opcNode in publisherConfigFileEntryLegacy.OpcNodes) { if (opcNode.ExpandedNodeId != null) { ExpandedNodeId expandedNodeId = ExpandedNodeId.Parse(opcNode.ExpandedNodeId); _nodePublishingConfiguration.Add(new NodePublishingConfigurationModel(expandedNodeId, opcNode.ExpandedNodeId, publisherConfigFileEntryLegacy.EndpointUrl.OriginalString, publisherConfigFileEntryLegacy.UseSecurity, opcNode.OpcPublishingInterval, opcNode.OpcSamplingInterval, opcNode.DisplayName, opcNode.HeartbeatInterval, opcNode.SkipFirst, publisherConfigFileEntryLegacy.OpcAuthenticationMode, publisherConfigFileEntryLegacy.EncryptedAuthCredential)); } else { // check Id string to check which format we have if (opcNode.Id.StartsWith("nsu=", StringComparison.InvariantCulture)) { // ExpandedNodeId format ExpandedNodeId expandedNodeId = ExpandedNodeId.Parse(opcNode.Id); _nodePublishingConfiguration.Add(new NodePublishingConfigurationModel(expandedNodeId, opcNode.Id, publisherConfigFileEntryLegacy.EndpointUrl.OriginalString, publisherConfigFileEntryLegacy.UseSecurity, opcNode.OpcPublishingInterval, opcNode.OpcSamplingInterval, opcNode.DisplayName, opcNode.HeartbeatInterval, opcNode.SkipFirst, publisherConfigFileEntryLegacy.OpcAuthenticationMode, publisherConfigFileEntryLegacy.EncryptedAuthCredential)); } else { // NodeId format NodeId nodeId = NodeId.Parse(opcNode.Id); _nodePublishingConfiguration.Add(new NodePublishingConfigurationModel(nodeId, opcNode.Id, publisherConfigFileEntryLegacy.EndpointUrl.OriginalString, publisherConfigFileEntryLegacy.UseSecurity, opcNode.OpcPublishingInterval, opcNode.OpcSamplingInterval, opcNode.DisplayName, opcNode.HeartbeatInterval, opcNode.SkipFirst, publisherConfigFileEntryLegacy.OpcAuthenticationMode, publisherConfigFileEntryLegacy.EncryptedAuthCredential)); } } } } else { // NodeId (ns=) format node configuration syntax using default sampling and publishing interval. _nodePublishingConfiguration.Add(new NodePublishingConfigurationModel(publisherConfigFileEntryLegacy.NodeId, publisherConfigFileEntryLegacy.NodeId.ToString(), publisherConfigFileEntryLegacy.EndpointUrl.OriginalString, publisherConfigFileEntryLegacy.UseSecurity, null, null, null, null, null, publisherConfigFileEntryLegacy.OpcAuthenticationMode, publisherConfigFileEntryLegacy.EncryptedAuthCredential)); } } } } else { Logger.Information($"The node configuration file '{PublisherNodeConfigurationFilename}' does not exist. Continue and wait for remote configuration requests."); } } catch (Exception e) { Logger.Fatal(e, "Loading of the node configuration file failed. Does the file exist and has correct syntax? Exiting..."); return(false); } finally { PublisherNodeConfigurationSemaphore.Release(); } Logger.Information($"There are {_nodePublishingConfiguration.Count.ToString(CultureInfo.InvariantCulture)} nodes to publish."); return(true); }
/// <summary> /// Constructor /// </summary> public NodeAttributeSet(ExpandedNodeId nodeId) : this(nodeId, new NamespaceTable()) { }
/// <summary> /// Does any initialization required before the address space can be used. /// </summary> /// <remarks> /// The externalReferences is an out parameter that allows the node manager to link to nodes /// in other node managers. For example, the 'Objects' node is managed by the CoreNodeManager and /// should have a reference to the root folder node(s) exposed by this node manager. /// </remarks> public override void CreateAddressSpace(IDictionary <NodeId, IList <IReference> > externalReferences) { lock (Lock) { //Load DI nodeset LoadPredefinedNodes(SystemContext, externalReferences); //Add my variables to Address Space, under the DeviceSet object ----------------------- //------------------------------------------------------------------------------------- //get the DeviceSet object of the Address Space NodeState DeviceSetobj = (NodeState)FindPredefinedNode( ExpandedNodeId.ToNodeId(ObjectIds.DeviceSet, Server.NamespaceUris), typeof(NodeState)); //------------------------------------------------------------------------------------- //create myDevice1 as a simple folder with a variable FolderState mydev1 = CreateFolder(DeviceSetobj, "myDevice1", "myDevice1"); //create myDevice1/Piece_Info Piece_Info = CreateVariable(mydev1, "Piece_Info", "Piece_Info", Opc.Ua.DataTypeIds.Boolean, ValueRanks.Scalar); // create myDevice1/Piece_SN Piece_SN = CreateVariable(mydev1, "Piece_SN", "Piece_SN", Opc.Ua.DataTypeIds.Int32, ValueRanks.Scalar); // create myDevice1/Mould_SN Mould_SN = CreateVariable(mydev1, "Mould_SN", "Mould_SN", Opc.Ua.DataTypeIds.String, ValueRanks.Scalar); // create myDevice1/Time Time = CreateVariable(mydev1, "Time", "Time", Opc.Ua.DataTypeIds.String, ValueRanks.Scalar); //initialize var Piece_Info.Value = (bool)false; Piece_SN.Value = (int)4; Mould_SN.Value = (string)"-"; Time.Value = (string)"-"; //add to Address Space AddPredefinedNode(SystemContext, mydev1); // Open connection to DB string connectionString = "SERVER=" + DB_server + ";" + "DATABASE=" + DB_database + ";" + "UID=" + DB_uid + ";" + "PASSWORD="******";"; DB_connection = new MySqlConnection(connectionString); try { DB_connection.Open(); } catch (MySqlException ex) { System.Windows.Forms.MessageBox.Show(ex.Message); }; //------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------- // start periodic method to update my Address Space variables m_doprocessingTimer = new Timer(myDoProcessing, null, m_doprocessingInterval, m_doprocessingInterval); } }
public Tree GetChildren(string node) { ReferenceDescriptionCollection references; Byte[] continuationPoint; Tree browserTree = new Tree(); try { session.Browse( null, null, node, 0u, BrowseDirection.Forward, ReferenceTypeIds.HierarchicalReferences, true, 0, out continuationPoint, out references); if (references != null) { foreach (var nodeReference in references) { ReferenceDescriptionCollection childReferences = null; Byte[] childContinuationPoint; session.Browse( null, null, ExpandedNodeId.ToNodeId(nodeReference.NodeId, session.NamespaceUris), 0u, BrowseDirection.Forward, ReferenceTypeIds.HierarchicalReferences, true, 0, out childContinuationPoint, out childReferences); INode currentNode = null; try { currentNode = session.ReadNode(ExpandedNodeId.ToNodeId(nodeReference.NodeId, session.NamespaceUris)); } catch (Exception) { // skip this node continue; } byte currentNodeAccessLevel = 0; byte currentNodeEventNotifier = 0; bool currentNodeExecutable = false; VariableNode variableNode = currentNode as VariableNode; if (variableNode != null) { currentNodeAccessLevel = variableNode.UserAccessLevel; currentNodeAccessLevel = (byte)((uint)currentNodeAccessLevel & ~0x2); } ObjectNode objectNode = currentNode as ObjectNode; if (objectNode != null) { currentNodeEventNotifier = objectNode.EventNotifier; } ViewNode viewNode = currentNode as ViewNode; if (viewNode != null) { currentNodeEventNotifier = viewNode.EventNotifier; } MethodNode methodNode = currentNode as MethodNode; if (methodNode != null) { currentNodeExecutable = methodNode.UserExecutable; } browserTree.currentView.Add(new ListNode() { id = nodeReference.NodeId.ToString(), NodeName = nodeReference.DisplayName.Text.ToString(), nodeClass = nodeReference.NodeClass.ToString(), accessLevel = currentNodeAccessLevel.ToString(), eventNotifier = currentNodeEventNotifier.ToString(), executable = currentNodeExecutable.ToString(), children = (references?.Count != 0), ImageUrl = (nodeReference.NodeClass.ToString() == "Variable") ? "folderOpen.jpg" : "folder.jpg" }); if (browserTree.currentView[0].ImageUrl == null) { browserTree.currentView[0].ImageUrl = ""; } } if (browserTree.currentView.Count == 0) { INode currentNode = session.ReadNode(new NodeId(node)); byte currentNodeAccessLevel = 0; byte currentNodeEventNotifier = 0; bool currentNodeExecutable = false; VariableNode variableNode = currentNode as VariableNode; if (variableNode != null) { currentNodeAccessLevel = variableNode.UserAccessLevel; currentNodeAccessLevel = (byte)((uint)currentNodeAccessLevel & ~0x2); } ObjectNode objectNode = currentNode as ObjectNode; if (objectNode != null) { currentNodeEventNotifier = objectNode.EventNotifier; } ViewNode viewNode = currentNode as ViewNode; if (viewNode != null) { currentNodeEventNotifier = viewNode.EventNotifier; } MethodNode methodNode = currentNode as MethodNode; if (methodNode != null) { currentNodeExecutable = methodNode.UserExecutable; } browserTree.currentView.Add(new ListNode() { id = node, NodeName = currentNode.DisplayName.Text.ToString(), nodeClass = currentNode.NodeClass.ToString(), accessLevel = currentNodeAccessLevel.ToString(), eventNotifier = currentNodeEventNotifier.ToString(), executable = currentNodeExecutable.ToString(), children = false, ImageUrl = null }); } } return(browserTree); } catch { Disconnect(session); return(null); } }
/// <summary> /// Returns a node managed by the manager with the specified node id. /// </summary> public ILocalNode GetLocalNode(ExpandedNodeId nodeId) { if (nodeId == null) { return null; } // check for absolute declarations of local nodes. if (nodeId.IsAbsolute) { if (nodeId.ServerIndex != 0) { return null; } int namespaceIndex = this.Server.NamespaceUris.GetIndex(nodeId.NamespaceUri); if (namespaceIndex < 0 || nodeId.NamespaceIndex >= this.Server.NamespaceUris.Count) { return null; } return GetLocalNode(new NodeId(nodeId.Identifier, (ushort)namespaceIndex)); } return GetLocalNode((NodeId)nodeId); }
/// <summary> /// Sets the value shown in the control. /// </summary> private void SetValue(Variant value) { ValueTB.ForeColor = Color.Empty; ValueTB.Font = new Font(ValueTB.Font, FontStyle.Regular); m_textChanged = false; // check for null. if (Variant.Null == value) { ValueTB.Text = String.Empty; m_value = Variant.Null; return; } // get the source type. TypeInfo sourceType = value.TypeInfo; if (sourceType == null) { sourceType = TypeInfo.Construct(value.Value); } m_value = new Variant(value.Value, sourceType); // display value as text. StringBuilder buffer = new StringBuilder(); XmlWriter writer = XmlWriter.Create(buffer, new XmlWriterSettings() { Indent = true, OmitXmlDeclaration = true }); XmlEncoder encoder = new XmlEncoder(new XmlQualifiedName("Value", Namespaces.OpcUaXsd), writer, m_session.MessageContext); encoder.WriteVariantContents(m_value.Value, m_value.TypeInfo); writer.Close(); ValueTB.Text = buffer.ToString(); // extract the encoding id from the value. ExpandedNodeId encodingId = null; ExtensionObjectEncoding encoding = ExtensionObjectEncoding.None; if (sourceType.BuiltInType == BuiltInType.ExtensionObject) { ExtensionObject extension = null; if (sourceType.ValueRank == ValueRanks.Scalar) { extension = (ExtensionObject)m_value.Value; } else { // only use the first item in the list for arrays. ExtensionObject[] list = (ExtensionObject[])m_value.Value; if (list.Length > 0) { extension = list[0]; } } encodingId = extension.TypeId; encoding = extension.Encoding; } if (encodingId == null) { StatusCTRL.Visible = false; return; } // check if the encoding is known. IObject encodingNode = m_session.NodeCache.Find(encodingId) as IObject; if (encodingNode == null) { StatusCTRL.Visible = false; return; } // update the encoding shown. if (encoding == ExtensionObjectEncoding.EncodeableObject) { EncodingCB.Text = "(Converted to XML by Client)"; } else { EncodingCB.Text = m_session.NodeCache.GetDisplayText(encodingNode); } m_encodingName = encodingNode.BrowseName; // find the data type for the encoding. IDataType dataTypeNode = null; foreach (INode node in m_session.NodeCache.Find(encodingNode.NodeId, Opc.Ua.ReferenceTypeIds.HasEncoding, true, false)) { dataTypeNode = node as IDataType; if (dataTypeNode != null) { break; } } if (dataTypeNode == null) { StatusCTRL.Visible = false; return; } // update data type display. DataTypeTB.Text = m_session.NodeCache.GetDisplayText(dataTypeNode); DataTypeTB.Tag = dataTypeNode; // update encoding drop down. EncodingCB.DropDownItems.Clear(); foreach (INode node in m_session.NodeCache.Find(dataTypeNode.NodeId, Opc.Ua.ReferenceTypeIds.HasEncoding, false, false)) { IObject encodingNode2 = node as IObject; if (encodingNode2 != null) { ToolStripMenuItem item = new ToolStripMenuItem(m_session.NodeCache.GetDisplayText(encodingNode2)); item.Tag = encodingNode2; item.Click += new EventHandler(EncodingCB_Item_Click); EncodingCB.DropDownItems.Add(item); } } StatusCTRL.Visible = true; }
/// <summary> /// Updates the cache with the type and its subtypes. /// </summary> /// <remarks> /// This method can be used to ensure the TypeTree is populated. /// </remarks> public void FetchTypeTree(ExpandedNodeId typeId) { Node node = NodeCache.Find(typeId) as Node; if (node != null) { foreach (IReference reference in node.Find(ReferenceTypeIds.HasSubtype, false)) { FetchTypeTree(reference.TargetId); } } }
/// <summary> /// Peridically checks the system state. /// </summary> private void OnCheckSystemStatus(object state) { #if CONDITION_SAMPLES lock (Lock) { try { // create the dialog. if (m_dialog == null) { m_dialog = new DialogConditionState(null); CreateNode( SystemContext, ExpandedNodeId.ToNodeId(ObjectIds.Data_Conditions, SystemContext.NamespaceUris), ReferenceTypeIds.HasComponent, new QualifiedName("ResetSystemDialog", m_namespaceIndex), m_dialog); m_dialog.OnAfterResponse = OnDialogComplete; } StatusCode systemStatus = m_system.SystemStatus; m_systemStatusCondition.UpdateStatus(systemStatus); // cycle through different status codes in order to simulate a real system. if (StatusCode.IsGood(systemStatus)) { m_systemStatusCondition.UpdateSeverity((ushort)EventSeverity.Low); m_system.SystemStatus = StatusCodes.Uncertain; } else if (StatusCode.IsUncertain(systemStatus)) { m_systemStatusCondition.UpdateSeverity((ushort)EventSeverity.Medium); m_system.SystemStatus = StatusCodes.Bad; } else { m_systemStatusCondition.UpdateSeverity((ushort)EventSeverity.High); m_system.SystemStatus = StatusCodes.Good; } // request a reset if status is bad. if (StatusCode.IsBad(systemStatus)) { m_dialog.RequestResponse( SystemContext, "Reset the test system?", (uint)(int)(DialogConditionChoice.Ok | DialogConditionChoice.Cancel), (ushort)EventSeverity.MediumHigh); } // report the event. TranslationInfo info = new TranslationInfo( "TestSystemStatusChange", "en-US", "The TestSystem status is now {0}.", systemStatus); m_systemStatusCondition.ReportConditionChange( SystemContext, null, new LocalizedText(info), false); } catch (Exception e) { Utils.Trace(e, "Unexpected error monitoring system status."); } } #endif }
/// <summary> /// Finds the <see cref="NamespaceMetadataState"/> node for the specified NamespaceUri. /// </summary> /// <param name="namespaceUri"></param> /// <returns></returns> private NamespaceMetadataState FindNamespaceMetadataState(string namespaceUri) { try { // find ServerNamespaces node NamespacesState serverNamespacesNode = FindPredefinedNode(ObjectIds.Server_Namespaces, typeof(NamespacesState)) as NamespacesState; if (serverNamespacesNode == null) { Utils.Trace("Cannot find ObjectIds.Server_Namespaces node."); return(null); } IList <BaseInstanceState> serverNamespacesChildren = new List <BaseInstanceState>(); serverNamespacesNode.GetChildren(SystemContext, serverNamespacesChildren); foreach (var namespacesReference in serverNamespacesChildren) { // Find NamespaceMetadata node of NamespaceUri in Namespaces children NamespaceMetadataState namespaceMetadata = namespacesReference as NamespaceMetadataState; if (namespaceMetadata == null) { continue; } if (namespaceMetadata.NamespaceUri.Value == namespaceUri) { return(namespaceMetadata); } else { continue; } } IList <IReference> serverNamespacesReferencs = new List <IReference>(); serverNamespacesNode.GetReferences(SystemContext, serverNamespacesReferencs); foreach (IReference serverNamespacesReference in serverNamespacesReferencs) { if (serverNamespacesReference.IsInverse == false) { // Find NamespaceMetadata node of NamespaceUri in Namespaces references NodeId nameSpaceNodeId = ExpandedNodeId.ToNodeId(serverNamespacesReference.TargetId, Server.NamespaceUris); NamespaceMetadataState namespaceMetadata = FindNodeInAddressSpace(nameSpaceNodeId) as NamespaceMetadataState; if (namespaceMetadata == null) { continue; } if (namespaceMetadata.NamespaceUri.Value == namespaceUri) { return(namespaceMetadata); } } } return(null); } catch (Exception ex) { Utils.Trace(ex, "Error searching NamespaceMetadata for namespaceUri {0}.", namespaceUri); return(null); } }
/// <summary> /// Method to start monitoring a node and publish the data to IoTHub. Executes synchronously. /// </summary> private ServiceResult OnPublishNodeCall(ISystemContext context, MethodState method, IList <object> inputArguments, IList <object> outputArguments) { string logPrefix = "OnPublishNodeCall:"; if (string.IsNullOrEmpty(inputArguments[0] as string) || string.IsNullOrEmpty(inputArguments[1] as string)) { Logger.Error($"{logPrefix} Invalid Arguments when trying to publish a node."); return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide all arguments as strings!")); } HttpStatusCode statusCode = HttpStatusCode.InternalServerError; NodeId nodeId = null; ExpandedNodeId expandedNodeId = null; Uri endpointUri = null; bool isNodeIdFormat = true; try { string id = inputArguments[0] as string; if (id.Contains("nsu=", StringComparison.InvariantCulture)) { expandedNodeId = ExpandedNodeId.Parse(id); isNodeIdFormat = false; } else { nodeId = NodeId.Parse(id); isNodeIdFormat = true; } endpointUri = new Uri(inputArguments[1] as string); } catch (UriFormatException) { Logger.Error($"{logPrefix} The EndpointUrl has an invalid format '{inputArguments[1] as string}'!"); return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide a valid OPC UA endpoint URL as second argument!")); } catch (Exception e) { Logger.Error(e, $"{logPrefix} The NodeId has an invalid format '{inputArguments[0] as string}'!"); return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide a valid OPC UA NodeId in NodeId or ExpandedNodeId format as first argument!")); } // find/create a session to the endpoint URL and start monitoring the node. try { // lock the publishing configuration till we are done OpcSessionsListSemaphore.Wait(); if (ShutdownTokenSource.IsCancellationRequested) { return(ServiceResult.Create(StatusCodes.BadUnexpectedError, $"Publisher shutdown in progress.")); } // find the session we need to monitor the node OpcSession opcSession = null; opcSession = OpcSessions.FirstOrDefault(s => s.EndpointUrl.Equals(endpointUri.OriginalString, StringComparison.OrdinalIgnoreCase)); // add a new session. if (opcSession == null) { // create new session info. opcSession = new OpcSession(endpointUri.OriginalString, true, OpcSessionCreationTimeout); OpcSessions.Add(opcSession); Logger.Information($"OnPublishNodeCall: No matching session found for endpoint '{endpointUri.OriginalString}'. Requested to create a new one."); } if (isNodeIdFormat) { // add the node info to the subscription with the default publishing interval, execute syncronously Logger.Debug($"{logPrefix} Request to monitor item with NodeId '{nodeId.ToString()}' (with default PublishingInterval and SamplingInterval)"); statusCode = opcSession.AddNodeForMonitoringAsync(nodeId, null, null, null, null, ShutdownTokenSource.Token).Result; } else { // add the node info to the subscription with the default publishing interval, execute syncronously Logger.Debug($"{logPrefix} Request to monitor item with ExpandedNodeId '{expandedNodeId.ToString()}' (with default PublishingInterval and SamplingInterval)"); statusCode = opcSession.AddNodeForMonitoringAsync(null, expandedNodeId, null, null, null, ShutdownTokenSource.Token).Result; } } catch (Exception e) { Logger.Error(e, $"{logPrefix} Exception while trying to configure publishing node '{(isNodeIdFormat ? nodeId.ToString() : expandedNodeId.ToString())}'"); return(ServiceResult.Create(e, StatusCodes.BadUnexpectedError, $"Unexpected error publishing node: {e.Message}")); } finally { OpcSessionsListSemaphore.Release(); } if (statusCode == HttpStatusCode.OK || statusCode == HttpStatusCode.Accepted) { return(ServiceResult.Good); } return(ServiceResult.Create(StatusCodes.Bad, "Can not start monitoring node! Reason unknown.")); }
/// <summary> /// Initializes the control with a set of items. /// </summary> public void Initialize(Session session, ExpandedNodeId nodeId) { ItemsLV.Items.Clear(); m_session = session; if (m_session == null) { return; } ILocalNode node = m_session.NodeCache.Find(nodeId) as ILocalNode; if (node == null) { return; } uint[] attributesIds = Attributes.GetIdentifiers(); for (int ii = 0; ii < attributesIds.Length; ii++) { uint attributesId = attributesIds[ii]; if (!node.SupportsAttribute(attributesId)) { continue; } ItemInfo info = new ItemInfo(); info.NodeId = node.NodeId; info.AttributeId = attributesId; info.Name = Attributes.GetBrowseName(attributesId); info.Value = new DataValue(StatusCodes.BadWaitingForInitialData); ServiceResult result = node.Read(null, attributesId, info.Value); if (ServiceResult.IsBad(result)) { info.Value = new DataValue(result.StatusCode); } AddItem(info); } IList<IReference> references = node.References.Find(ReferenceTypes.HasProperty, false, true, m_session.TypeTree); for (int ii = 0; ii < references.Count; ii++) { IReference reference = references[ii]; ILocalNode property = m_session.NodeCache.Find(reference.TargetId) as ILocalNode; if (property == null) { return; } ItemInfo info = new ItemInfo(); info.NodeId = property.NodeId; info.AttributeId = Attributes.Value; info.Name = Utils.Format("{0}", property.DisplayName); info.Value = new DataValue(StatusCodes.BadWaitingForInitialData); ServiceResult result = property.Read(null, Attributes.Value, info.Value); if (ServiceResult.IsBad(result)) { info.Value = new DataValue(result.StatusCode); } AddItem(info); } UpdateValues(); }
/// <summary> /// Method to remove the node from the subscription and stop publishing telemetry to IoTHub. Executes synchronously. /// </summary> private ServiceResult OnUnpublishNodeCall(ISystemContext context, MethodState method, IList <object> inputArguments, IList <object> outputArguments) { string logPrefix = "OnUnpublishNodeCall:"; if (string.IsNullOrEmpty(inputArguments[0] as string) || string.IsNullOrEmpty(inputArguments[1] as string)) { Logger.Error($"{logPrefix} Invalid arguments!"); return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide all arguments!")); } HttpStatusCode statusCode = HttpStatusCode.InternalServerError; NodeId nodeId = null; ExpandedNodeId expandedNodeId = null; Uri endpointUri = null; bool isNodeIdFormat = true; try { string id = inputArguments[0] as string; if (id.Contains("nsu=", StringComparison.InvariantCulture)) { expandedNodeId = ExpandedNodeId.Parse(id); isNodeIdFormat = false; } else { nodeId = NodeId.Parse(id); isNodeIdFormat = true; } endpointUri = new Uri(inputArguments[1] as string); } catch (UriFormatException) { Logger.Error($"{logPrefix} The endpointUrl is invalid '{inputArguments[1] as string}'!"); return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide a valid OPC UA endpoint URL as second argument!")); } catch (Exception e) { Logger.Error(e, $"{logPrefix} The NodeId has an invalid format '{inputArguments[0] as string}'!"); return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide a valid OPC UA NodeId in NodeId or ExpandedNodeId format as first argument!")); } // find the session and stop monitoring the node. try { OpcSessionsListSemaphore.Wait(); if (ShutdownTokenSource.IsCancellationRequested) { return(ServiceResult.Create(StatusCodes.BadUnexpectedError, $"Publisher shutdown in progress.")); } // find the session we need to monitor the node OpcSession opcSession = null; try { opcSession = OpcSessions.FirstOrDefault(s => s.EndpointUrl.Equals(endpointUri.OriginalString, StringComparison.OrdinalIgnoreCase)); } catch { opcSession = null; } if (opcSession == null) { // do nothing if there is no session for this endpoint. Logger.Error($"{logPrefix} Session for endpoint '{endpointUri.OriginalString}' not found."); return(ServiceResult.Create(StatusCodes.BadSessionIdInvalid, "Session for endpoint of node to unpublished not found!")); } else { if (isNodeIdFormat) { // stop monitoring the node, execute syncronously Logger.Information($"{logPrefix} Request to stop monitoring item with NodeId '{nodeId.ToString()}')"); statusCode = opcSession.RequestMonitorItemRemovalAsync(nodeId, null, ShutdownTokenSource.Token).Result; } else { // stop monitoring the node, execute syncronously Logger.Information($"{logPrefix} Request to stop monitoring item with ExpandedNodeId '{expandedNodeId.ToString()}')"); statusCode = opcSession.RequestMonitorItemRemovalAsync(null, expandedNodeId, ShutdownTokenSource.Token).Result; } } } catch (Exception e) { Logger.Error(e, $"{logPrefix} Exception while trying to configure publishing node '{nodeId.ToString()}'"); return(ServiceResult.Create(e, StatusCodes.BadUnexpectedError, $"Unexpected error unpublishing node: {e.Message}")); } finally { OpcSessionsListSemaphore.Release(); } return(statusCode == HttpStatusCode.OK || statusCode == HttpStatusCode.Accepted ? ServiceResult.Good : ServiceResult.Create(StatusCodes.Bad, "Can not stop monitoring node!")); }
/// <summary cref="INodeTable.Find(ExpandedNodeId,NodeId,bool,bool)" /> public IList<INode> Find( ExpandedNodeId sourceId, NodeId referenceTypeId, bool isInverse, bool includeSubtypes) { List<INode> hits = new List<INode>(); // find the source. Node source = Find(sourceId) as Node; if (source == null) { return hits; } // find all references. IList<IReference> references = source.ReferenceTable.Find(referenceTypeId, isInverse, includeSubtypes, m_typeTree); foreach (IReference reference in references) { INode target = Find(reference.TargetId); if (target == null) { continue; } hits.Add(target); } return hits; }
public OpcMethodTest(string testserverUrl, int maxShortWaitSec, int maxLongWaitSec, CancellationToken ct) : base("OpcMethodTest", testserverUrl, maxShortWaitSec, maxLongWaitSec, ct) { string logPrefix = $"{_logClassPrefix}:OpcMethodTest:"; Logger.Information($"{logPrefix} Publisher URL: {PublisherUrl}"); //TestserverUrl = testserverUrl; _application = new ApplicationInstance { ApplicationName = "UA Core Sample Client", ApplicationType = ApplicationType.Client, ConfigSectionName = "Opc.Ua.SampleClient" }; // load the application configuration. _config = _application.LoadApplicationConfiguration(false).Result; // check the application certificate. bool haveAppCertificate = _application.CheckApplicationInstanceCertificate(false, 0).Result; if (!haveAppCertificate) { Logger.Fatal($"{logPrefix} Application instance certificate invalid!"); throw new Exception("Application instance certificate invalid!"); } if (haveAppCertificate) { _config.ApplicationUri = Utils.GetApplicationUriFromCertificate(_config.SecurityConfiguration.ApplicationCertificate.Certificate); if (_config.SecurityConfiguration.AutoAcceptUntrustedCertificates) { AutoAccept = true; } _config.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation); } else { Logger.Warning($"{logPrefix} Missing application certificate, using unsecure connection."); } Logger.Information($"{logPrefix} Discover endpoints of {PublisherUrl}."); _selectedEndpoint = CoreClientUtils.SelectEndpoint(PublisherUrl, haveAppCertificate, 15000); Logger.Information($"{logPrefix} Selected endpoint uses: {0}", _selectedEndpoint.SecurityPolicyUri.Substring(_selectedEndpoint.SecurityPolicyUri.LastIndexOf('#') + 1)); Logger.Information($"{logPrefix} Create a session with OPC UA server."); _endpointConfiguration = EndpointConfiguration.Create(_config); _configuredEndpoint = new ConfiguredEndpoint(null, _selectedEndpoint, _endpointConfiguration); // create session _session = Session.Create(_config, _configuredEndpoint, false, "OPC UA Console Client", 60000, new UserIdentity(new AnonymousIdentityToken()), null).Result; _session.KeepAlive += Client_KeepAlive; Logger.Information($"{logPrefix} 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); Logger.Information($"{logPrefix} DisplayName, BrowseName, NodeClass"); foreach (var rd in references) { Logger.Information($"{logPrefix} {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) { Logger.Information($"{logPrefix} + {nextRd.DisplayName}, {nextRd.BrowseName}, {nextRd.NodeClass}"); } _publishingIntervalSec = maxLongWaitSec; Logger.Information($"{logPrefix} Create a subscription with publishing interval of {_publishingIntervalSec} second."); var subscription = new Subscription(_session.DefaultSubscription) { PublishingInterval = _publishingIntervalSec * 1000 }; Logger.Information($"{logPrefix} 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=" + Variables.Server_ServerStatus_CurrentTime.ToString(CultureInfo.InvariantCulture) } }; _lastTimestamp = new DateTime(0); list.ForEach(i => i.Notification += OnNotification); subscription.AddItems(list); Logger.Information($"{logPrefix} Add the subscription to the session."); _session.AddSubscription(subscription); subscription.Create(); //await Task.Delay(-1, ct); //subscription.Delete(true); } }
/// <summary> /// Returns the immediate supertype for the type. /// </summary> /// <param name="typeId">The extended type identifier.</param> /// <returns> /// A type identifier of the <paramref name="typeId "/> /// </returns> public NodeId FindSuperType(ExpandedNodeId typeId) { INode type = Find(typeId); if (type == null) { return null; } return m_typeTree.FindSuperType(typeId); }
/// <summary> /// Initializes the object with a <paramref name="typeId"/>. /// </summary> /// <param name="typeId">The type to copy and create an instance from</param> public OptionalFieldsComplexType(ExpandedNodeId typeId) : base(typeId) { m_encodingMask = 0; }
/// <summary> /// Determines whether a type is a subtype of another type. /// </summary> /// <param name="subTypeId">The subtype identifier.</param> /// <param name="superTypeId">The supertype identifier.</param> /// <returns> /// <c>true</c> if <paramref name="superTypeId"/> is supertype of <paramref name="subTypeId"/>; otherwise, <c>false</c>. /// </returns> public bool IsTypeOf(ExpandedNodeId subTypeId, ExpandedNodeId superTypeId) { if (subTypeId == superTypeId) { return true; } ILocalNode subtype = Find(subTypeId) as ILocalNode; if (subtype == null) { return false; } ILocalNode supertype = subtype; while (supertype != null) { ExpandedNodeId currentId = supertype.References.FindTarget(ReferenceTypeIds.HasSubtype, true, true, m_typeTree, 0); if (currentId == superTypeId) { return true; } supertype = Find(currentId) as ILocalNode; } return false; }
/// <summary> /// Initializes the object with a <paramref name="typeId"/>. /// </summary> /// <param name="typeId">The type to copy and create an instance from</param> public BaseComplexType(ExpandedNodeId typeId) { TypeId = typeId; }
/// <summary> /// Returns the data type for the specified encoding. /// </summary> /// <param name="encodingId">The encoding id.</param> /// <returns></returns> public NodeId FindDataTypeId(ExpandedNodeId encodingId) { ILocalNode encoding = Find(encodingId) as ILocalNode; if (encoding == null) { return NodeId.Null; } IList<IReference> references = encoding.References.Find(ReferenceTypeIds.HasEncoding, true, true, m_typeTree); if (references.Count > 0) { return ExpandedNodeId.ToNodeId(references[0].TargetId, m_session.NamespaceUris); } return NodeId.Null; }
/// <summary> /// This method is used to delete bi-directional references to nodes from other node managers. /// </summary> public virtual ServiceResult DeleteReference( object sourceHandle, NodeId referenceTypeId, bool isInverse, ExpandedNodeId targetId, bool deleteBiDirectional) { lock (Lock) { // check for valid handle. NodeState source = IsHandleInNamespace(sourceHandle); if (source == null) { return StatusCodes.BadNodeIdUnknown; } source.RemoveReference(referenceTypeId, isInverse, targetId); if (deleteBiDirectional) { // check if the target is also managed by the node manager. if (!targetId.IsAbsolute) { NodeState target = GetManagerHandle(m_systemContext, (NodeId)targetId, null) as NodeState; if (target != null) { target.RemoveReference(referenceTypeId, !isInverse, source.NodeId); } } } return ServiceResult.Good; } }
/// <summary> /// Adds the supertypes of the node to the cache. /// </summary> public void FetchSuperTypes(ExpandedNodeId nodeId) { // find the target node, ILocalNode source = Find(nodeId) as ILocalNode; if (source == null) { return; } // follow the tree. ILocalNode subType = source; while (subType != null) { ILocalNode superType = null; IList<IReference> references = subType.References.Find(ReferenceTypeIds.HasSubtype, true, true, this); if (references != null && references.Count > 0) { superType = Find(references[0].TargetId) as ILocalNode; } subType = superType; } }
/// <summary> /// Adds a node to the list. /// </summary> public void AddNodeId(ExpandedNodeId nodeId) { Node node = m_session.NodeCache.Find(nodeId) as Node; if (node == null) { return; } if ((node.NodeClass & m_nodeClassMask) != 0) { foreach (ListViewItem listItem in ItemsLV.Items) { Node target = listItem.Tag as Node; if (target != null) { if (target.NodeId == node.NodeId) { UpdateItem(listItem, node); return; } } } AddItem(node, "Property", -1); return; } if (node.NodeClass == NodeClass.ObjectType || node.NodeClass == NodeClass.VariableType) { ExpandedNodeId supertypeId = node.FindTarget(ReferenceTypeIds.HasSubtype, true, 0); if (supertypeId != null) { AddNodeId(supertypeId); } } IList<IReference> properties = node.ReferenceTable.Find(ReferenceTypeIds.HasProperty, false, true, m_session.TypeTree); for (int ii = 0; ii < properties.Count; ii++) { AddNodeId(properties[ii].TargetId); } }
/// <summary cref="INodeTable.Exists(ExpandedNodeId)" /> public bool Exists(ExpandedNodeId nodeId) { return Find(nodeId) != null; }
/// <summary> /// Returns to display icon for the target of a reference. /// </summary> public static string GetTargetIcon(Session session, NodeClass nodeClass, ExpandedNodeId typeDefinitionId) { // make sure the type definition is in the cache. INode typeDefinition = session.NodeCache.Find(typeDefinitionId); switch (nodeClass) { case NodeClass.Object: { if (session.TypeTree.IsTypeOf(typeDefinitionId, ObjectTypes.FolderType)) { return "Folder"; } return "Object"; } case NodeClass.Variable: { if (session.TypeTree.IsTypeOf(typeDefinitionId, VariableTypes.PropertyType)) { return "Property"; } return "Variable"; } } return nodeClass.ToString(); }
/// <summary> /// Shows a value in control. /// </summary> private void ShowValue(ref int index, ref bool overwrite, object value) { if (value == null) { return; } // show monitored items. MonitoredItem monitoredItem = value as MonitoredItem; if (monitoredItem != null) { m_monitoredItem = monitoredItem; ShowValue(ref index, ref overwrite, monitoredItem.LastValue); return; } // show data changes MonitoredItemNotification datachange = value as MonitoredItemNotification; if (datachange != null) { ShowValue(ref index, ref overwrite, datachange.Value); return; } // show events EventFieldList eventFields = value as EventFieldList; if (eventFields != null) { for (int ii = 0; ii < eventFields.EventFields.Count; ii++) { ShowValue(ref index, ref overwrite, eventFields, ii); } return; } // show extension bodies. ExtensionObject extension = value as ExtensionObject; if (extension != null) { ShowValue(ref index, ref overwrite, extension.Body); return; } // show encodeables. IEncodeable encodeable = value as IEncodeable; if (encodeable != null) { PropertyInfo[] properties = encodeable.GetType().GetProperties(); foreach (PropertyInfo property in properties) { ShowValue(ref index, ref overwrite, encodeable, property); } return; } // show bytes. byte[] bytes = value as byte[]; if (bytes != null) { if (!PromptOnLongList(bytes.Length / 16)) { return; } for (int ii = 0; ii < bytes.Length; ii += 16) { ShowValue(ref index, ref overwrite, bytes, ii); } return; } // show arrays Array array = value as Array; if (array != null) { if (!PromptOnLongList(array.Length)) { return; } for (int ii = 0; ii < array.Length; ii++) { ShowValue(ref index, ref overwrite, array, ii); } return; } // show lists IList list = value as IList; if (list != null) { if (!PromptOnLongList(list.Count)) { return; } for (int ii = 0; ii < list.Count; ii++) { ShowValue(ref index, ref overwrite, list, ii); } return; } // show xml elements XmlElement xml = value as XmlElement; if (xml != null) { if (!PromptOnLongList(xml.ChildNodes.Count)) { return; } for (int ii = 0; ii < xml.ChildNodes.Count; ii++) { ShowValue(ref index, ref overwrite, xml, ii); } return; } // show data value. DataValue datavalue = value as DataValue; if (datavalue != null) { ShowValue(ref index, ref overwrite, datavalue, 0); ShowValue(ref index, ref overwrite, datavalue, 1); ShowValue(ref index, ref overwrite, datavalue, 2); ShowValue(ref index, ref overwrite, datavalue, 3); return; } // show node id value. NodeId nodeId = value as NodeId; if (nodeId != null) { ShowValue(ref index, ref overwrite, nodeId, 0); ShowValue(ref index, ref overwrite, nodeId, 1); ShowValue(ref index, ref overwrite, nodeId, 2); return; } // show expanded node id value. ExpandedNodeId expandedNodeId = value as ExpandedNodeId; if (expandedNodeId != null) { ShowValue(ref index, ref overwrite, expandedNodeId, 0); ShowValue(ref index, ref overwrite, expandedNodeId, 1); ShowValue(ref index, ref overwrite, expandedNodeId, 2); ShowValue(ref index, ref overwrite, expandedNodeId, 3); return; } // show qualified name value. QualifiedName qualifiedName = value as QualifiedName; if (qualifiedName != null) { ShowValue(ref index, ref overwrite, qualifiedName, 0); ShowValue(ref index, ref overwrite, qualifiedName, 1); return; } // show qualified name value. LocalizedText localizedText = value as LocalizedText; if (localizedText != null) { ShowValue(ref index, ref overwrite, localizedText, 0); ShowValue(ref index, ref overwrite, localizedText, 1); return; } // show variant. Variant?variant = value as Variant?; if (variant != null) { ShowValue(ref index, ref overwrite, variant.Value.Value); return; } // show unknown types as strings. ShowValue(ref index, ref overwrite, String.Format("{0}", value)); }
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."); } 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, 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); }
/// <summary> /// Reads the value for an attribute of a node. /// </summary> public DataValue ReadAttributeValue( IOperationContext context, ExpandedNodeId typeDefinitionId, IList<QualifiedName> relativePath, uint attributeId, NumericRange indexRange) { lock (DataLock) { // check for match on the event type being searched. if (!Server.TypeTree.IsTypeOf(TypeDefinitionId, typeDefinitionId)) { return new DataValue(StatusCodes.BadNotSupported); } // find the target. NodeSource target = this; if (relativePath != null && relativePath.Count > 0) { target = Find(relativePath, 0); if (target == null) { return new DataValue(StatusCodes.BadNotSupported); } } // read the attribute value. DataValue dataValue = new DataValue(); ServiceResult result = target.Read(context, attributeId, dataValue); if (ServiceResult.IsBad(result)) { return new DataValue(result.StatusCode); } // apply any index range. object value = dataValue.Value; result = indexRange.ApplyRange(ref value); if (ServiceResult.IsBad(result)) { return new DataValue(result.StatusCode); } dataValue.Value = value; // return the value. return dataValue; } }
/// <summary> /// Decode nodeset node to node state /// </summary> /// <param name="vertex"></param> /// <param name="dataTypeId"></param> /// <param name="nodeReferences"></param> /// <param name="rolePermissions"></param> /// <param name="userRolePermissions"></param> /// <param name="codec"></param> /// <returns></returns> public static BaseNodeModel ToNodeModel(this BaseNodeVertexModel vertex, string dataTypeId, IEnumerable <ReferenceNodeVertexModel> nodeReferences, IEnumerable <RolePermissionEdgeModel> rolePermissions, IEnumerable <RolePermissionEdgeModel> userRolePermissions, IVariantEncoder codec) { BaseNodeModel decoded; switch (vertex) { case ObjectNodeVertexModel uaObject: decoded = new ObjectNodeModel(null) { EventNotifier = (byte?)uaObject.EventNotifier }; break; case PropertyNodeVertexModel uaProperty: decoded = new PropertyNodeModel(null) { DataType = dataTypeId.ToNodeId(codec.Context), ValueRank = (int?)uaProperty.ValueRank, ArrayDimensions = uaProperty.ArrayDimensions, AccessLevelEx = (uint?)uaProperty.AccessLevel, AccessLevel = uaProperty.AccessLevel == null ? null : (byte?)((uint)uaProperty.AccessLevel.Value & 0xff), UserAccessLevel = uaProperty.UserAccessLevel == null ? null : (byte?)((uint)uaProperty.UserAccessLevel.Value & 0xff), MinimumSamplingInterval = uaProperty.MinimumSamplingInterval, Historizing = uaProperty.Historizing, Value = codec.Decode(uaProperty.Value, uaProperty.BuiltInType), TypeDefinitionId = null }; break; case VariableNodeVertexModel uaVariable: decoded = new DataVariableNodeModel(null) { DataType = dataTypeId.ToNodeId(codec.Context), ValueRank = (int?)uaVariable.ValueRank, ArrayDimensions = uaVariable.ArrayDimensions, AccessLevelEx = (uint?)uaVariable.AccessLevel, AccessLevel = uaVariable.AccessLevel == null ? null : (byte?)((uint)uaVariable.AccessLevel.Value & 0xFF), UserAccessLevel = uaVariable.UserAccessLevel == null ? null : (byte?)((uint)uaVariable.UserAccessLevel.Value & 0xff), MinimumSamplingInterval = uaVariable.MinimumSamplingInterval, Historizing = uaVariable.Historizing, Value = codec.Decode(uaVariable.Value, uaVariable.BuiltInType), TypeDefinitionId = null }; break; case MethodNodeVertexModel uaMethod: decoded = new MethodNodeModel(null) { Executable = uaMethod.Executable ?? false, UserExecutable = uaMethod.UserExecutable ?? false, TypeDefinitionId = null }; break; case ViewNodeVertexModel uaView: decoded = new ViewNodeModel { ContainsNoLoops = uaView.ContainsNoLoops }; break; case ObjectTypeNodeVertexModel uaObjectType: decoded = new ObjectTypeNodeModel { IsAbstract = uaObjectType.IsAbstract }; break; case PropertyTypeNodeVertexModel uaPropertyType: decoded = new PropertyTypeNodeModel { IsAbstract = uaPropertyType.IsAbstract, DataType = dataTypeId.ToNodeId(codec.Context), ValueRank = (int?)uaPropertyType.ValueRank, ArrayDimensions = uaPropertyType.ArrayDimensions, Value = codec.Decode(uaPropertyType.Value, uaPropertyType.BuiltInType) }; break; case VariableTypeNodeVertexModel uaVariableType: decoded = new DataVariableTypeNodeModel { IsAbstract = uaVariableType.IsAbstract, DataType = dataTypeId.ToNodeId(codec.Context), ValueRank = (int?)uaVariableType.ValueRank, ArrayDimensions = uaVariableType.ArrayDimensions, Value = codec.Decode(uaVariableType.Value, uaVariableType.BuiltInType) }; break; case DataTypeNodeVertexModel uaDataType: decoded = new DataTypeNodeModel { IsAbstract = uaDataType.IsAbstract, Definition = uaDataType.DataTypeDefinition == null ? null : (DataTypeDefinition)(codec.Decode(uaDataType.DataTypeDefinition, BuiltInType.ExtensionObject).Value as ExtensionObject)?.Body, Purpose = Opc.Ua.Nodeset.Schema.DataTypePurpose.Normal }; break; case ReferenceTypeNodeVertexModel uaReferenceType: decoded = new ReferenceTypeNodeModel { IsAbstract = uaReferenceType.IsAbstract, InverseName = uaReferenceType.InverseName.ToLocalizedText(), Symmetric = uaReferenceType.Symmetric }; break; default: return(null); } decoded.NodeId = vertex.NodeId; decoded.BrowseName = vertex.BrowseName.ToQualifiedName(codec.Context); decoded.DisplayName = vertex.DisplayName.ToLocalizedText(); decoded.Description = vertex.Description.ToLocalizedText(); decoded.WriteMask = (AttributeWriteMask)vertex.WriteMask; decoded.UserWriteMask = (AttributeWriteMask)vertex.UserWriteMask; decoded.RolePermissions = rolePermissions? .Select(r => new RolePermissionType { Permissions = (uint)(PermissionType)(r.Permissions ?? 0), RoleId = r.RoleId.ToNodeId(codec.Context) }) .ToList(); decoded.UserRolePermissions = userRolePermissions? .Select(r => new RolePermissionType { Permissions = (uint)(PermissionType)(r.Permissions ?? 0), RoleId = r.RoleId.ToNodeId(codec.Context) }) .ToList(); if (!string.IsNullOrEmpty(vertex.SymbolicName)) { decoded.SymbolicName = vertex.SymbolicName; } // Decode references var references = new List <IReference>(); if (nodeReferences != null) { foreach (var reference in nodeReferences) { var referenceTypeId = reference.ReferenceTypeId.ToNodeId(codec.Context); var isInverse = reference.TargetId == vertex.NodeId; var targetId = isInverse ? reference.OriginId.ToNodeId(codec.Context) : reference.TargetId.ToNodeId(codec.Context); if (decoded is InstanceNodeModel instance) { if (referenceTypeId == ReferenceTypeIds.HasModellingRule && !isInverse) { instance.ModellingRuleId = ExpandedNodeId.ToNodeId( targetId, codec.Context.NamespaceUris); continue; } if (referenceTypeId == ReferenceTypeIds.HasTypeDefinition && !isInverse) { instance.TypeDefinitionId = ExpandedNodeId.ToNodeId( targetId, codec.Context.NamespaceUris); continue; } } if (decoded is TypeNodeModel type) { if (referenceTypeId == ReferenceTypeIds.HasSubtype && isInverse) { type.SuperTypeId = ExpandedNodeId.ToNodeId(targetId, codec.Context.NamespaceUris); continue; } } references.Add(new NodeStateReference(referenceTypeId, isInverse, targetId)); } } decoded.AddReferences(references); return(decoded); }
/// <summary> /// Finds the child node with the specified browse name. /// </summary> private INode FindChildByName(ExpandedNodeId startId, string browseName) { // find all parent nodes. IList<INode> children; try { children = m_session.NodeCache.Find(startId, ReferenceTypes.HasEventSource, false, true); // This would also include // the HasNotifier reference which is // a subtype of HasEventSource foreach (INode child in children) { // ignore external nodes. if (child.NodeId.IsAbsolute) { continue; } // ignore non-objects/variables. if ((child.NodeClass & (NodeClass.Object | NodeClass.Variable)) == 0) { continue; } // ignore the namespace when comparing. if (browseName == child.BrowseName.ToString()) { return child; } } } catch (Exception e) { Utils.Trace(e, "Unexpected error in FindChildByName"); } // child with specified browse name does not exist. return null; }
/// <summary> /// Returns the node ids for a set of relative paths. /// </summary> /// <param name="session">An open session with the server to use.</param> /// <param name="startNodeId">The starting node for the relative paths.</param> /// <param name="namespacesUris">The namespace URIs referenced by the relative paths.</param> /// <param name="relativePaths">The relative paths.</param> /// <returns>A collection of local nodes.</returns> public static List <NodeId> TranslateBrowsePaths( Session session, NodeId startNodeId, NamespaceTable namespacesUris, params string[] relativePaths) { // build the list of browse paths to follow by parsing the relative paths. BrowsePathCollection browsePaths = new BrowsePathCollection(); if (relativePaths != null) { for (int ii = 0; ii < relativePaths.Length; ii++) { BrowsePath browsePath = new BrowsePath(); // The relative paths used indexes in the namespacesUris table. These must be // converted to indexes used by the server. An error occurs if the relative path // refers to a namespaceUri that the server does not recognize. // The relative paths may refer to ReferenceType by their BrowseName. The TypeTree object // allows the parser to look up the server's NodeId for the ReferenceType. browsePath.RelativePath = RelativePath.Parse( relativePaths[ii], session.TypeTree, namespacesUris, session.NamespaceUris); browsePath.StartingNode = startNodeId; browsePaths.Add(browsePath); } } // make the call to the server. BrowsePathResultCollection results; DiagnosticInfoCollection diagnosticInfos; ResponseHeader responseHeader = session.TranslateBrowsePathsToNodeIds( null, browsePaths, out results, out diagnosticInfos); // ensure that the server returned valid results. Session.ValidateResponse(results, browsePaths); Session.ValidateDiagnosticInfos(diagnosticInfos, browsePaths); // collect the list of node ids found. List <NodeId> nodes = new List <NodeId>(); for (int ii = 0; ii < results.Count; ii++) { // check if the start node actually exists. if (StatusCode.IsBad(results[ii].StatusCode)) { nodes.Add(null); continue; } // an empty list is returned if no node was found. if (results[ii].Targets.Count == 0) { nodes.Add(null); continue; } // Multiple matches are possible, however, the node that matches the type model is the // one we are interested in here. The rest can be ignored. BrowsePathTarget target = results[ii].Targets[0]; if (target.RemainingPathIndex != UInt32.MaxValue) { nodes.Add(null); continue; } // The targetId is an ExpandedNodeId because it could be node in another server. // The ToNodeId function is used to convert a local NodeId stored in a ExpandedNodeId to a NodeId. nodes.Add(ExpandedNodeId.ToNodeId(target.TargetId, session.NamespaceUris)); } // return whatever was found. return(nodes); }
/// <summary> /// Returns an image index for the specified attribute. /// </summary> public static int GetImageIndex(Session session, NodeClass nodeClass, ExpandedNodeId typeDefinitionId, bool selected) { if (nodeClass == NodeClass.Variable) { if (session.NodeCache.IsTypeOf(typeDefinitionId, Opc.Ua.VariableTypeIds.PropertyType)) { return ClientUtils.Property; } return ClientUtils.Variable; } if (nodeClass == NodeClass.Object) { if (session.NodeCache.IsTypeOf(typeDefinitionId, Opc.Ua.ObjectTypeIds.FolderType)) { if (selected) { return ClientUtils.OpenFolder; } else { return ClientUtils.ClosedFolder; } } return ClientUtils.Object; } if (nodeClass == NodeClass.Method) { return ClientUtils.Method; } if (nodeClass == NodeClass.View) { return ClientUtils.View; } return ClientUtils.ObjectType; }
public static async Task ConsoleSampleClient(string endpointURL, int timeOut, bool autoAccept) { Console.WriteLine("1 - Create an Application Configuration."); exitCode = ExitCode.ErrorCreateApplication; 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\\My", 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 = autoAccept }, 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); exitCode = ExitCode.ErrorDiscoverEndpoints; var selectedEndpoint = CoreClientUtils.SelectEndpoint(endpointURL, haveAppCertificate, 15000); Console.WriteLine(" Selected endpoint uses: {0}", selectedEndpoint.SecurityPolicyUri.Substring(selectedEndpoint.SecurityPolicyUri.LastIndexOf('#') + 1)); Console.WriteLine("3 - Create a session with OPC UA server."); exitCode = ExitCode.ErrorCreateSession; 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."); exitCode = ExitCode.ErrorBrowseNamespace; 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."); exitCode = ExitCode.ErrorCreateSubscription; var subscription = new Subscription(session.DefaultSubscription) { PublishingInterval = 1000 }; Console.WriteLine("6 - Add a list of items (server current time and status) to the subscription."); exitCode = ExitCode.ErrorMonitoredItem; var list = new List <MonitoredItem> { new MonitoredItem(subscription.DefaultItem) { DisplayName = "ServerStatusCurrentTime", StartNodeId = "i=" + Variables.Server_ServerStatus_CurrentTime.ToString() } }; list.ForEach(i => i.Notification += OnNotification); subscription.AddItems(list); Console.WriteLine("7 - Add the subscription to the session."); exitCode = ExitCode.ErrorAddSubscription; session.AddSubscription(subscription); subscription.Create(); Console.WriteLine("8 - Running...Press Ctrl-C to exit..."); exitCode = ExitCode.ErrorRunning; ManualResetEvent quitEvent = new ManualResetEvent(false); try { Console.CancelKeyPress += (sender, eArgs) => { quitEvent.Set(); eArgs.Cancel = true; }; } catch { } // wait for timeout or Ctrl-C quitEvent.WaitOne(timeOut); // return error conditions if (session.KeepAliveStopped) { exitCode = ExitCode.ErrorNoKeepAlive; return; } exitCode = ExitCode.Ok; }