diff --git a/M2Mqtt/Exceptions/MqttClientException.cs b/M2Mqtt/Exceptions/MqttClientException.cs
index cd8303f..d26ddfb 100644
--- a/M2Mqtt/Exceptions/MqttClientException.cs
+++ b/M2Mqtt/Exceptions/MqttClientException.cs
@@ -16,117 +16,104 @@ Contributors:
using System;
-namespace uPLibrary.Networking.M2Mqtt.Exceptions
-{
+namespace uPLibrary.Networking.M2Mqtt.Exceptions {
+ ///
+ /// MQTT client exception
+ ///
+ public class MqttClientException : Exception {
///
- /// MQTT client exception
+ /// Constructor
///
- 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; }
- }
- }
-
+ /// Error code
+ public MqttClientException(MqttClientErrorCode errorCode) => this.ErrorCode = errorCode;
+
///
- /// MQTT client erroro code
+ /// Error 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
- }
+ public MqttClientErrorCode ErrorCode { get; set; }
+ }
+
+ ///
+ /// 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/M2Mqtt/Exceptions/MqttCommunicationException.cs b/M2Mqtt/Exceptions/MqttCommunicationException.cs
index 6b916cc..f995e94 100644
--- a/M2Mqtt/Exceptions/MqttCommunicationException.cs
+++ b/M2Mqtt/Exceptions/MqttCommunicationException.cs
@@ -16,27 +16,23 @@ Contributors:
using System;
-namespace uPLibrary.Networking.M2Mqtt.Exceptions
-{
+namespace uPLibrary.Networking.M2Mqtt.Exceptions {
+ ///
+ /// Exception due to error communication with broker on socket
+ ///
+ public class MqttCommunicationException : Exception {
///
- /// Exception due to error communication with broker on socket
+ /// Default constructor
///
- public class MqttCommunicationException : Exception
- {
- ///
- /// Default constructor
- ///
- public MqttCommunicationException()
- {
- }
-
- ///
- /// Constructor
- ///
- /// Inner Exception
- public MqttCommunicationException(Exception e)
- : base(String.Empty, e)
- {
- }
- }
+ public MqttCommunicationException() {
+ }
+
+ ///
+ /// Constructor
+ ///
+ /// Inner Exception
+ public MqttCommunicationException(Exception e)
+ : base(String.Empty, e) {
+ }
+ }
}
diff --git a/M2Mqtt/Exceptions/MqttConnectionException.cs b/M2Mqtt/Exceptions/MqttConnectionException.cs
index 3203c7e..2ad847f 100644
--- a/M2Mqtt/Exceptions/MqttConnectionException.cs
+++ b/M2Mqtt/Exceptions/MqttConnectionException.cs
@@ -16,16 +16,13 @@ Contributors:
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)
- {
- }
- }
+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/M2Mqtt/Exceptions/MqttTimeoutException.cs b/M2Mqtt/Exceptions/MqttTimeoutException.cs
index b15e69e..bd25dcc 100644
--- a/M2Mqtt/Exceptions/MqttTimeoutException.cs
+++ b/M2Mqtt/Exceptions/MqttTimeoutException.cs
@@ -16,12 +16,10 @@ Contributors:
using System;
-namespace uPLibrary.Networking.M2Mqtt.Exceptions
-{
- ///
- /// Timeout on receiving from broker exception
- ///
- public class MqttTimeoutException : Exception
- {
- }
+namespace uPLibrary.Networking.M2Mqtt.Exceptions {
+ ///
+ /// Timeout on receiving from broker exception
+ ///
+ public class MqttTimeoutException : Exception {
+ }
}
diff --git a/M2Mqtt/IMqttNetworkChannel.cs b/M2Mqtt/IMqttNetworkChannel.cs
index f4ff90f..0a1e86e 100644
--- a/M2Mqtt/IMqttNetworkChannel.cs
+++ b/M2Mqtt/IMqttNetworkChannel.cs
@@ -15,55 +15,52 @@ Contributors:
*/
using System;
-using System.Text;
-namespace uPLibrary.Networking.M2Mqtt
-{
+namespace uPLibrary.Networking.M2Mqtt {
+ ///
+ /// Interface for channel under MQTT library
+ ///
+ public interface IMqttNetworkChannel {
///
- /// Interface for channel under MQTT library
+ /// Data available on channel
///
- 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();
- }
+ Boolean DataAvailable { get; }
+
+ ///
+ /// Receive data from the network channel
+ ///
+ /// Data buffer for receiving data
+ /// Number of bytes received
+ Int32 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
+ Int32 Receive(Byte[] buffer, Int32 timeout);
+
+ ///
+ /// Send data on the network channel to the broker
+ ///
+ /// Data buffer to send
+ /// Number of byte sent
+ Int32 Send(Byte[] buffer);
+
+ ///
+ /// Close the network channel
+ ///
+ void Close();
+
+ ///
+ /// Connect to remote server
+ ///
+ void Connect();
+
+ ///
+ /// Accept client connection
+ ///
+ void Accept();
+ }
}
diff --git a/M2Mqtt/Internal/InternalEvent.cs b/M2Mqtt/Internal/InternalEvent.cs
index 7f298c7..ec196c6 100644
--- a/M2Mqtt/Internal/InternalEvent.cs
+++ b/M2Mqtt/Internal/InternalEvent.cs
@@ -14,12 +14,10 @@ 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
- {
- }
+namespace uPLibrary.Networking.M2Mqtt.Internal {
+ ///
+ /// Generic internal event for dispatching
+ ///
+ public abstract class InternalEvent {
+ }
}
diff --git a/M2Mqtt/Internal/MsgInternalEvent.cs b/M2Mqtt/Internal/MsgInternalEvent.cs
index 8cf46a4..8be6658 100644
--- a/M2Mqtt/Internal/MsgInternalEvent.cs
+++ b/M2Mqtt/Internal/MsgInternalEvent.cs
@@ -16,36 +16,26 @@ Contributors:
using uPLibrary.Networking.M2Mqtt.Messages;
-namespace uPLibrary.Networking.M2Mqtt.Internal
-{
+namespace uPLibrary.Networking.M2Mqtt.Internal {
+ ///
+ /// Internal event with a message
+ ///
+ public class MsgInternalEvent : InternalEvent {
+ #region Properties ...
+
///
- /// Internal event with a message
+ /// Related 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;
- }
- }
+ public MqttMsgBase Message { get; set; }
+
+ #endregion
+
+ // related message
+
+ ///
+ /// Constructor
+ ///
+ /// Related message
+ public MsgInternalEvent(MqttMsgBase msg) => this.Message = msg;
+ }
}
diff --git a/M2Mqtt/Internal/MsgPublishedInternalEvent.cs b/M2Mqtt/Internal/MsgPublishedInternalEvent.cs
index 5a7f182..062a8d2 100644
--- a/M2Mqtt/Internal/MsgPublishedInternalEvent.cs
+++ b/M2Mqtt/Internal/MsgPublishedInternalEvent.cs
@@ -14,40 +14,31 @@ Contributors:
Paolo Patierno - initial API and implementation and/or initial documentation
*/
+using System;
using uPLibrary.Networking.M2Mqtt.Messages;
-namespace uPLibrary.Networking.M2Mqtt.Internal
-{
+namespace uPLibrary.Networking.M2Mqtt.Internal {
+ ///
+ /// Internal event for a published message
+ ///
+ public class MsgPublishedInternalEvent : MsgInternalEvent {
+ #region Properties...
+
///
- /// Internal event for a published message
+ /// Message published (or failed due to retries)
///
- 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;
- }
- }
+ public Boolean IsPublished { get; internal set; }
+
+ #endregion
+
+ // published flag
+
+ ///
+ /// Constructor
+ ///
+ /// Message published
+ /// Publish flag
+ public MsgPublishedInternalEvent(MqttMsgBase msg, Boolean isPublished)
+ : base(msg) => this.IsPublished = isPublished;
+ }
}
diff --git a/M2Mqtt/M2Mqtt_Core.csproj b/M2Mqtt/M2Mqtt_Core.csproj
new file mode 100644
index 0000000..f18ab8e
--- /dev/null
+++ b/M2Mqtt/M2Mqtt_Core.csproj
@@ -0,0 +1,24 @@
+
+
+
+ netcoreapp3.0
+ M2Mqtt
+ uPLibrary.Networking.M2Mqtt
+ MQTT Client Library for M2M communication
+ Paolo Patierno
+ Paolo Patierno
+ Copyright © Paolo Patierno 2014
+ 4.3.0
+ 4.3.0
+ 4.3.0
+
+
+
+ TRACE;SSL
+
+
+
+ TRACE;SSL
+
+
+
diff --git a/M2Mqtt/Messages/MqttMsgBase.cs b/M2Mqtt/Messages/MqttMsgBase.cs
index 870fe5f..407adbd 100644
--- a/M2Mqtt/Messages/MqttMsgBase.cs
+++ b/M2Mqtt/Messages/MqttMsgBase.cs
@@ -17,259 +17,220 @@ Contributors:
using System;
using System.Text;
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
+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 UInt16 MAX_TOPIC_LENGTH = 65535;
+ internal const UInt16 MIN_TOPIC_LENGTH = 1;
+ internal const Byte MESSAGE_ID_SIZE = 2;
+
+ #endregion
+
+ #region Properties...
+
///
- /// Base class for all MQTT messages
+ /// Message type
///
- 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;
- }
-
+ public Byte Type { get; set; }
+
+ ///
+ /// Duplicate message flag
+ ///
+ public Boolean DupFlag { get; set; }
+
+ ///
+ /// Quality of Service level
+ ///
+ public Byte QosLevel { get; set; }
+
+ ///
+ /// Retain message flag
+ ///
+ public Boolean Retain { get; set; }
+
+ ///
+ /// Message identifier for the message
+ ///
+ public UInt16 MessageId { get; set; }
+
+ #endregion
+
+ // message type
+ // duplicate delivery
+ // quality of service level
+ // retain flag
+ // message identifier
+
+ ///
+ /// 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 Int32 EncodeRemainingLength(Int32 remainingLength, Byte[] buffer, Int32 index) {
+ do {
+ Int32 digit = remainingLength % 128;
+ remainingLength /= 128;
+ if (remainingLength > 0) {
+ 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 Int32 DecodeRemainingLength(IMqttNetworkChannel channel) {
+ Int32 multiplier = 1;
+ Int32 value = 0;
+ Byte[] nextByte = new Byte[1];
+ Int32 digit;
+ 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;
- }
+ ///
+ /// 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("(");
+ Boolean addComma = false;
+ for (Int32 i = 0; i < fieldValues.Length; i++) {
+ if (fieldValues[i] != null) {
+ if (addComma) {
+ _ = sb.Append(",");
+ }
+
+ _ = sb.Append(fieldNames[i]);
+ _ = sb.Append(":");
+ _ = sb.Append(this.GetStringObject(fieldValues[i]));
+ addComma = true;
+ }
+ }
+ _ = sb.Append(")");
+ }
+
+ return sb.ToString();
+ }
+
+ Object GetStringObject(Object value) {
+ if (value is Byte[] binary) {
+ String hexChars = "0123456789ABCDEF";
+ StringBuilder sb = new StringBuilder(binary.Length * 2);
+ for (Int32 i = 0; i < binary.Length; ++i) {
+ _ = sb.Append(hexChars[binary[i] >> 4]);
+ _ = sb.Append(hexChars[binary[i] & 0x0F]);
+ }
+
+ return sb.ToString();
+ }
+
+ if (value is Object[] list) {
+ StringBuilder sb = new StringBuilder();
+ _ = sb.Append('[');
+ for (Int32 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/M2Mqtt/Messages/MqttMsgConnack.cs b/M2Mqtt/Messages/MqttMsgConnack.cs
index ae5a342..f0e70df 100644
--- a/M2Mqtt/Messages/MqttMsgConnack.cs
+++ b/M2Mqtt/Messages/MqttMsgConnack.cs
@@ -17,175 +17,153 @@ Contributors:
using System;
using uPLibrary.Networking.M2Mqtt.Exceptions;
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
+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
///
- /// Class for CONNACK message from broker to client
+ /// Session present flag
///
- 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()
- {
+ public Boolean SessionPresent { get; set; }
+
+ ///
+ /// Return Code
+ ///
+ public Byte ReturnCode { get; set; }
+
+ #endregion
+
+ // [v3.1.1] session present flag
+
+ ///
+ /// 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
+ Int32 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) {
+ Int32 varHeaderSize = 0;
+ Int32 payloadSize = 0;
+ Int32 remainingLength = 0;
+ Byte[] buffer;
+ Int32 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
+ Int32 fixedHeaderSize = 1;
+
+ Int32 temp = remainingLength;
+ // increase fixed header size based on remaining length
+ // (each remaining length byte can encode until 128)
+ do {
+ fixedHeaderSize++;
+ temp /= 128;
+ } while (temp > 0);
+
+ // allocate buffer for message
+ buffer = new Byte[fixedHeaderSize + varHeaderSize + payloadSize];
+
+ // first fixed header byte
+ buffer[index++] = ProtocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1
+ ? (Byte)((MQTT_MSG_CONNACK_TYPE << MSG_TYPE_OFFSET) | MQTT_MSG_CONNACK_FLAG_BITS)
+ : (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 });
+ this.GetTraceString(
+ "CONNACK",
+ new Object[] { "returnCode" },
+ new Object[] { this.ReturnCode });
#else
- return base.ToString();
+ base.ToString();
#endif
- }
- }
+
+ }
}
diff --git a/M2Mqtt/Messages/MqttMsgConnect.cs b/M2Mqtt/Messages/MqttMsgConnect.cs
index 382cf83..8a11bb6 100644
--- a/M2Mqtt/Messages/MqttMsgConnect.cs
+++ b/M2Mqtt/Messages/MqttMsgConnect.cs
@@ -18,565 +18,481 @@ using System;
using System.Text;
using uPLibrary.Networking.M2Mqtt.Exceptions;
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
+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 Int32 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 UInt16 KEEP_ALIVE_PERIOD_DEFAULT = 60; // seconds
+ internal const UInt16 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...
+
///
- /// Class for CONNECT message from client to broker
+ /// Protocol name
///
- 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()
- {
+ public String ProtocolName { get; set; }
+
+ ///
+ /// Protocol version
+ ///
+ public Byte ProtocolVersion { get; set; }
+
+ ///
+ /// Client identifier
+ ///
+ public String ClientId { get; set; }
+
+ ///
+ /// Will retain flag
+ ///
+ public Boolean WillRetain { get; set; }
+
+ ///
+ /// Will QOS level
+ ///
+ public Byte WillQosLevel { get; set; }
+
+ ///
+ /// Will flag
+ ///
+ public Boolean WillFlag { get; set; }
+
+ ///
+ /// Will topic
+ ///
+ public String WillTopic { get; set; }
+
+ ///
+ /// Will message
+ ///
+ public String WillMessage { get; set; }
+
+ ///
+ /// Username
+ ///
+ public String Username { get; set; }
+
+ ///
+ /// Password
+ ///
+ public String Password { get; set; }
+
+ ///
+ /// Clean session flag
+ ///
+ public Boolean CleanSession { get; set; }
+
+ ///
+ /// Keep alive period
+ ///
+ public UInt16 KeepAlivePeriod { get; set; }
+
+ #endregion
+
+ // protocol name
+
+ // will retain flag
+ // will quality of service level
+
+ ///
+ /// 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,
+ Boolean willRetain,
+ Byte willQosLevel,
+ Boolean willFlag,
+ String willTopic,
+ String willMessage,
+ Boolean cleanSession,
+ UInt16 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;
+ Int32 index = 0;
+ Int32 protNameUtf8Length;
+ Byte[] protNameUtf8;
+ Boolean isUsernameFlag;
+ Boolean isPasswordFlag;
+ Int32 clientIdUtf8Length;
+ Byte[] clientIdUtf8;
+ Int32 willTopicUtf8Length;
+ Byte[] willTopicUtf8;
+ Int32 willMessageUtf8Length;
+ Byte[] willMessageUtf8;
+ Int32 usernameUtf8Length;
+ Byte[] usernameUtf8;
+ Int32 passwordUtf8Length;
+ Byte[] passwordUtf8;
+ MqttMsgConnect msg = new MqttMsgConnect();
+
+ // get remaining length and allocate buffer
+ Int32 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 = (UInt16)((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);
+ msg.Password = new String(Encoding.UTF8.GetChars(passwordUtf8));
+ }
+
+ return msg;
+ }
+
+ public override Byte[] GetBytes(Byte protocolVersion) {
+ Int32 varHeaderSize = 0;
+ Int32 payloadSize = 0;
+ Int32 remainingLength = 0;
+ Byte[] buffer;
+ Int32 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
+ Int32 fixedHeaderSize = 1;
+
+ Int32 temp = remainingLength;
+ // increase fixed header size based on remaining length
+ // (each remaining length byte can encode until 128)
+ do {
+ fixedHeaderSize++;
+ 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);
+ _ = 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 });
+ 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();
+ base.ToString();
#endif
- }
- }
+
+ }
}
diff --git a/M2Mqtt/Messages/MqttMsgConnectEventArgs.cs b/M2Mqtt/Messages/MqttMsgConnectEventArgs.cs
index ce0b3fe..8995f66 100644
--- a/M2Mqtt/Messages/MqttMsgConnectEventArgs.cs
+++ b/M2Mqtt/Messages/MqttMsgConnectEventArgs.cs
@@ -14,31 +14,26 @@ Contributors:
Paolo Patierno - initial API and implementation and/or initial documentation
*/
-#if (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3)
+#if !MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3
using System;
#else
using Microsoft.SPOT;
#endif
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
+namespace uPLibrary.Networking.M2Mqtt.Messages {
+ ///
+ /// Event Args class for CONNECT message received from client
+ ///
+ public class MqttMsgConnectEventArgs : EventArgs {
///
- /// Event Args class for CONNECT message received from client
+ /// 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;
- }
- }
-}
+ public MqttMsgConnect Message { get; private set; }
+
+ ///
+ /// Constructor
+ ///
+ /// CONNECT message received from client
+ public MqttMsgConnectEventArgs(MqttMsgConnect connect) => this.Message = connect;
+ }
+}
diff --git a/M2Mqtt/Messages/MqttMsgContext.cs b/M2Mqtt/Messages/MqttMsgContext.cs
index a2850d7..0b7891a 100644
--- a/M2Mqtt/Messages/MqttMsgContext.cs
+++ b/M2Mqtt/Messages/MqttMsgContext.cs
@@ -15,145 +15,137 @@ Contributors:
*/
using System;
-using System.Text;
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
+namespace uPLibrary.Networking.M2Mqtt.Messages {
+ ///
+ /// Context for MQTT message
+ ///
+ public class MqttMsgContext {
///
- /// Context for MQTT message
+ /// 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
- }
-
+ public MqttMsgBase Message { get; set; }
+
///
/// 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
- }
+ public MqttMsgState State { get; set; }
+
+ ///
+ /// Flow of the message
+ ///
+ public MqttMsgFlow Flow { get; set; }
+
+ ///
+ /// Timestamp in ticks (for retry)
+ ///
+ public Int32 Timestamp { get; set; }
+
+ ///
+ /// Attempt (for retry)
+ ///
+ public Int32 Attempt { get; set; }
+
+ ///
+ /// Unique key
+ ///
+ public String Key => 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/M2Mqtt/Messages/MqttMsgDisconnect.cs b/M2Mqtt/Messages/MqttMsgDisconnect.cs
index d918473..beb4476 100644
--- a/M2Mqtt/Messages/MqttMsgDisconnect.cs
+++ b/M2Mqtt/Messages/MqttMsgDisconnect.cs
@@ -14,73 +14,66 @@ Contributors:
Paolo Patierno - initial API and implementation and/or initial documentation
*/
+using System;
using uPLibrary.Networking.M2Mqtt.Exceptions;
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
+namespace uPLibrary.Networking.M2Mqtt.Messages {
+ ///
+ /// Class for DISCONNECT message from client to broker
+ ///
+ public class MqttMsgDisconnect : MqttMsgBase {
///
- /// Class for DISCONNECT message from client to broker
+ /// Constructor
///
- 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()
- {
+ 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
+ _ = DecodeRemainingLength(channel);
+ // NOTE : remainingLength must be 0
+
+ return msg;
+ }
+
+ public override Byte[] GetBytes(Byte protocolVersion) {
+ Byte[] buffer = new Byte[2];
+ Int32 index = 0;
+
+ // first fixed header byte
+ buffer[index++] = protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1
+ ? (Byte)((MQTT_MSG_DISCONNECT_TYPE << MSG_TYPE_OFFSET) | MQTT_MSG_DISCONNECT_FLAG_BITS)
+ : (Byte)(MQTT_MSG_DISCONNECT_TYPE << MSG_TYPE_OFFSET);
+
+ buffer[index++] = 0x00;
+
+ return buffer;
+ }
+
+ public override String ToString() =>
#if TRACE
- return this.GetTraceString(
- "DISCONNECT",
- null,
- null);
+ this.GetTraceString(
+ "DISCONNECT",
+ null,
+ null);
#else
- return base.ToString();
+ base.ToString();
#endif
- }
- }
+
+ }
}
diff --git a/M2Mqtt/Messages/MqttMsgPingReq.cs b/M2Mqtt/Messages/MqttMsgPingReq.cs
index b46bdb6..0695e53 100644
--- a/M2Mqtt/Messages/MqttMsgPingReq.cs
+++ b/M2Mqtt/Messages/MqttMsgPingReq.cs
@@ -14,73 +14,66 @@ Contributors:
Paolo Patierno - initial API and implementation and/or initial documentation
*/
+using System;
using uPLibrary.Networking.M2Mqtt.Exceptions;
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
+namespace uPLibrary.Networking.M2Mqtt.Messages {
+ ///
+ /// Class for PINGREQ message from client to broker
+ ///
+ public class MqttMsgPingReq : MqttMsgBase {
///
- /// Class for PINGREQ message from client to broker
+ /// Constructor
///
- 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()
- {
+ public MqttMsgPingReq() => this.Type = MQTT_MSG_PINGREQ_TYPE;
+
+ public override Byte[] GetBytes(Byte protocolVersion) {
+ Byte[] buffer = new Byte[2];
+ Int32 index = 0;
+
+ // first fixed header byte
+ buffer[index++] = protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1
+ ? (Byte)((MQTT_MSG_PINGREQ_TYPE << MSG_TYPE_OFFSET) | MQTT_MSG_PINGREQ_FLAG_BITS)
+ : (Byte)(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
+ _ = DecodeRemainingLength(channel);
+
+ return msg;
+ }
+
+ public override String ToString() =>
#if TRACE
- return this.GetTraceString(
- "PINGREQ",
- null,
- null);
+ this.GetTraceString(
+ "PINGREQ",
+ null,
+ null);
#else
- return base.ToString();
+ base.ToString();
#endif
- }
- }
+
+ }
}
diff --git a/M2Mqtt/Messages/MqttMsgPingResp.cs b/M2Mqtt/Messages/MqttMsgPingResp.cs
index 2b028b9..bfae63f 100644
--- a/M2Mqtt/Messages/MqttMsgPingResp.cs
+++ b/M2Mqtt/Messages/MqttMsgPingResp.cs
@@ -17,71 +17,63 @@ Contributors:
using System;
using uPLibrary.Networking.M2Mqtt.Exceptions;
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
+namespace uPLibrary.Networking.M2Mqtt.Messages {
+ ///
+ /// Class for PINGRESP message from client to broker
+ ///
+ public class MqttMsgPingResp : MqttMsgBase {
///
- /// Class for PINGRESP message from client to broker
+ /// Constructor
///
- 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()
- {
+ 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
+ _ = DecodeRemainingLength(channel);
+
+ return msg;
+ }
+
+ public override Byte[] GetBytes(Byte protocolVersion) {
+ Byte[] buffer = new Byte[2];
+ Int32 index = 0;
+
+ // first fixed header byte
+ buffer[index++] = protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1
+ ? (Byte)((MQTT_MSG_PINGRESP_TYPE << MSG_TYPE_OFFSET) | MQTT_MSG_PINGRESP_FLAG_BITS)
+ : (Byte)(MQTT_MSG_PINGRESP_TYPE << MSG_TYPE_OFFSET);
+
+ buffer[index++] = 0x00;
+
+ return buffer;
+ }
+
+ public override String ToString() =>
#if TRACE
- return this.GetTraceString(
- "PINGRESP",
- null,
- null);
+ this.GetTraceString(
+ "PINGRESP",
+ null,
+ null);
#else
- return base.ToString();
+ base.ToString();
#endif
- }
- }
+
+ }
}
diff --git a/M2Mqtt/Messages/MqttMsgPuback.cs b/M2Mqtt/Messages/MqttMsgPuback.cs
index e00e37f..9d59b74 100644
--- a/M2Mqtt/Messages/MqttMsgPuback.cs
+++ b/M2Mqtt/Messages/MqttMsgPuback.cs
@@ -14,112 +14,102 @@ Contributors:
Paolo Patierno - initial API and implementation and/or initial documentation
*/
+using System;
using uPLibrary.Networking.M2Mqtt.Exceptions;
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
+namespace uPLibrary.Networking.M2Mqtt.Messages {
+ ///
+ /// Class for PUBACK message from broker to client
+ ///
+ public class MqttMsgPuback : MqttMsgBase {
///
- /// Class for PUBACK message from broker to client
+ /// Constructor
///
- 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()
- {
+ public MqttMsgPuback() => this.Type = MQTT_MSG_PUBACK_TYPE;
+
+ public override Byte[] GetBytes(Byte protocolVersion) {
+ Int32 varHeaderSize = 0;
+ Int32 payloadSize = 0;
+ Int32 remainingLength = 0;
+ Byte[] buffer;
+ Int32 index = 0;
+
+ // message identifier
+ varHeaderSize += MESSAGE_ID_SIZE;
+
+ remainingLength += varHeaderSize + payloadSize;
+
+ // first byte of fixed header
+ Int32 fixedHeaderSize = 1;
+
+ Int32 temp = remainingLength;
+ // increase fixed header size based on remaining length
+ // (each remaining length byte can encode until 128)
+ do {
+ fixedHeaderSize++;
+ temp /= 128;
+ } while (temp > 0);
+
+ // allocate buffer for message
+ buffer = new Byte[fixedHeaderSize + varHeaderSize + payloadSize];
+
+ // first fixed header byte
+ buffer[index++] = protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1
+ ? (Byte)((MQTT_MSG_PUBACK_TYPE << MSG_TYPE_OFFSET) | MQTT_MSG_PUBACK_FLAG_BITS)
+ : (Byte)(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;
+ Int32 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
+ Int32 remainingLength = MqttMsgBase.DecodeRemainingLength(channel);
+ buffer = new Byte[remainingLength];
+
+ // read bytes from socket...
+ _ = channel.Receive(buffer);
+
+ // message id
+ msg.MessageId = (UInt16)((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 });
+ this.GetTraceString(
+ "PUBACK",
+ new Object[] { "messageId" },
+ new Object[] { this.MessageId });
#else
- return base.ToString();
+ base.ToString();
#endif
- }
- }
+
+ }
}
diff --git a/M2Mqtt/Messages/MqttMsgPubcomp.cs b/M2Mqtt/Messages/MqttMsgPubcomp.cs
index eeabd3b..a88a687 100644
--- a/M2Mqtt/Messages/MqttMsgPubcomp.cs
+++ b/M2Mqtt/Messages/MqttMsgPubcomp.cs
@@ -14,112 +14,102 @@ Contributors:
Paolo Patierno - initial API and implementation and/or initial documentation
*/
+using System;
using uPLibrary.Networking.M2Mqtt.Exceptions;
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
+namespace uPLibrary.Networking.M2Mqtt.Messages {
+ ///
+ /// Class for PUBCOMP message from broker to client
+ ///
+ public class MqttMsgPubcomp : MqttMsgBase {
///
- /// Class for PUBCOMP message from broker to client
+ /// Constructor
///
- 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()
- {
+ public MqttMsgPubcomp() => this.Type = MQTT_MSG_PUBCOMP_TYPE;
+
+ public override Byte[] GetBytes(Byte protocolVersion) {
+ Int32 varHeaderSize = 0;
+ Int32 payloadSize = 0;
+ Int32 remainingLength = 0;
+ Byte[] buffer;
+ Int32 index = 0;
+
+ // message identifier
+ varHeaderSize += MESSAGE_ID_SIZE;
+
+ remainingLength += varHeaderSize + payloadSize;
+
+ // first byte of fixed header
+ Int32 fixedHeaderSize = 1;
+
+ Int32 temp = remainingLength;
+ // increase fixed header size based on remaining length
+ // (each remaining length byte can encode until 128)
+ do {
+ fixedHeaderSize++;
+ temp /= 128;
+ } while (temp > 0);
+
+ // allocate buffer for message
+ buffer = new Byte[fixedHeaderSize + varHeaderSize + payloadSize];
+
+ // first fixed header byte
+ buffer[index++] = protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1
+ ? (Byte)((MQTT_MSG_PUBCOMP_TYPE << MSG_TYPE_OFFSET) | MQTT_MSG_PUBCOMP_FLAG_BITS)
+ : (Byte)(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;
+ Int32 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
+ Int32 remainingLength = MqttMsgBase.DecodeRemainingLength(channel);
+ buffer = new Byte[remainingLength];
+
+ // read bytes from socket...
+ _ = channel.Receive(buffer);
+
+ // message id
+ msg.MessageId = (UInt16)((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 });
+ this.GetTraceString(
+ "PUBCOMP",
+ new Object[] { "messageId" },
+ new Object[] { this.MessageId });
#else
- return base.ToString();
+ base.ToString();
#endif
- }
- }
+
+ }
}
diff --git a/M2Mqtt/Messages/MqttMsgPublish.cs b/M2Mqtt/Messages/MqttMsgPublish.cs
index 0809af9..0f2d0e6 100644
--- a/M2Mqtt/Messages/MqttMsgPublish.cs
+++ b/M2Mqtt/Messages/MqttMsgPublish.cs
@@ -40,9 +40,7 @@ namespace uPLibrary.Networking.M2Mqtt.Messages {
///
/// Constructor
///
- public MqttMsgPublish() {
- this.type = MQTT_MSG_PUBLISH_TYPE;
- }
+ public MqttMsgPublish() => this.Type = MQTT_MSG_PUBLISH_TYPE;
///
/// Constructor
@@ -61,17 +59,16 @@ namespace uPLibrary.Networking.M2Mqtt.Messages {
/// 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.Type = MQTT_MSG_PUBLISH_TYPE;
this.Topic = topic;
this.Message = message;
- this.dupFlag = dupFlag;
- this.qosLevel = qosLevel;
- this.retain = retain;
- this.messageId = 0;
+ 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;
@@ -79,17 +76,17 @@ namespace uPLibrary.Networking.M2Mqtt.Messages {
Int32 index = 0;
// topic can't contain wildcards
- if ((this.Topic.IndexOf('#') != -1) || (this.Topic.IndexOf('+') != -1)) {
+ 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)) {
+ 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) {
+ if (this.QosLevel > QOS_LEVEL_EXACTLY_ONCE) {
throw new MqttClientException(MqttClientErrorCode.QosNotAllowed);
}
@@ -99,7 +96,7 @@ namespace uPLibrary.Networking.M2Mqtt.Messages {
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)) {
+ if (this.QosLevel == QOS_LEVEL_AT_LEAST_ONCE || this.QosLevel == QOS_LEVEL_EXACTLY_ONCE) {
varHeaderSize += MESSAGE_ID_SIZE;
}
@@ -109,30 +106,30 @@ namespace uPLibrary.Networking.M2Mqtt.Messages {
payloadSize += this.Message.Length;
}
- remainingLength += (varHeaderSize + payloadSize);
+ remainingLength += varHeaderSize + payloadSize;
// first byte of fixed header
- fixedHeaderSize = 1;
+ Int32 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;
+ 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;
+ 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);
+ index = this.EncodeRemainingLength(remainingLength, buffer, index);
// topic name
buffer[index++] = (Byte)((topicUtf8.Length >> 8) & 0x00FF); // MSB
@@ -141,22 +138,22 @@ namespace uPLibrary.Networking.M2Mqtt.Messages {
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)) {
+ if (this.QosLevel == QOS_LEVEL_AT_LEAST_ONCE ||
+ this.QosLevel == QOS_LEVEL_EXACTLY_ONCE) {
// check message identifier assigned
- if (this.messageId == 0) {
+ if (this.MessageId == 0) {
throw new MqttClientException(MqttClientErrorCode.WrongMessageId);
}
- buffer[index++] = (Byte)((this.messageId >> 8) & 0x00FF); // MSB
- buffer[index++] = (Byte)(this.messageId & 0x00FF); // LSB
+ 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;
+ _ = this.Message.Length;
}
return buffer;
@@ -177,14 +174,14 @@ namespace uPLibrary.Networking.M2Mqtt.Messages {
MqttMsgPublish msg = new MqttMsgPublish();
// get remaining length and allocate buffer
- Int32 remainingLength = decodeRemainingLength(channel);
+ 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++] << 8) & 0xFF00;
topicUtf8Length |= buffer[index++];
topicUtf8 = new Byte[topicUtf8Length];
Array.Copy(buffer, index, topicUtf8, 0, topicUtf8Length);
@@ -192,22 +189,22 @@ namespace uPLibrary.Networking.M2Mqtt.Messages {
msg.Topic = new String(Encoding.UTF8.GetChars(topicUtf8));
// read QoS level from fixed header
- msg.qosLevel = (Byte)((fixedHeaderFirstByte & QOS_LEVEL_MASK) >> QOS_LEVEL_OFFSET);
+ 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) {
+ 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);
+ 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);
+ 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)) {
+ 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++]);
+ msg.MessageId = (UInt16)((buffer[index++] << 8) & 0xFF00);
+ msg.MessageId |= buffer[index++];
}
// get payload with message data
@@ -220,8 +217,8 @@ namespace uPLibrary.Networking.M2Mqtt.Messages {
// copy first part of payload data received
Array.Copy(buffer, index, msg.Message, messageOffset, received - index);
- remaining -= (received - index);
- messageOffset += (received - index);
+ remaining -= received - index;
+ messageOffset += received - index;
// if payload isn't finished
while (remaining > 0) {
@@ -235,15 +232,15 @@ namespace uPLibrary.Networking.M2Mqtt.Messages {
return msg;
}
- public override String ToString() {
+ public override String ToString() =>
#if TRACE
- return this.GetTraceString(
+ this.GetTraceString(
"PUBLISH",
new Object[] { "messageId", "topic", "message" },
- new Object[] { this.messageId, this.Topic, this.Message });
+ new Object[] { this.MessageId, this.Topic, this.Message });
#else
- return base.ToString();
+ base.ToString();
#endif
- }
+
}
}
diff --git a/M2Mqtt/Messages/MqttMsgPublishEventArgs.cs b/M2Mqtt/Messages/MqttMsgPublishEventArgs.cs
index efb2333..56af34b 100644
--- a/M2Mqtt/Messages/MqttMsgPublishEventArgs.cs
+++ b/M2Mqtt/Messages/MqttMsgPublishEventArgs.cs
@@ -14,98 +14,66 @@ Contributors:
Paolo Patierno - initial API and implementation and/or initial documentation
*/
-#if (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3)
+#if !MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3
using System;
#else
using Microsoft.SPOT;
#endif
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
+namespace uPLibrary.Networking.M2Mqtt.Messages {
+ ///
+ /// Event Args class for PUBLISH message received from broker
+ ///
+ public class MqttMsgPublishEventArgs : EventArgs {
+ #region Properties...
+
///
- /// Event Args class for PUBLISH message received from broker
+ /// Message topic
///
- 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;
- }
- }
+ public String Topic { get; internal set; }
+
+ ///
+ /// Message data
+ ///
+ public Byte[] Message { get; internal set; }
+
+ ///
+ /// Duplicate message flag
+ ///
+ public Boolean DupFlag { get; set; }
+
+ ///
+ /// Quality of Service level
+ ///
+ public Byte QosLevel { get; internal set; }
+
+ ///
+ /// Retain message flag
+ ///
+ public Boolean Retain { get; internal set; }
+
+ #endregion
+
+ // message topic
+
+ ///
+ /// Constructor
+ ///
+ /// Message topic
+ /// Message data
+ /// Duplicate delivery flag
+ /// Quality of Service level
+ /// Retain flag
+ public MqttMsgPublishEventArgs(String topic,
+ Byte[] message,
+ Boolean dupFlag,
+ Byte qosLevel,
+ Boolean retain) {
+ this.Topic = topic;
+ this.Message = message;
+ this.DupFlag = dupFlag;
+ this.QosLevel = qosLevel;
+ this.Retain = retain;
+ }
+ }
}
diff --git a/M2Mqtt/Messages/MqttMsgPublishedEventArgs.cs b/M2Mqtt/Messages/MqttMsgPublishedEventArgs.cs
index e507c38..ef040f0 100644
--- a/M2Mqtt/Messages/MqttMsgPublishedEventArgs.cs
+++ b/M2Mqtt/Messages/MqttMsgPublishedEventArgs.cs
@@ -14,65 +14,49 @@ Contributors:
Paolo Patierno - initial API and implementation and/or initial documentation
*/
-#if (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3)
+#if !MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3
using System;
#else
using Microsoft.SPOT;
#endif
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
+namespace uPLibrary.Networking.M2Mqtt.Messages {
+ ///
+ /// Event Args class for published message
+ ///
+ public class MqttMsgPublishedEventArgs : EventArgs {
+ #region Properties...
+
///
- /// Event Args class for published message
+ /// Message identifier
///
- 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;
- }
- }
+ public UInt16 MessageId { get; internal set; }
+
+ ///
+ /// Message published (or failed due to retries)
+ ///
+ public Boolean IsPublished { get; internal set; }
+
+ #endregion
+
+ // message identifier
+
+ ///
+ /// Constructor (published message)
+ ///
+ /// Message identifier published
+ public MqttMsgPublishedEventArgs(UInt16 messageId)
+ : this(messageId, true) {
+ }
+
+ ///
+ /// Constructor
+ ///
+ /// Message identifier
+ /// Publish flag
+ public MqttMsgPublishedEventArgs(UInt16 messageId, Boolean isPublished) {
+ this.MessageId = messageId;
+ this.IsPublished = isPublished;
+ }
+ }
}
diff --git a/M2Mqtt/Messages/MqttMsgPubrec.cs b/M2Mqtt/Messages/MqttMsgPubrec.cs
index 1855bf9..a37d604 100644
--- a/M2Mqtt/Messages/MqttMsgPubrec.cs
+++ b/M2Mqtt/Messages/MqttMsgPubrec.cs
@@ -14,112 +14,102 @@ Contributors:
Paolo Patierno - initial API and implementation and/or initial documentation
*/
+using System;
using uPLibrary.Networking.M2Mqtt.Exceptions;
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
+namespace uPLibrary.Networking.M2Mqtt.Messages {
+ ///
+ /// Class for PUBREC message from broker to client
+ ///
+ public class MqttMsgPubrec : MqttMsgBase {
///
- /// Class for PUBREC message from broker to client
+ /// Constructor
///
- 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()
- {
+ public MqttMsgPubrec() => this.Type = MQTT_MSG_PUBREC_TYPE;
+
+ public override Byte[] GetBytes(Byte protocolVersion) {
+ Int32 varHeaderSize = 0;
+ Int32 payloadSize = 0;
+ Int32 remainingLength = 0;
+ Byte[] buffer;
+ Int32 index = 0;
+
+ // message identifier
+ varHeaderSize += MESSAGE_ID_SIZE;
+
+ remainingLength += varHeaderSize + payloadSize;
+
+ // first byte of fixed header
+ Int32 fixedHeaderSize = 1;
+
+ Int32 temp = remainingLength;
+ // increase fixed header size based on remaining length
+ // (each remaining length byte can encode until 128)
+ do {
+ fixedHeaderSize++;
+ temp /= 128;
+ } while (temp > 0);
+
+ // allocate buffer for message
+ buffer = new Byte[fixedHeaderSize + varHeaderSize + payloadSize];
+
+ // first fixed header byte
+ buffer[index++] = protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1
+ ? (Byte)((MQTT_MSG_PUBREC_TYPE << MSG_TYPE_OFFSET) | MQTT_MSG_PUBREC_FLAG_BITS)
+ : (Byte)(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;
+ Int32 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
+ Int32 remainingLength = MqttMsgBase.DecodeRemainingLength(channel);
+ buffer = new Byte[remainingLength];
+
+ // read bytes from socket...
+ _ = channel.Receive(buffer);
+
+ // message id
+ msg.MessageId = (UInt16)((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 });
+ this.GetTraceString(
+ "PUBREC",
+ new Object[] { "messageId" },
+ new Object[] { this.MessageId });
#else
- return base.ToString();
+ base.ToString();
#endif
- }
- }
+
+ }
}
diff --git a/M2Mqtt/Messages/MqttMsgPubrel.cs b/M2Mqtt/Messages/MqttMsgPubrel.cs
index e43ca91..c2cc8b1 100644
--- a/M2Mqtt/Messages/MqttMsgPubrel.cs
+++ b/M2Mqtt/Messages/MqttMsgPubrel.cs
@@ -16,127 +16,117 @@ Contributors:
using uPLibrary.Networking.M2Mqtt.Exceptions;
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
+namespace uPLibrary.Networking.M2Mqtt.Messages {
+ ///
+ /// Class for PUBREL message from client top broker
+ ///
+ public class MqttMsgPubrel : MqttMsgBase {
///
- /// Class for PUBREL message from client top broker
+ /// Constructor
///
- 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()
- {
+ 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 System.Byte[] GetBytes(System.Byte protocolVersion) {
+ System.Int32 varHeaderSize = 0;
+ System.Int32 payloadSize = 0;
+ System.Int32 remainingLength = 0;
+ System.Byte[] buffer;
+ System.Int32 index = 0;
+
+ // message identifier
+ varHeaderSize += MESSAGE_ID_SIZE;
+
+ remainingLength += varHeaderSize + payloadSize;
+
+ // first byte of fixed header
+ System.Int32 fixedHeaderSize = 1;
+
+ System.Int32 temp = remainingLength;
+ // increase fixed header size based on remaining length
+ // (each remaining length byte can encode until 128)
+ do {
+ fixedHeaderSize++;
+ temp /= 128;
+ } while (temp > 0);
+
+ // allocate buffer for message
+ buffer = new System.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] = (System.Byte)((MQTT_MSG_PUBREL_TYPE << MSG_TYPE_OFFSET) |
+ (this.QosLevel << QOS_LEVEL_OFFSET));
+ buffer[index] |= this.DupFlag ? (System.Byte)(1 << DUP_FLAG_OFFSET) : (System.Byte)0x00;
+ index++;
+ }
+
+ // encode remaining length
+ index = this.EncodeRemainingLength(remainingLength, buffer, index);
+
+ // get next message identifier
+ buffer[index++] = (System.Byte)((this.MessageId >> 8) & 0x00FF); // MSB
+ buffer[index++] = (System.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(System.Byte fixedHeaderFirstByte, System.Byte protocolVersion, IMqttNetworkChannel channel) {
+ System.Byte[] buffer;
+ System.Int32 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
+ System.Int32 remainingLength = MqttMsgBase.DecodeRemainingLength(channel);
+ buffer = new System.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 = (System.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 = (System.UInt16)((buffer[index++] << 8) & 0xFF00);
+ msg.MessageId |= buffer[index++];
+
+ return msg;
+ }
+
+ public override System.String ToString() =>
#if TRACE
- return this.GetTraceString(
- "PUBREL",
- new object[] { "messageId" },
- new object[] { this.messageId });
+ this.GetTraceString(
+ "PUBREL",
+ new System.Object[] { "messageId" },
+ new System.Object[] { this.MessageId });
#else
- return base.ToString();
+ base.ToString();
#endif
- }
- }
+
+ }
}
diff --git a/M2Mqtt/Messages/MqttMsgSuback.cs b/M2Mqtt/Messages/MqttMsgSuback.cs
index 6ecfd0d..724e291 100644
--- a/M2Mqtt/Messages/MqttMsgSuback.cs
+++ b/M2Mqtt/Messages/MqttMsgSuback.cs
@@ -17,146 +17,127 @@ Contributors:
using System;
using uPLibrary.Networking.M2Mqtt.Exceptions;
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
+namespace uPLibrary.Networking.M2Mqtt.Messages {
+ ///
+ /// Class for SUBACK message from broker to client
+ ///
+ public class MqttMsgSuback : MqttMsgBase {
+ #region Properties...
+
///
- /// Class for SUBACK message from broker to client
+ /// List of granted QOS Levels
///
- 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()
- {
+ public Byte[] GrantedQoSLevels { get; set; }
+
+ #endregion
+
+ // granted QOS levels
+
+ ///
+ /// 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;
+ Int32 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
+ Int32 remainingLength = MqttMsgBase.DecodeRemainingLength(channel);
+ buffer = new Byte[remainingLength];
+
+ // read bytes from socket...
+ _ = channel.Receive(buffer);
+
+ // message id
+ msg.MessageId = (UInt16)((buffer[index++] << 8) & 0xFF00);
+ msg.MessageId |= buffer[index++];
+
+ // payload contains QoS levels granted
+ msg.GrantedQoSLevels = new Byte[remainingLength - MESSAGE_ID_SIZE];
+ Int32 qosIdx = 0;
+ do {
+ msg.GrantedQoSLevels[qosIdx++] = buffer[index++];
+ } while (index < remainingLength);
+
+ return msg;
+ }
+
+ public override Byte[] GetBytes(Byte protocolVersion) {
+ Int32 varHeaderSize = 0;
+ Int32 payloadSize = 0;
+ Int32 remainingLength = 0;
+ Byte[] buffer;
+ Int32 index = 0;
+
+ // message identifier
+ varHeaderSize += MESSAGE_ID_SIZE;
+
+ Int32 grantedQosIdx;
+ for (grantedQosIdx = 0; grantedQosIdx < this.GrantedQoSLevels.Length; grantedQosIdx++) {
+ payloadSize++;
+ }
+
+ remainingLength += varHeaderSize + payloadSize;
+
+ // first byte of fixed header
+ Int32 fixedHeaderSize = 1;
+
+ Int32 temp = remainingLength;
+ // increase fixed header size based on remaining length
+ // (each remaining length byte can encode until 128)
+ do {
+ fixedHeaderSize++;
+ temp /= 128;
+ } while (temp > 0);
+
+ // allocate buffer for message
+ buffer = new Byte[fixedHeaderSize + varHeaderSize + payloadSize];
+
+ // first fixed header byte
+ buffer[index++] = protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1
+ ? (Byte)((MQTT_MSG_SUBACK_TYPE << MSG_TYPE_OFFSET) | MQTT_MSG_SUBACK_FLAG_BITS)
+ : (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 });
+ this.GetTraceString(
+ "SUBACK",
+ new Object[] { "messageId", "grantedQosLevels" },
+ new Object[] { this.MessageId, this.GrantedQoSLevels });
#else
- return base.ToString();
+ base.ToString();
#endif
- }
- }
+
+ }
}
diff --git a/M2Mqtt/Messages/MqttMsgSubscribe.cs b/M2Mqtt/Messages/MqttMsgSubscribe.cs
index 0e3927e..e1d2ebf 100644
--- a/M2Mqtt/Messages/MqttMsgSubscribe.cs
+++ b/M2Mqtt/Messages/MqttMsgSubscribe.cs
@@ -16,257 +16,234 @@ Contributors:
using System;
// if NOT .Net Micro Framework
-#if (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3)
+#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
-{
+namespace uPLibrary.Networking.M2Mqtt.Messages {
+ ///
+ /// Class for SUBSCRIBE message from client to broker
+ ///
+ public class MqttMsgSubscribe : MqttMsgBase {
+ #region Properties...
+
///
- /// Class for SUBSCRIBE message from client to broker
+ /// List of topics to subscribe
///
- 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)
+ public String[] Topics { get; set; }
+
+ ///
+ /// List of QOS Levels related to topics
+ ///
+ public Byte[] QoSLevels { get; set; }
+
+ #endregion
+
+ // topics to subscribe
+
+ ///
+ /// 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;
+ Int32 index = 0;
+ Byte[] topicUtf8;
+ Int32 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
+ Int32 remainingLength = MqttMsgBase.DecodeRemainingLength(channel);
+ buffer = new Byte[remainingLength];
+
+ // read bytes from socket...
+ Int32 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 = (UInt16)((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();
+ 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()
- {
+ 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 (Int32 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) {
+ Int32 varHeaderSize = 0;
+ Int32 payloadSize = 0;
+ Int32 remainingLength = 0;
+ Byte[] buffer;
+ Int32 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;
+ Byte[][] topicsUtf8 = new Byte[this.Topics.Length][];
+
+
+ Int32 topicIdx;
+ 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
+ Int32 fixedHeaderSize = 1;
+
+ Int32 temp = remainingLength;
+ // increase fixed header size based on remaining length
+ // (each remaining length byte can encode until 128)
+ do {
+ fixedHeaderSize++;
+ 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)((this.MessageId >> 8) & 0x00FF); // MSB
+ buffer[index++] = (Byte)(this.MessageId & 0x00FF); // LSB
+
+ 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 });
+ this.GetTraceString(
+ "SUBSCRIBE",
+ new Object[] { "messageId", "topics", "qosLevels" },
+ new Object[] { this.MessageId, this.Topics, this.QoSLevels });
#else
- return base.ToString();
+ base.ToString();
#endif
- }
- }
+
+ }
}
diff --git a/M2Mqtt/Messages/MqttMsgSubscribeEventArgs.cs b/M2Mqtt/Messages/MqttMsgSubscribeEventArgs.cs
index 91c85f9..a0c2c10 100644
--- a/M2Mqtt/Messages/MqttMsgSubscribeEventArgs.cs
+++ b/M2Mqtt/Messages/MqttMsgSubscribeEventArgs.cs
@@ -14,68 +14,48 @@ Contributors:
Paolo Patierno - initial API and implementation and/or initial documentation
*/
-#if (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3)
+#if !MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3
using System;
#else
using Microsoft.SPOT;
#endif
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
+namespace uPLibrary.Networking.M2Mqtt.Messages {
+ ///
+ /// Event Args class for subscribe request on topics
+ ///
+ public class MqttMsgSubscribeEventArgs : EventArgs {
+ #region Properties...
+
///
- /// Event Args class for subscribe request on topics
+ /// Message identifier
///
- 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;
- }
- }
+ public UInt16 MessageId { get; internal set; }
+
+ ///
+ /// Topics requested to subscribe
+ ///
+ public String[] Topics { get; internal set; }
+
+ ///
+ /// List of QOS Levels requested
+ ///
+ public Byte[] QoSLevels { get; internal set; }
+
+ #endregion
+
+ // message identifier
+
+ ///
+ /// Constructor
+ ///
+ /// Message identifier for subscribe topics request
+ /// Topics requested to subscribe
+ /// List of QOS Levels requested
+ public MqttMsgSubscribeEventArgs(UInt16 messageId, String[] topics, Byte[] qosLevels) {
+ this.MessageId = messageId;
+ this.Topics = topics;
+ this.QoSLevels = qosLevels;
+ }
+ }
}
diff --git a/M2Mqtt/Messages/MqttMsgSubscribedEventArgs.cs b/M2Mqtt/Messages/MqttMsgSubscribedEventArgs.cs
index 58bbb22..d99e7e2 100644
--- a/M2Mqtt/Messages/MqttMsgSubscribedEventArgs.cs
+++ b/M2Mqtt/Messages/MqttMsgSubscribedEventArgs.cs
@@ -14,55 +14,41 @@ Contributors:
Paolo Patierno - initial API and implementation and/or initial documentation
*/
-#if (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3)
+#if !MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3
using System;
#else
using Microsoft.SPOT;
#endif
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
+namespace uPLibrary.Networking.M2Mqtt.Messages {
+ ///
+ /// Event Args class for subscribed topics
+ ///
+ public class MqttMsgSubscribedEventArgs : EventArgs {
+ #region Properties...
+
///
- /// Event Args class for subscribed topics
+ /// Message identifier
///
- 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;
- }
- }
+ public UInt16 MessageId { get; internal set; }
+
+ ///
+ /// List of granted QOS Levels
+ ///
+ public Byte[] GrantedQoSLevels { get; internal set; }
+
+ #endregion
+
+ // message identifier
+
+ ///
+ /// Constructor
+ ///
+ /// Message identifier for subscribed topics
+ /// List of granted QOS Levels
+ public MqttMsgSubscribedEventArgs(UInt16 messageId, Byte[] grantedQosLevels) {
+ this.MessageId = messageId;
+ this.GrantedQoSLevels = grantedQosLevels;
+ }
+ }
}
diff --git a/M2Mqtt/Messages/MqttMsgUnsuback.cs b/M2Mqtt/Messages/MqttMsgUnsuback.cs
index 8e49a06..481ebe1 100644
--- a/M2Mqtt/Messages/MqttMsgUnsuback.cs
+++ b/M2Mqtt/Messages/MqttMsgUnsuback.cs
@@ -17,110 +17,99 @@ Contributors:
using System;
using uPLibrary.Networking.M2Mqtt.Exceptions;
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
+namespace uPLibrary.Networking.M2Mqtt.Messages {
+ ///
+ /// Class for UNSUBACK message from broker to client
+ ///
+ public class MqttMsgUnsuback : MqttMsgBase {
///
- /// Class for UNSUBACK message from broker to client
+ /// Constructor
///
- 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()
- {
+ 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;
+ Int32 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
+ Int32 remainingLength = MqttMsgBase.DecodeRemainingLength(channel);
+ buffer = new Byte[remainingLength];
+
+ // read bytes from socket...
+ _ = channel.Receive(buffer);
+
+ // message id
+ msg.MessageId = (UInt16)((buffer[index++] << 8) & 0xFF00);
+ msg.MessageId |= buffer[index++];
+
+ return msg;
+ }
+
+ public override Byte[] GetBytes(Byte protocolVersion) {
+ Int32 varHeaderSize = 0;
+ Int32 payloadSize = 0;
+ Int32 remainingLength = 0;
+ Byte[] buffer;
+ Int32 index = 0;
+
+ // message identifier
+ varHeaderSize += MESSAGE_ID_SIZE;
+
+ remainingLength += varHeaderSize + payloadSize;
+
+ // first byte of fixed header
+ Int32 fixedHeaderSize = 1;
+
+ Int32 temp = remainingLength;
+ // increase fixed header size based on remaining length
+ // (each remaining length byte can encode until 128)
+ do {
+ fixedHeaderSize++;
+ temp /= 128;
+ } while (temp > 0);
+
+ // allocate buffer for message
+ buffer = new Byte[fixedHeaderSize + varHeaderSize + payloadSize];
+
+ // first fixed header byte
+ buffer[index++] = protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1
+ ? (Byte)((MQTT_MSG_UNSUBACK_TYPE << MSG_TYPE_OFFSET) | MQTT_MSG_UNSUBACK_FLAG_BITS)
+ : (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 });
+ this.GetTraceString(
+ "UNSUBACK",
+ new Object[] { "messageId" },
+ new Object[] { this.MessageId });
#else
- return base.ToString();
+ base.ToString();
#endif
- }
- }
+
+ }
}
diff --git a/M2Mqtt/Messages/MqttMsgUnsubscribe.cs b/M2Mqtt/Messages/MqttMsgUnsubscribe.cs
index e485133..d122940 100644
--- a/M2Mqtt/Messages/MqttMsgUnsubscribe.cs
+++ b/M2Mqtt/Messages/MqttMsgUnsubscribe.cs
@@ -16,224 +16,205 @@ Contributors:
using System;
// if NOT .Net Micro Framework
-#if (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3)
+#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
-{
+namespace uPLibrary.Networking.M2Mqtt.Messages {
+ ///
+ /// Class for UNSUBSCRIBE message from client to broker
+ ///
+ public class MqttMsgUnsubscribe : MqttMsgBase {
+ #region Properties...
+
///
- /// Class for UNSUBSCRIBE message from client to broker
+ /// List of topics to unsubscribe
///
- 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)
+ public String[] Topics { get; set; }
+
+ #endregion
+
+ // topics to unsubscribe
+
+ ///
+ /// 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;
+ Int32 index = 0;
+ Byte[] topicUtf8;
+ Int32 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
+ Int32 remainingLength = DecodeRemainingLength(channel);
+ buffer = new Byte[remainingLength];
+
+ // read bytes from socket...
+ Int32 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 = (UInt16)((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();
+ 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()
- {
+ 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 (Int32 i = 0; i < tmpTopics.Count; i++) {
+ msg.Topics[i] = (String)tmpTopics[i];
+ }
+
+ return msg;
+ }
+
+ public override Byte[] GetBytes(Byte protocolVersion) {
+ Int32 varHeaderSize = 0;
+ Int32 payloadSize = 0;
+ Int32 remainingLength = 0;
+ Byte[] buffer;
+ Int32 index = 0;
+
+ // topics list empty
+ if (this.Topics == null || this.Topics.Length == 0) {
+ throw new MqttClientException(MqttClientErrorCode.TopicsEmpty);
+ }
+
+ // message identifier
+ varHeaderSize += MESSAGE_ID_SIZE;
+ Byte[][] topicsUtf8 = new Byte[this.Topics.Length][];
+
+
+ Int32 topicIdx;
+ 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
+ Int32 fixedHeaderSize = 1;
+
+ Int32 temp = remainingLength;
+ // increase fixed header size based on remaining length
+ // (each remaining length byte can encode until 128)
+ do {
+ fixedHeaderSize++;
+ 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)((this.MessageId >> 8) & 0x00FF); // MSB
+ buffer[index++] = (Byte)(this.MessageId & 0x00FF); // LSB
+
+ 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 });
+ this.GetTraceString(
+ "UNSUBSCRIBE",
+ new Object[] { "messageId", "topics" },
+ new Object[] { this.MessageId, this.Topics });
#else
- return base.ToString();
+ base.ToString();
#endif
- }
- }
+
+ }
}
diff --git a/M2Mqtt/Messages/MqttMsgUnsubscribeEventArgs.cs b/M2Mqtt/Messages/MqttMsgUnsubscribeEventArgs.cs
index e158783..1f36052 100644
--- a/M2Mqtt/Messages/MqttMsgUnsubscribeEventArgs.cs
+++ b/M2Mqtt/Messages/MqttMsgUnsubscribeEventArgs.cs
@@ -14,55 +14,41 @@ Contributors:
Paolo Patierno - initial API and implementation and/or initial documentation
*/
-#if (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3)
+#if !MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3
using System;
#else
using Microsoft.SPOT;
#endif
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
+namespace uPLibrary.Networking.M2Mqtt.Messages {
+ ///
+ /// Event Args class for unsubscribe request on topics
+ ///
+ public class MqttMsgUnsubscribeEventArgs : EventArgs {
+ #region Properties...
+
///
- /// Event Args class for unsubscribe request on topics
+ /// Message identifier
///
- 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;
- }
- }
+ public UInt16 MessageId { get; internal set; }
+
+ ///
+ /// Topics requested to subscribe
+ ///
+ public String[] Topics { get; internal set; }
+
+ #endregion
+
+ // message identifier
+
+ ///
+ /// Constructor
+ ///
+ /// Message identifier for subscribed topics
+ /// Topics requested to subscribe
+ public MqttMsgUnsubscribeEventArgs(UInt16 messageId, String[] topics) {
+ this.MessageId = messageId;
+ this.Topics = topics;
+ }
+ }
}
diff --git a/M2Mqtt/Messages/MqttMsgUnsubscribedEventArgs.cs b/M2Mqtt/Messages/MqttMsgUnsubscribedEventArgs.cs
index e65c383..6b7d681 100644
--- a/M2Mqtt/Messages/MqttMsgUnsubscribedEventArgs.cs
+++ b/M2Mqtt/Messages/MqttMsgUnsubscribedEventArgs.cs
@@ -14,42 +14,32 @@ Contributors:
Paolo Patierno - initial API and implementation and/or initial documentation
*/
-#if (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3)
+#if !MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3
using System;
#else
using Microsoft.SPOT;
#endif
-namespace uPLibrary.Networking.M2Mqtt.Messages
-{
+namespace uPLibrary.Networking.M2Mqtt.Messages {
+ ///
+ /// Event Args class for unsubscribed topic
+ ///
+ public class MqttMsgUnsubscribedEventArgs : EventArgs {
+ #region Properties...
+
///
- /// Event Args class for unsubscribed topic
+ /// Message identifier
///
- 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;
- }
- }
+ public UInt16 MessageId { get; internal set; }
+
+ #endregion
+
+ // message identifier
+
+ ///
+ /// Constructor
+ ///
+ /// Message identifier for unsubscribed topic
+ public MqttMsgUnsubscribedEventArgs(UInt16 messageId) => this.MessageId = messageId;
+ }
}
diff --git a/M2Mqtt/MqttClient.cs b/M2Mqtt/MqttClient.cs
index 6daf7a2..f501b6a 100644
--- a/M2Mqtt/MqttClient.cs
+++ b/M2Mqtt/MqttClient.cs
@@ -27,7 +27,7 @@ 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)
+#if MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3
using Microsoft.SPOT;
#if SSL
using Microsoft.SPOT.Net.Security;
@@ -35,13 +35,13 @@ using Microsoft.SPOT.Net.Security;
// else other frameworks (.Net, .Net Compact, Mono, Windows Phone)
#else
using System.Collections.Generic;
-#if (SSL && !(WINDOWS_APP || WINDOWS_PHONE_APP))
+#if SSL && !(WINDOWS_APP || WINDOWS_PHONE_APP)
using System.Security.Authentication;
using System.Net.Security;
#endif
#endif
-#if (WINDOWS_APP || WINDOWS_PHONE_APP)
+#if WINDOWS_APP || WINDOWS_PHONE_APP
using Windows.Networking.Sockets;
#endif
@@ -51,184 +51,176 @@ using System.Collections;
// (it's ambiguos with uPLibrary.Networking.M2Mqtt.Utility.Trace)
using MqttUtility = uPLibrary.Networking.M2Mqtt.Utility;
using System.IO;
-//using System.Net.Security;
-namespace uPLibrary.Networking.M2Mqtt
-{
+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
+
///
- /// MQTT Client
+ /// Delagate that defines event handler for PUBLISH message received
///
- public class MqttClient
- {
-#if BROKER
- #region Constants ...
+ public delegate void MqttMsgPublishEventHandler(Object sender, MqttMsgPublishEventArgs e);
- // 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";
+ ///
+ /// Delegate that defines event handler for published message
+ ///
+ public delegate void MqttMsgPublishedEventHandler(Object sender, MqttMsgPublishedEventArgs e);
- #endregion
-#endif
+ ///
+ /// Delagate that defines event handler for subscribed topic
+ ///
+ public delegate void MqttMsgSubscribedEventHandler(Object sender, MqttMsgSubscribedEventArgs e);
- ///
- /// Delagate that defines event handler for PUBLISH message received
- ///
- public delegate void MqttMsgPublishEventHandler(object sender, MqttMsgPublishEventArgs e);
+ ///
+ /// Delagate that defines event handler for unsubscribed topic
+ ///
+ public delegate void MqttMsgUnsubscribedEventHandler(Object sender, MqttMsgUnsubscribedEventArgs e);
- ///
- /// Delegate that defines event handler for published message
- ///
- public delegate void MqttMsgPublishedEventHandler(object sender, MqttMsgPublishedEventArgs 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 subscribed topic
- ///
- public delegate void MqttMsgSubscribedEventHandler(object sender, MqttMsgSubscribedEventArgs e);
+ ///
+ /// Delagate that defines event handler for UNSUBSCRIBE message received
+ ///
+ public delegate void MqttMsgUnsubscribeEventHandler(object sender, MqttMsgUnsubscribeEventArgs e);
- ///
- /// Delagate that defines event handler for unsubscribed topic
- ///
- public delegate void MqttMsgUnsubscribedEventHandler(object sender, MqttMsgUnsubscribedEventArgs e);
+ ///
+ /// Delagate that defines event handler for CONNECT message received
+ ///
+ public delegate void MqttMsgConnectEventHandler(object sender, MqttMsgConnectEventArgs e);
-#if BROKER
- ///
- /// Delagate that defines event handler for SUBSCRIBE message received
- ///
- public delegate void MqttMsgSubscribeEventHandler(object sender, MqttMsgSubscribeEventArgs e);
+ ///
+ /// Delegate that defines event handler for client disconnection (DISCONNECT message or not)
+ ///
+ public delegate void MqttMsgDisconnectEventHandler(object sender, EventArgs e);
+ #endif
- ///
- /// Delagate that defines event handler for UNSUBSCRIBE message received
- ///
- public delegate void MqttMsgUnsubscribeEventHandler(object sender, MqttMsgUnsubscribeEventArgs e);
+ ///
+ /// Delegate that defines event handler for cliet/peer disconnection
+ ///
+ public delegate void ConnectionClosedEventHandler(Object sender, EventArgs e);
- ///
- /// Delagate that defines event handler for CONNECT message received
- ///
- public delegate void MqttMsgConnectEventHandler(object sender, MqttMsgConnectEventArgs e);
+ // broker hostname (or ip address) and port
+ private String brokerHostName;
+ private Int32 brokerPort;
- ///
- /// Delegate that defines event handler for client disconnection (DISCONNECT message or not)
- ///
- public delegate void MqttMsgDisconnectEventHandler(object sender, EventArgs e);
-#endif
+ // running status of threads
+ private Boolean isRunning;
+ // event for raising received message event
+ private AutoResetEvent receiveEventWaitHandle;
- ///
- /// Delegate that defines event handler for cliet/peer disconnection
- ///
- public delegate void ConnectionClosedEventHandler(object sender, EventArgs e);
+ // event for starting process inflight queue asynchronously
+ private AutoResetEvent inflightWaitHandle;
- // broker hostname (or ip address) and port
- private string brokerHostName;
- private int brokerPort;
+ // event for signaling synchronous receive
+ AutoResetEvent syncEndReceiving;
+ // message received
+ MqttMsgBase msgReceived;
- // running status of threads
- private bool isRunning;
- // event for raising received message event
- private AutoResetEvent receiveEventWaitHandle;
+ // exeption thrown during receiving
+ Exception exReceiving;
- // event for starting process inflight queue asynchronously
- private AutoResetEvent inflightWaitHandle;
+ // keep alive period (in ms)
+ private Int32 keepAlivePeriod;
+ // events for signaling on keep alive thread
+ private AutoResetEvent keepAliveEvent;
+ private AutoResetEvent keepAliveEventEnd;
+ // last communication time in ticks
+ private Int32 lastCommTime;
- // event for signaling synchronous receive
- AutoResetEvent syncEndReceiving;
- // message received
- MqttMsgBase msgReceived;
+ // 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
- // exeption thrown during receiving
- Exception exReceiving;
+ // event for peer/client disconnection
+ public event ConnectionClosedEventHandler ConnectionClosed;
- // 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;
+ // channel to communicate over the network
+ private IMqttNetworkChannel channel;
- // 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
+ // 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;
- // event for peer/client disconnection
- public event ConnectionClosedEventHandler ConnectionClosed;
-
- // channel to communicate over the network
- private IMqttNetworkChannel channel;
+ // current message identifier generated
+ private UInt16 messageIdCounter = 0;
- // 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;
+ // connection is closing due to peer
+ private Boolean isConnectionClosing;
- // reference to avoid access to singleton via property
- private MqttSettings settings;
+ ///
+ /// Connection status between client and broker
+ ///
+ public Boolean IsConnected { get; private set; }
- // current message identifier generated
- private ushort messageIdCounter = 0;
+ ///
+ /// Client identifier
+ ///
+ public String ClientId { get; private set; }
- // connection is closing due to peer
- private bool isConnectionClosing;
+ ///
+ /// Clean session flag
+ ///
+ public Boolean CleanSession { get; private set; }
- ///
- /// Connection status between client and broker
- ///
- public bool IsConnected { get; private set; }
+ ///
+ /// Will flag
+ ///
+ public Boolean WillFlag { get; private set; }
- ///
- /// Client identifier
- ///
- public string ClientId { get; private set; }
+ ///
+ /// Will QOS level
+ ///
+ public Byte WillQosLevel { get; private set; }
- ///
- /// Clean session flag
- ///
- public bool CleanSession { get; private set; }
+ ///
+ /// Will topic
+ ///
+ public String WillTopic { get; private set; }
- ///
- /// Will flag
- ///
- public bool WillFlag { get; private set; }
+ ///
+ /// Will message
+ ///
+ public String WillMessage { 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; }
+ ///
+ /// MQTT protocol version
+ ///
+ public MqttProtocolVersion ProtocolVersion { get; set; }
#if BROKER
///
@@ -241,134 +233,121 @@ namespace uPLibrary.Networking.M2Mqtt
}
#endif
- ///
- /// MQTT client settings
- ///
- public MqttSettings Settings
- {
- get { return this.settings; }
- }
+ ///
+ /// MQTT client settings
+ ///
+ public MqttSettings Settings { get; private set; }
-#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)
- {
- }
+#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)
- {
+ ///
+ /// 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, Int32 brokerPort, Boolean 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);
+ 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) :
+ ///
+ /// 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
+ ///
+ /// 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)
+ /// CA certificate for secure connection
+ /// Client certificate
+ public MqttClient(String brokerHostName, Int32 brokerPort, Boolean secure, X509Certificate caCert, X509Certificate clientCert, MqttSslProtocols sslProtocol) =>
#else
- public MqttClient(string brokerHostName, int brokerPort, bool secure, MqttSslProtocols sslProtocol)
+ 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, 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
+ /// 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, Int32 brokerPort, Boolean 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
+ /// 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, Int32 brokerPort, Boolean 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);
- }
+ ///
+ /// 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, Int32 brokerPort, Boolean secure, X509Certificate caCert, X509Certificate clientCert, MqttSslProtocols sslProtocol,
+ RemoteCertificateValidationCallback userCertificateValidationCallback,
+ LocalCertificateSelectionCallback userCertificateSelectionCallback) => this.Init(brokerHostName, brokerPort, secure, caCert, clientCert, sslProtocol, userCertificateValidationCallback, userCertificateSelectionCallback);
#endif
#if BROKER
@@ -407,213 +386,199 @@ namespace uPLibrary.Networking.M2Mqtt
}
#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
+ ///
+ /// 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)
+ /// 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, Int32 brokerPort, Boolean 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;
+ // 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");
+ // check security parameters
+ if (secure) {
+ throw new ArgumentException("Library compiled without SSL support");
+ }
#endif
- this.brokerHostName = brokerHostName;
- this.brokerPort = brokerPort;
+ 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;
+ // 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);
+ 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 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();
+ // queue for received message
+ this.receiveEventWaitHandle = new AutoResetEvent(false);
+ this.eventQueue = new Queue();
+ this.internalQueue = new Queue();
- // session
- this.session = null;
+ // session
+ this.session = null;
- // create network channel
+ // 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, 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) => 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) => 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,
+ Boolean cleanSession,
+ UInt16 keepAlivePeriod) => 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,
+ Boolean willRetain,
+ Byte willQosLevel,
+ Boolean willFlag,
+ String willTopic,
+ String willMessage,
+ Boolean cleanSession,
+ UInt16 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);
}
- ///
- /// 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);
- }
+ // start thread for raising received message event from broker
+ Fx.StartThread(this.DispatchEventThread);
- ///
- /// 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);
- }
+ // start thread for handling inflight messages queue to broker asynchronously (publish and acknowledge)
+ Fx.StartThread(this.ProcessInflightThread);
- ///
- /// 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);
- }
+ this.IsConnected = true;
+ }
+ return connack.ReturnCode;
+ }
- ///
- /// 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);
+ ///
+ /// Disconnect from broker
+ ///
+ public void Disconnect() {
+ MqttMsgDisconnect disconnect = new MqttMsgDisconnect();
+ this.Send(disconnect);
- 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();
- }
+ // close client
+ this.OnConnectionClosing();
+ }
#if BROKER
///
@@ -634,71 +599,70 @@ namespace uPLibrary.Networking.M2Mqtt
}
#endif
- ///
- /// Close client
- ///
+ ///
+ /// Close client
+ ///
#if BROKER
public void Close()
#else
- private void Close()
+ private void Close()
#endif
{
- // stop receiving thread
- this.isRunning = false;
+ // stop receiving thread
+ this.isRunning = false;
- // wait end receive event thread
- if (this.receiveEventWaitHandle != null)
- this.receiveEventWaitHandle.Set();
+ // wait end receive event thread
+ if (this.receiveEventWaitHandle != null) {
+ this.receiveEventWaitHandle.Set();
+ }
- // wait end process inflight thread
- if (this.inflightWaitHandle != null)
- this.inflightWaitHandle.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();
+ // unlock keep alive thread and wait
+ this.keepAliveEvent.Set();
- if (this.keepAliveEventEnd != null)
- this.keepAliveEventEnd.WaitOne();
+ if (this.keepAliveEventEnd != null) {
+ this.keepAliveEventEnd.WaitOne();
+ }
#endif
- // clear all queues
- this.inflightQueue.Clear();
- this.internalQueue.Clear();
- this.eventQueue.Clear();
+ // clear all queues
+ this.inflightQueue.Clear();
+ this.internalQueue.Clear();
+ this.eventQueue.Clear();
- // close network channel
- this.channel.Close();
+ // close network channel
+ this.channel.Close();
- this.IsConnected = false;
- }
+ 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)
- {
+ ///
+ /// 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());
+ MqttUtility.Trace.WriteLine(TraceLevel.Error, "Exception occurred: {0}", e.ToString());
#endif
- // client must close connection
- this.OnConnectionClosing();
- return null;
- }
- }
+ // client must close connection
+ this.OnConnectionClosing();
+ return null;
+ }
+ }
#if BROKER
///
@@ -777,155 +741,126 @@ namespace uPLibrary.Networking.M2Mqtt
}
#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();
+ ///
+ /// Subscribe for message topics
+ ///
+ /// List of topics to subscribe
+ /// QOS levels related to topics
+ /// Message Id related to SUBSCRIBE message
+ public UInt16 Subscribe(String[] topics, Byte[] qosLevels) {
+ MqttMsgSubscribe subscribe =
+ new MqttMsgSubscribe(topics, qosLevels) {
+ MessageId = this.GetMessageId()
+ };
- // enqueue subscribe request into the inflight queue
- this.EnqueueInflight(subscribe, MqttMsgFlow.ToPublish);
+ // enqueue subscribe request into the inflight queue
+ _ = this.EnqueueInflight(subscribe, MqttMsgFlow.ToPublish);
- return subscribe.MessageId;
- }
+ 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();
+ ///
+ /// Unsubscribe for message topics
+ ///
+ /// List of topics to unsubscribe
+ /// Message Id in UNSUBACK message from broker
+ public UInt16 Unsubscribe(String[] topics) {
+ MqttMsgUnsubscribe unsubscribe =
+ new MqttMsgUnsubscribe(topics) {
+ MessageId = this.GetMessageId()
+ };
- // enqueue unsubscribe request into the inflight queue
- this.EnqueueInflight(unsubscribe, MqttMsgFlow.ToPublish);
+ // enqueue unsubscribe request into the inflight queue
+ _ = this.EnqueueInflight(unsubscribe, MqttMsgFlow.ToPublish);
- return unsubscribe.MessageId;
- }
+ 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 (QoS Level 0 and not retained)
+ ///
+ /// Message topic
+ /// Message data (payload)
+ /// Message Id related to PUBLISH message
+ public UInt16 Publish(String topic, Byte[] message) => 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();
+ ///
+ /// Publish a message asynchronously
+ ///
+ /// Message topic
+ /// Message data (payload)
+ /// QoS Level
+ /// Retain flag
+ /// Message Id related to PUBLISH message
+ public UInt16 Publish(String topic, Byte[] message, Byte qosLevel, Boolean retain) {
+ MqttMsgPublish publish =
+ new MqttMsgPublish(topic, message, false, qosLevel, retain) {
+ MessageId = this.GetMessageId()
+ };
- // enqueue message to publish into the inflight queue
- bool enqueue = this.EnqueueInflight(publish, MqttMsgFlow.ToPublish);
+ // enqueue message to publish into the inflight queue
+ Boolean 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);
- }
+ // 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);
- }
+ ///
+ /// Wrapper method for raising events
+ ///
+ /// Internal event
+ private void OnInternalEvent(InternalEvent internalEvent) {
+ lock (this.eventQueue) {
+ this.eventQueue.Enqueue(internalEvent);
+ }
- this.receiveEventWaitHandle.Set();
- }
+ _ = 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 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 PUBLISH message received event
+ ///
+ /// PUBLISH message received
+ private void OnMqttMsgPublishReceived(MqttMsgPublish publish) => this.MqttMsgPublishReceived?.Invoke(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 published message event
+ ///
+ /// Message identifier for published message
+ /// Publish flag
+ private void OnMqttMsgPublished(UInt16 messageId, Boolean isPublished) => this.MqttMsgPublished?.Invoke(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 subscribed topic event
+ ///
+ /// SUBACK message received
+ private void OnMqttMsgSubscribed(MqttMsgSuback suback) => this.MqttMsgSubscribed?.Invoke(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));
- }
- }
+ ///
+ /// Wrapper method for raising unsubscribed topic event
+ ///
+ /// Message identifier for unsubscribed topic
+ private void OnMqttMsgUnsubscribed(UInt16 messageId) => this.MqttMsgUnsubscribed?.Invoke(this,
+ new MqttMsgUnsubscribedEventArgs(messageId));
#if BROKER
///
@@ -981,389 +916,342 @@ namespace uPLibrary.Networking.M2Mqtt
}
#endif
- ///
- /// Wrapper method for peer/client disconnection
- ///
- private void OnConnectionClosed()
- {
- if (this.ConnectionClosed != null)
- {
- this.ConnectionClosed(this, EventArgs.Empty);
- }
- }
+ ///
+ /// Wrapper method for peer/client disconnection
+ ///
+ private void OnConnectionClosed() => this.ConnectionClosed?.Invoke(this, EventArgs.Empty);
- ///
- /// Send a message
- ///
- /// Message bytes
- private void Send(byte[] msgBytes)
- {
- try
- {
- // send message
- this.channel.Send(msgBytes);
+ ///
+ /// 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;
+ // update last message sent ticks
+ this.lastCommTime = Environment.TickCount;
#endif
- }
- catch (Exception e)
- {
+ } catch (Exception e) {
#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Error, "Exception occurred: {0}", e.ToString());
+ MqttUtility.Trace.WriteLine(TraceLevel.Error, "Exception occurred: {0}", e.ToString());
#endif
- throw new MqttCommunicationException(e);
- }
- }
+ throw new MqttCommunicationException(e);
+ }
+ }
- ///
- /// Send a message
- ///
- /// Message
- private void Send(MqttMsgBase msg)
- {
+ ///
+ /// Send a message
+ ///
+ /// Message
+ private void Send(MqttMsgBase msg) {
#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Frame, "SEND {0}", msg);
+ MqttUtility.Trace.WriteLine(TraceLevel.Frame, "SEND {0}", msg);
#endif
- this.Send(msg.GetBytes((byte)this.ProtocolVersion));
- }
+ 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
+ /// MQTT message response
+ private MqttMsgBase SendReceive(Byte[] msgBytes) => 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);
+ ///
+ /// Send a message to the broker and wait answer
+ ///
+ /// Message bytes
+ /// Timeout for receiving answer
+ /// MQTT message response
+ private MqttMsgBase SendReceive(Byte[] msgBytes, Int32 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)
- {
+ // 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;
- }
+ 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());
+ Trace.WriteLine(TraceLevel.Error, "Exception occurred: {0}", e.ToString());
#endif
- throw new MqttCommunicationException(e);
- }
+ throw new MqttCommunicationException(e);
+ }
-#if (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK)
+#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))
+ // 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();
- }
+ // message received without exception
+ if (this.exReceiving == null) {
+ return this.msgReceived;
}
-
- ///
- /// 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);
+ // 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
- /// Timeout for receiving answer
- /// MQTT message response
- private MqttMsgBase SendReceive(MqttMsgBase msg, int timeout)
- {
+ ///
+ /// Send a message to the broker and wait answer
+ ///
+ /// Message
+ /// MQTT message response
+ private MqttMsgBase SendReceive(MqttMsgBase msg) => 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, Int32 timeout) {
#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Frame, "SEND {0}", msg);
+ MqttUtility.Trace.WriteLine(TraceLevel.Frame, "SEND {0}", msg);
#endif
- return this.SendReceive(msg.GetBytes((byte)this.ProtocolVersion), timeout);
+ 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 Boolean EnqueueInflight(MqttMsgBase msg, MqttMsgFlow flow) {
+ // enqueue is needed (or not)
+ Boolean 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;
}
- ///
- /// 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;
+ // [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;
+ }
- // 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
+ // queue message context
+ MqttMsgContext msgContext = new MqttMsgContext() {
+ Message = msg,
+ State = state,
+ Flow = flow,
+ Attempt = 0
+ };
- // 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);
+ lock (this.inflightQueue) {
+ // check number of messages inside inflight queue
+ enqueue = this.inflightQueue.Count < this.Settings.InflightQueueSize;
- // 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 (enqueue) {
+ // enqueue message and unlock send thread
+ this.inflightQueue.Enqueue(msgContext);
#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Queuing, "enqueued {0}", msg);
+ 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);
- }
- }
- }
+ // 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;
+ this.inflightWaitHandle.Set();
- // 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.
+ return enqueue;
+ }
- // 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);
+ ///
+ /// Enqueue a message into the internal queue
+ ///
+ /// Message to enqueue
+ private void EnqueueInternal(MqttMsgBase msg) {
+ // enqueue is needed (or not)
+ Boolean enqueue = true;
- // 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;
+ // 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.
- this.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);
- 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.
+ // 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 {
+ MessageId = msg.MessageId
+ };
- // 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);
+ this.Send(pubcomp);
- // 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.
+ 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);
+ // 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;
- }
- }
- }
+ // 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.
- if (enqueue)
- {
- lock (this.internalQueue)
- {
- this.internalQueue.Enqueue(msg);
+ // 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);
+ MqttUtility.Trace.WriteLine(TraceLevel.Queuing, "enqueued {0}", msg);
#endif
- this.inflightWaitHandle.Set();
- }
- }
+ this.inflightWaitHandle.Set();
}
+ }
+ }
- ///
- /// Thread for receiving messages
- ///
- private void ReceiveThread()
- {
- int readBytes = 0;
- byte[] fixedHeaderFirstByte = new byte[1];
- byte msgType;
+ ///
+ /// Thread for receiving messages
+ ///
+ private void ReceiveThread() {
+ Int32 readBytes = 0;
+ Byte[] fixedHeaderFirstByte = new Byte[1];
+ Byte msgType;
- while (this.isRunning)
- {
- try
- {
- // read first byte (fixed header)
- readBytes = this.channel.Receive(fixedHeaderFirstByte);
+ while (this.isRunning) {
+ try {
+ // read first byte (fixed header)
+ readBytes = this.channel.Receive(fixedHeaderFirstByte);
- if (readBytes > 0)
- {
+ 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);
+ // 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:
+ switch (msgType) {
+ // CONNECT message received
+ case MqttMsgBase.MQTT_MSG_CONNECT_TYPE:
#if BROKER
MqttMsgConnect connect = MqttMsgConnect.Parse(fixedHeaderFirstByte[0], (byte)this.ProtocolVersion, this.channel);
@@ -1375,25 +1263,25 @@ namespace uPLibrary.Networking.M2Mqtt
this.OnInternalEvent(new MsgInternalEvent(connect));
break;
#else
- throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
+ throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
#endif
-
- // CONNACK message received
- case MqttMsgBase.MQTT_MSG_CONNACK_TYPE:
+
+ // 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);
+ this.msgReceived = MqttMsgConnack.Parse(fixedHeaderFirstByte[0], (Byte)this.ProtocolVersion, this.channel);
#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Frame, "RECV {0}", this.msgReceived);
+ MqttUtility.Trace.WriteLine(TraceLevel.Frame, "RECV {0}", this.msgReceived);
#endif
- this.syncEndReceiving.Set();
- break;
+ this.syncEndReceiving.Set();
+ break;
#endif
- // PINGREQ message received
- case MqttMsgBase.MQTT_MSG_PINGREQ_TYPE:
+ // PINGREQ message received
+ case MqttMsgBase.MQTT_MSG_PINGREQ_TYPE:
#if BROKER
this.msgReceived = MqttMsgPingReq.Parse(fixedHeaderFirstByte[0], (byte)this.ProtocolVersion, this.channel);
@@ -1406,25 +1294,25 @@ namespace uPLibrary.Networking.M2Mqtt
break;
#else
- throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
+ throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
#endif
- // PINGRESP message received
- case MqttMsgBase.MQTT_MSG_PINGRESP_TYPE:
+ // 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);
+ this.msgReceived = MqttMsgPingResp.Parse(fixedHeaderFirstByte[0], (Byte)this.ProtocolVersion, this.channel);
#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Frame, "RECV {0}", this.msgReceived);
+ MqttUtility.Trace.WriteLine(TraceLevel.Frame, "RECV {0}", this.msgReceived);
#endif
- this.syncEndReceiving.Set();
- break;
+ this.syncEndReceiving.Set();
+ break;
#endif
- // SUBSCRIBE message received
- case MqttMsgBase.MQTT_MSG_SUBSCRIBE_TYPE:
+ // SUBSCRIBE message received
+ case MqttMsgBase.MQTT_MSG_SUBSCRIBE_TYPE:
#if BROKER
MqttMsgSubscribe subscribe = MqttMsgSubscribe.Parse(fixedHeaderFirstByte[0], (byte)this.ProtocolVersion, this.channel);
@@ -1437,98 +1325,98 @@ namespace uPLibrary.Networking.M2Mqtt
break;
#else
- throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
+ throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
#endif
- // SUBACK message received
- case MqttMsgBase.MQTT_MSG_SUBACK_TYPE:
+ // 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);
+ // 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);
+ MqttUtility.Trace.WriteLine(TraceLevel.Frame, "RECV {0}", suback);
#endif
- // enqueue SUBACK message into the internal queue
- this.EnqueueInternal(suback);
+ // enqueue SUBACK message into the internal queue
+ this.EnqueueInternal(suback);
- break;
+ break;
#endif
- // PUBLISH message received
- case MqttMsgBase.MQTT_MSG_PUBLISH_TYPE:
+ // PUBLISH message received
+ case MqttMsgBase.MQTT_MSG_PUBLISH_TYPE:
- MqttMsgPublish publish = MqttMsgPublish.Parse(fixedHeaderFirstByte[0], (byte)this.ProtocolVersion, this.channel);
+ MqttMsgPublish publish = MqttMsgPublish.Parse(fixedHeaderFirstByte[0], (Byte)this.ProtocolVersion, this.channel);
#if TRACE
- MqttUtility.Trace.WriteLine(TraceLevel.Frame, "RECV {0}", publish);
+ MqttUtility.Trace.WriteLine(TraceLevel.Frame, "RECV {0}", publish);
#endif
- // enqueue PUBLISH message to acknowledge into the inflight queue
- this.EnqueueInflight(publish, MqttMsgFlow.ToAcknowledge);
+ // enqueue PUBLISH message to acknowledge into the inflight queue
+ this.EnqueueInflight(publish, MqttMsgFlow.ToAcknowledge);
- break;
+ break;
- // PUBACK message received
- case MqttMsgBase.MQTT_MSG_PUBACK_TYPE:
+ // 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);
+ // 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);
+ MqttUtility.Trace.WriteLine(TraceLevel.Frame, "RECV {0}", puback);
#endif
- // enqueue PUBACK message into the internal queue
- this.EnqueueInternal(puback);
+ // enqueue PUBACK message into the internal queue
+ this.EnqueueInternal(puback);
- break;
+ break;
- // PUBREC message received
- case MqttMsgBase.MQTT_MSG_PUBREC_TYPE:
+ // 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);
+ // 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);
+ MqttUtility.Trace.WriteLine(TraceLevel.Frame, "RECV {0}", pubrec);
#endif
- // enqueue PUBREC message into the internal queue
- this.EnqueueInternal(pubrec);
+ // enqueue PUBREC message into the internal queue
+ this.EnqueueInternal(pubrec);
- break;
+ break;
- // PUBREL message received
- case MqttMsgBase.MQTT_MSG_PUBREL_TYPE:
+ // 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);
+ // 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);
+ MqttUtility.Trace.WriteLine(TraceLevel.Frame, "RECV {0}", pubrel);
#endif
- // enqueue PUBREL message into the internal queue
- this.EnqueueInternal(pubrel);
+ // enqueue PUBREL message into the internal queue
+ this.EnqueueInternal(pubrel);
- break;
-
- // PUBCOMP message received
- case MqttMsgBase.MQTT_MSG_PUBCOMP_TYPE:
+ break;
- // enqueue PUBCOMP message received (for QoS Level 2) into the internal queue
- MqttMsgPubcomp pubcomp = MqttMsgPubcomp.Parse(fixedHeaderFirstByte[0], (byte)this.ProtocolVersion, this.channel);
+ // 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);
+ MqttUtility.Trace.WriteLine(TraceLevel.Frame, "RECV {0}", pubcomp);
#endif
- // enqueue PUBCOMP message into the internal queue
- this.EnqueueInternal(pubcomp);
+ // enqueue PUBCOMP message into the internal queue
+ this.EnqueueInternal(pubcomp);
- break;
+ break;
- // UNSUBSCRIBE message received
- case MqttMsgBase.MQTT_MSG_UNSUBSCRIBE_TYPE:
+ // UNSUBSCRIBE message received
+ case MqttMsgBase.MQTT_MSG_UNSUBSCRIBE_TYPE:
#if BROKER
MqttMsgUnsubscribe unsubscribe = MqttMsgUnsubscribe.Parse(fixedHeaderFirstByte[0], (byte)this.ProtocolVersion, this.channel);
@@ -1541,29 +1429,29 @@ namespace uPLibrary.Networking.M2Mqtt
break;
#else
- throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
+ throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
#endif
- // UNSUBACK message received
- case MqttMsgBase.MQTT_MSG_UNSUBACK_TYPE:
+ // 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);
+ // 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);
+ MqttUtility.Trace.WriteLine(TraceLevel.Frame, "RECV {0}", unsuback);
#endif
- // enqueue UNSUBACK message into the internal queue
- this.EnqueueInternal(unsuback);
+ // enqueue UNSUBACK message into the internal queue
+ this.EnqueueInternal(unsuback);
- break;
+ break;
#endif
- // DISCONNECT message received
- case MqttMsgDisconnect.MQTT_MSG_DISCONNECT_TYPE:
+ // DISCONNECT message received
+ case MqttMsgDisconnect.MQTT_MSG_DISCONNECT_TYPE:
#if BROKER
MqttMsgDisconnect disconnect = MqttMsgDisconnect.Parse(fixedHeaderFirstByte[0], (byte)this.ProtocolVersion, this.channel);
@@ -1576,112 +1464,99 @@ namespace uPLibrary.Networking.M2Mqtt
break;
#else
- throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
+ throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
#endif
- default:
+ 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();
- }
- }
+ 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);
+
+ Boolean 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);
+ ///
+ /// Thread for handling keep alive message
+ ///
+ private void KeepAliveThread() {
+ Int32 delta = 0;
+ Int32 wait = this.keepAlivePeriod;
- while (this.isRunning)
- {
-#if (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK)
+ // 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);
+ // waiting...
+ this.keepAliveEvent.WaitOne(wait);
#endif
- if (this.isRunning)
- {
- delta = Environment.TickCount - this.lastCommTime;
+ if (this.isRunning) {
+ delta = Environment.TickCount - this.lastCommTime;
- // if timeout exceeded ...
- if (delta >= this.keepAlivePeriod)
- {
+ // if timeout exceeded ...
+ if (delta >= this.keepAlivePeriod) {
#if BROKER
// client must close connection
this.OnConnectionClosing();
#else
- // ... send keep alive
+ // ... send keep alive
this.Ping();
wait = this.keepAlivePeriod;
#endif
- }
- else
- {
- // update waiting time
- wait = this.keepAlivePeriod - delta;
- }
- }
- }
-
- // signal thread end
- this.keepAliveEventEnd.Set();
+ } else {
+ // update waiting time
+ wait = this.keepAlivePeriod - delta;
+ }
}
+ }
- ///
- /// Thread for raising event
- ///
- private void DispatchEventThread()
- {
- while (this.isRunning)
- {
+ // 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)
{
@@ -1706,44 +1581,41 @@ namespace uPLibrary.Networking.M2Mqtt
}
}
#else
- if ((this.eventQueue.Count == 0) && !this.isConnectionClosing)
- // wait on receiving message from client
- this.receiveEventWaitHandle.WaitOne();
+ 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();
- }
+ // 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;
+ // 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 (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);
+ throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
#endif
- // SUBSCRIBE message received
- case MqttMsgBase.MQTT_MSG_SUBSCRIBE_TYPE:
+ // SUBSCRIBE message received
+ case MqttMsgBase.MQTT_MSG_SUBSCRIBE_TYPE:
#if BROKER
MqttMsgSubscribe subscribe = (MqttMsgSubscribe)msg;
@@ -1751,53 +1623,55 @@ namespace uPLibrary.Networking.M2Mqtt
this.OnMqttMsgSubscribeReceived(subscribe.MessageId, subscribe.Topics, subscribe.QoSLevels);
break;
#else
- throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
+ throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
#endif
- // SUBACK message received
- case MqttMsgBase.MQTT_MSG_SUBACK_TYPE:
+ // SUBACK message received
+ case MqttMsgBase.MQTT_MSG_SUBACK_TYPE:
- // raise subscribed topic event (SUBACK message received)
- this.OnMqttMsgSubscribed((MqttMsgSuback)msg);
- break;
+ // raise subscribed topic event (SUBACK message received)
+ this.OnMqttMsgSubscribed((MqttMsgSuback)msg);
+ break;
- // PUBLISH message received
- case MqttMsgBase.MQTT_MSG_PUBLISH_TYPE:
+ // 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;
+ // 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);
+ }
- // PUBACK message received
- case MqttMsgBase.MQTT_MSG_PUBACK_TYPE:
+ break;
- // raise published message event
- // (PUBACK received for QoS Level 1)
- this.OnMqttMsgPublished(msg.MessageId, true);
- break;
+ // PUBACK message received
+ case MqttMsgBase.MQTT_MSG_PUBACK_TYPE:
- // PUBREL message received
- case MqttMsgBase.MQTT_MSG_PUBREL_TYPE:
+ // raise published message event
+ // (PUBACK received for QoS Level 1)
+ this.OnMqttMsgPublished(msg.MessageId, true);
+ break;
- // raise message received event
- // (PUBREL received for QoS Level 2)
- this.OnMqttMsgPublishReceived((MqttMsgPublish)msg);
- break;
+ // PUBREL message received
+ case MqttMsgBase.MQTT_MSG_PUBREL_TYPE:
- // PUBCOMP message received
- case MqttMsgBase.MQTT_MSG_PUBCOMP_TYPE:
+ // raise message received event
+ // (PUBREL received for QoS Level 2)
+ this.OnMqttMsgPublishReceived((MqttMsgPublish)msg);
+ break;
- // raise published message event
- // (PUBCOMP received for QoS Level 2)
- this.OnMqttMsgPublished(msg.MessageId, true);
- break;
+ // PUBCOMP message received
+ case MqttMsgBase.MQTT_MSG_PUBCOMP_TYPE:
- // UNSUBSCRIBE message received from client
- case MqttMsgBase.MQTT_MSG_UNSUBSCRIBE_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;
@@ -1805,759 +1679,692 @@ namespace uPLibrary.Networking.M2Mqtt
this.OnMqttMsgUnsubscribeReceived(unsubscribe.MessageId, unsubscribe.Topics);
break;
#else
- throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
+ throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
#endif
- // UNSUBACK message received
- case MqttMsgBase.MQTT_MSG_UNSUBACK_TYPE:
+ // UNSUBACK message received
+ case MqttMsgBase.MQTT_MSG_UNSUBACK_TYPE:
- // raise unsubscribed topic event
- this.OnMqttMsgUnsubscribed(msg.MessageId);
- break;
+ // raise unsubscribed topic event
+ this.OnMqttMsgUnsubscribed(msg.MessageId);
+ break;
- // DISCONNECT message received from client
- case MqttMsgDisconnect.MQTT_MSG_DISCONNECT_TYPE:
+ // 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);
+ 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();
- }
- }
+ }
}
+ }
+
+ // 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;
+ ///
+ /// Process inflight messages queue
+ ///
+ private void ProcessInflightThread() {
+ MqttMsgContext msgContext = null;
+ MqttMsgBase msgInflight = null;
+ MqttMsgBase msgReceived = null;
+ InternalEvent internalEvent = null;
+ Boolean acknowledge = false;
+ Int32 timeout = Timeout.Infinite;
+ Int32 delta;
+ Boolean msgReceivedProcessed = false;
- try
- {
- while (this.isRunning)
- {
-#if (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3 || COMPACT_FRAMEWORK)
+ 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);
+ // 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
- }
- }
- }
+ // 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
+ Int32 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;
}
- }
- 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);
+
+ // 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.Error, "Exception occurred: {0}", e.ToString());
+ MqttUtility.Trace.WriteLine(TraceLevel.Queuing, "processed {0}", msgInflight);
#endif
+ break;
- // raise disconnection client event
- this.OnConnectionClosing();
- }
- }
+ case MqttMsgState.QueuedQos1:
+ // [v3.1.1] SUBSCRIBE and UNSIBSCRIBE aren't "officially" QOS = 1
+ case MqttMsgState.SendSubscribe:
+ case MqttMsgState.SendUnsubscribe:
- ///
- /// 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)
- {
+ // 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 {
+ 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 {
+ 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
+ internalEvent = msgReceived.Type == MqttMsgBase.MQTT_MSG_PUBACK_TYPE
+ ? new MsgPublishedInternalEvent(msgReceived, true)
+ : 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);
- // 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;
- }
- }
- }
- }
- }
+ // 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);
+ }
- // unlock process inflight queue
- this.inflightWaitHandle.Set();
- }
- else
- {
- // create new session
- this.session = new MqttClientSession(this.ClientId);
+ 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
+ Int32 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 {
+ 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
+ Int32 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 {
+ 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
+ Int32 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 {
+ 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
+ }
}
- // clean any previous session
- else
- {
- if (this.session != null)
- this.session.Clear();
- }
+ }
}
+ } 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
@@ -2578,55 +2385,50 @@ namespace uPLibrary.Networking.M2Mqtt
}
#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);
-
- }
- }
+ ///
+ /// Generate the next message identifier
+ ///
+ /// Message identifier
+ private UInt16 GetMessageId() {
+ // if 0 or max UInt16, it becomes 1 (first valid messageId)
+ this.messageIdCounter = (this.messageIdCounter % UInt16.MaxValue != 0) ? (UInt16)(this.messageIdCounter + 1) : (UInt16)1;
+ return this.messageIdCounter;
}
///
- /// MQTT protocol version
+ /// Finder class for PUBLISH message inside a queue
///
- public enum MqttProtocolVersion
- {
- Version_3_1 = MqttMsgConnect.PROTOCOL_VERSION_V3_1,
- Version_3_1_1 = MqttMsgConnect.PROTOCOL_VERSION_V3_1_1
+ internal class MqttMsgContextFinder {
+ // PUBLISH message id
+ internal UInt16 MessageId { get; set; }
+ // message flow into inflight queue
+ internal MqttMsgFlow Flow { get; set; }
+
+ ///
+ /// Constructor
+ ///
+ /// Message Id
+ /// Message flow inside inflight queue
+ internal MqttMsgContextFinder(UInt16 messageId, MqttMsgFlow flow) {
+ this.MessageId = messageId;
+ this.Flow = flow;
+ }
+
+ internal Boolean 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
+ }
+}
\ No newline at end of file
diff --git a/M2Mqtt/MqttSecurity.cs b/M2Mqtt/MqttSecurity.cs
index b19f108..afd54e3 100644
--- a/M2Mqtt/MqttSecurity.cs
+++ b/M2Mqtt/MqttSecurity.cs
@@ -14,17 +14,15 @@ 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
- }
+namespace uPLibrary.Networking.M2Mqtt {
+ ///
+ /// Supported SSL/TLS protocol versions
+ ///
+ public enum MqttSslProtocols {
+ None,
+ SSLv3,
+ TLSv1_0,
+ TLSv1_1,
+ TLSv1_2
+ }
}
diff --git a/M2Mqtt/MqttSettings.cs b/M2Mqtt/MqttSettings.cs
index 994f622..af83d39 100644
--- a/M2Mqtt/MqttSettings.cs
+++ b/M2Mqtt/MqttSettings.cs
@@ -14,91 +14,90 @@ Contributors:
Paolo Patierno - initial API and implementation and/or initial documentation
*/
-namespace uPLibrary.Networking.M2Mqtt
-{
+using System;
+
+namespace uPLibrary.Networking.M2Mqtt {
+ ///
+ /// Settings class for the MQTT broker
+ ///
+ public class MqttSettings {
+ // default port for MQTT protocol
+ public const Int32 MQTT_BROKER_DEFAULT_PORT = 1883;
+ public const Int32 MQTT_BROKER_DEFAULT_SSL_PORT = 8883;
+ // default timeout on receiving from client
+ public const Int32 MQTT_DEFAULT_TIMEOUT = 30000;
+ // max publish, subscribe and unsubscribe retry for QoS Level 1 or 2
+ public const Int32 MQTT_ATTEMPTS_RETRY = 3;
+ // delay for retry publish, subscribe and unsubscribe for QoS Level 1 or 2
+ public const Int32 MQTT_DELAY_RETRY = 10000;
+ // broker need to receive the first message (CONNECT)
+ // within a reasonable amount of time after TCP/IP connection
+ public const Int32 MQTT_CONNECT_TIMEOUT = 30000;
+ // default inflight queue size
+ public const Int32 MQTT_MAX_INFLIGHT_QUEUE_SIZE = Int32.MaxValue;
+
///
- /// Settings class for the MQTT broker
+ /// Listening connection port
///
- 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;
- }
- }
+ public Int32 Port { get; internal set; }
+
+ ///
+ /// Listening connection SSL port
+ ///
+ public Int32 SslPort { get; internal set; }
+
+ ///
+ /// Timeout on client connection (before receiving CONNECT message)
+ ///
+ public Int32 TimeoutOnConnection { get; internal set; }
+
+ ///
+ /// Timeout on receiving
+ ///
+ public Int32 TimeoutOnReceiving { get; internal set; }
+
+ ///
+ /// Attempts on retry
+ ///
+ public Int32 AttemptsOnRetry { get; internal set; }
+
+ ///
+ /// Delay on retry
+ ///
+ public Int32 DelayOnRetry { get; internal set; }
+
+ ///
+ /// Inflight queue size
+ ///
+ public Int32 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/M2Mqtt/Net/Fx.cs b/M2Mqtt/Net/Fx.cs
index 3fcc505..a2a243c 100644
--- a/M2Mqtt/Net/Fx.cs
+++ b/M2Mqtt/Net/Fx.cs
@@ -14,23 +14,16 @@ Contributors:
Paolo Patierno - initial API and implementation and/or initial documentation
*/
+using System;
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);
- }
- }
+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(Int32 millisecondsTimeout) => Thread.Sleep(millisecondsTimeout);
+ }
}
diff --git a/M2Mqtt/Net/MqttNetworkChannel.cs b/M2Mqtt/Net/MqttNetworkChannel.cs
index c98879a..3aeb662 100644
--- a/M2Mqtt/Net/MqttNetworkChannel.cs
+++ b/M2Mqtt/Net/MqttNetworkChannel.cs
@@ -15,13 +15,17 @@ Contributors:
*/
#if SSL
-#if (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3)
+#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;
+#if NETCOREAPP
+using System.Net.Security;
+#endif
+
#endif
#endif
+
using System.Net.Sockets;
using System.Net;
using System.Security.Cryptography.X509Certificates;
@@ -29,90 +33,73 @@ using System;
//using System.Security.Authentication;
//using System.Net.Security;
-namespace uPLibrary.Networking.M2Mqtt
-{
- ///
- /// Channel to communicate over the network
- ///
- public class MqttNetworkChannel : IMqttNetworkChannel
- {
+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;
+ private readonly RemoteCertificateValidationCallback userCertificateValidationCallback;
+ private readonly LocalCertificateSelectionCallback userCertificateSelectionCallback;
#endif
- // remote host information
- private string remoteHostName;
- private IPAddress remoteIpAddress;
- private int remotePort;
+ // remote host information
- // socket for communication
- private Socket socket;
- // using SSL
- private bool secure;
+ // socket for communication
+ private Socket socket;
+ // using SSL
+ private readonly Boolean secure;
- // CA certificate (on client)
- private X509Certificate caCert;
- // Server certificate (on broker)
- private X509Certificate serverCert;
- // client certificate (on client)
- private X509Certificate clientCert;
+ // CA certificate (on client)
+ private readonly X509Certificate caCert;
+ // Server certificate (on broker)
+ private readonly X509Certificate serverCert;
+ // client certificate (on client)
+ private readonly X509Certificate clientCert;
- // SSL/TLS protocol version
- private MqttSslProtocols sslProtocol;
+ // SSL/TLS protocol version
+ private readonly MqttSslProtocols sslProtocol;
- ///
- /// Remote host name
- ///
- public string RemoteHostName { get { return this.remoteHostName; } }
+ ///
+ /// Remote host name
+ ///
+ public String RemoteHostName { get; }
- ///
- /// Remote IP address
- ///
- public IPAddress RemoteIpAddress { get { return this.remoteIpAddress; } }
+ ///
+ /// Remote IP address
+ ///
+ public IPAddress RemoteIpAddress { get; }
- ///
- /// Remote port
- ///
- public int RemotePort { get { return this.remotePort; } }
+ ///
+ /// Remote port
+ ///
+ public Int32 RemotePort { get; }
#if SSL
- // SSL stream
- private SslStream sslStream;
-#if (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3)
- private NetworkStream netStream;
+ // 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
- {
+ ///
+ /// Data available on the channel
+ ///
#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);
+#if MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3
+ public Boolean DataAvailable => this.secure ? this.sslStream.DataAvailable : this.socket.Available > 0;
#else
- if (secure)
- return this.netStream.DataAvailable;
- else
- return (this.socket.Available > 0);
+ public Boolean DataAvailable => this.secure ? this.netStream.DataAvailable : this.socket.Available > 0;
#endif
#else
- return (this.socket.Available > 0);
+ public Boolean DataAvailable => this.socket.Available > 0;
#endif
- }
- }
- ///
- /// Constructor
- ///
- /// Socket opened with the client
- public MqttNetworkChannel(Socket socket)
+ ///
+ /// 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
@@ -120,212 +107,203 @@ namespace uPLibrary.Networking.M2Mqtt
#endif
{
- }
-
- ///
- /// Constructor
- ///
- /// Socket opened with the client
- /// Secure connection (SSL/TLS)
- /// Server X509 certificate for secure connection
- /// SSL/TLS protocol version
+ }
+
+ ///
+ /// 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)
+ /// 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, Boolean 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;
+ 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;
+ this.userCertificateValidationCallback = userCertificateValidationCallback;
+ this.userCertificateSelectionCallback = userCertificateSelectionCallback;
#endif
- }
+ }
- ///
- /// Constructor
- ///
- /// Remote Host name
- /// Remote port
- public MqttNetworkChannel(string remoteHostName, int remotePort)
+ ///
+ /// Constructor
+ ///
+ /// Remote Host name
+ /// Remote port
+ public MqttNetworkChannel(String remoteHostName, Int32 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
+ ///
+ /// 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)
+ /// 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, Int32 remotePort, Boolean 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
- {
- }
+ 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");
- }
- }
+ // 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"
+ Int32 i = 0;
+ while (hostEntry.AddressList[i] == null) {
+ i++;
+ }
- 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
+ remoteIpAddress = hostEntry.AddressList[i];
+ } else {
+ throw new Exception("No address found for the remote host name");
}
+ }
- ///
- /// 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));
+ 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)
+ // secure channel requested
+ if (this.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);
+ 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)
+ // 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
+ 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 });
}
- ///
- /// Send data on the network channel
- ///
- /// Data buffer to send
- /// Number of byte sent
- public int Send(byte[] buffer)
- {
+ 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 Int32 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);
+ 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)
- {
+ ///
+ /// Receive data from the network
+ ///
+ /// Data buffer for receiving data
+ /// Number of bytes received
+ public Int32 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;
- }
+ if (this.secure) {
+ // read all data needed (until fill buffer)
+ Int32 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)
+ Int32 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;
@@ -340,118 +318,94 @@ namespace uPLibrary.Networking.M2Mqtt
}
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
+ /// Receive data from the network channel with a specified timeout
///
- 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;
+ /// Data buffer for receiving data
+ /// Timeout on receiving (in milliseconds)
+ /// Number of bytes received
+ public Int32 Receive(Byte[] buffer, Int32 timeout) =>
+ // check data availability (timeout is in microseconds)
+ this.socket.Poll(timeout * 1000, SelectMode.SelectRead) ? this.Receive(buffer) : 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 (this.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
+ ipAddress.AddressFamily;
#else
return (ipAddress.ToString().IndexOf(':') != -1) ?
AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork;
#endif
- }
- }
- ///
- /// MQTT SSL utility class
- ///
- public static class MqttSslUtility
+ }
+
+ ///
+ /// 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) => mqttSslProtocol switch
{
-#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)
+ MqttSslProtocols.None => SslProtocols.None,
+ //MqttSslProtocols.SSLv3 => SslProtocols.Ssl3,
+ MqttSslProtocols.TLSv1_0 => SslProtocols.Tls,
+ MqttSslProtocols.TLSv1_1 => SslProtocols.Tls11,
+ MqttSslProtocols.TLSv1_2 => SslProtocols.Tls12,
+ _ => 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)
{
@@ -468,5 +422,5 @@ namespace uPLibrary.Networking.M2Mqtt
}
}
#endif
- }
+ }
}
diff --git a/M2Mqtt/Properties/AssemblyInfo.cs b/M2Mqtt/Properties/AssemblyInfo.cs
index b218618..d2d0755 100644
--- a/M2Mqtt/Properties/AssemblyInfo.cs
+++ b/M2Mqtt/Properties/AssemblyInfo.cs
@@ -13,7 +13,7 @@ and the Eclipse Distribution License is available at
Contributors:
Paolo Patierno - initial API and implementation and/or initial documentation
*/
-
+#if !NETCOREAPP
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@@ -41,4 +41,5 @@ using System.Runtime.InteropServices;
// to avoid compilation error (AssemblyFileVersionAttribute doesn't exist) under .Net CF 3.5
#if !WindowsCE
[assembly: AssemblyFileVersion("4.3.0.0")]
+#endif
#endif
\ No newline at end of file
diff --git a/M2Mqtt/Session/MqttClientSession.cs b/M2Mqtt/Session/MqttClientSession.cs
index 7613880..cd3f824 100644
--- a/M2Mqtt/Session/MqttClientSession.cs
+++ b/M2Mqtt/Session/MqttClientSession.cs
@@ -14,20 +14,18 @@ Contributors:
Paolo Patierno - initial API and implementation and/or initial documentation
*/
-namespace uPLibrary.Networking.M2Mqtt.Session
-{
+using System;
+
+namespace uPLibrary.Networking.M2Mqtt.Session {
+ ///
+ /// MQTT Client Session
+ ///
+ public class MqttClientSession : MqttSession {
///
- /// MQTT Client Session
+ /// Constructor
///
- public class MqttClientSession : MqttSession
- {
- ///
- /// Constructor
- ///
- /// Client Id to create session
- public MqttClientSession(string clientId)
- : base(clientId)
- {
- }
- }
+ /// Client Id to create session
+ public MqttClientSession(String clientId) : base(clientId) {
+ }
+ }
}
diff --git a/M2Mqtt/Session/MqttSession.cs b/M2Mqtt/Session/MqttSession.cs
index 712a854..91cc416 100644
--- a/M2Mqtt/Session/MqttSession.cs
+++ b/M2Mqtt/Session/MqttSession.cs
@@ -14,50 +14,46 @@ Contributors:
Paolo Patierno - initial API and implementation and/or initial documentation
*/
+using System;
using System.Collections;
-namespace uPLibrary.Networking.M2Mqtt.Session
-{
+namespace uPLibrary.Networking.M2Mqtt.Session {
+ ///
+ /// MQTT Session base class
+ ///
+ public abstract class MqttSession {
///
- /// MQTT Session base class
+ /// Client Id
///
- 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();
- }
- }
-}
+ 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();
+ }
+ }
+}
\ No newline at end of file
diff --git a/M2Mqtt/Utility/QueueExtension.cs b/M2Mqtt/Utility/QueueExtension.cs
index 70175c3..39de963 100644
--- a/M2Mqtt/Utility/QueueExtension.cs
+++ b/M2Mqtt/Utility/QueueExtension.cs
@@ -17,34 +17,31 @@ Contributors:
using System;
using System.Collections;
-namespace uPLibrary.Networking.M2Mqtt.Utility
-{
+namespace uPLibrary.Networking.M2Mqtt.Utility {
+ ///
+ /// Extension class for a Queue
+ ///
+ internal static class QueueExtension {
///
- /// Extension class for a Queue
+ /// Predicate for searching inside 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;
- }
- }
+ /// Item of the queue
+ /// Result of predicate
+ internal delegate Boolean 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 (Object item in queue) {
+ if (predicate(item)) {
+ return item;
+ }
+ }
+ return null;
+ }
+ }
}
diff --git a/M2Mqtt/Utility/Trace.cs b/M2Mqtt/Utility/Trace.cs
index c299ebe..3771285 100644
--- a/M2Mqtt/Utility/Trace.cs
+++ b/M2Mqtt/Utility/Trace.cs
@@ -14,73 +14,57 @@ Contributors:
Paolo Patierno - initial API and implementation and/or initial documentation
*/
+using System;
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);
- }
- }
- }
+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) => TraceListener?.Invoke(format, args);
+
+ public static void WriteLine(TraceLevel level, String format) {
+ if ((level & TraceLevel) > 0) {
+ TraceListener.Invoke(format);
+ }
+ }
+
+ public static void WriteLine(TraceLevel level, String format, Object arg1) {
+ if ( (level & TraceLevel) > 0) {
+ TraceListener.Invoke(format, arg1);
+ }
+ }
+
+ public static void WriteLine(TraceLevel level, String format, Object arg1, Object arg2) {
+ if ((level & TraceLevel) > 0) {
+ TraceListener.Invoke(format, arg1, arg2);
+ }
+ }
+
+ public static void WriteLine(TraceLevel level, String format, Object arg1, Object arg2, Object arg3) {
+ if ((level & TraceLevel) > 0) {
+ TraceListener.Invoke(format, arg1, arg2, arg3);
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/M2Mqtt/WinRT/Fx.cs b/M2Mqtt/WinRT/Fx.cs
index 6d62d28..b853cd6 100644
--- a/M2Mqtt/WinRT/Fx.cs
+++ b/M2Mqtt/WinRT/Fx.cs
@@ -13,7 +13,7 @@ and the Eclipse Distribution License is available at
Contributors:
Paolo Patierno - initial API and implementation and/or initial documentation
*/
-
+#if !NETCOREAPP
using System.Threading;
using System.Threading.Tasks;
@@ -33,4 +33,5 @@ namespace uPLibrary.Networking.M2Mqtt
public static void SleepThread(int millisecondsTimeout) { Task.Delay(millisecondsTimeout).RunSynchronously(); }
}
-}
+}
+#endif
\ No newline at end of file
diff --git a/M2Mqtt/WinRT/Hashtable.cs b/M2Mqtt/WinRT/Hashtable.cs
index a42532b..2eeeebd 100644
--- a/M2Mqtt/WinRT/Hashtable.cs
+++ b/M2Mqtt/WinRT/Hashtable.cs
@@ -13,7 +13,7 @@ and the Eclipse Distribution License is available at
Contributors:
Paolo Patierno - initial API and implementation and/or initial documentation
*/
-
+#if !NETCOREAPP
using System.Collections.Generic;
namespace uPLibrary.Networking.M2Mqtt
@@ -25,3 +25,4 @@ namespace uPLibrary.Networking.M2Mqtt
{
}
}
+#endif
\ No newline at end of file
diff --git a/M2Mqtt/WinRT/MqttNetworkChannel.cs b/M2Mqtt/WinRT/MqttNetworkChannel.cs
index 305992c..4028f07 100644
--- a/M2Mqtt/WinRT/MqttNetworkChannel.cs
+++ b/M2Mqtt/WinRT/MqttNetworkChannel.cs
@@ -13,7 +13,7 @@ and the Eclipse Distribution License is available at
Contributors:
Paolo Patierno - initial API and implementation and/or initial documentation
*/
-
+#if !NETCOREAPP
using System;
using System.Collections.Generic;
using System.Linq;
@@ -177,3 +177,4 @@ namespace uPLibrary.Networking.M2Mqtt
}
}
}
+#endif
\ No newline at end of file
diff --git a/M2Mqtt/WinRT/Queue.cs b/M2Mqtt/WinRT/Queue.cs
index bc6728f..3492a52 100644
--- a/M2Mqtt/WinRT/Queue.cs
+++ b/M2Mqtt/WinRT/Queue.cs
@@ -13,7 +13,7 @@ and the Eclipse Distribution License is available at
Contributors:
Paolo Patierno - initial API and implementation and/or initial documentation
*/
-
+#if !NETCOREAPP
using System.Collections.Generic;
namespace uPLibrary.Networking.M2Mqtt
@@ -25,3 +25,4 @@ namespace uPLibrary.Networking.M2Mqtt
{
}
}
+#endif
\ No newline at end of file
diff --git a/M2Mqtt_Core.sln b/M2Mqtt_Core.sln
new file mode 100644
index 0000000..dd105ab
--- /dev/null
+++ b/M2Mqtt_Core.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29519.87
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "M2Mqtt", "M2Mqtt\M2Mqtt_Core.csproj", "{18F706D2-7610-428C-8324-8327F9D7BE90}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {18F706D2-7610-428C-8324-8327F9D7BE90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {18F706D2-7610-428C-8324-8327F9D7BE90}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {18F706D2-7610-428C-8324-8327F9D7BE90}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {18F706D2-7610-428C-8324-8327F9D7BE90}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {EBFDF320-2C59-4F89-8211-5B6EF9C310ED}
+ EndGlobalSection
+EndGlobal