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