aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTibor Csötönyi <work@taibsu.de>2023-05-03 15:33:35 +0200
committerLinus Jahn <lnj@kaidan.im>2023-05-14 23:58:00 +0200
commit2fde987d39dc66f028ea3ff44929ebd6e2b37f90 (patch)
tree14ce02a68b801caf984f74700ea28c0a85fc5b3b /src
parent44e9657c4e1551697f496cc9415f3d458103ca5c (diff)
downloadqxmpp-2fde987d39dc66f028ea3ff44929ebd6e2b37f90.tar.gz
Add XEP-0353: Jingle Message Initiation data classes
Diffstat (limited to 'src')
-rw-r--r--src/base/QXmppConstants.cpp2
-rw-r--r--src/base/QXmppConstants_p.h2
-rw-r--r--src/base/QXmppJingleIq.cpp275
-rw-r--r--src/base/QXmppJingleIq.h51
-rw-r--r--src/base/QXmppMessage.cpp35
-rw-r--r--src/base/QXmppMessage.h6
6 files changed, 370 insertions, 1 deletions
diff --git a/src/base/QXmppConstants.cpp b/src/base/QXmppConstants.cpp
index be5b62c7..0ddd3db2 100644
--- a/src/base/QXmppConstants.cpp
+++ b/src/base/QXmppConstants.cpp
@@ -160,6 +160,8 @@ const char *ns_chat_markers = "urn:xmpp:chat-markers:0";
const char *ns_message_processing_hints = "urn:xmpp:hints";
// XEP-0352: Client State Indication
const char *ns_csi = "urn:xmpp:csi:0";
+// XEP-0353: Jingle Message Initiation
+const char *ns_jingle_message_initiation = "urn:xmpp:jingle-message:0";
// XEP-0357: Push Notifications
const char *ns_push = "urn:xmpp:push:0";
// XEP-0359: Unique and Stable Stanza IDs
diff --git a/src/base/QXmppConstants_p.h b/src/base/QXmppConstants_p.h
index b90346b6..c859de96 100644
--- a/src/base/QXmppConstants_p.h
+++ b/src/base/QXmppConstants_p.h
@@ -172,6 +172,8 @@ extern const char *ns_chat_markers;
extern const char *ns_message_processing_hints;
// XEP-0352: Client State Indication
extern const char *ns_csi;
+// XEP-0353: Jingle Message Initiation
+extern const char *ns_jingle_message_initiation;
// XEP-0357: Push Notifications
extern const char *ns_push;
// XEP-0359: Unique and Stable Stanza IDs
diff --git a/src/base/QXmppJingleIq.cpp b/src/base/QXmppJingleIq.cpp
index d769e809..67883fc8 100644
--- a/src/base/QXmppJingleIq.cpp
+++ b/src/base/QXmppJingleIq.cpp
@@ -2930,3 +2930,278 @@ bool QXmppJingleRtpHeaderExtensionProperty::isJingleRtpHeaderExtensionProperty(c
return element.tagName() == QStringLiteral("rtp-hdrext") &&
element.namespaceURI() == ns_jingle_rtp_header_extensions_negotiation;
}
+
+class QXmppJingleMessageInitiationElementPrivate : public QSharedData
+{
+public:
+ QXmppJingleMessageInitiationElementPrivate() = default;
+
+ QXmppJingleMessageInitiationElement::Type type { QXmppJingleMessageInitiationElement::Type::None };
+ QString id;
+
+ std::optional<QXmppJingleDescription> description;
+ std::optional<QXmppJingleReason> reason;
+ QString migratedTo;
+
+ bool containsTieBreak;
+};
+
+QXMPP_PRIVATE_DEFINE_RULE_OF_SIX(QXmppJingleReason)
+
+///
+/// \enum QXmppJingleMessageInitiationElement::Type
+///
+/// Possible types of Jingle Message Initiation elements
+///
+
+///
+/// \class QXmppJingleMessageInitiationElement
+///
+/// \brief The QXmppJingleMessageInitiationElement class represents a Jingle Message Initiation
+/// element as specified by \xep{0353}: Jingle Message Initiation.
+///
+/// \ingroup Stanzas
+///
+/// \since QXmpp 1.6
+///
+
+///
+/// \brief Constructs a Jingle Message Initiation element.
+/// \param type The JMI element type
+///
+QXmppJingleMessageInitiationElement::QXmppJingleMessageInitiationElement()
+ : d(new QXmppJingleMessageInitiationElementPrivate())
+{
+}
+
+///
+/// Returns the Jingle Message Initiation element type
+///
+QXmppJingleMessageInitiationElement::Type QXmppJingleMessageInitiationElement::type() const
+{
+ return d->type;
+}
+
+///
+/// Sets the Jingle Message Initiation element type.
+///
+void QXmppJingleMessageInitiationElement::setType(Type type)
+{
+ d->type = type;
+}
+
+///
+/// Returns the Jingle Message Initiation element id.
+///
+QString QXmppJingleMessageInitiationElement::id() const
+{
+ return d->id;
+}
+
+///
+/// Sets the Jingle Message Initiation element id.
+///
+void QXmppJingleMessageInitiationElement::setId(const QString &id)
+{
+ d->id = id;
+}
+
+///
+/// Returns the Jingle Message Initiation element description.
+///
+std::optional<QXmppJingleDescription> QXmppJingleMessageInitiationElement::description() const
+{
+ return d->description;
+}
+
+///
+/// Sets the Jingle Message Initiation element description.
+///
+void QXmppJingleMessageInitiationElement::setDescription(std::optional<QXmppJingleDescription> description)
+{
+ d->description = description;
+}
+
+///
+/// Returns the Jingle Message Initiation element reason.
+///
+std::optional<QXmppJingleReason> QXmppJingleMessageInitiationElement::reason() const
+{
+ return d->reason;
+}
+
+///
+/// Sets the Jingle Message Initiation element reason.
+///
+void QXmppJingleMessageInitiationElement::setReason(std::optional<QXmppJingleReason> reason)
+{
+ d->reason = reason;
+
+ if (d->reason) {
+ d->reason->setNamespaceUri(ns_jingle);
+ }
+}
+
+///
+/// Returns true if the Jingle Message Initiation element contains a <tie-break/> tag.
+///
+bool QXmppJingleMessageInitiationElement::containsTieBreak() const
+{
+ return d->containsTieBreak;
+}
+
+///
+/// Sets if the Jingle Message Initiation element contains a <tie-break/> tag.
+///
+void QXmppJingleMessageInitiationElement::setContainsTieBreak(bool containsTieBreak)
+{
+ d->containsTieBreak = containsTieBreak;
+}
+
+///
+/// Returns the Jingle Message Initiation element ID migrated to if the Jingle is being migrated
+/// to a different device.
+///
+QString QXmppJingleMessageInitiationElement::migratedTo() const
+{
+ return d->migratedTo;
+}
+
+///
+/// Sets the Jingle Message Initiation element ID migrated to if the Jingle is being migrated
+/// to a different device.
+///
+void QXmppJingleMessageInitiationElement::setMigratedTo(const QString &migratedTo)
+{
+ d->migratedTo = migratedTo;
+}
+
+/// \cond
+void QXmppJingleMessageInitiationElement::parse(const QDomElement &element)
+{
+ d->type = stringToJmiElementType(element.nodeName());
+
+ if (d->type == Type::None) {
+ return;
+ }
+
+ d->id = element.attribute(QStringLiteral("id"));
+
+ // Type::Proceed and Type::Ringing don't need any parsing aside of the id.
+ switch (d->type) {
+ case Type::Propose: {
+ if (const auto &descriptionElement = element.firstChildElement("description"); !descriptionElement.isNull()) {
+ d->description = QXmppJingleDescription();
+ d->description->parse(descriptionElement);
+ }
+
+ break;
+ }
+ case Type::Reject:
+ case Type::Retract:
+ d->containsTieBreak = !element.firstChildElement("tie-break").isNull();
+
+ if (const auto &reasonElement = element.firstChildElement("reason"); !reasonElement.isNull()) {
+ d->reason = QXmppJingleReason();
+ d->reason->parse(reasonElement);
+ }
+
+ break;
+ case Type::Finish:
+ if (const auto &reasonElement = element.firstChildElement("reason"); !reasonElement.isNull()) {
+ d->reason = QXmppJingleReason();
+ d->reason->parse(reasonElement);
+ }
+
+ if (const auto &migratedToElement = element.firstChildElement("migrated"); !migratedToElement.isNull()) {
+ d->migratedTo = migratedToElement.attribute("to");
+ }
+
+ break;
+ default:
+ break;
+ }
+}
+
+void QXmppJingleMessageInitiationElement::toXml(QXmlStreamWriter *writer) const
+{
+ writer->writeStartElement(jmiElementTypeToString(d->type));
+ writer->writeDefaultNamespace(ns_jingle_message_initiation);
+
+ helperToXmlAddAttribute(writer, QStringLiteral("id"), d->id);
+
+ if (d->description) {
+ d->description->toXml(writer);
+ }
+
+ if (d->reason) {
+ d->reason->toXml(writer);
+ }
+
+ if (d->containsTieBreak) {
+ writer->writeEmptyElement(QStringLiteral("tie-break"));
+ }
+
+ if (!d->migratedTo.isEmpty()) {
+ writer->writeEmptyElement(QStringLiteral("migrated"));
+ helperToXmlAddAttribute(writer, QStringLiteral("to"), d->migratedTo);
+ }
+
+ writer->writeEndElement();
+}
+/// \endcond
+
+QXMPP_PRIVATE_DEFINE_RULE_OF_SIX(QXmppJingleMessageInitiationElement)
+
+///
+/// Returns true if passed QDomElement is a Jingle Message Initiation element
+///
+bool QXmppJingleMessageInitiationElement::isJingleMessageInitiationElement(const QDomElement &element)
+{
+ return (element.nodeName() == QStringLiteral("propose") || element.nodeName() == QStringLiteral("ringing") || element.nodeName() == QStringLiteral("proceed") || element.nodeName() == QStringLiteral("retract") || element.nodeName() == QStringLiteral("reject") || element.nodeName() == QStringLiteral("finish")) && element.hasAttribute(QStringLiteral("id")) && element.namespaceURI() == ns_jingle_message_initiation;
+}
+
+///
+/// Takes a Jingle Message Initiation element type and parses it to a string.
+///
+QString QXmppJingleMessageInitiationElement::jmiElementTypeToString(Type type) const
+{
+ switch (type) {
+ case Type::Propose:
+ return "propose";
+ case Type::Ringing:
+ return "ringing";
+ case Type::Proceed:
+ return "proceed";
+ case Type::Reject:
+ return "reject";
+ case Type::Retract:
+ return "retract";
+ case Type::Finish:
+ return "finish";
+ default:
+ return {};
+ }
+}
+
+///
+/// Takes a string and parses it to a Jingle Message Initiation element type.
+///
+QXmppJingleMessageInitiationElement::Type QXmppJingleMessageInitiationElement::stringToJmiElementType(const QString &typeStr) const
+{
+ if (typeStr == "propose") {
+ return Type::Propose;
+ } else if (typeStr == "ringing") {
+ return Type::Ringing;
+ } else if (typeStr == "proceed") {
+ return Type::Proceed;
+ } else if (typeStr == "reject") {
+ return Type::Reject;
+ } else if (typeStr == "retract") {
+ return Type::Retract;
+ } else if (typeStr == "finish") {
+ return Type::Finish;
+ }
+
+ return Type::None;
+}
diff --git a/src/base/QXmppJingleIq.h b/src/base/QXmppJingleIq.h
index 6589a5cb..1e425f4d 100644
--- a/src/base/QXmppJingleIq.h
+++ b/src/base/QXmppJingleIq.h
@@ -24,6 +24,7 @@ class QXmppJingleRtpEncryptionPrivate;
class QXmppJingleRtpFeedbackPropertyPrivate;
class QXmppJingleRtpHeaderExtensionPropertyPrivate;
class QXmppSdpParameterPrivate;
+class QXmppJingleMessageInitiationElementPrivate;
class QXMPP_EXPORT QXmppSdpParameter
{
@@ -595,6 +596,54 @@ private:
QSharedDataPointer<QXmppJingleIqPrivate> d;
};
-Q_DECLARE_METATYPE(QXmppJingleIq::Reason::RtpErrorCondition)
+class QXMPP_EXPORT QXmppJingleMessageInitiationElement
+{
+public:
+ enum class Type {
+ None,
+ Propose,
+ Ringing,
+ Proceed,
+ Reject,
+ Retract,
+ Finish
+ };
+
+ QXmppJingleMessageInitiationElement();
+ QXMPP_PRIVATE_DECLARE_RULE_OF_SIX(QXmppJingleMessageInitiationElement)
+
+ Type type() const;
+ void setType(Type type);
+
+ QString id() const;
+ void setId(const QString &id);
+
+ std::optional<QXmppJingleDescription> description() const;
+ void setDescription(std::optional<QXmppJingleDescription> description);
+
+ std::optional<QXmppJingleReason> reason() const;
+ void setReason(std::optional<QXmppJingleReason> reason);
+
+ bool containsTieBreak() const;
+ void setContainsTieBreak(bool containsTieBreak);
+
+ QString migratedTo() const;
+ void setMigratedTo(const QString &migratedTo);
+
+ /// \cond
+ void parse(const QDomElement &element);
+ void toXml(QXmlStreamWriter *writer) const;
+ /// \endcond
+
+ static bool isJingleMessageInitiationElement(const QDomElement &);
+
+private:
+ QString jmiElementTypeToString(Type type) const;
+ Type stringToJmiElementType(const QString &typeStr) const;
+
+ QSharedDataPointer<QXmppJingleMessageInitiationElementPrivate> d;
+};
+
+Q_DECLARE_METATYPE(QXmppJingleReason::RtpErrorCondition)
#endif
diff --git a/src/base/QXmppMessage.cpp b/src/base/QXmppMessage.cpp
index 9527f5ed..be6cd83e 100644
--- a/src/base/QXmppMessage.cpp
+++ b/src/base/QXmppMessage.cpp
@@ -2,6 +2,7 @@
// SPDX-FileCopyrightText: 2010 Jeremy Lainé <jeremy.laine@m4x.org>
// SPDX-FileCopyrightText: 2018 Linus Jahn <lnj@kaidan.im>
// SPDX-FileCopyrightText: 2021 Melvin Keskin <melvo@olomono.de>
+// SPDX-FileCopyrightText: 2023 Tibor Csötönyi <work@taibsu.de>
//
// SPDX-License-Identifier: LGPL-2.1-or-later
@@ -11,6 +12,7 @@
#include "QXmppConstants_p.h"
#include "QXmppFileShare.h"
#include "QXmppGlobal_p.h"
+#include "QXmppJingleData.h"
#include "QXmppMessageReaction.h"
#include "QXmppMixInvitation.h"
#ifdef BUILD_OMEMO
@@ -123,6 +125,9 @@ public:
// XEP-0334: Message Processing Hints
quint8 hints;
+ // XEP-0353: Jingle Message Initiation
+ std::optional<QXmppJingleMessageInitiationElement> jingleMessageInitiationElement;
+
// XEP-0359: Unique and Stable Stanza IDs
QString stanzaId;
QString stanzaIdBy;
@@ -872,6 +877,24 @@ void QXmppMessage::removeAllHints()
}
///
+/// Returns a Jingle Message Initiation element as defined in \xep{0353}: Jingle Message
+/// Initiation.
+///
+std::optional<QXmppJingleMessageInitiationElement> QXmppMessage::jingleMessageInitiationElement() const
+{
+ return d->jingleMessageInitiationElement;
+}
+
+///
+/// Sets a Jingle Message Initiation element as defined in \xep{0353}: Jingle Message
+/// Initiation.
+///
+void QXmppMessage::setJingleMessageInitiationElement(const std::optional<QXmppJingleMessageInitiationElement> &jingleMessageInitiationElement)
+{
+ d->jingleMessageInitiationElement = jingleMessageInitiationElement;
+}
+
+///
/// Returns the stanza ID of the message according to \xep{0359}: Unique and
/// Stable Stanza IDs.
///
@@ -1393,6 +1416,13 @@ bool QXmppMessage::parseExtension(const QDomElement &element, QXmpp::SceMode sce
}
return true;
}
+ // XEP-0353: Jingle Message Initiation
+ if (QXmppJingleMessageInitiationElement::isJingleMessageInitiationElement(element)) {
+ QXmppJingleMessageInitiationElement jingleMessageInitiationElement;
+ jingleMessageInitiationElement.parse(element);
+ d->jingleMessageInitiationElement = jingleMessageInitiationElement;
+ return true;
+ }
// XEP-0359: Unique and Stable Stanza IDs
if (checkElement(element, QStringLiteral("stanza-id"), ns_sid)) {
d->stanzaId = element.attribute(QStringLiteral("id"));
@@ -1811,6 +1841,11 @@ void QXmppMessage::serializeExtensions(QXmlStreamWriter *writer, QXmpp::SceMode
writer->writeEndElement();
}
+ // XEP-0353: Jingle Message Initiation
+ if (d->jingleMessageInitiationElement) {
+ d->jingleMessageInitiationElement->toXml(writer);
+ }
+
// XEP-0367: Message Attaching
if (!d->attachId.isEmpty()) {
writer->writeStartElement(QStringLiteral("attach-to"));
diff --git a/src/base/QXmppMessage.h b/src/base/QXmppMessage.h
index be9e9b96..cf6df18d 100644
--- a/src/base/QXmppMessage.h
+++ b/src/base/QXmppMessage.h
@@ -2,6 +2,7 @@
// SPDX-FileCopyrightText: 2010 Jeremy Lainé <jeremy.laine@m4x.org>
// SPDX-FileCopyrightText: 2018 Linus Jahn <lnj@kaidan.im>
// SPDX-FileCopyrightText: 2020 Melvin Keskin <melvo@olomono.de>
+// SPDX-FileCopyrightText: 2023 Tibor Csötönyi <work@taibsu.de>
//
// SPDX-License-Identifier: LGPL-2.1-or-later
@@ -18,6 +19,7 @@
class QXmppMessagePrivate;
class QXmppBitsOfBinaryDataList;
+class QXmppJingleMessageInitiationElement;
class QXmppMessageReaction;
class QXmppMixInvitation;
#ifdef BUILD_OMEMO
@@ -205,6 +207,10 @@ public:
void removeHint(const Hint hint);
void removeAllHints();
+ // XEP-0353: Jingle Message Initiation
+ std::optional<QXmppJingleMessageInitiationElement> jingleMessageInitiationElement() const;
+ void setJingleMessageInitiationElement(const std::optional<QXmppJingleMessageInitiationElement> &jingleMessageInitiationElement);
+
// XEP-0359: Unique and Stable Stanza IDs
QString stanzaId() const;
void setStanzaId(const QString &id);