diff --git a/CMakeLists.txt b/CMakeLists.txt index 440e1c863..c317d2edd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -274,12 +274,8 @@ pkg_check_modules(GNUTLS gnutls) if(GNUTLS_LIBRARIES) set(HAVE_GNUTLS 1) endif(GNUTLS_LIBRARIES) -pkg_check_modules(PJSIP libpjproject>=1.8) -if(PJSIP_LIBRARIES) - set(HAVE_PJSIP 1) -endif(PJSIP_LIBRARIES) -if(ENABLE_REMOTE AND HAVE_GNUTLS AND HAVE_PJSIP) +if(ENABLE_REMOTE AND HAVE_GNUTLS) set(HAVE_REMOTE ON) add_subdirectory(3rdparty/gloox) add_subdirectory(3rdparty/libxrme) @@ -287,7 +283,7 @@ if(ENABLE_REMOTE AND HAVE_GNUTLS AND HAVE_PJSIP) include_directories(3rdparty) include_directories(3rdparty/libxrme) include_directories(3rdparty/libportfwd/include) -endif(ENABLE_REMOTE AND HAVE_GNUTLS AND HAVE_PJSIP) +endif(ENABLE_REMOTE AND HAVE_GNUTLS) set(HAVE_STATIC_SQLITE ${STATIC_SQLITE}) if(STATIC_SQLITE) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1eecc2637..e7ff6d3f1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -40,10 +40,6 @@ if(HAVE_BREAKPAD) include_directories(../3rdparty/google-breakpad) endif(HAVE_BREAKPAD) -if(HAVE_REMOTE) - include_directories(${PJSIP_INCLUDE_DIRS}) -endif(HAVE_REMOTE) - cmake_policy(SET CMP0011 NEW) include(../cmake/ParseArguments.cmake) include(../cmake/Translations.cmake) @@ -907,13 +903,11 @@ optional_source(WIN32 optional_source(HAVE_REMOTE SOURCES - remote/icesession.cpp remote/portforwarder.cpp remote/remote.cpp remote/remotesettingspage.cpp remote/streampipeline.cpp HEADERS - remote/icesession.h remote/portforwarder.h remote/remote.h remote/remotesettingspage.h @@ -1025,8 +1019,6 @@ if(HAVE_REMOTE) link_directories(${GLOOX_LIBRARY_DIRS}) target_link_libraries(clementine_lib xrme) target_link_libraries(clementine_lib portfwd) - target_link_libraries(clementine_lib ${PJSIP_LIBRARIES}) - link_directories(${PJSIP_LIBRARY_DIRS}) endif(HAVE_REMOTE) if(HAVE_BREAKPAD) diff --git a/src/core/commandlineoptions.cpp b/src/core/commandlineoptions.cpp index 99d31d930..a11e015fa 100644 --- a/src/core/commandlineoptions.cpp +++ b/src/core/commandlineoptions.cpp @@ -76,7 +76,6 @@ CommandlineOptions::CommandlineOptions(int argc, char** argv) show_osd_(false), toggle_pretty_osd_(false), show_search_popup_(false), - stun_test_(StunTestNone), log_levels_(logging::kDefaultLogLevels) { #ifdef Q_OS_DARWIN @@ -130,8 +129,6 @@ bool CommandlineOptions::Parse() { {"log-levels", required_argument, 0, LogLevels}, {"version", no_argument, 0, Version}, - {"stun-test", required_argument, 0, 'z'}, - {0, 0, 0, 0} }; @@ -219,13 +216,6 @@ bool CommandlineOptions::Parse() { if (!ok) play_track_at_ = -1; break; - case 'z': { - // Stun test - QString direction = QString(optarg); - stun_test_ = direction == "offer" ? StunTestOffer : StunTestAccept; - break; - } - case '?': default: return false; diff --git a/src/core/commandlineoptions.h b/src/core/commandlineoptions.h index 8c4a0f61e..733b3825e 100644 --- a/src/core/commandlineoptions.h +++ b/src/core/commandlineoptions.h @@ -47,11 +47,6 @@ class CommandlineOptions { Player_Previous = 5, Player_Next = 6, }; - enum StunTestDirection { - StunTestNone = 0, - StunTestOffer = 1, - StunTestAccept = 2, - }; bool Parse(); @@ -71,9 +66,6 @@ class CommandlineOptions { QString language() const { return language_; } QString log_levels() const { return log_levels_; } - StunTestDirection stun_test() const { return stun_test_; } - - QByteArray Serialize() const; void Load(const QByteArray& serialized); @@ -113,7 +105,6 @@ class CommandlineOptions { bool toggle_pretty_osd_; bool show_search_popup_; QString language_; - StunTestDirection stun_test_; QString log_levels_; QList urls_; diff --git a/src/main.cpp b/src/main.cpp index 1b03fdf29..78c77851f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -140,7 +140,6 @@ void LoadTranslation(const QString& prefix, const QString& path, #ifdef HAVE_REMOTE #include -#include "remote/icesession.h" #endif int main(int argc, char *argv[]) { @@ -278,57 +277,6 @@ int main(int argc, char *argv[]) { UniversalEncodingHandler handler; TagLib::ID3v1::Tag::setStringHandler(&handler); -#ifdef HAVE_REMOTE - if (options.stun_test() != CommandlineOptions::StunTestNone) { - QCoreApplication app(argc, argv); - - ICESession::StaticInit(); - ICESession ice; - ice.Init(options.stun_test() == CommandlineOptions::StunTestOffer - ? ICESession::DirectionControlling - : ICESession::DirectionControlled); - - QEventLoop loop; - QObject::connect(&ice, - SIGNAL(CandidatesAvailable(const xrme::SIPInfo&)), - &loop, SLOT(quit())); - loop.exec(); - - const xrme::SIPInfo& candidates = ice.candidates(); - qDebug() << candidates; - - QString sip_info; - { - QFile file; - file.open(stdin, QIODevice::ReadOnly); - QTextStream in(&file); - in >> sip_info; - } - QStringList sip_components = sip_info.split(':'); - - xrme::SIPInfo remote_session; - remote_session.user_fragment = sip_components[0]; - remote_session.password = sip_components[1]; - - xrme::SIPInfo::Candidate cand; - cand.address = sip_components[2]; - cand.port = sip_components[3].toUShort(); - cand.type = sip_components[4]; - cand.component = sip_components[5].toInt(); - cand.priority = sip_components[6].toInt(); - cand.foundation = sip_components[7]; - - remote_session.candidates << cand; - - qDebug() << "Remote:" << remote_session; - - ice.StartNegotiation(remote_session); - loop.exec(); - - return 0; - } -#endif - #ifdef Q_OS_LINUX // Force Clementine's menu to be shown in the Clementine window and not in // the Unity global menubar thing. See: diff --git a/src/remote/icesession.cpp b/src/remote/icesession.cpp deleted file mode 100644 index c7e6fff72..000000000 --- a/src/remote/icesession.cpp +++ /dev/null @@ -1,319 +0,0 @@ -#include "icesession.h" -#include "core/logging.h" - -#include - -using xrme::SIPInfo; - -const char* ICESession::kStunServer = "stunserver.org"; -int ICESession::sComponentId = 0; -pj_caching_pool ICESession::sCachingPool; -pj_ice_strans_cfg ICESession::sIceConfig; - -pj_pool_t* ICESession::sPool; -pj_thread_t* ICESession::sThread; - -ICESession::ICESession(QObject* parent) - : QIODevice(parent) { -} - - -bool ICESession::Init(Direction direction) { - // Create instance. - pj_ice_strans_cb ice_cb; - pj_bzero(&ice_cb, sizeof(ice_cb)); - - ice_cb.on_rx_data = &OnReceiveData; - ice_cb.on_ice_complete = &OnICEComplete; - - component_id_ = ++sComponentId; - - pj_status_t status = pj_ice_strans_create( - "clementine", - &sIceConfig, - component_id_, - this, - &ice_cb, - &ice_instance_); - if (status != PJ_SUCCESS) { - qLog(Warning) << "Failed to create ICE instance"; - return false; - } - - // TODO - pj_ice_sess_role role = direction == DirectionControlling - ? PJ_ICE_SESS_ROLE_CONTROLLING - : PJ_ICE_SESS_ROLE_CONTROLLED; - - status = pj_ice_strans_init_ice(ice_instance_, role, NULL, NULL); - - qDebug() << "Init ice:" << status; - - return true; -} - -QString CandidateTypeToString(pj_ice_cand_type type) { - switch (type) { - case PJ_ICE_CAND_TYPE_HOST: - return "host"; - case PJ_ICE_CAND_TYPE_SRFLX: - return "srflx"; - case PJ_ICE_CAND_TYPE_PRFLX: - return "prflx"; - case PJ_ICE_CAND_TYPE_RELAYED: - return "relayed"; - } - return "unknown"; -} - -pj_ice_cand_type CandidateStringToType(const QString& type) { - if (type == "host") { - return PJ_ICE_CAND_TYPE_HOST; - } else if (type == "srflx") { - return PJ_ICE_CAND_TYPE_SRFLX; - } else if (type == "prflx") { - return PJ_ICE_CAND_TYPE_PRFLX; - } else if (type == "relayed") { - return PJ_ICE_CAND_TYPE_RELAYED; - } - return PJ_ICE_CAND_TYPE_HOST; -} - -void ICESession::InitialisationComplete(pj_status_t status) { - unsigned int candidates = pj_ice_strans_get_cands_count(ice_instance_, component_id_); - pj_ice_sess_cand cand[candidates]; - pj_ice_strans_enum_cands(ice_instance_, component_id_, &candidates, &cand[0]); - - pj_str_t ufrag; - pj_str_t pwd; - pj_ice_strans_get_ufrag_pwd(ice_instance_, &ufrag, &pwd, NULL, NULL); - - candidates_.user_fragment = QString::fromAscii(ufrag.ptr, ufrag.slen); - candidates_.password = QString::fromAscii(pwd.ptr, pwd.slen); - - for (int i = 0; i < candidates; ++i) { - if (!pj_sockaddr_has_addr(&cand[i].addr)) { - continue; - } - - int port = pj_sockaddr_get_port(&cand[i].addr); - char ipaddr[PJ_INET6_ADDRSTRLEN]; - pj_sockaddr_print(&cand[i].addr, ipaddr, sizeof(ipaddr), 0); - - QHostAddress address(QString::fromAscii(ipaddr)); - - SIPInfo::Candidate candidate; - candidate.address = address; - candidate.port = port; - candidate.type = CandidateTypeToString(cand[i].type); - candidate.component = component_id_; - candidate.priority = cand[i].prio; - candidate.foundation = QString::fromAscii( - cand[i].foundation.ptr, cand[i].foundation.slen); - - candidates_.candidates << candidate; - } - - emit CandidatesAvailable(candidates_); -} - - -void ICESession::StartNegotiation(const xrme::SIPInfo& session) { - pj_str_t remote_ufrag; - pj_str_t remote_password; - - pj_cstr(&remote_ufrag, strdup(session.user_fragment.toAscii().constData())); - pj_cstr(&remote_password, strdup(session.password.toAscii().constData())); - - pj_ice_sess_cand candidates[session.candidates.size()]; - for (int i = 0; i < session.candidates.size(); ++i) { - const xrme::SIPInfo::Candidate c = session.candidates[i]; - pj_ice_sess_cand* candidate = &candidates[i]; - pj_bzero(candidate, sizeof(*candidate)); - - candidate->type = CandidateStringToType(c.type); - candidate->comp_id = c.component; - candidate->prio = c.priority; - int af = c.address.protocol() == QAbstractSocket::IPv6Protocol - ? pj_AF_INET6() - : pj_AF_INET(); - - pj_sockaddr_init(af, &candidate->addr, NULL, 0); - pj_str_t temp_addr; - pj_cstr(&temp_addr, c.address.toString().toAscii().constData()); - pj_sockaddr_set_str_addr(af, &candidate->addr, &temp_addr); - pj_sockaddr_set_port(&candidate->addr, c.port); - - pj_cstr(&candidate->foundation, c.foundation.toAscii().constData()); - } - - pj_status_t status = pj_ice_strans_start_ice( - ice_instance_, - &remote_ufrag, - &remote_password, - session.candidates.size(), - candidates); - - if (status != PJ_SUCCESS) { - qLog(Warning) << "Start negotation failed"; - } else { - qDebug() << "ICE negotiation started"; - } -} - -qint64 ICESession::readData(char* data, qint64 max_size) { - QByteArray ret = receive_buffer_.left(max_size); - receive_buffer_ = receive_buffer_.mid(ret.size()); - memcpy(data, ret.constData(), ret.size()); - return ret.size(); -} - -qint64 ICESession::writeData(const char* data, qint64 max_size) { - // This address should never actually be used. - pj_sockaddr addr; - pj_getdefaultipinterface(pj_AF_INET(), &addr); - - pj_status_t ret = pj_ice_strans_sendto( - ice_instance_, component_id_, data, max_size, &addr, sizeof(addr)); - return ret == PJ_SUCCESS ? max_size : -1; -} - -void ICESession::OnReceiveData(pj_ice_strans* ice_st, - unsigned comp_id, - void* pkt, - pj_size_t size, - const pj_sockaddr_t* src_addr, - unsigned src_addr_len) { - ICESession* me = reinterpret_cast(pj_ice_strans_get_user_data(ice_st)); - QByteArray data((const char*)pkt, size); - qDebug() << "Received data" << data; - - me->receive_buffer_.append(data); - emit me->readyRead(); -} - -void ICESession::OnICEComplete(pj_ice_strans* ice_st, - pj_ice_strans_op op, - pj_status_t status) { - ICESession* me = reinterpret_cast(pj_ice_strans_get_user_data(ice_st)); - const char* op_name = NULL; - switch (op) { - case PJ_ICE_STRANS_OP_INIT: - op_name = "initialisation"; - me->InitialisationComplete(status); - break; - case PJ_ICE_STRANS_OP_NEGOTIATION: { - op_name = "negotation"; - const char* data = "Hello, World!"; - pj_sockaddr addr; - pj_getdefaultipinterface(pj_AF_INET(), &addr); - pj_ice_strans_sendto(ice_st, me->component_id_, data, strlen(data), &addr, sizeof(addr)); - emit me->Connected(); - break; - } - default: - op_name = "unknown"; - } - - qDebug() << op_name << (status == PJ_SUCCESS ? "succeeded" : "failed"); - -} - -int ICESession::HandleEvents(unsigned max_msec, unsigned* p_count) { - pj_time_val max_timeout = { 0, 0 }; - max_timeout.msec = max_msec; - - pj_time_val timeout = { 0, 0 }; - int c = pj_timer_heap_poll(sIceConfig.stun_cfg.timer_heap, &timeout); - int count = 0; - if (c > 0) { - count += c; - } - - if (timeout.msec >= 1000) { - timeout.msec = 999; - } - - if (PJ_TIME_VAL_GT(timeout, max_timeout)) { - timeout = max_timeout; - } - - static const int kMaxNetEvents = 1; - int net_event_count = 0; - do { - c = pj_ioqueue_poll(sIceConfig.stun_cfg.ioqueue, &timeout); - if (c < 0) { - pj_status_t err = pj_get_netos_error(); - pj_thread_sleep(PJ_TIME_VAL_MSEC(timeout)); - if (p_count) { - *p_count = count; - } - return err; - } else if (c == 0) { - break; - } else { - net_event_count += c; - timeout.sec = 0; - timeout.msec = 0; - } - - } while (c > 0 && net_event_count < kMaxNetEvents); - - count += net_event_count; - if (p_count) { - *p_count = count; - } - - return PJ_SUCCESS; -} - -int ICESession::WorkerThread(void*) { - forever { - HandleEvents(500, NULL); - } - return 0; -} - -void ICESession::PJLog(int level, const char* data, int len) { - //qLog(Debug) << QByteArray(data, len); -} - -void ICESession::StaticInit() { - //pj_log_set_log_func(&PJLog); - - pj_init(); - pjlib_util_init(); - pjnath_init(); - - pj_caching_pool_init(&sCachingPool, NULL, 0); - pj_ice_strans_cfg_default(&sIceConfig); - - sIceConfig.stun_cfg.pf = &sCachingPool.factory; - - sPool = pj_pool_create(&sCachingPool.factory, "clementine", 512, 512, NULL); - - pj_timer_heap_create(sPool, 100, &sIceConfig.stun_cfg.timer_heap); - pj_ioqueue_create(sPool, 16, &sIceConfig.stun_cfg.ioqueue); - - pj_thread_create(sPool, "clementine", &WorkerThread, NULL, 0, 0, &sThread); - - sIceConfig.af = pj_AF_INET(); - - sIceConfig.stun.server.ptr = strdup(kStunServer); - sIceConfig.stun.server.slen = strlen(kStunServer); - sIceConfig.stun.port = PJ_STUN_PORT; -} - -QDebug operator<< (QDebug dbg, const xrme::SIPInfo& session) { - dbg.nospace() << session.user_fragment.toAscii().constData() << ":" - << session.password.toAscii().constData() << ":"; - - const xrme::SIPInfo::Candidate& c = session.candidates[0]; - dbg.nospace() << c.address.toString().toAscii().constData() << ":" - << c.port << ":" - << c.type.toAscii().constData() << ":" - << c.component << ":" - << c.priority << ":" - << c.foundation.toAscii().constData(); - return dbg.space(); -} diff --git a/src/remote/icesession.h b/src/remote/icesession.h deleted file mode 100644 index f0f143d14..000000000 --- a/src/remote/icesession.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef ICESESSION_H -#define ICESESSION_H - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - - -class ICESession : public QIODevice { - Q_OBJECT - public: - enum Direction { - DirectionControlling = 0, - DirectionControlled, - }; - - explicit ICESession(QObject* parent = 0); - - static void StaticInit(); - bool Init(Direction direction); - - const xrme::SIPInfo& candidates() const { return candidates_; } - - void StartNegotiation(const xrme::SIPInfo& session); - - protected: - virtual qint64 readData(char* data, qint64 max_size); - virtual qint64 writeData(const char* data, qint64 max_size); - - signals: - void CandidatesAvailable(const xrme::SIPInfo& candidates); - void Connected(); - - private: - pj_ice_strans* ice_instance_; - int component_id_; - - xrme::SIPInfo candidates_; - - QByteArray receive_buffer_; - - void InitialisationComplete(pj_status_t status); - - static void PJLog(int level, const char* data, int len); - - static int HandleEvents(unsigned max_msec, unsigned* p_count); - static int WorkerThread(void*); - - static void OnReceiveData(pj_ice_strans* ice_st, - unsigned comp_id, - void* pkt, - pj_size_t size, - const pj_sockaddr_t* src_addr, - unsigned src_addr_len); - static void OnICEComplete(pj_ice_strans* ice_st, - pj_ice_strans_op op, - pj_status_t status); - - static pj_pool_t* sPool; - static pj_caching_pool sCachingPool; - static pj_ice_strans_cfg sIceConfig; - static pj_thread_t* sThread; - - static int sComponentId; - - static const char* kStunServer; -}; - -QDebug operator<< (QDebug dbg, const xrme::SIPInfo& session); - -#endif // ICESESSION_H diff --git a/src/remote/portforwarder.cpp b/src/remote/portforwarder.cpp index 0055db2d1..92cc5fea2 100644 --- a/src/remote/portforwarder.cpp +++ b/src/remote/portforwarder.cpp @@ -1,6 +1,6 @@ #include "portforwarder.h" -#include +#include #include "core/boundfuturewatcher.h" @@ -9,14 +9,15 @@ PortForwarder::PortForwarder(QObject* parent) } void PortForwarder::Init() { - QFuture future = QtConcurrent::run(this, &PortForwarder::Init); + QFuture future = QtConcurrent::run(this, &PortForwarder::InitSync); QFutureWatcher* watcher = new QFutureWatcher(this); watcher->setFuture(future); connect(watcher, SIGNAL(finished()), SLOT(InitFinished())); } -void PortForwarder::InitSync() { +bool PortForwarder::InitSync() { portfwd_.init(10000); + return true; } void PortForwarder::InitFinished() { @@ -31,9 +32,9 @@ void PortForwarder::AddPortMapping(quint16 port) { QFuture future = QtConcurrent::run( this, &PortForwarder::AddPortMappingSync, port); BoundFutureWatcher* watcher = - new BoundFutureWatcher(this); + new BoundFutureWatcher(port, this); watcher->setFuture(future); - connect(watcher, SIGNAL(finished()). SLOT(AddPortMappingFinished())); + connect(watcher, SIGNAL(finished()), SLOT(AddPortMappingFinished())); } bool PortForwarder::AddPortMappingSync(quint16 port) { @@ -54,9 +55,9 @@ void PortForwarder::RemovePortMapping(quint16 port) { QFuture future = QtConcurrent::run( this, &PortForwarder::RemovePortMappingSync, port); BoundFutureWatcher* watcher = - new BoundFutureWatcher(this); + new BoundFutureWatcher(port, this); watcher->setFuture(future); - connect(watcher, SIGNAL(finished()). SLOT(RemovePortMappingFinished())); + connect(watcher, SIGNAL(finished()), SLOT(RemovePortMappingFinished())); } bool PortForwarder::RemovePortMappingSync(quint16 port) { @@ -70,5 +71,5 @@ void PortForwarder::RemovePortMappingFinished() { watcher->deleteLater(); if (watcher->result()) - emit(PortMappingRemoveed(watcher->data())); + emit(PortMappingRemoved(watcher->data())); } diff --git a/src/remote/portforwarder.h b/src/remote/portforwarder.h index 19b777f36..981f9b115 100644 --- a/src/remote/portforwarder.h +++ b/src/remote/portforwarder.h @@ -19,7 +19,9 @@ class PortForwarder : public QObject { bool RemovePortMappingSync(quint16 port); private slots: + void InitFinished(); void AddPortMappingFinished(); + void RemovePortMappingFinished(); signals: void InitFinished(bool success); diff --git a/src/remote/remote.cpp b/src/remote/remote.cpp index a48506b4b..2c1834523 100644 --- a/src/remote/remote.cpp +++ b/src/remote/remote.cpp @@ -18,6 +18,7 @@ #include "remote.h" #include "remotesettingspage.h" #include "core/player.h" +#include "core/timeconstants.h" #include "engines/enginebase.h" #include "playlist/playlist.h" #include "playlist/playlistmanager.h" diff --git a/src/remote/streampipeline.cpp b/src/remote/streampipeline.cpp index 467228796..e4a45218d 100644 --- a/src/remote/streampipeline.cpp +++ b/src/remote/streampipeline.cpp @@ -2,6 +2,8 @@ #include +#include + #include "core/logging.h" const char* StreamPipeline::kPipeline =