diff --git a/deps/libjuice b/deps/libjuice index 92fc9e7..6942c8b 160000 --- a/deps/libjuice +++ b/deps/libjuice @@ -1 +1 @@ -Subproject commit 92fc9e7a9d8cd19a5c5d59cbc0a11cc9f684483b +Subproject commit 6942c8b521dad09dd5d380bf580cdc008562f55e diff --git a/src/candidate.cpp b/src/candidate.cpp index 111057b..9fe5d5b 100644 --- a/src/candidate.cpp +++ b/src/candidate.cpp @@ -52,10 +52,12 @@ Candidate::Candidate(string candidate, string mid) : mFamily(Family::Unresolved), mType(Type::Unknown), mTransportType(TransportType::Unknown), mPort(0), mPriority(0) { - const std::array prefixes{"a=", "candidate:"}; - for (const string &prefix : prefixes) - if (hasprefix(candidate, prefix)) - candidate.erase(0, prefix.size()); + if (!candidate.empty()) { + const std::array prefixes{"a=", "candidate:"}; + for (const string &prefix : prefixes) + if (hasprefix(candidate, prefix)) + candidate.erase(0, prefix.size()); + } mCandidate = std::move(candidate); mMid = std::move(mid); diff --git a/src/icetransport.cpp b/src/icetransport.cpp index b84f85a..a6b2fd3 100644 --- a/src/icetransport.cpp +++ b/src/icetransport.cpp @@ -187,6 +187,24 @@ std::optional IceTransport::getRemoteAddress() const { return nullopt; } +bool IceTransport::getSelectedCandidatePair(Candidate *local, Candidate *remote) { + char sdpLocal[JUICE_MAX_CANDIDATE_SDP_STRING_LEN]; + char sdpRemote[JUICE_MAX_CANDIDATE_SDP_STRING_LEN]; + if (juice_get_selected_candidates(mAgent.get(), sdpLocal, JUICE_MAX_CANDIDATE_SDP_STRING_LEN, + sdpRemote, JUICE_MAX_CANDIDATE_SDP_STRING_LEN) == 0) { + if (local) { + *local = Candidate(sdpLocal); + local->resolve(Candidate::ResolveMode::Simple); + } + if (remote) { + *remote = Candidate(sdpRemote); + remote->resolve(Candidate::ResolveMode::Simple); + } + return true; + } + return false; +} + bool IceTransport::send(message_ptr message) { auto s = state(); if (!message || (s != State::Connected && s != State::Completed)) @@ -729,8 +747,10 @@ bool IceTransport::getSelectedCandidatePair(Candidate *local, Candidate *remote) if(remote) *remote = Candidate(sdpRemote); g_free(sdpRemote); - local->resolve(Candidate::ResolveMode::Simple); - remote->resolve(Candidate::ResolveMode::Simple); + if (local) + local->resolve(Candidate::ResolveMode::Simple); + if (remote) + remote->resolve(Candidate::ResolveMode::Simple); return true; } diff --git a/src/icetransport.hpp b/src/icetransport.hpp index ea44f4f..7fe33e5 100644 --- a/src/icetransport.hpp +++ b/src/icetransport.hpp @@ -63,9 +63,7 @@ public: bool stop() override; bool send(message_ptr message) override; // false if dropped -#if USE_NICE bool getSelectedCandidatePair(Candidate *local, Candidate *remote); -#endif private: bool outgoing(message_ptr message) override; diff --git a/src/peerconnection.cpp b/src/peerconnection.cpp index 50c9a15..7707a05 100644 --- a/src/peerconnection.cpp +++ b/src/peerconnection.cpp @@ -902,13 +902,8 @@ void PeerConnection::resetCallbacks() { bool PeerConnection::getSelectedCandidatePair([[maybe_unused]] Candidate *local, [[maybe_unused]] Candidate *remote) { -#if USE_NICE auto iceTransport = std::atomic_load(&mIceTransport); - return iceTransport->getSelectedCandidatePair(local, remote); -#else - PLOG_WARNING << "getSelectedCandidatePair() is only implemented with libnice as ICE backend"; - return false; -#endif + return iceTransport ? iceTransport->getSelectedCandidatePair(local, remote) : false; } void PeerConnection::clearStats() { diff --git a/test/connectivity.cpp b/test/connectivity.cpp index eb1bc56..e42f23e 100644 --- a/test/connectivity.cpp +++ b/test/connectivity.cpp @@ -147,6 +147,16 @@ void test_connectivity() { if (auto addr = pc2->remoteAddress()) cout << "Remote address 2: " << *addr << endl; + Candidate local, remote; + if(pc1->getSelectedCandidatePair(&local, &remote)) { + cout << "Local candidate 1: " << local << endl; + cout << "Remote candidate 1: " << remote << endl; + } + if(pc2->getSelectedCandidatePair(&local, &remote)) { + cout << "Local candidate 2: " << local << endl; + cout << "Remote candidate 2: " << remote << endl; + } + // Try to open a second data channel with another label shared_ptr second2; pc2->onDataChannel([&second2](shared_ptr dc) {