From 6ae4afbed9edf8a36ccdab5026b6be725f89a685 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Thu, 17 Aug 2017 01:47:14 +0400 Subject: [PATCH] Fix CONNECT Control Packet marshaller regarding willMessage and password Per to MQTT 3.1.1 Standard: > 3.1.3.3 Will Message > If the Will Flag is set to 1 the Will Message is the next field in the payload. The Will Message defines the Application Message that is to be published to the Will Topic as described in Section 3.1.2.5. This field consists of a two byte length followed by the payload for the Will Message expressed as a sequence of zero or more bytes. The length gives the number of bytes in the data that follows and does not include the 2 bytes taken up by the length itself. > 3.1.3.5 Password > If the Password Flag is set to 1, this is the next field in the payload. The Password field contains 0 to 65535 bytes of binary data prefixed with a two byte length field which indicates the number of bytes used by the binary data (it does not include the two bytes taken up by the length field itself). --- src/mqtt/qmqtt_client.cpp | 8 ++++---- src/mqtt/qmqtt_client.h | 12 ++++++------ src/mqtt/qmqtt_client_p.cpp | 12 ++++++------ src/mqtt/qmqtt_client_p.h | 12 ++++++------ src/mqtt/qmqtt_frame.cpp | 22 ++++++++++++++++++++++ src/mqtt/qmqtt_frame.h | 2 ++ 6 files changed, 46 insertions(+), 22 deletions(-) diff --git a/src/mqtt/qmqtt_client.cpp b/src/mqtt/qmqtt_client.cpp index 6a07d9d..f46457f 100644 --- a/src/mqtt/qmqtt_client.cpp +++ b/src/mqtt/qmqtt_client.cpp @@ -155,13 +155,13 @@ void QMQTT::Client::setVersion(const QMQTT::MQTTVersion version) d->setVersion(version); } -QString QMQTT::Client::password() const +QByteArray QMQTT::Client::password() const { Q_D(const Client); return d->password(); } -void QMQTT::Client::setPassword(const QString& password) +void QMQTT::Client::setPassword(const QByteArray &password) { Q_D(Client); d->setPassword(password); @@ -251,13 +251,13 @@ void QMQTT::Client::setWillRetain(const bool willRetain) d->setWillRetain(willRetain); } -QString QMQTT::Client::willMessage() const +QByteArray QMQTT::Client::willMessage() const { Q_D(const Client); return d->willMessage(); } -void QMQTT::Client::setWillMessage(const QString& willMessage) +void QMQTT::Client::setWillMessage(const QByteArray &willMessage) { Q_D(Client); d->setWillMessage(willMessage); diff --git a/src/mqtt/qmqtt_client.h b/src/mqtt/qmqtt_client.h index dec14da..fae948a 100644 --- a/src/mqtt/qmqtt_client.h +++ b/src/mqtt/qmqtt_client.h @@ -105,7 +105,7 @@ class Q_MQTT_EXPORT Client : public QObject Q_PROPERTY(QString _hostName READ hostName WRITE setHostName) Q_PROPERTY(QString _clientId READ clientId WRITE setClientId) Q_PROPERTY(QString _username READ username WRITE setUsername) - Q_PROPERTY(QString _password READ password WRITE setPassword) + Q_PROPERTY(QByteArray _password READ password WRITE setPassword) Q_PROPERTY(quint16 _keepAlive READ keepAlive WRITE setKeepAlive) Q_PROPERTY(MQTTVersion _version READ version WRITE setVersion) Q_PROPERTY(bool _autoReconnect READ autoReconnect WRITE setAutoReconnect) @@ -114,7 +114,7 @@ class Q_MQTT_EXPORT Client : public QObject Q_PROPERTY(QString _willTopic READ willTopic WRITE setWillTopic) Q_PROPERTY(quint8 _willQos READ willQos WRITE setWillQos) Q_PROPERTY(bool _willRetain READ willRetain WRITE setWillRetain) - Q_PROPERTY(QString _willMessage READ willMessage WRITE setWillMessage) + Q_PROPERTY(QByteArray _willMessage READ willMessage WRITE setWillMessage) Q_PROPERTY(QString _connectionState READ connectionState) public: @@ -153,7 +153,7 @@ class Q_MQTT_EXPORT Client : public QObject quint16 port() const; QString clientId() const; QString username() const; - QString password() const; + QByteArray password() const; QMQTT::MQTTVersion version() const; quint16 keepAlive() const; bool cleanSession() const; @@ -163,7 +163,7 @@ class Q_MQTT_EXPORT Client : public QObject QString willTopic() const; quint8 willQos() const; bool willRetain() const; - QString willMessage() const; + QByteArray willMessage() const; bool isConnectedToHost() const; @@ -173,7 +173,7 @@ public slots: void setPort(const quint16 port); void setClientId(const QString& clientId); void setUsername(const QString& username); - void setPassword(const QString& password); + void setPassword(const QByteArray& password); void setVersion(const MQTTVersion version); void setKeepAlive(const quint16 keepAlive); void setCleanSession(const bool cleanSession); @@ -182,7 +182,7 @@ public slots: void setWillTopic(const QString& willTopic); void setWillQos(const quint8 willQos); void setWillRetain(const bool willRetain); - void setWillMessage(const QString& willMessage); + void setWillMessage(const QByteArray& willMessage); void connectToHost(); void disconnectFromHost(); diff --git a/src/mqtt/qmqtt_client_p.cpp b/src/mqtt/qmqtt_client_p.cpp index 9a08012..c17811e 100644 --- a/src/mqtt/qmqtt_client_p.cpp +++ b/src/mqtt/qmqtt_client_p.cpp @@ -222,7 +222,7 @@ void QMQTT::ClientPrivate::sendConnect() frame.writeString(willTopic()); if(!willMessage().isEmpty()) { - frame.writeString(willMessage()); + frame.writeByteArray(_willMessage); } } if (!_username.isEmpty()) @@ -230,7 +230,7 @@ void QMQTT::ClientPrivate::sendConnect() frame.writeString(_username); if (!_password.isEmpty()) { - frame.writeString(_password); + frame.writeByteArray(_password); } } _network->sendFrame(frame); @@ -543,12 +543,12 @@ quint16 QMQTT::ClientPrivate::keepAlive() const return _keepAlive; } -void QMQTT::ClientPrivate::setPassword(const QString& password) +void QMQTT::ClientPrivate::setPassword(const QByteArray& password) { _password = password; } -QString QMQTT::ClientPrivate::password() const +QByteArray QMQTT::ClientPrivate::password() const { return _password; } @@ -650,12 +650,12 @@ void QMQTT::ClientPrivate::setWillRetain(const bool willRetain) _willRetain = willRetain; } -QString QMQTT::ClientPrivate::willMessage() const +QByteArray QMQTT::ClientPrivate::willMessage() const { return _willMessage; } -void QMQTT::ClientPrivate::setWillMessage(const QString& willMessage) +void QMQTT::ClientPrivate::setWillMessage(const QByteArray& willMessage) { _willMessage = willMessage; } diff --git a/src/mqtt/qmqtt_client_p.h b/src/mqtt/qmqtt_client_p.h index fcffdcc..fbf9a52 100644 --- a/src/mqtt/qmqtt_client_p.h +++ b/src/mqtt/qmqtt_client_p.h @@ -64,7 +64,7 @@ class ClientPrivate MQTTVersion _version; QString _clientId; QString _username; - QString _password; + QByteArray _password; bool _cleanSession; quint16 _keepAlive; ConnectionState _connectionState; @@ -73,7 +73,7 @@ class ClientPrivate QString _willTopic; quint8 _willQos; bool _willRetain; - QString _willMessage; + QByteArray _willMessage; QHash _socketErrorHash; QHash _midToTopic; @@ -117,8 +117,8 @@ class ClientPrivate bool cleanSession() const; void setKeepAlive(const quint16 keepAlive); quint16 keepAlive() const; - void setPassword(const QString& password); - QString password() const; + void setPassword(const QByteArray& password); + QByteArray password() const; void setUsername(const QString& username); QString username() const; void setVersion(const MQTTVersion); @@ -134,11 +134,11 @@ class ClientPrivate void setWillTopic(const QString& willTopic); void setWillQos(const quint8 willQos); void setWillRetain(const bool willRetain); - void setWillMessage(const QString& willMessage); + void setWillMessage(const QByteArray& willMessage); QString willTopic() const; quint8 willQos() const; bool willRetain() const; - QString willMessage() const; + QByteArray willMessage() const; void initializeErrorHash(); void onNetworkError(QAbstractSocket::SocketError error); diff --git a/src/mqtt/qmqtt_frame.cpp b/src/mqtt/qmqtt_frame.cpp index be8576c..6791859 100644 --- a/src/mqtt/qmqtt_frame.cpp +++ b/src/mqtt/qmqtt_frame.cpp @@ -104,6 +104,14 @@ quint16 Frame::readInt() return (msb << 8) | lsb; } +QByteArray Frame::readByteArray() +{ + quint16 len = readInt(); + QByteArray data = _data.left(len); + _data.remove(0, len); + return data; +} + QString Frame::readString() { quint16 len = readInt(); @@ -118,6 +126,20 @@ void Frame::writeInt(const quint16 i) _data.append(LSB(i)); } +void Frame::writeByteArray(const QByteArray &data) +{ + if (data.size() > (int)USHRT_MAX) + { + qCritical("qmqtt: Binary data size bigger than %u bytes, truncate it!", USHRT_MAX); + writeInt(USHRT_MAX); + _data.append(data.left(USHRT_MAX)); + return; + } + + writeInt(data.size()); + _data.append(data); +} + void Frame::writeString(const QString &string) { QByteArray data = string.toUtf8(); diff --git a/src/mqtt/qmqtt_frame.h b/src/mqtt/qmqtt_frame.h index 15e27dc..5cca7fb 100644 --- a/src/mqtt/qmqtt_frame.h +++ b/src/mqtt/qmqtt_frame.h @@ -106,10 +106,12 @@ class Q_MQTT_EXPORT Frame quint16 readInt(); quint8 readChar(); + QByteArray readByteArray(); QString readString(); void writeInt(const quint16 i); void writeChar(const quint8 c); + void writeByteArray(const QByteArray &data); void writeString(const QString &string); void writeRawData(const QByteArray &data);