1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#ifndef QMQTTCONNECTION_P_H
6#define QMQTTCONNECTION_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include "qmqttclient.h"
20#include "qmqttcontrolpacket_p.h"
21#include "qmqttmessage.h"
22#include "qmqttsubscription.h"
23#include <QtCore/QBasicTimer>
24#include <QtCore/QBuffer>
25#include <QtCore/QHash>
26#include <QtCore/QObject>
27#include <QtCore/QSharedPointer>
28#include <QtCore/QtEndian>
29
30#include <memory>
31
32QT_BEGIN_NAMESPACE
33
34class QMqttClientPrivate;
35
36class Q_AUTOTEST_EXPORT QMqttConnection : public QObject
37{
38 Q_OBJECT
39public:
40 enum InternalConnectionState {
41 BrokerDisconnected = 0,
42 BrokerConnecting,
43 BrokerWaitForConnectAck,
44 BrokerConnected,
45 ClientDestruction
46 };
47
48 explicit QMqttConnection(QObject *parent = nullptr);
49 ~QMqttConnection() override;
50
51 void disconnectAndResetTransport();
52 void setTransport(QIODevice *device, QMqttClient::TransportType transport);
53 void connectTransport(QMqttClient::TransportType transport, const std::shared_ptr<QIODevice> &device);
54 QIODevice *transport() const;
55
56 bool ensureTransport(bool createSecureIfNeeded = false);
57 bool ensureTransportOpen(const QString &sslPeerName = QString());
58
59 bool sendControlConnect();
60 bool sendControlAuthenticate(const QMqttAuthenticationProperties &properties);
61 qint32 sendControlPublish(const QMqttTopicName &topic, const QByteArray &message, quint8 qos = 0, bool retain = false,
62 const QMqttPublishProperties &properties = QMqttPublishProperties());
63 bool sendControlPublishAcknowledge(quint16 id);
64 bool sendControlPublishRelease(quint16 id);
65 bool sendControlPublishReceive(quint16 id);
66 bool sendControlPublishComp(quint16 id);
67 QMqttSubscription *sendControlSubscribe(const QMqttTopicFilter &topic, quint8 qos, const QMqttSubscriptionProperties &properties);
68 bool sendControlUnsubscribe(const QMqttTopicFilter &topic, const QMqttUnsubscriptionProperties &properties);
69 bool sendControlPingRequest(bool isAuto = true);
70 bool sendControlDisconnect();
71
72 void setClientPrivate(QMqttClientPrivate *clientPrivate);
73
74 inline quint16 unusedPacketIdentifier() const;
75 inline InternalConnectionState internalState() const { return m_internalState; }
76 inline void setClientDestruction() { m_internalState = ClientDestruction; }
77
78 void cleanSubscriptions();
79
80private:
81 void transportConnectionEstablished();
82 void transportConnectionClosed();
83 void transportReadyRead();
84 void transportError(QAbstractSocket::SocketError e);
85
86protected:
87 void timerEvent(QTimerEvent *event) override;
88
89public:
90 std::shared_ptr<QIODevice> m_transport;
91 QMqttClient::TransportType m_transportType{QMqttClient::IODevice};
92 bool m_transportIsSet{false}; // connectTo* does not reset m_transport;
93 bool m_connectedTransport{false}; // We have connected the signals for m_transport if true
94 QMqttClientPrivate *m_clientPrivate{nullptr};
95#ifndef QT_NO_SSL
96 QSslConfiguration m_sslConfiguration;
97#endif
98private:
99 Q_DISABLE_COPY(QMqttConnection)
100 void finalize_auth();
101 void finalize_connack();
102 void finalize_suback();
103 void finalize_unsuback();
104 void finalize_publish();
105 void finalize_pubAckRecRelComp();
106 void finalize_pingresp();
107 void processData();
108 bool processDataHelper();
109 bool readBuffer(char *data, quint64 size);
110 qint32 readVariableByteInteger(qint64 *dataSize = nullptr);
111 void readAuthProperties(QMqttAuthenticationProperties &properties);
112 void readConnackProperties(QMqttServerConnectionProperties &properties);
113 void readMessageStatusProperties(QMqttMessageStatusProperties &properties);
114 void readPublishProperties(QMqttPublishProperties &properties);
115 void readSubscriptionProperties(QMqttSubscription *sub);
116 QByteArray writeConnectProperties();
117 QByteArray writeLastWillProperties() const;
118 QByteArray writePublishProperties(const QMqttPublishProperties &properties);
119 QByteArray writeSubscriptionProperties(const QMqttSubscriptionProperties &properties);
120 QByteArray writeUnsubscriptionProperties(const QMqttUnsubscriptionProperties &properties);
121 QByteArray writeAuthenticationProperties(const QMqttAuthenticationProperties &properties);
122 void closeConnection(QMqttClient::ClientError error);
123 QByteArray readBuffer(quint64 size);
124 template<typename T> T readBufferTyped(qint64 *dataSize = nullptr);
125 bool isPendingUnsubscribe(QMqttSubscription *) const;
126 QMqttSubscription *findActiveSubscription(const QMqttTopicFilter &topic) const;
127
128 QByteArray m_readBuffer;
129 int m_readPosition{0};
130 qint64 m_missingData{0};
131 struct PublishData {
132 quint8 qos;
133 bool dup;
134 bool retain;
135 };
136 PublishData m_currentPublish{.qos: 0, .dup: false, .retain: false};
137 QMqttControlPacket::PacketType m_currentPacket{QMqttControlPacket::UNKNOWN};
138
139 bool writePacketToTransport(const QMqttControlPacket &p);
140
141 // I: There can be many occurences of different QMqttSubscription * with
142 // the same QMqttTopicFilter, but only one that is not in
143 // m_pendingUnsubscriptions.
144 QHash<quint16, QMqttSubscription *> m_pendingSubscriptionAck;
145 QHash<quint16, QMqttSubscription *> m_pendingUnsubscriptions;
146 QMultiHash<QMqttTopicFilter, QMqttSubscription *> m_activeSubscriptions;
147 QHash<quint16, QSharedPointer<QMqttControlPacket>> m_pendingMessages;
148 QHash<quint16, QSharedPointer<QMqttControlPacket>> m_pendingReleaseMessages;
149 InternalConnectionState m_internalState{BrokerDisconnected};
150 QBasicTimer m_pingTimer;
151 int m_pingTimeout{0};
152
153 QList<QMqttTopicName> m_receiveAliases;
154 QList<QMqttTopicName> m_publishAliases;
155};
156
157QT_END_NAMESPACE
158
159#endif // QMQTTCONNECTION_P_H
160

source code of qtmqtt/src/mqtt/qmqttconnection_p.h