Beispiel #1
0
        public void ConnecAdvancedDecodeTestv5()
        {
            // Arrange
            byte[] correctEncoded = new byte[] { 122, 0, 4, 77, 81, 84, 84, 5, 246, 4, 210, 41, 21, 0, 10, 87, 111, 119, 111, 44, 32, 99, 111, 111, 108,
                                                 22, 0, 5, 0, 1, 2, 3, 4, 17, 0, 0, 212, 49, 33, 255, 105, 39, 255, 255, 255, 155, 34, 255, 245, 23, 1, 25, 1,
                                                 0, 8, 99, 108, 105, 101, 110, 116, 73, 68, 0, 10, 119, 105, 108, 108, 32, 116, 111, 112, 105, 99, 0, 12,
                                                 119, 105, 108, 108, 32, 109, 101, 115, 115, 97, 103, 101, 0, 9, 85, 115, 101, 114, 32, 78, 97, 109, 101,
                                                 0, 21, 65, 32, 116, 101, 120, 116, 32, 112, 97, 115, 115, 119, 111, 114, 100, 32, 36, 36, 39, 47, 37 };
            MokChannel mokChannel = new MokChannel(correctEncoded);
            // Act
            MqttMsgConnect connect = MqttMsgConnect.Parse((byte)MqttMessageType.Connect << 4, MqttProtocolVersion.Version_5, mokChannel);

            // Assert
            Assert.Equal((byte)MqttProtocolVersion.Version_5, (byte)connect.ProtocolVersion);
            Assert.Equal(ClientID, connect.ClientId);
            Assert.Equal(UserName, connect.Username);
            Assert.Equal(Password, connect.Password);
            Assert.Equal(WillTopic, connect.WillTopic);
            Assert.Equal(WillMessage, connect.WillMessage);
            Assert.Equal(KeepAlivePeriod, connect.KeepAlivePeriod);
            Assert.Equal(true, connect.CleanSession);
            Assert.Equal(new byte[5] {
                0, 1, 2, 3, 4
            }, connect.AuthenticationData);
            Assert.Equal("Wowo, cool", connect.AuthenticationMethod);
            Assert.Equal(uint.MaxValue - 100, connect.MaximumPacketSize);
            Assert.Equal((ushort)(ushort.MaxValue - 10), connect.TopicAliasMaximum);
            Assert.Equal((ushort)(ushort.MaxValue - 150), connect.ReceiveMaximum);
            Assert.Equal(true, connect.RequestProblemInformation);
            Assert.Equal(true, connect.RequestResponseInformation);
            Assert.Equal(54321, connect.SessionExpiryInterval);
        }
Beispiel #2
0
 public void OnMqttMsgConnected(MqttMsgConnect connect)
 {
     if (this.ConnectionManager != null)
     {
         this.ConnectionManager.OnMqttMsgConnected(this, connect);
     }
 }
Beispiel #3
0
        public void ConnectUserPropDecodeTestv5()
        {
            // Arrange
            byte[] correctEncoded = new byte[] { 115, 0, 4, 77, 81, 84, 84, 5, 246, 4, 210, 34, 38, 0, 3, 79, 110, 101, 0, 8, 80, 114, 111, 112, 101, 114,
                                                 116, 121, 38, 0, 3, 84, 119, 111, 0, 10, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 0, 8, 99, 108,
                                                 105, 101, 110, 116, 73, 68, 0, 10, 119, 105, 108, 108, 32, 116, 111, 112, 105, 99, 0, 12, 119, 105, 108,
                                                 108, 32, 109, 101, 115, 115, 97, 103, 101, 0, 9, 85, 115, 101, 114, 32, 78, 97, 109, 101, 0, 21, 65, 32,
                                                 116, 101, 120, 116, 32, 112, 97, 115, 115, 119, 111, 114, 100, 32, 36, 36, 39, 47, 37 };
            MokChannel mokChannel = new MokChannel(correctEncoded);
            // Act
            MqttMsgConnect connect = MqttMsgConnect.Parse((byte)MqttMessageType.Connect << 4, MqttProtocolVersion.Version_5, mokChannel);

            // Assert
            Assert.Equal((byte)MqttProtocolVersion.Version_5, (byte)connect.ProtocolVersion);
            Assert.Equal(ClientID, connect.ClientId);
            Assert.Equal(UserName, connect.Username);
            Assert.Equal(Password, connect.Password);
            Assert.Equal(WillTopic, connect.WillTopic);
            Assert.Equal(WillMessage, connect.WillMessage);
            Assert.Equal(KeepAlivePeriod, connect.KeepAlivePeriod);
            Assert.Equal(true, connect.CleanSession);
            Assert.Equal(2, connect.UserProperties.Count);
            var prop = new UserProperty("One", "Property");

            Assert.Equal(((UserProperty)connect.UserProperties[0]).Name, prop.Name);
            Assert.Equal(((UserProperty)connect.UserProperties[0]).Value, prop.Value);
            prop = new UserProperty("Two", "Properties");
            Assert.Equal(((UserProperty)connect.UserProperties[1]).Name, prop.Name);
            Assert.Equal(((UserProperty)connect.UserProperties[1]).Value, prop.Value);
        }
        /// <summary>
        /// Check CONNECT message to accept or not the connection request
        /// </summary>
        /// <param name="connect">CONNECT message received from client</param>
        /// <returns>Return code for CONNACK message</returns>
        private byte MqttConnectVerify(MqttMsgConnect connect)
        {
            // unacceptable protocol version
            if ((connect.ProtocolVersion != MqttMsgConnect.PROTOCOL_VERSION_V3_1) &&
                (connect.ProtocolVersion != MqttMsgConnect.PROTOCOL_VERSION_V3_1_1))
            {
                return(MqttMsgConnack.CONN_REFUSED_PROT_VERS);
            }

            // client id length exceeded (only for old MQTT 3.1)
            if ((connect.ProtocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1) &&
                (connect.ClientId.Length > MqttMsgConnect.CLIENT_ID_MAX_LENGTH))
            {
                return(MqttMsgConnack.CONN_REFUSED_IDENT_REJECTED);
            }

            // [v.3.1.1] client id zero length is allowed but clean session must be true
            if ((connect.ClientId.Length == 0) && (!connect.CleanSession))
            {
                return(MqttMsgConnack.CONN_REFUSED_IDENT_REJECTED);
            }

            // check user authentication
            if (!this.uacManager.AuthenticateUser(connect.Username, connect.Password))
            {
                return(MqttMsgConnack.CONN_REFUSED_USERNAME_PASSWORD);
            }
            // server unavailable and not authorized ?
            else
            {
                // TODO : other checks on CONNECT message
            }

            return(MqttMsgConnack.CONN_ACCEPTED);
        }
 public void OnMqttMsgConnected(MqttMsgConnect connect)
 {
     if (ProcessingManager != null)
     {
         ProcessingManager.OnMqttMsgConnected(this, connect);
     }
 }
Beispiel #6
0
        public void ConnectBasicDecodeTestv5()
        {
            // Arrange
            byte[] correctEncoded = new byte[] { 81, 0, 4, 77, 81, 84, 84, 5, 246, 4, 210, 0, 0, 8, 99, 108, 105, 101, 110, 116, 73, 68, 0, 10, 119, 105, 108, 108, 32, 116, 111, 112, 105, 99, 0, 12, 119, 105, 108, 108, 32, 109, 101, 115, 115, 97, 103, 101, 0, 9, 85, 115, 101, 114, 32, 78, 97,
                                                 109, 101, 0, 21, 65, 32, 116, 101, 120, 116, 32, 112, 97, 115, 115, 119, 111, 114, 100, 32, 36, 36, 39, 47, 37 };
            MokChannel mokChannel = new MokChannel(correctEncoded);
            // Act
            MqttMsgConnect connect = MqttMsgConnect.Parse((byte)MqttMessageType.Connect << 4, MqttProtocolVersion.Version_5, mokChannel);

            // Assert
            Assert.Equal((byte)MqttProtocolVersion.Version_5, (byte)connect.ProtocolVersion);
            Assert.Equal(ClientID, connect.ClientId);
            Assert.Equal(UserName, connect.Username);
            Assert.Equal(Password, connect.Password);
            Assert.Equal(WillTopic, connect.WillTopic);
            Assert.Equal(WillMessage, connect.WillMessage);
            Assert.Equal(KeepAlivePeriod, connect.KeepAlivePeriod);
            Assert.Equal(true, connect.CleanSession);
        }
Beispiel #7
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 void OnMqttMsgConnected(MqttClientConnection clientConnection, MqttMsgConnect message)
        {
            clientConnection.ProtocolVersion = (MqttProtocolVersion)message.ProtocolVersion;

            // verify message to determine CONNACK message return code to the client
            byte returnCode = MqttConnectVerify(message);

            // [v3.1.1] if client id is zero length, the broker assigns a unique identifier to it
            var clientId = (message.ClientId.Length != 0) ? message.ClientId : Guid.NewGuid().ToString();

            // connection "could" be accepted
            if (returnCode == MqttMsgConnack.CONN_ACCEPTED)
            {
                // check if there is a client already connected with same client Id
                MqttClientConnection clientConnectionConnected = MqttBroker.GetClientConnection(clientId);

                // force connection close to the existing client (MQTT protocol)
                if (clientConnectionConnected != null)
                {
                    OnConnectionClosed(clientConnectionConnected);
                }

                // add client to the collection
                MqttBroker.TryAddClientConnection(clientId, clientConnection);
                Interlocked.Increment(ref numberOfConnectedClients);
            }

            // connection accepted, load (if exists) client session
            if (returnCode == MqttMsgConnack.CONN_ACCEPTED)
            {
                // check if not clean session and try to recovery a session
                if (!message.CleanSession)
                {
                    // create session for the client
                    MqttClientSession clientSession = new MqttClientSession(clientId);

                    // get session for the connected client
                    MqttBrokerSession session = MqttSessionManager.GetSession(clientId);

                    // [v3.1.1] session present flag
                    bool sessionPresent = false;

                    // set inflight queue into the client session
                    if (session != null)
                    {
                        clientSession.InflightMessages = session.InflightMessages;
                        // [v3.1.1] session present flag
                        if (clientConnection.ProtocolVersion == MqttProtocolVersion.Version_3_1_1)
                        {
                            sessionPresent = true;
                        }
                    }

                    // send CONNACK message to the client
                    MqttOutgoingMessageManager.Connack(clientConnection, message, returnCode, clientId, sessionPresent);

                    // load/inject session to the client
                    clientConnection.LoadSession(clientSession);

                    if (session != null)
                    {
                        // set reference to connected client into the session
                        session.ClientConnection = clientConnection;

                        // there are saved subscriptions
                        if (session.Subscriptions != null)
                        {
                            // register all subscriptions for the connected client
                            foreach (MqttSubscription subscription in session.Subscriptions)
                            {
                                MqttSubscriberManager.Subscribe(
                                    subscription.Topic,
                                    subscription.QosLevel,
                                    clientConnection);

                                // publish retained message on the current subscription
                                RetainedMessageManager.PublishRetaind(subscription.Topic, clientConnection);
                            }
                        }

                        // there are saved outgoing messages
                        if (session.OutgoingMessages.Count > 0)
                        {
                            // publish outgoing messages for the session
                            this.publishManager.PublishSession(session.ClientId);
                        }
                    }
                }
                // requested clean session
                else
                {
                    // send CONNACK message to the client
                    MqttOutgoingMessageManager.Connack(clientConnection, message, returnCode, clientId, false);

                    MqttSessionManager.ClearSession(clientId);
                }
            }
            else
            {
                // send CONNACK message to the client
                MqttOutgoingMessageManager.Connack(clientConnection, message, returnCode, clientId, false);
            }
        }