diff options
| author | Jeremy Lainé <jeremy.laine@m4x.org> | 2015-08-27 15:27:02 +0200 |
|---|---|---|
| committer | Jeremy Lainé <jeremy.laine@m4x.org> | 2015-08-27 15:35:12 +0200 |
| commit | a100a8b3cf20c7dc029416e4471a11fea7c51599 (patch) | |
| tree | 3e9324700c45d9f36f6f1f713214ee199bb04314 | |
| parent | e1f1fa9ae899d74a22fd16ea14e604a4befdc3b7 (diff) | |
| download | qxmpp-a100a8b3cf20c7dc029416e4471a11fea7c51599.tar.gz | |
add method to generate SDP from QXmppJingleIq::Content
| -rw-r--r-- | src/base/QXmppJingleIq.cpp | 77 | ||||
| -rw-r--r-- | src/base/QXmppJingleIq.h | 1 | ||||
| -rw-r--r-- | tests/qxmppjingleiq/tst_qxmppjingleiq.cpp | 20 |
3 files changed, 98 insertions, 0 deletions
diff --git a/src/base/QXmppJingleIq.cpp b/src/base/QXmppJingleIq.cpp index 43241db9..17dbfb9f 100644 --- a/src/base/QXmppJingleIq.cpp +++ b/src/base/QXmppJingleIq.cpp @@ -21,12 +21,16 @@ * */ +#include <QDate> +#include <QDateTime> #include <QDomElement> #include "QXmppConstants.h" #include "QXmppJingleIq.h" #include "QXmppUtils.h" +static const int RTP_COMPONENT = 1; + static const char* ns_jingle_rtp_info = "urn:xmpp:jingle:apps:rtp:info:1"; static const char* jingle_actions[] = { @@ -68,6 +72,27 @@ static const char* jingle_reasons[] = { "unsupported-transports", }; +static QString addressToSdp(const QHostAddress &host) +{ + return QString("IN %1 %2").arg( + host.protocol() == QAbstractSocket::IPv6Protocol ? "IP6" : "IP4", + host.toString()); +} + +static QString candidateToSdp(const QXmppJingleCandidate &candidate) +{ + return QString("candidate:%1 %2 %3 %4 %5 %6 typ %7 generation %8").arg( + candidate.foundation(), + QString::number(candidate.component()), + candidate.protocol(), + QString::number(candidate.priority()), + candidate.host().toString(), + QString::number(candidate.port()), + "host", + QString::number(candidate.generation()) + ); +} + QXmppJingleIq::Content::Content() : m_descriptionSsrc(0) { @@ -208,6 +233,58 @@ void QXmppJingleIq::Content::parse(const QDomElement &element) } } +QString QXmppJingleIq::Content::toSdp() const +{ + const quint32 ntpSeconds = QDateTime(QDate(1900, 1, 1)).secsTo(QDateTime::currentDateTime()); + + // get default candidate + QHostAddress localRtpAddress = QHostAddress::Any; + quint16 localRtpPort = 0; + foreach (const QXmppJingleCandidate &candidate, m_transportCandidates) { + if (candidate.component() == RTP_COMPONENT) { + localRtpAddress = candidate.host(); + localRtpPort = candidate.port(); + break; + } + } + + QStringList sdp; + sdp << "v=0"; + sdp << QString("o=- %1 %2 %3").arg( + QString::number(ntpSeconds), + QString::number(ntpSeconds), + addressToSdp(QHostAddress::Any) + ); + sdp << "s=-"; + sdp << "t=0 0"; + + // media + QString payloads; + QStringList attrs; + foreach (const QXmppJinglePayloadType &payload, m_payloadTypes) { + payloads += " " + QString::number(payload.id()); + QString rtpmap = QString::number(payload.id()) + " " + payload.name() + "/" + QString::number(payload.clockrate()); + if (payload.channels() > 1) + rtpmap += "/" + QString::number(payload.channels()); + attrs << "a=rtpmap:" + rtpmap; + if (payload.name() == "telephone-event") + attrs << "a=fmtp:" + QByteArray::number(payload.id()) + " 0-15"; + } + sdp << QString("m=%1 %2 RTP/AVP%3").arg(m_descriptionMedia, QString::number(localRtpPort), payloads); + sdp << QString("c=%1").arg(addressToSdp(localRtpAddress)); + sdp += attrs; + + // transport + foreach (const QXmppJingleCandidate &candidate, m_transportCandidates) + sdp << QString("a=%1").arg(candidateToSdp(candidate)); + if (!m_transportUser.isEmpty()) + sdp << QString("a=ice-ufrag:%1").arg(m_transportUser); + if (!m_transportPassword.isEmpty()) + sdp << QString("a=ice-pwd:%1").arg(m_transportPassword); + + return sdp.join("\r\n") + "\r\n"; +} + void QXmppJingleIq::Content::toXml(QXmlStreamWriter *writer) const { if (m_creator.isEmpty() || m_name.isEmpty()) diff --git a/src/base/QXmppJingleIq.h b/src/base/QXmppJingleIq.h index d1a43c37..b0854495 100644 --- a/src/base/QXmppJingleIq.h +++ b/src/base/QXmppJingleIq.h @@ -217,6 +217,7 @@ public: /// \cond void parse(const QDomElement &element); + QString toSdp() const; void toXml(QXmlStreamWriter *writer) const; /// \endcond diff --git a/tests/qxmppjingleiq/tst_qxmppjingleiq.cpp b/tests/qxmppjingleiq/tst_qxmppjingleiq.cpp index 060f3340..f73f32e2 100644 --- a/tests/qxmppjingleiq/tst_qxmppjingleiq.cpp +++ b/tests/qxmppjingleiq/tst_qxmppjingleiq.cpp @@ -69,6 +69,24 @@ void tst_QXmppJingleIq::testCandidate() void tst_QXmppJingleIq::testRtpSession() { + const QString sdp( + "v=0\r\n" + "o=- NTPSTAMP NTPSTAMP IN IP4 0.0.0.0\r\n" + "s=-\r\n" + "t=0 0\r\n" + "m=audio 8998 RTP/AVP 96 97 18 0 103 98\r\n" + "c=IN IP4 10.0.1.1\r\n" + "a=rtpmap:96 speex/16000\r\n" + "a=rtpmap:97 speex/8000\r\n" + "a=rtpmap:18 G729/0\r\n" + "a=rtpmap:0 PCMU/0\r\n" + "a=rtpmap:103 L16/16000/2\r\n" + "a=rtpmap:98 x-ISAC/8000\r\n" + "a=candidate:1 1 udp 2130706431 10.0.1.1 8998 typ host generation 0\r\n" + "a=candidate:2 1 udp 1694498815 192.0.2.3 45664 typ host generation 0\r\n" + "a=ice-ufrag:8hhy\r\n" + "a=ice-pwd:asd88fgpdd777uzjYhagZg\r\n"); + const QByteArray xml( "<iq" " id=\"ih28sx61\"" @@ -126,6 +144,8 @@ void tst_QXmppJingleIq::testRtpSession() QCOMPARE(session.reason().text(), QString()); QCOMPARE(session.reason().type(), QXmppJingleIq::Reason::None); serializePacket(session, xml); + + QCOMPARE(session.content().toSdp().replace(QRegExp("o=- [0-9]+ [0-9]+"), "o=- NTPSTAMP NTPSTAMP"), sdp); } void tst_QXmppJingleIq::testSession() |
