/// <summary>
        /// Create encoder for content type
        /// </summary>
        /// <param name="contentType"></param>
        /// <param name="stream"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        private static IDecoder CreateDecoder(string contentType, Stream stream,
                                              IServiceMessageContext context)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }
            switch (contentType.ToLowerInvariant())
            {
            case ContentMimeType.Json:
            case ContentMimeType.UaJson:
                return(new JsonDecoderEx(stream, context));

            case ContentMimeType.UaBinary:
                return(new BinaryDecoder(stream,
                                         context ?? new ServiceMessageContext()));

            case ContentMimeType.UaXml:
                return(new XmlDecoder(null, XmlReader.Create(stream),
                                      context ?? new ServiceMessageContext()));

            default:
                throw new ArgumentException(nameof(contentType));
            }
        }
Exemple #2
0
        /// <summary>
        /// Creates a new transport channel that supports the IRegistrationChannel service contract.
        /// </summary>
        /// <param name="configuration">The application configuration.</param>
        /// <param name="description">The description for the endpoint.</param>
        /// <param name="endpointConfiguration">The configuration to use with the endpoint.</param>
        /// <param name="clientCertificate">The client certificate.</param>
        /// <param name="messageContext">The message context to use when serializing the messages.</param>
        /// <returns></returns>
        public static ITransportChannel Create(
            ApplicationConfiguration configuration,
            EndpointDescription description,
            EndpointConfiguration endpointConfiguration,
            X509Certificate2 clientCertificate,
            IServiceMessageContext messageContext)
        {
            // create a UA binary channel.
            ITransportChannel channel = CreateUaBinaryChannel(
                configuration,
                description,
                endpointConfiguration,
                clientCertificate,
                messageContext);

            // create a registration channel.
            if (channel == null)
            {
                Uri endpointUrl = new Uri(description.EndpointUrl);
                channel = new RegistrationChannel();

                TransportChannelSettings settings = new TransportChannelSettings();
                settings.Configuration     = endpointConfiguration;
                settings.Description       = description;
                settings.ClientCertificate = clientCertificate;
                channel.Initialize(endpointUrl, settings);
            }

            return(channel);
        }
        /// <summary>
        /// Returns an expanded node id from a node uri.
        /// </summary>
        /// <param name="value"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public static ExpandedNodeId ToExpandedNodeId(this string value, IServiceMessageContext context)
        {
            if (value == null)
            {
                return(ExpandedNodeId.Null);
            }
            var parts = value.Split(';');

            if (parts.Any(s =>
                          s.StartsWith("ns=", StringComparison.CurrentCulture) ||
                          s.StartsWith("nsu=", StringComparison.CurrentCulture)))
            {
                return(ExpandedNodeId.Parse(value));
            }
            var identifier = ParseNodeIdUri(value, out var nsUri, out var srvUri);

            // Allocate entry in context if does not exist
            var nsIndex = context.NamespaceUris.GetIndexOrAppend(nsUri);

            if (!string.IsNullOrEmpty(srvUri))
            {
                return(new ExpandedNodeId(identifier, 0, nsUri == Namespaces.OpcUa ? null : nsUri,
                                          context.ServerUris.GetIndexOrAppend(srvUri)));
            }
            return(new ExpandedNodeId(identifier, 0, nsUri == Namespaces.OpcUa ? null : nsUri, 0));
        }
 /// <summary>
 /// Encodes the object in the specified stream.
 /// </summary>
 /// <param name="messageContext">The system context.</param>
 /// <param name="writer">The stream to use.</param>
 public override void Encode(IServiceMessageContext messageContext, StreamWriter writer)
 {
     using (BinaryEncoder encoder = new BinaryEncoder(writer.BaseStream, messageContext))
     {
         Encode(encoder);
     }
 }
Exemple #5
0
        /// <summary>
        /// Encoder factory for all encoding types.
        /// </summary>
        /// <returns></returns>
        protected IEncoder CreateEncoder(
            EncodingType encoderType,
            IServiceMessageContext context,
            Stream stream,
            Type systemType,
            bool useReversibleEncoding = true,
            bool topLevelIsArray       = false,
            bool includeDefaultValues  = false,
            bool includeDefaultNumbers = true
            )
        {
            switch (encoderType)
            {
            case EncodingType.Binary:
                Assume.That(useReversibleEncoding, "Binary encoding only supports reversible option.");
                return(new BinaryEncoder(stream, context));

            case EncodingType.Xml:
                Assume.That(useReversibleEncoding, "Xml encoding only supports reversible option.");
                var xmlWriter = XmlWriter.Create(stream);
                return(new XmlEncoder(systemType, xmlWriter, context));

            case EncodingType.Json:
                return(new JsonEncoder(context, useReversibleEncoding, topLevelIsArray, stream)
                {
                    IncludeDefaultValues = includeDefaultValues,
                    IncludeDefaultNumberValues = includeDefaultNumbers
                });
            }
            return(null);
        }
Exemple #6
0
        /// <summary>
        /// Encodes the object in the specified stream.
        /// </summary>
        /// <param name="messageContext">The context.</param>
        /// <param name="stream">The stream to use.</param>
        public override void Encode(IServiceMessageContext messageContext, Stream stream)
        {
            bool topLevelIsArray = !HasNetworkMessageHeader && !HasSingleDataSetMessage && !IsMetaDataMessage;

            using (JsonEncoder encoder = new JsonEncoder(messageContext, true, topLevelIsArray, stream))
            {
                if (IsMetaDataMessage)
                {
                    EncodeNetworkMessageHeader(encoder);

                    encoder.WriteEncodeable(kFieldMetaData, m_metadata, null);

                    return;
                }

                // handle no header
                if (HasNetworkMessageHeader)
                {
                    Encode(encoder);
                }
                else if (DataSetMessages != null && DataSetMessages.Count > 0)
                {
                    if (HasSingleDataSetMessage)
                    {
                        // encode single dataset message
                        JsonDataSetMessage jsonDataSetMessage = DataSetMessages[0] as JsonDataSetMessage;

                        if (jsonDataSetMessage != null)
                        {
                            if (!jsonDataSetMessage.HasDataSetMessageHeader)
                            {
                                // If the NetworkMessageHeader and the DataSetMessageHeader bits are not set
                                // and SingleDataSetMessage bit is set, the NetworkMessage is a JSON object
                                // containing the set of name/value pairs defined for a single DataSet.
                                jsonDataSetMessage.EncodePayload(encoder, false);
                            }
                            else
                            {
                                // If the SingleDataSetMessage bit of the NetworkMessageContentMask is set,
                                // the content of the Messages field is a JSON object containing a single DataSetMessage.
                                jsonDataSetMessage.Encode(encoder);
                            }
                        }
                    }
                    else
                    {
                        // If the NetworkMessageHeader bit of the NetworkMessageContentMask is not set,
                        // the NetworkMessage is the contents of the Messages field (e.g. a JSON array of DataSetMessages).
                        foreach (var message in DataSetMessages)
                        {
                            JsonDataSetMessage jsonDataSetMessage = message as JsonDataSetMessage;
                            if (jsonDataSetMessage != null)
                            {
                                jsonDataSetMessage.Encode(encoder);
                            }
                        }
                    }
                }
            }
        }
 /// <summary>
 /// Encodes the object in the specified stream.
 /// </summary>
 /// <param name="messageContext">The system context.</param>
 /// <param name="stream">The stream to use.</param>
 public override void Encode(IServiceMessageContext messageContext, Stream stream)
 {
     using (BinaryEncoder encoder = new BinaryEncoder(stream, messageContext))
     {
         Encode(encoder);
     }
 }
        /// <summary>
        /// Encodes the object in binary
        /// </summary>
        public static byte[] EncodeBinary(IEncodeable encodeable, IServiceMessageContext context)
        {
            BinaryEncoder encoder = new BinaryEncoder(context);

            encoder.WriteEncodeable(null, encodeable, null);
            return(encoder.CloseAndReturnBuffer());
        }
        /// <summary>
        /// Initializes the datastore with the server configuration.
        /// </summary>
        /// <param name="serverDescription">The server description.</param>
        /// <param name="configuration">The configuration.</param>
        /// <param name="messageContext">The message context.</param>
        /// <param name="certificateValidator">The certificate validator.</param>
        /// <param name="instanceCertificate">The instance certificate.</param>
        public ServerInternalData(
            ServerProperties serverDescription,
            ApplicationConfiguration configuration,
            IServiceMessageContext messageContext,
            CertificateValidator certificateValidator,
            X509Certificate2 instanceCertificate)
        {
            m_serverDescription = serverDescription;
            m_configuration     = configuration;
            m_messageContext    = messageContext;

            m_endpointAddresses = new List <Uri>();

            foreach (string baseAddresses in m_configuration.ServerConfiguration.BaseAddresses)
            {
                Uri url = Utils.ParseUri(baseAddresses);

                if (url != null)
                {
                    m_endpointAddresses.Add(url);
                }
            }

            m_namespaceUris = m_messageContext.NamespaceUris;
            m_factory       = m_messageContext.Factory;

            m_serverUris = new StringTable();
            m_typeTree   = new TypeTable(m_namespaceUris);

            // add the server uri to the server table.
            m_serverUris.Append(m_configuration.ApplicationUri);

            // create the default system context.
            m_defaultSystemContext = new ServerSystemContext(this);
        }
        /// <summary>
        /// Returns a node uri from an expanded node id.
        /// </summary>
        /// <param name="nodeId"></param>
        /// <param name="context"></param>
        /// <param name="noRelativeUriAllowed"></param>
        /// <returns></returns>
        public static string AsString(this ExpandedNodeId nodeId, IServiceMessageContext context,
                                      bool noRelativeUriAllowed = false)
        {
            if (NodeId.IsNull(nodeId))
            {
                return(null);
            }
            var nsUri = nodeId.NamespaceUri;

            if (string.IsNullOrEmpty(nsUri) && (nodeId.NamespaceIndex != 0 || noRelativeUriAllowed))
            {
                nsUri = context.NamespaceUris.GetString(nodeId.NamespaceIndex);
                if (string.IsNullOrEmpty(nsUri))
                {
                    nsUri = null;
                }
            }
            string srvUri = null;

            if (nodeId.ServerIndex != 0 && context.ServerUris != null)
            {
                srvUri = context.ServerUris.GetString(nodeId.ServerIndex);
                if (string.IsNullOrEmpty(srvUri))
                {
                    srvUri = null;
                }
            }
            if (nsUri != null && !Uri.IsWellFormedUriString(nsUri, UriKind.Absolute))
            {
                // Fall back to nsu= format - but strip indexes
                return(new ExpandedNodeId(nodeId.Identifier, 0, nsUri, 0).ToString());
            }
            return(FormatNodeIdUri(nsUri, srvUri, nodeId.IdType, nodeId.Identifier));
        }
        /// <summary>
        /// Creates a new transport channel that supports the IDiscoveryChannel service contract.
        /// </summary>
        public static ITransportChannel Create(
            ApplicationConfiguration configuration,
            Uri discoveryUrl,
            EndpointConfiguration endpointConfiguration,
            IServiceMessageContext messageContext,
            X509Certificate2 clientCertificate = null)
        {
            // create a default description.
            var endpoint = new EndpointDescription {
                EndpointUrl       = discoveryUrl.ToString(),
                SecurityMode      = MessageSecurityMode.None,
                SecurityPolicyUri = SecurityPolicies.None
            };

            endpoint.Server.ApplicationUri  = endpoint.EndpointUrl;
            endpoint.Server.ApplicationType = ApplicationType.DiscoveryServer;

            ITransportChannel channel = CreateUaBinaryChannel(
                configuration,
                endpoint,
                endpointConfiguration,
                clientCertificate,
                (X509Certificate2Collection)null,
                messageContext);

            return(channel);
        }
        /// <summary>
        /// Returns a uri that identifies the qualified name uniquely.
        /// </summary>
        /// <param name="qn"></param>
        /// <param name="context"></param>
        /// <param name="noRelativeUriAllowed"></param>
        /// <returns></returns>
        public static string AsString(this QualifiedName qn, IServiceMessageContext context,
                                      bool noRelativeUriAllowed = false)
        {
            if (qn == null || qn == QualifiedName.Null)
            {
                return(string.Empty);
            }
            var buffer = new StringBuilder();

            if (qn.NamespaceIndex != 0 || noRelativeUriAllowed)
            {
                var nsUri = context.NamespaceUris.GetString(qn.NamespaceIndex);
                if (!string.IsNullOrEmpty(nsUri))
                {
                    buffer.Append(nsUri);
                    if (!string.IsNullOrEmpty(qn.Name))
                    {
                        // Append name as fragment
                        buffer.Append("#");
                    }
                }
            }
            buffer.Append(qn.Name?.UrlEncode() ?? string.Empty);
            return(buffer.ToString());
        }
        protected virtual DiscoveryClient CreateClient(
            string endpointUrl,
            string endpointTransportProfileUri)
        {
            if (String.IsNullOrEmpty(endpointUrl))
            {
                endpointUrl = DefaultUrl;
            }

            if (!Uri.IsWellFormedUriString(endpointUrl, UriKind.Absolute))
            {
                throw new ArgumentException("Not a valid URL.", nameof(endpointUrl));
            }

            IServiceMessageContext context = ApplicationConfiguration.CreateMessageContext();

            EndpointConfiguration configuration = EndpointConfiguration.Create(ApplicationConfiguration);

            if (DefaultOperationTimeout != 0)
            {
                configuration.OperationTimeout = DefaultOperationTimeout;
            }

            ITransportChannel channel = DiscoveryChannel.Create(new Uri(endpointUrl), configuration, context);

            DiscoveryClient client = new DiscoveryClient(channel);

            return(client);
        }
        /// <summary>
        /// Create encoder for content type
        /// </summary>
        /// <param name="contentType"></param>
        /// <param name="stream"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        private static IEncoder CreateEncoder(string contentType, Stream stream,
                                              IServiceMessageContext context)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }
            switch (contentType.ToLowerInvariant())
            {
            case ContentMimeType.Json:
            case ContentMimeType.UaJson:
                return(new JsonEncoderEx(new StreamWriter(stream),
                                         context ?? new ServiceMessageContext(),
                                         JsonEncoderEx.JsonEncoding.Array)
                {
                    UseAdvancedEncoding = true,
                    IgnoreDefaultValues = true
                });

            case ContentMimeType.UaBinary:
                return(new BinaryEncoder(stream,
                                         context ?? new ServiceMessageContext()));

            case ContentMimeType.UaXml:
                return(new XmlEncoder((Type)null, XmlWriter.Create(stream),
                                      context ?? new ServiceMessageContext()));

            default:
                throw new ArgumentException(nameof(contentType));
            }
        }
Exemple #15
0
 /// <summary>
 /// Convert xml to encodeable
 /// </summary>
 /// <param name="xmlElement"></param>
 /// <param name="typeId"></param>
 /// <param name="context"></param>
 /// <returns></returns>
 public static IEncodeable ToEncodeable(this XmlElement xmlElement,
                                        ExpandedNodeId typeId, IServiceMessageContext context)
 {
     using (var decoder = new XmlDecoder(xmlElement, context)) {
         var body = decoder.ReadExtensionObjectBody(typeId);
         return(body as IEncodeable);
     }
 }
Exemple #16
0
 /// <summary>
 /// Encodes the object and returns the resulting byte array.
 /// </summary>
 /// <param name="messageContext">The context.</param>
 public override byte[] Encode(IServiceMessageContext messageContext)
 {
     using (MemoryStream stream = new MemoryStream())
     {
         Encode(messageContext, stream);
         return(stream.ToArray());
     }
 }
 /// <summary>
 /// Creates a new UA-binary transport channel if requested. Null otherwise.
 /// </summary>
 /// <param name="configuration">The application configuration.</param>
 /// <param name="description">The description for the endpoint.</param>
 /// <param name="endpointConfiguration">The configuration to use with the endpoint.</param>
 /// <param name="clientCertificate">The client certificate.</param>
 /// <param name="messageContext">The message context to use when serializing the messages.</param>
 /// <returns></returns>
 public static ITransportChannel CreateUaBinaryChannel(
     ApplicationConfiguration configuration,
     EndpointDescription description,
     EndpointConfiguration endpointConfiguration,
     X509Certificate2 clientCertificate,
     IServiceMessageContext messageContext)
 {
     return(CreateUaBinaryChannel(configuration, description, endpointConfiguration, clientCertificate, null, messageContext));
 }
Exemple #18
0
 /// <summary>
 /// Convert encodeable to binary
 /// </summary>
 /// <param name="encodeable"></param>
 /// <param name="context"></param>
 /// <returns></returns>
 public static byte[] AsBinary(this IEncodeable encodeable,
                               IServiceMessageContext context)
 {
     using (var stream = new MemoryStream()) {
         using (var encoder = new BinaryEncoder(stream, context)) {
             encodeable.Encode(encoder);
         }
         return(stream.ToArray());
     }
 }
 /// <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, IServiceMessageContext context,
                               bool noRelativeUriAllowed = false)
 {
     if (NodeId.IsNull(nodeId))
     {
         return(null);
     }
     return(nodeId.ToExpandedNodeId(context?.NamespaceUris).AsString(context,
                                                                     noRelativeUriAllowed));
 }
 /// <summary>
 /// Convert a relative path to path strings
 /// </summary>
 /// <param name="path"></param>
 /// <param name="context"></param>
 /// <returns></returns>
 public static string[] AsString(this RelativePath path,
                                 IServiceMessageContext context)
 {
     if (path == null)
     {
         return(null);
     }
     return(path.Elements
            .Select(p => FormatRelativePathElement(p, context))
            .ToArray());
 }
 /// <summary>
 /// Convert service model to role permission type
 /// </summary>
 /// <param name="model"></param>
 /// <param name="context"></param>
 /// <returns></returns>
 public static RolePermissionType ToStackModel(this RolePermissionModel model,
                                               IServiceMessageContext context)
 {
     if (model == null)
     {
         return(null);
     }
     return(new RolePermissionType {
         RoleId = model.RoleId.ToNodeId(context),
         Permissions = (uint)model.Permissions.ToStackType()
     });
 }
 /// <summary>
 /// Convert to system context
 /// </summary>
 /// <param name="context"></param>
 public static ISystemContext ToSystemContext(this IServiceMessageContext context)
 {
     if (context == null)
     {
         return(null);
     }
     return(new SystemContext {
         EncodeableFactory = context.Factory,
         NamespaceUris = context.NamespaceUris,
         ServerUris = context.ServerUris
     });
 }
 /// <summary>
 /// Convert role permission type to service model
 /// </summary>
 /// <param name="type"></param>
 /// <param name="context"></param>
 /// <returns></returns>
 public static RolePermissionModel ToServiceModel(this RolePermissionType type,
                                                  IServiceMessageContext context)
 {
     if (type == null)
     {
         return(null);
     }
     return(new RolePermissionModel {
         RoleId = type.RoleId.AsString(context),
         Permissions = ((PermissionType)type.Permissions).ToServiceType()
     });
 }
Exemple #24
0
        /// <summary>
        /// Convert encodeable to xml
        /// </summary>
        /// <param name="encodeable"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public static XmlElement AsXmlElement(this IEncodeable encodeable,
                                              IServiceMessageContext context)
        {
#pragma warning disable IDE0067 // Dispose objects before losing scope
            var encoder = new XmlEncoder(context);
#pragma warning restore IDE0067 // Dispose objects before losing scope
            encoder.WriteExtensionObjectBody(encodeable);
            var document = new XmlDocument {
                InnerXml = encoder.Close()
            };
            return(document.DocumentElement);
        }
Exemple #25
0
        /// <summary>
        /// Start the UdpDiscovery process
        /// </summary>
        /// <param name="messageContext">The <see cref="IServiceMessageContext"/> object that should be used in encode/decode messages</param>
        /// <returns></returns>
        public virtual async Task StartAsync(IServiceMessageContext messageContext)
        {
            await Task.Run(() => {
                lock (m_lock)
                {
                    MessageContext = messageContext;

                    // initialize Discovery channels
                    m_discoveryUdpClients = UdpClientCreator.GetUdpClients(UsedInContext.Discovery, DiscoveryNetworkInterfaceName, DiscoveryNetworkAddressEndPoint);
                }
            }).ConfigureAwait(false);
        }
 /// <summary>
 /// Convert to path object
 /// </summary>
 /// <param name="path"></param>
 /// <param name="context"></param>
 /// <returns></returns>
 public static RelativePath ToRelativePath(this string[] path,
                                           IServiceMessageContext context)
 {
     if (path == null)
     {
         return(new RelativePath());
     }
     return(new RelativePath {
         Elements = new RelativePathElementCollection(path
                                                      .Where(p => !string.IsNullOrEmpty(p))
                                                      .Select(p => ParsePathElement(p, context)))
     });
 }
 /// <summary>
 /// Encodes the object in XML or Binary
 /// </summary>
 public static ExtensionObject Encode(IServiceMessageContext context, IEncodeable encodeable, bool useXml)
 {
     if (useXml)
     {
         XmlElement body = EncodeableObject.EncodeXml(encodeable, context);
         return(new ExtensionObject(encodeable.XmlEncodingId, body));
     }
     else
     {
         byte[] body = EncodeableObject.EncodeBinary(encodeable, context);
         return(new ExtensionObject(encodeable.BinaryEncodingId, body));
     }
 }
        /// <summary>
        /// Decodes the message
        /// </summary>
        /// <param name="context"></param>
        /// <param name="message"></param>
        /// <param name="dataSetReaders"></param>
        public override void Decode(IServiceMessageContext context, byte[] message, IList <DataSetReaderDataType> dataSetReaders)
        {
            if (dataSetReaders == null || dataSetReaders.Count == 0)
            {
                return;
            }

            using (BinaryDecoder decoder = new BinaryDecoder(message, context))
            {
                //decode bytes using dataset reader information
                DecodeSubscribedDataSets(decoder, dataSetReaders);
            }
        }
Exemple #29
0
        /// <summary>
        /// Convert buffer to encodeable
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="typeId"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public static IEncodeable ToEncodeable(this byte[] buffer,
                                               ExpandedNodeId typeId, IServiceMessageContext context)
        {
            var systemType = TypeInfo.GetSystemType(typeId.ToNodeId(context.NamespaceUris),
                                                    context.Factory);

            if (systemType == null)
            {
                return(null);
            }
            using (var decoder = new BinaryDecoder(buffer, context)) {
                return(decoder.ReadEncodeable(null, systemType));
            }
        }
 /// <summary>
 /// Update message context from context
 /// </summary>
 /// <param name="context"></param>
 /// <param name="update"></param>
 public static void UpdateFromContext(this IServiceMessageContext context,
                                      IServiceMessageContext update)
 {
     if (context is ServiceMessageContext serviceMessageContext)
     {
         serviceMessageContext.Factory             = update.Factory;
         serviceMessageContext.NamespaceUris       = update.NamespaceUris;
         serviceMessageContext.ServerUris          = update.ServerUris;
         serviceMessageContext.MaxStringLength     = update.MaxStringLength;
         serviceMessageContext.MaxArrayLength      = update.MaxArrayLength;
         serviceMessageContext.MaxByteStringLength = update.MaxByteStringLength;
         serviceMessageContext.MaxMessageSize      = update.MaxMessageSize;
     }
 }