Commit c04cde48 authored by Guillaume Roguez's avatar Guillaume Roguez Committed by Olivier SOLDANO

call: move ICE transport into SIPCall class

Just moving all ICE transport related methods from Call class
into the SIPCall call.
This is done in the mind of refactoring media transport system.

Call is agnostic to transport implementation and this stuff
has to be handled by concrete classes of Call that known all about
transport information.

Note: <algorithm> included in audiolayer.cpp to make this patch
buildable on UWP platform.

Change-Id: I04b780dcff3483237a2de3c47ee667df9bba9f97
Reviewed-by: default avatarOlivier SOLDANO <olivier.soldano@savoirfairelinux.com>
parent c84633fc
......@@ -108,7 +108,6 @@ Call::removeCall()
{
auto this_ = shared_from_this();
Manager::instance().callFactory.removeCall(*this);
iceTransport_.reset();
setState(CallState::OVER);
recAudio_->closeFile();
}
......@@ -340,28 +339,6 @@ Call::getNullDetails()
};
}
bool
Call::initIceTransport(bool master, unsigned channel_num)
{
auto& iceTransportFactory = Manager::instance().getIceTransportFactory();
iceTransport_ = iceTransportFactory.createTransport(getCallId().c_str(),
channel_num, master,
account_.getIceOptions());
return static_cast<bool>(iceTransport_);
}
bool
Call::isIceRunning() const
{
return iceTransport_ and iceTransport_->isRunning();
}
std::unique_ptr<IceSocket>
Call::newIceSocket(unsigned compId)
{
return std::unique_ptr<IceSocket> {new IceSocket(iceTransport_, compId)};
}
void
Call::onTextMessage(std::map<std::string, std::string>&& messages)
{
......@@ -497,7 +474,6 @@ Call::merge(Call& subcall)
std::lock_guard<std::recursive_mutex> lk1 {callMutex_, std::adopt_lock};
std::lock_guard<std::recursive_mutex> lk2 {subcall.callMutex_, std::adopt_lock};
pendingInMessages_ = std::move(subcall.pendingInMessages_);
iceTransport_ = std::move(subcall.iceTransport_);
if (peerNumber_.empty())
peerNumber_ = std::move(subcall.peerNumber_);
peerDisplayName_ = std::move(subcall.peerDisplayName_);
......
......@@ -31,7 +31,6 @@
#include "recordable.h"
#include "ip_utils.h"
#include "ice_transport.h"
#include <mutex>
#include <map>
......@@ -289,16 +288,6 @@ class Call : public Recordable, public std::enable_shared_from_this<Call> {
void onTextMessage(std::map<std::string, std::string>&& messages);
virtual bool initIceTransport(bool master, unsigned channel_num=4);
bool isIceRunning() const;
std::unique_ptr<IceSocket> newIceSocket(unsigned compId);
std::shared_ptr<IceTransport> getIceTransport() const {
return iceTransport_;
}
virtual bool useVideoCodec(const AccountVideoCodecInfo* /*codec*/) const {
return false;
}
......@@ -319,8 +308,6 @@ class Call : public Recordable, public std::enable_shared_from_this<Call> {
// TODO all these members are not protected against multi-thread access
std::shared_ptr<IceTransport> iceTransport_ {};
bool isAudioMuted_{false};
bool isVideoMuted_{false};
......
......@@ -51,6 +51,7 @@ class RingBufferPool;
class VideoManager;
class Conference;
class AudioLoop;
class IceTransportFactory;
/** Manager (controller) of Ring daemon */
class Manager {
......
......@@ -29,6 +29,7 @@
#include "client/ring_signal.h"
#include <ctime>
#include <algorithm>
namespace ring {
......
......@@ -564,13 +564,13 @@ RingAccount::createOutgoingCall(const std::shared_ptr<SIPCall>& call, const std:
{
RING_WARN("RingAccount::createOutgoingCall to: %s target: %s",
to_id.c_str(), target.toString(true).c_str());
call->initIceTransport(true);
call->initIceMediaTransport(true);
call->setIPToIP(true);
call->setPeerNumber(getToUri(to_id+"@"+target.toString(true).c_str()));
call->initRecFilename(to_id);
const auto localAddress = ip_utils::getInterfaceAddr(getLocalInterface());
call->setCallMediaLocal(call->getIceTransport()->getDefaultLocalAddress());
call->setCallMediaLocal(call->getIceMediaTransport()->getDefaultLocalAddress());
IpAddr addrSdp;
if (getUPnPActive()) {
......
......@@ -200,7 +200,7 @@ SIPAccount::newOutgoingCall(const std::string& toUrl)
}
auto toUri = getToUri(to);
call->initIceTransport(true);
call->initIceMediaTransport(true);
call->setIPToIP(isIP2IP());
call->setPeerNumber(toUri);
call->initRecFilename(to);
......
......@@ -40,6 +40,7 @@
#include "dring/call_const.h"
#include "dring/media_const.h"
#include "client/ring_signal.h"
#include "ice_transport.h"
#ifdef RING_VIDEO
#include "client/videomanager.h"
......@@ -232,7 +233,7 @@ SIPCall::SIPSessionReinvite()
getState() == CallState::HOLD))
return !PJ_SUCCESS;
if (initIceTransport(true))
if (initIceMediaTransport(true))
setupLocalSDPFromIce();
pjsip_tx_data* tdata;
......@@ -684,6 +685,7 @@ SIPCall::removeCall()
{
RING_WARN("[call:%s] removeCall()", getCallId().c_str());
Call::removeCall();
mediaTransport_.reset();
inv.reset();
setTransport({});
}
......@@ -724,25 +726,25 @@ SIPCall::onPeerRinging()
void
SIPCall::setupLocalSDPFromIce()
{
if (not iceTransport_) {
if (not mediaTransport_) {
RING_WARN("[call:%s] null icetransport, no attributes added to SDP", getCallId().c_str());
return;
}
// we need an initialized ICE to progress further
if (iceTransport_->waitForInitialization(DEFAULT_ICE_INIT_TIMEOUT) <= 0) {
if (mediaTransport_->waitForInitialization(DEFAULT_ICE_INIT_TIMEOUT) <= 0) {
RING_ERR("[call:%s] Medias' ICE init failed", getCallId().c_str());
return;
}
sdp_->addIceAttributes(iceTransport_->getLocalAttributes());
sdp_->addIceAttributes(mediaTransport_->getLocalAttributes());
// Add video and audio channels
sdp_->addIceCandidates(SDP_AUDIO_MEDIA_ID, iceTransport_->getLocalCandidates(ICE_AUDIO_RTP_COMPID));
sdp_->addIceCandidates(SDP_AUDIO_MEDIA_ID, iceTransport_->getLocalCandidates(ICE_AUDIO_RTCP_COMPID));
sdp_->addIceCandidates(SDP_AUDIO_MEDIA_ID, mediaTransport_->getLocalCandidates(ICE_AUDIO_RTP_COMPID));
sdp_->addIceCandidates(SDP_AUDIO_MEDIA_ID, mediaTransport_->getLocalCandidates(ICE_AUDIO_RTCP_COMPID));
#ifdef RING_VIDEO
sdp_->addIceCandidates(SDP_VIDEO_MEDIA_ID, iceTransport_->getLocalCandidates(ICE_VIDEO_RTP_COMPID));
sdp_->addIceCandidates(SDP_VIDEO_MEDIA_ID, iceTransport_->getLocalCandidates(ICE_VIDEO_RTCP_COMPID));
sdp_->addIceCandidates(SDP_VIDEO_MEDIA_ID, mediaTransport_->getLocalCandidates(ICE_VIDEO_RTP_COMPID));
sdp_->addIceCandidates(SDP_VIDEO_MEDIA_ID, mediaTransport_->getLocalCandidates(ICE_VIDEO_RTCP_COMPID));
#endif
}
......@@ -755,7 +757,7 @@ SIPCall::getAllRemoteCandidates()
std::vector<IceCandidate>& out) {
IceCandidate cand;
for (auto& line : sdp_->getIceCandidates(sdpMediaId)) {
if (iceTransport_->getCandidateFromSDP(line, cand)) {
if (mediaTransport_->getCandidateFromSDP(line, cand)) {
RING_DBG("[call:%s] add remote ICE candidate: %s", getCallId().c_str(), line.c_str());
out.emplace_back(cand);
}
......@@ -773,9 +775,9 @@ SIPCall::getAllRemoteCandidates()
bool
SIPCall::startIce()
{
if (not iceTransport_ or iceTransport_->isFailed() or not iceTransport_->isInitialized())
if (not mediaTransport_ or mediaTransport_->isFailed() or not mediaTransport_->isInitialized())
return false;
if (iceTransport_->isStarted()) {
if (mediaTransport_->isStarted()) {
RING_DBG("[call:%s] ICE already started", getCallId().c_str());
return true;
}
......@@ -784,7 +786,7 @@ SIPCall::startIce()
RING_ERR("[call:%s] ICE empty attributes", getCallId().c_str());
return false;
}
return iceTransport_->start(rem_ice_attrs, getAllRemoteCandidates());
return mediaTransport_->start(rem_ice_attrs, getAllRemoteCandidates());
}
bool
......@@ -965,23 +967,23 @@ SIPCall::onMediaUpdate()
void
SIPCall::waitForIceAndStartMedia()
{
auto ice = iceTransport_;
auto ice = mediaTransport_;
auto iceTimeout = std::chrono::steady_clock::now() + std::chrono::seconds(10);
auto wthis = std::weak_ptr<SIPCall>(std::static_pointer_cast<SIPCall>(shared_from_this()));
Manager::instance().addTask([wthis,ice,iceTimeout] {
if (auto sthis = wthis.lock()) {
auto& this_ = *sthis;
if (ice != this_.iceTransport_) {
if (ice != this_.mediaTransport_) {
RING_WARN("[call:%s] ICE transport replaced", this_.getCallId().c_str());
return false;
}
/* First step: wait for an ICE transport for SIP channel */
if (this_.iceTransport_->isFailed() or std::chrono::steady_clock::now() >= iceTimeout) {
if (this_.mediaTransport_->isFailed() or std::chrono::steady_clock::now() >= iceTimeout) {
RING_DBG("[call:%s] ICE init failed (or timeout)", this_.getCallId().c_str());
this_.onFailure(ETIMEDOUT);
return false;
}
if (not this_.iceTransport_->isRunning())
if (not this_.mediaTransport_->isRunning())
return true;
this_.startAllMedia();
}
......@@ -1100,16 +1102,19 @@ SIPCall::InvSessionDeleter::operator ()(pjsip_inv_session* inv) const noexcept
}
bool
SIPCall::initIceTransport(bool master, unsigned channel_num)
SIPCall::initIceMediaTransport(bool master, unsigned channel_num)
{
auto result = Call::initIceTransport(master, channel_num);
if (result) {
auto& iceTransportFactory = Manager::instance().getIceTransportFactory();
mediaTransport_ = iceTransportFactory.createTransport(getCallId().c_str(),
channel_num, master,
getAccount().getIceOptions());
if (mediaTransport_) {
if (const auto& publicIP = getSIPAccount().getPublishedIpAddress()) {
for (unsigned compId = 1; compId <= iceTransport_->getComponentCount(); ++compId)
iceTransport_->registerPublicIP(compId, publicIP);
for (unsigned compId = 1; compId <= mediaTransport_->getComponentCount(); ++compId)
mediaTransport_->registerPublicIP(compId, publicIP);
}
}
return result;
return static_cast<bool>(mediaTransport_);
}
void
......@@ -1130,10 +1135,11 @@ SIPCall::merge(Call& call)
pj_strcpy(&contactHeader_, &subcall.contactHeader_);
localAudioPort_ = subcall.localAudioPort_;
localVideoPort_ = subcall.localVideoPort_;
mediaTransport_ = std::move(subcall.mediaTransport_);
Call::merge(subcall);
if (iceTransport_->isStarted())
if (mediaTransport_->isStarted())
waitForIceAndStartMedia();
}
......@@ -1145,12 +1151,24 @@ SIPCall::setRemoteSdp(const pjmedia_sdp_session* sdp)
auto ice_attrs = Sdp::getIceAttributes(sdp);
if (not ice_attrs.ufrag.empty() and not ice_attrs.pwd.empty()) {
if (not getIceTransport()) {
if (not mediaTransport_) {
RING_DBG("Initializing ICE transport");
initIceTransport(false);
initIceMediaTransport(false);
}
setupLocalSDPFromIce();
}
}
bool
SIPCall::isIceRunning() const
{
return mediaTransport_ and mediaTransport_->isRunning();
}
std::unique_ptr<IceSocket>
SIPCall::newIceSocket(unsigned compId)
{
return std::unique_ptr<IceSocket> {new IceSocket(mediaTransport_, compId)};
}
} // namespace ring
......@@ -43,6 +43,7 @@
struct pjsip_evsub;
struct pjsip_inv_session;
struct pjmedia_sdp_session;
struct pj_ice_sess_cand;
namespace ring {
......@@ -50,6 +51,10 @@ class Sdp;
class SIPAccountBase;
class SipTransport;
class AudioRtpSession;
class IceTransport;
class IceSocket;
using IceCandidate = pj_ice_sess_cand;
namespace upnp {
class Controller;
......@@ -99,7 +104,6 @@ public: // overridden
void restartMediaReceiver() override;
bool useVideoCodec(const AccountVideoCodecInfo* codec) const override;
std::map<std::string, std::string> getDetails() const override;
bool initIceTransport(bool master, unsigned channel_num=4) override;
public: // SIP related
/**
......@@ -207,6 +211,16 @@ public: // NOT SIP RELATED (good candidates to be moved elsewhere)
peerRegistredName_ = name;
}
bool initIceMediaTransport(bool master, unsigned channel_num=4);
bool isIceRunning() const;
std::unique_ptr<IceSocket> newIceSocket(unsigned compId);
std::shared_ptr<IceTransport> getIceMediaTransport() const {
return mediaTransport_;
}
private:
NON_COPYABLE(SIPCall);
......@@ -265,6 +279,9 @@ private:
/** Local video port, as seen by me. */
unsigned int localVideoPort_ {0};
///< Transport used for media streams
std::shared_ptr<IceTransport> mediaTransport_ {};
};
// Helpers
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment