From f762f730b5adf769a55434e7786b56f3d092b662 Mon Sep 17 00:00:00 2001 From: Melvin Keskin Date: Wed, 21 Sep 2022 14:14:43 +0200 Subject: Implement XEP-0167: Jingle RTP Sessions multiplexing --- doc/doap.xml | 4 ++-- src/base/QXmppJingleIq.cpp | 33 +++++++++++++++++++++++++++++++ src/base/QXmppJingleIq.h | 3 +++ tests/qxmppjingleiq/tst_qxmppjingleiq.cpp | 5 +++++ 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 partial - 1.1 + 1.2 0.2 - 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 + '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 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 payloadTypes() const; void setPayloadTypes(const QList &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( "" "" + "" "" "" "" @@ -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)); -- cgit v1.2.3