mirror of
https://github.com/qt/qtmqtt.git
synced 2026-10-25 16:16:26 +00:00
Make packet identifier standard conformant
The standard requires that the identifier is non-zero and currently unused. The identifier has also to be unique in the scope of the client, not only to SUBSCRIBE, UNSUBSCRIBE, and PUBLISH messages. Change-Id: Ide1546dbc3282fe256f08f9d3cd779ffea0318a5 Reviewed-by: Maurice Kalinowski <maurice.kalinowski@qt.io>
This commit is contained in:
parent
828348f6aa
commit
5e7be337f0
@ -34,9 +34,6 @@
|
||||
#include <QtCore/QLoggingCategory>
|
||||
#include <QtNetwork/QSslSocket>
|
||||
#include <QtNetwork/QTcpSocket>
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
||||
#include <QtCore/QRandomGenerator>
|
||||
#endif
|
||||
|
||||
#include <limits>
|
||||
#include <cstdint>
|
||||
@ -271,24 +268,15 @@ qint32 QMqttConnection::sendControlPublish(const QString &topic, const QByteArra
|
||||
packet->append(topicArray);
|
||||
quint16 identifier = 0;
|
||||
if (qos > 0) {
|
||||
// Add Packet Identifier
|
||||
static quint16 publishIdCounter = 0;
|
||||
if (publishIdCounter + 1 == u16max)
|
||||
publishIdCounter = 0;
|
||||
else
|
||||
publishIdCounter++;
|
||||
|
||||
identifier = publishIdCounter;
|
||||
identifier = unusedPacketIdentifier();
|
||||
packet->append(identifier);
|
||||
m_pendingMessages.insert(identifier, packet);
|
||||
}
|
||||
packet->appendRaw(message);
|
||||
|
||||
if (qos)
|
||||
m_pendingMessages.insert(identifier, packet);
|
||||
|
||||
const bool written = writePacketToTransport(*packet.data());
|
||||
|
||||
if (!written)
|
||||
if (!written && qos > 0)
|
||||
m_pendingMessages.remove(identifier);
|
||||
return written ? identifier : -1;
|
||||
}
|
||||
@ -341,12 +329,7 @@ QMqttSubscription *QMqttConnection::sendControlSubscribe(const QString &topic, q
|
||||
QMqttControlPacket packet(header);
|
||||
|
||||
// Add Packet Identifier
|
||||
const quint16 identifier =
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
|
||||
qrand();
|
||||
#else
|
||||
QRandomGenerator::get32();
|
||||
#endif
|
||||
const quint16 identifier = unusedPacketIdentifier();
|
||||
|
||||
packet.append(identifier);
|
||||
|
||||
@ -405,12 +388,7 @@ bool QMqttConnection::sendControlUnsubscribe(const QString &topic)
|
||||
QMqttControlPacket packet(header);
|
||||
|
||||
// Add Packet Identifier
|
||||
const quint16 identifier =
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
|
||||
qrand();
|
||||
#else
|
||||
QRandomGenerator::get32();
|
||||
#endif
|
||||
const quint16 identifier = unusedPacketIdentifier();
|
||||
|
||||
packet.append(identifier);
|
||||
|
||||
@ -471,6 +449,31 @@ void QMqttConnection::setClient(QMqttClient *client)
|
||||
m_client = client;
|
||||
}
|
||||
|
||||
quint16 QMqttConnection::unusedPacketIdentifier() const
|
||||
{
|
||||
// MQTT-2.3.1-1 Control Packets MUST contain a non-zero 16-bit Packet Identifier
|
||||
static quint16 packetIdentifierCounter = 1;
|
||||
const std::uint16_t u16max = std::numeric_limits<std::uint16_t>::max();
|
||||
|
||||
// MQTT-2.3.1-2 ...it MUST assign it a currently unused Packet Identifier
|
||||
const quint16 lastIdentifier = packetIdentifierCounter;
|
||||
do {
|
||||
if (packetIdentifierCounter == u16max)
|
||||
packetIdentifierCounter = 1;
|
||||
else
|
||||
packetIdentifierCounter++;
|
||||
|
||||
if (lastIdentifier == packetIdentifierCounter) {
|
||||
qWarning("Can't generate unique packet identifier.");
|
||||
break;
|
||||
}
|
||||
} while (m_pendingSubscriptionAck.contains(packetIdentifierCounter)
|
||||
|| m_pendingUnsubscriptions.contains(packetIdentifierCounter)
|
||||
|| m_pendingMessages.contains(packetIdentifierCounter)
|
||||
|| m_pendingReleaseMessages.contains(packetIdentifierCounter));
|
||||
return packetIdentifierCounter;
|
||||
}
|
||||
|
||||
void QMqttConnection::transportConnectionClosed()
|
||||
{
|
||||
m_readBuffer.clear();
|
||||
|
||||
@ -94,6 +94,7 @@ public:
|
||||
|
||||
void setClient(QMqttClient *client);
|
||||
|
||||
inline quint16 unusedPacketIdentifier() const;
|
||||
inline InternalConnectionState internalState() const { return m_internalState; }
|
||||
|
||||
public Q_SLOTS:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user