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; }
/// <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; }
/// <summary> /// Constructor /// </summary> /// <param name="msg">CONNECT message received from client</param> public MqttMsgConnectEventArgs(MqttMsgConnect connect) { this.Message = connect; }
/// <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; }
/// <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(); } }
/// <summary> /// Wrapper method for client connection event /// </summary> private void OnMqttMsgConnected(MqttMsgConnect connect) { if (this.MqttMsgConnected != null) { this.MqttMsgConnected(this, new MqttMsgConnectEventArgs(connect)); } }
/// <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; }
/// <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; }
public void MqttOpen(MqttMsgConnect msg) { MqttClient = new MqttClient(this.ProtocolInstance.Transport.Socket); ((MqttManager)Composable.GetExport<IXSocketController>(typeof(MqttManager))).RegisterClient(this.MqttClient,msg); }
/// <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); }
/// <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); }
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); }
/// <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; }