/// <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, ServiceMessageContext messageContext) { // create a UA binary channel. ITransportChannel channel = CreateUaBinaryChannel( configuration, description, endpointConfiguration, clientCertificate, messageContext); // create a WCF XML 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> /// Initializes the object with an XML element to parse. /// </summary> public XmlDecoder(XmlElement element, ServiceMessageContext context) { if (context == null) throw new ArgumentNullException("context"); Initialize(); m_reader = XmlReader.Create(new StringReader(element.OuterXml)); m_context = context; }
/// <summary> /// Initializes the object with a XML reader. /// </summary> public XmlDecoder(System.Type systemType, XmlReader reader, ServiceMessageContext context) { Initialize(); m_reader = reader; m_context = context; string ns = null; string name = null; if (systemType != null) { XmlQualifiedName typeName = EncodeableFactory.GetXmlName(systemType); ns = typeName.Namespace; name = typeName.Name; } if (ns == null) { m_reader.MoveToContent(); ns = m_reader.NamespaceURI; name = m_reader.Name; } int index = name.IndexOf(':'); if (index != -1) { name = name.Substring(index + 1); } PushNamespace(ns); BeginField(name, false); }
/// <summary> /// Creates a decoder that reads from a stream. /// </summary> public BinaryDecoder(Stream stream, ServiceMessageContext context) { if (stream == null) throw new ArgumentNullException("stream"); m_istrm = stream; m_reader = new BinaryReader(m_istrm); m_context = context; }
/// <summary> /// Initializes object with default values. /// </summary> public ServerBase() { m_messageContext = new ServiceMessageContext(); m_serverError = new ServiceResult(StatusCodes.BadServerHalted); m_hosts = new List<ServiceHost>(); m_listeners = new List<ITransportListener>(); m_endpoints = null; m_requestQueue = new RequestQueue(this, 10, 100, 1000); }
/// <summary> /// Initializes the object with an XML element to parse. /// </summary> public XmlDecoder(XmlElement element, ServiceMessageContext context) { #if !SILVERLIGHT if (context == null) throw new ArgumentNullException("context"); Initialize(); m_reader = new XmlNodeReader(element); m_context = context; #endif }
public JsonDecoder(System.Type systemType, JsonTextReader reader, ServiceMessageContext context) { Initialize(); m_context = context; m_reader = reader; m_root = ReadObject(); m_stack = new Stack<object>(); m_stack.Push(m_root); }
public JsonDecoder(string json, ServiceMessageContext context) { if (context == null) throw new ArgumentNullException("context"); Initialize(); m_context = context; m_reader = new JsonTextReader(new StringReader(json)); m_root = ReadObject(); m_stack = new Stack<object>(); m_stack.Push(m_root); }
/// <summary> /// Initializes the object with default values. /// </summary> public XmlEncoder(ServiceMessageContext context) { Initialize(); m_destination = new StringBuilder(); m_context = context; XmlWriterSettings settings = new XmlWriterSettings(); settings.CheckCharacters = false; m_writer = XmlWriter.Create(m_destination, settings); }
/// <summary> /// Creates an empty factory. /// </summary> /// <param name="messageContext">The message context.</param> public BindingFactory(ServiceMessageContext messageContext) { m_bindings = new Dictionary<string, Type>(); AddDefaultBindings(m_bindings); m_namespaceUris = ServiceMessageContext.GlobalContext.NamespaceUris; m_factory = ServiceMessageContext.GlobalContext.Factory; if (messageContext != null) { m_namespaceUris = messageContext.NamespaceUris; m_factory = messageContext.Factory; } }
/// <summary> /// Initializes the object with default values. /// </summary> public JsonEncoder(ServiceMessageContext context, bool useReversibleEncoding, StreamWriter writer = null) { Initialize(); m_context = context; UseReversibleEncoding = useReversibleEncoding; if (writer == null) { m_destination = new MemoryStream(); m_writer = new StreamWriter(m_destination, new UTF8Encoding(false)); } m_writer.Write("{"); }
/// <summary> /// Creates a new transport channel that supports the ISessionChannel 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, ServiceMessageContext messageContext) { // create a UA binary channel. ITransportChannel channel = CreateUaBinaryChannel( configuration, description, endpointConfiguration, clientCertificate, messageContext); return channel; }
/// <summary> /// Initializes the object with a system type to encode and a XML writer. /// </summary> public XmlEncoder(XmlQualifiedName root, XmlWriter writer, ServiceMessageContext context) { Initialize(); if (writer == null) { m_destination = new StringBuilder(); m_writer = XmlWriter.Create(m_destination); } else { m_destination = null; m_writer = writer; } Initialize(root.Name, root.Namespace); m_context = context; }
/// <summary> /// Creates a new transport channel that supports the ISessionChannel 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="clientCertificateChain">The client certificate chain.</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, X509Certificate2Collection clientCertificateChain, ServiceMessageContext messageContext) { // create a UA binary channel. ITransportChannel channel = CreateUaBinaryChannel( configuration, description, endpointConfiguration, clientCertificate, clientCertificateChain, messageContext); return(channel); }
/// <summary> /// Dispatches an incoming binary encoded request. /// </summary> /// <param name="request">Request.</param> /// <returns>Invoke service response message.</returns> public virtual InvokeServiceResponseMessage InvokeService(InvokeServiceMessage request) { IServiceRequest decodedRequest = null; IServiceResponse response = null; // create context for request and reply. ServiceMessageContext context = MessageContext; try { // check for null. if (request == null || request.InvokeServiceRequest == null) { throw new ServiceResultException(StatusCodes.BadDecodingError, Utils.Format("Null message cannot be processed.")); } // decoding incoming message. decodedRequest = BinaryDecoder.DecodeMessage(request.InvokeServiceRequest, null, context) as IServiceRequest; // invoke service. response = ProcessRequest(decodedRequest); // encode response. InvokeServiceResponseMessage outgoing = new InvokeServiceResponseMessage(); outgoing.InvokeServiceResponse = BinaryEncoder.EncodeMessage(response, context); return(outgoing); } catch (Exception e) { // create fault. ServiceFault fault = CreateFault(decodedRequest, e); // encode fault response. if (context == null) { context = new ServiceMessageContext(); } InvokeServiceResponseMessage outgoing = new InvokeServiceResponseMessage(); outgoing.InvokeServiceResponse = BinaryEncoder.EncodeMessage(fault, context); return(outgoing); } }
/// <summary> /// Creates the message context from the configuration. /// </summary> /// <returns>A new instance of a ServiceMessageContext object.</returns> public ServiceMessageContext CreateMessageContext(bool clonedFactory = false) { ServiceMessageContext messageContext = new ServiceMessageContext(); if (m_transportQuotas != null) { messageContext.MaxArrayLength = m_transportQuotas.MaxArrayLength; messageContext.MaxByteStringLength = m_transportQuotas.MaxByteStringLength; messageContext.MaxStringLength = m_transportQuotas.MaxStringLength; messageContext.MaxMessageSize = m_transportQuotas.MaxMessageSize; } messageContext.NamespaceUris = new NamespaceTable(); messageContext.ServerUris = new StringTable(); if (clonedFactory) { messageContext.Factory = new EncodeableFactory(EncodeableFactory.GlobalFactory); } return(messageContext); }
/// <summary> /// Writes the collection to a binary file. /// </summary> public void SaveAsBinary(ISystemContext context, Stream ostrm) { ServiceMessageContext messageContext = new ServiceMessageContext(); messageContext.NamespaceUris = context.NamespaceUris; messageContext.ServerUris = context.ServerUris; messageContext.Factory = context.EncodeableFactory; BinaryEncoder encoder = new BinaryEncoder(ostrm, messageContext); encoder.SaveStringTable(context.NamespaceUris); encoder.SaveStringTable(context.ServerUris); encoder.WriteInt32(null, this.Count); for (int ii = 0; ii < this.Count; ii++) { NodeState state = this[ii]; state.SaveAsBinary(context, encoder); } }
/// <summary> /// Creates a new transport channel that supports the IDiscoveryChannel service contract. /// </summary> /// <param name="discoveryUrl">The discovery URL.</param> /// <param name="bindingFactory">The binding factory.</param> /// <param name="endpointConfiguration">The endpoint configuration.</param> /// <param name="messageContext">The message context.</param> /// <returns></returns> public static ITransportChannel Create( Uri discoveryUrl, BindingFactory bindingFactory, EndpointConfiguration endpointConfiguration, ServiceMessageContext messageContext) { // create a dummy description. EndpointDescription endpoint = new EndpointDescription(); endpoint.EndpointUrl = discoveryUrl.ToString(); endpoint.SecurityMode = MessageSecurityMode.None; endpoint.SecurityPolicyUri = SecurityPolicies.None; endpoint.Server.ApplicationUri = endpoint.EndpointUrl; endpoint.Server.ApplicationType = ApplicationType.DiscoveryServer; ITransportChannel channel = CreateUaBinaryChannel( null, endpoint, endpointConfiguration, (System.Security.Cryptography.X509Certificates.X509Certificate2)null, messageContext); // create a WCF XML channel. if (channel == null) { Binding binding = bindingFactory.Create(discoveryUrl.Scheme, endpointConfiguration); DiscoveryChannel wcfXmlChannel = new DiscoveryChannel(); wcfXmlChannel.Initialize( endpoint, endpointConfiguration, binding, null); channel = wcfXmlChannel; } return(channel); }
/// <summary> /// Creates a new transport channel that supports the ISessionChannel 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, ServiceMessageContext messageContext) { // create a UA binary channel. ITransportChannel channel = CreateUaBinaryChannel( configuration, description, endpointConfiguration, clientCertificate, messageContext); #if !SILVERLIGHT // create a WCF XML channel. if (channel == null) { Uri endpointUrl = new Uri(description.EndpointUrl); BindingFactory bindingFactory = BindingFactory.Create(configuration, messageContext); Binding binding = bindingFactory.Create(endpointUrl.Scheme, description, endpointConfiguration); SessionChannel wcfXmlChannel = new SessionChannel(); wcfXmlChannel.Initialize( configuration, description, endpointConfiguration, binding, clientCertificate, null); channel = wcfXmlChannel; } #endif return channel; }
/// <summary> /// Creates a new transport channel that supports the ISessionChannel 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, ServiceMessageContext messageContext) { // create a UA binary channel. ITransportChannel channel = CreateUaBinaryChannel( configuration, description, endpointConfiguration, clientCertificate, messageContext); #if !SILVERLIGHT // create a WCF XML channel. if (channel == null) { Uri endpointUrl = new Uri(description.EndpointUrl); BindingFactory bindingFactory = BindingFactory.Create(configuration, messageContext); Binding binding = bindingFactory.Create(endpointUrl.Scheme, description, endpointConfiguration); SessionChannel wcfXmlChannel = new SessionChannel(); wcfXmlChannel.Initialize( configuration, description, endpointConfiguration, binding, clientCertificate, null); channel = wcfXmlChannel; } #endif return(channel); }
/// <summary> /// Creates a new transport channel that supports the ISessionChannel service contract. /// </summary> /// <param name="discoveryUrl">The discovery url.</param> /// <param name="endpointConfiguration">The configuration to use with the endpoint.</param> /// <param name="messageContext">The message context to use when serializing the messages.</param> /// <returns></returns> public static ITransportChannel Create( Uri discoveryUrl, EndpointConfiguration endpointConfiguration, ServiceMessageContext messageContext) { // create a dummy description. EndpointDescription endpoint = new EndpointDescription(); endpoint.EndpointUrl = discoveryUrl.ToString(); endpoint.SecurityMode = MessageSecurityMode.None; endpoint.SecurityPolicyUri = SecurityPolicies.None; endpoint.Server.ApplicationUri = endpoint.EndpointUrl; endpoint.Server.ApplicationType = ApplicationType.DiscoveryServer; ITransportChannel channel = CreateUaBinaryChannel( null, endpoint, endpointConfiguration, (System.Security.Cryptography.X509Certificates.X509Certificate2)null, messageContext); return(channel); }
/// <summary> /// Provides the ability to change run-time property values or insert custom extension objects such as error handlers, message or parameter interceptors, security extensions, and other custom extension objects. /// </summary> /// <param name="serviceDescription">The service description.</param> /// <param name="serviceHostBase">The host that is currently being built.</param> public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { ServiceMessageContext contextToUse = null; Opc.Ua.ServiceHost serviceHost = serviceHostBase as Opc.Ua.ServiceHost; if (serviceHost == null) { contextToUse = ServiceMessageContext.GlobalContext; } else { contextToUse = serviceHost.Server.MessageContext; } foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers) { foreach (EndpointDispatcher endpoint in dispatcher.Endpoints) { endpoint.DispatchRuntime.MessageInspectors.Add(new ServiceMessageContextMessageInspector(contextToUse)); } } }
/// <summary> /// Writes the schema information to a static XML export file. /// </summary> public void SaveAsXml(ISystemContext context, Stream ostrm, bool keepStreamOpen) { XmlWriterSettings settings = new XmlWriterSettings(); settings.Encoding = Encoding.UTF8; settings.CloseOutput = !keepStreamOpen; settings.ConformanceLevel = ConformanceLevel.Document; settings.Indent = true; ServiceMessageContext messageContext = new ServiceMessageContext(); messageContext.NamespaceUris = context.NamespaceUris; messageContext.ServerUris = context.ServerUris; messageContext.Factory = context.EncodeableFactory; using (XmlWriter writer = XmlWriter.Create(ostrm, settings)) { XmlQualifiedName root = new XmlQualifiedName("ListOfNodeState", Namespaces.OpcUaXsd); XmlEncoder encoder = new XmlEncoder(root, writer, messageContext); encoder.SaveStringTable("NamespaceUris", "NamespaceUri", context.NamespaceUris); encoder.SaveStringTable("ServerUris", "ServerUri", context.ServerUris); for (int ii = 0; ii < this.Count; ii++) { NodeState state = this[ii]; if (state != null) { state.SaveAsXml(context, encoder); } } encoder.Close(); } }
/// <summary> /// Initializes the object with the message context to use. /// </summary> /// <param name="messageContext">The message context.</param> public ServiceMessageContextMessageInspector(ServiceMessageContext messageContext) { m_messageContext = messageContext; }
/// <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, ServiceMessageContext messageContext) { // check if the server if configured to use the ANSI C stack. bool useUaTcp = description.EndpointUrl.StartsWith(Utils.UriSchemeOpcTcp); bool useHttps = description.EndpointUrl.StartsWith(Utils.UriSchemeHttps); bool useAnsiCStack = false; switch (description.TransportProfileUri) { case Profiles.UaTcpTransport: { useUaTcp = true; if (configuration != null) { useAnsiCStack = configuration.UseNativeStack; } break; } case Profiles.HttpsXmlTransport: case Profiles.HttpsBinaryTransport: case Profiles.HttpsXmlOrBinaryTransport: { useHttps = true; break; } } // note: WCF channels are not supported if (!useUaTcp && !useHttps) { throw ServiceResultException.Create( StatusCodes.BadServiceUnsupported, "Unsupported transport profile\r\n"); } // initialize the channel which will be created with the server. ITransportChannel channel = null; // create a UA-TCP channel. TransportChannelSettings settings = new TransportChannelSettings(); settings.Description = description; settings.Configuration = endpointConfiguration; settings.ClientCertificate = clientCertificate; if (description.ServerCertificate != null && description.ServerCertificate.Length > 0) { settings.ServerCertificate = Utils.ParseCertificateBlob(description.ServerCertificate); } if (configuration != null) { settings.CertificateValidator = configuration.CertificateValidator.GetChannelValidator(); } settings.NamespaceUris = messageContext.NamespaceUris; settings.Factory = messageContext.Factory; if (useUaTcp) { Type type = null; if (useAnsiCStack) { type = Type.GetType("Opc.Ua.NativeStack.NativeStackChannel,Opc.Ua.NativeStackWrapper"); } if (useAnsiCStack && type != null) { channel = (ITransportChannel)Activator.CreateInstance(type); } else { channel = new Opc.Ua.Bindings.TcpTransportChannel(); } } else if (useHttps) { channel = new Opc.Ua.Bindings.HttpsTransportChannel(); } channel.Initialize(new Uri(description.EndpointUrl), settings); channel.Open(); return(channel); }
/// <summary> /// Creates a binding table from the bindings specified in the application configuration. /// </summary> public static BindingFactory Create(ApplicationConfiguration configuration, ServiceMessageContext context) { if (configuration == null || configuration.TransportConfigurations == null || configuration.TransportConfigurations.Count == 0) { return new BindingFactory(context.NamespaceUris, context.Factory); } BindingFactory table = new BindingFactory(context.NamespaceUris, context.Factory); foreach (TransportConfiguration entry in configuration.TransportConfigurations) { if (entry.TypeName == Utils.UaTcpBindingDefault) { continue; } Type type = Type.GetType(entry.TypeName); if (type == null) { throw ServiceResultException.Create(StatusCodes.BadConfigurationError, "Could not find binding type '{0}'.", entry.TypeName); } table.Add(entry.UriScheme, type); } return table; }
/// <summary> /// Initializes the object with default values. /// </summary> public XmlDecoder(ServiceMessageContext context) { if (context == null) throw new ArgumentNullException("context"); Initialize(); m_context = context; }
/// <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="clientCertificateChain">The client certificate chain.</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, X509Certificate2Collection clientCertificateChain, ServiceMessageContext messageContext) { string uriScheme = new Uri(description.EndpointUrl).Scheme; switch (description.TransportProfileUri) { case Profiles.UaTcpTransport: { uriScheme = Utils.UriSchemeOpcTcp; break; } case Profiles.HttpsBinaryTransport: { uriScheme = Utils.UriSchemeHttps; break; } case Profiles.UaWssTransport: { uriScheme = Utils.UriSchemeOpcWss; break; } } // initialize the channel which will be created with the server. ITransportChannel channel = TransportBindings.Channels.GetChannel(uriScheme); if (channel == null) { throw ServiceResultException.Create( StatusCodes.BadProtocolVersionUnsupported, "Unsupported transport profile for scheme {0}.", uriScheme); } // create a UA-TCP channel. TransportChannelSettings settings = new TransportChannelSettings { Description = description, Configuration = endpointConfiguration, ClientCertificate = clientCertificate, ClientCertificateChain = clientCertificateChain }; if (description.ServerCertificate != null && description.ServerCertificate.Length > 0) { settings.ServerCertificate = Utils.ParseCertificateBlob(description.ServerCertificate); } if (configuration != null) { settings.CertificateValidator = configuration.CertificateValidator.GetChannelValidator(); } settings.NamespaceUris = messageContext.NamespaceUris; settings.Factory = messageContext.Factory; channel.Initialize(new Uri(description.EndpointUrl), settings); channel.Open(); return(channel); }
/// <summary> /// Initializes the object with a system type to encode and a XML writer. /// </summary> public XmlEncoder(System.Type systemType, XmlWriter writer, ServiceMessageContext context) : this(EncodeableFactory.GetXmlName(systemType), writer, context) { }
/// <summary> /// Reads the schema information from a XML document. /// </summary> public void LoadFromBinary(ISystemContext context, Stream istrm, bool updateTables) { ServiceMessageContext messageContext = new ServiceMessageContext(); messageContext.NamespaceUris = context.NamespaceUris; messageContext.ServerUris = context.ServerUris; messageContext.Factory = context.EncodeableFactory; using (BinaryDecoder decoder = new BinaryDecoder(istrm, messageContext)) { // check if a namespace table was provided. NamespaceTable namespaceUris = new NamespaceTable(); if (!decoder.LoadStringTable(namespaceUris)) { namespaceUris = null; } // update namespace table. if (updateTables) { if (namespaceUris != null && context.NamespaceUris != null) { for (int ii = 0; ii < namespaceUris.Count; ii++) { context.NamespaceUris.GetIndexOrAppend(namespaceUris.GetString((uint)ii)); } } } // check if a server uri table was provided. StringTable serverUris = new StringTable(); if (namespaceUris != null && namespaceUris.Count > 1) { serverUris.Append(namespaceUris.GetString(1)); } if (!decoder.LoadStringTable(serverUris)) { serverUris = null; } // update server table. if (updateTables) { if (serverUris != null && context.ServerUris != null) { for (int ii = 0; ii < serverUris.Count; ii++) { context.ServerUris.GetIndexOrAppend(serverUris.GetString((uint)ii)); } } } // setup the mappings to use during decoding. decoder.SetMappingTables(namespaceUris, serverUris); int count = decoder.ReadInt32(null); for (int ii = 0; ii < count; ii++) { NodeState state = NodeState.LoadNode(context, decoder); this.Add(state); } } }
/// <summary> /// Creates a new transport channel that supports the ISessionChannel service contract. /// </summary> /// <param name="discoveryUrl">The discovery url.</param> /// <param name="endpointConfiguration">The configuration to use with the endpoint.</param> /// <param name="messageContext">The message context to use when serializing the messages.</param> /// <returns></returns> public static ITransportChannel Create( Uri discoveryUrl, EndpointConfiguration endpointConfiguration, ServiceMessageContext messageContext) { // create a dummy description. EndpointDescription endpoint = new EndpointDescription(); endpoint.EndpointUrl = discoveryUrl.ToString(); endpoint.SecurityMode = MessageSecurityMode.None; endpoint.SecurityPolicyUri = SecurityPolicies.None; endpoint.Server.ApplicationUri = endpoint.EndpointUrl; endpoint.Server.ApplicationType = ApplicationType.DiscoveryServer; ITransportChannel channel = CreateUaBinaryChannel( null, endpoint, endpointConfiguration, (System.Security.Cryptography.X509Certificates.X509Certificate2)null, messageContext); return channel; }
/// <summary> /// Dispatches an incoming binary encoded request. /// </summary> /// <param name="request">Request.</param> /// <returns>Invoke service response message.</returns> public virtual InvokeServiceResponseMessage InvokeService(InvokeServiceMessage request) { IServiceRequest decodedRequest = null; IServiceResponse response = null; // create context for request and reply. ServiceMessageContext context = MessageContext; try { // check for null. if (request == null || request.InvokeServiceRequest == null) { throw new ServiceResultException(StatusCodes.BadDecodingError, Utils.Format("Null message cannot be processed.")); } // decoding incoming message. decodedRequest = BinaryDecoder.DecodeMessage(request.InvokeServiceRequest, null, context) as IServiceRequest; // invoke service. response = ProcessRequest(decodedRequest); // encode response. InvokeServiceResponseMessage outgoing = new InvokeServiceResponseMessage(); outgoing.InvokeServiceResponse = BinaryEncoder.EncodeMessage(response, context); return outgoing; } catch (Exception e) { // create fault. ServiceFault fault = CreateFault(decodedRequest, e); // encode fault response. if (context == null) { context = new ServiceMessageContext(); } InvokeServiceResponseMessage outgoing = new InvokeServiceResponseMessage(); outgoing.InvokeServiceResponse = BinaryEncoder.EncodeMessage(fault, context); return outgoing; } }
/// <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="clientCertificateChain">The client certificate chain.</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, X509Certificate2Collection clientCertificateChain, ServiceMessageContext messageContext) { bool useUaTcp = description.EndpointUrl.StartsWith(Utils.UriSchemeOpcTcp); bool useHttps = description.EndpointUrl.StartsWith(Utils.UriSchemeHttps); switch (description.TransportProfileUri) { case Profiles.UaTcpTransport: { useUaTcp = true; break; } case Profiles.HttpsBinaryTransport: { useHttps = true; break; } } // note: WCF channels are not supported if (!useUaTcp #if !NO_HTTPS && !useHttps #endif ) { throw ServiceResultException.Create( StatusCodes.BadProtocolVersionUnsupported, "Unsupported transport profile\r\n"); } // initialize the channel which will be created with the server. ITransportChannel channel = null; // create a UA-TCP channel. TransportChannelSettings settings = new TransportChannelSettings(); settings.Description = description; settings.Configuration = endpointConfiguration; settings.ClientCertificate = clientCertificate; settings.ClientCertificateChain = clientCertificateChain; if (description.ServerCertificate != null && description.ServerCertificate.Length > 0) { settings.ServerCertificate = Utils.ParseCertificateBlob(description.ServerCertificate); } if (configuration != null) { settings.CertificateValidator = configuration.CertificateValidator.GetChannelValidator(); } settings.NamespaceUris = messageContext.NamespaceUris; settings.Factory = messageContext.Factory; if (useUaTcp) { if (g_CustomTransportChannel != null) { channel = g_CustomTransportChannel.Create(); } else { channel = new TcpTransportChannel(); } } else if (useHttps) { #if !NO_HTTPS channel = new HttpsTransportChannel(); #endif } channel.Initialize(new Uri(description.EndpointUrl), settings); channel.Open(); return(channel); }
/// <summary> /// Encodes the object in XML. /// </summary> public static XmlElement EncodeXml(IEncodeable encodeable, ServiceMessageContext context) { // create encoder. XmlEncoder encoder = new XmlEncoder(context); // write body. encoder.WriteExtensionObjectBody(encodeable); // create document from encoder. XmlDocument document = new XmlDocument(); document.InnerXml = encoder.Close(); // return root element. return document.DocumentElement; }
/// <summary> /// Encodes the object in binary /// </summary> public static byte[] EncodeBinary(IEncodeable encodeable, ServiceMessageContext context) { BinaryEncoder encoder = new BinaryEncoder(context); encoder.WriteEncodeable(null, encodeable, null); return encoder.CloseAndReturnBuffer(); }
/// <summary> /// Applies the data encoding to the value. /// </summary> public static ServiceResult ApplyDataEncoding(ServiceMessageContext context, QualifiedName dataEncoding, ref object value) { // check if nothing to do. if (QualifiedName.IsNull(dataEncoding) || value == null) { return ServiceResult.Good; } // check for supported encoding type. if (dataEncoding.NamespaceIndex != 0) { return StatusCodes.BadDataEncodingUnsupported; } bool useXml = dataEncoding.Name == DefaultXml; if (!useXml && dataEncoding.Name != DefaultBinary) { return StatusCodes.BadDataEncodingUnsupported; } try { // check for array of encodeables. IList<IEncodeable> encodeables = value as IList<IEncodeable>; if (encodeables == null) { // check for array of extension objects. IList<ExtensionObject> extensions = value as IList<ExtensionObject>; if (extensions != null) { // convert extension objects to encodeables. encodeables = new IEncodeable[extensions.Count]; for (int ii = 0; ii < encodeables.Count; ii++) { if (ExtensionObject.IsNull(extensions[ii])) { encodeables[ii] = null; continue; } IEncodeable element = extensions[ii].Body as IEncodeable; if (element == null) { return StatusCodes.BadTypeMismatch; } encodeables[ii] = element; } } } // apply data encoding to the array. if (encodeables != null) { ExtensionObject[] extensions = new ExtensionObject[encodeables.Count]; for (int ii = 0; ii < extensions.Length; ii++) { extensions[ii] = Encode(context, encodeables[ii], useXml); } value = extensions; return ServiceResult.Good; } // check for scalar value. IEncodeable encodeable = value as IEncodeable; if (encodeable == null) { ExtensionObject extension = value as ExtensionObject; if (extension == null) { return StatusCodes.BadDataEncodingUnsupported; } encodeable = extension.Body as IEncodeable; } if (encodeable == null) { return StatusCodes.BadDataEncodingUnsupported; } // do conversion. value = Encode(context, encodeable, useXml); return ServiceResult.Good; } catch (Exception e) { return ServiceResult.Create(e, StatusCodes.BadTypeMismatch, "Could not convert value to requested format."); } }
/// <summary> /// Creates a decoder that reads from a memory buffer. /// </summary> public BinaryDecoder(byte[] buffer, ServiceMessageContext context) : this(buffer, 0, buffer.Length, context) { }
/// <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, ServiceMessageContext messageContext) { // check if the server if configured to use the ANSI C stack. bool useUaTcp = description.EndpointUrl.StartsWith(Utils.UriSchemeOpcTcp); bool useHttps = description.EndpointUrl.StartsWith(Utils.UriSchemeHttps); #if !SILVERLIGHT bool useAnsiCStack = false; #else useHttps = description.EndpointUrl.StartsWith(Utils.UriSchemeHttp); #endif switch (description.TransportProfileUri) { case Profiles.UaTcpTransport: { useUaTcp = true; #if !SILVERLIGHT if (configuration != null) { useAnsiCStack = configuration.UseNativeStack; } #endif break; } case Profiles.HttpsXmlTransport: case Profiles.HttpsBinaryTransport: case Profiles.HttpsXmlOrBinaryTransport: { useHttps = true; break; } } #if !SILVERLIGHT // check for a WCF channel. if (!useUaTcp && !useHttps) { // binary channels only need the base class. if (endpointConfiguration.UseBinaryEncoding) { Uri endpointUrl = new Uri(description.EndpointUrl); BindingFactory bindingFactory = BindingFactory.Create(configuration, messageContext); Binding binding = bindingFactory.Create(endpointUrl.Scheme, description, endpointConfiguration); WcfChannelBase<IChannelBase> wcfChannel = new WcfChannelBase<IChannelBase>(); // create regular binding. if (configuration != null) { wcfChannel.Initialize( configuration, description, endpointConfiguration, binding, clientCertificate, null); } // create no-security discovery binding. else { wcfChannel.Initialize( description, endpointConfiguration, binding, null); } return wcfChannel; } return null; } #endif // initialize the channel which will be created with the server. ITransportChannel channel = null; // create a UA-TCP channel. TransportChannelSettings settings = new TransportChannelSettings(); settings.Description = description; settings.Configuration = endpointConfiguration; settings.ClientCertificate = clientCertificate; if (description.ServerCertificate != null && description.ServerCertificate.Length > 0) { settings.ServerCertificate = Utils.ParseCertificateBlob(description.ServerCertificate); } #if !SILVERLIGHT if (configuration != null) { settings.CertificateValidator = configuration.CertificateValidator.GetChannelValidator(); } #endif settings.NamespaceUris = messageContext.NamespaceUris; settings.Factory = messageContext.Factory; if (useUaTcp) { #if !SILVERLIGHT Type type = null; if (useAnsiCStack) { type = Type.GetType("Opc.Ua.NativeStack.NativeStackChannel,Opc.Ua.NativeStackWrapper"); } if (useAnsiCStack && type != null) { channel = (ITransportChannel)Activator.CreateInstance(type); } else { channel = new Opc.Ua.Bindings.TcpTransportChannel(); } #endif } else if (useHttps) { channel = new Opc.Ua.Bindings.HttpsTransportChannel(); } channel.Initialize(new Uri(description.EndpointUrl), settings); channel.Open(); return channel; }
/// <summary> /// Reads the schema information from a XML document. /// </summary> public void LoadFromXml(ISystemContext context, Stream istrm, bool updateTables) { ServiceMessageContext messageContext = new ServiceMessageContext(); messageContext.NamespaceUris = context.NamespaceUris; messageContext.ServerUris = context.ServerUris; messageContext.Factory = context.EncodeableFactory; using (XmlReader reader = XmlReader.Create(istrm)) { XmlQualifiedName root = new XmlQualifiedName("ListOfNodeState", Namespaces.OpcUaXsd); XmlDecoder decoder = new XmlDecoder(null, reader, messageContext); NamespaceTable namespaceUris = new NamespaceTable(); if (!decoder.LoadStringTable("NamespaceUris", "NamespaceUri", namespaceUris)) { namespaceUris = null; } // update namespace table. if (updateTables) { if (namespaceUris != null && context.NamespaceUris != null) { for (int ii = 0; ii < namespaceUris.Count; ii++) { context.NamespaceUris.GetIndexOrAppend(namespaceUris.GetString((uint)ii)); } } } StringTable serverUris = new StringTable(); if (!decoder.LoadStringTable("ServerUris", "ServerUri", context.ServerUris)) { serverUris = null; } // update server table. if (updateTables) { if (serverUris != null && context.ServerUris != null) { for (int ii = 0; ii < serverUris.Count; ii++) { context.ServerUris.GetIndexOrAppend(serverUris.GetString((uint)ii)); } } } // set mapping. decoder.SetMappingTables(namespaceUris, serverUris); decoder.PushNamespace(Namespaces.OpcUaXsd); NodeState state = NodeState.LoadNode(context, decoder); while (state != null) { this.Add(state); state = NodeState.LoadNode(context, decoder); } decoder.Close(); } }
/// <summary> /// Acknowledges the specified context. /// </summary> /// <param name="context">The context.</param> /// <param name="eventId">The event id.</param> /// <param name="comment">The comment.</param> /// <returns></returns> public uint Acknowledge( ServerSystemContext context, byte[] eventId, LocalizedText comment) { // get the user name from the context. string userName = String.Empty; if (context.UserIdentity != null) { userName = context.UserIdentity.DisplayName; } // get the comment. string commentText = String.Empty; if (comment != null) { commentText = comment.Text; } System.Runtime.InteropServices.ComTypes.FILETIME ftActiveTime; // unpack the event id. ServiceMessageContext messageContext = new ServiceMessageContext(); messageContext.NamespaceUris = context.NamespaceUris; messageContext.ServerUris = context.ServerUris; messageContext.Factory = context.EncodeableFactory; BinaryDecoder decoder = new BinaryDecoder(eventId, messageContext); string source = decoder.ReadString(null); string conditionName = decoder.ReadString(null); ftActiveTime.dwHighDateTime = decoder.ReadInt32(null); ftActiveTime.dwLowDateTime = decoder.ReadInt32(null); int cookie = decoder.ReadInt32(null); decoder.Close(); string methodName = "IOPCEventServer.AckCondition"; IntPtr pErrors = IntPtr.Zero; try { IOPCEventServer server = BeginComCall<IOPCEventServer>(methodName, true); server.AckCondition( 1, userName, commentText, new string[] { source }, new string[] { conditionName }, new System.Runtime.InteropServices.ComTypes.FILETIME[] { ftActiveTime }, new int[] { cookie }, out pErrors); } catch (Exception e) { ComCallError(methodName, e); return StatusCodes.BadUnexpectedError; } finally { EndComCall(methodName); } // unmarshal results. int[] errors = ComUtils.GetInt32s(ref pErrors, 1, true); if (errors[0] == ResultIds.S_ALREADYACKED) { return StatusCodes.BadConditionBranchAlreadyAcked; } else if (errors[0] < 0) { return StatusCodes.BadEventIdUnknown; } return StatusCodes.Good; }
/// <summary> /// Decodes a message from a buffer. /// </summary> public static IEncodeable DecodeMessage(byte[] buffer, System.Type expectedType, ServiceMessageContext context) { if (buffer == null) throw new ArgumentNullException("buffer"); if (context == null) throw new ArgumentNullException("context"); BinaryDecoder decoder = new BinaryDecoder(buffer, context); try { return decoder.DecodeMessage(expectedType); } finally { decoder.Close(); } }
/// <summary> /// Creates a decoder that reads from a memory buffer. /// </summary> public BinaryDecoder(byte[] buffer, int start, int count, ServiceMessageContext context) { m_istrm = new MemoryStream(buffer, start, count, false); m_reader = new BinaryReader(m_istrm); m_context = context; }
/// <summary> /// Applies the data encoding to the value. /// </summary> public static ServiceResult ApplyDataEncoding(ServiceMessageContext context, QualifiedName dataEncoding, ref object value) { // check if nothing to do. if (QualifiedName.IsNull(dataEncoding) || value == null) { return(ServiceResult.Good); } // check for supported encoding type. if (dataEncoding.NamespaceIndex != 0) { return(StatusCodes.BadDataEncodingUnsupported); } bool useXml = dataEncoding.Name == DefaultXml; if (!useXml && dataEncoding.Name != DefaultBinary) { return(StatusCodes.BadDataEncodingUnsupported); } try { // check for array of encodeables. IList <IEncodeable> encodeables = value as IList <IEncodeable>; if (encodeables == null) { // check for array of extension objects. IList <ExtensionObject> extensions = value as IList <ExtensionObject>; if (extensions != null) { // convert extension objects to encodeables. encodeables = new IEncodeable[extensions.Count]; for (int ii = 0; ii < encodeables.Count; ii++) { if (ExtensionObject.IsNull(extensions[ii])) { encodeables[ii] = null; continue; } IEncodeable element = extensions[ii].Body as IEncodeable; if (element == null) { return(StatusCodes.BadTypeMismatch); } encodeables[ii] = element; } } } // apply data encoding to the array. if (encodeables != null) { ExtensionObject[] extensions = new ExtensionObject[encodeables.Count]; for (int ii = 0; ii < extensions.Length; ii++) { extensions[ii] = Encode(context, encodeables[ii], useXml); } value = extensions; return(ServiceResult.Good); } // check for scalar value. IEncodeable encodeable = value as IEncodeable; if (encodeable == null) { ExtensionObject extension = value as ExtensionObject; if (extension == null) { return(StatusCodes.BadDataEncodingUnsupported); } encodeable = extension.Body as IEncodeable; } if (encodeable == null) { return(StatusCodes.BadDataEncodingUnsupported); } // do conversion. value = Encode(context, encodeable, useXml); return(ServiceResult.Good); } catch (Exception e) { return(ServiceResult.Create(e, StatusCodes.BadTypeMismatch, "Could not convert value to requested format.")); } }
/// <summary> /// Creates an decoder to restore Variant values. /// </summary> private XmlDecoder CreateDecoder(ISystemContext context, XmlElement source) { ServiceMessageContext messageContext = new ServiceMessageContext(); messageContext.NamespaceUris = context.NamespaceUris; messageContext.ServerUris = context.ServerUris; messageContext.Factory = context.EncodeableFactory; XmlDecoder decoder = new XmlDecoder(source, messageContext); NamespaceTable namespaceUris = new NamespaceTable(); if (NamespaceUris != null) { for (int ii = 0; ii < NamespaceUris.Length; ii++) { namespaceUris.Append(NamespaceUris[ii]); } } StringTable serverUris = new StringTable(); if (ServerUris != null) { serverUris.Append(context.ServerUris.GetString(0)); for (int ii = 0; ii < ServerUris.Length; ii++) { serverUris.Append(ServerUris[ii]); } } decoder.SetMappingTables(namespaceUris, serverUris); return decoder; }
/// <summary> /// Initializes the object with the message context to use. /// </summary> public MessageContextExtension(ServiceMessageContext messageContext) { m_messageContext = messageContext; }
/// <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, ServiceMessageContext messageContext) { // check if the server if configured to use the ANSI C stack. bool useUaTcp = description.EndpointUrl.StartsWith(Utils.UriSchemeOpcTcp); bool useHttps = description.EndpointUrl.StartsWith(Utils.UriSchemeHttps); bool useAnsiCStack = false; switch (description.TransportProfileUri) { case Profiles.UaTcpTransport: { useUaTcp = true; if (configuration != null) { useAnsiCStack = configuration.UseNativeStack; } break; } case Profiles.HttpsXmlTransport: case Profiles.HttpsBinaryTransport: case Profiles.HttpsXmlOrBinaryTransport: { useHttps = true; break; } } // note: WCF channels are not supported if (!useUaTcp && !useHttps) { throw ServiceResultException.Create( StatusCodes.BadServiceUnsupported, "Unsupported transport profile\r\n"); } // initialize the channel which will be created with the server. ITransportChannel channel = null; // create a UA-TCP channel. TransportChannelSettings settings = new TransportChannelSettings(); settings.Description = description; settings.Configuration = endpointConfiguration; settings.ClientCertificate = clientCertificate; if (description.ServerCertificate != null && description.ServerCertificate.Length > 0) { settings.ServerCertificate = Utils.ParseCertificateBlob(description.ServerCertificate); } if (configuration != null) { settings.CertificateValidator = configuration.CertificateValidator.GetChannelValidator(); } settings.NamespaceUris = messageContext.NamespaceUris; settings.Factory = messageContext.Factory; if (useUaTcp) { Type type = null; if (useAnsiCStack) { type = Type.GetType("Opc.Ua.NativeStack.NativeStackChannel,Opc.Ua.NativeStackWrapper"); } if (useAnsiCStack && type != null) { channel = (ITransportChannel)Activator.CreateInstance(type); } else { channel = new Opc.Ua.Bindings.TcpTransportChannel(); } } else if (useHttps) { channel = new Opc.Ua.Bindings.HttpsTransportChannel(); } channel.Initialize(new Uri(description.EndpointUrl), settings); channel.Open(); return channel; }