aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLinus Jahn <lnj@kaidan.im>2020-09-09 15:32:01 +0200
committerLinus Jahn <lnj@kaidan.im>2021-01-09 14:37:47 +0100
commitaf22e07a2300dc18ec62eee30508569062d918b3 (patch)
tree753c28084811c1beac0d1657eb193aa756703e4d /src
parent8570b4c56616547e5fa2530e6b9733fb37cf02a3 (diff)
downloadqxmpp-af22e07a2300dc18ec62eee30508569062d918b3.tar.gz
QXmppClient: Advertise stream management state
Diffstat (limited to 'src')
-rw-r--r--src/client/QXmppClient.cpp18
-rw-r--r--src/client/QXmppClient.h16
-rw-r--r--src/client/QXmppOutgoingClient.cpp51
-rw-r--r--src/client/QXmppOutgoingClient.h2
4 files changed, 85 insertions, 2 deletions
diff --git a/src/client/QXmppClient.cpp b/src/client/QXmppClient.cpp
index 926a9463..6f3c2d57 100644
--- a/src/client/QXmppClient.cpp
+++ b/src/client/QXmppClient.cpp
@@ -350,6 +350,24 @@ void QXmppClient::setActive(bool active)
}
}
+///
+/// Returns the current \xep{0198}: Stream Management state of the connection.
+///
+/// Upon connection of the client this can be used to check whether the
+/// previous stream has been resumed.
+///
+/// \since QXmpp 1.4
+///
+QXmppClient::StreamManagementState QXmppClient::streamManagementState() const
+{
+ if (d->stream->isStreamManagementEnabled()) {
+ if (d->stream->isStreamResumed())
+ return ResumedStream;
+ return NewStream;
+ }
+ return NoStreamManagement;
+}
+
/// Returns the reference to QXmppRosterManager object of the client.
///
/// \return Reference to the roster object of the connected client. Use this to
diff --git a/src/client/QXmppClient.h b/src/client/QXmppClient.h
index 02c580c3..0afe6235 100644
--- a/src/client/QXmppClient.h
+++ b/src/client/QXmppClient.h
@@ -89,7 +89,7 @@ class QXmppVersionManager;
/// - QXmppEntityTimeManager
///
/// \ingroup Core
-
+///
class QXMPP_EXPORT QXmppClient : public QXmppLoggable
{
Q_OBJECT
@@ -118,6 +118,16 @@ public:
};
Q_ENUM(State)
+ /// Describes the use of \xep{0198}: Stream Management
+ enum StreamManagementState {
+ /// Stream Management is not used.
+ NoStreamManagement,
+ /// Stream Management is used and the previous stream has not been resumed.
+ NewStream,
+ /// Stream Management is used and the previous stream has been resumed.
+ ResumedStream
+ };
+
QXmppClient(QObject *parent = nullptr);
~QXmppClient() override;
@@ -127,6 +137,7 @@ public:
QList<QXmppClientExtension *> extensions();
+ ///
/// \brief Returns the extension which can be cast into type T*, or 0
/// if there is no such extension.
///
@@ -151,6 +162,7 @@ public:
return nullptr;
}
+ ///
/// \brief Returns the index of an extension
///
/// Usage example:
@@ -182,6 +194,8 @@ public:
bool isActive() const;
void setActive(bool active);
+ StreamManagementState streamManagementState() const;
+
QXmppPresence clientPresence() const;
void setClientPresence(const QXmppPresence &presence);
diff --git a/src/client/QXmppOutgoingClient.cpp b/src/client/QXmppOutgoingClient.cpp
index 9f3e5e58..e5338a72 100644
--- a/src/client/QXmppOutgoingClient.cpp
+++ b/src/client/QXmppOutgoingClient.cpp
@@ -107,6 +107,8 @@ public:
bool isResuming;
QString resumeHost;
quint16 resumePort;
+ bool streamManagementEnabled;
+ bool streamResumed;
// Client State Indication
bool clientStateIndicationEnabled;
@@ -120,7 +122,23 @@ private:
};
QXmppOutgoingClientPrivate::QXmppOutgoingClientPrivate(QXmppOutgoingClient *qq)
- : nextSrvRecordIdx(0), redirectPort(0), bindModeAvailable(false), sessionAvailable(false), sessionStarted(false), isAuthenticated(false), saslClient(nullptr), streamManagementAvailable(false), canResume(false), isResuming(false), resumePort(0), clientStateIndicationEnabled(false), pingTimer(nullptr), timeoutTimer(nullptr), q(qq)
+ : nextSrvRecordIdx(0),
+ redirectPort(0),
+ bindModeAvailable(false),
+ sessionAvailable(false),
+ sessionStarted(false),
+ isAuthenticated(false),
+ saslClient(nullptr),
+ streamManagementAvailable(false),
+ canResume(false),
+ isResuming(false),
+ resumePort(0),
+ streamManagementEnabled(false),
+ streamResumed(false),
+ clientStateIndicationEnabled(false),
+ pingTimer(nullptr),
+ timeoutTimer(nullptr),
+ q(qq)
{
}
@@ -285,6 +303,30 @@ bool QXmppOutgoingClient::isClientStateIndicationEnabled() const
return d->clientStateIndicationEnabled;
}
+///
+/// Returns whether Stream Management is currently enabled.
+///
+/// \since QXmpp 1.4
+///
+bool QXmppOutgoingClient::isStreamManagementEnabled() const
+{
+ return d->streamManagementEnabled;
+}
+
+///
+/// Returns true if the current stream is a successful resumption of a previous
+/// stream.
+///
+/// In case a stream has been resumed, some tasks like fetching the roster again
+/// are not required.
+///
+/// \since QXmpp 1.4
+///
+bool QXmppOutgoingClient::isStreamResumed() const
+{
+ return d->streamResumed;
+}
+
void QXmppOutgoingClient::_q_socketDisconnected()
{
debug("Socket disconnected");
@@ -346,6 +388,10 @@ void QXmppOutgoingClient::handleStart()
d->sessionAvailable = false;
d->sessionStarted = false;
+ // reset stream management
+ d->streamResumed = false;
+ d->streamManagementEnabled = false;
+
// start stream
QByteArray data = "<?xml version='1.0'?><stream:stream to='";
data.append(configuration().domain().toUtf8());
@@ -682,6 +728,7 @@ void QXmppOutgoingClient::handleStanza(const QDomElement &nodeRecv)
setResumeAddress(streamManagementEnabled.location());
}
+ d->streamManagementEnabled = true;
enableStreamManagement(true);
// we are connected now
emit connected();
@@ -690,7 +737,9 @@ void QXmppOutgoingClient::handleStanza(const QDomElement &nodeRecv)
streamManagementResumed.parse(nodeRecv);
setAcknowledgedSequenceNumber(streamManagementResumed.h());
d->isResuming = false;
+ d->streamResumed = true;
+ d->streamManagementEnabled = true;
enableStreamManagement(false);
// we are connected now
// TODO: The stream was resumed. Therefore, we should not send presence information or request the roster.
diff --git a/src/client/QXmppOutgoingClient.h b/src/client/QXmppOutgoingClient.h
index e740babc..3948f5b0 100644
--- a/src/client/QXmppOutgoingClient.h
+++ b/src/client/QXmppOutgoingClient.h
@@ -55,6 +55,8 @@ public:
bool isAuthenticated() const;
bool isConnected() const override;
bool isClientStateIndicationEnabled() const;
+ bool isStreamManagementEnabled() const;
+ bool isStreamResumed() const;
QSslSocket *socket() const { return QXmppStream::socket(); };
QXmppStanza::Error::Condition xmppStreamError();