public void ProcessConnack(ConnackCode code, Boolean sessionPresent) { // CANCEL CONNECT TIMER MessageResendTimer <MQMessage> timer = _timers.ConnectTimer; _timers.StopConnectTimer(); // CHECK CODE , IF OK THEN MOVE TO CONNECTED AND NOTIFY NETWORK SESSION if (code == ConnackCode.ACCEPTED) { SetState(ConnectionState.CONNECTION_ESTABLISHED); if (timer != null) { Connect connect = (Connect)timer.Message; if (connect.CleanSession) { clearAccountTopics(); } } _timers.StartPingTimer(); } else { _timers.StopAllTimers(); _client.Shutdown(); SetState(ConnectionState.CONNECTION_FAILED); } }
public Connack(Boolean sessionPresent, ConnackCode returnCode) { this._sessionPresent = sessionPresent; this._returnCode = returnCode; }
/// <exception cref="MalformedMessageException">Exception is thrown in case of invalid packet format</exception> public static MQMessage Decode(IByteBuffer buf) { MQMessage header = null; byte fixedHeader = buf.ReadByte(); LengthDetails length = DecodeLength(buf); MessageType type = (MessageType)((fixedHeader >> 4) & 0xf); switch (type) { case MessageType.CONNECT: Byte[] nameValue = new byte[buf.ReadUnsignedShort()]; buf.ReadBytes(nameValue, 0, nameValue.Length); String name = Encoding.UTF8.GetString(nameValue); if (!name.Equals(Connect.PROTOCOL_NAME)) { throw new MalformedMessageException("CONNECT, protocol-name set to " + name); } Byte protocolLevel = buf.ReadByte(); Byte contentFlags = buf.ReadByte(); Boolean userNameFlag = (((contentFlags >> 7) & 1) == 1) ? true : false; Boolean userPassFlag = (((contentFlags >> 6) & 1) == 1) ? true : false; Boolean willRetain = (((contentFlags >> 5) & 1) == 1) ? true : false; Int32 QOSValue = ((contentFlags & 0x1f) >> 3) & 3; QOS willQos = (QOS)QOSValue; if (!Enum.IsDefined(typeof(QOS), QOSValue)) { throw new MalformedMessageException("CONNECT, will QoS set to " + willQos); } Boolean willFlag = (((contentFlags >> 2) & 1) == 1) ? true : false; if (willQos != QOS.AT_MOST_ONCE && !willFlag) { throw new MalformedMessageException("CONNECT, will QoS set to " + willQos + ", willFlag not set"); } if (willRetain && !willFlag) { throw new MalformedMessageException("CONNECT, will retain set, willFlag not set"); } Boolean cleanSession = (((contentFlags >> 1) & 1) == 1) ? true : false; Boolean reservedFlag = ((contentFlags & 1) == 1) ? true : false; if (reservedFlag) { throw new MalformedMessageException("CONNECT, reserved flag set to true"); } int keepalive = buf.ReadUnsignedShort(); Byte[] clientIdValue = new byte[buf.ReadUnsignedShort()]; buf.ReadBytes(clientIdValue, 0, clientIdValue.Length); String clientID = Encoding.UTF8.GetString(clientIdValue); if (!StringVerifier.verify(clientID)) { throw new MalformedMessageException("ClientID contains restricted characters: U+0000, U+D000-U+DFFF"); } String willTopic = null; Byte[] willMessage = null; String username = null; String password = null; Will will = null; if (willFlag) { if (buf.ReadableBytes < 2) { throw new MalformedMessageException("Invalid encoding will/username/password"); } byte[] willTopicValue = new byte[buf.ReadUnsignedShort()]; if (buf.ReadableBytes < willTopicValue.Length) { throw new MalformedMessageException("Invalid encoding will/username/password"); } buf.ReadBytes(willTopicValue, 0, willTopicValue.Length); willTopic = Encoding.UTF8.GetString(willTopicValue); if (!StringVerifier.verify(willTopic)) { throw new MalformedMessageException("WillTopic contains one or more restricted characters: U+0000, U+D000-U+DFFF"); } if (buf.ReadableBytes < 2) { throw new MalformedMessageException("Invalid encoding will/username/password"); } willMessage = new byte[buf.ReadUnsignedShort()]; if (buf.ReadableBytes < willMessage.Length) { throw new MalformedMessageException("Invalid encoding will/username/password"); } buf.ReadBytes(willMessage, 0, willMessage.Length); if (willTopic.Length == 0) { throw new MalformedMessageException("invalid will encoding"); } will = new Will(new Topic(willTopic, willQos), willMessage, willRetain); if (!will.IsValid()) { throw new MalformedMessageException("invalid will encoding"); } } if (userNameFlag) { if (buf.ReadableBytes < 2) { throw new MalformedMessageException("Invalid encoding will/username/password"); } byte[] userNameValue = new byte[buf.ReadUnsignedShort()]; if (buf.ReadableBytes < userNameValue.Length) { throw new MalformedMessageException("Invalid encoding will/username/password"); } buf.ReadBytes(userNameValue, 0, userNameValue.Length); username = Encoding.UTF8.GetString(userNameValue); if (!StringVerifier.verify(username)) { throw new MalformedMessageException("Username contains one or more restricted characters: U+0000, U+D000-U+DFFF"); } } if (userPassFlag) { if (buf.ReadableBytes < 2) { throw new MalformedMessageException("Invalid encoding will/username/password"); } byte[] userPassValue = new byte[buf.ReadUnsignedShort()]; if (buf.ReadableBytes < userPassValue.Length) { throw new MalformedMessageException("Invalid encoding will/username/password"); } buf.ReadBytes(userPassValue, 0, userPassValue.Length); password = Encoding.UTF8.GetString(userPassValue); if (!StringVerifier.verify(password)) { throw new MalformedMessageException("Password contains one or more restricted characters: U+0000, U+D000-U+DFFF"); } } if (buf.ReadableBytes > 0) { throw new MalformedMessageException("Invalid encoding will/username/password"); } Connect connect = new Connect(username, password, clientID, cleanSession, keepalive, will); if (protocolLevel != 4) { connect.ProtocolLevel = protocolLevel; } header = connect; break; case MessageType.CONNACK: byte sessionPresentValue = buf.ReadByte(); if (sessionPresentValue != 0 && sessionPresentValue != 1) { throw new MalformedMessageException("CONNACK, session-present set to " + (sessionPresentValue & 0xff)); } Boolean isPresent = sessionPresentValue == 1 ? true : false; Int32 connackByte = ((Int32)buf.ReadByte()) & 0xFF; ConnackCode connackCode = (ConnackCode)connackByte; if (!Enum.IsDefined(typeof(ConnackCode), connackByte)) { throw new MalformedMessageException("Invalid connack code: " + connackByte); } header = new Connack(isPresent, connackCode); break; case MessageType.PUBLISH: int dataLength = length.Length; fixedHeader &= 0xf; Boolean dup = (((fixedHeader >> 3) & 1) == 1) ? true : false; QOSValue = (fixedHeader & 0x07) >> 1; QOS qos = (QOS)QOSValue; if (!Enum.IsDefined(typeof(QOS), (byte)QOSValue)) { throw new MalformedMessageException("invalid QoS value"); } if (dup && qos == QOS.AT_MOST_ONCE) { throw new MalformedMessageException("PUBLISH, QoS-0 dup flag present"); } Boolean retain = ((fixedHeader & 1) == 1) ? true : false; byte[] topicNameValue = new byte[buf.ReadUnsignedShort()]; buf.ReadBytes(topicNameValue, 0, topicNameValue.Length); String topicName = Encoding.UTF8.GetString(topicNameValue); if (!StringVerifier.verify(topicName)) { throw new MalformedMessageException("Publish-topic contains one or more restricted characters: U+0000, U+D000-U+DFFF"); } dataLength -= topicName.Length + 2; Int32?packetID = null; if (qos != QOS.AT_MOST_ONCE) { packetID = buf.ReadUnsignedShort(); if (packetID < 0 || packetID > 65535) { throw new MalformedMessageException("Invalid PUBLISH packetID encoding"); } dataLength -= 2; } byte[] data = new byte[dataLength]; if (dataLength > 0) { buf.ReadBytes(data, 0, data.Length); } header = new Publish(packetID, new Topic(topicName, qos), data, retain, dup); break; case MessageType.PUBACK: header = new Puback(buf.ReadUnsignedShort()); break; case MessageType.PUBREC: header = new Pubrec(buf.ReadUnsignedShort()); break; case MessageType.PUBREL: header = new Pubrel(buf.ReadUnsignedShort()); break; case MessageType.PUBCOMP: header = new Pubcomp(buf.ReadUnsignedShort()); break; case MessageType.SUBSCRIBE: Int32 subID = buf.ReadUnsignedShort(); List <Topic> subscriptions = new List <Topic>(); while (buf.IsReadable()) { byte[] value = new byte[buf.ReadUnsignedShort()]; buf.ReadBytes(value, 0, value.Length); QOSValue = buf.ReadByte(); QOS requestedQos = (QOS)QOSValue; if (!Enum.IsDefined(typeof(QOS), QOSValue)) { throw new MalformedMessageException("Subscribe qos must be in range from 0 to 2: " + requestedQos); } String topic = Encoding.UTF8.GetString(value); if (!StringVerifier.verify(topic)) { throw new MalformedMessageException("Subscribe topic contains one or more restricted characters: U+0000, U+D000-U+DFFF"); } Topic subscription = new Topic(topic, requestedQos); subscriptions.Add(subscription); } if (subscriptions.Count == 0) { throw new MalformedMessageException("Subscribe with 0 topics"); } header = new Subscribe(subID, subscriptions.ToArray()); break; case MessageType.SUBACK: Int32 subackID = buf.ReadUnsignedShort(); List <SubackCode> subackCodes = new List <SubackCode>(); while (buf.IsReadable()) { Int32 subackByte = ((Int32)buf.ReadByte()) & 0xFF; SubackCode subackCode = (SubackCode)subackByte; if (!Enum.IsDefined(typeof(SubackCode), subackByte)) { throw new MalformedMessageException("Invalid suback code: " + subackByte); } subackCodes.Add(subackCode); } if (subackCodes.Count == 0) { throw new MalformedMessageException("Suback with 0 return-codes"); } header = new Suback(subackID, subackCodes); break; case MessageType.UNSUBSCRIBE: Int32 unsubID = buf.ReadUnsignedShort(); List <String> unsubscribeTopics = new List <String>(); while (buf.IsReadable()) { byte[] value = new byte[buf.ReadUnsignedShort()]; buf.ReadBytes(value, 0, value.Length); String topic = Encoding.UTF8.GetString(value); if (!StringVerifier.verify(topic)) { throw new MalformedMessageException("Unsubscribe topic contains one or more restricted characters: U+0000, U+D000-U+DFFF"); } unsubscribeTopics.Add(topic); } if (unsubscribeTopics.Count == 0) { throw new MalformedMessageException("Unsubscribe with 0 topics"); } header = new Unsubscribe(unsubID, unsubscribeTopics.ToArray()); break; case MessageType.UNSUBACK: header = new Unsuback(buf.ReadUnsignedShort()); break; case MessageType.PINGREQ: header = new Pingreq(); break; case MessageType.PINGRESP: header = new Pingresp(); break; case MessageType.DISCONNECT: header = new Disconnect(); break; default: throw new MalformedMessageException("Invalid header type: " + type); } if (buf.IsReadable()) { throw new MalformedMessageException("unexpected bytes in content"); } if (length.Length != header.GetLength()) { throw new MalformedMessageException("Invalid length. Encoded: " + length.Length + ", actual: " + header.GetLength()); } return(header); }