Beispiel #1
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
 /// <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));
        }
Beispiel #6
0
        public bool TryGetExpandedNodeId(NodeId nodeId, out ExpandedNodeId eId)
        {
            if (nodeId == null)
            {
                eId = null;
                return(false);
            }

            eId = NodeId.ToExpandedNodeId(nodeId, _namespaceUris);

            return(eId != null);
        }
Beispiel #7
0
 /// <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);
         }
     }
 }
Beispiel #8
0
        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();
            }
        }
Beispiel #10
0
        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);
            }
        }
Beispiel #11
0
        /// <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);
        }
Beispiel #12
0
 /// <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);
 }
Beispiel #13
0
 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
            }
        }