예제 #1
0
        public void PublishAdvancedBinaryDecodeTestv5()
        {
            // Arrange
            byte[] encodedCorrect = new byte[] { 109, 0, 19, 116, 104, 105, 115, 116, 111, 112, 105, 99, 47, 115, 111, 109, 101, 116, 104, 105, 110,
                                                 103, 0, 42, 79, 2, 0, 0, 48, 57, 35, 0, 33, 8, 0, 14, 114, 101, 115, 112, 111, 110, 115, 101, 32, 116, 111,
                                                 112, 105, 99, 9, 0, 6, 1, 2, 3, 4, 5, 6, 38, 0, 3, 79, 110, 101, 0, 4, 112, 114, 111, 112, 38, 0, 6, 115, 101,
                                                 99, 111, 110, 100, 0, 8, 112, 114, 111, 112, 101, 114, 116, 121, 11, 254, 255, 255, 127, 3, 0, 6, 98, 105,
                                                 110, 97, 114, 121, 6, 5, 4, 3, 2, 1 };
            MokChannel mokChannel = new(encodedCorrect);
            // Act
            MqttMsgPublish publish = MqttMsgPublish.Parse(60, MqttProtocolVersion.Version_5, mokChannel);

            // Assert
            Assert.Equal(Topic, publish.Topic);
            Assert.Equal(MessageId, publish.MessageId);
            Assert.Equal(new byte[] { 6, 5, 4, 3, 2, 1 }, publish.Message);
            Assert.Equal((byte)MqttQoSLevel.ExactlyOnce, (byte)publish.QosLevel);
            Assert.Equal(true, publish.DupFlag);
            Assert.Equal(false, publish.Retain);
            Assert.Equal(publish.ContentType, "binary");
            Assert.Equal(publish.IsPayloadUTF8, false);
            Assert.Equal(publish.SubscriptionIdentifier, 268435454);
            Assert.Equal(publish.UserProperties.Count, 2);
            var prop = new UserProperty("One", "prop");

            Assert.Equal(((UserProperty)publish.UserProperties[0]).Name, prop.Name);
            Assert.Equal(((UserProperty)publish.UserProperties[0]).Value, prop.Value);
            prop = new UserProperty("second", "property");
            Assert.Equal(((UserProperty)publish.UserProperties[1]).Name, prop.Name);
            Assert.Equal(((UserProperty)publish.UserProperties[1]).Value, prop.Value);
            Assert.Equal(publish.CorrelationData, new byte[] { 1, 2, 3, 4, 5, 6 });
            Assert.Equal(publish.ResponseTopic, "response topic");
            Assert.Equal(publish.TopicAlias, (ushort)33);
            Assert.Equal(publish.MessageExpiryInterval, 12345);
        }
예제 #2
0
        private void RouteOnTheQoSLevelOfTheSubscriber(string topic)
        {
            MqttMsgPublish publish = publishQueue[topic].Dequeue();
            //var connectedClients = MqttServer.GetConnectedClientIds();
            var connectedClients     = PacketManager.GetConnectedClientIds();
            var subscriptionsByTopic = subscriptionManager.GetSubscriptionsByTopic(publish.Topic);
            var subscriptions        = subscriptionsByTopic != null?subscriptionsByTopic.Where(s => connectedClients.Contains(s.ClientId)) : null;

            if (subscriptions != null)
            {
                foreach (var sub in subscriptions)
                {
                    if (sub.QosLevel == 0x00 && publish.QosLevel > MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE)
                    {
                        MqttMsgPublish pub = MqttMsgPublish.Parse(publish.GetBytes());
                        pub.QosLevel = MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE;
                        RouteOnQoS(pub, sub);
                    }
                    else if (sub.QosLevel == 0x01 && publish.QosLevel > MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE)
                    {
                        MqttMsgPublish pub = MqttMsgPublish.Parse(publish.GetBytes());
                        pub.QosLevel = MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE;
                        RouteOnQoS(pub, sub);
                    }
                    else
                    {
                        RouteOnQoS(publish, sub);
                    }
                }
            }
        }
예제 #3
0
        public void PublishBasicDecodeTestv311()
        {
            // Arrange
            byte[] encodedCorrect = new byte[] { 47, 0, 19, 116, 104, 105, 115, 116, 111, 112, 105, 99, 47, 115, 111, 109, 101, 116, 104, 105, 110,
                                                 103, 0, 42, 84, 104, 105, 115, 32, 105, 115, 32, 97, 32, 115, 116, 114, 105, 110, 103, 32, 109, 101, 115,
                                                 115, 97, 103, 101 };
            MokChannel mokChannel = new(encodedCorrect);
            // Act
            MqttMsgPublish publish = MqttMsgPublish.Parse(60, MqttProtocolVersion.Version_3_1_1, mokChannel);

            // Assert
            Assert.Equal(Topic, publish.Topic);
            Assert.Equal(MessageId, publish.MessageId);
            Assert.Equal(MessageString, Encoding.UTF8.GetString(publish.Message, 0, publish.Message.Length));
            Assert.Equal((byte)MqttQoSLevel.ExactlyOnce, (byte)publish.QosLevel);
            Assert.Equal(true, publish.DupFlag);
            Assert.Equal(false, publish.Retain);
        }
예제 #4
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();
            }
            }
        }
예제 #5
0
        /// <summary>
        /// Thread for receiving messages from broker
        /// </summary>
        private void ReceiveThread()
        {
            int readBytes;

            byte[] fixedHeaderFirstByte = new byte[1];
            byte   msgType;

            while (this.isRunning)
            {
                try
                {
                    // read first byte (fixed header)
                    readBytes = this.socket.Receive(fixedHeaderFirstByte);

                    if (readBytes > 0)
                    {
                        // extract message type from received byte
                        msgType = (byte)((fixedHeaderFirstByte[0] & MqttMsgBase.MSG_TYPE_MASK) >> MqttMsgBase.MSG_TYPE_OFFSET);

                        switch (msgType)
                        {
                        // impossible, broker can't send CONNECT message
                        case MqttMsgBase.MQTT_MSG_CONNECT_TYPE:

                            throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);

                        // CONNACK message received from broker
                        case MqttMsgBase.MQTT_MSG_CONNACK_TYPE:

                            this.msgReceived = MqttMsgConnack.Parse(fixedHeaderFirstByte[0], this.socket);
                            this.endReceiving.Set();
                            break;

                        // impossible, broker can't send PINGREQ message
                        case MqttMsgBase.MQTT_MSG_PINGREQ_TYPE:

                            throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);

                        // CONNACK message received from broker
                        case MqttMsgBase.MQTT_MSG_PINGRESP_TYPE:

                            this.msgReceived = MqttMsgPingResp.Parse(fixedHeaderFirstByte[0], this.socket);
                            this.endReceiving.Set();
                            break;

                        // impossible, broker can't send SUBSCRIBE message
                        case MqttMsgBase.MQTT_MSG_SUBSCRIBE_TYPE:

                            throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);

                        // SUBACK message received from broker
                        case MqttMsgBase.MQTT_MSG_SUBACK_TYPE:

                            this.msgReceived = MqttMsgSuback.Parse(fixedHeaderFirstByte[0], this.socket);
                            this.endReceiving.Set();

                            // raise subscribed topic event (SUBACK message received)
                            this.OnMqttMsgSubscribed((MqttMsgSuback)this.msgReceived);

                            break;

                        // PUBLISH message received from broker
                        case MqttMsgBase.MQTT_MSG_PUBLISH_TYPE:

                            MqttMsgPublish msgReceived = MqttMsgPublish.Parse(fixedHeaderFirstByte[0], this.socket);

                            // for QoS Level 1 and 2, client sends PUBACK message to broker
                            if ((this.msgReceived.QosLevel == MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE) ||
                                (this.msgReceived.QosLevel == MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE))
                            {
                                MqttMsgPuback puback = new MqttMsgPuback();
                                puback.MessageId = (msgReceived).MessageId;
                                this.Send(puback.GetBytes());
                            }

                            // raise PUBLISH message received event
                            this.OnMqttMsgPublishReceived(msgReceived);

                            break;

                        // PUBACK message received from broker
                        case MqttMsgBase.MQTT_MSG_PUBACK_TYPE:

                            this.msgReceived = MqttMsgPuback.Parse(fixedHeaderFirstByte[0], this.socket);
                            this.endReceiving.Set();

                            // raise published message event
                            // (PUBACK received for QoS Level 1)
                            this.OnMqttMsgPublished(((MqttMsgPuback)this.msgReceived).MessageId);

                            break;

                        // PUBREC message received from broker
                        case MqttMsgBase.MQTT_MSG_PUBREC_TYPE:

                            this.msgReceived = MqttMsgPubrec.Parse(fixedHeaderFirstByte[0], this.socket);
                            this.endReceiving.Set();
                            break;

                        // impossible, broker can't send PUBREL message
                        case MqttMsgBase.MQTT_MSG_PUBREL_TYPE:

                            throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);

                        // PUBCOMP message received from broker
                        case MqttMsgBase.MQTT_MSG_PUBCOMP_TYPE:

                            this.msgReceived = MqttMsgPubcomp.Parse(fixedHeaderFirstByte[0], this.socket);
                            this.endReceiving.Set();

                            // raise published message event
                            // (PUBCOMP received for QoS Level 2)
                            this.OnMqttMsgPublished(((MqttMsgPuback)this.msgReceived).MessageId);

                            break;

                        // impossible, broker can't send UNSUBSCRIBE message
                        case MqttMsgBase.MQTT_MSG_UNSUBSCRIBE_TYPE:

                            throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);

                        // UNSUBACK message received from broker
                        case MqttMsgBase.MQTT_MSG_UNSUBACK_TYPE:

                            this.msgReceived = MqttMsgUnsuback.Parse(fixedHeaderFirstByte[0], this.socket);
                            this.endReceiving.Set();

                            // raise unsubscribed topic event
                            this.OnMqttMsgUnsubscribed(((MqttMsgUnsuback)this.msgReceived).MessageId);

                            break;

                        default:

                            throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
                        }

                        this.exReceiving = null;
                    }
                }
                catch (Exception)
                {
                    this.exReceiving = new MqttCommunicationException();
                }
            }
        }
예제 #6
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);
            }
        }
예제 #8
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);
            }
            }
        }