aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMelvin Keskin <melvo@olomono.de>2022-09-21 14:14:43 +0200
committerLinus Jahn <lnj@kaidan.im>2022-09-25 14:14:26 +0200
commitf762f730b5adf769a55434e7786b56f3d092b662 (patch)
treecde1b296b312140d23ca4e96bc6a7f4a95006ffa
parent3bd90b240c2692f6654fb0967556caeacf478f5a (diff)
downloadqxmpp-f762f730b5adf769a55434e7786b56f3d092b662.tar.gz
Implement XEP-0167: Jingle RTP Sessions multiplexing
-rw-r--r--doc/doap.xml4
-rw-r--r--src/base/QXmppJingleIq.cpp33
-rw-r--r--src/base/QXmppJingleIq.h3
-rw-r--r--tests/qxmppjingleiq/tst_qxmppjingleiq.cpp5
4 files changed, 43 insertions, 2 deletions
diff --git a/doc/doap.xml b/doc/doap.xml
index 4733e86a..95b07a11 100644
--- a/doc/doap.xml
+++ b/doc/doap.xml
@@ -281,9 +281,9 @@ SPDX-License-Identifier: CC0-1.0
<xmpp:SupportedXep>
<xmpp:xep rdf:resource='https://xmpp.org/extensions/xep-0167.html'/>
<xmpp:status>partial</xmpp:status>
- <xmpp:version>1.1</xmpp:version>
+ <xmpp:version>1.2</xmpp:version>
<xmpp:since>0.2</xmpp:since>
- <xmpp:note>Missing 'rtcp-mux' of https://xmpp.org/extensions/xep-0167.html#format, 'encryption' of https://xmpp.org/extensions/xep-0167.html#srtp, https://xmpp.org/extensions/xep-0167.html#info-active, https://xmpp.org/extensions/xep-0167.html#info-hold, https://xmpp.org/extensions/xep-0167.html#info-mute</xmpp:note>
+ <xmpp:note>'rtcp-mux' of https://xmpp.org/extensions/xep-0167.html#format since 1.5, 'encryption' of https://xmpp.org/extensions/xep-0167.html#srtp, https://xmpp.org/extensions/xep-0167.html#info-active, https://xmpp.org/extensions/xep-0167.html#info-hold, https://xmpp.org/extensions/xep-0167.html#info-mute</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
diff --git a/src/base/QXmppJingleIq.cpp b/src/base/QXmppJingleIq.cpp
index 9d883860..9a365929 100644
--- a/src/base/QXmppJingleIq.cpp
+++ b/src/base/QXmppJingleIq.cpp
@@ -134,6 +134,8 @@ public:
QString descriptionMedia;
quint32 descriptionSsrc;
QString descriptionType;
+ bool isRtpMultiplexingSupported = false;
+
QString transportType;
QString transportUser;
QString transportPassword;
@@ -230,6 +232,33 @@ void QXmppJingleIq::Content::setDescriptionSsrc(quint32 ssrc)
d->descriptionSsrc = ssrc;
}
+///
+/// Returns whether multiplexing of RTP data and control packets on a single port is supported as
+/// specified by \xep{0167, Jingle RTP Sessions} and RFC 5761.
+///
+/// \return whether multiplexing of RTP data and control packets is supported
+///
+/// \since QXmpp 1.5
+///
+bool QXmppJingleIq::Content::isRtpMultiplexingSupported() const
+{
+ return d->isRtpMultiplexingSupported;
+}
+
+///
+/// Sets whether multiplexing of RTP data and control packets on a single port is supported as
+/// specified by \xep{0167, Jingle RTP Sessions} and RFC 5761.
+///
+/// \param isRtpMultiplexingSupported whether multiplexing of RTP data and control packets is
+/// supported
+///
+/// \since QXmpp 1.5
+///
+void QXmppJingleIq::Content::setRtpMultiplexingSupported(bool isRtpMultiplexingSupported)
+{
+ d->isRtpMultiplexingSupported = isRtpMultiplexingSupported;
+}
+
void QXmppJingleIq::Content::addPayloadType(const QXmppJinglePayloadType &payload)
{
d->descriptionType = ns_jingle_rtp;
@@ -374,6 +403,7 @@ void QXmppJingleIq::Content::parse(const QDomElement &element)
d->descriptionType = descriptionElement.namespaceURI();
d->descriptionMedia = descriptionElement.attribute(QStringLiteral("media"));
d->descriptionSsrc = descriptionElement.attribute(QStringLiteral("ssrc")).toULong();
+ d->isRtpMultiplexingSupported = !descriptionElement.firstChildElement(QStringLiteral("rtcp-mux")).isNull();
QDomElement child = descriptionElement.firstChildElement(QStringLiteral("payload-type"));
while (!child.isNull()) {
QXmppJinglePayloadType payload;
@@ -424,6 +454,9 @@ void QXmppJingleIq::Content::toXml(QXmlStreamWriter *writer) const
if (d->descriptionSsrc) {
writer->writeAttribute(QStringLiteral("ssrc"), QString::number(d->descriptionSsrc));
}
+ if (d->isRtpMultiplexingSupported) {
+ writer->writeEmptyElement(QStringLiteral("rtcp-mux"));
+ }
for (const auto &payload : d->payloadTypes) {
payload.toXml(writer);
}
diff --git a/src/base/QXmppJingleIq.h b/src/base/QXmppJingleIq.h
index be915787..cbb711d6 100644
--- a/src/base/QXmppJingleIq.h
+++ b/src/base/QXmppJingleIq.h
@@ -189,6 +189,9 @@ public:
quint32 descriptionSsrc() const;
void setDescriptionSsrc(quint32 ssrc);
+ bool isRtpMultiplexingSupported() const;
+ void setRtpMultiplexingSupported(bool isRtpMultiplexingSupported);
+
void addPayloadType(const QXmppJinglePayloadType &payload);
QList<QXmppJinglePayloadType> payloadTypes() const;
void setPayloadTypes(const QList<QXmppJinglePayloadType> &payloadTypes);
diff --git a/tests/qxmppjingleiq/tst_qxmppjingleiq.cpp b/tests/qxmppjingleiq/tst_qxmppjingleiq.cpp
index 4f207ca2..8f2e5ab0 100644
--- a/tests/qxmppjingleiq/tst_qxmppjingleiq.cpp
+++ b/tests/qxmppjingleiq/tst_qxmppjingleiq.cpp
@@ -60,6 +60,7 @@ void tst_QXmppJingleIq::testContent()
const QByteArray xml(
"<content creator=\"initiator\" name=\"voice\">"
"<description xmlns=\"urn:xmpp:jingle:apps:rtp:1\" media=\"audio\">"
+ "<rtcp-mux/>"
"<payload-type id=\"96\"/>"
"<payload-type id=\"97\"/>"
"</description>"
@@ -88,6 +89,7 @@ void tst_QXmppJingleIq::testContent()
QVERIFY(content1.name().isEmpty());
QVERIFY(content1.descriptionMedia().isEmpty());
QCOMPARE(content1.descriptionSsrc(), quint32(0));
+ QVERIFY(!content1.isRtpMultiplexingSupported());
QCOMPARE(content1.payloadTypes().size(), 0);
QVERIFY(content1.transportUser().isEmpty());
QVERIFY(content1.transportPassword().isEmpty());
@@ -98,6 +100,7 @@ void tst_QXmppJingleIq::testContent()
QCOMPARE(content1.name(), QStringLiteral("voice"));
QCOMPARE(content1.descriptionMedia(), QStringLiteral("audio"));
QCOMPARE(content1.descriptionSsrc(), quint32(0));
+ QVERIFY(content1.isRtpMultiplexingSupported());
QCOMPARE(content1.payloadTypes().size(), 2);
QCOMPARE(content1.payloadTypes().at(0).id(), quint8(96));
QCOMPARE(content1.payloadTypes().at(1).id(), quint8(97));
@@ -113,6 +116,7 @@ void tst_QXmppJingleIq::testContent()
content2.setName(QStringLiteral("voice"));
content2.setDescriptionMedia(QStringLiteral("audio"));
content2.setDescriptionSsrc(quint32(0));
+ content2.setRtpMultiplexingSupported(true);
QXmppJinglePayloadType payloadType1;
payloadType1.setId(quint8(96));
content2.setPayloadTypes({ payloadType1 });
@@ -132,6 +136,7 @@ void tst_QXmppJingleIq::testContent()
QCOMPARE(content2.name(), QStringLiteral("voice"));
QCOMPARE(content2.descriptionMedia(), QStringLiteral("audio"));
QCOMPARE(content2.descriptionSsrc(), quint32(0));
+ QVERIFY(content2.isRtpMultiplexingSupported());
QCOMPARE(content2.payloadTypes().size(), 2);
QCOMPARE(content2.payloadTypes().at(0).id(), quint8(96));
QCOMPARE(content2.payloadTypes().at(1).id(), quint8(97));