diff options
| author | Jeremy Lainé <jeremy.laine@m4x.org> | 2010-08-22 13:44:09 +0000 |
|---|---|---|
| committer | Jeremy Lainé <jeremy.laine@m4x.org> | 2010-08-22 13:44:09 +0000 |
| commit | 2878f5808a942d6342e47a3162669f9d23c1b824 (patch) | |
| tree | 49d21d759e01d052af17b449dca79a93604356ae /src/QXmppCallManager.cpp | |
| parent | b424f792b558ce766cdd2644007e5a68314a3218 (diff) | |
| download | qxmpp-2878f5808a942d6342e47a3162669f9d23c1b824.tar.gz | |
improve STUN support, discover server reflexive address
Diffstat (limited to 'src/QXmppCallManager.cpp')
| -rw-r--r-- | src/QXmppCallManager.cpp | 144 |
1 files changed, 75 insertions, 69 deletions
diff --git a/src/QXmppCallManager.cpp b/src/QXmppCallManager.cpp index e6345079..379eed0b 100644 --- a/src/QXmppCallManager.cpp +++ b/src/QXmppCallManager.cpp @@ -27,10 +27,13 @@ #include "QXmppCodec.h" #include "QXmppConstants.h" #include "QXmppJingleIq.h" -#include "QXmppStream.h" +#include "QXmppOutgoingClient.h" #include "QXmppStun.h" #include "QXmppUtils.h" +const int RTP_COMPONENT = 1; +const int RTCP_COMPONENT = 2; + const quint8 RTP_VERSION = 0x02; enum CodecId { @@ -63,32 +66,30 @@ QXmppCall::QXmppCall(const QString &jid, QXmppCall::Direction direction, QObject m_outgoingSequence(0), m_outgoingStamp(0) { - bool iceControlling = (m_direction == OutgoingDirection); + m_contentCreator = QLatin1String("initiator"); + m_contentName = QLatin1String("voice"); - // RTP socket - m_socket = new QXmppStunSocket(iceControlling, this); - m_socket->setComponent(1); + // ICE connection + bool iceControlling = (m_direction == OutgoingDirection); + m_connection = new QXmppIceConnection(iceControlling, this); + m_connection->setStunServer("stun.ekiga.net"); + m_connection->addComponent(RTP_COMPONENT); + m_connection->addComponent(RTCP_COMPONENT); - bool check = connect(m_socket, SIGNAL(logMessage(QXmppLogger::MessageType, QString)), + bool check = connect(m_connection, SIGNAL(logMessage(QXmppLogger::MessageType, QString)), this, SIGNAL(logMessage(QXmppLogger::MessageType, QString))); Q_ASSERT(check); - check = connect(m_socket, SIGNAL(connected()), - this, SLOT(updateOpenMode())); + check = connect(m_connection, SIGNAL(localCandidatesChanged()), + this, SIGNAL(localCandidatesChanged())); Q_ASSERT(check); - check = connect(m_socket, SIGNAL(datagramReceived(QByteArray)), - this, SLOT(datagramReceived(QByteArray))); + check = connect(m_connection, SIGNAL(connected()), + this, SLOT(updateOpenMode())); Q_ASSERT(check); - // RTCP socket - m_rtcpSocket = new QXmppStunSocket(iceControlling, this); - m_rtcpSocket->setComponent(2); - m_rtcpSocket->setLocalUser(m_socket->localUser()); - m_rtcpSocket->setLocalPassword(m_socket->localPassword()); - - check = connect(m_rtcpSocket, SIGNAL(logMessage(QXmppLogger::MessageType, QString)), - this, SIGNAL(logMessage(QXmppLogger::MessageType, QString))); + check = connect(m_connection, SIGNAL(datagramReceived(int,QByteArray)), + this, SLOT(datagramReceived(int, QByteArray))); Q_ASSERT(check); } @@ -117,8 +118,7 @@ void QXmppCall::terminate() m_state = QXmppCall::FinishedState; close(); - m_socket->close(); - m_rtcpSocket->close(); + m_connection->close(); // emit signals later QTimer::singleShot(0, this, SLOT(terminated())); @@ -130,12 +130,6 @@ void QXmppCall::terminated() emit finished(); } -void QXmppCall::connectToHost() -{ - m_socket->connectToHost(); - m_rtcpSocket->connectToHost(); -} - /// Returns the call's direction. /// @@ -173,11 +167,6 @@ QString QXmppCall::jid() const return m_jid; } -QList<QXmppJingleCandidate> QXmppCall::localCandidates() const -{ - return m_socket->localCandidates() + m_rtcpSocket->localCandidates(); -} - /// Returns the negociated payload type. /// /// You can use this to determine the QAudioFormat to use with your @@ -220,28 +209,13 @@ void QXmppCall::setPayloadType(const QXmppJinglePayloadType &payloadType) void QXmppCall::addRemoteCandidates(const QList<QXmppJingleCandidate> &candidates) { foreach (const QXmppJingleCandidate &candidate, candidates) - { - m_socket->addRemoteCandidate(candidate); - m_rtcpSocket->addRemoteCandidate(candidate); - } -} - -void QXmppCall::setRemoteUser(const QString &user) -{ - m_socket->setRemoteUser(user); - m_rtcpSocket->setRemoteUser(user); -} - -void QXmppCall::setRemotePassword(const QString &password) -{ - m_socket->setRemotePassword(password); - m_rtcpSocket->setRemotePassword(password); + m_connection->addRemoteCandidate(candidate); } void QXmppCall::updateOpenMode() { // determine mode - if (m_codec && m_socket->isConnected() && m_state != ActiveState) + if (m_codec && m_connection->isConnected() && m_state != ActiveState) { open(QIODevice::ReadWrite); setState(ActiveState); @@ -249,8 +223,11 @@ void QXmppCall::updateOpenMode() } } -void QXmppCall::datagramReceived(const QByteArray &buffer) +void QXmppCall::datagramReceived(int component, const QByteArray &buffer) { + if (component != RTP_COMPONENT) + return; + if (!m_codec) { emit logMessage(QXmppLogger::WarningMessage, @@ -407,7 +384,7 @@ qint64 QXmppCall::writeData(const char * data, qint64 maxSize) input.setByteOrder(QDataStream::LittleEndian); m_outgoingStamp += m_codec->encode(input, stream); - if (m_socket->writeDatagram(header) < 0) + if (m_connection->writeDatagram(RTP_COMPONENT, header) < 0) emit logMessage(QXmppLogger::WarningMessage, QLatin1String("QXmppCall:writeData could not send audio data")); #ifdef QXMPP_DEBUG_RTP @@ -431,7 +408,7 @@ qint64 QXmppCall::writeData(const char * data, qint64 maxSize) return maxSize; } -QXmppCallManager::QXmppCallManager(QXmppStream *stream, QObject *parent) +QXmppCallManager::QXmppCallManager(QXmppOutgoingClient *stream, QObject *parent) : QObject(parent), m_stream(stream) { // setup logging @@ -460,6 +437,8 @@ QXmppCall *QXmppCallManager::call(const QString &jid) connect(call, SIGNAL(destroyed(QObject*)), this, SLOT(callDestroyed(QObject*))); connect(call, SIGNAL(stateChanged(QXmppCall::State)), this, SLOT(callStateChanged(QXmppCall::State))); + connect(call, SIGNAL(localCandidatesChanged()), + this, SLOT(localCandidatesChanged())); connect(call, SIGNAL(logMessage(QXmppLogger::MessageType, QString)), this, SIGNAL(logMessage(QXmppLogger::MessageType, QString))); @@ -469,8 +448,8 @@ QXmppCall *QXmppCallManager::call(const QString &jid) iq.setAction(QXmppJingleIq::SessionInitiate); iq.setInitiator(m_stream->configuration().jid()); iq.setSid(call->m_sid); - iq.content().setCreator("initiator"); - iq.content().setName("voice"); + iq.content().setCreator(call->m_contentCreator); + iq.content().setName(call->m_contentName); iq.content().setSenders("both"); // description @@ -479,9 +458,9 @@ QXmppCall *QXmppCallManager::call(const QString &jid) iq.content().addPayloadType(payload); // transport - iq.content().setTransportUser(call->m_socket->localUser()); - iq.content().setTransportPassword(call->m_socket->localPassword()); - foreach (const QXmppJingleCandidate &candidate, call->localCandidates()) + iq.content().setTransportUser(call->m_connection->localUser()); + iq.content().setTransportPassword(call->m_connection->localPassword()); + foreach (const QXmppJingleCandidate &candidate, call->m_connection->localCandidates()) iq.content().addTransportCandidate(candidate); sendRequest(call, iq); @@ -529,7 +508,7 @@ void QXmppCallManager::callStateChanged(QXmppCall::State state) iq.setAction(QXmppJingleIq::SessionAccept); iq.setResponder(m_stream->configuration().jid()); iq.setSid(call->m_sid); - iq.content().setCreator("initiator"); + iq.content().setCreator(call->m_contentCreator); iq.content().setName(call->m_contentName); // description @@ -538,15 +517,15 @@ void QXmppCallManager::callStateChanged(QXmppCall::State state) iq.content().addPayloadType(payload); // transport - iq.content().setTransportUser(call->m_socket->localUser()); - iq.content().setTransportPassword(call->m_socket->localPassword()); - foreach (const QXmppJingleCandidate &candidate, call->localCandidates()) + iq.content().setTransportUser(call->m_connection->localUser()); + iq.content().setTransportPassword(call->m_connection->localPassword()); + foreach (const QXmppJingleCandidate &candidate, call->m_connection->localCandidates()) iq.content().addTransportCandidate(candidate); sendRequest(call, iq); // perform ICE negotiation - call->connectToHost(); + call->m_connection->connectToHost(); } } @@ -685,9 +664,10 @@ void QXmppCallManager::jingleIqReceived(const QXmppJingleIq &iq) // build call QXmppCall *call = new QXmppCall(iq.from(), QXmppCall::IncomingDirection, this); call->m_sid = iq.sid(); + call->m_contentCreator = iq.content().creator(); call->m_contentName = iq.content().name(); - call->setRemoteUser(iq.content().transportUser()); - call->setRemotePassword(iq.content().transportPassword()); + call->m_connection->setRemoteUser(iq.content().transportUser()); + call->m_connection->setRemotePassword(iq.content().transportPassword()); call->addRemoteCandidates(iq.content().transportCandidates()); // send ack @@ -704,6 +684,8 @@ void QXmppCallManager::jingleIqReceived(const QXmppJingleIq &iq) m_calls.append(call); connect(call, SIGNAL(stateChanged(QXmppCall::State)), this, SLOT(callStateChanged(QXmppCall::State))); + connect(call, SIGNAL(localCandidatesChanged()), + this, SLOT(localCandidatesChanged())); connect(call, SIGNAL(logMessage(QXmppLogger::MessageType, QString)), this, SIGNAL(logMessage(QXmppLogger::MessageType, QString))); @@ -741,11 +723,11 @@ void QXmppCallManager::jingleIqReceived(const QXmppJingleIq &iq) // perform ICE negotiation if (!iq.content().transportCandidates().isEmpty()) { - call->setRemoteUser(iq.content().transportUser()); - call->setRemotePassword(iq.content().transportPassword()); + call->m_connection->setRemoteUser(iq.content().transportUser()); + call->m_connection->setRemotePassword(iq.content().transportPassword()); call->addRemoteCandidates(iq.content().transportCandidates()); } - call->connectToHost(); + call->m_connection->connectToHost(); } else if (iq.action() == QXmppJingleIq::SessionInfo) { @@ -788,13 +770,37 @@ void QXmppCallManager::jingleIqReceived(const QXmppJingleIq &iq) sendAck(iq); // perform ICE negotiation - call->setRemoteUser(iq.content().transportUser()); - call->setRemotePassword(iq.content().transportPassword()); + call->m_connection->setRemoteUser(iq.content().transportUser()); + call->m_connection->setRemotePassword(iq.content().transportPassword()); call->addRemoteCandidates(iq.content().transportCandidates()); - call->connectToHost(); + call->m_connection->connectToHost(); } } +/// Sends a transport-info to inform the remote party of new local candidates. +/// + +void QXmppCallManager::localCandidatesChanged() +{ + QXmppCall *call = qobject_cast<QXmppCall*>(sender()); + if (!call || !m_calls.contains(call)) + return; + + QXmppJingleIq iq; + iq.setTo(call->jid()); + iq.setType(QXmppIq::Set); + iq.setAction(QXmppJingleIq::TransportInfo); + iq.setInitiator(m_stream->configuration().jid()); + iq.setSid(call->sid()); + + iq.content().setCreator(call->m_contentCreator); + iq.content().setName(call->m_contentName); + foreach (const QXmppJingleCandidate &candidate, call->m_connection->localCandidates()) + iq.content().addTransportCandidate(candidate); + + sendRequest(call, iq); +} + /// Sends an acknowledgement for a Jingle IQ. /// |
