7#ifndef QXMPPOUTGOINGCLIENT_H
8#define QXMPPOUTGOINGCLIENT_H
10#include "QXmppAuthenticationError.h"
11#include "QXmppBindError.h"
12#include "QXmppClient.h"
13#include "QXmppPromise.h"
14#include "QXmppStanza.h"
15#include "QXmppStreamError.h"
17#include <QAbstractSocket>
28class QXmppOutgoingClientPrivate;
31namespace QXmpp::Private {
32class C2sStreamManager;
35class OutgoingIqManager;
37class SendDataInterface;
38class StreamAckManager;
45struct StreamErrorElement;
47enum HandleElementResult {
53enum class AuthenticationMethod {
63 bool fastTokenChanged;
64 AuthenticationMethod authenticationMethod;
72namespace QXmpp::Private::Sasl2 {
84 using IqResult = std::variant<QDomElement, QXmppError>;
85 using ConnectionError = std::variant<QAbstractSocket::SocketError, QXmpp::TimeoutError, QXmpp::StreamError, QXmpp::AuthenticationError, QXmpp::BindError>;
86 static constexpr QStringView TaskName = u
"client session";
88 explicit QXmppOutgoingClient(QObject *parent);
89 ~QXmppOutgoingClient()
override;
92 void disconnectFromHost();
93 bool isAuthenticated()
const;
94 bool isConnected()
const;
95 QXmppTask<IqResult> sendIq(QXmppIq &&);
98 QSslSocket *socket()
const;
101 QXmppConfiguration &configuration();
103 QXmpp::Private::XmppSocket &xmppSocket()
const;
104 QXmpp::Private::StreamAckManager &streamAckManager()
const;
105 QXmpp::Private::OutgoingIqManager &iqManager()
const;
106 QXmpp::Private::C2sStreamManager &c2sStreamManager()
const;
107 QXmpp::Private::CarbonManager &carbonManager()
const;
108 QXmpp::Private::CsiManager &csiManager()
const;
111 Q_SIGNAL
void connected(
const QXmpp::Private::SessionBegin &);
114 Q_SIGNAL
void disconnected(
const QXmpp::Private::SessionEnd &);
117 Q_SIGNAL
void errorOccurred(
const QString &text,
const QXmppOutgoingClient::ConnectionError &details,
QXmppClient::Error oldError);
120 Q_SIGNAL
void elementReceived(
const QDomElement &element,
bool &handled);
123 Q_SIGNAL
void presenceReceived(
const QXmppPresence &);
126 Q_SIGNAL
void messageReceived(
const QXmppMessage &);
130 Q_SIGNAL
void iqReceived(
const QXmppIq &);
133 Q_SIGNAL
void sslErrors(
const QList<QSslError> &errors);
137 void handleStream(
const QDomElement &element);
138 void handlePacketReceived(
const QDomElement &element);
139 QXmpp::Private::HandleElementResult handleElement(
const QDomElement &nodeRecv);
140 void handleStreamFeatures(
const QXmppStreamFeatures &features);
141 void handleStreamError(
const QXmpp::Private::StreamErrorElement &streamError);
142 bool handleStanza(
const QDomElement &);
143 bool handleStarttls(
const QXmppStreamFeatures &features);
145 void _q_socketDisconnected();
146 void socketError(QAbstractSocket::SocketError);
147 void socketSslErrors(
const QList<QSslError> &);
149 void startSasl2Auth(
const QXmpp::Private::Sasl2::StreamFeature &sasl2Feature);
150 void startNonSaslAuth();
151 void startSmResume();
152 void startSmEnable();
153 void startResourceBinding();
156 void setError(
const QString &text, ConnectionError &&details);
157 void throwKeepAliveError();
160 void enableStreamManagement(
bool resetSequenceNumber);
161 bool handleIqResponse(
const QDomElement &);
163 friend class QXmppOutgoingClientPrivate;
164 friend class QXmpp::Private::PingManager;
165 friend class QXmpp::Private::C2sStreamManager;
166 friend class QXmppRegistrationManager;
167 friend class TestClient;
169 const std::unique_ptr<QXmppOutgoingClientPrivate> d;
172namespace QXmpp::Private {
174class C2sStreamManager
177 using Result = std::variant<Success, QXmppError>;
178 static constexpr QStringView TaskName = u
"stream management";
180 explicit C2sStreamManager(QXmppOutgoingClient *q);
182 HandleElementResult handleElement(
const QDomElement &);
183 bool hasResumeAddress()
const {
return m_canResume && !m_resumeHost.isEmpty() && m_resumePort; }
184 std::pair<QString, quint16> resumeAddress()
const {
return { m_resumeHost, m_resumePort }; }
185 void onStreamStart();
186 void onStreamFeatures(
const QXmppStreamFeatures &);
187 void onStreamClosed();
188 void onSasl2Authenticate(Sasl2::Authenticate &auth,
const Sasl2::StreamFeature &feature);
189 void onSasl2Success(
const Sasl2::Success &success);
190 void onBind2Request(Bind2Request &request,
const std::vector<QString> &bind2Features);
191 void onBind2Bound(
const Bind2Bound &);
192 bool canResume()
const {
return m_canResume; }
193 bool enabled()
const {
return m_enabled; }
194 bool streamResumed()
const {
return m_streamResumed; }
195 bool canRequestResume()
const {
return m_smAvailable && !m_enabled && m_canResume; }
196 QXmppTask<void> requestResume();
197 bool canRequestEnable()
const {
return m_smAvailable && !m_enabled; }
198 QXmppTask<void> requestEnable();
199 bool hasOngoingRequest()
const {
return !std::holds_alternative<NoRequest>(m_request); }
202 friend class ::TestClient;
204 void onEnabled(
const SmEnabled &enabled);
205 void onEnableFailed(
const SmFailed &failed);
206 void onResumed(
const SmResumed &resumed);
207 void onResumeFailed(
const SmFailed &failed);
208 bool setResumeAddress(
const QString &address);
209 void setEnabled(
bool enabled) { m_enabled = enabled; }
210 void setResumed(
bool resumed) { m_streamResumed = resumed; }
212 struct NoRequest { };
213 struct ResumeRequest {
214 QXmppPromise<void> p;
216 struct EnableRequest {
217 QXmppPromise<void> p;
220 QXmppOutgoingClient *q;
222 std::variant<NoRequest, ResumeRequest, EnableRequest> m_request;
223 bool m_smAvailable =
false;
225 bool m_canResume =
false;
226 QString m_resumeHost;
227 quint16 m_resumePort = 0;
228 bool m_enabled =
false;
229 bool m_streamResumed =
false;
236 void setEnableViaBind2(
bool enable) { m_enableViaBind2 = enable; }
237 bool enabled()
const {
return m_enabled; }
238 void onBind2Request(Bind2Request &request,
const std::vector<QString> &bind2Features);
239 void onSessionOpened(
const SessionBegin &session);
243 bool m_enableViaBind2 =
false;
245 bool m_enabled =
false;
246 bool m_requested =
false;
258 explicit CsiManager(QXmppOutgoingClient *client);
260 State state()
const {
return m_state; }
261 void setState(State);
262 void onSessionOpened(
const SessionBegin &);
263 void onStreamFeatures(
const QXmppStreamFeatures &);
264 void onBind2Request(Bind2Request &request,
const std::vector<QString> &bind2Features);
269 QXmppOutgoingClient *m_client;
270 State m_state = Active;
271 bool m_synced =
true;
272 bool m_featureAvailable =
false;
273 bool m_bind2InactiveSet =
false;
Error
Definition QXmppClient.h:76
The QXmppConfiguration class holds configuration options.
Definition QXmppConfiguration.h:37
The QXmppIq class is the base class for all IQs.
Definition QXmppIq.h:23
The QXmppLoggable class represents a source of logging messages.
Definition QXmppLogger.h:110
The QXmppMessage class represents an XMPP message.
Definition QXmppMessage.h:64
The QXmppPresence class represents an XMPP presence stanza.
Definition QXmppPresence.h:22
Condition
A detailed condition of the error.
Definition QXmppStanza.h:110
The QXmppStreamFeatures class represents the features returned by an XMPP server or client.
Definition QXmppStreamFeatures.h:23