diff --git a/mqtt/M2Mqtt/Exceptions/MqttClientException.cs b/mqtt/M2Mqtt/Exceptions/MqttClientException.cs
deleted file mode 100644
index cd8303f..0000000
--- a/mqtt/M2Mqtt/Exceptions/MqttClientException.cs
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
-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
-*/
-
-using System;
-
-namespace uPLibrary.Networking.M2Mqtt.Exceptions
-{
- ///
- /// MQTT client exception
- ///
- public class MqttClientException : Exception
- {
- ///
- /// Constructor
- ///
- /// Error code
- public MqttClientException(MqttClientErrorCode errorCode)
- {
- this.errorCode = errorCode;
- }
-
- // error code
- private MqttClientErrorCode errorCode;
-
- ///
- /// Error code
- ///
- public MqttClientErrorCode ErrorCode
- {
- get { return this.errorCode; }
- set { this.errorCode = value; }
- }
- }
-
- ///
- /// MQTT client erroro code
- ///
- public enum MqttClientErrorCode
- {
- ///
- /// Will error (topic, message or QoS level)
- ///
- WillWrong = 1,
-
- ///
- /// Keep alive period too large
- ///
- KeepAliveWrong,
-
- ///
- /// Topic contains wildcards
- ///
- TopicWildcard,
-
- ///
- /// Topic length wrong
- ///
- TopicLength,
-
- ///
- /// QoS level not allowed
- ///
- QosNotAllowed,
-
- ///
- /// Topics list empty for subscribe
- ///
- TopicsEmpty,
-
- ///
- /// Qos levels list empty for subscribe
- ///
- QosLevelsEmpty,
-
- ///
- /// Topics / Qos Levels not match in subscribe
- ///
- TopicsQosLevelsNotMatch,
-
- ///
- /// Wrong message from broker
- ///
- WrongBrokerMessage,
-
- ///
- /// Wrong Message Id
- ///
- WrongMessageId,
-
- ///
- /// Inflight queue is full
- ///
- InflightQueueFull,
-
- // [v3.1.1]
- ///
- /// Invalid flag bits received
- ///
- InvalidFlagBits,
-
- // [v3.1.1]
- ///
- /// Invalid connect flags received
- ///
- InvalidConnectFlags,
-
- // [v3.1.1]
- ///
- /// Invalid client id
- ///
- InvalidClientId,
-
- // [v3.1.1]
- ///
- /// Invalid protocol name
- ///
- InvalidProtocolName
- }
-}
diff --git a/mqtt/M2Mqtt/Exceptions/MqttCommunicationException.cs b/mqtt/M2Mqtt/Exceptions/MqttCommunicationException.cs
deleted file mode 100644
index 6b916cc..0000000
--- a/mqtt/M2Mqtt/Exceptions/MqttCommunicationException.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
-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
-*/
-
-using System;
-
-namespace uPLibrary.Networking.M2Mqtt.Exceptions
-{
- ///
- /// Exception due to error communication with broker on socket
- ///
- public class MqttCommunicationException : Exception
- {
- ///
- /// Default constructor
- ///
- public MqttCommunicationException()
- {
- }
-
- ///
- /// Constructor
- ///
- /// Inner Exception
- public MqttCommunicationException(Exception e)
- : base(String.Empty, e)
- {
- }
- }
-}
diff --git a/mqtt/M2Mqtt/Exceptions/MqttConnectionException.cs b/mqtt/M2Mqtt/Exceptions/MqttConnectionException.cs
deleted file mode 100644
index 3203c7e..0000000
--- a/mqtt/M2Mqtt/Exceptions/MqttConnectionException.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-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
-*/
-
-using System;
-
-namespace uPLibrary.Networking.M2Mqtt.Exceptions
-{
- ///
- /// Connection to the broker exception
- ///
- public class MqttConnectionException : Exception
- {
- public MqttConnectionException(string message, Exception innerException)
- : base(message, innerException)
- {
- }
- }
-}
diff --git a/mqtt/M2Mqtt/Exceptions/MqttTimeoutException.cs b/mqtt/M2Mqtt/Exceptions/MqttTimeoutException.cs
deleted file mode 100644
index b15e69e..0000000
--- a/mqtt/M2Mqtt/Exceptions/MqttTimeoutException.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
-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
-*/
-
-using System;
-
-namespace uPLibrary.Networking.M2Mqtt.Exceptions
-{
- ///
- /// Timeout on receiving from broker exception
- ///
- public class MqttTimeoutException : Exception
- {
- }
-}
diff --git a/mqtt/M2Mqtt/IMqttNetworkChannel.cs b/mqtt/M2Mqtt/IMqttNetworkChannel.cs
deleted file mode 100644
index f4ff90f..0000000
--- a/mqtt/M2Mqtt/IMqttNetworkChannel.cs
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
-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
-*/
-
-using System;
-using System.Text;
-
-namespace uPLibrary.Networking.M2Mqtt
-{
- ///
- /// Interface for channel under MQTT library
- ///
- public interface IMqttNetworkChannel
- {
- ///
- /// Data available on channel
- ///
- bool DataAvailable { get; }
-
- ///
- /// Receive data from the network channel
- ///
- /// Data buffer for receiving data
- /// Number of bytes received
- int Receive(byte[] buffer);
-
- ///
- /// Receive data from the network channel with a specified timeout
- ///
- /// Data buffer for receiving data
- /// Timeout on receiving (in milliseconds)
- /// Number of bytes received
- int Receive(byte[] buffer, int timeout);
-
- ///
- /// Send data on the network channel to the broker
- ///
- /// Data buffer to send
- /// Number of byte sent
- int Send(byte[] buffer);
-
- ///
- /// Close the network channel
- ///
- void Close();
-
- ///
- /// Connect to remote server
- ///
- void Connect();
-
- ///
- /// Accept client connection
- ///
- void Accept();
- }
-}
diff --git a/mqtt/M2Mqtt/Internal/InternalEvent.cs b/mqtt/M2Mqtt/Internal/InternalEvent.cs
deleted file mode 100644
index 7f298c7..0000000
--- a/mqtt/M2Mqtt/Internal/InternalEvent.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
-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
-*/
-
-namespace uPLibrary.Networking.M2Mqtt.Internal
-{
- ///
- /// Generic internal event for dispatching
- ///
- public abstract class InternalEvent
- {
- }
-}
diff --git a/mqtt/M2Mqtt/Internal/MsgInternalEvent.cs b/mqtt/M2Mqtt/Internal/MsgInternalEvent.cs
deleted file mode 100644
index 8cf46a4..0000000
--- a/mqtt/M2Mqtt/Internal/MsgInternalEvent.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
-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
-*/
-
-using uPLibrary.Networking.M2Mqtt.Messages;
-
-namespace uPLibrary.Networking.M2Mqtt.Internal
-{
- ///
- /// Internal event with a message
- ///
- public class MsgInternalEvent : InternalEvent
- {
- #region Properties ...
-
- ///
- /// Related message
- ///
- public MqttMsgBase Message
- {
- get { return this.msg; }
- set { this.msg = value; }
- }
-
- #endregion
-
- // related message
- protected MqttMsgBase msg;
-
- ///
- /// Constructor
- ///
- /// Related message
- public MsgInternalEvent(MqttMsgBase msg)
- {
- this.msg = msg;
- }
- }
-}
diff --git a/mqtt/M2Mqtt/Internal/MsgPublishedInternalEvent.cs b/mqtt/M2Mqtt/Internal/MsgPublishedInternalEvent.cs
deleted file mode 100644
index 5a7f182..0000000
--- a/mqtt/M2Mqtt/Internal/MsgPublishedInternalEvent.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
-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
-*/
-
-using uPLibrary.Networking.M2Mqtt.Messages;
-
-namespace uPLibrary.Networking.M2Mqtt.Internal
-{
- ///
- /// Internal event for a published message
- ///
- public class MsgPublishedInternalEvent : MsgInternalEvent
- {
- #region Properties...
-
- ///
- /// Message published (or failed due to retries)
- ///
- public bool IsPublished
- {
- get { return this.isPublished; }
- internal set { this.isPublished = value; }
- }
-
- #endregion
-
- // published flag
- bool isPublished;
-
- ///
- /// Constructor
- ///
- /// Message published
- /// Publish flag
- public MsgPublishedInternalEvent(MqttMsgBase msg, bool isPublished)
- : base(msg)
- {
- this.isPublished = isPublished;
- }
- }
-}
diff --git a/mqtt/M2Mqtt/M2Mqtt_2.csproj b/mqtt/M2Mqtt/M2Mqtt_2.csproj
deleted file mode 100644
index bc4a1d9..0000000
--- a/mqtt/M2Mqtt/M2Mqtt_2.csproj
+++ /dev/null
@@ -1,93 +0,0 @@
-
-
-
- Debug
- AnyCPU
- 8.0.30703
- 2.0
- {A11AEF5A-B246-4FE8-8330-06DB73CC8074}
- Library
- Properties
- uPLibrary.Networking.M2Mqtt
- M2Mqtt
- v2.0
- 512
-
-
-
- true
- full
- false
- bin\Debug\2.0\
- TRACE;DEBUG
- prompt
- 4
- false
-
-
- pdbonly
- true
- bin\Release\2.0\
- TRACE
- prompt
- 4
- false
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/mqtt/M2Mqtt/M2Mqtt_4.7.1.csproj b/mqtt/M2Mqtt/M2Mqtt_4.7.1.csproj
deleted file mode 100644
index 9fd2d99..0000000
--- a/mqtt/M2Mqtt/M2Mqtt_4.7.1.csproj
+++ /dev/null
@@ -1,93 +0,0 @@
-
-
-
- Debug
- AnyCPU
- 8.0.30703
- 2.0
- {A11AEF5A-B246-4FE8-8330-06DB73CC8074}
- Library
- Properties
- uPLibrary.Networking.M2Mqtt
- M2Mqtt
- v4.7.1
- 512
-
-
-
- true
- full
- false
- bin\Debug\4.7.1\
- TRACE;DEBUG;SSL
- prompt
- 4
- false
-
-
- pdbonly
- true
- bin\Release\4.7.1\
- TRACE;SSL
- prompt
- 4
- false
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/mqtt/M2Mqtt/Messages/MqttMsgBase.cs b/mqtt/M2Mqtt/Messages/MqttMsgBase.cs
deleted file mode 100644
index 870fe5f..0000000
--- a/mqtt/M2Mqtt/Messages/MqttMsgBase.cs
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
-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
-*/
-
-using System;
-using System.Text;
-
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
- ///
- /// Base class for all MQTT messages
- ///
- public abstract class MqttMsgBase
- {
- #region Constants...
-
- // mask, offset and size for fixed header fields
- internal const byte MSG_TYPE_MASK = 0xF0;
- internal const byte MSG_TYPE_OFFSET = 0x04;
- internal const byte MSG_TYPE_SIZE = 0x04;
- internal const byte MSG_FLAG_BITS_MASK = 0x0F; // [v3.1.1]
- internal const byte MSG_FLAG_BITS_OFFSET = 0x00; // [v3.1.1]
- internal const byte MSG_FLAG_BITS_SIZE = 0x04; // [v3.1.1]
- internal const byte DUP_FLAG_MASK = 0x08;
- internal const byte DUP_FLAG_OFFSET = 0x03;
- internal const byte DUP_FLAG_SIZE = 0x01;
- internal const byte QOS_LEVEL_MASK = 0x06;
- internal const byte QOS_LEVEL_OFFSET = 0x01;
- internal const byte QOS_LEVEL_SIZE = 0x02;
- internal const byte RETAIN_FLAG_MASK = 0x01;
- internal const byte RETAIN_FLAG_OFFSET = 0x00;
- internal const byte RETAIN_FLAG_SIZE = 0x01;
-
- // MQTT message types
- internal const byte MQTT_MSG_CONNECT_TYPE = 0x01;
- internal const byte MQTT_MSG_CONNACK_TYPE = 0x02;
- internal const byte MQTT_MSG_PUBLISH_TYPE = 0x03;
- internal const byte MQTT_MSG_PUBACK_TYPE = 0x04;
- internal const byte MQTT_MSG_PUBREC_TYPE = 0x05;
- internal const byte MQTT_MSG_PUBREL_TYPE = 0x06;
- internal const byte MQTT_MSG_PUBCOMP_TYPE = 0x07;
- internal const byte MQTT_MSG_SUBSCRIBE_TYPE = 0x08;
- internal const byte MQTT_MSG_SUBACK_TYPE = 0x09;
- internal const byte MQTT_MSG_UNSUBSCRIBE_TYPE = 0x0A;
- internal const byte MQTT_MSG_UNSUBACK_TYPE = 0x0B;
- internal const byte MQTT_MSG_PINGREQ_TYPE = 0x0C;
- internal const byte MQTT_MSG_PINGRESP_TYPE = 0x0D;
- internal const byte MQTT_MSG_DISCONNECT_TYPE = 0x0E;
-
- // [v3.1.1] MQTT flag bits
- internal const byte MQTT_MSG_CONNECT_FLAG_BITS = 0x00;
- internal const byte MQTT_MSG_CONNACK_FLAG_BITS = 0x00;
- internal const byte MQTT_MSG_PUBLISH_FLAG_BITS = 0x00; // just defined as 0x00 but depends on publish props (dup, qos, retain)
- internal const byte MQTT_MSG_PUBACK_FLAG_BITS = 0x00;
- internal const byte MQTT_MSG_PUBREC_FLAG_BITS = 0x00;
- internal const byte MQTT_MSG_PUBREL_FLAG_BITS = 0x02;
- internal const byte MQTT_MSG_PUBCOMP_FLAG_BITS = 0x00;
- internal const byte MQTT_MSG_SUBSCRIBE_FLAG_BITS = 0x02;
- internal const byte MQTT_MSG_SUBACK_FLAG_BITS = 0x00;
- internal const byte MQTT_MSG_UNSUBSCRIBE_FLAG_BITS = 0x02;
- internal const byte MQTT_MSG_UNSUBACK_FLAG_BITS = 0x00;
- internal const byte MQTT_MSG_PINGREQ_FLAG_BITS = 0x00;
- internal const byte MQTT_MSG_PINGRESP_FLAG_BITS = 0x00;
- internal const byte MQTT_MSG_DISCONNECT_FLAG_BITS = 0x00;
-
- // QOS levels
- public const byte QOS_LEVEL_AT_MOST_ONCE = 0x00;
- public const byte QOS_LEVEL_AT_LEAST_ONCE = 0x01;
- public const byte QOS_LEVEL_EXACTLY_ONCE = 0x02;
-
- // SUBSCRIBE QoS level granted failure [v3.1.1]
- public const byte QOS_LEVEL_GRANTED_FAILURE = 0x80;
-
- internal const ushort MAX_TOPIC_LENGTH = 65535;
- internal const ushort MIN_TOPIC_LENGTH = 1;
- internal const byte MESSAGE_ID_SIZE = 2;
-
- #endregion
-
- #region Properties...
-
- ///
- /// Message type
- ///
- public byte Type
- {
- get { return this.type; }
- set { this.type = value; }
- }
-
- ///
- /// Duplicate message flag
- ///
- public bool DupFlag
- {
- get { return this.dupFlag; }
- set { this.dupFlag = value; }
- }
-
- ///
- /// Quality of Service level
- ///
- public byte QosLevel
- {
- get { return this.qosLevel; }
- set { this.qosLevel = value; }
- }
-
- ///
- /// Retain message flag
- ///
- public bool Retain
- {
- get { return this.retain; }
- set { this.retain = value; }
- }
-
- ///
- /// Message identifier for the message
- ///
- public ushort MessageId
- {
- get { return this.messageId; }
- set { this.messageId = value; }
- }
-
- #endregion
-
- // message type
- protected byte type;
- // duplicate delivery
- protected bool dupFlag;
- // quality of service level
- protected byte qosLevel;
- // retain flag
- protected bool retain;
- // message identifier
- protected ushort messageId;
-
- ///
- /// Returns message bytes rapresentation
- ///
- /// Protocol version
- /// Bytes rapresentation
- public abstract byte[] GetBytes(byte protocolVersion);
-
- ///
- /// Encode remaining length and insert it into message buffer
- ///
- /// Remaining length value to encode
- /// Message buffer for inserting encoded value
- /// Index from which insert encoded value into buffer
- /// Index updated
- protected int encodeRemainingLength(int remainingLength, byte[] buffer, int index)
- {
- int digit = 0;
- do
- {
- digit = remainingLength % 128;
- remainingLength /= 128;
- if (remainingLength > 0)
- digit = digit | 0x80;
- buffer[index++] = (byte)digit;
- } while (remainingLength > 0);
- return index;
- }
-
- ///
- /// Decode remaining length reading bytes from socket
- ///
- /// Channel from reading bytes
- /// Decoded remaining length
- protected static int decodeRemainingLength(IMqttNetworkChannel channel)
- {
- int multiplier = 1;
- int value = 0;
- int digit = 0;
- byte[] nextByte = new byte[1];
- do
- {
- // next digit from stream
- channel.Receive(nextByte);
- digit = nextByte[0];
- value += ((digit & 127) * multiplier);
- multiplier *= 128;
- } while ((digit & 128) != 0);
- return value;
- }
-
-#if TRACE
- ///
- /// Returns a string representation of the message for tracing
- ///
- /// Message name
- /// Message fields name
- /// Message fields value
- /// String representation of the message
- protected string GetTraceString(string name, object[] fieldNames, object[] fieldValues)
- {
- StringBuilder sb = new StringBuilder();
- sb.Append(name);
-
- if ((fieldNames != null) && (fieldValues != null))
- {
- sb.Append("(");
- bool addComma = false;
- for (int i = 0; i < fieldValues.Length; i++)
- {
- if (fieldValues[i] != null)
- {
- if (addComma)
- {
- sb.Append(",");
- }
-
- sb.Append(fieldNames[i]);
- sb.Append(":");
- sb.Append(GetStringObject(fieldValues[i]));
- addComma = true;
- }
- }
- sb.Append(")");
- }
-
- return sb.ToString();
- }
-
- object GetStringObject(object value)
- {
- byte[] binary = value as byte[];
- if (binary != null)
- {
- string hexChars = "0123456789ABCDEF";
- StringBuilder sb = new StringBuilder(binary.Length * 2);
- for (int i = 0; i < binary.Length; ++i)
- {
- sb.Append(hexChars[binary[i] >> 4]);
- sb.Append(hexChars[binary[i] & 0x0F]);
- }
-
- return sb.ToString();
- }
-
- object[] list = value as object[];
- if (list != null)
- {
- StringBuilder sb = new StringBuilder();
- sb.Append('[');
- for (int i = 0; i < list.Length; ++i)
- {
- if (i > 0) sb.Append(',');
- sb.Append(list[i]);
- }
- sb.Append(']');
-
- return sb.ToString();
- }
-
- return value;
- }
-#endif
- }
-}
diff --git a/mqtt/M2Mqtt/Messages/MqttMsgConnack.cs b/mqtt/M2Mqtt/Messages/MqttMsgConnack.cs
deleted file mode 100644
index ae5a342..0000000
--- a/mqtt/M2Mqtt/Messages/MqttMsgConnack.cs
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
-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
-*/
-
-using System;
-using uPLibrary.Networking.M2Mqtt.Exceptions;
-
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
- ///
- /// Class for CONNACK message from broker to client
- ///
- public class MqttMsgConnack : MqttMsgBase
- {
- #region Constants...
-
- // return codes for CONNACK message
- public const byte CONN_ACCEPTED = 0x00;
- public const byte CONN_REFUSED_PROT_VERS = 0x01;
- public const byte CONN_REFUSED_IDENT_REJECTED = 0x02;
- public const byte CONN_REFUSED_SERVER_UNAVAILABLE = 0x03;
- public const byte CONN_REFUSED_USERNAME_PASSWORD = 0x04;
- public const byte CONN_REFUSED_NOT_AUTHORIZED = 0x05;
-
- private const byte TOPIC_NAME_COMP_RESP_BYTE_OFFSET = 0;
- private const byte TOPIC_NAME_COMP_RESP_BYTE_SIZE = 1;
- // [v3.1.1] connect acknowledge flags replace "old" topic name compression respone (not used in 3.1)
- private const byte CONN_ACK_FLAGS_BYTE_OFFSET = 0;
- private const byte CONN_ACK_FLAGS_BYTE_SIZE = 1;
- // [v3.1.1] session present flag
- private const byte SESSION_PRESENT_FLAG_MASK = 0x01;
- private const byte SESSION_PRESENT_FLAG_OFFSET = 0x00;
- private const byte SESSION_PRESENT_FLAG_SIZE = 0x01;
- private const byte CONN_RETURN_CODE_BYTE_OFFSET = 1;
- private const byte CONN_RETURN_CODE_BYTE_SIZE = 1;
-
- #endregion
-
- #region Properties...
-
- // [v3.1.1] session present flag
- ///
- /// Session present flag
- ///
- public bool SessionPresent
- {
- get { return this.sessionPresent; }
- set { this.sessionPresent = value; }
- }
-
- ///
- /// Return Code
- ///
- public byte ReturnCode
- {
- get { return this.returnCode; }
- set { this.returnCode = value; }
- }
-
- #endregion
-
- // [v3.1.1] session present flag
- private bool sessionPresent;
-
- // return code for CONNACK message
- private byte returnCode;
-
- ///
- /// Constructor
- ///
- public MqttMsgConnack()
- {
- this.type = MQTT_MSG_CONNACK_TYPE;
- }
-
- ///
- /// Parse bytes for a CONNACK message
- ///
- /// First fixed header byte
- /// Protocol Version
- /// Channel connected to the broker
- /// CONNACK message instance
- public static MqttMsgConnack Parse(byte fixedHeaderFirstByte, byte protocolVersion, IMqttNetworkChannel channel)
- {
- byte[] buffer;
- MqttMsgConnack msg = new MqttMsgConnack();
-
- if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1)
- {
- // [v3.1.1] check flag bits
- if ((fixedHeaderFirstByte & MSG_FLAG_BITS_MASK) != MQTT_MSG_CONNACK_FLAG_BITS)
- throw new MqttClientException(MqttClientErrorCode.InvalidFlagBits);
- }
-
- // get remaining length and allocate buffer
- int remainingLength = MqttMsgBase.decodeRemainingLength(channel);
- buffer = new byte[remainingLength];
-
- // read bytes from socket...
- channel.Receive(buffer);
- if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1)
- {
- // [v3.1.1] ... set session present flag ...
- msg.sessionPresent = (buffer[CONN_ACK_FLAGS_BYTE_OFFSET] & SESSION_PRESENT_FLAG_MASK) != 0x00;
- }
- // ...and set return code from broker
- msg.returnCode = buffer[CONN_RETURN_CODE_BYTE_OFFSET];
-
- return msg;
- }
-
- public override byte[] GetBytes(byte ProtocolVersion)
- {
- int fixedHeaderSize = 0;
- int varHeaderSize = 0;
- int payloadSize = 0;
- int remainingLength = 0;
- byte[] buffer;
- int index = 0;
-
- if (ProtocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1)
- // flags byte and connect return code
- varHeaderSize += (CONN_ACK_FLAGS_BYTE_SIZE + CONN_RETURN_CODE_BYTE_SIZE);
- else
- // topic name compression response and connect return code
- varHeaderSize += (TOPIC_NAME_COMP_RESP_BYTE_SIZE + CONN_RETURN_CODE_BYTE_SIZE);
-
- remainingLength += (varHeaderSize + payloadSize);
-
- // first byte of fixed header
- fixedHeaderSize = 1;
-
- int temp = remainingLength;
- // increase fixed header size based on remaining length
- // (each remaining length byte can encode until 128)
- do
- {
- fixedHeaderSize++;
- temp = temp / 128;
- } while (temp > 0);
-
- // allocate buffer for message
- buffer = new byte[fixedHeaderSize + varHeaderSize + payloadSize];
-
- // first fixed header byte
- if (ProtocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1)
- buffer[index++] = (MQTT_MSG_CONNACK_TYPE << MSG_TYPE_OFFSET) | MQTT_MSG_CONNACK_FLAG_BITS; // [v.3.1.1]
- else
- buffer[index++] = (byte)(MQTT_MSG_CONNACK_TYPE << MSG_TYPE_OFFSET);
-
- // encode remaining length
- index = this.encodeRemainingLength(remainingLength, buffer, index);
-
- if (ProtocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1)
- // [v3.1.1] session present flag
- buffer[index++] = this.sessionPresent ? (byte)(1 << SESSION_PRESENT_FLAG_OFFSET) : (byte)0x00;
- else
- // topic name compression response (reserved values. not used);
- buffer[index++] = 0x00;
-
- // connect return code
- buffer[index++] = this.returnCode;
-
- return buffer;
- }
-
- public override string ToString()
- {
-#if TRACE
- return this.GetTraceString(
- "CONNACK",
- new object[] { "returnCode" },
- new object[] { this.returnCode });
-#else
- return base.ToString();
-#endif
- }
- }
-}
diff --git a/mqtt/M2Mqtt/Messages/MqttMsgConnect.cs b/mqtt/M2Mqtt/Messages/MqttMsgConnect.cs
deleted file mode 100644
index 382cf83..0000000
--- a/mqtt/M2Mqtt/Messages/MqttMsgConnect.cs
+++ /dev/null
@@ -1,582 +0,0 @@
-/*
-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
-*/
-
-using System;
-using System.Text;
-using uPLibrary.Networking.M2Mqtt.Exceptions;
-
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
- ///
- /// Class for CONNECT message from client to broker
- ///
- public class MqttMsgConnect : MqttMsgBase
- {
- #region Constants...
-
- // protocol name supported
- internal const string PROTOCOL_NAME_V3_1 = "MQIsdp";
- internal const string PROTOCOL_NAME_V3_1_1 = "MQTT"; // [v.3.1.1]
-
- // max length for client id (removed in 3.1.1)
- internal const int CLIENT_ID_MAX_LENGTH = 23;
-
- // variable header fields
- internal const byte PROTOCOL_NAME_LEN_SIZE = 2;
- internal const byte PROTOCOL_NAME_V3_1_SIZE = 6;
- internal const byte PROTOCOL_NAME_V3_1_1_SIZE = 4; // [v.3.1.1]
- internal const byte PROTOCOL_VERSION_SIZE = 1;
- internal const byte CONNECT_FLAGS_SIZE = 1;
- internal const byte KEEP_ALIVE_TIME_SIZE = 2;
-
- internal const byte PROTOCOL_VERSION_V3_1 = 0x03;
- internal const byte PROTOCOL_VERSION_V3_1_1 = 0x04; // [v.3.1.1]
- internal const ushort KEEP_ALIVE_PERIOD_DEFAULT = 60; // seconds
- internal const ushort MAX_KEEP_ALIVE = 65535; // 16 bit
-
- // connect flags
- internal const byte USERNAME_FLAG_MASK = 0x80;
- internal const byte USERNAME_FLAG_OFFSET = 0x07;
- internal const byte USERNAME_FLAG_SIZE = 0x01;
- internal const byte PASSWORD_FLAG_MASK = 0x40;
- internal const byte PASSWORD_FLAG_OFFSET = 0x06;
- internal const byte PASSWORD_FLAG_SIZE = 0x01;
- internal const byte WILL_RETAIN_FLAG_MASK = 0x20;
- internal const byte WILL_RETAIN_FLAG_OFFSET = 0x05;
- internal const byte WILL_RETAIN_FLAG_SIZE = 0x01;
- internal const byte WILL_QOS_FLAG_MASK = 0x18;
- internal const byte WILL_QOS_FLAG_OFFSET = 0x03;
- internal const byte WILL_QOS_FLAG_SIZE = 0x02;
- internal const byte WILL_FLAG_MASK = 0x04;
- internal const byte WILL_FLAG_OFFSET = 0x02;
- internal const byte WILL_FLAG_SIZE = 0x01;
- internal const byte CLEAN_SESSION_FLAG_MASK = 0x02;
- internal const byte CLEAN_SESSION_FLAG_OFFSET = 0x01;
- internal const byte CLEAN_SESSION_FLAG_SIZE = 0x01;
- // [v.3.1.1] lsb (reserved) must be now 0
- internal const byte RESERVED_FLAG_MASK = 0x01;
- internal const byte RESERVED_FLAG_OFFSET = 0x00;
- internal const byte RESERVED_FLAG_SIZE = 0x01;
-
- #endregion
-
- #region Properties...
-
- ///
- /// Protocol name
- ///
- public string ProtocolName
- {
- get { return this.protocolName; }
- set { this.protocolName = value; }
- }
-
- ///
- /// Protocol version
- ///
- public byte ProtocolVersion
- {
- get { return this.protocolVersion; }
- set { this.protocolVersion = value; }
- }
-
- ///
- /// Client identifier
- ///
- public string ClientId
- {
- get { return this.clientId; }
- set { this.clientId = value; }
- }
-
- ///
- /// Will retain flag
- ///
- public bool WillRetain
- {
- get { return this.willRetain; }
- set { this.willRetain = value; }
- }
-
- ///
- /// Will QOS level
- ///
- public byte WillQosLevel
- {
- get { return this.willQosLevel; }
- set { this.willQosLevel = value; }
- }
-
- ///
- /// Will flag
- ///
- public bool WillFlag
- {
- get { return this.willFlag; }
- set { this.willFlag = value; }
- }
-
- ///
- /// Will topic
- ///
- public string WillTopic
- {
- get { return this.willTopic; }
- set { this.willTopic = value; }
- }
-
- ///
- /// Will message
- ///
- public string WillMessage
- {
- get { return this.willMessage; }
- set { this.willMessage = value; }
- }
-
- ///
- /// Username
- ///
- public string Username
- {
- get { return this.username; }
- set { this.username = value; }
- }
-
- ///
- /// Password
- ///
- public string Password
- {
- get { return this.password; }
- set { this.password = value; }
- }
-
- ///
- /// Clean session flag
- ///
- public bool CleanSession
- {
- get { return this.cleanSession; }
- set { this.cleanSession = value; }
- }
-
- ///
- /// Keep alive period
- ///
- public ushort KeepAlivePeriod
- {
- get { return this.keepAlivePeriod; }
- set { this.keepAlivePeriod = value; }
- }
-
- #endregion
-
- // protocol name
- private string protocolName;
- // protocol version
- private byte protocolVersion;
- // client identifier
- private string clientId;
- // will retain flag
- protected bool willRetain;
- // will quality of service level
- protected byte willQosLevel;
- // will flag
- private bool willFlag;
- // will topic
- private string willTopic;
- // will message
- private string willMessage;
- // username
- private string username;
- // password
- private string password;
- // clean session flag
- private bool cleanSession;
- // keep alive period (in sec)
- private ushort keepAlivePeriod;
-
- ///
- /// Constructor
- ///
- public MqttMsgConnect()
- {
- this.type = MQTT_MSG_CONNECT_TYPE;
- }
-
- ///
- /// Constructor
- ///
- /// Client identifier
- public MqttMsgConnect(string clientId) :
- this(clientId, null, null, false, QOS_LEVEL_AT_LEAST_ONCE, false, null, null, true, KEEP_ALIVE_PERIOD_DEFAULT, PROTOCOL_VERSION_V3_1_1)
- {
- }
-
- ///
- /// Constructor
- ///
- /// Client identifier
- /// Username
- /// Password
- /// Will retain flag
- /// Will QOS level
- /// Will flag
- /// Will topic
- /// Will message
- /// Clean sessione flag
- /// Keep alive period
- /// Protocol version
- public MqttMsgConnect(string clientId,
- string username,
- string password,
- bool willRetain,
- byte willQosLevel,
- bool willFlag,
- string willTopic,
- string willMessage,
- bool cleanSession,
- ushort keepAlivePeriod,
- byte protocolVersion
- )
- {
- this.type = MQTT_MSG_CONNECT_TYPE;
-
- this.clientId = clientId;
- this.username = username;
- this.password = password;
- this.willRetain = willRetain;
- this.willQosLevel = willQosLevel;
- this.willFlag = willFlag;
- this.willTopic = willTopic;
- this.willMessage = willMessage;
- this.cleanSession = cleanSession;
- this.keepAlivePeriod = keepAlivePeriod;
- // [v.3.1.1] added new protocol name and version
- this.protocolVersion = protocolVersion;
- this.protocolName = (this.protocolVersion == PROTOCOL_VERSION_V3_1_1) ? PROTOCOL_NAME_V3_1_1 : PROTOCOL_NAME_V3_1;
- }
-
- ///
- /// Parse bytes for a CONNECT message
- ///
- /// First fixed header byte
- /// Protocol Version
- /// Channel connected to the broker
- /// CONNECT message instance
- public static MqttMsgConnect Parse(byte fixedHeaderFirstByte, byte protocolVersion, IMqttNetworkChannel channel)
- {
- byte[] buffer;
- int index = 0;
- int protNameUtf8Length;
- byte[] protNameUtf8;
- bool isUsernameFlag;
- bool isPasswordFlag;
- int clientIdUtf8Length;
- byte[] clientIdUtf8;
- int willTopicUtf8Length;
- byte[] willTopicUtf8;
- int willMessageUtf8Length;
- byte[] willMessageUtf8;
- int usernameUtf8Length;
- byte[] usernameUtf8;
- int passwordUtf8Length;
- byte[] passwordUtf8;
- MqttMsgConnect msg = new MqttMsgConnect();
-
- // get remaining length and allocate buffer
- int remainingLength = MqttMsgBase.decodeRemainingLength(channel);
- buffer = new byte[remainingLength];
-
- // read bytes from socket...
- channel.Receive(buffer);
-
- // protocol name
- protNameUtf8Length = ((buffer[index++] << 8) & 0xFF00);
- protNameUtf8Length |= buffer[index++];
- protNameUtf8 = new byte[protNameUtf8Length];
- Array.Copy(buffer, index, protNameUtf8, 0, protNameUtf8Length);
- index += protNameUtf8Length;
- msg.protocolName = new String(Encoding.UTF8.GetChars(protNameUtf8));
-
- // [v3.1.1] wrong protocol name
- if (!msg.protocolName.Equals(PROTOCOL_NAME_V3_1) && !msg.protocolName.Equals(PROTOCOL_NAME_V3_1_1))
- throw new MqttClientException(MqttClientErrorCode.InvalidProtocolName);
-
- // protocol version
- msg.protocolVersion = buffer[index];
- index += PROTOCOL_VERSION_SIZE;
-
- // connect flags
- // [v3.1.1] check lsb (reserved) must be 0
- if ((msg.protocolVersion == PROTOCOL_VERSION_V3_1_1) &&
- ((buffer[index] & RESERVED_FLAG_MASK) != 0x00))
- throw new MqttClientException(MqttClientErrorCode.InvalidConnectFlags);
-
- isUsernameFlag = (buffer[index] & USERNAME_FLAG_MASK) != 0x00;
- isPasswordFlag = (buffer[index] & PASSWORD_FLAG_MASK) != 0x00;
- msg.willRetain = (buffer[index] & WILL_RETAIN_FLAG_MASK) != 0x00;
- msg.willQosLevel = (byte)((buffer[index] & WILL_QOS_FLAG_MASK) >> WILL_QOS_FLAG_OFFSET);
- msg.willFlag = (buffer[index] & WILL_FLAG_MASK) != 0x00;
- msg.cleanSession = (buffer[index] & CLEAN_SESSION_FLAG_MASK) != 0x00;
- index += CONNECT_FLAGS_SIZE;
-
- // keep alive timer
- msg.keepAlivePeriod = (ushort)((buffer[index++] << 8) & 0xFF00);
- msg.keepAlivePeriod |= buffer[index++];
-
- // client identifier [v3.1.1] it may be zero bytes long (empty string)
- clientIdUtf8Length = ((buffer[index++] << 8) & 0xFF00);
- clientIdUtf8Length |= buffer[index++];
- clientIdUtf8 = new byte[clientIdUtf8Length];
- Array.Copy(buffer, index, clientIdUtf8, 0, clientIdUtf8Length);
- index += clientIdUtf8Length;
- msg.clientId = new String(Encoding.UTF8.GetChars(clientIdUtf8));
- // [v3.1.1] if client identifier is zero bytes long, clean session must be true
- if ((msg.protocolVersion == PROTOCOL_VERSION_V3_1_1) && (clientIdUtf8Length == 0) && (!msg.cleanSession))
- throw new MqttClientException(MqttClientErrorCode.InvalidClientId);
-
- // will topic and will message
- if (msg.willFlag)
- {
- willTopicUtf8Length = ((buffer[index++] << 8) & 0xFF00);
- willTopicUtf8Length |= buffer[index++];
- willTopicUtf8 = new byte[willTopicUtf8Length];
- Array.Copy(buffer, index, willTopicUtf8, 0, willTopicUtf8Length);
- index += willTopicUtf8Length;
- msg.willTopic = new String(Encoding.UTF8.GetChars(willTopicUtf8));
-
- willMessageUtf8Length = ((buffer[index++] << 8) & 0xFF00);
- willMessageUtf8Length |= buffer[index++];
- willMessageUtf8 = new byte[willMessageUtf8Length];
- Array.Copy(buffer, index, willMessageUtf8, 0, willMessageUtf8Length);
- index += willMessageUtf8Length;
- msg.willMessage = new String(Encoding.UTF8.GetChars(willMessageUtf8));
- }
-
- // username
- if (isUsernameFlag)
- {
- usernameUtf8Length = ((buffer[index++] << 8) & 0xFF00);
- usernameUtf8Length |= buffer[index++];
- usernameUtf8 = new byte[usernameUtf8Length];
- Array.Copy(buffer, index, usernameUtf8, 0, usernameUtf8Length);
- index += usernameUtf8Length;
- msg.username = new String(Encoding.UTF8.GetChars(usernameUtf8));
- }
-
- // password
- if (isPasswordFlag)
- {
- passwordUtf8Length = ((buffer[index++] << 8) & 0xFF00);
- passwordUtf8Length |= buffer[index++];
- passwordUtf8 = new byte[passwordUtf8Length];
- Array.Copy(buffer, index, passwordUtf8, 0, passwordUtf8Length);
- index += passwordUtf8Length;
- msg.password = new String(Encoding.UTF8.GetChars(passwordUtf8));
- }
-
- return msg;
- }
-
- public override byte[] GetBytes(byte protocolVersion)
- {
- int fixedHeaderSize = 0;
- int varHeaderSize = 0;
- int payloadSize = 0;
- int remainingLength = 0;
- byte[] buffer;
- int index = 0;
-
- byte[] clientIdUtf8 = Encoding.UTF8.GetBytes(this.clientId);
- byte[] willTopicUtf8 = (this.willFlag && (this.willTopic != null)) ? Encoding.UTF8.GetBytes(this.willTopic) : null;
- byte[] willMessageUtf8 = (this.willFlag && (this.willMessage != null)) ? Encoding.UTF8.GetBytes(this.willMessage) : null;
- byte[] usernameUtf8 = ((this.username != null) && (this.username.Length > 0)) ? Encoding.UTF8.GetBytes(this.username) : null;
- byte[] passwordUtf8 = ((this.password != null) && (this.password.Length > 0)) ? Encoding.UTF8.GetBytes(this.password) : null;
-
- // [v3.1.1]
- if (this.protocolVersion == PROTOCOL_VERSION_V3_1_1)
- {
- // will flag set, will topic and will message MUST be present
- if (this.willFlag && ((this.willQosLevel >= 0x03) ||
- (willTopicUtf8 == null) || (willMessageUtf8 == null) ||
- ((willTopicUtf8 != null) && (willTopicUtf8.Length == 0)) ||
- ((willMessageUtf8 != null) && (willMessageUtf8.Length == 0))))
- throw new MqttClientException(MqttClientErrorCode.WillWrong);
- // willflag not set, retain must be 0 and will topic and message MUST NOT be present
- else if (!this.willFlag && ((this.willRetain) ||
- (willTopicUtf8 != null) || (willMessageUtf8 != null) ||
- ((willTopicUtf8 != null) && (willTopicUtf8.Length != 0)) ||
- ((willMessageUtf8 != null) && (willMessageUtf8.Length != 0))))
- throw new MqttClientException(MqttClientErrorCode.WillWrong);
- }
-
- if (this.keepAlivePeriod > MAX_KEEP_ALIVE)
- throw new MqttClientException(MqttClientErrorCode.KeepAliveWrong);
-
- // check on will QoS Level
- if ((this.willQosLevel < MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE) ||
- (this.willQosLevel > MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE))
- throw new MqttClientException(MqttClientErrorCode.WillWrong);
-
- // protocol name field size
- // MQTT version 3.1
- if (this.protocolVersion == PROTOCOL_VERSION_V3_1)
- {
- varHeaderSize += (PROTOCOL_NAME_LEN_SIZE + PROTOCOL_NAME_V3_1_SIZE);
- }
- // MQTT version 3.1.1
- else
- {
- varHeaderSize += (PROTOCOL_NAME_LEN_SIZE + PROTOCOL_NAME_V3_1_1_SIZE);
- }
- // protocol level field size
- varHeaderSize += PROTOCOL_VERSION_SIZE;
- // connect flags field size
- varHeaderSize += CONNECT_FLAGS_SIZE;
- // keep alive timer field size
- varHeaderSize += KEEP_ALIVE_TIME_SIZE;
-
- // client identifier field size
- payloadSize += clientIdUtf8.Length + 2;
- // will topic field size
- payloadSize += (willTopicUtf8 != null) ? (willTopicUtf8.Length + 2) : 0;
- // will message field size
- payloadSize += (willMessageUtf8 != null) ? (willMessageUtf8.Length + 2) : 0;
- // username field size
- payloadSize += (usernameUtf8 != null) ? (usernameUtf8.Length + 2) : 0;
- // password field size
- payloadSize += (passwordUtf8 != null) ? (passwordUtf8.Length + 2) : 0;
-
- remainingLength += (varHeaderSize + payloadSize);
-
- // first byte of fixed header
- fixedHeaderSize = 1;
-
- int temp = remainingLength;
- // increase fixed header size based on remaining length
- // (each remaining length byte can encode until 128)
- do
- {
- fixedHeaderSize++;
- temp = temp / 128;
- } while (temp > 0);
-
- // allocate buffer for message
- buffer = new byte[fixedHeaderSize + varHeaderSize + payloadSize];
-
- // first fixed header byte
- buffer[index++] = (MQTT_MSG_CONNECT_TYPE << MSG_TYPE_OFFSET) | MQTT_MSG_CONNECT_FLAG_BITS; // [v.3.1.1]
-
- // encode remaining length
- index = this.encodeRemainingLength(remainingLength, buffer, index);
-
- // protocol name
- buffer[index++] = 0; // MSB protocol name size
- // MQTT version 3.1
- if (this.protocolVersion == PROTOCOL_VERSION_V3_1)
- {
- buffer[index++] = PROTOCOL_NAME_V3_1_SIZE; // LSB protocol name size
- Array.Copy(Encoding.UTF8.GetBytes(PROTOCOL_NAME_V3_1), 0, buffer, index, PROTOCOL_NAME_V3_1_SIZE);
- index += PROTOCOL_NAME_V3_1_SIZE;
- // protocol version
- buffer[index++] = PROTOCOL_VERSION_V3_1;
- }
- // MQTT version 3.1.1
- else
- {
- buffer[index++] = PROTOCOL_NAME_V3_1_1_SIZE; // LSB protocol name size
- Array.Copy(Encoding.UTF8.GetBytes(PROTOCOL_NAME_V3_1_1), 0, buffer, index, PROTOCOL_NAME_V3_1_1_SIZE);
- index += PROTOCOL_NAME_V3_1_1_SIZE;
- // protocol version
- buffer[index++] = PROTOCOL_VERSION_V3_1_1;
- }
-
- // connect flags
- byte connectFlags = 0x00;
- connectFlags |= (usernameUtf8 != null) ? (byte)(1 << USERNAME_FLAG_OFFSET) : (byte)0x00;
- connectFlags |= (passwordUtf8 != null) ? (byte)(1 << PASSWORD_FLAG_OFFSET) : (byte)0x00;
- connectFlags |= (this.willRetain) ? (byte)(1 << WILL_RETAIN_FLAG_OFFSET) : (byte)0x00;
- // only if will flag is set, we have to use will QoS level (otherwise is MUST be 0)
- if (this.willFlag)
- connectFlags |= (byte)(this.willQosLevel << WILL_QOS_FLAG_OFFSET);
- connectFlags |= (this.willFlag) ? (byte)(1 << WILL_FLAG_OFFSET) : (byte)0x00;
- connectFlags |= (this.cleanSession) ? (byte)(1 << CLEAN_SESSION_FLAG_OFFSET) : (byte)0x00;
- buffer[index++] = connectFlags;
-
- // keep alive period
- buffer[index++] = (byte)((this.keepAlivePeriod >> 8) & 0x00FF); // MSB
- buffer[index++] = (byte)(this.keepAlivePeriod & 0x00FF); // LSB
-
- // client identifier
- buffer[index++] = (byte)((clientIdUtf8.Length >> 8) & 0x00FF); // MSB
- buffer[index++] = (byte)(clientIdUtf8.Length & 0x00FF); // LSB
- Array.Copy(clientIdUtf8, 0, buffer, index, clientIdUtf8.Length);
- index += clientIdUtf8.Length;
-
- // will topic
- if (this.willFlag && (willTopicUtf8 != null))
- {
- buffer[index++] = (byte)((willTopicUtf8.Length >> 8) & 0x00FF); // MSB
- buffer[index++] = (byte)(willTopicUtf8.Length & 0x00FF); // LSB
- Array.Copy(willTopicUtf8, 0, buffer, index, willTopicUtf8.Length);
- index += willTopicUtf8.Length;
- }
-
- // will message
- if (this.willFlag && (willMessageUtf8 != null))
- {
- buffer[index++] = (byte)((willMessageUtf8.Length >> 8) & 0x00FF); // MSB
- buffer[index++] = (byte)(willMessageUtf8.Length & 0x00FF); // LSB
- Array.Copy(willMessageUtf8, 0, buffer, index, willMessageUtf8.Length);
- index += willMessageUtf8.Length;
- }
-
- // username
- if (usernameUtf8 != null)
- {
- buffer[index++] = (byte)((usernameUtf8.Length >> 8) & 0x00FF); // MSB
- buffer[index++] = (byte)(usernameUtf8.Length & 0x00FF); // LSB
- Array.Copy(usernameUtf8, 0, buffer, index, usernameUtf8.Length);
- index += usernameUtf8.Length;
- }
-
- // password
- if (passwordUtf8 != null)
- {
- buffer[index++] = (byte)((passwordUtf8.Length >> 8) & 0x00FF); // MSB
- buffer[index++] = (byte)(passwordUtf8.Length & 0x00FF); // LSB
- Array.Copy(passwordUtf8, 0, buffer, index, passwordUtf8.Length);
- index += passwordUtf8.Length;
- }
-
- return buffer;
- }
-
- public override string ToString()
- {
-#if TRACE
- return this.GetTraceString(
- "CONNECT",
- new object[] { "protocolName", "protocolVersion", "clientId", "willFlag", "willRetain", "willQosLevel", "willTopic", "willMessage", "username", "password", "cleanSession", "keepAlivePeriod" },
- new object[] { this.protocolName, this.protocolVersion, this.clientId, this.willFlag, this.willRetain, this.willQosLevel, this.willTopic, this.willMessage, this.username, this.password, this.cleanSession, this.keepAlivePeriod });
-#else
- return base.ToString();
-#endif
- }
- }
-}
diff --git a/mqtt/M2Mqtt/Messages/MqttMsgConnectEventArgs.cs b/mqtt/M2Mqtt/Messages/MqttMsgConnectEventArgs.cs
deleted file mode 100644
index ce0b3fe..0000000
--- a/mqtt/M2Mqtt/Messages/MqttMsgConnectEventArgs.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-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 (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3)
-using System;
-#else
-using Microsoft.SPOT;
-#endif
-
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
- ///
- /// Event Args class for CONNECT message received from client
- ///
- public class MqttMsgConnectEventArgs : EventArgs
- {
- ///
- /// Message received from client
- ///
- public MqttMsgConnect Message { get; private set; }
-
- ///
- /// Constructor
- ///
- /// CONNECT message received from client
- public MqttMsgConnectEventArgs(MqttMsgConnect connect)
- {
- this.Message = connect;
- }
- }
-}
diff --git a/mqtt/M2Mqtt/Messages/MqttMsgContext.cs b/mqtt/M2Mqtt/Messages/MqttMsgContext.cs
deleted file mode 100644
index a2850d7..0000000
--- a/mqtt/M2Mqtt/Messages/MqttMsgContext.cs
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
-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
-*/
-
-using System;
-using System.Text;
-
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
- ///
- /// Context for MQTT message
- ///
- public class MqttMsgContext
- {
- ///
- /// MQTT message
- ///
- public MqttMsgBase Message { get; set; }
-
- ///
- /// MQTT message state
- ///
- public MqttMsgState State { get; set; }
-
- ///
- /// Flow of the message
- ///
- public MqttMsgFlow Flow { get; set; }
-
- ///
- /// Timestamp in ticks (for retry)
- ///
- public int Timestamp { get; set; }
-
- ///
- /// Attempt (for retry)
- ///
- public int Attempt { get; set; }
-
- ///
- /// Unique key
- ///
- public string Key
- {
- get { return this.Flow + "_" + this.Message.MessageId; }
- }
- }
-
- ///
- /// Flow of the message
- ///
- public enum MqttMsgFlow
- {
- ///
- /// To publish to subscribers
- ///
- ToPublish,
-
- ///
- /// To acknowledge to publisher
- ///
- ToAcknowledge
- }
-
- ///
- /// MQTT message state
- ///
- public enum MqttMsgState
- {
- ///
- /// QOS = 0, Message queued
- ///
- QueuedQos0,
-
- ///
- /// QOS = 1, Message queued
- ///
- QueuedQos1,
-
- ///
- /// QOS = 2, Message queued
- ///
- QueuedQos2,
-
- ///
- /// QOS = 1, PUBLISH sent, wait for PUBACK
- ///
- WaitForPuback,
-
- ///
- /// QOS = 2, PUBLISH sent, wait for PUBREC
- ///
- WaitForPubrec,
-
- ///
- /// QOS = 2, PUBREC sent, wait for PUBREL
- ///
- WaitForPubrel,
-
- ///
- /// QOS = 2, PUBREL sent, wait for PUBCOMP
- ///
- WaitForPubcomp,
-
- ///
- /// QOS = 2, start first phase handshake send PUBREC
- ///
- SendPubrec,
-
- ///
- /// QOS = 2, start second phase handshake send PUBREL
- ///
- SendPubrel,
-
- ///
- /// QOS = 2, end second phase handshake send PUBCOMP
- ///
- SendPubcomp,
-
- ///
- /// QOS = 1, PUBLISH received, send PUBACK
- ///
- SendPuback,
-
- // [v3.1.1] SUBSCRIBE isn't "officially" QOS = 1
- ///
- /// Send SUBSCRIBE message
- ///
- SendSubscribe,
-
- // [v3.1.1] UNSUBSCRIBE isn't "officially" QOS = 1
- ///
- /// Send UNSUBSCRIBE message
- ///
- SendUnsubscribe,
-
- ///
- /// (QOS = 1), SUBSCRIBE sent, wait for SUBACK
- ///
- WaitForSuback,
-
- ///
- /// (QOS = 1), UNSUBSCRIBE sent, wait for UNSUBACK
- ///
- WaitForUnsuback
- }
-}
diff --git a/mqtt/M2Mqtt/Messages/MqttMsgDisconnect.cs b/mqtt/M2Mqtt/Messages/MqttMsgDisconnect.cs
deleted file mode 100644
index d918473..0000000
--- a/mqtt/M2Mqtt/Messages/MqttMsgDisconnect.cs
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
-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
-*/
-
-using uPLibrary.Networking.M2Mqtt.Exceptions;
-
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
- ///
- /// Class for DISCONNECT message from client to broker
- ///
- public class MqttMsgDisconnect : MqttMsgBase
- {
- ///
- /// Constructor
- ///
- public MqttMsgDisconnect()
- {
- this.type = MQTT_MSG_DISCONNECT_TYPE;
- }
-
- ///
- /// Parse bytes for a DISCONNECT message
- ///
- /// First fixed header byte
- /// Protocol Version
- /// Channel connected to the broker
- /// DISCONNECT message instance
- public static MqttMsgDisconnect Parse(byte fixedHeaderFirstByte, byte protocolVersion, IMqttNetworkChannel channel)
- {
- MqttMsgDisconnect msg = new MqttMsgDisconnect();
-
- if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1)
- {
- // [v3.1.1] check flag bits
- if ((fixedHeaderFirstByte & MSG_FLAG_BITS_MASK) != MQTT_MSG_DISCONNECT_FLAG_BITS)
- throw new MqttClientException(MqttClientErrorCode.InvalidFlagBits);
- }
-
- // get remaining length and allocate buffer
- int remainingLength = MqttMsgBase.decodeRemainingLength(channel);
- // NOTE : remainingLength must be 0
-
- return msg;
- }
-
- public override byte[] GetBytes(byte protocolVersion)
- {
- byte[] buffer = new byte[2];
- int index = 0;
-
- // first fixed header byte
- if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1)
- buffer[index++] = (MQTT_MSG_DISCONNECT_TYPE << MSG_TYPE_OFFSET) | MQTT_MSG_DISCONNECT_FLAG_BITS; // [v.3.1.1]
- else
- buffer[index++] = (MQTT_MSG_DISCONNECT_TYPE << MSG_TYPE_OFFSET);
- buffer[index++] = 0x00;
-
- return buffer;
- }
-
- public override string ToString()
- {
-#if TRACE
- return this.GetTraceString(
- "DISCONNECT",
- null,
- null);
-#else
- return base.ToString();
-#endif
- }
- }
-}
diff --git a/mqtt/M2Mqtt/Messages/MqttMsgPingReq.cs b/mqtt/M2Mqtt/Messages/MqttMsgPingReq.cs
deleted file mode 100644
index b46bdb6..0000000
--- a/mqtt/M2Mqtt/Messages/MqttMsgPingReq.cs
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
-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
-*/
-
-using uPLibrary.Networking.M2Mqtt.Exceptions;
-
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
- ///
- /// Class for PINGREQ message from client to broker
- ///
- public class MqttMsgPingReq : MqttMsgBase
- {
- ///
- /// Constructor
- ///
- public MqttMsgPingReq()
- {
- this.type = MQTT_MSG_PINGREQ_TYPE;
- }
-
- public override byte[] GetBytes(byte protocolVersion)
- {
- byte[] buffer = new byte[2];
- int index = 0;
-
- // first fixed header byte
- if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1)
- buffer[index++] = (MQTT_MSG_PINGREQ_TYPE << MSG_TYPE_OFFSET) | MQTT_MSG_PINGREQ_FLAG_BITS; // [v.3.1.1]
- else
- buffer[index++] = (MQTT_MSG_PINGREQ_TYPE << MSG_TYPE_OFFSET);
- buffer[index++] = 0x00;
-
- return buffer;
- }
-
- ///
- /// Parse bytes for a PINGREQ message
- ///
- /// First fixed header byte
- /// Protocol Version
- /// Channel connected to the broker
- /// PINGREQ message instance
- public static MqttMsgPingReq Parse(byte fixedHeaderFirstByte, byte protocolVersion, IMqttNetworkChannel channel)
- {
- MqttMsgPingReq msg = new MqttMsgPingReq();
-
- if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1)
- {
- // [v3.1.1] check flag bits
- if ((fixedHeaderFirstByte & MSG_FLAG_BITS_MASK) != MQTT_MSG_PINGREQ_FLAG_BITS)
- throw new MqttClientException(MqttClientErrorCode.InvalidFlagBits);
- }
-
- // already know remaininglength is zero (MQTT specification),
- // so it isn't necessary to read other data from socket
- int remainingLength = MqttMsgBase.decodeRemainingLength(channel);
-
- return msg;
- }
-
- public override string ToString()
- {
-#if TRACE
- return this.GetTraceString(
- "PINGREQ",
- null,
- null);
-#else
- return base.ToString();
-#endif
- }
- }
-}
diff --git a/mqtt/M2Mqtt/Messages/MqttMsgPingResp.cs b/mqtt/M2Mqtt/Messages/MqttMsgPingResp.cs
deleted file mode 100644
index 2b028b9..0000000
--- a/mqtt/M2Mqtt/Messages/MqttMsgPingResp.cs
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
-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
-*/
-
-using System;
-using uPLibrary.Networking.M2Mqtt.Exceptions;
-
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
- ///
- /// Class for PINGRESP message from client to broker
- ///
- public class MqttMsgPingResp : MqttMsgBase
- {
- ///
- /// Constructor
- ///
- public MqttMsgPingResp()
- {
- this.type = MQTT_MSG_PINGRESP_TYPE;
- }
-
- ///
- /// Parse bytes for a PINGRESP message
- ///
- /// First fixed header byte
- /// Protocol Version
- /// Channel connected to the broker
- /// PINGRESP message instance
- public static MqttMsgPingResp Parse(byte fixedHeaderFirstByte, byte protocolVersion, IMqttNetworkChannel channel)
- {
- MqttMsgPingResp msg = new MqttMsgPingResp();
-
- if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1)
- {
- // [v3.1.1] check flag bits
- if ((fixedHeaderFirstByte & MSG_FLAG_BITS_MASK) != MQTT_MSG_PINGRESP_FLAG_BITS)
- throw new MqttClientException(MqttClientErrorCode.InvalidFlagBits);
- }
-
- // already know remaininglength is zero (MQTT specification),
- // so it isn't necessary to read other data from socket
- int remainingLength = MqttMsgBase.decodeRemainingLength(channel);
-
- return msg;
- }
-
- public override byte[] GetBytes(byte protocolVersion)
- {
- byte[] buffer = new byte[2];
- int index = 0;
-
- // first fixed header byte
- if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1)
- buffer[index++] = (MQTT_MSG_PINGRESP_TYPE << MSG_TYPE_OFFSET) | MQTT_MSG_PINGRESP_FLAG_BITS; // [v.3.1.1]
- else
- buffer[index++] = (MQTT_MSG_PINGRESP_TYPE << MSG_TYPE_OFFSET);
- buffer[index++] = 0x00;
-
- return buffer;
- }
-
- public override string ToString()
- {
-#if TRACE
- return this.GetTraceString(
- "PINGRESP",
- null,
- null);
-#else
- return base.ToString();
-#endif
- }
- }
-}
diff --git a/mqtt/M2Mqtt/Messages/MqttMsgPuback.cs b/mqtt/M2Mqtt/Messages/MqttMsgPuback.cs
deleted file mode 100644
index e00e37f..0000000
--- a/mqtt/M2Mqtt/Messages/MqttMsgPuback.cs
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
-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
-*/
-
-using uPLibrary.Networking.M2Mqtt.Exceptions;
-
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
- ///
- /// Class for PUBACK message from broker to client
- ///
- public class MqttMsgPuback : MqttMsgBase
- {
- ///
- /// Constructor
- ///
- public MqttMsgPuback()
- {
- this.type = MQTT_MSG_PUBACK_TYPE;
- }
-
- public override byte[] GetBytes(byte protocolVersion)
- {
- int fixedHeaderSize = 0;
- int varHeaderSize = 0;
- int payloadSize = 0;
- int remainingLength = 0;
- byte[] buffer;
- int index = 0;
-
- // message identifier
- varHeaderSize += MESSAGE_ID_SIZE;
-
- remainingLength += (varHeaderSize + payloadSize);
-
- // first byte of fixed header
- fixedHeaderSize = 1;
-
- int temp = remainingLength;
- // increase fixed header size based on remaining length
- // (each remaining length byte can encode until 128)
- do
- {
- fixedHeaderSize++;
- temp = temp / 128;
- } while (temp > 0);
-
- // allocate buffer for message
- buffer = new byte[fixedHeaderSize + varHeaderSize + payloadSize];
-
- // first fixed header byte
- if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1)
- buffer[index++] = (MQTT_MSG_PUBACK_TYPE << MSG_TYPE_OFFSET) | MQTT_MSG_PUBACK_FLAG_BITS; // [v.3.1.1]
- else
- buffer[index++] = (MQTT_MSG_PUBACK_TYPE << MSG_TYPE_OFFSET);
-
- // encode remaining length
- index = this.encodeRemainingLength(remainingLength, buffer, index);
-
- // get message identifier
- buffer[index++] = (byte)((this.messageId >> 8) & 0x00FF); // MSB
- buffer[index++] = (byte)(this.messageId & 0x00FF); // LSB
-
- return buffer;
- }
-
- ///
- /// Parse bytes for a PUBACK message
- ///
- /// First fixed header byte
- /// Protocol Version
- /// Channel connected to the broker
- /// PUBACK message instance
- public static MqttMsgPuback Parse(byte fixedHeaderFirstByte, byte protocolVersion, IMqttNetworkChannel channel)
- {
- byte[] buffer;
- int index = 0;
- MqttMsgPuback msg = new MqttMsgPuback();
-
- if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1)
- {
- // [v3.1.1] check flag bits
- if ((fixedHeaderFirstByte & MSG_FLAG_BITS_MASK) != MQTT_MSG_PUBACK_FLAG_BITS)
- throw new MqttClientException(MqttClientErrorCode.InvalidFlagBits);
- }
-
- // get remaining length and allocate buffer
- int remainingLength = MqttMsgBase.decodeRemainingLength(channel);
- buffer = new byte[remainingLength];
-
- // read bytes from socket...
- channel.Receive(buffer);
-
- // message id
- msg.messageId = (ushort)((buffer[index++] << 8) & 0xFF00);
- msg.messageId |= (buffer[index++]);
-
- return msg;
- }
-
- public override string ToString()
- {
-#if TRACE
- return this.GetTraceString(
- "PUBACK",
- new object[] { "messageId" },
- new object[] { this.messageId });
-#else
- return base.ToString();
-#endif
- }
- }
-}
diff --git a/mqtt/M2Mqtt/Messages/MqttMsgPubcomp.cs b/mqtt/M2Mqtt/Messages/MqttMsgPubcomp.cs
deleted file mode 100644
index eeabd3b..0000000
--- a/mqtt/M2Mqtt/Messages/MqttMsgPubcomp.cs
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
-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
-*/
-
-using uPLibrary.Networking.M2Mqtt.Exceptions;
-
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
- ///
- /// Class for PUBCOMP message from broker to client
- ///
- public class MqttMsgPubcomp : MqttMsgBase
- {
- ///
- /// Constructor
- ///
- public MqttMsgPubcomp()
- {
- this.type = MQTT_MSG_PUBCOMP_TYPE;
- }
-
- public override byte[] GetBytes(byte protocolVersion)
- {
- int fixedHeaderSize = 0;
- int varHeaderSize = 0;
- int payloadSize = 0;
- int remainingLength = 0;
- byte[] buffer;
- int index = 0;
-
- // message identifier
- varHeaderSize += MESSAGE_ID_SIZE;
-
- remainingLength += (varHeaderSize + payloadSize);
-
- // first byte of fixed header
- fixedHeaderSize = 1;
-
- int temp = remainingLength;
- // increase fixed header size based on remaining length
- // (each remaining length byte can encode until 128)
- do
- {
- fixedHeaderSize++;
- temp = temp / 128;
- } while (temp > 0);
-
- // allocate buffer for message
- buffer = new byte[fixedHeaderSize + varHeaderSize + payloadSize];
-
- // first fixed header byte
- if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1)
- buffer[index++] = (MQTT_MSG_PUBCOMP_TYPE << MSG_TYPE_OFFSET) | MQTT_MSG_PUBCOMP_FLAG_BITS; // [v.3.1.1]
- else
- buffer[index++] = (MQTT_MSG_PUBCOMP_TYPE << MSG_TYPE_OFFSET);
-
- // encode remaining length
- index = this.encodeRemainingLength(remainingLength, buffer, index);
-
- // get message identifier
- buffer[index++] = (byte)((this.messageId >> 8) & 0x00FF); // MSB
- buffer[index++] = (byte)(this.messageId & 0x00FF); // LSB
-
- return buffer;
- }
-
- ///
- /// Parse bytes for a PUBCOMP message
- ///
- /// First fixed header byte
- /// Protocol Version
- /// Channel connected to the broker
- /// PUBCOMP message instance
- public static MqttMsgPubcomp Parse(byte fixedHeaderFirstByte, byte protocolVersion, IMqttNetworkChannel channel)
- {
- byte[] buffer;
- int index = 0;
- MqttMsgPubcomp msg = new MqttMsgPubcomp();
-
- if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1)
- {
- // [v3.1.1] check flag bits
- if ((fixedHeaderFirstByte & MSG_FLAG_BITS_MASK) != MQTT_MSG_PUBCOMP_FLAG_BITS)
- throw new MqttClientException(MqttClientErrorCode.InvalidFlagBits);
- }
-
- // get remaining length and allocate buffer
- int remainingLength = MqttMsgBase.decodeRemainingLength(channel);
- buffer = new byte[remainingLength];
-
- // read bytes from socket...
- channel.Receive(buffer);
-
- // message id
- msg.messageId = (ushort)((buffer[index++] << 8) & 0xFF00);
- msg.messageId |= (buffer[index++]);
-
- return msg;
- }
-
- public override string ToString()
- {
-#if TRACE
- return this.GetTraceString(
- "PUBCOMP",
- new object[] { "messageId" },
- new object[] { this.messageId });
-#else
- return base.ToString();
-#endif
- }
- }
-}
diff --git a/mqtt/M2Mqtt/Messages/MqttMsgPublish.cs b/mqtt/M2Mqtt/Messages/MqttMsgPublish.cs
deleted file mode 100644
index 0809af9..0000000
--- a/mqtt/M2Mqtt/Messages/MqttMsgPublish.cs
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
-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
-*/
-
-using System;
-using System.Text;
-using uPLibrary.Networking.M2Mqtt.Exceptions;
-
-namespace uPLibrary.Networking.M2Mqtt.Messages {
- ///
- /// Class for PUBLISH message from client to broker
- ///
- public class MqttMsgPublish : MqttMsgBase {
- #region Properties...
-
- ///
- /// Message topic
- ///
- public String Topic { get; set; }
-
- ///
- /// Message data
- ///
- public Byte[] Message { get; set; }
-
- #endregion
-
- ///
- /// Constructor
- ///
- public MqttMsgPublish() {
- this.type = MQTT_MSG_PUBLISH_TYPE;
- }
-
- ///
- /// Constructor
- ///
- /// Message topic
- /// Message data
- public MqttMsgPublish(String topic, Byte[] message) : this(topic, message, false, QOS_LEVEL_AT_MOST_ONCE, false) {
- }
-
- ///
- /// Constructor
- ///
- /// Message topic
- /// Message data
- /// Duplicate flag
- /// Quality of Service level
- /// Retain flag
- public MqttMsgPublish(String topic, Byte[] message, Boolean dupFlag, Byte qosLevel, Boolean retain) : base() {
- this.type = MQTT_MSG_PUBLISH_TYPE;
- this.Topic = topic;
- this.Message = message;
- this.dupFlag = dupFlag;
- this.qosLevel = qosLevel;
- this.retain = retain;
- this.messageId = 0;
- }
-
- public override Byte[] GetBytes(Byte protocolVersion) {
- Int32 fixedHeaderSize = 0;
- Int32 varHeaderSize = 0;
- Int32 payloadSize = 0;
- Int32 remainingLength = 0;
- Byte[] buffer;
- Int32 index = 0;
-
- // topic can't contain wildcards
- if ((this.Topic.IndexOf('#') != -1) || (this.Topic.IndexOf('+') != -1)) {
- throw new MqttClientException(MqttClientErrorCode.TopicWildcard);
- }
-
- // check topic length
- if ((this.Topic.Length < MIN_TOPIC_LENGTH) || (this.Topic.Length > MAX_TOPIC_LENGTH)) {
- throw new MqttClientException(MqttClientErrorCode.TopicLength);
- }
-
- // check wrong QoS level (both bits can't be set 1)
- if (this.qosLevel > QOS_LEVEL_EXACTLY_ONCE) {
- throw new MqttClientException(MqttClientErrorCode.QosNotAllowed);
- }
-
- Byte[] topicUtf8 = Encoding.UTF8.GetBytes(this.Topic);
-
- // topic name
- varHeaderSize += topicUtf8.Length + 2;
-
- // message id is valid only with QOS level 1 or QOS level 2
- if ((this.qosLevel == QOS_LEVEL_AT_LEAST_ONCE) || (this.qosLevel == QOS_LEVEL_EXACTLY_ONCE)) {
- varHeaderSize += MESSAGE_ID_SIZE;
- }
-
- // check on message with zero length
- if (this.Message != null) {
- // message data
- payloadSize += this.Message.Length;
- }
-
- remainingLength += (varHeaderSize + payloadSize);
-
- // first byte of fixed header
- fixedHeaderSize = 1;
-
- Int32 temp = remainingLength;
- // increase fixed header size based on remaining length
- // (each remaining length byte can encode until 128)
- do {
- fixedHeaderSize++;
- temp = temp / 128;
- } while (temp > 0);
-
- // allocate buffer for message
- buffer = new Byte[fixedHeaderSize + varHeaderSize + payloadSize];
-
- // first fixed header byte
- buffer[index] = (Byte)((MQTT_MSG_PUBLISH_TYPE << MSG_TYPE_OFFSET) | (this.qosLevel << QOS_LEVEL_OFFSET));
- buffer[index] |= this.dupFlag ? (Byte)(1 << DUP_FLAG_OFFSET) : (Byte)0x00;
- buffer[index] |= this.retain ? (Byte)(1 << RETAIN_FLAG_OFFSET) : (Byte)0x00;
- index++;
-
- // encode remaining length
- index = this.encodeRemainingLength(remainingLength, buffer, index);
-
- // topic name
- buffer[index++] = (Byte)((topicUtf8.Length >> 8) & 0x00FF); // MSB
- buffer[index++] = (Byte)(topicUtf8.Length & 0x00FF); // LSB
- Array.Copy(topicUtf8, 0, buffer, index, topicUtf8.Length);
- index += topicUtf8.Length;
-
- // message id is valid only with QOS level 1 or QOS level 2
- if ((this.qosLevel == QOS_LEVEL_AT_LEAST_ONCE) ||
- (this.qosLevel == QOS_LEVEL_EXACTLY_ONCE)) {
- // check message identifier assigned
- if (this.messageId == 0) {
- throw new MqttClientException(MqttClientErrorCode.WrongMessageId);
- }
-
- buffer[index++] = (Byte)((this.messageId >> 8) & 0x00FF); // MSB
- buffer[index++] = (Byte)(this.messageId & 0x00FF); // LSB
- }
-
- // check on message with zero length
- if (this.Message != null) {
- // message data
- Array.Copy(this.Message, 0, buffer, index, this.Message.Length);
- index += this.Message.Length;
- }
-
- return buffer;
- }
-
- ///
- /// Parse bytes for a PUBLISH message
- ///
- /// First fixed header byte
- /// Protocol Version
- /// Channel connected to the broker
- /// PUBLISH message instance
- public static MqttMsgPublish Parse(Byte fixedHeaderFirstByte, Byte protocolVersion, IMqttNetworkChannel channel) {
- Byte[] buffer;
- Int32 index = 0;
- Byte[] topicUtf8;
- Int32 topicUtf8Length;
- MqttMsgPublish msg = new MqttMsgPublish();
-
- // get remaining length and allocate buffer
- Int32 remainingLength = decodeRemainingLength(channel);
- buffer = new Byte[remainingLength];
-
- // read bytes from socket...
- Int32 received = channel.Receive(buffer);
-
- // topic name
- topicUtf8Length = ((buffer[index++] << 8) & 0xFF00);
- topicUtf8Length |= buffer[index++];
- topicUtf8 = new Byte[topicUtf8Length];
- Array.Copy(buffer, index, topicUtf8, 0, topicUtf8Length);
- index += topicUtf8Length;
- msg.Topic = new String(Encoding.UTF8.GetChars(topicUtf8));
-
- // read QoS level from fixed header
- msg.qosLevel = (Byte)((fixedHeaderFirstByte & QOS_LEVEL_MASK) >> QOS_LEVEL_OFFSET);
- // check wrong QoS level (both bits can't be set 1)
- if (msg.qosLevel > QOS_LEVEL_EXACTLY_ONCE) {
- throw new MqttClientException(MqttClientErrorCode.QosNotAllowed);
- }
- // read DUP flag from fixed header
- msg.dupFlag = (((fixedHeaderFirstByte & DUP_FLAG_MASK) >> DUP_FLAG_OFFSET) == 0x01);
- // read retain flag from fixed header
- msg.retain = (((fixedHeaderFirstByte & RETAIN_FLAG_MASK) >> RETAIN_FLAG_OFFSET) == 0x01);
-
- // message id is valid only with QOS level 1 or QOS level 2
- if ((msg.qosLevel == QOS_LEVEL_AT_LEAST_ONCE) ||
- (msg.qosLevel == QOS_LEVEL_EXACTLY_ONCE)) {
- // message id
- msg.messageId = (UInt16)((buffer[index++] << 8) & 0xFF00);
- msg.messageId |= (buffer[index++]);
- }
-
- // get payload with message data
- Int32 messageSize = remainingLength - index;
- Int32 remaining = messageSize;
- Int32 messageOffset = 0;
- msg.Message = new Byte[messageSize];
-
- // BUG FIX 26/07/2013 : receiving large payload
-
- // copy first part of payload data received
- Array.Copy(buffer, index, msg.Message, messageOffset, received - index);
- remaining -= (received - index);
- messageOffset += (received - index);
-
- // if payload isn't finished
- while (remaining > 0) {
- // receive other payload data
- received = channel.Receive(buffer);
- Array.Copy(buffer, 0, msg.Message, messageOffset, received);
- remaining -= received;
- messageOffset += received;
- }
-
- return msg;
- }
-
- public override String ToString() {
-#if TRACE
- return this.GetTraceString(
- "PUBLISH",
- new Object[] { "messageId", "topic", "message" },
- new Object[] { this.messageId, this.Topic, this.Message });
-#else
- return base.ToString();
-#endif
- }
- }
-}
diff --git a/mqtt/M2Mqtt/Messages/MqttMsgPublishEventArgs.cs b/mqtt/M2Mqtt/Messages/MqttMsgPublishEventArgs.cs
deleted file mode 100644
index efb2333..0000000
--- a/mqtt/M2Mqtt/Messages/MqttMsgPublishEventArgs.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
-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 (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3)
-using System;
-#else
-using Microsoft.SPOT;
-#endif
-
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
- ///
- /// Event Args class for PUBLISH message received from broker
- ///
- public class MqttMsgPublishEventArgs : EventArgs
- {
- #region Properties...
-
- ///
- /// Message topic
- ///
- public string Topic
- {
- get { return this.topic; }
- internal set { this.topic = value; }
- }
-
- ///
- /// Message data
- ///
- public byte[] Message
- {
- get { return this.message; }
- internal set { this.message = value; }
- }
-
- ///
- /// Duplicate message flag
- ///
- public bool DupFlag
- {
- get { return this.dupFlag; }
- set { this.dupFlag = value; }
- }
-
- ///
- /// Quality of Service level
- ///
- public byte QosLevel
- {
- get { return this.qosLevel; }
- internal set { this.qosLevel = value; }
- }
-
- ///
- /// Retain message flag
- ///
- public bool Retain
- {
- get { return this.retain; }
- internal set { this.retain = value; }
- }
-
- #endregion
-
- // message topic
- private string topic;
- // message data
- private byte[] message;
- // duplicate delivery
- private bool dupFlag;
- // quality of service level
- private byte qosLevel;
- // retain flag
- private bool retain;
-
- ///
- /// Constructor
- ///
- /// Message topic
- /// Message data
- /// Duplicate delivery flag
- /// Quality of Service level
- /// Retain flag
- public MqttMsgPublishEventArgs(string topic,
- byte[] message,
- bool dupFlag,
- byte qosLevel,
- bool retain)
- {
- this.topic = topic;
- this.message = message;
- this.dupFlag = dupFlag;
- this.qosLevel = qosLevel;
- this.retain = retain;
- }
- }
-}
diff --git a/mqtt/M2Mqtt/Messages/MqttMsgPublishedEventArgs.cs b/mqtt/M2Mqtt/Messages/MqttMsgPublishedEventArgs.cs
deleted file mode 100644
index e507c38..0000000
--- a/mqtt/M2Mqtt/Messages/MqttMsgPublishedEventArgs.cs
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
-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 (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3)
-using System;
-#else
-using Microsoft.SPOT;
-#endif
-
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
- ///
- /// Event Args class for published message
- ///
- public class MqttMsgPublishedEventArgs : EventArgs
- {
- #region Properties...
-
- ///
- /// Message identifier
- ///
- public ushort MessageId
- {
- get { return this.messageId; }
- internal set { this.messageId = value; }
- }
-
- ///
- /// Message published (or failed due to retries)
- ///
- public bool IsPublished
- {
- get { return this.isPublished; }
- internal set { this.isPublished = value; }
- }
-
- #endregion
-
- // message identifier
- ushort messageId;
-
- // published flag
- bool isPublished;
-
- ///
- /// Constructor (published message)
- ///
- /// Message identifier published
- public MqttMsgPublishedEventArgs(ushort messageId)
- : this(messageId, true)
- {
- }
-
- ///
- /// Constructor
- ///
- /// Message identifier
- /// Publish flag
- public MqttMsgPublishedEventArgs(ushort messageId, bool isPublished)
- {
- this.messageId = messageId;
- this.isPublished = isPublished;
- }
- }
-}
diff --git a/mqtt/M2Mqtt/Messages/MqttMsgPubrec.cs b/mqtt/M2Mqtt/Messages/MqttMsgPubrec.cs
deleted file mode 100644
index 1855bf9..0000000
--- a/mqtt/M2Mqtt/Messages/MqttMsgPubrec.cs
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
-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
-*/
-
-using uPLibrary.Networking.M2Mqtt.Exceptions;
-
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
- ///
- /// Class for PUBREC message from broker to client
- ///
- public class MqttMsgPubrec : MqttMsgBase
- {
- ///
- /// Constructor
- ///
- public MqttMsgPubrec()
- {
- this.type = MQTT_MSG_PUBREC_TYPE;
- }
-
- public override byte[] GetBytes(byte protocolVersion)
- {
- int fixedHeaderSize = 0;
- int varHeaderSize = 0;
- int payloadSize = 0;
- int remainingLength = 0;
- byte[] buffer;
- int index = 0;
-
- // message identifier
- varHeaderSize += MESSAGE_ID_SIZE;
-
- remainingLength += (varHeaderSize + payloadSize);
-
- // first byte of fixed header
- fixedHeaderSize = 1;
-
- int temp = remainingLength;
- // increase fixed header size based on remaining length
- // (each remaining length byte can encode until 128)
- do
- {
- fixedHeaderSize++;
- temp = temp / 128;
- } while (temp > 0);
-
- // allocate buffer for message
- buffer = new byte[fixedHeaderSize + varHeaderSize + payloadSize];
-
- // first fixed header byte
- if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1)
- buffer[index++] = (MQTT_MSG_PUBREC_TYPE << MSG_TYPE_OFFSET) | MQTT_MSG_PUBREC_FLAG_BITS; // [v.3.1.1]
- else
- buffer[index++] = (MQTT_MSG_PUBREC_TYPE << MSG_TYPE_OFFSET);
-
- // encode remaining length
- index = this.encodeRemainingLength(remainingLength, buffer, index);
-
- // get message identifier
- buffer[index++] = (byte)((this.messageId >> 8) & 0x00FF); // MSB
- buffer[index++] = (byte)(this.messageId & 0x00FF); // LSB
-
- return buffer;
- }
-
- ///
- /// Parse bytes for a PUBREC message
- ///
- /// First fixed header byte
- /// Protocol Version
- /// Channel connected to the broker
- /// PUBREC message instance
- public static MqttMsgPubrec Parse(byte fixedHeaderFirstByte, byte protocolVersion, IMqttNetworkChannel channel)
- {
- byte[] buffer;
- int index = 0;
- MqttMsgPubrec msg = new MqttMsgPubrec();
-
- if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1)
- {
- // [v3.1.1] check flag bits
- if ((fixedHeaderFirstByte & MSG_FLAG_BITS_MASK) != MQTT_MSG_PUBREC_FLAG_BITS)
- throw new MqttClientException(MqttClientErrorCode.InvalidFlagBits);
- }
-
- // get remaining length and allocate buffer
- int remainingLength = MqttMsgBase.decodeRemainingLength(channel);
- buffer = new byte[remainingLength];
-
- // read bytes from socket...
- channel.Receive(buffer);
-
- // message id
- msg.messageId = (ushort)((buffer[index++] << 8) & 0xFF00);
- msg.messageId |= (buffer[index++]);
-
- return msg;
- }
-
- public override string ToString()
- {
-#if TRACE
- return this.GetTraceString(
- "PUBREC",
- new object[] { "messageId" },
- new object[] { this.messageId });
-#else
- return base.ToString();
-#endif
- }
- }
-}
diff --git a/mqtt/M2Mqtt/Messages/MqttMsgPubrel.cs b/mqtt/M2Mqtt/Messages/MqttMsgPubrel.cs
deleted file mode 100644
index e43ca91..0000000
--- a/mqtt/M2Mqtt/Messages/MqttMsgPubrel.cs
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
-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
-*/
-
-using uPLibrary.Networking.M2Mqtt.Exceptions;
-
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
- ///
- /// Class for PUBREL message from client top broker
- ///
- public class MqttMsgPubrel : MqttMsgBase
- {
- ///
- /// Constructor
- ///
- public MqttMsgPubrel()
- {
- this.type = MQTT_MSG_PUBREL_TYPE;
- // PUBREL message use QoS Level 1 (not "officially" in 3.1.1)
- this.qosLevel = QOS_LEVEL_AT_LEAST_ONCE;
- }
-
- public override byte[] GetBytes(byte protocolVersion)
- {
- int fixedHeaderSize = 0;
- int varHeaderSize = 0;
- int payloadSize = 0;
- int remainingLength = 0;
- byte[] buffer;
- int index = 0;
-
- // message identifier
- varHeaderSize += MESSAGE_ID_SIZE;
-
- remainingLength += (varHeaderSize + payloadSize);
-
- // first byte of fixed header
- fixedHeaderSize = 1;
-
- int temp = remainingLength;
- // increase fixed header size based on remaining length
- // (each remaining length byte can encode until 128)
- do
- {
- fixedHeaderSize++;
- temp = temp / 128;
- } while (temp > 0);
-
- // allocate buffer for message
- buffer = new byte[fixedHeaderSize + varHeaderSize + payloadSize];
-
- // first fixed header byte
- if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1)
- buffer[index++] = (MQTT_MSG_PUBREL_TYPE << MSG_TYPE_OFFSET) | MQTT_MSG_PUBREL_FLAG_BITS; // [v.3.1.1]
- else
- {
- buffer[index] = (byte)((MQTT_MSG_PUBREL_TYPE << MSG_TYPE_OFFSET) |
- (this.qosLevel << QOS_LEVEL_OFFSET));
- buffer[index] |= this.dupFlag ? (byte)(1 << DUP_FLAG_OFFSET) : (byte)0x00;
- index++;
- }
-
- // encode remaining length
- index = this.encodeRemainingLength(remainingLength, buffer, index);
-
- // get next message identifier
- buffer[index++] = (byte)((this.messageId >> 8) & 0x00FF); // MSB
- buffer[index++] = (byte)(this.messageId & 0x00FF); // LSB
-
- return buffer;
- }
-
- ///
- /// Parse bytes for a PUBREL message
- ///
- /// First fixed header byte
- /// Protocol Version
- /// Channel connected to the broker
- /// PUBREL message instance
- public static MqttMsgPubrel Parse(byte fixedHeaderFirstByte, byte protocolVersion, IMqttNetworkChannel channel)
- {
- byte[] buffer;
- int index = 0;
- MqttMsgPubrel msg = new MqttMsgPubrel();
-
- if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1)
- {
- // [v3.1.1] check flag bits
- if ((fixedHeaderFirstByte & MSG_FLAG_BITS_MASK) != MQTT_MSG_PUBREL_FLAG_BITS)
- throw new MqttClientException(MqttClientErrorCode.InvalidFlagBits);
- }
-
- // get remaining length and allocate buffer
- int remainingLength = MqttMsgBase.decodeRemainingLength(channel);
- buffer = new byte[remainingLength];
-
- // read bytes from socket...
- channel.Receive(buffer);
-
- if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1)
- {
- // only 3.1.0
-
- // read QoS level from fixed header (would be QoS Level 1)
- msg.qosLevel = (byte)((fixedHeaderFirstByte & QOS_LEVEL_MASK) >> QOS_LEVEL_OFFSET);
- // read DUP flag from fixed header
- msg.dupFlag = (((fixedHeaderFirstByte & DUP_FLAG_MASK) >> DUP_FLAG_OFFSET) == 0x01);
- }
-
- // message id
- msg.messageId = (ushort)((buffer[index++] << 8) & 0xFF00);
- msg.messageId |= (buffer[index++]);
-
- return msg;
- }
-
- public override string ToString()
- {
-#if TRACE
- return this.GetTraceString(
- "PUBREL",
- new object[] { "messageId" },
- new object[] { this.messageId });
-#else
- return base.ToString();
-#endif
- }
- }
-}
diff --git a/mqtt/M2Mqtt/Messages/MqttMsgSuback.cs b/mqtt/M2Mqtt/Messages/MqttMsgSuback.cs
deleted file mode 100644
index 6ecfd0d..0000000
--- a/mqtt/M2Mqtt/Messages/MqttMsgSuback.cs
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
-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
-*/
-
-using System;
-using uPLibrary.Networking.M2Mqtt.Exceptions;
-
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
- ///
- /// Class for SUBACK message from broker to client
- ///
- public class MqttMsgSuback : MqttMsgBase
- {
- #region Properties...
-
- ///
- /// List of granted QOS Levels
- ///
- public byte[] GrantedQoSLevels
- {
- get { return this.grantedQosLevels; }
- set { this.grantedQosLevels = value; }
- }
-
- #endregion
-
- // granted QOS levels
- byte[] grantedQosLevels;
-
- ///
- /// Constructor
- ///
- public MqttMsgSuback()
- {
- this.type = MQTT_MSG_SUBACK_TYPE;
- }
-
- ///
- /// Parse bytes for a SUBACK message
- ///
- /// First fixed header byte
- /// Protocol Version
- /// Channel connected to the broker
- /// SUBACK message instance
- public static MqttMsgSuback Parse(byte fixedHeaderFirstByte, byte protocolVersion, IMqttNetworkChannel channel)
- {
- byte[] buffer;
- int index = 0;
- MqttMsgSuback msg = new MqttMsgSuback();
-
- if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1)
- {
- // [v3.1.1] check flag bits
- if ((fixedHeaderFirstByte & MSG_FLAG_BITS_MASK) != MQTT_MSG_SUBACK_FLAG_BITS)
- throw new MqttClientException(MqttClientErrorCode.InvalidFlagBits);
- }
-
- // get remaining length and allocate buffer
- int remainingLength = MqttMsgBase.decodeRemainingLength(channel);
- buffer = new byte[remainingLength];
-
- // read bytes from socket...
- channel.Receive(buffer);
-
- // message id
- msg.messageId = (ushort)((buffer[index++] << 8) & 0xFF00);
- msg.messageId |= (buffer[index++]);
-
- // payload contains QoS levels granted
- msg.grantedQosLevels = new byte[remainingLength - MESSAGE_ID_SIZE];
- int qosIdx = 0;
- do
- {
- msg.grantedQosLevels[qosIdx++] = buffer[index++];
- } while (index < remainingLength);
-
- return msg;
- }
-
- public override byte[] GetBytes(byte protocolVersion)
- {
- int fixedHeaderSize = 0;
- int varHeaderSize = 0;
- int payloadSize = 0;
- int remainingLength = 0;
- byte[] buffer;
- int index = 0;
-
- // message identifier
- varHeaderSize += MESSAGE_ID_SIZE;
-
- int grantedQosIdx = 0;
- for (grantedQosIdx = 0; grantedQosIdx < this.grantedQosLevels.Length; grantedQosIdx++)
- {
- payloadSize++;
- }
-
- remainingLength += (varHeaderSize + payloadSize);
-
- // first byte of fixed header
- fixedHeaderSize = 1;
-
- int temp = remainingLength;
- // increase fixed header size based on remaining length
- // (each remaining length byte can encode until 128)
- do
- {
- fixedHeaderSize++;
- temp = temp / 128;
- } while (temp > 0);
-
- // allocate buffer for message
- buffer = new byte[fixedHeaderSize + varHeaderSize + payloadSize];
-
- // first fixed header byte
- if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1)
- buffer[index++] = (MQTT_MSG_SUBACK_TYPE << MSG_TYPE_OFFSET) | MQTT_MSG_SUBACK_FLAG_BITS; // [v.3.1.1]
- else
- buffer[index++] = (byte)(MQTT_MSG_SUBACK_TYPE << MSG_TYPE_OFFSET);
-
- // encode remaining length
- index = this.encodeRemainingLength(remainingLength, buffer, index);
-
- // message id
- buffer[index++] = (byte)((this.messageId >> 8) & 0x00FF); // MSB
- buffer[index++] = (byte)(this.messageId & 0x00FF); // LSB
-
- // payload contains QoS levels granted
- for (grantedQosIdx = 0; grantedQosIdx < this.grantedQosLevels.Length; grantedQosIdx++)
- {
- buffer[index++] = this.grantedQosLevels[grantedQosIdx];
- }
-
- return buffer;
- }
-
- public override string ToString()
- {
-#if TRACE
- return this.GetTraceString(
- "SUBACK",
- new object[] { "messageId", "grantedQosLevels" },
- new object[] { this.messageId, this.grantedQosLevels });
-#else
- return base.ToString();
-#endif
- }
- }
-}
diff --git a/mqtt/M2Mqtt/Messages/MqttMsgSubscribe.cs b/mqtt/M2Mqtt/Messages/MqttMsgSubscribe.cs
deleted file mode 100644
index 0e3927e..0000000
--- a/mqtt/M2Mqtt/Messages/MqttMsgSubscribe.cs
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
-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
-*/
-
-using System;
-// if NOT .Net Micro Framework
-#if (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3)
-using System.Collections.Generic;
-#endif
-using System.Collections;
-using System.Text;
-using uPLibrary.Networking.M2Mqtt.Exceptions;
-
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
- ///
- /// Class for SUBSCRIBE message from client to broker
- ///
- public class MqttMsgSubscribe : MqttMsgBase
- {
- #region Properties...
-
- ///
- /// List of topics to subscribe
- ///
- public string[] Topics
- {
- get { return this.topics; }
- set { this.topics = value; }
- }
-
- ///
- /// List of QOS Levels related to topics
- ///
- public byte[] QoSLevels
- {
- get { return this.qosLevels; }
- set { this.qosLevels = value; }
- }
-
- #endregion
-
- // topics to subscribe
- string[] topics;
- // QOS levels related to topics
- byte[] qosLevels;
-
- ///
- /// Constructor
- ///
- public MqttMsgSubscribe()
- {
- this.type = MQTT_MSG_SUBSCRIBE_TYPE;
- }
-
- ///
- /// Constructor
- ///
- /// List of topics to subscribe
- /// List of QOS Levels related to topics
- public MqttMsgSubscribe(string[] topics, byte[] qosLevels)
- {
- this.type = MQTT_MSG_SUBSCRIBE_TYPE;
-
- this.topics = topics;
- this.qosLevels = qosLevels;
-
- // SUBSCRIBE message uses QoS Level 1 (not "officially" in 3.1.1)
- this.qosLevel = QOS_LEVEL_AT_LEAST_ONCE;
- }
-
- ///
- /// Parse bytes for a SUBSCRIBE message
- ///
- /// First fixed header byte
- /// Protocol Version
- /// Channel connected to the broker
- /// SUBSCRIBE message instance
- public static MqttMsgSubscribe Parse(byte fixedHeaderFirstByte, byte protocolVersion, IMqttNetworkChannel channel)
- {
- byte[] buffer;
- int index = 0;
- byte[] topicUtf8;
- int topicUtf8Length;
- MqttMsgSubscribe msg = new MqttMsgSubscribe();
-
- if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1)
- {
- // [v3.1.1] check flag bits
- if ((fixedHeaderFirstByte & MSG_FLAG_BITS_MASK) != MQTT_MSG_SUBSCRIBE_FLAG_BITS)
- throw new MqttClientException(MqttClientErrorCode.InvalidFlagBits);
- }
-
- // get remaining length and allocate buffer
- int remainingLength = MqttMsgBase.decodeRemainingLength(channel);
- buffer = new byte[remainingLength];
-
- // read bytes from socket...
- int received = channel.Receive(buffer);
-
- if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1)
- {
- // only 3.1.0
-
- // read QoS level from fixed header
- msg.qosLevel = (byte)((fixedHeaderFirstByte & QOS_LEVEL_MASK) >> QOS_LEVEL_OFFSET);
- // read DUP flag from fixed header
- msg.dupFlag = (((fixedHeaderFirstByte & DUP_FLAG_MASK) >> DUP_FLAG_OFFSET) == 0x01);
- // retain flag not used
- msg.retain = false;
- }
-
- // message id
- msg.messageId = (ushort)((buffer[index++] << 8) & 0xFF00);
- msg.messageId |= (buffer[index++]);
-
- // payload contains topics and QoS levels
- // NOTE : before, I don't know how many topics will be in the payload (so use List)
-
-// if .Net Micro Framework
-#if (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3)
- IList tmpTopics = new ArrayList();
- IList tmpQosLevels = new ArrayList();
-// else other frameworks (.Net, .Net Compact, Mono, Windows Phone)
-#else
- IList tmpTopics = new List();
- IList tmpQosLevels = new List();
-#endif
- do
- {
- // topic name
- topicUtf8Length = ((buffer[index++] << 8) & 0xFF00);
- topicUtf8Length |= buffer[index++];
- topicUtf8 = new byte[topicUtf8Length];
- Array.Copy(buffer, index, topicUtf8, 0, topicUtf8Length);
- index += topicUtf8Length;
- tmpTopics.Add(new String(Encoding.UTF8.GetChars(topicUtf8)));
-
- // QoS level
- tmpQosLevels.Add(buffer[index++]);
-
- } while (index < remainingLength);
-
- // copy from list to array
- msg.topics = new string[tmpTopics.Count];
- msg.qosLevels = new byte[tmpQosLevels.Count];
- for (int i = 0; i < tmpTopics.Count; i++)
- {
- msg.topics[i] = (string)tmpTopics[i];
- msg.qosLevels[i] = (byte)tmpQosLevels[i];
- }
-
- return msg;
- }
-
- public override byte[] GetBytes(byte protocolVersion)
- {
- int fixedHeaderSize = 0;
- int varHeaderSize = 0;
- int payloadSize = 0;
- int remainingLength = 0;
- byte[] buffer;
- int index = 0;
-
- // topics list empty
- if ((this.topics == null) || (this.topics.Length == 0))
- throw new MqttClientException(MqttClientErrorCode.TopicsEmpty);
-
- // qos levels list empty
- if ((this.qosLevels == null) || (this.qosLevels.Length == 0))
- throw new MqttClientException(MqttClientErrorCode.QosLevelsEmpty);
-
- // topics and qos levels lists length don't match
- if (this.topics.Length != this.qosLevels.Length)
- throw new MqttClientException(MqttClientErrorCode.TopicsQosLevelsNotMatch);
-
- // message identifier
- varHeaderSize += MESSAGE_ID_SIZE;
-
- int topicIdx = 0;
- byte[][] topicsUtf8 = new byte[this.topics.Length][];
-
- for (topicIdx = 0; topicIdx < this.topics.Length; topicIdx++)
- {
- // check topic length
- if ((this.topics[topicIdx].Length < MIN_TOPIC_LENGTH) || (this.topics[topicIdx].Length > MAX_TOPIC_LENGTH))
- throw new MqttClientException(MqttClientErrorCode.TopicLength);
-
- topicsUtf8[topicIdx] = Encoding.UTF8.GetBytes(this.topics[topicIdx]);
- payloadSize += 2; // topic size (MSB, LSB)
- payloadSize += topicsUtf8[topicIdx].Length;
- payloadSize++; // byte for QoS
- }
-
- remainingLength += (varHeaderSize + payloadSize);
-
- // first byte of fixed header
- fixedHeaderSize = 1;
-
- int temp = remainingLength;
- // increase fixed header size based on remaining length
- // (each remaining length byte can encode until 128)
- do
- {
- fixedHeaderSize++;
- temp = temp / 128;
- } while (temp > 0);
-
- // allocate buffer for message
- buffer = new byte[fixedHeaderSize + varHeaderSize + payloadSize];
-
- // first fixed header byte
- if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1)
- buffer[index++] = (MQTT_MSG_SUBSCRIBE_TYPE << MSG_TYPE_OFFSET) | MQTT_MSG_SUBSCRIBE_FLAG_BITS; // [v.3.1.1]
- else
- {
- buffer[index] = (byte)((MQTT_MSG_SUBSCRIBE_TYPE << MSG_TYPE_OFFSET) |
- (this.qosLevel << QOS_LEVEL_OFFSET));
- buffer[index] |= this.dupFlag ? (byte)(1 << DUP_FLAG_OFFSET) : (byte)0x00;
- index++;
- }
-
- // encode remaining length
- index = this.encodeRemainingLength(remainingLength, buffer, index);
-
- // check message identifier assigned (SUBSCRIBE uses QoS Level 1, so message id is mandatory)
- if (this.messageId == 0)
- throw new MqttClientException(MqttClientErrorCode.WrongMessageId);
- buffer[index++] = (byte)((messageId >> 8) & 0x00FF); // MSB
- buffer[index++] = (byte)(messageId & 0x00FF); // LSB
-
- topicIdx = 0;
- for (topicIdx = 0; topicIdx < this.topics.Length; topicIdx++)
- {
- // topic name
- buffer[index++] = (byte)((topicsUtf8[topicIdx].Length >> 8) & 0x00FF); // MSB
- buffer[index++] = (byte)(topicsUtf8[topicIdx].Length & 0x00FF); // LSB
- Array.Copy(topicsUtf8[topicIdx], 0, buffer, index, topicsUtf8[topicIdx].Length);
- index += topicsUtf8[topicIdx].Length;
-
- // requested QoS
- buffer[index++] = this.qosLevels[topicIdx];
- }
-
- return buffer;
- }
-
- public override string ToString()
- {
-#if TRACE
- return this.GetTraceString(
- "SUBSCRIBE",
- new object[] { "messageId", "topics", "qosLevels" },
- new object[] { this.messageId, this.topics, this.qosLevels });
-#else
- return base.ToString();
-#endif
- }
- }
-}
diff --git a/mqtt/M2Mqtt/Messages/MqttMsgSubscribeEventArgs.cs b/mqtt/M2Mqtt/Messages/MqttMsgSubscribeEventArgs.cs
deleted file mode 100644
index 91c85f9..0000000
--- a/mqtt/M2Mqtt/Messages/MqttMsgSubscribeEventArgs.cs
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
-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 (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3)
-using System;
-#else
-using Microsoft.SPOT;
-#endif
-
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
- ///
- /// Event Args class for subscribe request on topics
- ///
- public class MqttMsgSubscribeEventArgs : EventArgs
- {
- #region Properties...
-
- ///
- /// Message identifier
- ///
- public ushort MessageId
- {
- get { return this.messageId; }
- internal set { this.messageId = value; }
- }
-
- ///
- /// Topics requested to subscribe
- ///
- public string[] Topics
- {
- get { return this.topics; }
- internal set { this.topics = value; }
- }
-
- ///
- /// List of QOS Levels requested
- ///
- public byte[] QoSLevels
- {
- get { return this.qosLevels; }
- internal set { this.qosLevels = value; }
- }
-
- #endregion
-
- // message identifier
- ushort messageId;
- // topics requested to subscribe
- string[] topics;
- // QoS levels requested
- byte[] qosLevels;
-
- ///
- /// Constructor
- ///
- /// Message identifier for subscribe topics request
- /// Topics requested to subscribe
- /// List of QOS Levels requested
- public MqttMsgSubscribeEventArgs(ushort messageId, string[] topics, byte[] qosLevels)
- {
- this.messageId = messageId;
- this.topics = topics;
- this.qosLevels = qosLevels;
- }
- }
-}
diff --git a/mqtt/M2Mqtt/Messages/MqttMsgSubscribedEventArgs.cs b/mqtt/M2Mqtt/Messages/MqttMsgSubscribedEventArgs.cs
deleted file mode 100644
index 58bbb22..0000000
--- a/mqtt/M2Mqtt/Messages/MqttMsgSubscribedEventArgs.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
-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 (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3)
-using System;
-#else
-using Microsoft.SPOT;
-#endif
-
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
- ///
- /// Event Args class for subscribed topics
- ///
- public class MqttMsgSubscribedEventArgs : EventArgs
- {
- #region Properties...
-
- ///
- /// Message identifier
- ///
- public ushort MessageId
- {
- get { return this.messageId; }
- internal set { this.messageId = value; }
- }
-
- ///
- /// List of granted QOS Levels
- ///
- public byte[] GrantedQoSLevels
- {
- get { return this.grantedQosLevels; }
- internal set { this.grantedQosLevels = value; }
- }
-
- #endregion
-
- // message identifier
- ushort messageId;
- // granted QOS levels
- byte[] grantedQosLevels;
-
- ///
- /// Constructor
- ///
- /// Message identifier for subscribed topics
- /// List of granted QOS Levels
- public MqttMsgSubscribedEventArgs(ushort messageId, byte[] grantedQosLevels)
- {
- this.messageId = messageId;
- this.grantedQosLevels = grantedQosLevels;
- }
- }
-}
diff --git a/mqtt/M2Mqtt/Messages/MqttMsgUnsuback.cs b/mqtt/M2Mqtt/Messages/MqttMsgUnsuback.cs
deleted file mode 100644
index 8e49a06..0000000
--- a/mqtt/M2Mqtt/Messages/MqttMsgUnsuback.cs
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
-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
-*/
-
-using System;
-using uPLibrary.Networking.M2Mqtt.Exceptions;
-
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
- ///
- /// Class for UNSUBACK message from broker to client
- ///
- public class MqttMsgUnsuback : MqttMsgBase
- {
- ///
- /// Constructor
- ///
- public MqttMsgUnsuback()
- {
- this.type = MQTT_MSG_UNSUBACK_TYPE;
- }
-
- ///
- /// Parse bytes for a UNSUBACK message
- ///
- /// First fixed header byte
- /// Protocol Version
- /// Channel connected to the broker
- /// UNSUBACK message instance
- public static MqttMsgUnsuback Parse(byte fixedHeaderFirstByte, byte protocolVersion, IMqttNetworkChannel channel)
- {
- byte[] buffer;
- int index = 0;
- MqttMsgUnsuback msg = new MqttMsgUnsuback();
-
- if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1)
- {
- // [v3.1.1] check flag bits
- if ((fixedHeaderFirstByte & MSG_FLAG_BITS_MASK) != MQTT_MSG_UNSUBACK_FLAG_BITS)
- throw new MqttClientException(MqttClientErrorCode.InvalidFlagBits);
- }
-
- // get remaining length and allocate buffer
- int remainingLength = MqttMsgBase.decodeRemainingLength(channel);
- buffer = new byte[remainingLength];
-
- // read bytes from socket...
- channel.Receive(buffer);
-
- // message id
- msg.messageId = (ushort)((buffer[index++] << 8) & 0xFF00);
- msg.messageId |= (buffer[index++]);
-
- return msg;
- }
-
- public override byte[] GetBytes(byte protocolVersion)
- {
- int fixedHeaderSize = 0;
- int varHeaderSize = 0;
- int payloadSize = 0;
- int remainingLength = 0;
- byte[] buffer;
- int index = 0;
-
- // message identifier
- varHeaderSize += MESSAGE_ID_SIZE;
-
- remainingLength += (varHeaderSize + payloadSize);
-
- // first byte of fixed header
- fixedHeaderSize = 1;
-
- int temp = remainingLength;
- // increase fixed header size based on remaining length
- // (each remaining length byte can encode until 128)
- do
- {
- fixedHeaderSize++;
- temp = temp / 128;
- } while (temp > 0);
-
- // allocate buffer for message
- buffer = new byte[fixedHeaderSize + varHeaderSize + payloadSize];
-
- // first fixed header byte
- if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1)
- buffer[index++] = (MQTT_MSG_UNSUBACK_TYPE << MSG_TYPE_OFFSET) | MQTT_MSG_UNSUBACK_FLAG_BITS; // [v.3.1.1]
- else
- buffer[index++] = (byte)(MQTT_MSG_UNSUBACK_TYPE << MSG_TYPE_OFFSET);
-
- // encode remaining length
- index = this.encodeRemainingLength(remainingLength, buffer, index);
-
- // message id
- buffer[index++] = (byte)((this.messageId >> 8) & 0x00FF); // MSB
- buffer[index++] = (byte)(this.messageId & 0x00FF); // LSB
-
- return buffer;
- }
-
- public override string ToString()
- {
-#if TRACE
- return this.GetTraceString(
- "UNSUBACK",
- new object[] { "messageId" },
- new object[] { this.messageId });
-#else
- return base.ToString();
-#endif
- }
- }
-}
diff --git a/mqtt/M2Mqtt/Messages/MqttMsgUnsubscribe.cs b/mqtt/M2Mqtt/Messages/MqttMsgUnsubscribe.cs
deleted file mode 100644
index e485133..0000000
--- a/mqtt/M2Mqtt/Messages/MqttMsgUnsubscribe.cs
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
-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
-*/
-
-using System;
-// if NOT .Net Micro Framework
-#if (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3)
-using System.Collections.Generic;
-#endif
-using System.Collections;
-using System.Text;
-using uPLibrary.Networking.M2Mqtt.Exceptions;
-
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
- ///
- /// Class for UNSUBSCRIBE message from client to broker
- ///
- public class MqttMsgUnsubscribe : MqttMsgBase
- {
- #region Properties...
-
- ///
- /// List of topics to unsubscribe
- ///
- public string[] Topics
- {
- get { return this.topics; }
- set { this.topics = value; }
- }
-
- #endregion
-
- // topics to unsubscribe
- string[] topics;
-
- ///
- /// Constructor
- ///
- public MqttMsgUnsubscribe()
- {
- this.type = MQTT_MSG_UNSUBSCRIBE_TYPE;
- }
-
- ///
- /// Constructor
- ///
- /// List of topics to unsubscribe
- public MqttMsgUnsubscribe(string[] topics)
- {
- this.type = MQTT_MSG_UNSUBSCRIBE_TYPE;
-
- this.topics = topics;
-
- // UNSUBSCRIBE message uses QoS Level 1 (not "officially" in 3.1.1)
- this.qosLevel = QOS_LEVEL_AT_LEAST_ONCE;
- }
-
- ///
- /// Parse bytes for a UNSUBSCRIBE message
- ///
- /// First fixed header byte
- /// Protocol Version
- /// Channel connected to the broker
- /// UNSUBSCRIBE message instance
- public static MqttMsgUnsubscribe Parse(byte fixedHeaderFirstByte, byte protocolVersion, IMqttNetworkChannel channel)
- {
- byte[] buffer;
- int index = 0;
- byte[] topicUtf8;
- int topicUtf8Length;
- MqttMsgUnsubscribe msg = new MqttMsgUnsubscribe();
-
- if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1)
- {
- // [v3.1.1] check flag bits
- if ((fixedHeaderFirstByte & MSG_FLAG_BITS_MASK) != MQTT_MSG_UNSUBSCRIBE_FLAG_BITS)
- throw new MqttClientException(MqttClientErrorCode.InvalidFlagBits);
- }
-
- // get remaining length and allocate buffer
- int remainingLength = MqttMsgBase.decodeRemainingLength(channel);
- buffer = new byte[remainingLength];
-
- // read bytes from socket...
- int received = channel.Receive(buffer);
-
- if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1)
- {
- // only 3.1.0
-
- // read QoS level from fixed header
- msg.qosLevel = (byte)((fixedHeaderFirstByte & QOS_LEVEL_MASK) >> QOS_LEVEL_OFFSET);
- // read DUP flag from fixed header
- msg.dupFlag = (((fixedHeaderFirstByte & DUP_FLAG_MASK) >> DUP_FLAG_OFFSET) == 0x01);
- // retain flag not used
- msg.retain = false;
- }
-
- // message id
- msg.messageId = (ushort)((buffer[index++] << 8) & 0xFF00);
- msg.messageId |= (buffer[index++]);
-
- // payload contains topics
- // NOTE : before, I don't know how many topics will be in the payload (so use List)
-
-// if .Net Micro Framework
-#if (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3)
- IList tmpTopics = new ArrayList();
-// else other frameworks (.Net, .Net Compact, Mono, Windows Phone)
-#else
- IList tmpTopics = new List();
-#endif
- do
- {
- // topic name
- topicUtf8Length = ((buffer[index++] << 8) & 0xFF00);
- topicUtf8Length |= buffer[index++];
- topicUtf8 = new byte[topicUtf8Length];
- Array.Copy(buffer, index, topicUtf8, 0, topicUtf8Length);
- index += topicUtf8Length;
- tmpTopics.Add(new String(Encoding.UTF8.GetChars(topicUtf8)));
- } while (index < remainingLength);
-
- // copy from list to array
- msg.topics = new string[tmpTopics.Count];
- for (int i = 0; i < tmpTopics.Count; i++)
- {
- msg.topics[i] = (string)tmpTopics[i];
- }
-
- return msg;
- }
-
- public override byte[] GetBytes(byte protocolVersion)
- {
- int fixedHeaderSize = 0;
- int varHeaderSize = 0;
- int payloadSize = 0;
- int remainingLength = 0;
- byte[] buffer;
- int index = 0;
-
- // topics list empty
- if ((this.topics == null) || (this.topics.Length == 0))
- throw new MqttClientException(MqttClientErrorCode.TopicsEmpty);
-
- // message identifier
- varHeaderSize += MESSAGE_ID_SIZE;
-
- int topicIdx = 0;
- byte[][] topicsUtf8 = new byte[this.topics.Length][];
-
- for (topicIdx = 0; topicIdx < this.topics.Length; topicIdx++)
- {
- // check topic length
- if ((this.topics[topicIdx].Length < MIN_TOPIC_LENGTH) || (this.topics[topicIdx].Length > MAX_TOPIC_LENGTH))
- throw new MqttClientException(MqttClientErrorCode.TopicLength);
-
- topicsUtf8[topicIdx] = Encoding.UTF8.GetBytes(this.topics[topicIdx]);
- payloadSize += 2; // topic size (MSB, LSB)
- payloadSize += topicsUtf8[topicIdx].Length;
- }
-
- remainingLength += (varHeaderSize + payloadSize);
-
- // first byte of fixed header
- fixedHeaderSize = 1;
-
- int temp = remainingLength;
- // increase fixed header size based on remaining length
- // (each remaining length byte can encode until 128)
- do
- {
- fixedHeaderSize++;
- temp = temp / 128;
- } while (temp > 0);
-
- // allocate buffer for message
- buffer = new byte[fixedHeaderSize + varHeaderSize + payloadSize];
-
- // first fixed header byte
- if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1)
- buffer[index++] = (MQTT_MSG_UNSUBSCRIBE_TYPE << MSG_TYPE_OFFSET) | MQTT_MSG_UNSUBSCRIBE_FLAG_BITS; // [v.3.1.1]
- else
- {
- buffer[index] = (byte)((MQTT_MSG_UNSUBSCRIBE_TYPE << MSG_TYPE_OFFSET) |
- (this.qosLevel << QOS_LEVEL_OFFSET));
- buffer[index] |= this.dupFlag ? (byte)(1 << DUP_FLAG_OFFSET) : (byte)0x00;
- index++;
- }
-
- // encode remaining length
- index = this.encodeRemainingLength(remainingLength, buffer, index);
-
- // check message identifier assigned
- if (this.messageId == 0)
- throw new MqttClientException(MqttClientErrorCode.WrongMessageId);
- buffer[index++] = (byte)((messageId >> 8) & 0x00FF); // MSB
- buffer[index++] = (byte)(messageId & 0x00FF); // LSB
-
- topicIdx = 0;
- for (topicIdx = 0; topicIdx < this.topics.Length; topicIdx++)
- {
- // topic name
- buffer[index++] = (byte)((topicsUtf8[topicIdx].Length >> 8) & 0x00FF); // MSB
- buffer[index++] = (byte)(topicsUtf8[topicIdx].Length & 0x00FF); // LSB
- Array.Copy(topicsUtf8[topicIdx], 0, buffer, index, topicsUtf8[topicIdx].Length);
- index += topicsUtf8[topicIdx].Length;
- }
-
- return buffer;
- }
-
- public override string ToString()
- {
-#if TRACE
- return this.GetTraceString(
- "UNSUBSCRIBE",
- new object[] { "messageId", "topics" },
- new object[] { this.messageId, this.topics });
-#else
- return base.ToString();
-#endif
- }
- }
-}
diff --git a/mqtt/M2Mqtt/Messages/MqttMsgUnsubscribeEventArgs.cs b/mqtt/M2Mqtt/Messages/MqttMsgUnsubscribeEventArgs.cs
deleted file mode 100644
index e158783..0000000
--- a/mqtt/M2Mqtt/Messages/MqttMsgUnsubscribeEventArgs.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
-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 (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3)
-using System;
-#else
-using Microsoft.SPOT;
-#endif
-
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
- ///
- /// Event Args class for unsubscribe request on topics
- ///
- public class MqttMsgUnsubscribeEventArgs : EventArgs
- {
- #region Properties...
-
- ///
- /// Message identifier
- ///
- public ushort MessageId
- {
- get { return this.messageId; }
- internal set { this.messageId = value; }
- }
-
- ///
- /// Topics requested to subscribe
- ///
- public string[] Topics
- {
- get { return this.topics; }
- internal set { this.topics = value; }
- }
-
- #endregion
-
- // message identifier
- ushort messageId;
- // topics requested to unsubscribe
- string[] topics;
-
- ///
- /// Constructor
- ///
- /// Message identifier for subscribed topics
- /// Topics requested to subscribe
- public MqttMsgUnsubscribeEventArgs(ushort messageId, string[] topics)
- {
- this.messageId = messageId;
- this.topics = topics;
- }
- }
-}
diff --git a/mqtt/M2Mqtt/Messages/MqttMsgUnsubscribedEventArgs.cs b/mqtt/M2Mqtt/Messages/MqttMsgUnsubscribedEventArgs.cs
deleted file mode 100644
index e65c383..0000000
--- a/mqtt/M2Mqtt/Messages/MqttMsgUnsubscribedEventArgs.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
-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 (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3)
-using System;
-#else
-using Microsoft.SPOT;
-#endif
-
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
- ///
- /// Event Args class for unsubscribed topic
- ///
- public class MqttMsgUnsubscribedEventArgs : EventArgs
- {
- #region Properties...
-
- ///
- /// Message identifier
- ///
- public ushort MessageId
- {
- get { return this.messageId; }
- internal set { this.messageId = value; }
- }
-
- #endregion
-
- // message identifier
- ushort messageId;
-
- ///
- /// Constructor
- ///
- /// Message identifier for unsubscribed topic
- public MqttMsgUnsubscribedEventArgs(ushort messageId)
- {
- this.messageId = messageId;
- }
- }
-}
diff --git a/mqtt/M2Mqtt/MqttClient.cs b/mqtt/M2Mqtt/MqttClient.cs
deleted file mode 100644
index 6daf7a2..0000000
--- a/mqtt/M2Mqtt/MqttClient.cs
+++ /dev/null
@@ -1,2632 +0,0 @@
-/*
-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
-*/
-
-using System;
-using System.Net;
-#if !(WINDOWS_APP || WINDOWS_PHONE_APP)
-using System.Net.Sockets;
-using System.Security.Cryptography.X509Certificates;
-#endif
-using System.Threading;
-using uPLibrary.Networking.M2Mqtt.Exceptions;
-using uPLibrary.Networking.M2Mqtt.Messages;
-using uPLibrary.Networking.M2Mqtt.Session;
-using uPLibrary.Networking.M2Mqtt.Utility;
-using uPLibrary.Networking.M2Mqtt.Internal;
-// if .Net Micro Framework
-#if (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3)
-using Microsoft.SPOT;
-#if SSL
-using Microsoft.SPOT.Net.Security;
-#endif
-// else other frameworks (.Net, .Net Compact, Mono, Windows Phone)
-#else
-using System.Collections.Generic;
-#if (SSL && !(WINDOWS_APP || WINDOWS_PHONE_APP))
-using System.Security.Authentication;
-using System.Net.Security;
-#endif
-#endif
-
-#if (WINDOWS_APP || WINDOWS_PHONE_APP)
-using Windows.Networking.Sockets;
-#endif
-
-using System.Collections;
-
-// alias needed due to Microsoft.SPOT.Trace in .Net Micro Framework
-// (it's ambiguos with uPLibrary.Networking.M2Mqtt.Utility.Trace)
-using MqttUtility = uPLibrary.Networking.M2Mqtt.Utility;
-using System.IO;
-//using System.Net.Security;
-
-namespace uPLibrary.Networking.M2Mqtt
-{
- ///
- /// MQTT Client
- ///
- public class MqttClient
- {
-#if BROKER
- #region Constants ...
-
- // thread names
- private const string RECEIVE_THREAD_NAME = "ReceiveThread";
- private const string RECEIVE_EVENT_THREAD_NAME = "DispatchEventThread";
- private const string PROCESS_INFLIGHT_THREAD_NAME = "ProcessInflightThread";
- private const string KEEP_ALIVE_THREAD = "KeepAliveThread";
-
- #endregion
-#endif
-
- ///
- /// Delagate that defines event handler for PUBLISH message received
- ///
- public delegate void MqttMsgPublishEventHandler(object sender, MqttMsgPublishEventArgs e);
-
- ///
- /// Delegate that defines event handler for published message
- ///
- public delegate void MqttMsgPublishedEventHandler(object sender, MqttMsgPublishedEventArgs e);
-
- ///
- /// Delagate that defines event handler for subscribed topic
- ///
- public delegate void MqttMsgSubscribedEventHandler(object sender, MqttMsgSubscribedEventArgs e);
-
- ///
- /// Delagate that defines event handler for unsubscribed topic
- ///
- public delegate void MqttMsgUnsubscribedEventHandler(object sender, MqttMsgUnsubscribedEventArgs e);
-
-#if BROKER
- ///
- /// Delagate that defines event handler for SUBSCRIBE message received
- ///
- public delegate void MqttMsgSubscribeEventHandler(object sender, MqttMsgSubscribeEventArgs e);
-
- ///
- /// Delagate that defines event handler for UNSUBSCRIBE message received
- ///
- public delegate void MqttMsgUnsubscribeEventHandler(object sender, MqttMsgUnsubscribeEventArgs e);
-
- ///
- /// Delagate that defines event handler for CONNECT message received
- ///
- public delegate void MqttMsgConnectEventHandler(object sender, MqttMsgConnectEventArgs e);
-
- ///
- /// Delegate that defines event handler for client disconnection (DISCONNECT message or not)
- ///
- public delegate void MqttMsgDisconnectEventHandler(object sender, EventArgs e);
-#endif
-
- ///
- /// Delegate that defines event handler for cliet/peer disconnection
- ///
- public delegate void ConnectionClosedEventHandler(object sender, EventArgs e);
-
- // broker hostname (or ip address) and port
- private string brokerHostName;
- private int brokerPort;
-
- // running status of threads
- private bool isRunning;
- // event for raising received message event
- private AutoResetEvent receiveEventWaitHandle;
-
- // event for starting process inflight queue asynchronously
- private AutoResetEvent inflightWaitHandle;
-
- // event for signaling synchronous receive
- AutoResetEvent syncEndReceiving;
- // message received
- MqttMsgBase msgReceived;
-
- // exeption thrown during receiving
- Exception exReceiving;
-
- // keep alive period (in ms)
- private int keepAlivePeriod;
- // events for signaling on keep alive thread
- private AutoResetEvent keepAliveEvent;
- private AutoResetEvent keepAliveEventEnd;
- // last communication time in ticks
- private int lastCommTime;
-
- // event for PUBLISH message received
- public event MqttMsgPublishEventHandler MqttMsgPublishReceived;
- // event for published message
- public event MqttMsgPublishedEventHandler MqttMsgPublished;
- // event for subscribed topic
- public event MqttMsgSubscribedEventHandler MqttMsgSubscribed;
- // event for unsubscribed topic
- public event MqttMsgUnsubscribedEventHandler MqttMsgUnsubscribed;
-#if BROKER
- // event for SUBSCRIBE message received
- public event MqttMsgSubscribeEventHandler MqttMsgSubscribeReceived;
- // event for USUBSCRIBE message received
- public event MqttMsgUnsubscribeEventHandler MqttMsgUnsubscribeReceived;
- // event for CONNECT message received
- public event MqttMsgConnectEventHandler MqttMsgConnected;
- // event for DISCONNECT message received
- public event MqttMsgDisconnectEventHandler MqttMsgDisconnected;
-#endif
-
- // event for peer/client disconnection
- public event ConnectionClosedEventHandler ConnectionClosed;
-
- // channel to communicate over the network
- private IMqttNetworkChannel channel;
-
- // inflight messages queue
- private Queue inflightQueue;
- // internal queue for received messages about inflight messages
- private Queue internalQueue;
- // internal queue for dispatching events
- private Queue eventQueue;
- // session
- private MqttClientSession session;
-
- // reference to avoid access to singleton via property
- private MqttSettings settings;
-
- // current message identifier generated
- private ushort messageIdCounter = 0;
-
- // connection is closing due to peer
- private bool isConnectionClosing;
-
- ///
- /// Connection status between client and broker
- ///
- public bool IsConnected { get; private set; }
-
- ///
- /// Client identifier
- ///
- public string ClientId { get; private set; }
-
- ///
- /// Clean session flag
- ///
- public bool CleanSession { get; private set; }
-
- ///
- /// Will flag
- ///
- public bool WillFlag { get; private set; }
-
- ///
- /// Will QOS level
- ///
- public byte WillQosLevel { get; private set; }
-
- ///
- /// Will topic
- ///
- public string WillTopic { get; private set; }
-
- ///
- /// Will message
- ///
- public string WillMessage { get; private set; }
-
- ///
- /// MQTT protocol version
- ///
- public MqttProtocolVersion ProtocolVersion { get; set; }
-
-#if BROKER
- ///
- /// MQTT Client Session
- ///
- public MqttClientSession Session
- {
- get { return this.session; }
- set { this.session = value; }
- }
-#endif
-
- ///
- /// MQTT client settings
- ///
- public MqttSettings Settings
- {
- get { return this.settings; }
- }
-
-#if !(WINDOWS_APP || WINDOWS_PHONE_APP)
- ///
- /// Constructor
- ///
- /// Broker IP address
- [Obsolete("Use this ctor MqttClient(string brokerHostName) insted")]
- public MqttClient(IPAddress brokerIpAddress) :
- this(brokerIpAddress, MqttSettings.MQTT_BROKER_DEFAULT_PORT, false, null, null, MqttSslProtocols.None)
- {
- }
-
- ///
- /// Constructor
- ///
- /// Broker IP address
- /// Broker port
- /// Using secure connection
- /// CA certificate for secure connection
- /// Client certificate
- /// SSL/TLS protocol version
- [Obsolete("Use this ctor MqttClient(string brokerHostName, int brokerPort, bool secure, X509Certificate caCert) insted")]
- public MqttClient(IPAddress brokerIpAddress, int brokerPort, bool secure, X509Certificate caCert, X509Certificate clientCert, MqttSslProtocols sslProtocol)
- {
-#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK)
- this.Init(brokerIpAddress.ToString(), brokerPort, secure, caCert, clientCert, sslProtocol, null, null);
-#else
- this.Init(brokerIpAddress.ToString(), brokerPort, secure, caCert, clientCert, sslProtocol);
-#endif
- }
-#endif
-
- ///
- /// Constructor
- ///
- /// Broker Host Name or IP Address
- public MqttClient(string brokerHostName) :
-#if !(WINDOWS_APP || WINDOWS_PHONE_APP)
- this(brokerHostName, MqttSettings.MQTT_BROKER_DEFAULT_PORT, false, null, null, MqttSslProtocols.None)
-#else
- this(brokerHostName, MqttSettings.MQTT_BROKER_DEFAULT_PORT, false, MqttSslProtocols.None)
-#endif
- {
- }
-
- ///
- /// Constructor
- ///
- /// Broker Host Name or IP Address
- /// Broker port
- /// Using secure connection
- /// SSL/TLS protocol version
-#if !(WINDOWS_APP || WINDOWS_PHONE_APP)
- /// CA certificate for secure connection
- /// Client certificate
- public MqttClient(string brokerHostName, int brokerPort, bool secure, X509Certificate caCert, X509Certificate clientCert, MqttSslProtocols sslProtocol)
-#else
- public MqttClient(string brokerHostName, int brokerPort, bool secure, MqttSslProtocols sslProtocol)
-#endif
- {
-#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK || WINDOWS_APP || WINDOWS_PHONE_APP)
- this.Init(brokerHostName, brokerPort, secure, caCert, clientCert, sslProtocol, null, null);
-#elif (WINDOWS_APP || WINDOWS_PHONE_APP)
- this.Init(brokerHostName, brokerPort, secure, sslProtocol);
-#else
- this.Init(brokerHostName, brokerPort, secure, caCert, clientCert, sslProtocol);
-#endif
- }
-
-
-#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK || WINDOWS_APP || WINDOWS_PHONE_APP)
-
- ///
- /// Constructor
- ///
- /// Broker Host Name or IP Address
- /// Broker port
- /// Using secure connection
- /// CA certificate for secure connection
- /// Client certificate
- /// SSL/TLS protocol version
- /// A RemoteCertificateValidationCallback delegate responsible for validating the certificate supplied by the remote party
- public MqttClient(string brokerHostName, int brokerPort, bool secure, X509Certificate caCert, X509Certificate clientCert, MqttSslProtocols sslProtocol,
- RemoteCertificateValidationCallback userCertificateValidationCallback)
- : this(brokerHostName, brokerPort, secure, caCert, clientCert, sslProtocol, userCertificateValidationCallback, null)
- {
- }
-
- ///
- /// Constructor
- ///
- /// Broker Host Name or IP Address
- /// Broker port
- /// Using secure connection
- /// SSL/TLS protocol version
- /// 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 MqttClient(string brokerHostName, int brokerPort, bool secure, MqttSslProtocols sslProtocol,
- RemoteCertificateValidationCallback userCertificateValidationCallback,
- LocalCertificateSelectionCallback userCertificateSelectionCallback)
- : this(brokerHostName, brokerPort, secure, null, null, sslProtocol, userCertificateValidationCallback, userCertificateSelectionCallback)
- {
- }
-
- ///
- /// Constructor
- ///
- /// Broker Host Name or IP Address
- /// Broker port
- /// Using secure connection
- /// CA certificate for secure connection
- /// Client certificate
- /// SSL/TLS protocol version
- /// 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 MqttClient(string brokerHostName, int brokerPort, bool secure, X509Certificate caCert, X509Certificate clientCert, MqttSslProtocols sslProtocol,
- RemoteCertificateValidationCallback userCertificateValidationCallback,
- LocalCertificateSelectionCallback userCertificateSelectionCallback)
- {
- this.Init(brokerHostName, brokerPort, secure, caCert, clientCert, sslProtocol, userCertificateValidationCallback, userCertificateSelectionCallback);
- }
-#endif
-
-#if BROKER
- ///
- /// Constructor
- ///
- /// Network channel for communication
- public MqttClient(IMqttNetworkChannel channel)
- {
- // set default MQTT protocol version (default is 3.1.1)
- this.ProtocolVersion = MqttProtocolVersion.Version_3_1_1;
-
- this.channel = channel;
-
- // reference to MQTT settings
- this.settings = MqttSettings.Instance;
-
- // client not connected yet (CONNACK not send from client), some default values
- this.IsConnected = false;
- this.ClientId = null;
- this.CleanSession = true;
-
- this.keepAliveEvent = new AutoResetEvent(false);
-
- // queue for handling inflight messages (publishing and acknowledge)
- this.inflightWaitHandle = new AutoResetEvent(false);
- this.inflightQueue = new Queue();
-
- // queue for received message
- this.receiveEventWaitHandle = new AutoResetEvent(false);
- this.eventQueue = new Queue();
- this.internalQueue = new Queue();
-
- // session
- this.session = null;
- }
-#endif
-
- ///
- /// MqttClient initialization
- ///
- /// Broker Host Name or IP Address
- /// Broker port
- /// >Using secure connection
- /// CA certificate for secure connection
- /// Client certificate
- /// SSL/TLS protocol version
-#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK || WINDOWS_APP || WINDOWS_PHONE_APP)
- /// A RemoteCertificateValidationCallback delegate responsible for validating the certificate supplied by the remote party
- /// A LocalCertificateSelectionCallback delegate responsible for selecting the certificate used for authentication
- private void Init(string brokerHostName, int brokerPort, bool secure, X509Certificate caCert, X509Certificate clientCert, MqttSslProtocols sslProtocol,
- RemoteCertificateValidationCallback userCertificateValidationCallback,
- LocalCertificateSelectionCallback userCertificateSelectionCallback)
-#elif (WINDOWS_APP || WINDOWS_PHONE_APP)
- private void Init(string brokerHostName, int brokerPort, bool secure, MqttSslProtocols sslProtocol)
-#else
- private void Init(string brokerHostName, int brokerPort, bool secure, X509Certificate caCert, X509Certificate clientCert, MqttSslProtocols sslProtocol)
-#endif
- {
- // set default MQTT protocol version (default is 3.1.1)
- this.ProtocolVersion = MqttProtocolVersion.Version_3_1_1;
-#if !SSL
- // check security parameters
- if (secure)
- throw new ArgumentException("Library compiled without SSL support");
-#endif
-
- this.brokerHostName = brokerHostName;
- this.brokerPort = brokerPort;
-
- // reference to MQTT settings
- this.settings = MqttSettings.Instance;
- // set settings port based on secure connection or not
- if (!secure)
- this.settings.Port = this.brokerPort;
- else
- this.settings.SslPort = this.brokerPort;
-
- this.syncEndReceiving = new AutoResetEvent(false);
- this.keepAliveEvent = new AutoResetEvent(false);
-
- // queue for handling inflight messages (publishing and acknowledge)
- this.inflightWaitHandle = new AutoResetEvent(false);
- this.inflightQueue = new Queue();
-
- // queue for received message
- this.receiveEventWaitHandle = new AutoResetEvent(false);
- this.eventQueue = new Queue();
- this.internalQueue = new Queue();
-
- // session
- this.session = null;
-
- // create network channel
-#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK || WINDOWS_APP || WINDOWS_PHONE_APP)
- this.channel = new MqttNetworkChannel(this.brokerHostName, this.brokerPort, secure, caCert, clientCert, sslProtocol, userCertificateValidationCallback, userCertificateSelectionCallback);
-#elif (WINDOWS_APP || WINDOWS_PHONE_APP)
- this.channel = new MqttNetworkChannel(this.brokerHostName, this.brokerPort, secure, sslProtocol);
-#else
- this.channel = new MqttNetworkChannel(this.brokerHostName, this.brokerPort, secure, caCert, clientCert, sslProtocol);
-#endif
- }
-
- ///
- /// Connect to broker
- ///
- /// Client identifier
- /// Return code of CONNACK message from broker
- public byte Connect(string clientId)
- {
- return this.Connect(clientId, null, null, false, MqttMsgConnect.QOS_LEVEL_AT_MOST_ONCE, false, null, null, true, MqttMsgConnect.KEEP_ALIVE_PERIOD_DEFAULT);
- }
-
- ///
- /// Connect to broker
- ///
- /// Client identifier
- /// Username
- /// Password
- /// Return code of CONNACK message from broker
- public byte Connect(string clientId,
- string username,
- string password)
- {
- return this.Connect(clientId, username, password, false, MqttMsgConnect.QOS_LEVEL_AT_MOST_ONCE, false, null, null, true, MqttMsgConnect.KEEP_ALIVE_PERIOD_DEFAULT);
- }
-
- ///
- /// Connect to broker
- ///
- /// Client identifier
- /// Username
- /// Password
- /// Clean sessione flag
- /// Keep alive period
- /// Return code of CONNACK message from broker
- public byte Connect(string clientId,
- string username,
- string password,
- bool cleanSession,
- ushort keepAlivePeriod)
- {
- return this.Connect(clientId, username, password, false, MqttMsgConnect.QOS_LEVEL_AT_MOST_ONCE, false, null, null, cleanSession, keepAlivePeriod);
- }
-
- ///
- /// Connect to broker
- ///
- /// Client identifier
- /// Username
- /// Password
- /// Will retain flag
- /// Will QOS level
- /// Will flag
- /// Will topic
- /// Will message
- /// Clean sessione flag
- /// Keep alive period
- /// Return code of CONNACK message from broker
- public byte Connect(string clientId,
- string username,
- string password,
- bool willRetain,
- byte willQosLevel,
- bool willFlag,
- string willTopic,
- string willMessage,
- bool cleanSession,
- ushort keepAlivePeriod)
- {
- // create CONNECT message
- MqttMsgConnect connect = new MqttMsgConnect(clientId,
- username,
- password,
- willRetain,
- willQosLevel,
- willFlag,
- willTopic,
- willMessage,
- cleanSession,
- keepAlivePeriod,
- (byte)this.ProtocolVersion);
-
- try
- {
- // connect to the broker
- this.channel.Connect();
- }
- catch (Exception ex)
- {
- throw new MqttConnectionException("Exception connecting to the broker", ex);
- }
-
- this.lastCommTime = 0;
- this.isRunning = true;
- this.isConnectionClosing = false;
- // start thread for receiving messages from broker
- Fx.StartThread(this.ReceiveThread);
-
- MqttMsgConnack connack = (MqttMsgConnack)this.SendReceive(connect);
- // if connection accepted, start keep alive timer and
- if (connack.ReturnCode == MqttMsgConnack.CONN_ACCEPTED)
- {
- // set all client properties
- this.ClientId = clientId;
- this.CleanSession = cleanSession;
- this.WillFlag = willFlag;
- this.WillTopic = willTopic;
- this.WillMessage = willMessage;
- this.WillQosLevel = willQosLevel;
-
- this.keepAlivePeriod = keepAlivePeriod * 1000; // convert in ms
-
- // restore previous session
- this.RestoreSession();
-
- // keep alive period equals zero means turning off keep alive mechanism
- if (this.keepAlivePeriod != 0)
- {
- // start thread for sending keep alive message to the broker
- Fx.StartThread(this.KeepAliveThread);
- }
-
- // start thread for raising received message event from broker
- Fx.StartThread(this.DispatchEventThread);
-
- // start thread for handling inflight messages queue to broker asynchronously (publish and acknowledge)
- Fx.StartThread(this.ProcessInflightThread);
-
- this.IsConnected = true;
- }
- return connack.ReturnCode;
- }
-
- ///
- /// Disconnect from broker
- ///
- public void Disconnect()
- {
- MqttMsgDisconnect disconnect = new MqttMsgDisconnect();
- this.Send(disconnect);
-
- // close client
- this.OnConnectionClosing();
- }
-
-#if BROKER
- ///
- /// Open client communication
- ///
- public void Open()
- {
- this.isRunning = true;
-
- // start thread for receiving messages from client
- Fx.StartThread(this.ReceiveThread);
-
- // start thread for raising received message event from client
- Fx.StartThread(this.DispatchEventThread);
-
- // start thread for handling inflight messages queue to client asynchronously (publish and acknowledge)
- Fx.StartThread(this.ProcessInflightThread);
- }
-#endif
-
- ///
- /// Close client
- ///
-#if BROKER
- public void Close()
-#else
- private void Close()
-#endif
- {
- // stop receiving thread
- this.isRunning = false;
-
- // wait end receive event thread
- if (this.receiveEventWaitHandle != null)
- this.receiveEventWaitHandle.Set();
-
- // wait end process inflight thread
- if (this.inflightWaitHandle != null)
- this.inflightWaitHandle.Set();
-
-#if BROKER
- // unlock keep alive thread
- this.keepAliveEvent.Set();
-#else
- // unlock keep alive thread and wait
- this.keepAliveEvent.Set();
-
- if (this.keepAliveEventEnd != null)
- this.keepAliveEventEnd.WaitOne();
-#endif
-
- // clear all queues
- this.inflightQueue.Clear();
- this.internalQueue.Clear();
- this.eventQueue.Clear();
-
- // close network channel
- this.channel.Close();
-
- this.IsConnected = false;
- }
-
- ///
- /// Execute ping to broker for keep alive
- ///
- /// PINGRESP message from broker
- private MqttMsgPingResp Ping()
- {
- MqttMsgPingReq pingreq = new MqttMsgPingReq();
- try
- {
- // broker must send PINGRESP within timeout equal to keep alive period
- return (MqttMsgPingResp)this.SendReceive(pingreq, this.keepAlivePeriod);
- }
- catch (Exception e)
- {
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Error, "Exception occurred: {0}", e.ToString());
-#endif
-
- // client must close connection
- this.OnConnectionClosing();
- return null;
- }
- }
-
-#if BROKER
- ///
- /// Send CONNACK message to the client (connection accepted or not)
- ///
- /// CONNECT message with all client information
- /// Return code for CONNACK message
- /// If not null, client id assigned by broker
- /// Session present on the broker
- public void Connack(MqttMsgConnect connect, byte returnCode, string clientId, bool sessionPresent)
- {
- this.lastCommTime = 0;
-
- // create CONNACK message and ...
- MqttMsgConnack connack = new MqttMsgConnack();
- connack.ReturnCode = returnCode;
- // [v3.1.1] session present flag
- if (this.ProtocolVersion == MqttProtocolVersion.Version_3_1_1)
- connack.SessionPresent = sessionPresent;
- // ... send it to the client
- this.Send(connack);
-
- // connection accepted, start keep alive thread checking
- if (connack.ReturnCode == MqttMsgConnack.CONN_ACCEPTED)
- {
- // [v3.1.1] if client id isn't null, the CONNECT message has a cliend id with zero bytes length
- // and broker assigned a unique identifier to the client
- this.ClientId = (clientId == null) ? connect.ClientId : clientId;
- this.CleanSession = connect.CleanSession;
- this.WillFlag = connect.WillFlag;
- this.WillTopic = connect.WillTopic;
- this.WillMessage = connect.WillMessage;
- this.WillQosLevel = connect.WillQosLevel;
-
- this.keepAlivePeriod = connect.KeepAlivePeriod * 1000; // convert in ms
- // broker has a tolerance of 1.5 specified keep alive period
- this.keepAlivePeriod += (this.keepAlivePeriod / 2);
-
- // start thread for checking keep alive period timeout
- Fx.StartThread(this.KeepAliveThread);
-
- this.isConnectionClosing = false;
- this.IsConnected = true;
- }
- // connection refused, close TCP/IP channel
- else
- {
- this.Close();
- }
- }
-
- ///
- /// Send SUBACK message to the client
- ///
- /// Message Id for the SUBSCRIBE message that is being acknowledged
- /// Granted QoS Levels
- public void Suback(ushort messageId, byte[] grantedQosLevels)
- {
- MqttMsgSuback suback = new MqttMsgSuback();
- suback.MessageId = messageId;
- suback.GrantedQoSLevels = grantedQosLevels;
-
- this.Send(suback);
- }
-
- ///
- /// Send UNSUBACK message to the client
- ///
- /// Message Id for the UNSUBSCRIBE message that is being acknowledged
- public void Unsuback(ushort messageId)
- {
- MqttMsgUnsuback unsuback = new MqttMsgUnsuback();
- unsuback.MessageId = messageId;
-
- this.Send(unsuback);
- }
-#endif
-
- ///
- /// Subscribe for message topics
- ///
- /// List of topics to subscribe
- /// QOS levels related to topics
- /// Message Id related to SUBSCRIBE message
- public ushort Subscribe(string[] topics, byte[] qosLevels)
- {
- MqttMsgSubscribe subscribe =
- new MqttMsgSubscribe(topics, qosLevels);
- subscribe.MessageId = this.GetMessageId();
-
- // enqueue subscribe request into the inflight queue
- this.EnqueueInflight(subscribe, MqttMsgFlow.ToPublish);
-
- return subscribe.MessageId;
- }
-
- ///
- /// Unsubscribe for message topics
- ///
- /// List of topics to unsubscribe
- /// Message Id in UNSUBACK message from broker
- public ushort Unsubscribe(string[] topics)
- {
- MqttMsgUnsubscribe unsubscribe =
- new MqttMsgUnsubscribe(topics);
- unsubscribe.MessageId = this.GetMessageId();
-
- // enqueue unsubscribe request into the inflight queue
- this.EnqueueInflight(unsubscribe, MqttMsgFlow.ToPublish);
-
- return unsubscribe.MessageId;
- }
-
- ///
- /// Publish a message asynchronously (QoS Level 0 and not retained)
- ///
- /// Message topic
- /// Message data (payload)
- /// Message Id related to PUBLISH message
- public ushort Publish(string topic, byte[] message)
- {
- return this.Publish(topic, message, MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE, false);
- }
-
- ///
- /// Publish a message asynchronously
- ///
- /// Message topic
- /// Message data (payload)
- /// QoS Level
- /// Retain flag
- /// Message Id related to PUBLISH message
- public ushort Publish(string topic, byte[] message, byte qosLevel, bool retain)
- {
- MqttMsgPublish publish =
- new MqttMsgPublish(topic, message, false, qosLevel, retain);
- publish.MessageId = this.GetMessageId();
-
- // enqueue message to publish into the inflight queue
- bool enqueue = this.EnqueueInflight(publish, MqttMsgFlow.ToPublish);
-
- // message enqueued
- if (enqueue)
- return publish.MessageId;
- // infligh queue full, message not enqueued
- else
- throw new MqttClientException(MqttClientErrorCode.InflightQueueFull);
- }
-
- ///
- /// Wrapper method for raising events
- ///
- /// Internal event
- private void OnInternalEvent(InternalEvent internalEvent)
- {
- lock (this.eventQueue)
- {
- this.eventQueue.Enqueue(internalEvent);
- }
-
- this.receiveEventWaitHandle.Set();
- }
-
- ///
- /// Wrapper method for raising closing connection event
- ///
- private void OnConnectionClosing()
- {
- if (!this.isConnectionClosing)
- {
- this.isConnectionClosing = true;
- this.receiveEventWaitHandle.Set();
- }
- }
-
- ///
- /// Wrapper method for raising PUBLISH message received event
- ///
- /// PUBLISH message received
- private void OnMqttMsgPublishReceived(MqttMsgPublish publish)
- {
- if (this.MqttMsgPublishReceived != null)
- {
- this.MqttMsgPublishReceived(this,
- new MqttMsgPublishEventArgs(publish.Topic, publish.Message, publish.DupFlag, publish.QosLevel, publish.Retain));
- }
- }
-
- ///
- /// Wrapper method for raising published message event
- ///
- /// Message identifier for published message
- /// Publish flag
- private void OnMqttMsgPublished(ushort messageId, bool isPublished)
- {
- if (this.MqttMsgPublished != null)
- {
- this.MqttMsgPublished(this,
- new MqttMsgPublishedEventArgs(messageId, isPublished));
- }
- }
-
- ///
- /// Wrapper method for raising subscribed topic event
- ///
- /// SUBACK message received
- private void OnMqttMsgSubscribed(MqttMsgSuback suback)
- {
- if (this.MqttMsgSubscribed != null)
- {
- this.MqttMsgSubscribed(this,
- new MqttMsgSubscribedEventArgs(suback.MessageId, suback.GrantedQoSLevels));
- }
- }
-
- ///
- /// Wrapper method for raising unsubscribed topic event
- ///
- /// Message identifier for unsubscribed topic
- private void OnMqttMsgUnsubscribed(ushort messageId)
- {
- if (this.MqttMsgUnsubscribed != null)
- {
- this.MqttMsgUnsubscribed(this,
- new MqttMsgUnsubscribedEventArgs(messageId));
- }
- }
-
-#if BROKER
- ///
- /// Wrapper method for raising SUBSCRIBE message event
- ///
- /// Message identifier for subscribe topics request
- /// Topics requested to subscribe
- /// List of QOS Levels requested
- private void OnMqttMsgSubscribeReceived(ushort messageId, string[] topics, byte[] qosLevels)
- {
- if (this.MqttMsgSubscribeReceived != null)
- {
- this.MqttMsgSubscribeReceived(this,
- new MqttMsgSubscribeEventArgs(messageId, topics, qosLevels));
- }
- }
-
- ///
- /// Wrapper method for raising UNSUBSCRIBE message event
- ///
- /// Message identifier for unsubscribe topics request
- /// Topics requested to unsubscribe
- private void OnMqttMsgUnsubscribeReceived(ushort messageId, string[] topics)
- {
- if (this.MqttMsgUnsubscribeReceived != null)
- {
- this.MqttMsgUnsubscribeReceived(this,
- new MqttMsgUnsubscribeEventArgs(messageId, topics));
- }
- }
-
- ///
- /// Wrapper method for raising CONNECT message event
- ///
- private void OnMqttMsgConnected(MqttMsgConnect connect)
- {
- if (this.MqttMsgConnected != null)
- {
- this.ProtocolVersion = (MqttProtocolVersion)connect.ProtocolVersion;
- this.MqttMsgConnected(this, new MqttMsgConnectEventArgs(connect));
- }
- }
-
- ///
- /// Wrapper method for raising DISCONNECT message event
- ///
- private void OnMqttMsgDisconnected()
- {
- if (this.MqttMsgDisconnected != null)
- {
- this.MqttMsgDisconnected(this, EventArgs.Empty);
- }
- }
-#endif
-
- ///
- /// Wrapper method for peer/client disconnection
- ///
- private void OnConnectionClosed()
- {
- if (this.ConnectionClosed != null)
- {
- this.ConnectionClosed(this, EventArgs.Empty);
- }
- }
-
- ///
- /// Send a message
- ///
- /// Message bytes
- private void Send(byte[] msgBytes)
- {
- try
- {
- // send message
- this.channel.Send(msgBytes);
-
-#if !BROKER
- // update last message sent ticks
- this.lastCommTime = Environment.TickCount;
-#endif
- }
- catch (Exception e)
- {
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Error, "Exception occurred: {0}", e.ToString());
-#endif
-
- throw new MqttCommunicationException(e);
- }
- }
-
- ///
- /// Send a message
- ///
- /// Message
- private void Send(MqttMsgBase msg)
- {
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Frame, "SEND {0}", msg);
-#endif
- this.Send(msg.GetBytes((byte)this.ProtocolVersion));
- }
-
- ///
- /// Send a message to the broker and wait answer
- ///
- /// Message bytes
- /// MQTT message response
- private MqttMsgBase SendReceive(byte[] msgBytes)
- {
- return this.SendReceive(msgBytes, MqttSettings.MQTT_DEFAULT_TIMEOUT);
- }
-
- ///
- /// Send a message to the broker and wait answer
- ///
- /// Message bytes
- /// Timeout for receiving answer
- /// MQTT message response
- private MqttMsgBase SendReceive(byte[] msgBytes, int timeout)
- {
- // reset handle before sending
- this.syncEndReceiving.Reset();
- try
- {
- // send message
- this.channel.Send(msgBytes);
-
- // update last message sent ticks
- this.lastCommTime = Environment.TickCount;
- }
- catch (Exception e)
- {
-#if !(MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK || WINDOWS_APP || WINDOWS_PHONE_APP)
- if (typeof(SocketException) == e.GetType())
- {
- // connection reset by broker
- if (((SocketException)e).SocketErrorCode == SocketError.ConnectionReset)
- this.IsConnected = false;
- }
-#endif
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Error, "Exception occurred: {0}", e.ToString());
-#endif
-
- throw new MqttCommunicationException(e);
- }
-
-#if (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK)
- // wait for answer from broker
- if (this.syncEndReceiving.WaitOne(timeout, false))
-#else
- // wait for answer from broker
- if (this.syncEndReceiving.WaitOne(timeout))
-#endif
- {
- // message received without exception
- if (this.exReceiving == null)
- return this.msgReceived;
- // receiving thread catched exception
- else
- throw this.exReceiving;
- }
- else
- {
- // throw timeout exception
- throw new MqttCommunicationException();
- }
- }
-
- ///
- /// Send a message to the broker and wait answer
- ///
- /// Message
- /// MQTT message response
- private MqttMsgBase SendReceive(MqttMsgBase msg)
- {
- return this.SendReceive(msg, MqttSettings.MQTT_DEFAULT_TIMEOUT);
- }
-
- ///
- /// Send a message to the broker and wait answer
- ///
- /// Message
- /// Timeout for receiving answer
- /// MQTT message response
- private MqttMsgBase SendReceive(MqttMsgBase msg, int timeout)
- {
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Frame, "SEND {0}", msg);
-#endif
- return this.SendReceive(msg.GetBytes((byte)this.ProtocolVersion), timeout);
- }
-
- ///
- /// Enqueue a message into the inflight queue
- ///
- /// Message to enqueue
- /// Message flow (publish, acknowledge)
- /// Message enqueued or not
- private bool EnqueueInflight(MqttMsgBase msg, MqttMsgFlow flow)
- {
- // enqueue is needed (or not)
- bool enqueue = true;
-
- // if it is a PUBLISH message with QoS Level 2
- if ((msg.Type == MqttMsgBase.MQTT_MSG_PUBLISH_TYPE) &&
- (msg.QosLevel == MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE))
- {
- lock (this.inflightQueue)
- {
- // if it is a PUBLISH message already received (it is in the inflight queue), the publisher
- // re-sent it because it didn't received the PUBREC. In this case, we have to re-send PUBREC
-
- // NOTE : I need to find on message id and flow because the broker could be publish/received
- // to/from client and message id could be the same (one tracked by broker and the other by client)
- MqttMsgContextFinder msgCtxFinder = new MqttMsgContextFinder(msg.MessageId, MqttMsgFlow.ToAcknowledge);
- MqttMsgContext msgCtx = (MqttMsgContext) QueueExtension.Get(this.inflightQueue, msgCtxFinder.Find);
-
- // the PUBLISH message is alredy in the inflight queue, we don't need to re-enqueue but we need
- // to change state to re-send PUBREC
- if (msgCtx != null)
- {
- msgCtx.State = MqttMsgState.QueuedQos2;
- msgCtx.Flow = MqttMsgFlow.ToAcknowledge;
- enqueue = false;
- }
- }
- }
-
- if (enqueue)
- {
- // set a default state
- MqttMsgState state = MqttMsgState.QueuedQos0;
-
- // based on QoS level, the messages flow between broker and client changes
- switch (msg.QosLevel)
- {
- // QoS Level 0
- case MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE:
-
- state = MqttMsgState.QueuedQos0;
- break;
-
- // QoS Level 1
- case MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE:
-
- state = MqttMsgState.QueuedQos1;
- break;
-
- // QoS Level 2
- case MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE:
-
- state = MqttMsgState.QueuedQos2;
- break;
- }
-
- // [v3.1.1] SUBSCRIBE and UNSUBSCRIBE aren't "officially" QOS = 1
- // so QueuedQos1 state isn't valid for them
- if (msg.Type == MqttMsgBase.MQTT_MSG_SUBSCRIBE_TYPE)
- state = MqttMsgState.SendSubscribe;
- else if (msg.Type == MqttMsgBase.MQTT_MSG_UNSUBSCRIBE_TYPE)
- state = MqttMsgState.SendUnsubscribe;
-
- // queue message context
- MqttMsgContext msgContext = new MqttMsgContext()
- {
- Message = msg,
- State = state,
- Flow = flow,
- Attempt = 0
- };
-
- lock (this.inflightQueue)
- {
- // check number of messages inside inflight queue
- enqueue = (this.inflightQueue.Count < this.settings.InflightQueueSize);
-
- if (enqueue)
- {
- // enqueue message and unlock send thread
- this.inflightQueue.Enqueue(msgContext);
-
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Queuing, "enqueued {0}", msg);
-#endif
-
- // PUBLISH message
- if (msg.Type == MqttMsgBase.MQTT_MSG_PUBLISH_TYPE)
- {
- // to publish and QoS level 1 or 2
- if ((msgContext.Flow == MqttMsgFlow.ToPublish) &&
- ((msg.QosLevel == MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE) ||
- (msg.QosLevel == MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE)))
- {
- if (this.session != null)
- this.session.InflightMessages.Add(msgContext.Key, msgContext);
- }
- // to acknowledge and QoS level 2
- else if ((msgContext.Flow == MqttMsgFlow.ToAcknowledge) &&
- (msg.QosLevel == MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE))
- {
- if (this.session != null)
- this.session.InflightMessages.Add(msgContext.Key, msgContext);
- }
- }
- }
- }
- }
-
- this.inflightWaitHandle.Set();
-
- return enqueue;
- }
-
- ///
- /// Enqueue a message into the internal queue
- ///
- /// Message to enqueue
- private void EnqueueInternal(MqttMsgBase msg)
- {
- // enqueue is needed (or not)
- bool enqueue = true;
-
- // if it is a PUBREL message (for QoS Level 2)
- if (msg.Type == MqttMsgBase.MQTT_MSG_PUBREL_TYPE)
- {
- lock (this.inflightQueue)
- {
- // if it is a PUBREL but the corresponding PUBLISH isn't in the inflight queue,
- // it means that we processed PUBLISH message and received PUBREL and we sent PUBCOMP
- // but publisher didn't receive PUBCOMP so it re-sent PUBREL. We need only to re-send PUBCOMP.
-
- // NOTE : I need to find on message id and flow because the broker could be publish/received
- // to/from client and message id could be the same (one tracked by broker and the other by client)
- MqttMsgContextFinder msgCtxFinder = new MqttMsgContextFinder(msg.MessageId, MqttMsgFlow.ToAcknowledge);
- MqttMsgContext msgCtx = (MqttMsgContext) QueueExtension.Get(this.inflightQueue,msgCtxFinder.Find);
-
- // the PUBLISH message isn't in the inflight queue, it was already processed so
- // we need to re-send PUBCOMP only
- if (msgCtx == null)
- {
- MqttMsgPubcomp pubcomp = new MqttMsgPubcomp();
- pubcomp.MessageId = msg.MessageId;
-
- this.Send(pubcomp);
-
- enqueue = false;
- }
- }
- }
- // if it is a PUBCOMP message (for QoS Level 2)
- else if (msg.Type == MqttMsgBase.MQTT_MSG_PUBCOMP_TYPE)
- {
- lock (this.inflightQueue)
- {
- // if it is a PUBCOMP but the corresponding PUBLISH isn't in the inflight queue,
- // it means that we sent PUBLISH message, sent PUBREL (after receiving PUBREC) and already received PUBCOMP
- // but publisher didn't receive PUBREL so it re-sent PUBCOMP. We need only to ignore this PUBCOMP.
-
- // NOTE : I need to find on message id and flow because the broker could be publish/received
- // to/from client and message id could be the same (one tracked by broker and the other by client)
- MqttMsgContextFinder msgCtxFinder = new MqttMsgContextFinder(msg.MessageId, MqttMsgFlow.ToPublish);
- MqttMsgContext msgCtx = (MqttMsgContext) QueueExtension.Get(this.inflightQueue, msgCtxFinder.Find);
-
- // the PUBLISH message isn't in the inflight queue, it was already sent so we need to ignore this PUBCOMP
- if (msgCtx == null)
- {
- enqueue = false;
- }
- }
- }
- // if it is a PUBREC message (for QoS Level 2)
- else if (msg.Type == MqttMsgBase.MQTT_MSG_PUBREC_TYPE)
- {
- lock (this.inflightQueue)
- {
- // if it is a PUBREC but the corresponding PUBLISH isn't in the inflight queue,
- // it means that we sent PUBLISH message more times (retries) but broker didn't send PUBREC in time
- // the publish is failed and we need only to ignore this PUBREC.
-
- // NOTE : I need to find on message id and flow because the broker could be publish/received
- // to/from client and message id could be the same (one tracked by broker and the other by client)
- MqttMsgContextFinder msgCtxFinder = new MqttMsgContextFinder(msg.MessageId, MqttMsgFlow.ToPublish);
- MqttMsgContext msgCtx = (MqttMsgContext) QueueExtension.Get(this.inflightQueue, msgCtxFinder.Find);
-
- // the PUBLISH message isn't in the inflight queue, it was already sent so we need to ignore this PUBREC
- if (msgCtx == null)
- {
- enqueue = false;
- }
- }
- }
-
- if (enqueue)
- {
- lock (this.internalQueue)
- {
- this.internalQueue.Enqueue(msg);
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Queuing, "enqueued {0}", msg);
-#endif
- this.inflightWaitHandle.Set();
- }
- }
- }
-
- ///
- /// Thread for receiving messages
- ///
- private void ReceiveThread()
- {
- int readBytes = 0;
- byte[] fixedHeaderFirstByte = new byte[1];
- byte msgType;
-
- while (this.isRunning)
- {
- try
- {
- // read first byte (fixed header)
- readBytes = this.channel.Receive(fixedHeaderFirstByte);
-
- if (readBytes > 0)
- {
-#if BROKER
- // update last message received ticks
- this.lastCommTime = Environment.TickCount;
-#endif
-
- // extract message type from received byte
- msgType = (byte)((fixedHeaderFirstByte[0] & MqttMsgBase.MSG_TYPE_MASK) >> MqttMsgBase.MSG_TYPE_OFFSET);
-
- switch (msgType)
- {
- // CONNECT message received
- case MqttMsgBase.MQTT_MSG_CONNECT_TYPE:
-
-#if BROKER
- MqttMsgConnect connect = MqttMsgConnect.Parse(fixedHeaderFirstByte[0], (byte)this.ProtocolVersion, this.channel);
-#if TRACE
- Trace.WriteLine(TraceLevel.Frame, "RECV {0}", connect);
-#endif
-
- // raise message received event
- this.OnInternalEvent(new MsgInternalEvent(connect));
- break;
-#else
- throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
-#endif
-
- // CONNACK message received
- case MqttMsgBase.MQTT_MSG_CONNACK_TYPE:
-
-#if BROKER
- throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
-#else
- this.msgReceived = MqttMsgConnack.Parse(fixedHeaderFirstByte[0], (byte)this.ProtocolVersion, this.channel);
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Frame, "RECV {0}", this.msgReceived);
-#endif
- this.syncEndReceiving.Set();
- break;
-#endif
-
- // PINGREQ message received
- case MqttMsgBase.MQTT_MSG_PINGREQ_TYPE:
-
-#if BROKER
- this.msgReceived = MqttMsgPingReq.Parse(fixedHeaderFirstByte[0], (byte)this.ProtocolVersion, this.channel);
-#if TRACE
- Trace.WriteLine(TraceLevel.Frame, "RECV {0}", this.msgReceived);
-#endif
-
- MqttMsgPingResp pingresp = new MqttMsgPingResp();
- this.Send(pingresp);
-
- break;
-#else
- throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
-#endif
-
- // PINGRESP message received
- case MqttMsgBase.MQTT_MSG_PINGRESP_TYPE:
-
-#if BROKER
- throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
-#else
- this.msgReceived = MqttMsgPingResp.Parse(fixedHeaderFirstByte[0], (byte)this.ProtocolVersion, this.channel);
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Frame, "RECV {0}", this.msgReceived);
-#endif
- this.syncEndReceiving.Set();
- break;
-#endif
-
- // SUBSCRIBE message received
- case MqttMsgBase.MQTT_MSG_SUBSCRIBE_TYPE:
-
-#if BROKER
- MqttMsgSubscribe subscribe = MqttMsgSubscribe.Parse(fixedHeaderFirstByte[0], (byte)this.ProtocolVersion, this.channel);
-#if TRACE
- Trace.WriteLine(TraceLevel.Frame, "RECV {0}", subscribe);
-#endif
-
- // raise message received event
- this.OnInternalEvent(new MsgInternalEvent(subscribe));
-
- break;
-#else
- throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
-#endif
-
- // SUBACK message received
- case MqttMsgBase.MQTT_MSG_SUBACK_TYPE:
-
-#if BROKER
- throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
-#else
- // enqueue SUBACK message received (for QoS Level 1) into the internal queue
- MqttMsgSuback suback = MqttMsgSuback.Parse(fixedHeaderFirstByte[0], (byte)this.ProtocolVersion, this.channel);
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Frame, "RECV {0}", suback);
-#endif
-
- // enqueue SUBACK message into the internal queue
- this.EnqueueInternal(suback);
-
- break;
-#endif
-
- // PUBLISH message received
- case MqttMsgBase.MQTT_MSG_PUBLISH_TYPE:
-
- MqttMsgPublish publish = MqttMsgPublish.Parse(fixedHeaderFirstByte[0], (byte)this.ProtocolVersion, this.channel);
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Frame, "RECV {0}", publish);
-#endif
-
- // enqueue PUBLISH message to acknowledge into the inflight queue
- this.EnqueueInflight(publish, MqttMsgFlow.ToAcknowledge);
-
- break;
-
- // PUBACK message received
- case MqttMsgBase.MQTT_MSG_PUBACK_TYPE:
-
- // enqueue PUBACK message received (for QoS Level 1) into the internal queue
- MqttMsgPuback puback = MqttMsgPuback.Parse(fixedHeaderFirstByte[0], (byte)this.ProtocolVersion, this.channel);
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Frame, "RECV {0}", puback);
-#endif
-
- // enqueue PUBACK message into the internal queue
- this.EnqueueInternal(puback);
-
- break;
-
- // PUBREC message received
- case MqttMsgBase.MQTT_MSG_PUBREC_TYPE:
-
- // enqueue PUBREC message received (for QoS Level 2) into the internal queue
- MqttMsgPubrec pubrec = MqttMsgPubrec.Parse(fixedHeaderFirstByte[0], (byte)this.ProtocolVersion, this.channel);
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Frame, "RECV {0}", pubrec);
-#endif
-
- // enqueue PUBREC message into the internal queue
- this.EnqueueInternal(pubrec);
-
- break;
-
- // PUBREL message received
- case MqttMsgBase.MQTT_MSG_PUBREL_TYPE:
-
- // enqueue PUBREL message received (for QoS Level 2) into the internal queue
- MqttMsgPubrel pubrel = MqttMsgPubrel.Parse(fixedHeaderFirstByte[0], (byte)this.ProtocolVersion, this.channel);
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Frame, "RECV {0}", pubrel);
-#endif
-
- // enqueue PUBREL message into the internal queue
- this.EnqueueInternal(pubrel);
-
- break;
-
- // PUBCOMP message received
- case MqttMsgBase.MQTT_MSG_PUBCOMP_TYPE:
-
- // enqueue PUBCOMP message received (for QoS Level 2) into the internal queue
- MqttMsgPubcomp pubcomp = MqttMsgPubcomp.Parse(fixedHeaderFirstByte[0], (byte)this.ProtocolVersion, this.channel);
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Frame, "RECV {0}", pubcomp);
-#endif
-
- // enqueue PUBCOMP message into the internal queue
- this.EnqueueInternal(pubcomp);
-
- break;
-
- // UNSUBSCRIBE message received
- case MqttMsgBase.MQTT_MSG_UNSUBSCRIBE_TYPE:
-
-#if BROKER
- MqttMsgUnsubscribe unsubscribe = MqttMsgUnsubscribe.Parse(fixedHeaderFirstByte[0], (byte)this.ProtocolVersion, this.channel);
-#if TRACE
- Trace.WriteLine(TraceLevel.Frame, "RECV {0}", unsubscribe);
-#endif
-
- // raise message received event
- this.OnInternalEvent(new MsgInternalEvent(unsubscribe));
-
- break;
-#else
- throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
-#endif
-
- // UNSUBACK message received
- case MqttMsgBase.MQTT_MSG_UNSUBACK_TYPE:
-
-#if BROKER
- throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
-#else
- // enqueue UNSUBACK message received (for QoS Level 1) into the internal queue
- MqttMsgUnsuback unsuback = MqttMsgUnsuback.Parse(fixedHeaderFirstByte[0], (byte)this.ProtocolVersion, this.channel);
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Frame, "RECV {0}", unsuback);
-#endif
-
- // enqueue UNSUBACK message into the internal queue
- this.EnqueueInternal(unsuback);
-
- break;
-#endif
-
- // DISCONNECT message received
- case MqttMsgDisconnect.MQTT_MSG_DISCONNECT_TYPE:
-
-#if BROKER
- MqttMsgDisconnect disconnect = MqttMsgDisconnect.Parse(fixedHeaderFirstByte[0], (byte)this.ProtocolVersion, this.channel);
-#if TRACE
- Trace.WriteLine(TraceLevel.Frame, "RECV {0}", disconnect);
-#endif
-
- // raise message received event
- this.OnInternalEvent(new MsgInternalEvent(disconnect));
-
- break;
-#else
- throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
-#endif
-
- default:
-
- throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
- }
-
- this.exReceiving = null;
- }
- // zero bytes read, peer gracefully closed socket
- else
- {
- // wake up thread that will notify connection is closing
- this.OnConnectionClosing();
- }
- }
- catch (Exception e)
- {
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Error, "Exception occurred: {0}", e.ToString());
-#endif
- this.exReceiving = new MqttCommunicationException(e);
-
- bool close = false;
- if (e.GetType() == typeof(MqttClientException))
- {
- // [v3.1.1] scenarios the receiver MUST close the network connection
- MqttClientException ex = e as MqttClientException;
- close = ((ex.ErrorCode == MqttClientErrorCode.InvalidFlagBits) ||
- (ex.ErrorCode == MqttClientErrorCode.InvalidProtocolName) ||
- (ex.ErrorCode == MqttClientErrorCode.InvalidConnectFlags));
- }
-#if !(WINDOWS_APP || WINDOWS_PHONE_APP)
- else if ((e.GetType() == typeof(IOException)) || (e.GetType() == typeof(SocketException)) ||
- ((e.InnerException != null) && (e.InnerException.GetType() == typeof(SocketException)))) // added for SSL/TLS incoming connection that use SslStream that wraps SocketException
- {
- close = true;
- }
-#endif
-
- if (close)
- {
- // wake up thread that will notify connection is closing
- this.OnConnectionClosing();
- }
- }
- }
- }
-
- ///
- /// Thread for handling keep alive message
- ///
- private void KeepAliveThread()
- {
- int delta = 0;
- int wait = this.keepAlivePeriod;
-
- // create event to signal that current thread is end
- this.keepAliveEventEnd = new AutoResetEvent(false);
-
- while (this.isRunning)
- {
-#if (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK)
- // waiting...
- this.keepAliveEvent.WaitOne(wait, false);
-#else
- // waiting...
- this.keepAliveEvent.WaitOne(wait);
-#endif
-
- if (this.isRunning)
- {
- delta = Environment.TickCount - this.lastCommTime;
-
- // if timeout exceeded ...
- if (delta >= this.keepAlivePeriod)
- {
-#if BROKER
- // client must close connection
- this.OnConnectionClosing();
-#else
- // ... send keep alive
- this.Ping();
- wait = this.keepAlivePeriod;
-#endif
- }
- else
- {
- // update waiting time
- wait = this.keepAlivePeriod - delta;
- }
- }
- }
-
- // signal thread end
- this.keepAliveEventEnd.Set();
- }
-
- ///
- /// Thread for raising event
- ///
- private void DispatchEventThread()
- {
- while (this.isRunning)
- {
-#if BROKER
- if ((this.eventQueue.Count == 0) && !this.isConnectionClosing)
- {
- // broker need to receive the first message (CONNECT)
- // within a reasonable amount of time after TCP/IP connection
- if (!this.IsConnected)
- {
- // wait on receiving message from client with a connection timeout
- if (!this.receiveEventWaitHandle.WaitOne(this.settings.TimeoutOnConnection))
- {
- // client must close connection
- this.Close();
-
- // client raw disconnection
- this.OnConnectionClosed();
- }
- }
- else
- {
- // wait on receiving message from client
- this.receiveEventWaitHandle.WaitOne();
- }
- }
-#else
- if ((this.eventQueue.Count == 0) && !this.isConnectionClosing)
- // wait on receiving message from client
- this.receiveEventWaitHandle.WaitOne();
-#endif
-
- // check if it is running or we are closing client
- if (this.isRunning)
- {
- // get event from queue
- InternalEvent internalEvent = null;
- lock (this.eventQueue)
- {
- if (this.eventQueue.Count > 0)
- internalEvent = (InternalEvent)this.eventQueue.Dequeue();
- }
-
- // it's an event with a message inside
- if (internalEvent != null)
- {
- MqttMsgBase msg = ((MsgInternalEvent)internalEvent).Message;
-
- if (msg != null)
- {
- switch (msg.Type)
- {
- // CONNECT message received
- case MqttMsgBase.MQTT_MSG_CONNECT_TYPE:
-
-#if BROKER
- // raise connected client event (CONNECT message received)
- this.OnMqttMsgConnected((MqttMsgConnect)msg);
- break;
-#else
- throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
-#endif
-
- // SUBSCRIBE message received
- case MqttMsgBase.MQTT_MSG_SUBSCRIBE_TYPE:
-
-#if BROKER
- MqttMsgSubscribe subscribe = (MqttMsgSubscribe)msg;
- // raise subscribe topic event (SUBSCRIBE message received)
- this.OnMqttMsgSubscribeReceived(subscribe.MessageId, subscribe.Topics, subscribe.QoSLevels);
- break;
-#else
- throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
-#endif
-
- // SUBACK message received
- case MqttMsgBase.MQTT_MSG_SUBACK_TYPE:
-
- // raise subscribed topic event (SUBACK message received)
- this.OnMqttMsgSubscribed((MqttMsgSuback)msg);
- break;
-
- // PUBLISH message received
- case MqttMsgBase.MQTT_MSG_PUBLISH_TYPE:
-
- // PUBLISH message received in a published internal event, no publish succeeded
- if (internalEvent.GetType() == typeof(MsgPublishedInternalEvent))
- this.OnMqttMsgPublished(msg.MessageId, false);
- else
- // raise PUBLISH message received event
- this.OnMqttMsgPublishReceived((MqttMsgPublish)msg);
- break;
-
- // PUBACK message received
- case MqttMsgBase.MQTT_MSG_PUBACK_TYPE:
-
- // raise published message event
- // (PUBACK received for QoS Level 1)
- this.OnMqttMsgPublished(msg.MessageId, true);
- break;
-
- // PUBREL message received
- case MqttMsgBase.MQTT_MSG_PUBREL_TYPE:
-
- // raise message received event
- // (PUBREL received for QoS Level 2)
- this.OnMqttMsgPublishReceived((MqttMsgPublish)msg);
- break;
-
- // PUBCOMP message received
- case MqttMsgBase.MQTT_MSG_PUBCOMP_TYPE:
-
- // raise published message event
- // (PUBCOMP received for QoS Level 2)
- this.OnMqttMsgPublished(msg.MessageId, true);
- break;
-
- // UNSUBSCRIBE message received from client
- case MqttMsgBase.MQTT_MSG_UNSUBSCRIBE_TYPE:
-
-#if BROKER
- MqttMsgUnsubscribe unsubscribe = (MqttMsgUnsubscribe)msg;
- // raise unsubscribe topic event (UNSUBSCRIBE message received)
- this.OnMqttMsgUnsubscribeReceived(unsubscribe.MessageId, unsubscribe.Topics);
- break;
-#else
- throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
-#endif
-
- // UNSUBACK message received
- case MqttMsgBase.MQTT_MSG_UNSUBACK_TYPE:
-
- // raise unsubscribed topic event
- this.OnMqttMsgUnsubscribed(msg.MessageId);
- break;
-
- // DISCONNECT message received from client
- case MqttMsgDisconnect.MQTT_MSG_DISCONNECT_TYPE:
-
-#if BROKER
- // raise disconnected client event (DISCONNECT message received)
- this.OnMqttMsgDisconnected();
- break;
-#else
- throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
-#endif
- }
- }
- }
-
- // all events for received messages dispatched, check if there is closing connection
- if ((this.eventQueue.Count == 0) && this.isConnectionClosing)
- {
- // client must close connection
- this.Close();
-
- // client raw disconnection
- this.OnConnectionClosed();
- }
- }
- }
- }
-
- ///
- /// Process inflight messages queue
- ///
- private void ProcessInflightThread()
- {
- MqttMsgContext msgContext = null;
- MqttMsgBase msgInflight = null;
- MqttMsgBase msgReceived = null;
- InternalEvent internalEvent = null;
- bool acknowledge = false;
- int timeout = Timeout.Infinite;
- int delta;
- bool msgReceivedProcessed = false;
-
- try
- {
- while (this.isRunning)
- {
-#if (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK)
- // wait on message queueud to inflight
- this.inflightWaitHandle.WaitOne(timeout, false);
-#else
- // wait on message queueud to inflight
- this.inflightWaitHandle.WaitOne(timeout);
-#endif
-
- // it could be unblocked because Close() method is joining
- if (this.isRunning)
- {
- lock (this.inflightQueue)
- {
- // message received and peeked from internal queue is processed
- // NOTE : it has the corresponding message in inflight queue based on messageId
- // (ex. a PUBREC for a PUBLISH, a SUBACK for a SUBSCRIBE, ...)
- // if it's orphan we need to remove from internal queue
- msgReceivedProcessed = false;
- acknowledge = false;
- msgReceived = null;
-
- // set timeout tu MaxValue instead of Infinte (-1) to perform
- // compare with calcultad current msgTimeout
- timeout = Int32.MaxValue;
-
- // a message inflight could be re-enqueued but we have to
- // analyze it only just one time for cycle
- int count = this.inflightQueue.Count;
- // process all inflight queued messages
- while (count > 0)
- {
- count--;
- acknowledge = false;
- msgReceived = null;
-
- // check to be sure that client isn't closing and all queues are now empty !
- if (!this.isRunning)
- break;
-
- // dequeue message context from queue
- msgContext = (MqttMsgContext)this.inflightQueue.Dequeue();
-
- // get inflight message
- msgInflight = (MqttMsgBase)msgContext.Message;
-
- switch (msgContext.State)
- {
- case MqttMsgState.QueuedQos0:
-
- // QoS 0, PUBLISH message to send to broker, no state change, no acknowledge
- if (msgContext.Flow == MqttMsgFlow.ToPublish)
- {
- this.Send(msgInflight);
- }
- // QoS 0, no need acknowledge
- else if (msgContext.Flow == MqttMsgFlow.ToAcknowledge)
- {
- internalEvent = new MsgInternalEvent(msgInflight);
- // notify published message from broker (no need acknowledged)
- this.OnInternalEvent(internalEvent);
- }
-
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Queuing, "processed {0}", msgInflight);
-#endif
- break;
-
- case MqttMsgState.QueuedQos1:
- // [v3.1.1] SUBSCRIBE and UNSIBSCRIBE aren't "officially" QOS = 1
- case MqttMsgState.SendSubscribe:
- case MqttMsgState.SendUnsubscribe:
-
- // QoS 1, PUBLISH or SUBSCRIBE/UNSUBSCRIBE message to send to broker, state change to wait PUBACK or SUBACK/UNSUBACK
- if (msgContext.Flow == MqttMsgFlow.ToPublish)
- {
- msgContext.Timestamp = Environment.TickCount;
- msgContext.Attempt++;
-
- if (msgInflight.Type == MqttMsgBase.MQTT_MSG_PUBLISH_TYPE)
- {
- // PUBLISH message to send, wait for PUBACK
- msgContext.State = MqttMsgState.WaitForPuback;
- // retry ? set dup flag [v3.1.1] only for PUBLISH message
- if (msgContext.Attempt > 1)
- msgInflight.DupFlag = true;
- }
- else if (msgInflight.Type == MqttMsgBase.MQTT_MSG_SUBSCRIBE_TYPE)
- // SUBSCRIBE message to send, wait for SUBACK
- msgContext.State = MqttMsgState.WaitForSuback;
- else if (msgInflight.Type == MqttMsgBase.MQTT_MSG_UNSUBSCRIBE_TYPE)
- // UNSUBSCRIBE message to send, wait for UNSUBACK
- msgContext.State = MqttMsgState.WaitForUnsuback;
-
- this.Send(msgInflight);
-
- // update timeout : minimum between delay (based on current message sent) or current timeout
- timeout = (this.settings.DelayOnRetry < timeout) ? this.settings.DelayOnRetry : timeout;
-
- // re-enqueue message (I have to re-analyze for receiving PUBACK, SUBACK or UNSUBACK)
- this.inflightQueue.Enqueue(msgContext);
- }
- // QoS 1, PUBLISH message received from broker to acknowledge, send PUBACK
- else if (msgContext.Flow == MqttMsgFlow.ToAcknowledge)
- {
- MqttMsgPuback puback = new MqttMsgPuback();
- puback.MessageId = msgInflight.MessageId;
-
- this.Send(puback);
-
- internalEvent = new MsgInternalEvent(msgInflight);
- // notify published message from broker and acknowledged
- this.OnInternalEvent(internalEvent);
-
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Queuing, "processed {0}", msgInflight);
-#endif
- }
- break;
-
- case MqttMsgState.QueuedQos2:
-
- // QoS 2, PUBLISH message to send to broker, state change to wait PUBREC
- if (msgContext.Flow == MqttMsgFlow.ToPublish)
- {
- msgContext.Timestamp = Environment.TickCount;
- msgContext.Attempt++;
- msgContext.State = MqttMsgState.WaitForPubrec;
- // retry ? set dup flag
- if (msgContext.Attempt > 1)
- msgInflight.DupFlag = true;
-
- this.Send(msgInflight);
-
- // update timeout : minimum between delay (based on current message sent) or current timeout
- timeout = (this.settings.DelayOnRetry < timeout) ? this.settings.DelayOnRetry : timeout;
-
- // re-enqueue message (I have to re-analyze for receiving PUBREC)
- this.inflightQueue.Enqueue(msgContext);
- }
- // QoS 2, PUBLISH message received from broker to acknowledge, send PUBREC, state change to wait PUBREL
- else if (msgContext.Flow == MqttMsgFlow.ToAcknowledge)
- {
- MqttMsgPubrec pubrec = new MqttMsgPubrec();
- pubrec.MessageId = msgInflight.MessageId;
-
- msgContext.State = MqttMsgState.WaitForPubrel;
-
- this.Send(pubrec);
-
- // re-enqueue message (I have to re-analyze for receiving PUBREL)
- this.inflightQueue.Enqueue(msgContext);
- }
- break;
-
- case MqttMsgState.WaitForPuback:
- case MqttMsgState.WaitForSuback:
- case MqttMsgState.WaitForUnsuback:
-
- // QoS 1, waiting for PUBACK of a PUBLISH message sent or
- // waiting for SUBACK of a SUBSCRIBE message sent or
- // waiting for UNSUBACK of a UNSUBSCRIBE message sent or
- if (msgContext.Flow == MqttMsgFlow.ToPublish)
- {
- acknowledge = false;
- lock (this.internalQueue)
- {
- if (this.internalQueue.Count > 0)
- msgReceived = (MqttMsgBase)this.internalQueue.Peek();
- }
-
- // it is a PUBACK message or a SUBACK/UNSUBACK message
- if (msgReceived != null)
- {
- // PUBACK message or SUBACK/UNSUBACK message for the current message
- if (((msgReceived.Type == MqttMsgBase.MQTT_MSG_PUBACK_TYPE) && (msgInflight.Type == MqttMsgBase.MQTT_MSG_PUBLISH_TYPE) && (msgReceived.MessageId == msgInflight.MessageId)) ||
- ((msgReceived.Type == MqttMsgBase.MQTT_MSG_SUBACK_TYPE) && (msgInflight.Type == MqttMsgBase.MQTT_MSG_SUBSCRIBE_TYPE) && (msgReceived.MessageId == msgInflight.MessageId)) ||
- ((msgReceived.Type == MqttMsgBase.MQTT_MSG_UNSUBACK_TYPE) && (msgInflight.Type == MqttMsgBase.MQTT_MSG_UNSUBSCRIBE_TYPE) && (msgReceived.MessageId == msgInflight.MessageId)))
- {
- lock (this.internalQueue)
- {
- // received message processed
- this.internalQueue.Dequeue();
- acknowledge = true;
- msgReceivedProcessed = true;
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Queuing, "dequeued {0}", msgReceived);
-#endif
- }
-
- // if PUBACK received, confirm published with flag
- if (msgReceived.Type == MqttMsgBase.MQTT_MSG_PUBACK_TYPE)
- internalEvent = new MsgPublishedInternalEvent(msgReceived, true);
- else
- internalEvent = new MsgInternalEvent(msgReceived);
-
- // notify received acknowledge from broker of a published message or subscribe/unsubscribe message
- this.OnInternalEvent(internalEvent);
-
- // PUBACK received for PUBLISH message with QoS Level 1, remove from session state
- if ((msgInflight.Type == MqttMsgBase.MQTT_MSG_PUBLISH_TYPE) &&
- (this.session != null) &&
-#if (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK)
- (this.session.InflightMessages.Contains(msgContext.Key)))
-#else
- (this.session.InflightMessages.ContainsKey(msgContext.Key)))
-#endif
- {
- this.session.InflightMessages.Remove(msgContext.Key);
- }
-
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Queuing, "processed {0}", msgInflight);
-#endif
- }
- }
-
- // current message not acknowledged, no PUBACK or SUBACK/UNSUBACK or not equal messageid
- if (!acknowledge)
- {
- delta = Environment.TickCount - msgContext.Timestamp;
- // check timeout for receiving PUBACK since PUBLISH was sent or
- // for receiving SUBACK since SUBSCRIBE was sent or
- // for receiving UNSUBACK since UNSUBSCRIBE was sent
- if (delta >= this.settings.DelayOnRetry)
- {
- // max retry not reached, resend
- if (msgContext.Attempt < this.settings.AttemptsOnRetry)
- {
- msgContext.State = MqttMsgState.QueuedQos1;
-
- // re-enqueue message
- this.inflightQueue.Enqueue(msgContext);
-
- // update timeout (0 -> reanalyze queue immediately)
- timeout = 0;
- }
- else
- {
- // if PUBACK for a PUBLISH message not received after retries, raise event for not published
- if (msgInflight.Type == MqttMsgBase.MQTT_MSG_PUBLISH_TYPE)
- {
- // PUBACK not received in time, PUBLISH retries failed, need to remove from session inflight messages too
- if ((this.session != null) &&
-#if (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK)
- (this.session.InflightMessages.Contains(msgContext.Key)))
-#else
- (this.session.InflightMessages.ContainsKey(msgContext.Key)))
-#endif
- {
- this.session.InflightMessages.Remove(msgContext.Key);
- }
-
- internalEvent = new MsgPublishedInternalEvent(msgInflight, false);
-
- // notify not received acknowledge from broker and message not published
- this.OnInternalEvent(internalEvent);
- }
- // NOTE : not raise events for SUBACK or UNSUBACK not received
- // for the user no event raised means subscribe/unsubscribe failed
- }
- }
- else
- {
- // re-enqueue message (I have to re-analyze for receiving PUBACK, SUBACK or UNSUBACK)
- this.inflightQueue.Enqueue(msgContext);
-
- // update timeout
- int msgTimeout = (this.settings.DelayOnRetry - delta);
- timeout = (msgTimeout < timeout) ? msgTimeout : timeout;
- }
- }
- }
- break;
-
- case MqttMsgState.WaitForPubrec:
-
- // QoS 2, waiting for PUBREC of a PUBLISH message sent
- if (msgContext.Flow == MqttMsgFlow.ToPublish)
- {
- acknowledge = false;
- lock (this.internalQueue)
- {
- if (this.internalQueue.Count > 0)
- msgReceived = (MqttMsgBase)this.internalQueue.Peek();
- }
-
- // it is a PUBREC message
- if ((msgReceived != null) && (msgReceived.Type == MqttMsgBase.MQTT_MSG_PUBREC_TYPE))
- {
- // PUBREC message for the current PUBLISH message, send PUBREL, wait for PUBCOMP
- if (msgReceived.MessageId == msgInflight.MessageId)
- {
- lock (this.internalQueue)
- {
- // received message processed
- this.internalQueue.Dequeue();
- acknowledge = true;
- msgReceivedProcessed = true;
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Queuing, "dequeued {0}", msgReceived);
-#endif
- }
-
- MqttMsgPubrel pubrel = new MqttMsgPubrel();
- pubrel.MessageId = msgInflight.MessageId;
-
- msgContext.State = MqttMsgState.WaitForPubcomp;
- msgContext.Timestamp = Environment.TickCount;
- msgContext.Attempt = 1;
-
- this.Send(pubrel);
-
- // update timeout : minimum between delay (based on current message sent) or current timeout
- timeout = (this.settings.DelayOnRetry < timeout) ? this.settings.DelayOnRetry : timeout;
-
- // re-enqueue message
- this.inflightQueue.Enqueue(msgContext);
- }
- }
-
- // current message not acknowledged
- if (!acknowledge)
- {
- delta = Environment.TickCount - msgContext.Timestamp;
- // check timeout for receiving PUBREC since PUBLISH was sent
- if (delta >= this.settings.DelayOnRetry)
- {
- // max retry not reached, resend
- if (msgContext.Attempt < this.settings.AttemptsOnRetry)
- {
- msgContext.State = MqttMsgState.QueuedQos2;
-
- // re-enqueue message
- this.inflightQueue.Enqueue(msgContext);
-
- // update timeout (0 -> reanalyze queue immediately)
- timeout = 0;
- }
- else
- {
- // PUBREC not received in time, PUBLISH retries failed, need to remove from session inflight messages too
- if ((this.session != null) &&
-#if (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK)
- (this.session.InflightMessages.Contains(msgContext.Key)))
-#else
- (this.session.InflightMessages.ContainsKey(msgContext.Key)))
-#endif
- {
- this.session.InflightMessages.Remove(msgContext.Key);
- }
-
- // if PUBREC for a PUBLISH message not received after retries, raise event for not published
- internalEvent = new MsgPublishedInternalEvent(msgInflight, false);
- // notify not received acknowledge from broker and message not published
- this.OnInternalEvent(internalEvent);
- }
- }
- else
- {
- // re-enqueue message
- this.inflightQueue.Enqueue(msgContext);
-
- // update timeout
- int msgTimeout = (this.settings.DelayOnRetry - delta);
- timeout = (msgTimeout < timeout) ? msgTimeout : timeout;
- }
- }
- }
- break;
-
- case MqttMsgState.WaitForPubrel:
-
- // QoS 2, waiting for PUBREL of a PUBREC message sent
- if (msgContext.Flow == MqttMsgFlow.ToAcknowledge)
- {
- lock (this.internalQueue)
- {
- if (this.internalQueue.Count > 0)
- msgReceived = (MqttMsgBase)this.internalQueue.Peek();
- }
-
- // it is a PUBREL message
- if ((msgReceived != null) && (msgReceived.Type == MqttMsgBase.MQTT_MSG_PUBREL_TYPE))
- {
- // PUBREL message for the current message, send PUBCOMP
- if (msgReceived.MessageId == msgInflight.MessageId)
- {
- lock (this.internalQueue)
- {
- // received message processed
- this.internalQueue.Dequeue();
- msgReceivedProcessed = true;
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Queuing, "dequeued {0}", msgReceived);
-#endif
- }
-
- MqttMsgPubcomp pubcomp = new MqttMsgPubcomp();
- pubcomp.MessageId = msgInflight.MessageId;
-
- this.Send(pubcomp);
-
- internalEvent = new MsgInternalEvent(msgInflight);
- // notify published message from broker and acknowledged
- this.OnInternalEvent(internalEvent);
-
- // PUBREL received (and PUBCOMP sent) for PUBLISH message with QoS Level 2, remove from session state
- if ((msgInflight.Type == MqttMsgBase.MQTT_MSG_PUBLISH_TYPE) &&
- (this.session != null) &&
-#if (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK)
- (this.session.InflightMessages.Contains(msgContext.Key)))
-#else
- (this.session.InflightMessages.ContainsKey(msgContext.Key)))
-#endif
- {
- this.session.InflightMessages.Remove(msgContext.Key);
- }
-
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Queuing, "processed {0}", msgInflight);
-#endif
- }
- else
- {
- // re-enqueue message
- this.inflightQueue.Enqueue(msgContext);
- }
- }
- else
- {
- // re-enqueue message
- this.inflightQueue.Enqueue(msgContext);
- }
- }
- break;
-
- case MqttMsgState.WaitForPubcomp:
-
- // QoS 2, waiting for PUBCOMP of a PUBREL message sent
- if (msgContext.Flow == MqttMsgFlow.ToPublish)
- {
- acknowledge = false;
- lock (this.internalQueue)
- {
- if (this.internalQueue.Count > 0)
- msgReceived = (MqttMsgBase)this.internalQueue.Peek();
- }
-
- // it is a PUBCOMP message
- if ((msgReceived != null) && (msgReceived.Type == MqttMsgBase.MQTT_MSG_PUBCOMP_TYPE))
- {
- // PUBCOMP message for the current message
- if (msgReceived.MessageId == msgInflight.MessageId)
- {
- lock (this.internalQueue)
- {
- // received message processed
- this.internalQueue.Dequeue();
- acknowledge = true;
- msgReceivedProcessed = true;
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Queuing, "dequeued {0}", msgReceived);
-#endif
- }
-
- internalEvent = new MsgPublishedInternalEvent(msgReceived, true);
- // notify received acknowledge from broker of a published message
- this.OnInternalEvent(internalEvent);
-
- // PUBCOMP received for PUBLISH message with QoS Level 2, remove from session state
- if ((msgInflight.Type == MqttMsgBase.MQTT_MSG_PUBLISH_TYPE) &&
- (this.session != null) &&
-#if (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK)
- (this.session.InflightMessages.Contains(msgContext.Key)))
-#else
- (this.session.InflightMessages.ContainsKey(msgContext.Key)))
-#endif
- {
- this.session.InflightMessages.Remove(msgContext.Key);
- }
-
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Queuing, "processed {0}", msgInflight);
-#endif
- }
- }
- // it is a PUBREC message
- else if ((msgReceived != null) && (msgReceived.Type == MqttMsgBase.MQTT_MSG_PUBREC_TYPE))
- {
- // another PUBREC message for the current message due to a retransmitted PUBLISH
- // I'm in waiting for PUBCOMP, so I can discard this PUBREC
- if (msgReceived.MessageId == msgInflight.MessageId)
- {
- lock (this.internalQueue)
- {
- // received message processed
- this.internalQueue.Dequeue();
- acknowledge = true;
- msgReceivedProcessed = true;
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Queuing, "dequeued {0}", msgReceived);
-#endif
-
- // re-enqueue message
- this.inflightQueue.Enqueue(msgContext);
- }
- }
- }
-
- // current message not acknowledged
- if (!acknowledge)
- {
- delta = Environment.TickCount - msgContext.Timestamp;
- // check timeout for receiving PUBCOMP since PUBREL was sent
- if (delta >= this.settings.DelayOnRetry)
- {
- // max retry not reached, resend
- if (msgContext.Attempt < this.settings.AttemptsOnRetry)
- {
- msgContext.State = MqttMsgState.SendPubrel;
-
- // re-enqueue message
- this.inflightQueue.Enqueue(msgContext);
-
- // update timeout (0 -> reanalyze queue immediately)
- timeout = 0;
- }
- else
- {
- // PUBCOMP not received, PUBREL retries failed, need to remove from session inflight messages too
- if ((this.session != null) &&
-#if (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK)
- (this.session.InflightMessages.Contains(msgContext.Key)))
-#else
- (this.session.InflightMessages.ContainsKey(msgContext.Key)))
-#endif
- {
- this.session.InflightMessages.Remove(msgContext.Key);
- }
-
- // if PUBCOMP for a PUBLISH message not received after retries, raise event for not published
- internalEvent = new MsgPublishedInternalEvent(msgInflight, false);
- // notify not received acknowledge from broker and message not published
- this.OnInternalEvent(internalEvent);
- }
- }
- else
- {
- // re-enqueue message
- this.inflightQueue.Enqueue(msgContext);
-
- // update timeout
- int msgTimeout = (this.settings.DelayOnRetry - delta);
- timeout = (msgTimeout < timeout) ? msgTimeout : timeout;
- }
- }
- }
- break;
-
- case MqttMsgState.SendPubrec:
-
- // TODO : impossible ? --> QueuedQos2 ToAcknowledge
- break;
-
- case MqttMsgState.SendPubrel:
-
- // QoS 2, PUBREL message to send to broker, state change to wait PUBCOMP
- if (msgContext.Flow == MqttMsgFlow.ToPublish)
- {
- MqttMsgPubrel pubrel = new MqttMsgPubrel();
- pubrel.MessageId = msgInflight.MessageId;
-
- msgContext.State = MqttMsgState.WaitForPubcomp;
- msgContext.Timestamp = Environment.TickCount;
- msgContext.Attempt++;
- // retry ? set dup flag [v3.1.1] no needed
- if (this.ProtocolVersion == MqttProtocolVersion.Version_3_1)
- {
- if (msgContext.Attempt > 1)
- pubrel.DupFlag = true;
- }
-
- this.Send(pubrel);
-
- // update timeout : minimum between delay (based on current message sent) or current timeout
- timeout = (this.settings.DelayOnRetry < timeout) ? this.settings.DelayOnRetry : timeout;
-
- // re-enqueue message
- this.inflightQueue.Enqueue(msgContext);
- }
- break;
-
- case MqttMsgState.SendPubcomp:
- // TODO : impossible ?
- break;
- case MqttMsgState.SendPuback:
- // TODO : impossible ? --> QueuedQos1 ToAcknowledge
- break;
- default:
- break;
- }
- }
-
- // if calculated timeout is MaxValue, it means that must be Infinite (-1)
- if (timeout == Int32.MaxValue)
- timeout = Timeout.Infinite;
-
- // if message received is orphan, no corresponding message in inflight queue
- // based on messageId, we need to remove from the queue
- if ((msgReceived != null) && !msgReceivedProcessed)
- {
- this.internalQueue.Dequeue();
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Queuing, "dequeued {0} orphan", msgReceived);
-#endif
- }
- }
- }
- }
- }
- catch (MqttCommunicationException e)
- {
- // possible exception on Send, I need to re-enqueue not sent message
- if (msgContext != null)
- // re-enqueue message
- this.inflightQueue.Enqueue(msgContext);
-
-#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Error, "Exception occurred: {0}", e.ToString());
-#endif
-
- // raise disconnection client event
- this.OnConnectionClosing();
- }
- }
-
- ///
- /// Restore session
- ///
- private void RestoreSession()
- {
- // if not clean session
- if (!this.CleanSession)
- {
- // there is a previous session
- if (this.session != null)
- {
- lock (this.inflightQueue)
- {
- foreach (MqttMsgContext msgContext in this.session.InflightMessages.Values)
- {
- this.inflightQueue.Enqueue(msgContext);
-
- // if it is a PUBLISH message to publish
- if ((msgContext.Message.Type == MqttMsgBase.MQTT_MSG_PUBLISH_TYPE) &&
- (msgContext.Flow == MqttMsgFlow.ToPublish))
- {
- // it's QoS 1 and we haven't received PUBACK
- if ((msgContext.Message.QosLevel == MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE) &&
- (msgContext.State == MqttMsgState.WaitForPuback))
- {
- // we haven't received PUBACK, we need to resend PUBLISH message
- msgContext.State = MqttMsgState.QueuedQos1;
- }
- // it's QoS 2
- else if (msgContext.Message.QosLevel == MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE)
- {
- // we haven't received PUBREC, we need to resend PUBLISH message
- if (msgContext.State == MqttMsgState.WaitForPubrec)
- {
- msgContext.State = MqttMsgState.QueuedQos2;
- }
- // we haven't received PUBCOMP, we need to resend PUBREL for it
- else if (msgContext.State == MqttMsgState.WaitForPubcomp)
- {
- msgContext.State = MqttMsgState.SendPubrel;
- }
- }
- }
- }
- }
-
- // unlock process inflight queue
- this.inflightWaitHandle.Set();
- }
- else
- {
- // create new session
- this.session = new MqttClientSession(this.ClientId);
- }
- }
- // clean any previous session
- else
- {
- if (this.session != null)
- this.session.Clear();
- }
- }
-
-#if BROKER
-
- ///
- /// Load a given session
- ///
- /// MQTT Client session to load
- public void LoadSession(MqttClientSession session)
- {
- // if not clean session
- if (!this.CleanSession)
- {
- // set the session ...
- this.session = session;
- // ... and restore it
- this.RestoreSession();
- }
- }
-#endif
-
- ///
- /// Generate the next message identifier
- ///
- /// Message identifier
- private ushort GetMessageId()
- {
- // if 0 or max UInt16, it becomes 1 (first valid messageId)
- this.messageIdCounter = ((this.messageIdCounter % UInt16.MaxValue) != 0) ? (ushort)(this.messageIdCounter + 1) : (ushort)1;
- return this.messageIdCounter;
- }
-
- ///
- /// Finder class for PUBLISH message inside a queue
- ///
- internal class MqttMsgContextFinder
- {
- // PUBLISH message id
- internal ushort MessageId { get; set; }
- // message flow into inflight queue
- internal MqttMsgFlow Flow { get; set; }
-
- ///
- /// Constructor
- ///
- /// Message Id
- /// Message flow inside inflight queue
- internal MqttMsgContextFinder(ushort messageId, MqttMsgFlow flow)
- {
- this.MessageId = messageId;
- this.Flow = flow;
- }
-
- internal bool Find(object item)
- {
- MqttMsgContext msgCtx = (MqttMsgContext)item;
- return ((msgCtx.Message.Type == MqttMsgBase.MQTT_MSG_PUBLISH_TYPE) &&
- (msgCtx.Message.MessageId == this.MessageId) &&
- msgCtx.Flow == this.Flow);
-
- }
- }
- }
-
- ///
- /// MQTT protocol version
- ///
- public enum MqttProtocolVersion
- {
- Version_3_1 = MqttMsgConnect.PROTOCOL_VERSION_V3_1,
- Version_3_1_1 = MqttMsgConnect.PROTOCOL_VERSION_V3_1_1
- }
-}
diff --git a/mqtt/M2Mqtt/MqttSecurity.cs b/mqtt/M2Mqtt/MqttSecurity.cs
deleted file mode 100644
index b19f108..0000000
--- a/mqtt/M2Mqtt/MqttSecurity.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
-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
-*/
-
-namespace uPLibrary.Networking.M2Mqtt
-{
- ///
- /// Supported SSL/TLS protocol versions
- ///
- public enum MqttSslProtocols
- {
- None,
- SSLv3,
- TLSv1_0,
- TLSv1_1,
- TLSv1_2
- }
-}
diff --git a/mqtt/M2Mqtt/MqttSettings.cs b/mqtt/M2Mqtt/MqttSettings.cs
deleted file mode 100644
index 994f622..0000000
--- a/mqtt/M2Mqtt/MqttSettings.cs
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
-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
-*/
-
-namespace uPLibrary.Networking.M2Mqtt
-{
- ///
- /// Settings class for the MQTT broker
- ///
- public class MqttSettings
- {
- // default port for MQTT protocol
- public const int MQTT_BROKER_DEFAULT_PORT = 1883;
- public const int MQTT_BROKER_DEFAULT_SSL_PORT = 8883;
- // default timeout on receiving from client
- public const int MQTT_DEFAULT_TIMEOUT = 30000;
- // max publish, subscribe and unsubscribe retry for QoS Level 1 or 2
- public const int MQTT_ATTEMPTS_RETRY = 3;
- // delay for retry publish, subscribe and unsubscribe for QoS Level 1 or 2
- public const int MQTT_DELAY_RETRY = 10000;
- // broker need to receive the first message (CONNECT)
- // within a reasonable amount of time after TCP/IP connection
- public const int MQTT_CONNECT_TIMEOUT = 30000;
- // default inflight queue size
- public const int MQTT_MAX_INFLIGHT_QUEUE_SIZE = int.MaxValue;
-
- ///
- /// Listening connection port
- ///
- public int Port { get; internal set; }
-
- ///
- /// Listening connection SSL port
- ///
- public int SslPort { get; internal set; }
-
- ///
- /// Timeout on client connection (before receiving CONNECT message)
- ///
- public int TimeoutOnConnection { get; internal set; }
-
- ///
- /// Timeout on receiving
- ///
- public int TimeoutOnReceiving { get; internal set; }
-
- ///
- /// Attempts on retry
- ///
- public int AttemptsOnRetry { get; internal set; }
-
- ///
- /// Delay on retry
- ///
- public int DelayOnRetry { get; internal set; }
-
- ///
- /// Inflight queue size
- ///
- public int InflightQueueSize { get; set; }
-
- ///
- /// Singleton instance of settings
- ///
- public static MqttSettings Instance
- {
- get
- {
- if (instance == null)
- instance = new MqttSettings();
- return instance;
- }
- }
-
- // singleton instance
- private static MqttSettings instance;
-
- ///
- /// Constructor
- ///
- private MqttSettings()
- {
- this.Port = MQTT_BROKER_DEFAULT_PORT;
- this.SslPort = MQTT_BROKER_DEFAULT_SSL_PORT;
- this.TimeoutOnReceiving = MQTT_DEFAULT_TIMEOUT;
- this.AttemptsOnRetry = MQTT_ATTEMPTS_RETRY;
- this.DelayOnRetry = MQTT_DELAY_RETRY;
- this.TimeoutOnConnection = MQTT_CONNECT_TIMEOUT;
- this.InflightQueueSize = MQTT_MAX_INFLIGHT_QUEUE_SIZE;
- }
- }
-}
diff --git a/mqtt/M2Mqtt/Net/Fx.cs b/mqtt/M2Mqtt/Net/Fx.cs
deleted file mode 100644
index 3fcc505..0000000
--- a/mqtt/M2Mqtt/Net/Fx.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
-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
-*/
-
-using System.Threading;
-
-namespace uPLibrary.Networking.M2Mqtt
-{
- ///
- /// Support methods fos specific framework
- ///
- public class Fx
- {
- public static void StartThread(ThreadStart threadStart)
- {
- new Thread(threadStart).Start();
- }
-
- public static void SleepThread(int millisecondsTimeout)
- {
- Thread.Sleep(millisecondsTimeout);
- }
- }
-}
diff --git a/mqtt/M2Mqtt/Net/MqttNetworkChannel.cs b/mqtt/M2Mqtt/Net/MqttNetworkChannel.cs
deleted file mode 100644
index c98879a..0000000
--- a/mqtt/M2Mqtt/Net/MqttNetworkChannel.cs
+++ /dev/null
@@ -1,472 +0,0 @@
-/*
-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;
-
-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/Properties/AssemblyInfo.cs b/mqtt/M2Mqtt/Properties/AssemblyInfo.cs
deleted file mode 100644
index b218618..0000000
--- a/mqtt/M2Mqtt/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-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
-*/
-
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("M2Mqtt")]
-[assembly: AssemblyDescription("MQTT Client Library for M2M communication")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Paolo Patierno")]
-[assembly: AssemblyProduct("M2Mqtt")]
-[assembly: AssemblyCopyright("Copyright © Paolo Patierno 2014")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-[assembly: AssemblyVersion("4.3.0.0")]
-// to avoid compilation error (AssemblyFileVersionAttribute doesn't exist) under .Net CF 3.5
-#if !WindowsCE
-[assembly: AssemblyFileVersion("4.3.0.0")]
-#endif
\ No newline at end of file
diff --git a/mqtt/M2Mqtt/Session/MqttBrokerSession.cs b/mqtt/M2Mqtt/Session/MqttBrokerSession.cs
deleted file mode 100644
index 859213c..0000000
--- a/mqtt/M2Mqtt/Session/MqttBrokerSession.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-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 BROKER
-using System.Collections;
-using System.Collections.Generic;
-using uPLibrary.Networking.M2Mqtt.Managers;
-using uPLibrary.Networking.M2Mqtt.Messages;
-
-namespace uPLibrary.Networking.M2Mqtt.Session
-{
- ///
- /// MQTT Broker Session
- ///
- public class MqttBrokerSession : MqttSession
- {
- ///
- /// Client related to the subscription
- ///
- public MqttClient Client { get; set; }
-
- ///
- /// Subscriptions for the client session
- ///
- public List Subscriptions;
-
- ///
- /// Outgoing messages to publish
- ///
- public Queue OutgoingMessages;
-
- ///
- /// Constructor
- ///
- public MqttBrokerSession()
- : base()
- {
- this.Client = null;
- this.Subscriptions = new List();
- this.OutgoingMessages = new Queue();
- }
-
- public override void Clear()
- {
- base.Clear();
- this.Client = null;
- this.Subscriptions.Clear();
- this.OutgoingMessages.Clear();
- }
- }
-}
-#endif
\ No newline at end of file
diff --git a/mqtt/M2Mqtt/Session/MqttClientSession.cs b/mqtt/M2Mqtt/Session/MqttClientSession.cs
deleted file mode 100644
index 7613880..0000000
--- a/mqtt/M2Mqtt/Session/MqttClientSession.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
-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
-*/
-
-namespace uPLibrary.Networking.M2Mqtt.Session
-{
- ///
- /// MQTT Client Session
- ///
- public class MqttClientSession : MqttSession
- {
- ///
- /// Constructor
- ///
- /// Client Id to create session
- public MqttClientSession(string clientId)
- : base(clientId)
- {
- }
- }
-}
diff --git a/mqtt/M2Mqtt/Session/MqttSession.cs b/mqtt/M2Mqtt/Session/MqttSession.cs
deleted file mode 100644
index 712a854..0000000
--- a/mqtt/M2Mqtt/Session/MqttSession.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
-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
-*/
-
-using System.Collections;
-
-namespace uPLibrary.Networking.M2Mqtt.Session
-{
- ///
- /// MQTT Session base class
- ///
- public abstract class MqttSession
- {
- ///
- /// Client Id
- ///
- public string ClientId { get; set; }
-
- ///
- /// Messages inflight during session
- ///
- public Hashtable InflightMessages { get; set; }
-
- ///
- /// Constructor
- ///
- public MqttSession()
- : this(null)
- {
- }
-
- ///
- /// Constructor
- ///
- /// Client Id to create session
- public MqttSession(string clientId)
- {
- this.ClientId = clientId;
- this.InflightMessages = new Hashtable();
- }
-
- ///
- /// Clean session
- ///
- public virtual void Clear()
- {
- this.ClientId = null;
- this.InflightMessages.Clear();
- }
- }
-}
diff --git a/mqtt/M2Mqtt/Utility/QueueExtension.cs b/mqtt/M2Mqtt/Utility/QueueExtension.cs
deleted file mode 100644
index 70175c3..0000000
--- a/mqtt/M2Mqtt/Utility/QueueExtension.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-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
-*/
-
-using System;
-using System.Collections;
-
-namespace uPLibrary.Networking.M2Mqtt.Utility
-{
- ///
- /// Extension class for a Queue
- ///
- internal static class QueueExtension
- {
- ///
- /// Predicate for searching inside a queue
- ///
- /// Item of the queue
- /// Result of predicate
- internal delegate bool QueuePredicate(object item);
-
- ///
- /// Get (without removing) an item from queue based on predicate
- ///
- /// Queue in which to search
- /// Predicate to verify to get item
- /// Item matches the predicate
- internal static object Get(Queue queue, QueuePredicate predicate)
- {
- foreach (var item in queue)
- {
- if (predicate(item))
- return item;
- }
- return null;
- }
- }
-}
diff --git a/mqtt/M2Mqtt/Utility/Trace.cs b/mqtt/M2Mqtt/Utility/Trace.cs
deleted file mode 100644
index c299ebe..0000000
--- a/mqtt/M2Mqtt/Utility/Trace.cs
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
-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
-*/
-
-using System.Diagnostics;
-
-namespace uPLibrary.Networking.M2Mqtt.Utility
-{
- ///
- /// Tracing levels
- ///
- public enum TraceLevel
- {
- Error = 0x01,
- Warning = 0x02,
- Information = 0x04,
- Verbose = 0x0F,
- Frame = 0x10,
- Queuing = 0x20
- }
-
- // delegate for writing trace
- public delegate void WriteTrace(string format, params object[] args);
-
- ///
- /// Tracing class
- ///
- public static class Trace
- {
- public static TraceLevel TraceLevel;
- public static WriteTrace TraceListener;
-
- [Conditional("DEBUG")]
- public static void Debug(string format, params object[] args)
- {
- if (TraceListener != null)
- {
- TraceListener(format, args);
- }
- }
-
- public static void WriteLine(TraceLevel level, string format)
- {
- if (TraceListener != null && (level & TraceLevel) > 0)
- {
- TraceListener(format);
- }
- }
-
- public static void WriteLine(TraceLevel level, string format, object arg1)
- {
- if (TraceListener != null && (level & TraceLevel) > 0)
- {
- TraceListener(format, arg1);
- }
- }
-
- public static void WriteLine(TraceLevel level, string format, object arg1, object arg2)
- {
- if (TraceListener != null && (level & TraceLevel) > 0)
- {
- TraceListener(format, arg1, arg2);
- }
- }
-
- public static void WriteLine(TraceLevel level, string format, object arg1, object arg2, object arg3)
- {
- if (TraceListener != null && (level & TraceLevel) > 0)
- {
- TraceListener(format, arg1, arg2, arg3);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/mqtt/M2Mqtt/WinRT/Fx.cs b/mqtt/M2Mqtt/WinRT/Fx.cs
deleted file mode 100644
index 6d62d28..0000000
--- a/mqtt/M2Mqtt/WinRT/Fx.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
-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
-*/
-
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace uPLibrary.Networking.M2Mqtt
-{
- ///
- /// Support methods fos specific framework
- ///
- public class Fx
- {
-
- public delegate void ThreadStart();
- public static void StartThread(ThreadStart threadStart)
- {
- Task.Factory.StartNew(o => ((ThreadStart)o)(), threadStart);
- }
-
- public static void SleepThread(int millisecondsTimeout) { Task.Delay(millisecondsTimeout).RunSynchronously(); }
- }
-}
diff --git a/mqtt/M2Mqtt/WinRT/Hashtable.cs b/mqtt/M2Mqtt/WinRT/Hashtable.cs
deleted file mode 100644
index a42532b..0000000
--- a/mqtt/M2Mqtt/WinRT/Hashtable.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
-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
-*/
-
-using System.Collections.Generic;
-
-namespace uPLibrary.Networking.M2Mqtt
-{
- ///
- /// Wrapper Hashtable class for generic Dictionary (the only available in WinRT)
- ///
- public class Hashtable : Dictionary