aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/base/QXmppJingleIq.cpp38
-rw-r--r--src/base/QXmppJingleIq.h6
-rw-r--r--src/client/QXmppCallManager.cpp136
3 files changed, 105 insertions, 75 deletions
diff --git a/src/base/QXmppJingleIq.cpp b/src/base/QXmppJingleIq.cpp
index 6d2304f1..fa958490 100644
--- a/src/base/QXmppJingleIq.cpp
+++ b/src/base/QXmppJingleIq.cpp
@@ -267,6 +267,12 @@ QList<QXmppJingleCandidate> QXmppJingleIq::Content::transportCandidates() const
return d->transportCandidates;
}
+void QXmppJingleIq::Content::setTransportCandidates(const QList<QXmppJingleCandidate> &candidates)
+{
+ d->transportType = candidates.isEmpty() ? QString() : ns_jingle_ice_udp;
+ d->transportCandidates = candidates;
+}
+
QString QXmppJingleIq::Content::transportUser() const
{
return d->transportUser;
@@ -662,7 +668,7 @@ public:
QString responder;
QString sid;
- QXmppJingleIq::Content content;
+ QList<QXmppJingleIq::Content> contents;
QXmppJingleIq::Reason reason;
bool ringing;
};
@@ -705,18 +711,25 @@ void QXmppJingleIq::setAction(QXmppJingleIq::Action action)
d->action = action;
}
-/// Returns a reference to the IQ's content element.
+// Adds an element to the IQ's content elements.
+
+void QXmppJingleIq::addContent(const QXmppJingleIq::Content &content)
+{
+ d->contents << content;
+}
+
+/// Returns the IQ's content elements.
-QXmppJingleIq::Content& QXmppJingleIq::content()
+QList<QXmppJingleIq::Content> QXmppJingleIq::contents() const
{
- return d->content;
+ return d->contents;
}
-/// Returns a const reference to the IQ's content element.
+/// Sets the IQ's content elements.
-const QXmppJingleIq::Content& QXmppJingleIq::content() const
+void QXmppJingleIq::setContents(const QList<QXmppJingleIq::Content> &contents)
{
- return d->content;
+ d->contents = contents;
}
/// Returns the session initiator.
@@ -819,8 +832,14 @@ void QXmppJingleIq::parseElementFromChild(const QDomElement &element)
d->sid = jingleElement.attribute("sid");
// content
+ d->contents.clear();
QDomElement contentElement = jingleElement.firstChildElement("content");
- d->content.parse(contentElement);
+ while (!contentElement.isNull()) {
+ QXmppJingleIq::Content content;
+ content.parse(contentElement);
+ addContent(content);
+ contentElement = contentElement.nextSiblingElement("content");
+ }
QDomElement reasonElement = jingleElement.firstChildElement("reason");
d->reason.parse(reasonElement);
@@ -837,7 +856,8 @@ void QXmppJingleIq::toXmlElementFromChild(QXmlStreamWriter *writer) const
helperToXmlAddAttribute(writer, "initiator", d->initiator);
helperToXmlAddAttribute(writer, "responder", d->responder);
helperToXmlAddAttribute(writer, "sid", d->sid);
- d->content.toXml(writer);
+ foreach (const QXmppJingleIq::Content &content, d->contents)
+ content.toXml(writer);
d->reason.toXml(writer);
// ringing
diff --git a/src/base/QXmppJingleIq.h b/src/base/QXmppJingleIq.h
index 5156646d..7e21b054 100644
--- a/src/base/QXmppJingleIq.h
+++ b/src/base/QXmppJingleIq.h
@@ -213,6 +213,7 @@ public:
void addTransportCandidate(const QXmppJingleCandidate &candidate);
QList<QXmppJingleCandidate> transportCandidates() const;
+ void setTransportCandidates(const QList<QXmppJingleCandidate> &candidates);
QString transportUser() const;
void setTransportUser(const QString &user);
@@ -296,8 +297,9 @@ public:
Action action() const;
void setAction(Action action);
- Content& content();
- const Content& content() const;
+ void addContent(const Content &content);
+ QList<Content> contents() const;
+ void setContents(const QList<Content> &contents);
QString initiator() const;
void setInitiator(const QString &initiator);
diff --git a/src/client/QXmppCallManager.cpp b/src/client/QXmppCallManager.cpp
index a278eef6..7792dad8 100644
--- a/src/client/QXmppCallManager.cpp
+++ b/src/client/QXmppCallManager.cpp
@@ -171,6 +171,8 @@ bool QXmppCallPrivate::handleTransport(QXmppCallPrivate::Stream *stream, const Q
void QXmppCallPrivate::handleRequest(const QXmppJingleIq &iq)
{
+ const QXmppJingleIq::Content content = iq.contents().isEmpty() ? QXmppJingleIq::Content() : iq.contents().first();
+
if (iq.action() == QXmppJingleIq::SessionAccept) {
if (direction == QXmppCall::IncomingDirection) {
@@ -182,10 +184,10 @@ void QXmppCallPrivate::handleRequest(const QXmppJingleIq &iq)
sendAck(iq);
// check content description and transport
- QXmppCallPrivate::Stream *stream = findStreamByName(iq.content().name());
+ QXmppCallPrivate::Stream *stream = findStreamByName(content.name());
if (!stream ||
- !handleDescription(stream, iq.content()) ||
- !handleTransport(stream, iq.content())) {
+ !handleDescription(stream, content) ||
+ !handleTransport(stream, content)) {
// terminate call
terminate(QXmppJingleIq::Reason::FailedApplication);
@@ -215,10 +217,10 @@ void QXmppCallPrivate::handleRequest(const QXmppJingleIq &iq)
sendAck(iq);
// check content description and transport
- QXmppCallPrivate::Stream *stream = findStreamByName(iq.content().name());
+ QXmppCallPrivate::Stream *stream = findStreamByName(content.name());
if (!stream ||
- !handleDescription(stream, iq.content()) ||
- !handleTransport(stream, iq.content())) {
+ !handleDescription(stream, content) ||
+ !handleTransport(stream, content)) {
// FIXME: what action?
return;
@@ -230,20 +232,20 @@ void QXmppCallPrivate::handleRequest(const QXmppJingleIq &iq)
sendAck(iq);
// check media stream does not exist yet
- QXmppCallPrivate::Stream *stream = findStreamByName(iq.content().name());
+ QXmppCallPrivate::Stream *stream = findStreamByName(content.name());
if (stream)
return;
// create media stream
- stream = createStream(iq.content().descriptionMedia());
+ stream = createStream(content.descriptionMedia());
if (!stream)
return;
- stream->creator = iq.content().creator();
- stream->name = iq.content().name();
+ stream->creator = content.creator();
+ stream->name = content.name();
// check content description
- if (!handleDescription(stream, iq.content()) ||
- !handleTransport(stream, iq.content())) {
+ if (!handleDescription(stream, content) ||
+ !handleTransport(stream, content)) {
QXmppJingleIq iq;
iq.setTo(q->jid());
@@ -263,21 +265,22 @@ void QXmppCallPrivate::handleRequest(const QXmppJingleIq &iq)
iq.setType(QXmppIq::Set);
iq.setAction(QXmppJingleIq::ContentAccept);
iq.setSid(q->sid());
- iq.content().setCreator(stream->creator);
- iq.content().setName(stream->name);
+
+ QXmppJingleIq::Content responseContent;
+ responseContent.setCreator(stream->creator);
+ responseContent.setName(stream->name);
// description
- iq.content().setDescriptionMedia(stream->media);
- iq.content().setDescriptionSsrc(stream->channel->localSsrc());
- foreach (const QXmppJinglePayloadType &payload, stream->channel->localPayloadTypes())
- iq.content().addPayloadType(payload);
+ responseContent.setDescriptionMedia(stream->media);
+ responseContent.setDescriptionSsrc(stream->channel->localSsrc());
+ responseContent.setPayloadTypes(stream->channel->localPayloadTypes());
// transport
- iq.content().setTransportUser(stream->connection->localUser());
- iq.content().setTransportPassword(stream->connection->localPassword());
- foreach (const QXmppJingleCandidate &candidate, stream->connection->localCandidates())
- iq.content().addTransportCandidate(candidate);
+ responseContent.setTransportUser(stream->connection->localUser());
+ responseContent.setTransportPassword(stream->connection->localPassword());
+ responseContent.setTransportCandidates(stream->connection->localCandidates());
+ iq.addContent(responseContent);
sendRequest(iq);
} else if (iq.action() == QXmppJingleIq::TransportInfo) {
@@ -286,9 +289,9 @@ void QXmppCallPrivate::handleRequest(const QXmppJingleIq &iq)
sendAck(iq);
// check content transport
- QXmppCallPrivate::Stream *stream = findStreamByName(iq.content().name());
+ QXmppCallPrivate::Stream *stream = findStreamByName(content.name());
if (!stream ||
- !handleTransport(stream, iq.content())) {
+ !handleTransport(stream, content)) {
// FIXME: what action?
return;
}
@@ -387,21 +390,22 @@ bool QXmppCallPrivate::sendInvite()
// create audio stream
QXmppCallPrivate::Stream *stream = findStreamByMedia(AUDIO_MEDIA);
Q_ASSERT(stream);
- iq.content().setCreator(stream->creator);
- iq.content().setName(stream->name);
- iq.content().setSenders("both");
+
+ QXmppJingleIq::Content content;
+ content.setCreator(stream->creator);
+ content.setName(stream->name);
+ content.setSenders("both");
// description
- iq.content().setDescriptionMedia(stream->media);
- foreach (const QXmppJinglePayloadType &payload, stream->channel->localPayloadTypes())
- iq.content().addPayloadType(payload);
+ content.setDescriptionMedia(stream->media);
+ content.setPayloadTypes(stream->channel->localPayloadTypes());
// transport
- iq.content().setTransportUser(stream->connection->localUser());
- iq.content().setTransportPassword(stream->connection->localPassword());
- foreach (const QXmppJingleCandidate &candidate, stream->connection->localCandidates())
- iq.content().addTransportCandidate(candidate);
+ content.setTransportUser(stream->connection->localUser());
+ content.setTransportPassword(stream->connection->localPassword());
+ content.setTransportCandidates(stream->connection->localCandidates());
+ iq.addContent(content);
return sendRequest(iq);
}
@@ -490,20 +494,21 @@ void QXmppCall::accept()
iq.setAction(QXmppJingleIq::SessionAccept);
iq.setResponder(d->ownJid);
iq.setSid(d->sid);
- iq.content().setCreator(stream->creator);
- iq.content().setName(stream->name);
+
+ QXmppJingleIq::Content content;
+ content.setCreator(stream->creator);
+ content.setName(stream->name);
// description
- iq.content().setDescriptionMedia(stream->media);
- foreach (const QXmppJinglePayloadType &payload, stream->channel->localPayloadTypes())
- iq.content().addPayloadType(payload);
+ content.setDescriptionMedia(stream->media);
+ content.setPayloadTypes(stream->channel->localPayloadTypes());
// transport
- iq.content().setTransportUser(stream->connection->localUser());
- iq.content().setTransportPassword(stream->connection->localPassword());
- foreach (const QXmppJingleCandidate &candidate, stream->connection->localCandidates())
- iq.content().addTransportCandidate(candidate);
+ content.setTransportUser(stream->connection->localUser());
+ content.setTransportPassword(stream->connection->localPassword());
+ content.setTransportCandidates(stream->connection->localCandidates());
+ iq.addContent(content);
d->sendRequest(iq);
// notify user
@@ -606,15 +611,16 @@ void QXmppCall::localCandidatesChanged()
iq.setAction(QXmppJingleIq::TransportInfo);
iq.setSid(d->sid);
- iq.content().setCreator(stream->creator);
- iq.content().setName(stream->name);
+ QXmppJingleIq::Content content;
+ content.setCreator(stream->creator);
+ content.setName(stream->name);
// transport
- iq.content().setTransportUser(stream->connection->localUser());
- iq.content().setTransportPassword(stream->connection->localPassword());
- foreach (const QXmppJingleCandidate &candidate, stream->connection->localCandidates())
- iq.content().addTransportCandidate(candidate);
+ content.setTransportUser(stream->connection->localUser());
+ content.setTransportPassword(stream->connection->localPassword());
+ content.setTransportCandidates(stream->connection->localCandidates());
+ iq.addContent(content);
d->sendRequest(iq);
}
@@ -700,21 +706,22 @@ void QXmppCall::startVideo()
iq.setType(QXmppIq::Set);
iq.setAction(QXmppJingleIq::ContentAdd);
iq.setSid(d->sid);
- iq.content().setCreator(stream->creator);
- iq.content().setName(stream->name);
- iq.content().setSenders("both");
+
+ QXmppJingleIq::Content content;
+ content.setCreator(stream->creator);
+ content.setName(stream->name);
+ content.setSenders("both");
// description
- iq.content().setDescriptionMedia(stream->media);
- foreach (const QXmppJinglePayloadType &payload, stream->channel->localPayloadTypes())
- iq.content().addPayloadType(payload);
+ content.setDescriptionMedia(stream->media);
+ content.setPayloadTypes(stream->channel->localPayloadTypes());
// transport
- iq.content().setTransportUser(stream->connection->localUser());
- iq.content().setTransportPassword(stream->connection->localPassword());
- foreach (const QXmppJingleCandidate &candidate, stream->connection->localCandidates())
- iq.content().addTransportCandidate(candidate);
+ content.setTransportUser(stream->connection->localUser());
+ content.setTransportPassword(stream->connection->localPassword());
+ content.setTransportCandidates(stream->connection->localCandidates());
+ iq.addContent(content);
d->sendRequest(iq);
}
@@ -939,18 +946,19 @@ void QXmppCallManager::_q_jingleIqReceived(const QXmppJingleIq &iq)
QXmppCall *call = new QXmppCall(iq.from(), QXmppCall::IncomingDirection, this);
call->d->sid = iq.sid();
- QXmppCallPrivate::Stream *stream = call->d->findStreamByMedia(iq.content().descriptionMedia());
+ const QXmppJingleIq::Content content = iq.contents().isEmpty() ? QXmppJingleIq::Content() : iq.contents().first();
+ QXmppCallPrivate::Stream *stream = call->d->findStreamByMedia(content.descriptionMedia());
if (!stream)
return;
- stream->creator = iq.content().creator();
- stream->name = iq.content().name();
+ stream->creator = content.creator();
+ stream->name = content.name();
// send ack
call->d->sendAck(iq);
// check content description and transport
- if (!call->d->handleDescription(stream, iq.content()) ||
- !call->d->handleTransport(stream, iq.content())) {
+ if (!call->d->handleDescription(stream, content) ||
+ !call->d->handleTransport(stream, content)) {
// terminate call
call->d->terminate(QXmppJingleIq::Reason::FailedApplication);