aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Lainé <jeremy.laine@m4x.org>2015-08-27 17:13:21 +0200
committerJeremy Lainé <jeremy.laine@m4x.org>2015-08-27 17:23:17 +0200
commit5f144d0f0a10e2f55de00f838bea43748a27d8ab (patch)
treea9f84273986ed10de1a4c4ff468ddf6020f69976
parent44cbba5d6538b998b5b5fbb4264d78ab135f669f (diff)
downloadqxmpp-5f144d0f0a10e2f55de00f838bea43748a27d8ab.tar.gz
parse SDP parameters
-rw-r--r--src/base/QXmppJingleIq.cpp40
-rw-r--r--tests/qxmppjingleiq/tst_qxmppjingleiq.cpp39
2 files changed, 77 insertions, 2 deletions
diff --git a/src/base/QXmppJingleIq.cpp b/src/base/QXmppJingleIq.cpp
index 3422734d..f2dd6a95 100644
--- a/src/base/QXmppJingleIq.cpp
+++ b/src/base/QXmppJingleIq.cpp
@@ -24,6 +24,7 @@
#include <QDate>
#include <QDateTime>
#include <QDomElement>
+#include <QRegExp>
#include "QXmppConstants.h"
#include "QXmppJingleIq.h"
@@ -318,6 +319,29 @@ bool QXmppJingleIq::Content::parseSdp(const QString &sdp)
return false;
}
addTransportCandidate(candidate);
+ } else if (attrName == "fmtp") {
+ int spIdx = attrValue.indexOf(' ');
+ if (spIdx == -1) {
+ qWarning() << "Could not parse payload parameters" << line;
+ return false;
+ }
+ const int id = attrValue.left(spIdx).toInt();
+ const QString paramStr = attrValue.mid(spIdx + 1);
+ for (int i = 0; i < payloads.size(); ++i) {
+ if (payloads[i].id() == id) {
+ QMap<QString, QString> params;
+ if (payloads[i].name() == "telephone-event") {
+ params.insert("events", paramStr);
+ } else {
+ foreach (const QString p, paramStr.split(QRegExp(";\\s*"))) {
+ QStringList bits = p.split('=');
+ if (bits.size() == 2)
+ params.insert(bits[0], bits[1]);
+ }
+ }
+ payloads[i].setParameters(params);
+ }
+ }
} else if (attrName == "rtpmap") {
// payload type map
const QStringList bits = attrValue.split(' ');
@@ -409,8 +433,20 @@ QString QXmppJingleIq::Content::toSdp() const
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";
+
+ // payload parameters
+ QStringList paramList;
+ const QMap<QString, QString> params = payload.parameters();
+ if (payload.name() == "telephone-event") {
+ if (params.contains("events"))
+ paramList << params.value("events");
+ } else {
+ QMap<QString, QString>::const_iterator i;
+ for (i = params.begin(); i != params.end(); ++i)
+ paramList << i.key() + "=" + i.value();
+ }
+ if (!paramList.isEmpty())
+ attrs << "a=fmtp:" + QByteArray::number(payload.id()) + " " + paramList.join("; ");
}
sdp << QString("m=%1 %2 RTP/AVP%3").arg(m_descriptionMedia, QString::number(localRtpPort), payloads);
sdp << QString("c=%1").arg(addressToSdp(localRtpAddress));
diff --git a/tests/qxmppjingleiq/tst_qxmppjingleiq.cpp b/tests/qxmppjingleiq/tst_qxmppjingleiq.cpp
index ad20e083..26b11c35 100644
--- a/tests/qxmppjingleiq/tst_qxmppjingleiq.cpp
+++ b/tests/qxmppjingleiq/tst_qxmppjingleiq.cpp
@@ -33,6 +33,7 @@ private slots:
void testCandidate();
void testRtpSession();
void testRtpSessionSdp();
+ void testRtpSessionSdpParameters();
void testSession();
void testTerminate();
void testAudioPayloadType();
@@ -211,6 +212,44 @@ void tst_QXmppJingleIq::testRtpSessionSdp()
QCOMPARE(content.toSdp().replace(QRegExp("o=- [0-9]+ [0-9]+"), "o=- NTPSTAMP NTPSTAMP"), sdp);
}
+void tst_QXmppJingleIq::testRtpSessionSdpParameters()
+{
+ 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 100\r\n"
+ "c=IN IP4 10.0.1.1\r\n"
+ "a=rtpmap:96 speex/16000\r\n"
+ "a=fmtp:96 cng=on; vbr=on\r\n"
+ "a=rtpmap:100 telephone-event/8000\r\n"
+ "a=fmtp:100 0-15,66,70\r\n"
+ "a=candidate:1 1 udp 2130706431 10.0.1.1 8998 typ host generation 0\r\n");
+
+ QXmppJingleIq::Content content;
+ QVERIFY(content.parseSdp(sdp));
+
+ QCOMPARE(content.descriptionMedia(), QLatin1String("audio"));
+ QCOMPARE(content.descriptionSsrc(), quint32(0));
+ QCOMPARE(content.payloadTypes().size(), 2);
+ QCOMPARE(content.payloadTypes()[0].id(), quint8(96));
+ QCOMPARE(content.payloadTypes()[0].parameters().value("vbr"), QLatin1String("on"));
+ QCOMPARE(content.payloadTypes()[0].parameters().value("cng"), QLatin1String("on"));
+ QCOMPARE(content.payloadTypes()[1].id(), quint8(100));
+ QCOMPARE(content.payloadTypes()[1].parameters().value("events"), QLatin1String("0-15,66,70"));
+ QCOMPARE(content.transportCandidates().size(), 1);
+ QCOMPARE(content.transportCandidates()[0].component(), 1);
+ QCOMPARE(content.transportCandidates()[0].foundation(), QLatin1String("1"));
+ QCOMPARE(content.transportCandidates()[0].host(), QHostAddress("10.0.1.1"));
+ QCOMPARE(content.transportCandidates()[0].port(), quint16(8998));
+ QCOMPARE(content.transportCandidates()[0].priority(), 2130706431);
+ QCOMPARE(content.transportCandidates()[0].protocol(), QLatin1String("udp"));
+ QCOMPARE(content.transportCandidates()[0].type(), QXmppJingleCandidate::HostType);
+
+ QCOMPARE(content.toSdp().replace(QRegExp("o=- [0-9]+ [0-9]+"), "o=- NTPSTAMP NTPSTAMP"), sdp);
+}
+
void tst_QXmppJingleIq::testSession()
{
const QByteArray xml(