aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/QXmppCallManager.cpp204
-rw-r--r--src/QXmppCallManager.h18
2 files changed, 125 insertions, 97 deletions
diff --git a/src/QXmppCallManager.cpp b/src/QXmppCallManager.cpp
index a7221251..399c7dcb 100644
--- a/src/QXmppCallManager.cpp
+++ b/src/QXmppCallManager.cpp
@@ -41,6 +41,9 @@ const int RTCP_COMPONENT = 2;
class QXmppCallPrivate
{
public:
+ QXmppCallPrivate(QXmppCall *qq);
+ void setState(QXmppCall::State state);
+
QXmppCall::Direction direction;
QString jid;
QString sid;
@@ -56,12 +59,29 @@ public:
// RTP
QXmppRtpChannel *audioChannel;
QList<QXmppJinglePayloadType> commonPayloadTypes;
+
+private:
+ QXmppCall *q;
};
+QXmppCallPrivate::QXmppCallPrivate(QXmppCall *qq)
+ : q(qq)
+{
+}
+
+void QXmppCallPrivate::setState(QXmppCall::State newState)
+{
+ if (state != newState)
+ {
+ state = newState;
+ emit q->stateChanged(state);
+ }
+}
+
QXmppCall::QXmppCall(const QString &jid, QXmppCall::Direction direction, QObject *parent)
- : QXmppLoggable(parent),
- d(new QXmppCallPrivate)
+ : QXmppLoggable(parent)
{
+ d = new QXmppCallPrivate(this);
d->direction = direction;
d->jid = jid;
d->contentCreator = QLatin1String("initiator");
@@ -105,7 +125,7 @@ QXmppCall::~QXmppCall()
void QXmppCall::accept()
{
if (d->direction == IncomingDirection && d->state == OfferState)
- setState(QXmppCall::ConnectingState);
+ d->setState(QXmppCall::ConnectingState);
}
/// Returns the RTP channel for the audio data.
@@ -156,7 +176,7 @@ QXmppCall::Direction QXmppCall::direction() const
void QXmppCall::hangup()
{
if (d->state != QXmppCall::FinishedState)
- setState(QXmppCall::DisconnectingState);
+ d->setState(QXmppCall::DisconnectingState);
}
/// Returns the remote party's JID.
@@ -167,24 +187,12 @@ QString QXmppCall::jid() const
return d->jid;
}
-void QXmppCall::setPayloadType(const QXmppJinglePayloadType &payloadType)
-{
- d->audioChannel->setPayloadType(payloadType);
- updateOpenMode();
-}
-
-void QXmppCall::addRemoteCandidates(const QList<QXmppJingleCandidate> &candidates)
-{
- foreach (const QXmppJingleCandidate &candidate, candidates)
- d->connection->addRemoteCandidate(candidate);
-}
-
void QXmppCall::updateOpenMode()
{
// determine mode
if (d->audioChannel->isOpen() && d->connection->isConnected() && d->state != ActiveState)
{
- setState(ActiveState);
+ d->setState(ActiveState);
emit connected();
}
}
@@ -214,23 +222,79 @@ QXmppCall::State QXmppCall::state() const
return d->state;
}
-void QXmppCall::setState(QXmppCall::State state)
+class QXmppCallManagerPrivate
{
- if (d->state != state)
- {
- d->state = state;
- emit stateChanged(d->state);
- }
+public:
+ QXmppCallManagerPrivate(QXmppCallManager *qq);
+ bool checkPayloadTypes(QXmppCall *call, const QList<QXmppJinglePayloadType> &remotePayloadTypes);
+ QXmppCall *findCall(const QString &sid) const;
+ QXmppCall *findCall(const QString &sid, QXmppCall::Direction direction) const;
+ bool sendAck(const QXmppJingleIq &iq);
+ bool sendRequest(QXmppCall *call, const QXmppJingleIq &iq);
+
+ QList<QXmppCall*> calls;
+
+private:
+ QXmppCallManager *q;
+};
+
+QXmppCallManagerPrivate::QXmppCallManagerPrivate(QXmppCallManager *qq)
+ : q(qq)
+{
+}
+
+QXmppCall *QXmppCallManagerPrivate::findCall(const QString &sid) const
+{
+ foreach (QXmppCall *call, calls)
+ if (call->sid() == sid)
+ return call;
+ return 0;
+}
+
+QXmppCall *QXmppCallManagerPrivate::findCall(const QString &sid, QXmppCall::Direction direction) const
+{
+ foreach (QXmppCall *call, calls)
+ if (call->sid() == sid && call->direction() == direction)
+ return call;
+ return 0;
+}
+
+/// Sends an acknowledgement for a Jingle IQ.
+///
+
+bool QXmppCallManagerPrivate::sendAck(const QXmppJingleIq &iq)
+{
+ QXmppIq ack;
+ ack.setId(iq.id());
+ ack.setTo(iq.from());
+ ack.setType(QXmppIq::Result);
+ return q->client()->sendPacket(ack);
+}
+
+/// Sends a Jingle IQ and adds it to outstanding requests.
+///
+
+bool QXmppCallManagerPrivate::sendRequest(QXmppCall *call, const QXmppJingleIq &iq)
+{
+ call->d->requests << iq;
+ return q->client()->sendPacket(iq);
}
QXmppCallManager::QXmppCallManager(QXmppClient *client)
{
+ d = new QXmppCallManagerPrivate(this);
+
bool check = connect(client, SIGNAL(iqReceived(QXmppIq)),
this, SLOT(iqReceived(QXmppIq)));
Q_ASSERT(check);
Q_UNUSED(check);
}
+QXmppCallManager::~QXmppCallManager()
+{
+ delete d;
+}
+
QStringList QXmppCallManager::discoveryFeatures() const
{
return QStringList()
@@ -267,7 +331,7 @@ QXmppCall *QXmppCallManager::call(const QString &jid)
call->d->sid = generateStanzaHash();
// register call
- m_calls << call;
+ d->calls << call;
connect(call, SIGNAL(destroyed(QObject*)),
this, SLOT(callDestroyed(QObject*)));
connect(call, SIGNAL(stateChanged(QXmppCall::State)),
@@ -296,20 +360,20 @@ QXmppCall *QXmppCallManager::call(const QString &jid)
foreach (const QXmppJingleCandidate &candidate, call->d->connection->localCandidates())
iq.content().addTransportCandidate(candidate);
- sendRequest(call, iq);
+ d->sendRequest(call, iq);
return call;
}
void QXmppCallManager::callDestroyed(QObject *object)
{
- m_calls.removeAll(static_cast<QXmppCall*>(object));
+ d->calls.removeAll(static_cast<QXmppCall*>(object));
}
void QXmppCallManager::callStateChanged(QXmppCall::State state)
{
QXmppCall *call = qobject_cast<QXmppCall*>(sender());
- if (!call || !m_calls.contains(call))
+ if (!call || !d->calls.contains(call))
return;
#if 0
@@ -326,7 +390,7 @@ void QXmppCallManager::callStateChanged(QXmppCall::State state)
iq.setType(QXmppIq::Set);
iq.setAction(QXmppJingleIq::SessionTerminate);
iq.setSid(call->sid());
- sendRequest(call, iq);
+ d->sendRequest(call, iq);
// schedule forceful termination in 5s
QTimer::singleShot(5000, call, SLOT(terminate()));
@@ -355,7 +419,7 @@ void QXmppCallManager::callStateChanged(QXmppCall::State state)
foreach (const QXmppJingleCandidate &candidate, call->d->connection->localCandidates())
iq.content().addTransportCandidate(candidate);
- sendRequest(call, iq);
+ d->sendRequest(call, iq);
// perform ICE negotiation
call->d->connection->connectToHost();
@@ -365,7 +429,7 @@ void QXmppCallManager::callStateChanged(QXmppCall::State state)
/// Determine common payload types for a call.
///
-bool QXmppCallManager::checkPayloadTypes(QXmppCall *call, const QList<QXmppJinglePayloadType> &remotePayloadTypes)
+bool QXmppCallManagerPrivate::checkPayloadTypes(QXmppCall *call, const QList<QXmppJinglePayloadType> &remotePayloadTypes)
{
foreach (const QXmppJinglePayloadType &payload, call->d->audioChannel->supportedPayloadTypes())
{
@@ -375,7 +439,7 @@ bool QXmppCallManager::checkPayloadTypes(QXmppCall *call, const QList<QXmppJingl
}
if (call->d->commonPayloadTypes.isEmpty())
{
- warning(QString("Remote party %1 did not provide any known payload types for call %2").arg(call->jid(), call->sid()));
+ q->warning(QString("Remote party %1 did not provide any known payload types for call %2").arg(call->jid(), call->sid()));
// terminate call
QXmppJingleIq iq;
@@ -387,27 +451,12 @@ bool QXmppCallManager::checkPayloadTypes(QXmppCall *call, const QList<QXmppJingl
sendRequest(call, iq);
return false;
} else {
- call->setPayloadType(call->d->commonPayloadTypes.first());
+ call->d->audioChannel->setPayloadType(call->d->commonPayloadTypes.first());
+ call->updateOpenMode();
return true;
}
}
-QXmppCall *QXmppCallManager::findCall(const QString &sid) const
-{
- foreach (QXmppCall *call, m_calls)
- if (call->sid() == sid)
- return call;
- return 0;
-}
-
-QXmppCall *QXmppCallManager::findCall(const QString &sid, QXmppCall::Direction direction) const
-{
- foreach (QXmppCall *call, m_calls)
- if (call->sid() == sid && call->direction() == direction)
- return call;
- return 0;
-}
-
/// Handles acknowledgements
///
@@ -420,7 +469,7 @@ void QXmppCallManager::iqReceived(const QXmppIq &ack)
bool found = false;
QXmppCall *call = 0;
QXmppJingleIq request;
- foreach (call, m_calls)
+ foreach (call, d->calls)
{
for (int i = 0; i < call->d->requests.size(); i++)
{
@@ -463,20 +512,21 @@ void QXmppCallManager::jingleIqReceived(const QXmppJingleIq &iq)
call->d->contentName = iq.content().name();
call->d->connection->setRemoteUser(iq.content().transportUser());
call->d->connection->setRemotePassword(iq.content().transportPassword());
- call->addRemoteCandidates(iq.content().transportCandidates());
+ foreach (const QXmppJingleCandidate &candidate, iq.content().transportCandidates())
+ call->d->connection->addRemoteCandidate(candidate);
// send ack
- sendAck(iq);
+ d->sendAck(iq);
// determine common payload types
- if (!checkPayloadTypes(call, iq.content().payloadTypes()))
+ if (!d->checkPayloadTypes(call, iq.content().payloadTypes()))
{
delete call;
return;
}
// register call
- m_calls << call;
+ d->calls << call;
connect(call, SIGNAL(destroyed(QObject*)),
this, SLOT(callDestroyed(QObject*)));
connect(call, SIGNAL(stateChanged(QXmppCall::State)),
@@ -491,13 +541,13 @@ void QXmppCallManager::jingleIqReceived(const QXmppJingleIq &iq)
ringing.setAction(QXmppJingleIq::SessionInfo);
ringing.setSid(call->sid());
ringing.setRinging(true);
- sendRequest(call, ringing);
+ d->sendRequest(call, ringing);
// notify user
emit callReceived(call);
} else if (iq.action() == QXmppJingleIq::SessionAccept) {
- QXmppCall *call = findCall(iq.sid(), QXmppCall::OutgoingDirection);
+ QXmppCall *call = d->findCall(iq.sid(), QXmppCall::OutgoingDirection);
if (!call)
{
warning(QString("Remote party %1 accepted unknown call %2").arg(iq.from(), iq.sid()));
@@ -505,10 +555,10 @@ void QXmppCallManager::jingleIqReceived(const QXmppJingleIq &iq)
}
// send ack
- sendAck(iq);
+ d->sendAck(iq);
// determine common payload types
- if (!checkPayloadTypes(call, iq.content().payloadTypes()))
+ if (!d->checkPayloadTypes(call, iq.content().payloadTypes()))
{
delete call;
return;
@@ -519,13 +569,14 @@ void QXmppCallManager::jingleIqReceived(const QXmppJingleIq &iq)
{
call->d->connection->setRemoteUser(iq.content().transportUser());
call->d->connection->setRemotePassword(iq.content().transportPassword());
- call->addRemoteCandidates(iq.content().transportCandidates());
+ foreach (const QXmppJingleCandidate &candidate, iq.content().transportCandidates())
+ call->d->connection->addRemoteCandidate(candidate);
}
call->d->connection->connectToHost();
} else if (iq.action() == QXmppJingleIq::SessionInfo) {
- QXmppCall *call = findCall(iq.sid());
+ QXmppCall *call = d->findCall(iq.sid());
if (!call)
return;
@@ -534,7 +585,7 @@ void QXmppCallManager::jingleIqReceived(const QXmppJingleIq &iq)
} else if (iq.action() == QXmppJingleIq::SessionTerminate) {
- QXmppCall *call = findCall(iq.sid());
+ QXmppCall *call = d->findCall(iq.sid());
if (!call)
{
warning(QString("Remote party %1 terminated unknown call %2").arg(iq.from(), iq.sid()));
@@ -544,13 +595,13 @@ void QXmppCallManager::jingleIqReceived(const QXmppJingleIq &iq)
info(QString("Remote party %1 terminated call %2").arg(iq.from(), iq.sid()));
// send ack
- sendAck(iq);
+ d->sendAck(iq);
// terminate
call->terminate();
} else if (iq.action() == QXmppJingleIq::TransportInfo) {
- QXmppCall *call = findCall(iq.sid());
+ QXmppCall *call = d->findCall(iq.sid());
if (!call)
{
warning(QString("Remote party %1 sent transports for unknown call %2").arg(iq.from(), iq.sid()));
@@ -558,12 +609,13 @@ void QXmppCallManager::jingleIqReceived(const QXmppJingleIq &iq)
}
// send ack
- sendAck(iq);
+ d->sendAck(iq);
// perform ICE negotiation
call->d->connection->setRemoteUser(iq.content().transportUser());
call->d->connection->setRemotePassword(iq.content().transportPassword());
- call->addRemoteCandidates(iq.content().transportCandidates());
+ foreach (const QXmppJingleCandidate &candidate, iq.content().transportCandidates())
+ call->d->connection->addRemoteCandidate(candidate);
call->d->connection->connectToHost();
}
}
@@ -574,7 +626,7 @@ void QXmppCallManager::jingleIqReceived(const QXmppJingleIq &iq)
void QXmppCallManager::localCandidatesChanged()
{
QXmppCall *call = qobject_cast<QXmppCall*>(sender());
- if (!call || !m_calls.contains(call))
+ if (!call || !d->calls.contains(call))
return;
QXmppJingleIq iq;
@@ -589,27 +641,7 @@ void QXmppCallManager::localCandidatesChanged()
foreach (const QXmppJingleCandidate &candidate, call->d->connection->localCandidates())
iq.content().addTransportCandidate(candidate);
- sendRequest(call, iq);
-}
-
-/// Sends an acknowledgement for a Jingle IQ.
-///
-
-bool QXmppCallManager::sendAck(const QXmppJingleIq &iq)
-{
- QXmppIq ack;
- ack.setId(iq.id());
- ack.setTo(iq.from());
- ack.setType(QXmppIq::Result);
- return client()->sendPacket(ack);
+ d->sendRequest(call, iq);
}
-/// Sends a Jingle IQ and adds it to outstanding requests.
-///
-
-bool QXmppCallManager::sendRequest(QXmppCall *call, const QXmppJingleIq &iq)
-{
- call->d->requests << iq;
- return client()->sendPacket(iq);
-}
diff --git a/src/QXmppCallManager.h b/src/QXmppCallManager.h
index 29da58dd..0fb489b2 100644
--- a/src/QXmppCallManager.h
+++ b/src/QXmppCallManager.h
@@ -32,6 +32,7 @@
#include "QXmppLogger.h"
class QXmppCallPrivate;
+class QXmppCallManagerPrivate;
class QXmppIq;
class QXmppJingleCandidate;
class QXmppJingleIq;
@@ -111,12 +112,11 @@ private slots:
private:
QXmppCall(const QString &jid, QXmppCall::Direction direction, QObject *parent);
- void setPayloadType(const QXmppJinglePayloadType &type);
- void addRemoteCandidates(const QList<QXmppJingleCandidate> &candidates);
- void setState(QXmppCall::State state);
- QXmppCallPrivate * const d;
+ QXmppCallPrivate *d;
friend class QXmppCallManager;
+ friend class QXmppCallManagerPrivate;
+ friend class QXmppCallPrivate;
};
/// \brief The QXmppCallManager class provides support for making and
@@ -138,6 +138,7 @@ class QXmppCallManager : public QXmppClientExtension
public:
QXmppCallManager(QXmppClient *client);
+ ~QXmppCallManager();
QXmppCall *call(const QString &jid);
/// \cond
@@ -160,13 +161,8 @@ private slots:
void localCandidatesChanged();
private:
- bool checkPayloadTypes(QXmppCall *call, const QList<QXmppJinglePayloadType> &remotePayloadTypes);
- QXmppCall *findCall(const QString &sid) const;
- QXmppCall *findCall(const QString &sid, QXmppCall::Direction direction) const;
- bool sendAck(const QXmppJingleIq &iq);
- bool sendRequest(QXmppCall *call, const QXmppJingleIq &iq);
-
- QList<QXmppCall*> m_calls;
+ QXmppCallManagerPrivate *d;
+ friend class QXmppCallManagerPrivate;
};
Q_DECLARE_METATYPE(QXmppCall::State)