public T ReadExtensionObject <T>(string fieldName) where T : IEncodable { NodeId nodeId = this.ReadNodeId(null); byte b = this.reader.ReadByte(); if (b == 1) { ExpandedNodeId binaryEncodingId = NodeId.ToExpandedNodeId(nodeId, this.channel?.NamespaceUris); Type type2; if (!UaTcpSecureChannel.BinaryEncodingIdToTypeDictionary.TryGetValue(binaryEncodingId, out type2)) { throw new ServiceResultException(StatusCodes.BadDataTypeIdUnknown); } if (!typeof(T).GetTypeInfo().IsAssignableFrom(type2.GetTypeInfo())) { throw new ServiceResultException(StatusCodes.BadDecodingError); } var len = this.ReadInt32(null); var encodable = Activator.CreateInstance(type2) as IEncodable; encodable.Decode(this); return((T)encodable); } // TODO: else if (b = 2) use XmlDecoder return(default(T)); }
public ExtensionObject ReadExtensionObject(string fieldName) { Type type; NodeId nodeId = this.ReadNodeId(null); byte b = this.reader.ReadByte(); if (b == (byte)BodyType.ByteString) // BodyType Encodable is encoded as ByteString. { ExpandedNodeId binaryEncodingId = NodeId.ToExpandedNodeId(nodeId, this.channel?.NamespaceUris); if (this.channel.TryGetTypeFromEncodingId(nodeId, out type)) { var len = this.ReadInt32(null); var encodable = Activator.CreateInstance(type) as IEncodable; encodable.Decode(this); return(new ExtensionObject(encodable, binaryEncodingId)); } return(new ExtensionObject(this.ReadByteString(null), binaryEncodingId)); } if (b == (byte)BodyType.XmlElement) { ExpandedNodeId xmlEncodingId = NodeId.ToExpandedNodeId(nodeId, this.channel?.NamespaceUris); return(new ExtensionObject(this.ReadXElement(null), xmlEncodingId)); } return(null); }
public ExtensionObject ReadExtensionObject(string fieldName) { NodeId nodeId = this.ReadNodeId(null); byte b = this.reader.ReadByte(); if (b == 1) { ExpandedNodeId binaryEncodingId = NodeId.ToExpandedNodeId(nodeId, this.channel?.NamespaceUris); Type type2; if (UaTcpSecureChannel.BinaryEncodingIdToTypeDictionary.TryGetValue(binaryEncodingId, out type2)) { var len = this.ReadInt32(null); var encodable = Activator.CreateInstance(type2) as IEncodable; encodable.Decode(this); return(new ExtensionObject(encodable)); } return(new ExtensionObject(this.ReadByteString(null), binaryEncodingId)); } else if (b == 2) { ExpandedNodeId xmlEncodingId = NodeId.ToExpandedNodeId(nodeId, this.channel?.NamespaceUris); return(new ExtensionObject(this.ReadXElement(null), xmlEncodingId)); } return(null); }
/// <summary> /// Returns a uri that identifies the node id uniquely. If the server /// uri information is provided, and the it contains a server name at /// index 0, the node id will be formatted as an expanded node id uri /// (see below). Otherwise, the resource is the namespace and not the /// server. /// </summary> /// <param name="nodeId"></param> /// <param name="context"></param> /// <param name="noRelativeUriAllowed"></param> /// <returns></returns> public static string AsString(this NodeId nodeId, ServiceMessageContext context, bool noRelativeUriAllowed = false) { if (NodeId.IsNull(nodeId)) { return(null); } return(nodeId.ToExpandedNodeId(context?.NamespaceUris).AsString(context, noRelativeUriAllowed)); }
public void FetchAllReferenceTypes() { var bindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public; var fieldValues = typeof(ReferenceTypeIds) .GetFields(bindingFlags) .Select(field => NodeId.ToExpandedNodeId((NodeId)field.GetValue(null), Session.NamespaceUris)); Session.FetchTypeTree(new ExpandedNodeIdCollection(fieldValues)); }
public bool TryGetExpandedNodeId(NodeId nodeId, out ExpandedNodeId eId) { if (nodeId == null) { eId = null; return(false); } eId = NodeId.ToExpandedNodeId(nodeId, _namespaceUris); return(eId != null); }
/// <summary> /// Helper to cast a enumeration node value to an enumeration type. /// </summary> private void CastInt32ToEnum(VariableNode variableNode, DataValue value) { if (value.Value?.GetType() == typeof(Int32)) { // test if this is an enum datatype? Type systemType = m_session.Factory.GetSystemType( NodeId.ToExpandedNodeId(variableNode.DataType, m_session.NamespaceUris) ); if (systemType != null) { value.Value = Enum.ToObject(systemType, value.Value); } } }
public void NodeIdConstructor() { Guid id1 = Guid.NewGuid(); NodeId nodeId1 = new NodeId(id1); // implicit conversion; NodeId inodeId1 = id1; Assert.AreEqual(nodeId1, inodeId1); byte[] id2 = new byte[] { 65, 66, 67, 68, 69 }; NodeId nodeId2 = new NodeId(id2); // implicit conversion; NodeId inodeId2 = id2; Assert.AreEqual(nodeId2, inodeId2); _ = nodeId2 < inodeId2; _ = nodeId2 == inodeId2; _ = nodeId2 > inodeId2; string text = "i=123"; NodeId nodeIdText = new NodeId(text); Assert.AreEqual(123, nodeIdText.Identifier); // implicit conversion; NodeId inodeIdText = text; Assert.AreEqual(nodeIdText, inodeIdText); _ = nodeIdText < inodeIdText; _ = nodeIdText == inodeIdText; _ = nodeIdText > inodeIdText; _ = nodeIdText < nodeId2; _ = nodeIdText == nodeId2; _ = nodeIdText > nodeId2; _ = new NodeId((object)(uint)123, 123); _ = new NodeId((object)"Test", 123); _ = new NodeId((object)id2, 123); _ = new NodeId((object)null, 123); _ = new NodeId((object)id1, 123); Assert.Throws <ArgumentException>(() => _ = new NodeId((object)(int)123, 123)); Assert.Throws <ServiceResultException>(() => _ = NodeId.Create((uint)123, "urn:xyz", null)); Assert.Throws <ServiceResultException>(() => _ = NodeId.Parse("ns=")); Assert.IsNull(NodeId.ToExpandedNodeId(null, null)); }
/// <summary> /// Decodes a message from a buffer. /// </summary> private static IEncodeable DecodeBinaryMessage(Stream stream, ServiceMessageContext context) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } if (context == null) { throw new ArgumentNullException(nameof(context)); } MemoryStream buffer = null; try { // // Binary decoder unfortunately uses seeking (to keep track of // position). Therefore we need to wrap a non seeking stream. // if (!stream.CanSeek) { // Read entire buffer and pass as memory stream. var segment = stream.ReadAsBuffer(); stream = buffer = new MemoryStream(segment.Array, 0, segment.Count); } using (var decoder = new BinaryDecoder(stream, context)) { // read the node id. var typeId = decoder.ReadNodeId(null); // convert to absolute node id. var absoluteId = NodeId.ToExpandedNodeId(typeId, context.NamespaceUris); // lookup message type. var actualType = context.Factory.GetSystemType(absoluteId); if (actualType == null) { throw new ServiceResultException(StatusCodes.BadEncodingError, $"Cannot decode message with type id: {absoluteId}."); } // read the message. return(decoder.ReadEncodeable(null, actualType)); } } finally { buffer?.Dispose(); } }
public void NodeCache_References() { INodeCache nodeCache = Session.NodeCache; Assert.IsNotNull(nodeCache); // ensure the predefined types are loaded nodeCache.LoadUaDefinedTypes(Session.SystemContext); // check on all reference type ids var refTypeDictionary = typeof(ReferenceTypeIds).GetFields(BindingFlags.Public | BindingFlags.Static) .Where(f => f.FieldType == typeof(NodeId)) .ToDictionary(f => f.Name, f => (NodeId)f.GetValue(null)); TestContext.Out.WriteLine("Testing {0} references", refTypeDictionary.Count); foreach (var property in refTypeDictionary) { TestContext.Out.WriteLine("FindReferenceTypeName({0})={1}", property.Value, property.Key); // find the Qualified Name var qn = nodeCache.FindReferenceTypeName(property.Value); Assert.NotNull(qn); Assert.AreEqual(property.Key, qn.Name); // find the node by name var refId = nodeCache.FindReferenceType(new QualifiedName(property.Key)); Assert.NotNull(refId); Assert.AreEqual(property.Value, refId); // is the node id known? var isKnown = nodeCache.IsKnown(property.Value); Assert.IsTrue(isKnown); // is it a reference? var isTypeOf = nodeCache.IsTypeOf( NodeId.ToExpandedNodeId(refId, Session.NamespaceUris), NodeId.ToExpandedNodeId(ReferenceTypeIds.References, Session.NamespaceUris)); Assert.IsTrue(isTypeOf); // negative test isTypeOf = nodeCache.IsTypeOf( NodeId.ToExpandedNodeId(refId, Session.NamespaceUris), NodeId.ToExpandedNodeId(DataTypeIds.Byte, Session.NamespaceUris)); Assert.IsFalse(isTypeOf); var subTypes = nodeCache.FindSubTypes(NodeId.ToExpandedNodeId(refId, Session.NamespaceUris)); Assert.NotNull(subTypes); } }
/// <summary> /// save server connection settings and node subscription list to app storage /// <summary> private OpcuaSessionConfig SaveSessionConfig(string targetfile, string sesssionName, Session session) { OpcuaSessionConfig sessionConfig = null; if (session != null) { try { sessionConfig = new OpcuaSessionConfig(); sessionConfig.timestamp = DateTime.Now; sessionConfig.endpoint = session.ConfiguredEndpoint; sessionConfig.sessionname = sesssionName; sessionConfig.monitoredlist = new List <MonitoredNode>(); sessionConfig.publishinterval = session.DefaultSubscription.PublishingInterval; NamespaceTable namespaceTable = new NamespaceTable(); DataValue namespaceArrayNodeValue = session.ReadValue(VariableIds.Server_NamespaceArray); namespaceTable.Update(namespaceArrayNodeValue.GetValue <string[]>(null)); //collect monitored list foreach (MonitoredItem x in session.DefaultSubscription.MonitoredItems) { int trimStartIndex = x.DisplayName.IndexOf(" ("); var displayName = x.DisplayName.Substring(trimStartIndex + 2); displayName = displayName.Remove(displayName.IndexOf(" -")); var description = (trimStartIndex >= 0) ? x.DisplayName.Remove(trimStartIndex) : x.DisplayName; ExpandedNodeId expendedId = NodeId.ToExpandedNodeId(x.StartNodeId, namespaceTable); MonitoredNode monnode = new MonitoredNode(expendedId.ToString(), displayName, description); sessionConfig.monitoredlist.Add(monnode); } sessionConfig.SaveToJsonFile(targetfile); } catch (Exception exception) { GuiUtils.HandleException(String.Empty, GuiUtils.CallerName(), exception); sessionConfig = null; } } return(sessionConfig); }
/// <summary> /// Helper to ensure the expanded nodeId contains a valid namespaceUri. /// </summary> /// <param name="expandedNodeId">The expanded nodeId.</param> /// <param name="namespaceTable">The session namespace table.</param> /// <returns>The normalized expanded nodeId.</returns> private ExpandedNodeId NormalizeExpandedNodeId(ExpandedNodeId expandedNodeId) { var nodeId = ExpandedNodeId.ToNodeId(expandedNodeId, m_session.NamespaceUris); return NodeId.ToExpandedNodeId(nodeId, m_session.NamespaceUris); }
public void FetchTypeTree() { Session.FetchTypeTree(NodeId.ToExpandedNodeId(DataTypeIds.BaseDataType, Session.NamespaceUris)); }
private async Task LoadChildrenAsync(ReferenceDescriptionViewModel parent) { try { var token = this.cts.Token; await [email protected](token); this.NotifyPropertyChanged("IsLoading"); try { parent.Children.Clear(); do { try { if (this.channel == null || this.channel.State != CommunicationState.Opened) { var getEndpointsRequest = new GetEndpointsRequest { EndpointUrl = this.endpointUrl, ProfileUris = new[] { TransportProfileUris.UaTcpTransport } }; var getEndpointsResponse = await UaTcpDiscoveryClient.GetEndpointsAsync(getEndpointsRequest); token.ThrowIfCancellationRequested(); var selectedEndpoint = getEndpointsResponse.Endpoints.OrderBy(e => e.SecurityLevel).First(); if (selectedEndpoint.UserIdentityTokens.Any(p => p.TokenType == UserTokenType.Anonymous)) { this.HideLoginPanel(); this.userIdentity = new AnonymousIdentity(); } else if (selectedEndpoint.UserIdentityTokens.Any(p => p.TokenType == UserTokenType.UserName)) { if (!this.showingLoginPanel) { this.ShowLoginPanel(); return; } else if (!this.ValidateLoginCredentials()) { return; } else { this.userIdentity = new UserNameIdentity(this.userName, this.password); } } else { throw new NotImplementedException("Browser supports only UserName and Anonymous identity, for now."); } dataTypeCache = new Dictionary <ExpandedNodeId, Type>(); this.channel = new UaTcpSessionChannel( this.localDescription, this.CertificateStore, this.userIdentity, selectedEndpoint); await this.channel.OpenAsync(); } token.ThrowIfCancellationRequested(); var rds = new List <ReferenceDescription>(); var browseRequest = new BrowseRequest { NodesToBrowse = new[] { new BrowseDescription { NodeId = ExpandedNodeId.ToNodeId(parent.NodeId, this.channel.NamespaceUris), ReferenceTypeId = NodeId.Parse(ReferenceTypeIds.HierarchicalReferences), ResultMask = (uint)BrowseResultMask.TargetInfo, NodeClassMask = (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, BrowseDirection = BrowseDirection.Forward, IncludeSubtypes = true } } }; var browseResponse = await this.channel.BrowseAsync(browseRequest); rds.AddRange(browseResponse.Results.Where(result => result.References != null).SelectMany(result => result.References)); var continuationPoints = browseResponse.Results.Select(br => br.ContinuationPoint).Where(cp => cp != null).ToArray(); while (continuationPoints.Length > 0) { token.ThrowIfCancellationRequested(); var browseNextRequest = new BrowseNextRequest { ContinuationPoints = continuationPoints, ReleaseContinuationPoints = false }; var browseNextResponse = await this.channel.BrowseNextAsync(browseNextRequest); rds.AddRange(browseResponse.Results.Where(result => result.References != null).SelectMany(result => result.References)); } if (rds.Count == 0) { return; } foreach (var rd in rds) { token.ThrowIfCancellationRequested(); var n = ExpandedNodeId.ToNodeId(rd.NodeId, this.channel.NamespaceUris); Type dataType = null; EventNotifierFlags notifier = EventNotifierFlags.None; AccessLevelFlags accessLevel = AccessLevelFlags.None; if (rd.NodeClass == NodeClass.Variable) { var readRequest = new ReadRequest { NodesToRead = new ReadValueId[] { new ReadValueId { NodeId = n, AttributeId = AttributeIds.DataType }, new ReadValueId { NodeId = n, AttributeId = AttributeIds.ValueRank }, new ReadValueId { NodeId = n, AttributeId = AttributeIds.UserAccessLevel } } }; var readResponse = await this.channel.ReadAsync(readRequest); ExpandedNodeId dataTypeId, origDataTypeId; ReferenceDescription dataTypeRef; var dataTypeNode = readResponse.Results[0].GetValueOrDefault(NodeId.Null); if (dataTypeNode != NodeId.Null) { dataTypeId = origDataTypeId = NodeId.ToExpandedNodeId(dataTypeNode, this.channel.NamespaceUris); if (!this.dataTypeCache.TryGetValue(dataTypeId, out dataType)) { if (!UaTcpSecureChannel.DataTypeIdToTypeDictionary.TryGetValue(dataTypeId, out dataType)) { do { dataTypeNode = ExpandedNodeId.ToNodeId(dataTypeId, this.channel.NamespaceUris); var browseRequest2 = new BrowseRequest { NodesToBrowse = new[] { new BrowseDescription { NodeId = dataTypeNode, ReferenceTypeId = NodeId.Parse(ReferenceTypeIds.HasSubtype), ResultMask = (uint)BrowseResultMask.None, NodeClassMask = (uint)NodeClass.DataType, BrowseDirection = BrowseDirection.Inverse, IncludeSubtypes = false } } }; var browseResponse2 = await this.channel.BrowseAsync(browseRequest2); dataTypeRef = browseResponse2.Results[0].References?.FirstOrDefault(); dataTypeId = dataTypeRef?.NodeId; }while (dataTypeId != null && !UaTcpSecureChannel.DataTypeIdToTypeDictionary.TryGetValue(dataTypeId, out dataType)); if (dataTypeId == null) { dataType = typeof(object); } } this.dataTypeCache.Add(origDataTypeId, dataType); } var valueRank = readResponse.Results[1].GetValueOrDefault(-1); if (valueRank == 1) { dataType = dataType.MakeArrayType(); } if (valueRank > 1) { dataType = dataType.MakeArrayType(valueRank); } } else { dataType = typeof(object); } accessLevel = (AccessLevelFlags)Enum.ToObject(typeof(AccessLevelFlags), readResponse.Results[2].GetValueOrDefault <byte>()); } else if (rd.NodeClass == NodeClass.Object) { var readRequest = new ReadRequest { NodesToRead = new ReadValueId[] { new ReadValueId { NodeId = n, AttributeId = AttributeIds.EventNotifier }, } }; var readResponse = await this.channel.ReadAsync(readRequest); notifier = (EventNotifierFlags)Enum.ToObject(typeof(EventNotifierFlags), readResponse.Results[0].GetValueOrDefault <byte>()); } parent.Children.Add(new ReferenceDescriptionViewModel(rd, dataType, accessLevel, notifier, parent, this.LoadChildrenAsync)); await Task.Yield(); } break; // exit while; } catch (OperationCanceledException ex) { // exit while; } catch (ServiceResultException ex) { Console.WriteLine("ServiceResultException: {0}", ex); if (this.channel != null) { await this.channel.AbortAsync(token); this.channel = null; } if (ex.HResult == unchecked ((int)StatusCodes.BadSessionIdInvalid)) { continue; } } catch (Exception ex) { Console.WriteLine("Exception {0}", ex); if (this.channel != null) { await this.channel.AbortAsync(token); this.channel = null; } } try { await Task.Delay(5000, token); } catch (OperationCanceledException) { } }while (!token.IsCancellationRequested); } catch (Exception ex) { Console.WriteLine("Exception {0}", ex); } finally { [email protected](); this.NotifyPropertyChanged("IsLoading"); } } catch (OperationCanceledException) { // only get here if cancelled while waiting for lock } }