Пример #1
0
        /// <summary>
        /// Subscribe for message topics
        /// </summary>
        /// <param name="topics">List of topics to subscribe</param>
        /// <param name="qosLevels">QOS levels related to topics</param>
        /// <returns>Granted QoS Levels in SUBACK message from broker</returns>
        public byte[] Subscribe(string[] topics, byte[] qosLevels)
        {
            int  attempts     = 0;
            bool acknowledged = false;

            MqttMsgSubscribe subscribe =
                new MqttMsgSubscribe(topics, qosLevels);

            MqttMsgSuback suback = null;

            do
            {
                try
                {
                    // try subscribe
                    suback       = (MqttMsgSuback)this.SendReceive(subscribe.GetBytes());
                    acknowledged = true;
                }
                catch (MqttTimeoutException)
                {
                    // no SUBACK message received in time, retry with duplicate flag
                    attempts++;
                    subscribe.DupFlag = true;
                    // delay before retry
                    if (attempts < MQTT_ATTEMPTS_RETRY)
                    {
                        Thread.Sleep(MQTT_DELAY_RETRY);
                    }
                }
            } while ((attempts < MQTT_ATTEMPTS_RETRY) && !acknowledged);

            // return granted QoS Levels or null
            return(acknowledged ? suback.GrantedQoSLevels : null);
        }
Пример #2
0
 protected void DecodeMultiplePacketsByteArray(uint clientIndex, byte[] data, bool isWebSocketClient)
 {
     lock (oldDecodedFrame)
     {
         int         numberOfBytesProcessed = 0;
         int         numberOfBytesToProcess = 0;
         int         numberOfBytesReceived  = data.Length;
         byte[]      packetByteArray;
         List <byte> packets   = new List <byte>();
         MqttMsgBase tmpPacket = new MqttMsgSubscribe();
         try
         {
             while (numberOfBytesProcessed != numberOfBytesReceived)
             {
                 int remainingLength      = MqttMsgBase.decodeRemainingLength(data);
                 int remainingLenghtIndex = tmpPacket.encodeRemainingLength(remainingLength, data, 1);
                 numberOfBytesToProcess = remainingLength + remainingLenghtIndex;
                 packetByteArray        = new byte[numberOfBytesToProcess];
                 Array.Copy(data, 0, packetByteArray, 0, numberOfBytesToProcess);
                 MqttMsgBase packet = PacketDecoder.DecodeControlPacket(packetByteArray);
                 OnPacketReceived(clientIndex, packet, isWebSocketClient);
                 {
                     byte[] tmp = new byte[data.Length - numberOfBytesToProcess];
                     Array.Copy(data, numberOfBytesToProcess, tmp, 0, tmp.Length);
                     data = tmp;
                 }
                 numberOfBytesProcessed += numberOfBytesToProcess;
             }
         }
         catch (Exception e)
         {
             oldDecodedFrame[clientIndex].AddRange(data);
         }
     }
 }
Пример #3
0
    /// <summary>
    /// <description>Subscribes a client to defined topic</description>
    /// </summary>
    /// <param name="topics">the topic the client subscribes to</param>
    /// <param name="qosLevels">The level of quality service the message is sent with</param>
    /// <returns></returns>
    public override ushort Subscribe(string [] topics, byte [] qosLevels)
    {
        MqttMsgSubscribe subscribe = new MqttMsgSubscribe(topics, qosLevels);

        subscribe.MessageId = this.GetMessageId();

        // enqueue subscribe request into the inflight queue
        this.EnqueueInflight(subscribe, MqttMsgFlow.ToPublish);

        if (topicList.Count == 0)
        {
            for (int i = 0; i < topics.Length; i++)
            {
                AddButton(topics, i);
            }
        }
        else
        {
            for (int j = 0; j < topics.Length; j++)
            {
                for (int i = 0; i < topicList.Count; i++)
                {
                    if (topicList[i].Equals(topics[j]))
                    {
                        return(subscribe.MessageId);
                    }
                }
                //Debug.Log (topicList [i]);
                Debug.Log(topics[j]);
                AddButton(topics, j);
            }
        }
        return(subscribe.MessageId);
    }
        public void SubscribeDecodeAvanceTestsv5()
        {
            // Arrange
            byte[] encodedCorrect = new byte[] { 249, 1, 0, 42, 223, 1, 11, 253, 255, 255, 127, 38, 0, 8, 108, 111, 110, 103, 32, 111, 110, 101, 0, 210,
                                                 111, 110, 101, 32, 118, 101, 114, 121, 32, 108, 111, 110, 103, 32, 111, 110, 101, 32, 116, 111, 32, 116,
                                                 101, 115, 116, 32, 102, 111, 114, 32, 111, 110, 99, 101, 32, 104, 111, 119, 32, 116, 104, 105, 115, 32,
                                                 119, 105, 108, 108, 32, 101, 110, 99, 111, 100, 101, 32, 97, 110, 100, 32, 109, 97, 107, 101, 32, 105,
                                                 116, 32, 114, 101, 97, 108, 108, 108, 108, 108, 108, 121, 121, 121, 121, 121, 121, 121, 32, 115, 111,
                                                 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 32, 115, 111, 111, 111, 111, 111, 111, 111, 111,
                                                 111, 111, 111, 111, 111, 111, 32, 115, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,
                                                 111, 111, 111, 32, 115, 111, 111, 111, 111, 111, 111, 111, 111, 111, 32, 108, 111, 110, 103, 46, 32, 89,
                                                 101, 97, 44, 32, 116, 104, 97, 116, 32, 115, 104, 111, 117, 108, 100, 32, 98, 101, 32, 116, 101, 115, 116,
                                                 101, 100, 32, 102, 111, 114, 32, 114, 101, 97, 108, 32, 105, 110, 32, 116, 104, 101, 32, 114, 101, 97,
                                                 108, 32, 108, 105, 102, 101, 32, 97, 115, 32, 119, 101, 108, 108, 0, 5, 102, 105, 114, 115, 116, 1, 0, 6,
                                                 115, 101, 99, 111, 110, 100, 2 };
            MokChannel mokChannel = new MokChannel(encodedCorrect);
            // Act
            MqttMsgSubscribe subscribe = MqttMsgSubscribe.Parse(130, MqttProtocolVersion.Version_5, mokChannel);

            // Assert
            Assert.Equal(subscribe.MessageId, (ushort)42);
            Assert.Equal(subscribe.QoSLevels, new MqttQoSLevel[] { MqttQoSLevel.AtLeastOnce, MqttQoSLevel.ExactlyOnce });
            Assert.Equal(subscribe.Topics, new string[] { "first", "second" });
            Assert.Equal(subscribe.SubscriptionIdentifier, 268435453);
            var prop = new UserProperty("long one", "one very long one to test for once how this will encode and make it reallllllyyyyyyy soooooooooooo soooooooooooooo soooooooooooooooo sooooooooo long. Yea, that should be tested for real in the real life as well");

            Assert.Equal(((UserProperty)subscribe.UserProperties[0]).Name, prop.Name);
            Assert.Equal(((UserProperty)subscribe.UserProperties[0]).Value, prop.Value);
        }
Пример #5
0
        public void DecodeMultiplePacketsByteArray(byte[] data)
        {
            List <MqttMsgBase> packetsInTheByteArray = new List <MqttMsgBase>();
            int numberOfBytesProcessed = 0;
            int numberOfBytesToProcess = 0;
            int numberOfBytesReceived  = data.Length;

            byte[]      packetByteArray;
            MqttMsgBase tmpPacket = new MqttMsgSubscribe();

            while (numberOfBytesProcessed != numberOfBytesReceived)
            {
                int remainingLength      = MqttMsgBase.decodeRemainingLength(data);
                int remainingLenghtIndex = tmpPacket.encodeRemainingLength(remainingLength, data, 1);
                numberOfBytesToProcess = remainingLength + remainingLenghtIndex;
                packetByteArray        = new byte[numberOfBytesToProcess];
                Array.Copy(data, 0, packetByteArray, 0, numberOfBytesToProcess);
                {
                    byte[] tmp = new byte[data.Length - numberOfBytesToProcess];
                    Array.Copy(data, numberOfBytesToProcess, tmp, 0, tmp.Length);
                    data = tmp;
                }
                numberOfBytesProcessed += numberOfBytesToProcess;
                MqttMsgBase packet = PacketDecoder.DecodeControlPacket(packetByteArray);
                //RouteControlPacketDelegate r = new RouteControlPacketDelegate(RouteControlPacketToMethodHandler);
                //r.Invoke(packet);
                CrestronInvoke.BeginInvoke(RouteControlPacketToMethodHandler, packet);
            }
        }
Пример #6
0
        public void Subscribe(string clientId, MqttMsgSubscribe packet)
        {
            try
            {
                Session             session = SessionManager.sessions.First(ss => ss.ClientId == clientId);
                List <Subscription> subs    = session.Subscriptions;
                lock (subs)
                {
                    for (int i = 0; i < packet.Topics.Length; i++)
                    {
                        string topicReplaced = packet.Topics[i].Replace(PLUS_WILDCARD, PLUS_WILDCARD_REPLACE).Replace(SHARP_WILDCARD, SHARP_WILDCARD_REPLACE);
                        topicReplaced = "^" + topicReplaced + "$";

                        Subscription existingSubscription = subs.FirstOrDefault(sub => sub.Topic == packet.Topics[i]);
                        if (existingSubscription == null)
                        {
                            Subscription s = new Subscription(clientId, topicReplaced, packet.QoSLevels[i]);
                            subs.Add(s);
                        }
                    }
                    OnClientSubscribed(packet.Topics, clientId);
                }
            }
            catch (Exception)
            {
                throw;
            }
        }
Пример #7
0
        private void HandleSUBSCRIBEType(uint clientIndex, MqttMsgSubscribe packet, bool isWebSocketClient)
        {
            CrestronLogger.WriteToLog("MQTTSERVER  - HandleSUBSCRIBEType - Subscription Received" + packet.ToString(), 6);
            sessionManager.AddSubscription(GetClientByIndex(clientIndex, isWebSocketClient).ClientId, packet);

            byte[] subAckBytes = MsgBuilder.BuildSubAck(packet.MessageId, packet.QoSLevels).GetBytes();
            Send(clientIndex, subAckBytes, subAckBytes.Length, isWebSocketClient);
        }
Пример #8
0
        internal static MqttMsgSubscribe BuildSubscribe(string[] topics, byte[] qosLevels, ushort messageId)
        {
            MqttMsgSubscribe subscribe = new MqttMsgSubscribe();

            subscribe.Topics    = topics.ToArray();
            subscribe.QoSLevels = qosLevels;
            subscribe.MessageId = messageId;
            return(subscribe);
        }
        public void SubscribeDecodeBasicTestsv5()
        {
            // Arrange
            byte[]     encodedCorrect = new byte[] { 20, 0, 42, 0, 0, 5, 102, 105, 114, 115, 116, 1, 0, 6, 115, 101, 99, 111, 110, 100, 2 };
            MokChannel mokChannel     = new MokChannel(encodedCorrect);
            // Act
            MqttMsgSubscribe subscribe = MqttMsgSubscribe.Parse(130, MqttProtocolVersion.Version_5, mokChannel);

            // Assert
            Assert.Equal(subscribe.MessageId, (ushort)42);
            Assert.Equal(subscribe.QoSLevels, new MqttQoSLevel[] { MqttQoSLevel.AtLeastOnce, MqttQoSLevel.ExactlyOnce });
            Assert.Equal(subscribe.Topics, new string[] { "first", "second" });
        }
Пример #10
0
        public static MqttMsgBase DecodeControlPacket(byte[] data)
        {
            byte fixedHeaderFirstByte = (byte)(data[0] >> MqttMsgBase.MSG_TYPE_OFFSET);

            switch (fixedHeaderFirstByte)
            {
            case MqttMsgBase.MQTT_MSG_CONNECT_TYPE:
            {
                return(MqttMsgConnect.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_CONNACK_TYPE:
            {
                return(MqttMsgConnack.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_PUBLISH_TYPE:
            {
                return(MqttMsgPublish.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_PUBACK_TYPE:
            {
                return(MqttMsgPuback.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_PUBREC_TYPE:
            {
                return(MqttMsgPubrec.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_PUBREL_TYPE:
            {
                return(MqttMsgPubrel.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_PUBCOMP_TYPE:
            {
                return(MqttMsgPubcomp.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_SUBSCRIBE_TYPE:
            {
                return(MqttMsgSubscribe.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_SUBACK_TYPE:
            {
                return(MqttMsgSuback.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_UNSUBSCRIBE_TYPE:
            {
                return(MqttMsgUnsubscribe.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_UNSUBACK_TYPE:
            {
                return(MqttMsgUnsuback.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_PINGREQ_TYPE:
            {
                return(MqttMsgPingReq.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_PINGRESP_TYPE:
            {
                return(MqttMsgPingResp.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_DISCONNECT_TYPE:
            {
                CrestronLogger.WriteToLog("PACKETDECODER - Riconosciuto DISCONNNECT: ", 1);
                return(MqttMsgDisconnect.Parse(data));
            }

            default:
            {
                throw new FormatException();
            }
            }
        }
Пример #11
0
 internal void AddSubscription(string clientId, MqttMsgSubscribe packet)
 {
     subscriptionManager.Subscribe(clientId, packet);
 }
Пример #12
0
        public MqttMsgBase DecodeControlPacket(byte[] data)
        {
            byte fixedHeaderFirstByte = (byte)(data[0] >> MSG_TYPE_OFFSET);

            switch (fixedHeaderFirstByte)
            {
            case MqttMsgBase.MQTT_MSG_CONNECT_TYPE:
            {
                return(MqttMsgConnect.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_CONNACK_TYPE:
            {
                return(MqttMsgConnack.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_PUBLISH_TYPE:
            {
                return(MqttMsgPublish.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_PUBACK_TYPE:
            {
                return(MqttMsgPuback.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_PUBREC_TYPE:
            {
                return(MqttMsgPubrec.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_PUBREL_TYPE:
            {
                return(MqttMsgPubrel.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_PUBCOMP_TYPE:
            {
                return(MqttMsgPubcomp.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_SUBSCRIBE_TYPE:
            {
                return(MqttMsgSubscribe.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_SUBACK_TYPE:
            {
                return(MqttMsgSuback.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_UNSUBSCRIBE_TYPE:
            {
                return(MqttMsgUnsubscribe.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_UNSUBACK_TYPE:
            {
                return(MqttMsgUnsuback.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_PINGREQ_TYPE:
            {
                return(MqttMsgPingReq.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_PINGRESP_TYPE:
            {
                return(MqttMsgPingResp.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_DISCONNECT_TYPE:
            {
                return(MqttMsgDisconnect.Parse(data));
            }

            default:
            {
                throw new FormatException(" First byte shifted : " + fixedHeaderFirstByte);
            }
            }
        }
        public void ProcessReceivedMessage(MqttRawMessage rawMessage)
        {
            if (!rawMessage.Connection.IsRunning)
            {
                return;
            }

            // update last message received ticks
            rawMessage.Connection.LastCommunicationTime = Environment.TickCount;

            // extract message type from received byte
            var msgType         = (byte)((rawMessage.MessageType & MqttMsgBase.MSG_TYPE_MASK) >> MqttMsgBase.MSG_TYPE_OFFSET);
            var protocolVersion = (byte)rawMessage.Connection.ProtocolVersion;

            switch (msgType)
            {
            case MqttMsgBase.MQTT_MSG_CONNECT_TYPE:
                var connect = MqttMsgConnect.Parse(
                    rawMessage.MessageType,
                    protocolVersion,
                    rawMessage.PayloadBuffer);
                rawMessage.Connection.EnqueueInternalEvent(new InternalEvent(connect));
                break;

            case MqttMsgBase.MQTT_MSG_PINGREQ_TYPE:
                var pingReqest = MqttMsgPingReq.Parse(rawMessage.MessageType, protocolVersion);
                outgoingMessageHandler.PingResp(rawMessage.Connection);
                break;

            case MqttMsgBase.MQTT_MSG_SUBSCRIBE_TYPE:
                var subscribe = MqttMsgSubscribe.Parse(
                    rawMessage.MessageType,
                    protocolVersion,
                    rawMessage.PayloadBuffer,
                    rawMessage.PayloadLength);
                rawMessage.Connection.EnqueueInternalEvent(new InternalEvent(subscribe));
                break;

            case MqttMsgBase.MQTT_MSG_PUBLISH_TYPE:
                var publish = MqttMsgPublish.Parse(
                    rawMessage.MessageType,
                    protocolVersion,
                    rawMessage.PayloadBuffer,
                    rawMessage.PayloadLength);
                EnqueueInflight(rawMessage.Connection, publish, MqttMsgFlow.ToAcknowledge);
                break;

            case MqttMsgBase.MQTT_MSG_PUBACK_TYPE:
                // enqueue PUBACK message received (for QoS Level 1) into the internal queue
                var puback = MqttMsgPuback.Parse(
                    rawMessage.MessageType,
                    protocolVersion,
                    rawMessage.PayloadBuffer);
                EnqueueInternal(rawMessage.Connection, puback);
                break;

            case MqttMsgBase.MQTT_MSG_PUBREC_TYPE:
                // enqueue PUBREC message received (for QoS Level 2) into the internal queue
                var pubrec = MqttMsgPubrec.Parse(
                    rawMessage.MessageType,
                    protocolVersion,
                    rawMessage.PayloadBuffer);
                EnqueueInternal(rawMessage.Connection, pubrec);
                break;

            case MqttMsgBase.MQTT_MSG_PUBREL_TYPE:
                // enqueue PUBREL message received (for QoS Level 2) into the internal queue
                var pubrel = MqttMsgPubrel.Parse(
                    rawMessage.MessageType,
                    protocolVersion,
                    rawMessage.PayloadBuffer);
                EnqueueInternal(rawMessage.Connection, pubrel);
                break;

            case MqttMsgBase.MQTT_MSG_PUBCOMP_TYPE:
                // enqueue PUBCOMP message received (for QoS Level 2) into the internal queue
                var pubcomp = MqttMsgPubcomp.Parse(
                    rawMessage.MessageType,
                    protocolVersion,
                    rawMessage.PayloadBuffer);
                EnqueueInternal(rawMessage.Connection, pubcomp);
                break;

            case MqttMsgBase.MQTT_MSG_UNSUBSCRIBE_TYPE:
                var unsubscribe = MqttMsgUnsubscribe.Parse(
                    rawMessage.MessageType,
                    protocolVersion,
                    rawMessage.PayloadBuffer,
                    rawMessage.PayloadLength);
                rawMessage.Connection.EnqueueInternalEvent(new InternalEvent(unsubscribe));
                break;

            case MqttMsgBase.MQTT_MSG_DISCONNECT_TYPE:
                var disconnect = MqttMsgDisconnect.Parse(rawMessage.MessageType, protocolVersion);
                rawMessage.Connection.EnqueueInternalEvent(new InternalEvent(disconnect));
                break;

            case MqttMsgBase.MQTT_MSG_CONNACK_TYPE:
            case MqttMsgBase.MQTT_MSG_PINGRESP_TYPE:
            case MqttMsgBase.MQTT_MSG_SUBACK_TYPE:
            case MqttMsgBase.MQTT_MSG_UNSUBACK_TYPE:
                throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);

            default:
                throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
            }
        }
Пример #14
0
        public MqttMsgBase DecodeControlPacket(byte[] data)
        {
            #if PACKET_DEBUG
            CrestronLogger.WriteToLog("MQTTCLIENT - RECEIVE - " + BitConverter.ToString(data), 2);
            #endif

            byte fixedHeaderFirstByte = (byte)(data[0] >> MSG_TYPE_OFFSET);

            switch (fixedHeaderFirstByte)
            {
            case MqttMsgBase.MQTT_MSG_CONNECT_TYPE:
            {
                return(MqttMsgConnect.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_CONNACK_TYPE:
            {
                return(MqttMsgConnack.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_PUBLISH_TYPE:
            {
                return(MqttMsgPublish.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_PUBACK_TYPE:
            {
                return(MqttMsgPuback.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_PUBREC_TYPE:
            {
                return(MqttMsgPubrec.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_PUBREL_TYPE:
            {
                return(MqttMsgPubrel.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_PUBCOMP_TYPE:
            {
                return(MqttMsgPubcomp.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_SUBSCRIBE_TYPE:
            {
                return(MqttMsgSubscribe.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_SUBACK_TYPE:
            {
                return(MqttMsgSuback.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_UNSUBSCRIBE_TYPE:
            {
                return(MqttMsgUnsubscribe.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_UNSUBACK_TYPE:
            {
                return(MqttMsgUnsuback.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_PINGREQ_TYPE:
            {
                return(MqttMsgPingReq.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_PINGRESP_TYPE:
            {
                return(MqttMsgPingResp.Parse(data));
            }

            case MqttMsgBase.MQTT_MSG_DISCONNECT_TYPE:
            {
                return(MqttMsgDisconnect.Parse(data));
            }

            default:
            {
                throw new FormatException(" First byte shifted : " + fixedHeaderFirstByte);
            }
            }
        }
        public static void ProcessInternalEventQueue(MqttClientConnection clientConnection)
        {
            if (!clientConnection.IsRunning)
            {
                return;
            }

            InternalEvent internalEvent;

            if (clientConnection.EventQueue.TryDequeue(out internalEvent))
            {
                MqttMsgBase msg = ((MsgInternalEvent)internalEvent).Message;
                if (msg != null)
                {
                    switch (msg.Type)
                    {
                    // CONNECT message received
                    case MqttMsgBase.MQTT_MSG_CONNECT_TYPE:
                        clientConnection.OnMqttMsgConnected((MqttMsgConnect)msg);
                        break;

                    // SUBSCRIBE message received
                    case MqttMsgBase.MQTT_MSG_SUBSCRIBE_TYPE:
                        MqttMsgSubscribe subscribe = (MqttMsgSubscribe)msg;
                        clientConnection.OnMqttMsgSubscribeReceived(subscribe.MessageId, subscribe.Topics, subscribe.QoSLevels);
                        break;

                    // SUBACK message received
                    case MqttMsgBase.MQTT_MSG_SUBACK_TYPE:
                        OnMqttMsgSubscribed(clientConnection, (MqttMsgSuback)msg);
                        break;

                    // PUBLISH message received
                    case MqttMsgBase.MQTT_MSG_PUBLISH_TYPE:
                        // PUBLISH message received in a published internal event, no publish succeeded
                        if (internalEvent.GetType() == typeof(MsgPublishedInternalEvent))
                        {
                            OnMqttMsgPublished(clientConnection, msg.MessageId, false);
                        }
                        else
                        {
                            // raise PUBLISH message received event
                            clientConnection.OnMqttMsgPublishReceived((MqttMsgPublish)msg);
                        }

                        break;

                    // (PUBACK received for QoS Level 1)
                    case MqttMsgBase.MQTT_MSG_PUBACK_TYPE:
                        OnMqttMsgPublished(clientConnection, msg.MessageId, true);
                        break;

                    // (PUBREL received for QoS Level 2)
                    case MqttMsgBase.MQTT_MSG_PUBREL_TYPE:
                        clientConnection.OnMqttMsgPublishReceived((MqttMsgPublish)msg);
                        break;

                    // (PUBCOMP received for QoS Level 2)
                    case MqttMsgBase.MQTT_MSG_PUBCOMP_TYPE:
                        OnMqttMsgPublished(clientConnection, msg.MessageId, true);
                        break;

                    // UNSUBSCRIBE message received from client
                    case MqttMsgBase.MQTT_MSG_UNSUBSCRIBE_TYPE:
                        MqttMsgUnsubscribe unsubscribe = (MqttMsgUnsubscribe)msg;
                        OnMqttMsgUnsubscribeReceived(clientConnection, unsubscribe.MessageId, unsubscribe.Topics);
                        break;

                    // UNSUBACK message received
                    case MqttMsgBase.MQTT_MSG_UNSUBACK_TYPE:
                        OnMqttMsgUnsubscribed(clientConnection, msg.MessageId);
                        break;

                    // DISCONNECT message received from client
                    case MqttMsgBase.MQTT_MSG_DISCONNECT_TYPE:
                        OnMqttMsgDisconnected(clientConnection);
                        break;
                    }
                }
            }

            // all events for received messages dispatched, check if there is closing connection
            if ((clientConnection.EventQueue.Count == 0) && clientConnection.IsConnectionClosing)
            {
                // client raw disconnection
                clientConnection.OnConnectionClosed();
            }
        }