diff --git a/litjson/litjson/bin/Release/4.7.1/litjson.dll b/litjson/litjson/bin/Release/4.7.1/litjson.dll index 7697337..dc3da15 100644 Binary files a/litjson/litjson/bin/Release/4.7.1/litjson.dll and b/litjson/litjson/bin/Release/4.7.1/litjson.dll differ diff --git a/mqtt/M2Mqtt/MqttClient.cs b/mqtt/M2Mqtt/MqttClient.cs index e5a2415..6daf7a2 100644 --- a/mqtt/M2Mqtt/MqttClient.cs +++ b/mqtt/M2Mqtt/MqttClient.cs @@ -51,7 +51,7 @@ using System.Collections; // (it's ambiguos with uPLibrary.Networking.M2Mqtt.Utility.Trace) using MqttUtility = uPLibrary.Networking.M2Mqtt.Utility; using System.IO; -using System.Net.Security; +//using System.Net.Security; namespace uPLibrary.Networking.M2Mqtt { diff --git a/mqtt/M2Mqtt/Net/MqttNetworkChannel.cs b/mqtt/M2Mqtt/Net/MqttNetworkChannel.cs index 445bcc6..c98879a 100644 --- a/mqtt/M2Mqtt/Net/MqttNetworkChannel.cs +++ b/mqtt/M2Mqtt/Net/MqttNetworkChannel.cs @@ -1,472 +1,472 @@ -/* -Copyright (c) 2013, 2014 Paolo Patierno - -All rights reserved. This program and the accompanying materials -are made available under the terms of the Eclipse Public License v1.0 -and Eclipse Distribution License v1.0 which accompany this distribution. - -The Eclipse Public License is available at - http://www.eclipse.org/legal/epl-v10.html -and the Eclipse Distribution License is available at - http://www.eclipse.org/org/documents/edl-v10.php. - -Contributors: - Paolo Patierno - initial API and implementation and/or initial documentation -*/ - -#if SSL -#if (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3) -using Microsoft.SPOT.Net.Security; -#else -using System.Net.Security; -using System.Security.Authentication; -#endif -#endif -using System.Net.Sockets; -using System.Net; -using System.Security.Cryptography.X509Certificates; -using System; -using System.Security.Authentication; -using System.Net.Security; +/* +Copyright (c) 2013, 2014 Paolo Patierno -namespace uPLibrary.Networking.M2Mqtt -{ - /// - /// Channel to communicate over the network - /// - public class MqttNetworkChannel : IMqttNetworkChannel - { -#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK) - private readonly RemoteCertificateValidationCallback userCertificateValidationCallback; - private readonly LocalCertificateSelectionCallback userCertificateSelectionCallback; -#endif - // remote host information - private string remoteHostName; - private IPAddress remoteIpAddress; - private int remotePort; - - // socket for communication - private Socket socket; - // using SSL - private bool secure; - - // CA certificate (on client) - private X509Certificate caCert; - // Server certificate (on broker) - private X509Certificate serverCert; - // client certificate (on client) - private X509Certificate clientCert; - - // SSL/TLS protocol version - private MqttSslProtocols sslProtocol; - - /// - /// Remote host name - /// - public string RemoteHostName { get { return this.remoteHostName; } } - - /// - /// Remote IP address - /// - public IPAddress RemoteIpAddress { get { return this.remoteIpAddress; } } - - /// - /// Remote port - /// - public int RemotePort { get { return this.remotePort; } } - -#if SSL - // SSL stream - private SslStream sslStream; -#if (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3) - private NetworkStream netStream; -#endif -#endif - - /// - /// Data available on the channel - /// - public bool DataAvailable - { - get - { -#if SSL -#if (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3) - if (secure) - return this.sslStream.DataAvailable; - else - return (this.socket.Available > 0); -#else - if (secure) - return this.netStream.DataAvailable; - else - return (this.socket.Available > 0); -#endif -#else - return (this.socket.Available > 0); -#endif - } - } - - /// - /// Constructor - /// - /// Socket opened with the client - public MqttNetworkChannel(Socket socket) -#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK) - : this(socket, false, null, MqttSslProtocols.None, null, null) -#else - : this(socket, false, null, MqttSslProtocols.None) -#endif - { - - } - - /// - /// Constructor - /// - /// Socket opened with the client - /// Secure connection (SSL/TLS) - /// Server X509 certificate for secure connection - /// SSL/TLS protocol version -#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK) - /// A RemoteCertificateValidationCallback delegate responsible for validating the certificate supplied by the remote party - /// A LocalCertificateSelectionCallback delegate responsible for selecting the certificate used for authentication - public MqttNetworkChannel(Socket socket, bool secure, X509Certificate serverCert, MqttSslProtocols sslProtocol, - RemoteCertificateValidationCallback userCertificateValidationCallback, - LocalCertificateSelectionCallback userCertificateSelectionCallback) -#else - public MqttNetworkChannel(Socket socket, bool secure, X509Certificate serverCert, MqttSslProtocols sslProtocol) -#endif - { - this.socket = socket; - this.secure = secure; - this.serverCert = serverCert; - this.sslProtocol = sslProtocol; -#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK) - this.userCertificateValidationCallback = userCertificateValidationCallback; - this.userCertificateSelectionCallback = userCertificateSelectionCallback; -#endif - } - - /// - /// Constructor - /// - /// Remote Host name - /// Remote port - public MqttNetworkChannel(string remoteHostName, int remotePort) -#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK) - : this(remoteHostName, remotePort, false, null, null, MqttSslProtocols.None, null, null) -#else - : this(remoteHostName, remotePort, false, null, null, MqttSslProtocols.None) -#endif - { - } - - /// - /// Constructor - /// - /// Remote Host name - /// Remote port - /// Using SSL - /// CA certificate - /// Client certificate - /// SSL/TLS protocol version -#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK) - /// A RemoteCertificateValidationCallback delegate responsible for validating the certificate supplied by the remote party - /// A LocalCertificateSelectionCallback delegate responsible for selecting the certificate used for authentication - public MqttNetworkChannel(string remoteHostName, int remotePort, bool secure, X509Certificate caCert, X509Certificate clientCert, MqttSslProtocols sslProtocol, - RemoteCertificateValidationCallback userCertificateValidationCallback, - LocalCertificateSelectionCallback userCertificateSelectionCallback) -#else - public MqttNetworkChannel(string remoteHostName, int remotePort, bool secure, X509Certificate caCert, X509Certificate clientCert, MqttSslProtocols sslProtocol) -#endif - { - IPAddress remoteIpAddress = null; - try - { - // check if remoteHostName is a valid IP address and get it - remoteIpAddress = IPAddress.Parse(remoteHostName); - } - catch - { - } - - // in this case the parameter remoteHostName isn't a valid IP address - if (remoteIpAddress == null) - { - IPHostEntry hostEntry = Dns.GetHostEntry(remoteHostName); - if ((hostEntry != null) && (hostEntry.AddressList.Length > 0)) - { - // check for the first address not null - // it seems that with .Net Micro Framework, the IPV6 addresses aren't supported and return "null" - int i = 0; - while (hostEntry.AddressList[i] == null) i++; - remoteIpAddress = hostEntry.AddressList[i]; - } - else - { - throw new Exception("No address found for the remote host name"); - } - } - - this.remoteHostName = remoteHostName; - this.remoteIpAddress = remoteIpAddress; - this.remotePort = remotePort; - this.secure = secure; - this.caCert = caCert; - this.clientCert = clientCert; - this.sslProtocol = sslProtocol; -#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK) - this.userCertificateValidationCallback = userCertificateValidationCallback; - this.userCertificateSelectionCallback = userCertificateSelectionCallback; -#endif - } - - /// - /// Connect to remote server - /// - public void Connect() - { - this.socket = new Socket(IPAddressUtility.GetAddressFamily(this.remoteIpAddress), SocketType.Stream, ProtocolType.Tcp); - // try connection to the broker - this.socket.Connect(new IPEndPoint(this.remoteIpAddress, this.remotePort)); - -#if SSL - // secure channel requested - if (secure) - { - // create SSL stream -#if (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3) - this.sslStream = new SslStream(this.socket); -#else - this.netStream = new NetworkStream(this.socket); - this.sslStream = new SslStream(this.netStream, false, this.userCertificateValidationCallback, this.userCertificateSelectionCallback); -#endif - - // server authentication (SSL/TLS handshake) -#if (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3) - this.sslStream.AuthenticateAsClient(this.remoteHostName, - this.clientCert, - new X509Certificate[] { this.caCert }, - SslVerification.CertificateRequired, - MqttSslUtility.ToSslPlatformEnum(this.sslProtocol)); -#else - X509CertificateCollection clientCertificates = null; - // check if there is a client certificate to add to the collection, otherwise it's null (as empty) - if (this.clientCert != null) - clientCertificates = new X509CertificateCollection(new X509Certificate[] { this.clientCert }); - - this.sslStream.AuthenticateAsClient(this.remoteHostName, - clientCertificates, - MqttSslUtility.ToSslPlatformEnum(this.sslProtocol), - false); - -#endif - } -#endif - } - - /// - /// Send data on the network channel - /// - /// Data buffer to send - /// Number of byte sent - public int Send(byte[] buffer) - { -#if SSL - if (this.secure) - { - this.sslStream.Write(buffer, 0, buffer.Length); - this.sslStream.Flush(); - return buffer.Length; - } - else - return this.socket.Send(buffer, 0, buffer.Length, SocketFlags.None); -#else - return this.socket.Send(buffer, 0, buffer.Length, SocketFlags.None); -#endif - } - - /// - /// Receive data from the network - /// - /// Data buffer for receiving data - /// Number of bytes received - public int Receive(byte[] buffer) - { -#if SSL - if (this.secure) - { - // read all data needed (until fill buffer) - int idx = 0, read = 0; - while (idx < buffer.Length) - { - // fixed scenario with socket closed gracefully by peer/broker and - // Read return 0. Avoid infinite loop. - read = this.sslStream.Read(buffer, idx, buffer.Length - idx); - if (read == 0) - return 0; - idx += read; - } - return buffer.Length; - } - else - { - // read all data needed (until fill buffer) - int idx = 0, read = 0; - while (idx < buffer.Length) - { - // fixed scenario with socket closed gracefully by peer/broker and - // Read return 0. Avoid infinite loop. - read = this.socket.Receive(buffer, idx, buffer.Length - idx, SocketFlags.None); - if (read == 0) - return 0; - idx += read; - } - return buffer.Length; - } -#else - // read all data needed (until fill buffer) - int idx = 0, read = 0; - while (idx < buffer.Length) - { - // fixed scenario with socket closed gracefully by peer/broker and - // Read return 0. Avoid infinite loop. - read = this.socket.Receive(buffer, idx, buffer.Length - idx, SocketFlags.None); - if (read == 0) - return 0; - idx += read; - } - return buffer.Length; -#endif - } - - /// - /// Receive data from the network channel with a specified timeout - /// - /// Data buffer for receiving data - /// Timeout on receiving (in milliseconds) - /// Number of bytes received - public int Receive(byte[] buffer, int timeout) - { - // check data availability (timeout is in microseconds) - if (this.socket.Poll(timeout * 1000, SelectMode.SelectRead)) - { - return this.Receive(buffer); - } - else - { - return 0; - } - } - - /// - /// Close the network channel - /// - public void Close() - { -#if SSL - if (this.secure) - { -#if (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3) - this.netStream.Close(); -#endif - this.sslStream.Close(); - } - this.socket.Close(); -#else - this.socket.Close(); -#endif - } - - /// - /// Accept connection from a remote client - /// - public void Accept() - { -#if SSL - // secure channel requested - if (secure) - { -#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3) - - this.netStream = new NetworkStream(this.socket); - this.sslStream = new SslStream(this.netStream, false, this.userCertificateValidationCallback, this.userCertificateSelectionCallback); - - this.sslStream.AuthenticateAsServer(this.serverCert, false, MqttSslUtility.ToSslPlatformEnum(this.sslProtocol), false); -#endif - } - - return; -#else - return; -#endif - } - } - - /// - /// IPAddress Utility class - /// - public static class IPAddressUtility - { - /// - /// Return AddressFamily for the IP address - /// - /// IP address to check - /// Address family - public static AddressFamily GetAddressFamily(IPAddress ipAddress) - { -#if (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3) - return ipAddress.AddressFamily; -#else - return (ipAddress.ToString().IndexOf(':') != -1) ? - AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork; -#endif - } - } - - /// - /// MQTT SSL utility class - /// - public static class MqttSslUtility - { -#if (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3 && !COMPACT_FRAMEWORK) - public static SslProtocols ToSslPlatformEnum(MqttSslProtocols mqttSslProtocol) - { - switch (mqttSslProtocol) - { - case MqttSslProtocols.None: - return SslProtocols.None; - case MqttSslProtocols.SSLv3: - return SslProtocols.Ssl3; - case MqttSslProtocols.TLSv1_0: - return SslProtocols.Tls; - /*case MqttSslProtocols.TLSv1_1: - return SslProtocols.Tls11; - case MqttSslProtocols.TLSv1_2: - return SslProtocols.Tls12;*/ - default: - throw new ArgumentException("SSL/TLS protocol version not supported"); - } - } -#elif (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3) - public static SslProtocols ToSslPlatformEnum(MqttSslProtocols mqttSslProtocol) - { - switch (mqttSslProtocol) - { - case MqttSslProtocols.None: - return SslProtocols.None; - case MqttSslProtocols.SSLv3: - return SslProtocols.SSLv3; - case MqttSslProtocols.TLSv1_0: - return SslProtocols.TLSv1; - case MqttSslProtocols.TLSv1_1: - case MqttSslProtocols.TLSv1_2: - default: - throw new ArgumentException("SSL/TLS protocol version not supported"); - } - } -#endif - } -} +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License v1.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + http://www.eclipse.org/legal/epl-v10.html +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +Contributors: + Paolo Patierno - initial API and implementation and/or initial documentation +*/ + +#if SSL +#if (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3) +using Microsoft.SPOT.Net.Security; +#else +using System.Net.Security; +using System.Security.Authentication; +#endif +#endif +using System.Net.Sockets; +using System.Net; +using System.Security.Cryptography.X509Certificates; +using System; +//using System.Security.Authentication; +//using System.Net.Security; + +namespace uPLibrary.Networking.M2Mqtt +{ + /// + /// Channel to communicate over the network + /// + public class MqttNetworkChannel : IMqttNetworkChannel + { +#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK) + private readonly RemoteCertificateValidationCallback userCertificateValidationCallback; + private readonly LocalCertificateSelectionCallback userCertificateSelectionCallback; +#endif + // remote host information + private string remoteHostName; + private IPAddress remoteIpAddress; + private int remotePort; + + // socket for communication + private Socket socket; + // using SSL + private bool secure; + + // CA certificate (on client) + private X509Certificate caCert; + // Server certificate (on broker) + private X509Certificate serverCert; + // client certificate (on client) + private X509Certificate clientCert; + + // SSL/TLS protocol version + private MqttSslProtocols sslProtocol; + + /// + /// Remote host name + /// + public string RemoteHostName { get { return this.remoteHostName; } } + + /// + /// Remote IP address + /// + public IPAddress RemoteIpAddress { get { return this.remoteIpAddress; } } + + /// + /// Remote port + /// + public int RemotePort { get { return this.remotePort; } } + +#if SSL + // SSL stream + private SslStream sslStream; +#if (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3) + private NetworkStream netStream; +#endif +#endif + + /// + /// Data available on the channel + /// + public bool DataAvailable + { + get + { +#if SSL +#if (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3) + if (secure) + return this.sslStream.DataAvailable; + else + return (this.socket.Available > 0); +#else + if (secure) + return this.netStream.DataAvailable; + else + return (this.socket.Available > 0); +#endif +#else + return (this.socket.Available > 0); +#endif + } + } + + /// + /// Constructor + /// + /// Socket opened with the client + public MqttNetworkChannel(Socket socket) +#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK) + : this(socket, false, null, MqttSslProtocols.None, null, null) +#else + : this(socket, false, null, MqttSslProtocols.None) +#endif + { + + } + + /// + /// Constructor + /// + /// Socket opened with the client + /// Secure connection (SSL/TLS) + /// Server X509 certificate for secure connection + /// SSL/TLS protocol version +#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK) + /// A RemoteCertificateValidationCallback delegate responsible for validating the certificate supplied by the remote party + /// A LocalCertificateSelectionCallback delegate responsible for selecting the certificate used for authentication + public MqttNetworkChannel(Socket socket, bool secure, X509Certificate serverCert, MqttSslProtocols sslProtocol, + RemoteCertificateValidationCallback userCertificateValidationCallback, + LocalCertificateSelectionCallback userCertificateSelectionCallback) +#else + public MqttNetworkChannel(Socket socket, bool secure, X509Certificate serverCert, MqttSslProtocols sslProtocol) +#endif + { + this.socket = socket; + this.secure = secure; + this.serverCert = serverCert; + this.sslProtocol = sslProtocol; +#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK) + this.userCertificateValidationCallback = userCertificateValidationCallback; + this.userCertificateSelectionCallback = userCertificateSelectionCallback; +#endif + } + + /// + /// Constructor + /// + /// Remote Host name + /// Remote port + public MqttNetworkChannel(string remoteHostName, int remotePort) +#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK) + : this(remoteHostName, remotePort, false, null, null, MqttSslProtocols.None, null, null) +#else + : this(remoteHostName, remotePort, false, null, null, MqttSslProtocols.None) +#endif + { + } + + /// + /// Constructor + /// + /// Remote Host name + /// Remote port + /// Using SSL + /// CA certificate + /// Client certificate + /// SSL/TLS protocol version +#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK) + /// A RemoteCertificateValidationCallback delegate responsible for validating the certificate supplied by the remote party + /// A LocalCertificateSelectionCallback delegate responsible for selecting the certificate used for authentication + public MqttNetworkChannel(string remoteHostName, int remotePort, bool secure, X509Certificate caCert, X509Certificate clientCert, MqttSslProtocols sslProtocol, + RemoteCertificateValidationCallback userCertificateValidationCallback, + LocalCertificateSelectionCallback userCertificateSelectionCallback) +#else + public MqttNetworkChannel(string remoteHostName, int remotePort, bool secure, X509Certificate caCert, X509Certificate clientCert, MqttSslProtocols sslProtocol) +#endif + { + IPAddress remoteIpAddress = null; + try + { + // check if remoteHostName is a valid IP address and get it + remoteIpAddress = IPAddress.Parse(remoteHostName); + } + catch + { + } + + // in this case the parameter remoteHostName isn't a valid IP address + if (remoteIpAddress == null) + { + IPHostEntry hostEntry = Dns.GetHostEntry(remoteHostName); + if ((hostEntry != null) && (hostEntry.AddressList.Length > 0)) + { + // check for the first address not null + // it seems that with .Net Micro Framework, the IPV6 addresses aren't supported and return "null" + int i = 0; + while (hostEntry.AddressList[i] == null) i++; + remoteIpAddress = hostEntry.AddressList[i]; + } + else + { + throw new Exception("No address found for the remote host name"); + } + } + + this.remoteHostName = remoteHostName; + this.remoteIpAddress = remoteIpAddress; + this.remotePort = remotePort; + this.secure = secure; + this.caCert = caCert; + this.clientCert = clientCert; + this.sslProtocol = sslProtocol; +#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK) + this.userCertificateValidationCallback = userCertificateValidationCallback; + this.userCertificateSelectionCallback = userCertificateSelectionCallback; +#endif + } + + /// + /// Connect to remote server + /// + public void Connect() + { + this.socket = new Socket(IPAddressUtility.GetAddressFamily(this.remoteIpAddress), SocketType.Stream, ProtocolType.Tcp); + // try connection to the broker + this.socket.Connect(new IPEndPoint(this.remoteIpAddress, this.remotePort)); + +#if SSL + // secure channel requested + if (secure) + { + // create SSL stream +#if (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3) + this.sslStream = new SslStream(this.socket); +#else + this.netStream = new NetworkStream(this.socket); + this.sslStream = new SslStream(this.netStream, false, this.userCertificateValidationCallback, this.userCertificateSelectionCallback); +#endif + + // server authentication (SSL/TLS handshake) +#if (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3) + this.sslStream.AuthenticateAsClient(this.remoteHostName, + this.clientCert, + new X509Certificate[] { this.caCert }, + SslVerification.CertificateRequired, + MqttSslUtility.ToSslPlatformEnum(this.sslProtocol)); +#else + X509CertificateCollection clientCertificates = null; + // check if there is a client certificate to add to the collection, otherwise it's null (as empty) + if (this.clientCert != null) + clientCertificates = new X509CertificateCollection(new X509Certificate[] { this.clientCert }); + + this.sslStream.AuthenticateAsClient(this.remoteHostName, + clientCertificates, + MqttSslUtility.ToSslPlatformEnum(this.sslProtocol), + false); + +#endif + } +#endif + } + + /// + /// Send data on the network channel + /// + /// Data buffer to send + /// Number of byte sent + public int Send(byte[] buffer) + { +#if SSL + if (this.secure) + { + this.sslStream.Write(buffer, 0, buffer.Length); + this.sslStream.Flush(); + return buffer.Length; + } + else + return this.socket.Send(buffer, 0, buffer.Length, SocketFlags.None); +#else + return this.socket.Send(buffer, 0, buffer.Length, SocketFlags.None); +#endif + } + + /// + /// Receive data from the network + /// + /// Data buffer for receiving data + /// Number of bytes received + public int Receive(byte[] buffer) + { +#if SSL + if (this.secure) + { + // read all data needed (until fill buffer) + int idx = 0, read = 0; + while (idx < buffer.Length) + { + // fixed scenario with socket closed gracefully by peer/broker and + // Read return 0. Avoid infinite loop. + read = this.sslStream.Read(buffer, idx, buffer.Length - idx); + if (read == 0) + return 0; + idx += read; + } + return buffer.Length; + } + else + { + // read all data needed (until fill buffer) + int idx = 0, read = 0; + while (idx < buffer.Length) + { + // fixed scenario with socket closed gracefully by peer/broker and + // Read return 0. Avoid infinite loop. + read = this.socket.Receive(buffer, idx, buffer.Length - idx, SocketFlags.None); + if (read == 0) + return 0; + idx += read; + } + return buffer.Length; + } +#else + // read all data needed (until fill buffer) + int idx = 0, read = 0; + while (idx < buffer.Length) + { + // fixed scenario with socket closed gracefully by peer/broker and + // Read return 0. Avoid infinite loop. + read = this.socket.Receive(buffer, idx, buffer.Length - idx, SocketFlags.None); + if (read == 0) + return 0; + idx += read; + } + return buffer.Length; +#endif + } + + /// + /// Receive data from the network channel with a specified timeout + /// + /// Data buffer for receiving data + /// Timeout on receiving (in milliseconds) + /// Number of bytes received + public int Receive(byte[] buffer, int timeout) + { + // check data availability (timeout is in microseconds) + if (this.socket.Poll(timeout * 1000, SelectMode.SelectRead)) + { + return this.Receive(buffer); + } + else + { + return 0; + } + } + + /// + /// Close the network channel + /// + public void Close() + { +#if SSL + if (this.secure) + { +#if (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3) + this.netStream.Close(); +#endif + this.sslStream.Close(); + } + this.socket.Close(); +#else + this.socket.Close(); +#endif + } + + /// + /// Accept connection from a remote client + /// + public void Accept() + { +#if SSL + // secure channel requested + if (secure) + { +#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3) + + this.netStream = new NetworkStream(this.socket); + this.sslStream = new SslStream(this.netStream, false, this.userCertificateValidationCallback, this.userCertificateSelectionCallback); + + this.sslStream.AuthenticateAsServer(this.serverCert, false, MqttSslUtility.ToSslPlatformEnum(this.sslProtocol), false); +#endif + } + + return; +#else + return; +#endif + } + } + + /// + /// IPAddress Utility class + /// + public static class IPAddressUtility + { + /// + /// Return AddressFamily for the IP address + /// + /// IP address to check + /// Address family + public static AddressFamily GetAddressFamily(IPAddress ipAddress) + { +#if (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3) + return ipAddress.AddressFamily; +#else + return (ipAddress.ToString().IndexOf(':') != -1) ? + AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork; +#endif + } + } + + /// + /// MQTT SSL utility class + /// + public static class MqttSslUtility + { +#if (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3 && !COMPACT_FRAMEWORK) + public static SslProtocols ToSslPlatformEnum(MqttSslProtocols mqttSslProtocol) + { + switch (mqttSslProtocol) + { + case MqttSslProtocols.None: + return SslProtocols.None; + case MqttSslProtocols.SSLv3: + return SslProtocols.Ssl3; + case MqttSslProtocols.TLSv1_0: + return SslProtocols.Tls; + /*case MqttSslProtocols.TLSv1_1: + return SslProtocols.Tls11; + case MqttSslProtocols.TLSv1_2: + return SslProtocols.Tls12;*/ + default: + throw new ArgumentException("SSL/TLS protocol version not supported"); + } + } +#elif (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3) + public static SslProtocols ToSslPlatformEnum(MqttSslProtocols mqttSslProtocol) + { + switch (mqttSslProtocol) + { + case MqttSslProtocols.None: + return SslProtocols.None; + case MqttSslProtocols.SSLv3: + return SslProtocols.SSLv3; + case MqttSslProtocols.TLSv1_0: + return SslProtocols.TLSv1; + case MqttSslProtocols.TLSv1_1: + case MqttSslProtocols.TLSv1_2: + default: + throw new ArgumentException("SSL/TLS protocol version not supported"); + } + } +#endif + } +} diff --git a/mqtt/M2Mqtt/bin/Release/4.7.1/M2Mqtt.dll b/mqtt/M2Mqtt/bin/Release/4.7.1/M2Mqtt.dll index e21d585..327ddec 100644 Binary files a/mqtt/M2Mqtt/bin/Release/4.7.1/M2Mqtt.dll and b/mqtt/M2Mqtt/bin/Release/4.7.1/M2Mqtt.dll differ