diff options
author | trilene <trilene@runbox.com> | 2020-07-26 10:59:50 -0400 |
---|---|---|
committer | trilene <trilene@runbox.com> | 2020-07-26 10:59:50 -0400 |
commit | 43ec0c062467c05a66eac7a3fb992bc093315c89 (patch) | |
tree | d90f85eb42e4d07d31c2aa46906ebb9c21179c86 /src/CallManager.cpp | |
parent | Improve debug messages (diff) | |
download | nheko-43ec0c062467c05a66eac7a3fb992bc093315c89.tar.xz |
Handle ICE failure
Diffstat (limited to 'src/CallManager.cpp')
-rw-r--r-- | src/CallManager.cpp | 96 |
1 files changed, 64 insertions, 32 deletions
diff --git a/src/CallManager.cpp b/src/CallManager.cpp index 3caa812d..b57ef1bb 100644 --- a/src/CallManager.cpp +++ b/src/CallManager.cpp @@ -11,9 +11,10 @@ #include "MatrixClient.h" #include "UserSettingsPage.h" #include "WebRTCSession.h" - #include "dialogs/AcceptCall.h" +#include "mtx/responses/turn_server.hpp" + Q_DECLARE_METATYPE(std::vector<mtx::events::msg::CallCandidates::Candidate>) Q_DECLARE_METATYPE(mtx::events::msg::CallCandidates::Candidate) Q_DECLARE_METATYPE(mtx::responses::TurnServer) @@ -24,6 +25,11 @@ using namespace mtx::events::msg; // https://github.com/vector-im/riot-web/issues/10173 #define STUN_SERVER "stun://turn.matrix.org:3478" +namespace { +std::vector<std::string> +getTurnURIs(const mtx::responses::TurnServer &turnServer); +} + CallManager::CallManager(QSharedPointer<UserSettings> userSettings) : QObject(), session_(WebRTCSession::instance()), @@ -80,15 +86,23 @@ CallManager::CallManager(QSharedPointer<UserSettings> userSettings) // Request new credentials close to expiry // See https://tools.ietf.org/html/draft-uberti-behave-turn-rest-00 - turnServer_ = res; + turnURIs_ = getTurnURIs(res); turnServerTimer_.setInterval(res.ttl * 1000 * 0.9); }); connect(&session_, &WebRTCSession::stateChanged, this, [this](WebRTCSession::State state) { - if (state == WebRTCSession::State::DISCONNECTED) + if (state == WebRTCSession::State::DISCONNECTED) { playRingtone("qrc:/media/media/callend.ogg", false); - }); + } + else if (state == WebRTCSession::State::ICEFAILED) { + QString error("Call connection failed."); + if (turnURIs_.empty()) + error += " Your homeserver has no configured TURN server."; + emit ChatPage::instance()->showNotification(error); + hangUp(CallHangUp::Reason::ICEFailed); + } + }); connect(&player_, &QMediaPlayer::mediaStatusChanged, this, [this](QMediaPlayer::MediaStatus status) { @@ -116,8 +130,8 @@ CallManager::sendInvite(const QString &roomid) } roomid_ = roomid; - setTurnServers(); session_.setStunServer(settings_->useStunServer() ? STUN_SERVER : ""); + session_.setTurnServers(turnURIs_); generateCallID(); nhlog::ui()->debug("WebRTC: call id: {} - creating invite", callid_); @@ -132,11 +146,26 @@ CallManager::sendInvite(const QString &roomid) } } +namespace { +std::string callHangUpReasonString(CallHangUp::Reason reason) +{ + switch (reason) { + case CallHangUp::Reason::ICEFailed: + return "ICE failed"; + case CallHangUp::Reason::InviteTimeOut: + return "Invite time out"; + default: + return "User"; + } +} +} + void CallManager::hangUp(CallHangUp::Reason reason) { if (!callid_.empty()) { - nhlog::ui()->debug("WebRTC: call id: {} - hanging up", callid_); + nhlog::ui()->debug("WebRTC: call id: {} - hanging up ({})", callid_, + callHangUpReasonString(reason)); emit newMessage(roomid_, CallHangUp{callid_, 0, reason}); endCall(); } @@ -221,8 +250,8 @@ CallManager::answerInvite(const CallInvite &invite) return; } - setTurnServers(); session_.setStunServer(settings_->useStunServer() ? STUN_SERVER : ""); + session_.setTurnServers(turnURIs_); if (!session_.acceptOffer(invite.sdp)) { emit ChatPage::instance()->showNotification("Problem setting up call."); @@ -279,8 +308,9 @@ CallManager::handleEvent(const RoomEvent<CallAnswer> &callAnswerEvent) void CallManager::handleEvent(const RoomEvent<CallHangUp> &callHangUpEvent) { - nhlog::ui()->debug("WebRTC: call id: {} - incoming CallHangUp from {}", - callHangUpEvent.content.call_id, callHangUpEvent.sender); + nhlog::ui()->debug("WebRTC: call id: {} - incoming CallHangUp ({}) from {}", + callHangUpEvent.content.call_id, callHangUpReasonString(callHangUpEvent.content.reason), + callHangUpEvent.sender); if (callid_ == callHangUpEvent.content.call_id) { MainWindow::instance()->hideOverlay(); @@ -320,12 +350,30 @@ CallManager::retrieveTurnServer() } void -CallManager::setTurnServers() +CallManager::playRingtone(const QString &ringtone, bool repeat) +{ + static QMediaPlaylist playlist; + playlist.clear(); + playlist.setPlaybackMode(repeat ? QMediaPlaylist::CurrentItemInLoop : QMediaPlaylist::CurrentItemOnce); + playlist.addMedia(QUrl(ringtone)); + player_.setVolume(100); + player_.setPlaylist(&playlist); +} + +void +CallManager::stopRingtone() +{ + player_.setPlaylist(nullptr); +} + +namespace { +std::vector<std::string> +getTurnURIs(const mtx::responses::TurnServer &turnServer) { // gstreamer expects: turn(s)://username:password@host:port?transport=udp(tcp) // where username and password are percent-encoded - std::vector<std::string> uris; - for (const auto &uri : turnServer_.uris) { + std::vector<std::string> ret; + for (const auto &uri : turnServer.uris) { if (auto c = uri.find(':'); c == std::string::npos) { nhlog::ui()->error("Invalid TURN server uri: {}", uri); continue; @@ -338,29 +386,13 @@ CallManager::setTurnServers() } QString encodedUri = QString::fromStdString(scheme) + "://" + - QUrl::toPercentEncoding(QString::fromStdString(turnServer_.username)) + ":" + - QUrl::toPercentEncoding(QString::fromStdString(turnServer_.password)) + "@" + + QUrl::toPercentEncoding(QString::fromStdString(turnServer.username)) + ":" + + QUrl::toPercentEncoding(QString::fromStdString(turnServer.password)) + "@" + QString::fromStdString(std::string(uri, ++c)); - uris.push_back(encodedUri.toStdString()); + ret.push_back(encodedUri.toStdString()); } } - if (!uris.empty()) - session_.setTurnServers(uris); + return ret; } - -void -CallManager::playRingtone(const QString &ringtone, bool repeat) -{ - static QMediaPlaylist playlist; - playlist.clear(); - playlist.setPlaybackMode(repeat ? QMediaPlaylist::CurrentItemInLoop : QMediaPlaylist::CurrentItemOnce); - playlist.addMedia(QUrl(ringtone)); - player_.setVolume(100); - player_.setPlaylist(&playlist); } -void -CallManager::stopRingtone() -{ - player_.setPlaylist(nullptr); -} |