Commit 4bf112b6d9f450f2ee8eb5665eb4f3f9d4ecbed4

Authored by Wiebe Cazemier
1 parent f262b796

Separate DISCONNECT packet parsing and handling

This is necessary for the test client I have in mind, so I can re-use
this code in that new test client which has no MQTT behavior, but just
returns packets (meaning I have to be able to parse them without
initiating handling).
mqttpacket.cpp
... ... @@ -812,19 +812,23 @@ void MqttPacket::handleExtendedAuth()
812 812 }
813 813 }
814 814  
815   -void MqttPacket::handleDisconnect()
  815 +DisconnectData MqttPacket::parseDisconnectData()
816 816 {
  817 + if (this->packetType != PacketType::DISCONNECT)
  818 + throw std::runtime_error("Packet must be disconnect packet.");
  819 +
817 820 if (first_byte & 0b1111)
818 821 throw ProtocolError("Disconnect packet first 4 bits should be 0.", ReasonCodes::MalformedPacket);
819 822  
820   - ReasonCodes reasonCode = ReasonCodes::Success;
821   - std::string reasonString;
  823 + setPosToDataStart();
  824 +
  825 + DisconnectData result;
822 826  
823 827 if (this->protocolVersion >= ProtocolVersion::Mqtt5)
824 828 {
825 829 if (!atEnd())
826 830 {
827   - reasonCode = static_cast<ReasonCodes>(readByte());
  831 + result.reasonCode = static_cast<ReasonCodes>(readByte());
828 832  
829 833 const size_t proplen = decodeVariableByteIntAtPos();
830 834 const size_t prop_end_at = pos + proplen;
... ... @@ -839,12 +843,13 @@ void MqttPacket::handleDisconnect()
839 843 {
840 844 const Settings *settings = ThreadGlobals::getSettings();
841 845 const uint32_t session_expire = std::min<uint32_t>(readFourBytesToUint32(), settings->getExpireSessionAfterSeconds());
842   - sender->getSession()->setSessionExpiryInterval(session_expire);
  846 + result.session_expiry_interval = session_expire;
  847 + result.session_expiry_interval_set = true;
843 848 break;
844 849 }
845 850 case Mqtt5Properties::ReasonString:
846 851 {
847   - reasonString = readBytesToString();
  852 + result.reasonString = readBytesToString();
848 853 break;
849 854 }
850 855 case Mqtt5Properties::ServerReference:
... ... @@ -862,15 +867,25 @@ void MqttPacket::handleDisconnect()
862 867 }
863 868 }
864 869  
865   - std::string disconnectReason = formatString("MQTT Disconnect received (code %d).", static_cast<uint8_t>(reasonCode));
  870 + return result;
  871 +}
  872 +
  873 +void MqttPacket::handleDisconnect()
  874 +{
  875 + DisconnectData data = parseDisconnectData();
  876 +
  877 + std::string disconnectReason = formatString("MQTT Disconnect received (code %d).", static_cast<uint8_t>(data.reasonCode));
  878 +
  879 + if (!data.reasonString.empty())
  880 + disconnectReason += data.reasonString;
866 881  
867   - if (!reasonString.empty())
868   - disconnectReason += reasonString;
  882 + if (data.session_expiry_interval_set)
  883 + sender->getSession()->setSessionExpiryInterval(data.session_expiry_interval);
869 884  
870 885 logger->logf(LOG_NOTICE, "Client '%s' cleanly disconnecting", sender->repr().c_str());
871 886 sender->setDisconnectReason(disconnectReason);
872 887 sender->markAsDisconnecting();
873   - if (reasonCode == ReasonCodes::Success)
  888 + if (data.reasonCode == ReasonCodes::Success)
874 889 sender->clearWill();
875 890 ThreadGlobals::getThreadData()->removeClientQueued(sender);
876 891 }
... ...
mqttpacket.h
... ... @@ -113,6 +113,7 @@ public:
113 113 ConnectData parseConnectData();
114 114 void handleConnect();
115 115 void handleExtendedAuth();
  116 + DisconnectData parseDisconnectData();
116 117 void handleDisconnect();
117 118 void handleSubscribe();
118 119 void handleUnsubscribe();
... ...
packetdatatypes.h
... ... @@ -38,5 +38,14 @@ struct ConnectData
38 38 ConnectData();
39 39 };
40 40  
  41 +struct DisconnectData
  42 +{
  43 + ReasonCodes reasonCode = ReasonCodes::Success;
  44 + std::string reasonString;
  45 +
  46 + bool session_expiry_interval_set = false;
  47 + uint32_t session_expiry_interval = 0;
  48 +};
  49 +
41 50  
42 51 #endif // PACKETDATATYPES_H
... ...