Commit 4bf112b6d9f450f2ee8eb5665eb4f3f9d4ecbed4
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).
Showing
3 changed files
with
35 additions
and
10 deletions
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
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 | ... | ... |