Exemplo n.º 1
0
        public void RegisterClient(MqttClient client, MqttMsgConnect msg)
        {
            // register event handlers from client
            client.MqttMsgDisconnected += Client_MqttMsgDisconnected;
            client.MqttMsgPublishReceived += Client_MqttMsgPublishReceived;
            client.MqttMsgConnected += Client_MqttMsgConnected;
            client.MqttMsgSubscribeReceived += Client_MqttMsgSubscribeReceived;
            client.MqttMsgUnsubscribeReceived += Client_MqttMsgUnsubscribeReceived;
            client.ConnectionClosed += Client_ConnectionClosed;

            // add client to the collection
            this.clients.Add(client);

            //TODO: Avoid calling this... But how do I get the MqttMsgConnect into the receive thred of the MqttClient?
            //client.OnMqttMsgConnected((MqttMsgConnect)msg);
            //Calling this way instead....
            client.ProtocolVersion = (MqttProtocolVersion)msg.ProtocolVersion;
            this.Client_MqttMsgConnected(client, new MqttMsgConnectEventArgs(msg));

            // start client threads
            client.Open();
        }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="msg">CONNECT message received from client</param>
 public MqttMsgConnectEventArgs(MqttMsgConnect connect)
 {
     this.Message = connect;
 }
Exemplo n.º 3
0
        /// <summary>
        /// Connect to broker
        /// </summary>
        /// <param name="clientId">Client identifier</param>
        /// <param name="username">Username</param>
        /// <param name="password">Password</param>
        /// <param name="willRetain">Will retain flag</param>
        /// <param name="willQosLevel">Will QOS level</param>
        /// <param name="willFlag">Will flag</param>
        /// <param name="willTopic">Will topic</param>
        /// <param name="willMessage">Will message</param>
        /// <param name="cleanSession">Clean sessione flag</param>
        /// <param name="keepAlivePeriod">Keep alive period</param>
        /// <returns>Return code of CONNACK message from broker</returns>
        public byte Connect(string clientId, 
            string username = null,
            string password = null,
            bool willRetain = false,
            byte willQosLevel = MqttMsgConnect.QOS_LEVEL_AT_LEAST_ONCE,
            bool willFlag = false,
            string willTopic = null,
            string willMessage = null,
            bool cleanSession = true,
            ushort keepAlivePeriod = MqttMsgConnect.KEEP_ALIVE_PERIOD_DEFAULT)
        {
            // create CONNECT message
            MqttMsgConnect connect = new MqttMsgConnect(clientId,
                username,
                password,
                willRetain,
                willQosLevel,
                willFlag,
                willTopic,
                willMessage,
                cleanSession,
                keepAlivePeriod);

            try
            {
                this.socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                // try connection to the broker
                this.socket.Connect(new IPEndPoint(this.brokerIpAddress, this.brokerPort));
            }
            catch
            {
                throw new MqttConnectionException();
            }

            this.lastSend = 0;
            this.isRunning = true;
            // start thread for receiving messages from broker
            this.receiveThread = new Thread(this.ReceiveThread);
            this.receiveThread.Start();

            MqttMsgConnack connack = (MqttMsgConnack)this.SendReceive(connect.GetBytes());
            // if connection accepted, start keep alive timer
            if (connack.ReturnCode == MqttMsgConnack.CONN_ACCEPTED)
            {
                this.IsConnected = true;

                this.keepAlivePeriod = keepAlivePeriod * 1000; // convert in ms

                // start thread for sending keep alive message to the broker
                this.keepAliveThread = new Thread(this.KeepAliveThread);
                this.keepAliveThread.Start();
            }
            return connack.ReturnCode;
        }
Exemplo n.º 4
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="msg">CONNECT message received from client</param>
 public MqttMsgConnectEventArgs(MqttMsgConnect connect)
 {
     this.Message = connect;
 }
Exemplo n.º 5
0
        /// <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)
        {
            byte returnCode = MqttMsgConnack.CONN_ACCEPTED;

            // unacceptable protocol version
            if ((connect.ProtocolVersion != PROTOCOL_VERSION_V3_1) &&
                (connect.ProtocolVersion != PROTOCOL_VERSION_V3_1_1))
                returnCode = MqttMsgConnack.CONN_REFUSED_PROT_VERS;
            else
            {
                // client id length exceeded (only for old MQTT 3.1)
                if ((connect.ProtocolVersion == PROTOCOL_VERSION_V3_1) &&
                     (connect.ClientId.Length > CLIENT_ID_MAX_LENGTH))
                    returnCode = MqttMsgConnack.CONN_REFUSED_IDENT_REJECTED;
                else
                {
                    // [v.3.1.1] client id zero length is allowed but clean session must be true
                    if ((connect.ClientId.Length == 0) && (!connect.CleanSession))
                        returnCode = MqttMsgConnack.CONN_REFUSED_IDENT_REJECTED;
                    else
                    {
                        // check user authentication
                        if (!this.uacManager.UserAuthentication(connect.Username, connect.Password))
                            returnCode = MqttMsgConnack.CONN_REFUSED_USERNAME_PASSWORD;
                        // server unavailable and not authorized ?
                        else
                        {
                            // TODO : other checks on CONNECT message
                        }
                    }
                }
            }

            return returnCode;
        }
Exemplo n.º 6
0
        /// <summary>
        /// Send CONNACK message to the client (connection accepted or not)
        /// </summary>
        /// <param name="returnCode">Return code for CONNACK message</param>
        /// <param name="connect">CONNECT message with all client information</param>
        public void Connack(byte returnCode, MqttMsgConnect connect)
        {
            this.lastCommTime = 0;

            // create CONNACK message and ...
            MqttMsgConnack connack = new MqttMsgConnack();
            connack.ReturnCode = returnCode;
            // ... send it to the client
            this.Send(connack);

            // connection accepted, start keep alive thread checking
            if (connack.ReturnCode == MqttMsgConnack.CONN_ACCEPTED)
            {
                this.ClientId = connect.ClientId;
                this.CleanSession = connect.CleanSession;
                this.WillFlag = connect.WillFlag;
                this.WillTopic = connect.WillTopic;
                this.WillMessage = connect.WillMessage;
                this.WillQosLevel = connect.WillQosLevel;

                this.keepAlivePeriod = connect.KeepAlivePeriod * 1000; // convert in ms
                // broker has a tolerance of 1.5 specified keep alive period
                this.keepAlivePeriod += (this.keepAlivePeriod / 2);

                // start thread for checking keep alive period timeout
                this.keepAliveThread = new Thread(this.KeepAliveThread);
                this.keepAliveThread.Name = KEEP_ALIVE_THREAD;
                this.keepAliveThread.Start();

                this.IsConnected = true;
            }
            // connection refused, close TCP/IP channel
            else
            {
                this.Close();
            }
        }
Exemplo n.º 7
0
 /// <summary>
 /// Wrapper method for client connection event
 /// </summary>
 private void OnMqttMsgConnected(MqttMsgConnect connect)
 {
     if (this.MqttMsgConnected != null)
     {
         this.MqttMsgConnected(this, new MqttMsgConnectEventArgs(connect));
     }
 }
Exemplo n.º 8
0
        /// <summary>
        /// Parse bytes for a CONNECT message
        /// </summary>
        /// <param name="fixedHeaderFirstByte">First fixed header byte</param>
        /// <param name="channel">Channel connected to the broker</param>
        /// <returns>CONNECT message instance</returns>
        public static MqttMsgConnect Parse(byte fixedHeaderFirstByte, 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));

            // protocol version
            msg.protocolVersion = buffer[index];
            index += PROTOCOL_VERSION_NUMBER_SIZE;

            // connect flags
            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
            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));

            // 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;
        }
Exemplo n.º 9
0
        /// <summary>
        /// Connect to broker
        /// </summary>
        /// <param name="clientId">Client identifier</param>
        /// <param name="username">Username</param>
        /// <param name="password">Password</param>
        /// <param name="willRetain">Will retain flag</param>
        /// <param name="willQosLevel">Will QOS level</param>
        /// <param name="willFlag">Will flag</param>
        /// <param name="willTopic">Will topic</param>
        /// <param name="willMessage">Will message</param>
        /// <param name="cleanSession">Clean sessione flag</param>
        /// <param name="keepAlivePeriod">Keep alive period</param>
        /// <returns>Return code of CONNACK message from broker</returns>
        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);

            try
            {
                // create network channel and connect to broker
#if WINDOWS_PHONE
                this.channel = new WPMqttNetworkChannel(this.brokerHostName, this.brokerIpAddress, this.brokerPort, this.secure, this.caCert);
#else
                this.channel = new MqttNetworkChannel(this.brokerHostName, this.brokerIpAddress, this.brokerPort, this.secure, this.caCert);
#endif
                this.channel.Connect();
            }
            catch (Exception ex)
            {
                throw new MqttConnectionException("Exception connecting to the broker", ex);
            }

            this.lastCommTime = 0;
            this.isRunning = true;
            // start thread for receiving messages from broker
            this.receiveThread = new Thread(this.ReceiveThread);
            this.receiveThread.Start();

            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

                // start thread for sending keep alive message to the broker
                this.keepAliveThread = new Thread(this.KeepAliveThread);
                this.keepAliveThread.Start();

                // start thread for raising received message event from broker
                this.receiveEventThread = new Thread(this.ReceiveEventThread);
                this.receiveEventThread.Start();

                // start thread for handling inflight messages queue to broker asynchronously (publish and acknowledge)
                this.processInflightThread = new Thread(this.ProcessInflightThread);
                this.processInflightThread.Start();

                this.IsConnected = true;
            }
            return connack.ReturnCode;
        }
Exemplo n.º 10
0
 public void MqttOpen(MqttMsgConnect msg)
 {
     MqttClient = new MqttClient(this.ProtocolInstance.Transport.Socket);
     ((MqttManager)Composable.GetExport<IXSocketController>(typeof(MqttManager))).RegisterClient(this.MqttClient,msg);
 }
Exemplo n.º 11
0
        /// <summary>
        /// Parse bytes for a CONNECT message
        /// </summary>
        /// <param name="fixedHeaderFirstByte">First fixed header byte</param>
        /// <param name="channel">Channel connected to the broker</param>
        /// <returns>CONNECT message instance</returns>
        public static MqttMsgConnect Parse(byte fixedHeaderFirstByte, 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));

            // protocol version
            msg.protocolVersion = buffer[index];
            index += PROTOCOL_VERSION_NUMBER_SIZE;

            // connect flags
            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
            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));

            // 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);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Parse bytes for a CONNECT message
        /// </summary>
        /// <param name="fixedHeaderFirstByte">First fixed header byte</param>
        /// <param name="protocolVersion">Protocol Version</param>
        /// <param name="channel">Channel connected to the broker</param>
        /// <returns>CONNECT message instance</returns>
        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);
        }
Exemplo n.º 13
0
        public static MqttMsgConnect Parse(byte fixedHeaderFirstByte, byte protocolVersion, IMqttNetworkChannel channel)
        {
            int            num1            = 0;
            MqttMsgConnect mqttMsgConnect1 = new MqttMsgConnect();

            byte[] buffer = new byte[MqttMsgBase.decodeRemainingLength(channel)];
            channel.Receive(buffer);
            byte[] numArray1 = buffer;
            int    index1    = num1;
            int    num2      = checked (index1 + 1);
            int    num3      = (int)numArray1[index1] << 8 & 65280;

            byte[] numArray2    = buffer;
            int    index2       = num2;
            int    sourceIndex1 = checked (index2 + 1);
            int    num4         = (int)numArray2[index2];
            int    length1      = num3 | num4;

            byte[] bytes1 = new byte[length1];
            Array.Copy((Array)buffer, sourceIndex1, (Array)bytes1, 0, length1);
            int index3 = checked (sourceIndex1 + length1);

            mqttMsgConnect1.protocolName = new string(Encoding.UTF8.GetChars(bytes1));
            if (!mqttMsgConnect1.protocolName.Equals("MQIsdp") && !mqttMsgConnect1.protocolName.Equals("MQTT"))
            {
                throw new MqttClientException(MqttClientErrorCode.InvalidProtocolName);
            }
            mqttMsgConnect1.protocolVersion = buffer[index3];
            int index4 = checked (index3 + 1);

            if (mqttMsgConnect1.protocolVersion == (byte)4 && ((uint)buffer[index4] & 1U) > 0U)
            {
                throw new MqttClientException(MqttClientErrorCode.InvalidConnectFlags);
            }
            bool flag1 = ((uint)buffer[index4] & 128U) > 0U;
            bool flag2 = ((uint)buffer[index4] & 64U) > 0U;

            mqttMsgConnect1.willRetain   = ((uint)buffer[index4] & 32U) > 0U;
            mqttMsgConnect1.willQosLevel = checked ((byte)(((int)buffer[index4] & 24) >> 3));
            mqttMsgConnect1.willFlag     = ((uint)buffer[index4] & 4U) > 0U;
            mqttMsgConnect1.cleanSession = ((uint)buffer[index4] & 2U) > 0U;
            int            num5            = checked (index4 + 1);
            MqttMsgConnect mqttMsgConnect2 = mqttMsgConnect1;

            byte[] numArray3 = buffer;
            int    index5    = num5;
            int    num6      = checked (index5 + 1);
            int    num7      = (int)checked ((ushort)((int)numArray3[index5] << 8 & 65280));

            mqttMsgConnect2.keepAlivePeriod = (ushort)num7;
            MqttMsgConnect mqttMsgConnect3 = mqttMsgConnect1;
            int            keepAlivePeriod = (int)mqttMsgConnect3.keepAlivePeriod;

            byte[] numArray4 = buffer;
            int    index6    = num6;
            int    num8      = checked (index6 + 1);
            int    num9      = (int)numArray4[index6];

            mqttMsgConnect3.keepAlivePeriod = (ushort)(keepAlivePeriod | num9);
            byte[] numArray5 = buffer;
            int    index7    = num8;
            int    num10     = checked (index7 + 1);
            int    num11     = (int)numArray5[index7] << 8 & 65280;

            byte[] numArray6    = buffer;
            int    index8       = num10;
            int    sourceIndex2 = checked (index8 + 1);
            int    num12        = (int)numArray6[index8];
            int    length2      = num11 | num12;

            byte[] bytes2 = new byte[length2];
            Array.Copy((Array)buffer, sourceIndex2, (Array)bytes2, 0, length2);
            int num13 = checked (sourceIndex2 + length2);

            mqttMsgConnect1.clientId = new string(Encoding.UTF8.GetChars(bytes2));
            if (mqttMsgConnect1.protocolVersion == (byte)4 && length2 == 0 && !mqttMsgConnect1.cleanSession)
            {
                throw new MqttClientException(MqttClientErrorCode.InvalidClientId);
            }
            if (mqttMsgConnect1.willFlag)
            {
                byte[] numArray7    = buffer;
                int    index9       = num13;
                int    num14        = checked (index9 + 1);
                int    num15        = (int)numArray7[index9] << 8 & 65280;
                byte[] numArray8    = buffer;
                int    index10      = num14;
                int    sourceIndex3 = checked (index10 + 1);
                int    num16        = (int)numArray8[index10];
                int    length3      = num15 | num16;
                byte[] bytes3       = new byte[length3];
                Array.Copy((Array)buffer, sourceIndex3, (Array)bytes3, 0, length3);
                int num17 = checked (sourceIndex3 + length3);
                mqttMsgConnect1.willTopic = new string(Encoding.UTF8.GetChars(bytes3));
                byte[] numArray9    = buffer;
                int    index11      = num17;
                int    num18        = checked (index11 + 1);
                int    num19        = (int)numArray9[index11] << 8 & 65280;
                byte[] numArray10   = buffer;
                int    index12      = num18;
                int    sourceIndex4 = checked (index12 + 1);
                int    num20        = (int)numArray10[index12];
                int    length4      = num19 | num20;
                byte[] bytes4       = new byte[length4];
                Array.Copy((Array)buffer, sourceIndex4, (Array)bytes4, 0, length4);
                num13 = checked (sourceIndex4 + length4);
                mqttMsgConnect1.willMessage = new string(Encoding.UTF8.GetChars(bytes4));
            }
            if (flag1)
            {
                byte[] numArray7    = buffer;
                int    index9       = num13;
                int    num14        = checked (index9 + 1);
                int    num15        = (int)numArray7[index9] << 8 & 65280;
                byte[] numArray8    = buffer;
                int    index10      = num14;
                int    sourceIndex3 = checked (index10 + 1);
                int    num16        = (int)numArray8[index10];
                int    length3      = num15 | num16;
                byte[] bytes3       = new byte[length3];
                Array.Copy((Array)buffer, sourceIndex3, (Array)bytes3, 0, length3);
                num13 = checked (sourceIndex3 + length3);
                mqttMsgConnect1.username = new string(Encoding.UTF8.GetChars(bytes3));
            }
            if (flag2)
            {
                byte[] numArray7    = buffer;
                int    index9       = num13;
                int    num14        = checked (index9 + 1);
                int    num15        = (int)numArray7[index9] << 8 & 65280;
                byte[] numArray8    = buffer;
                int    index10      = num14;
                int    sourceIndex3 = checked (index10 + 1);
                int    num16        = (int)numArray8[index10];
                int    length3      = num15 | num16;
                byte[] bytes3       = new byte[length3];
                Array.Copy((Array)buffer, sourceIndex3, (Array)bytes3, 0, length3);
                int num17 = checked (sourceIndex3 + length3);
                mqttMsgConnect1.password = new string(Encoding.UTF8.GetChars(bytes3));
            }
            return(mqttMsgConnect1);
        }
Exemplo n.º 14
0
        /// <summary>
        /// Parse bytes for a CONNECT message
        /// </summary>
        /// <param name="fixedHeaderFirstByte">First fixed header byte</param>
        /// <param name="protocolVersion">Protocol Version</param>
        /// <param name="channel">Channel connected to the broker</param>
        /// <returns>CONNECT message instance</returns>
        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;
        }