sipcall/ice: remove obsolete temporary shared pointer

This patch removes the temporary ICE shared pointer

Gitlab: #619

Change-Id: Icacac9df1102327d4d1a0f0d67dfa457016048cd
This commit is contained in:
Mohamed Chibani
2021-08-17 18:08:21 -04:00
committed by Sébastien Blin
parent 2053afe934
commit 910a5c5de3
7 changed files with 238 additions and 217 deletions

View File

@ -81,6 +81,8 @@ public:
Impl(const char* name, const IceTransportOptions& options);
~Impl();
void initIceInstance();
void onComplete(pj_ice_strans* ice_st, pj_ice_strans_op op, pj_status_t status);
void onReceiveData(unsigned comp_id, void* pkt, pj_size_t size);
@ -132,7 +134,10 @@ public:
int flushTimerHeapAndIoQueue();
int checkEventQueue(int maxEventToPoll);
std::string sessionName_ {};
std::unique_ptr<pj_pool_t, std::function<void(pj_pool_t*)>> pool_ {};
bool isTcp_ {false};
bool upnpEnabled_ {false};
IceTransportCompleteCb on_initdone_cb_ {};
IceTransportCompleteCb on_negodone_cb_ {};
IceRecvInfo on_recv_cb_ {};
@ -173,12 +178,18 @@ public:
std::vector<PeerChannel> peerChannels_ {};
std::vector<IpAddr> iceDefaultRemoteAddr_;
// ICE controlling role. True for controller agents and false for
// controlled agents
std::atomic_bool initiatorSession_ {true};
// Local/Public addresses used by the account owning the ICE instance.
IpAddr accountLocalAddr_ {};
IpAddr accountPublicAddr_ {};
// STUN and TURN servers
std::vector<StunServerInfo> stunServers_;
std::vector<TurnServerInfo> turnServers_;
/**
* Returns the IP of each candidate for a given component in the ICE session
*/
@ -294,7 +305,13 @@ add_turn_server(pj_pool_t& pool, pj_ice_strans_cfg& cfg, const TurnServerInfo& i
//==============================================================================
IceTransport::Impl::Impl(const char* name, const IceTransportOptions& options)
: pool_(nullptr, [](pj_pool_t* pool) { pj_pool_release(pool); })
: sessionName_(name)
, pool_(nullptr,
[](pj_pool_t* pool) {
pj_pool_release(pool);
})
, isTcp_(options.tcpEnable)
, upnpEnabled_(options.upnpEnable)
, on_initdone_cb_(options.onInitDone)
, on_negodone_cb_(options.onNegoDone)
, streamsCount_(options.streamsCount)
@ -306,158 +323,15 @@ IceTransport::Impl::Impl(const char* name, const IceTransportOptions& options)
, initiatorSession_(options.master)
, accountLocalAddr_(std::move(options.accountLocalAddr))
, accountPublicAddr_(std::move(options.accountPublicAddr))
, stunServers_(std::move(options.stunServers))
, turnServers_(std::move(options.turnServers))
, thread_()
{
JAMI_DBG("[ice:%p] Creating IceTransport session for \"%s\" - comp count %u - as a %s",
this,
name,
compCount_,
initiatorSession_ ? "master" : "slave");
if (options.upnpEnable)
upnp_.reset(new upnp::Controller());
auto& iceTransportFactory = Manager::instance().getIceTransportFactory();
config_ = iceTransportFactory.getIceCfg(); // config copy
if (options.tcpEnable) {
config_.protocol = PJ_ICE_TP_TCP;
config_.stun.conn_type = PJ_STUN_TP_TCP;
config_.turn.conn_type = PJ_TURN_TP_TCP;
} else {
config_.protocol = PJ_ICE_TP_UDP;
config_.stun.conn_type = PJ_STUN_TP_UDP;
config_.turn.conn_type = PJ_TURN_TP_UDP;
}
// Note: For server reflexive candidates, UPNP mappings will
// be used if available. Then, the public address learnt during
// the account registration process will be added only if it
// differs from the UPNP public address.
// Also note that UPNP candidates should be added first in order
// to have a higher priority when performing the connectivity
// checks.
// STUN configs layout:
// - index 0 : host IPv4
// - index 1 : host IPv6
// - index 2 : upnp/generic srflx IPv4.
// - index 3 : generic srflx (if upnp exists and different)
config_.stun_tp_cnt = 0;
JAMI_DBG("[ice:%p] Add host candidates", this);
addStunConfig(pj_AF_INET());
addStunConfig(pj_AF_INET6());
std::vector<std::pair<IpAddr, IpAddr>> upnpSrflxCand;
if (upnp_) {
requestUpnpMappings();
upnpSrflxCand = setupUpnpReflexiveCandidates();
if (not upnpSrflxCand.empty()) {
addServerReflexiveCandidates(upnpSrflxCand);
JAMI_DBG("[ice:%p] Added UPNP srflx candidates:", this);
}
}
auto genericSrflxCand = setupGenericReflexiveCandidates();
if (not genericSrflxCand.empty()) {
// Generic srflx candidates will be added only if different
// from upnp candidates.
if (upnpSrflxCand.empty()
or (upnpSrflxCand[0].second.toString() != genericSrflxCand[0].second.toString())) {
addServerReflexiveCandidates(genericSrflxCand);
JAMI_DBG("[ice:%p] Added generic srflx candidates:", this);
}
}
if (upnpSrflxCand.empty() and genericSrflxCand.empty()) {
JAMI_WARN("[ice:%p] No server reflexive candidates added", this);
}
pool_.reset(
pj_pool_create(iceTransportFactory.getPoolFactory(), "IceTransport.pool", 512, 512, NULL));
if (not pool_)
throw std::runtime_error("pj_pool_create() failed");
pj_ice_strans_cb icecb;
pj_bzero(&icecb, sizeof(icecb));
icecb.on_rx_data = [](pj_ice_strans* ice_st,
unsigned comp_id,
void* pkt,
pj_size_t size,
const pj_sockaddr_t* /*src_addr*/,
unsigned /*src_addr_len*/) {
if (auto* tr = static_cast<Impl*>(pj_ice_strans_get_user_data(ice_st)))
tr->onReceiveData(comp_id, pkt, size);
else
JAMI_WARN("null IceTransport");
};
icecb.on_ice_complete = [](pj_ice_strans* ice_st, pj_ice_strans_op op, pj_status_t status) {
if (auto* tr = static_cast<Impl*>(pj_ice_strans_get_user_data(ice_st)))
tr->onComplete(ice_st, op, status);
else
JAMI_WARN("null IceTransport");
};
icecb.on_data_sent = [](pj_ice_strans* ice_st, pj_ssize_t size) {
if (auto* tr = static_cast<Impl*>(pj_ice_strans_get_user_data(ice_st))) {
std::lock_guard<std::mutex> lk(tr->iceMutex_);
tr->lastSentLen_ += size;
tr->waitDataCv_.notify_all();
} else
JAMI_WARN("null IceTransport");
};
icecb.on_destroy = [](pj_ice_strans* ice_st) {
if (auto* tr = static_cast<Impl*>(pj_ice_strans_get_user_data(ice_st))) {
tr->destroying_ = true;
tr->waitDataCv_.notify_all();
if (tr->scb)
tr->scb();
} else {
JAMI_WARN("null IceTransport");
}
};
// Add STUN servers
for (auto& server : options.stunServers)
add_stun_server(*pool_, config_, server);
// Add TURN servers
for (auto& server : options.turnServers)
add_turn_server(*pool_, config_, server);
static constexpr auto IOQUEUE_MAX_HANDLES = std::min(PJ_IOQUEUE_MAX_HANDLES, 64);
TRY(pj_timer_heap_create(pool_.get(), 100, &config_.stun_cfg.timer_heap));
TRY(pj_ioqueue_create(pool_.get(), IOQUEUE_MAX_HANDLES, &config_.stun_cfg.ioqueue));
std::ostringstream sessionName {};
// We use the instance pointer as the PJNATH session name in order
// to easily identify the logs reported by PJNATH.
sessionName << this;
pj_status_t status = pj_ice_strans_create(sessionName.str().c_str(),
&config_,
compCount_,
this,
&icecb,
&icest_);
if (status != PJ_SUCCESS || icest_ == nullptr) {
throw std::runtime_error("pj_ice_strans_create() failed");
}
// Must be created after any potential failure
thread_ = std::thread([this] {
while (not threadTerminateFlags_) {
// NOTE: handleEvents can return false in this case
// but here we don't care if there is event or not.
handleEvents(HANDLE_EVENT_DURATION);
}
});
// Init to invalid addresses
iceDefaultRemoteAddr_.reserve(compCount_);
}
IceTransport::Impl::~Impl()
@ -510,6 +384,156 @@ IceTransport::Impl::~Impl()
JAMI_DBG("[ice:%p] done destroying", this);
}
void
IceTransport::Impl::initIceInstance()
{
if (upnpEnabled_)
upnp_.reset(new upnp::Controller());
auto& iceTransportFactory = Manager::instance().getIceTransportFactory();
config_ = iceTransportFactory.getIceCfg(); // config copy
if (isTcp_) {
config_.protocol = PJ_ICE_TP_TCP;
config_.stun.conn_type = PJ_STUN_TP_TCP;
config_.turn.conn_type = PJ_TURN_TP_TCP;
} else {
config_.protocol = PJ_ICE_TP_UDP;
config_.stun.conn_type = PJ_STUN_TP_UDP;
config_.turn.conn_type = PJ_TURN_TP_UDP;
}
pool_.reset(
pj_pool_create(iceTransportFactory.getPoolFactory(), "IceTransport.pool", 512, 512, NULL));
if (not pool_)
throw std::runtime_error("pj_pool_create() failed");
// Note: For server reflexive candidates, UPNP mappings will
// be used if available. Then, the public address learnt during
// the account registration process will be added only if it
// differs from the UPNP public address.
// Also note that UPNP candidates should be added first in order
// to have a higher priority when performing the connectivity
// checks.
// STUN configs layout:
// - index 0 : host IPv4
// - index 1 : host IPv6
// - index 2 : upnp/generic srflx IPv4.
// - index 3 : generic srflx (if upnp exists and different)
config_.stun_tp_cnt = 0;
JAMI_DBG("[ice:%p] Add host candidates", this);
addStunConfig(pj_AF_INET());
addStunConfig(pj_AF_INET6());
std::vector<std::pair<IpAddr, IpAddr>> upnpSrflxCand;
if (upnp_) {
requestUpnpMappings();
upnpSrflxCand = setupUpnpReflexiveCandidates();
if (not upnpSrflxCand.empty()) {
addServerReflexiveCandidates(upnpSrflxCand);
JAMI_DBG("[ice:%p] Added UPNP srflx candidates:", this);
}
}
auto genericSrflxCand = setupGenericReflexiveCandidates();
if (not genericSrflxCand.empty()) {
// Generic srflx candidates will be added only if different
// from upnp candidates.
if (upnpSrflxCand.empty()
or (upnpSrflxCand[0].second.toString() != genericSrflxCand[0].second.toString())) {
addServerReflexiveCandidates(genericSrflxCand);
JAMI_DBG("[ice:%p] Added generic srflx candidates:", this);
}
}
if (upnpSrflxCand.empty() and genericSrflxCand.empty()) {
JAMI_WARN("[ice:%p] No server reflexive candidates added", this);
}
pj_ice_strans_cb icecb;
pj_bzero(&icecb, sizeof(icecb));
icecb.on_rx_data = [](pj_ice_strans* ice_st,
unsigned comp_id,
void* pkt,
pj_size_t size,
const pj_sockaddr_t* /*src_addr*/,
unsigned /*src_addr_len*/) {
if (auto* tr = static_cast<Impl*>(pj_ice_strans_get_user_data(ice_st)))
tr->onReceiveData(comp_id, pkt, size);
else
JAMI_WARN("null IceTransport");
};
icecb.on_ice_complete = [](pj_ice_strans* ice_st, pj_ice_strans_op op, pj_status_t status) {
if (auto* tr = static_cast<Impl*>(pj_ice_strans_get_user_data(ice_st)))
tr->onComplete(ice_st, op, status);
else
JAMI_WARN("null IceTransport");
};
icecb.on_data_sent = [](pj_ice_strans* ice_st, pj_ssize_t size) {
if (auto* tr = static_cast<Impl*>(pj_ice_strans_get_user_data(ice_st))) {
std::lock_guard<std::mutex> lk(tr->iceMutex_);
tr->lastSentLen_ += size;
tr->waitDataCv_.notify_all();
} else
JAMI_WARN("null IceTransport");
};
icecb.on_destroy = [](pj_ice_strans* ice_st) {
if (auto* tr = static_cast<Impl*>(pj_ice_strans_get_user_data(ice_st))) {
tr->destroying_ = true;
tr->waitDataCv_.notify_all();
if (tr->scb)
tr->scb();
} else {
JAMI_WARN("null IceTransport");
}
};
// Add STUN servers
for (auto& server : stunServers_)
add_stun_server(*pool_, config_, server);
// Add TURN servers
for (auto& server : turnServers_)
add_turn_server(*pool_, config_, server);
static constexpr auto IOQUEUE_MAX_HANDLES = std::min(PJ_IOQUEUE_MAX_HANDLES, 64);
TRY(pj_timer_heap_create(pool_.get(), 100, &config_.stun_cfg.timer_heap));
TRY(pj_ioqueue_create(pool_.get(), IOQUEUE_MAX_HANDLES, &config_.stun_cfg.ioqueue));
std::ostringstream sessionName {};
// We use the instance pointer as the PJNATH session name in order
// to easily identify the logs reported by PJNATH.
sessionName << this;
pj_status_t status = pj_ice_strans_create(sessionName.str().c_str(),
&config_,
compCount_,
this,
&icecb,
&icest_);
if (status != PJ_SUCCESS || icest_ == nullptr) {
throw std::runtime_error("pj_ice_strans_create() failed");
}
// Must be created after any potential failure
thread_ = std::thread([this] {
while (not threadTerminateFlags_) {
// NOTE: handleEvents can return false in this case
// but here we don't care if there is event or not.
handleEvents(HANDLE_EVENT_DURATION);
}
});
// Init to invalid addresses
iceDefaultRemoteAddr_.reserve(compCount_);
}
bool
IceTransport::Impl::_isInitialized() const
{
@ -652,7 +676,7 @@ IceTransport::Impl::checkEventQueue(int maxEventToPoll)
}
void
IceTransport::Impl::onComplete(pj_ice_strans* ice_st, pj_ice_strans_op op, pj_status_t status)
IceTransport::Impl::onComplete(pj_ice_strans*, pj_ice_strans_op op, pj_status_t status)
{
const char* opname = op == PJ_ICE_STRANS_OP_INIT
? "initialization"
@ -1108,6 +1132,12 @@ IceTransport::~IceTransport()
cancelOperations();
}
void
IceTransport::initIceInstance()
{
pimpl_->initIceInstance();
}
bool
IceTransport::isInitialized() const
{

View File

@ -132,6 +132,9 @@ public:
*/
IceTransport(const char* name, const IceTransportOptions& options = {});
~IceTransport();
void initIceInstance();
/**
* Get current state
*/

View File

@ -574,6 +574,7 @@ ConnectionManager::Impl::connectDevice(const std::shared_ptr<dht::crypto::Certif
info->ice_ = Manager::instance()
.getIceTransportFactory()
.createUTransport(sthis->account.getAccountID().c_str(), ice_config);
info->ice_->initIceInstance();
if (!info->ice_) {
JAMI_ERR("Cannot initialize ICE session.");
@ -933,6 +934,8 @@ ConnectionManager::Impl::onDhtPeerRequest(const PeerConnectionRequest& req,
info->ice_ = Manager::instance()
.getIceTransportFactory()
.createUTransport(shared->account.getAccountID().c_str(), ice_config);
info->ice_->initIceInstance();
if (not info->ice_) {
JAMI_ERR("Cannot initialize ICE session.");
if (shared->connReadyCb_)

View File

@ -778,6 +778,8 @@ JamiAccount::onConnectedOutgoingCall(const std::shared_ptr<SIPCall>& call,
bool
JamiAccount::SIPStartCall(SIPCall& call, const IpAddr& target)
{
JAMI_DBG("Start SIP call [%s]", call.getCallId().c_str());
if (call.isIceEnabled())
call.addLocalIceAttributes();
@ -816,13 +818,6 @@ JamiAccount::SIPStartCall(SIPCall& call, const IpAddr& target)
inv->mod_data[link_.getModId()] = &call;
call.setInviteSession(inv);
/*
updateDialogViaSentBy(dialog);
if (hasServiceRoute())
pjsip_dlg_set_route_set(dialog, sip_utils::createRouteSet(getServiceRoute(),
call->inv->pool));
*/
pjsip_tx_data* tdata;
if (pjsip_inv_invite(call.inviteSession_.get(), &tdata) != PJ_SUCCESS) {

View File

@ -173,10 +173,7 @@ SIPCall::SIPCall(const std::shared_ptr<SIPAccountBase>& account,
SIPCall::~SIPCall()
{
std::lock_guard<std::recursive_mutex> lk {callMutex_};
{
std::lock_guard<std::mutex> lk(transportMtx_);
resetTransport(std::move(tmpMediaTransport_));
}
setTransport({});
setInviteSession(); // prevents callback usage
}
@ -855,7 +852,7 @@ SIPCall::answer(const std::vector<DRing::MediaMap>& mediaList)
generateMediaPorts();
// Setup and create ICE offer
if (account->isIceForMediaEnabled()) {
if (isIceEnabled()) {
sdp_->clearIce();
auto opts = account->getIceOptions();
@ -867,8 +864,8 @@ SIPCall::answer(const std::vector<DRing::MediaMap>& mediaList)
if (auto interfaceAddr = ip_utils::getInterfaceAddr(account->getLocalInterface(),
publicAddr.getFamily())) {
opts.accountLocalAddr = interfaceAddr;
initIceMediaTransport(true, std::move(opts));
addLocalIceAttributes();
if (initIceMediaTransport(true, std::move(opts)))
addLocalIceAttributes();
} else {
JAMI_WARN("[call:%s] Cant init ICE transport, missing local address",
getCallId().c_str());
@ -1456,7 +1453,6 @@ SIPCall::removeCall()
{
std::lock_guard<std::mutex> lk(transportMtx_);
resetTransport(std::move(mediaTransport_));
resetTransport(std::move(tmpMediaTransport_));
}
setInviteSession();
@ -1628,15 +1624,13 @@ SIPCall::onPeerRinging()
void
SIPCall::addLocalIceAttributes()
{
auto media_tr = getIceMediaTransport();
if (not media_tr) {
JAMI_WARN("[call:%s] no media ICE transport, SDP not changed", getCallId().c_str());
if (not mediaTransport_) {
JAMI_ERR("[call:%s] Invalid media ICE transport", getCallId().c_str());
return;
}
// we need an initialized ICE to progress further
if (media_tr->waitForInitialization(DEFAULT_ICE_INIT_TIMEOUT) <= 0) {
if (mediaTransport_->waitForInitialization(DEFAULT_ICE_INIT_TIMEOUT) <= 0) {
JAMI_ERR("[call:%s] Medias' ICE init failed", getCallId().c_str());
return;
}
@ -1651,10 +1645,12 @@ SIPCall::addLocalIceAttributes()
return;
}
JAMI_DBG("[call:%s] fill SDP with ICE transport %p", getCallId().c_str(), media_tr);
JAMI_DBG("[call:%s] Add local attributes for ICE instance [%p]",
getCallId().c_str(),
mediaTransport_.get());
if (isIceEnabled()) {
sdp_->addIceAttributes(media_tr->getLocalAttributes());
sdp_->addIceAttributes(mediaTransport_->getLocalAttributes());
}
if (account->isIceCompIdRfc5245Compliant()) {
@ -1674,11 +1670,12 @@ SIPCall::addLocalIceAttributes()
streamIdx);
// RTP
sdp_->addIceCandidates(streamIdx,
media_tr->getLocalCandidates(streamIdx, ICE_COMP_ID_RTP));
mediaTransport_->getLocalCandidates(streamIdx, ICE_COMP_ID_RTP));
// RTCP if it has its own port
if (not rtcpMuxEnabled_) {
sdp_->addIceCandidates(streamIdx,
media_tr->getLocalCandidates(streamIdx, ICE_COMP_ID_RTP + 1));
mediaTransport_->getLocalCandidates(streamIdx,
ICE_COMP_ID_RTP + 1));
}
streamIdx++;
@ -1696,12 +1693,12 @@ SIPCall::addLocalIceAttributes()
stream.mediaAttribute_->toString().c_str(),
idx);
// RTP
sdp_->addIceCandidates(idx, media_tr->getLocalCandidates(compId));
sdp_->addIceCandidates(idx, mediaTransport_->getLocalCandidates(compId));
compId++;
// RTCP if it has its own port
if (not rtcpMuxEnabled_) {
sdp_->addIceCandidates(idx, media_tr->getLocalCandidates(compId));
sdp_->addIceCandidates(idx, mediaTransport_->getLocalCandidates(compId));
compId++;
}
@ -1713,10 +1710,8 @@ SIPCall::addLocalIceAttributes()
std::vector<IceCandidate>
SIPCall::getAllRemoteCandidates()
{
auto media_tr = getIceMediaTransport();
if (not media_tr) {
JAMI_WARN("[call:%s] no media ICE transport", getCallId().c_str());
if (not mediaTransport_) {
JAMI_ERR("[call:%s] No media ICE transport", getCallId().c_str());
return {};
}
@ -1724,8 +1719,8 @@ SIPCall::getAllRemoteCandidates()
for (unsigned mediaIdx = 0; mediaIdx < static_cast<unsigned>(rtpStreams_.size()); mediaIdx++) {
IceCandidate cand;
for (auto& line : sdp_->getIceCandidates(mediaIdx)) {
if (media_tr->parseIceAttributeLine(mediaIdx, line, cand)) {
JAMI_DBG("[call:%s] add remote ICE candidate: %s",
if (mediaTransport_->parseIceAttributeLine(mediaIdx, line, cand)) {
JAMI_DBG("[call:%s] Add remote ICE candidate: %s",
getCallId().c_str(),
line.c_str());
rem_candidates.emplace_back(cand);
@ -2332,22 +2327,20 @@ SIPCall::startIceMedia()
{
JAMI_DBG("[call:%s] Starting ICE", getCallId().c_str());
auto ice = getIceMediaTransport();
if (not ice or ice->isFailed()) {
if (not mediaTransport_ or mediaTransport_->isFailed()) {
JAMI_ERR("[call:%s] Media ICE init failed", getCallId().c_str());
onFailure(EIO);
return;
}
if (ice->isStarted()) {
if (mediaTransport_->isStarted()) {
// NOTE: for incoming calls, the ice is already there and running
if (ice->isRunning())
if (mediaTransport_->isRunning())
onIceNegoSucceed();
return;
}
if (!ice->isInitialized()) {
if (not mediaTransport_->isInitialized()) {
// In this case, onInitDone will occurs after the startIceMedia
waitForIceInit_ = true;
return;
@ -2362,7 +2355,7 @@ SIPCall::startIceMedia()
onFailure(EIO);
return;
}
if (not ice->startIce(rem_ice_attrs, getAllRemoteCandidates())) {
if (not mediaTransport_->startIce(rem_ice_attrs, getAllRemoteCandidates())) {
JAMI_ERR("[call:%s] Media ICE start failed", getCallId().c_str());
onFailure(EIO);
}
@ -2387,13 +2380,7 @@ SIPCall::onIceNegoSucceed()
// Nego succeed: move to the new media transport
stopAllMedia();
{
std::unique_lock<std::mutex> lk(transportMtx_);
if (tmpMediaTransport_) {
resetTransport(std::move(mediaTransport_));
mediaTransport_ = std::move(tmpMediaTransport_);
}
}
startAllMedia();
}
@ -2563,7 +2550,7 @@ SIPCall::onReceiveOfferIn200OK(const pjmedia_sdp_session* offer)
openPortsUPnP();
}
if (acc->isIceForMediaEnabled()) {
if (isIceEnabled()) {
setupIceResponse();
}
@ -2823,9 +2810,8 @@ SIPCall::monitor() const
if (auto codec = getVideoCodec())
JAMI_DBG("\t- Video codec: %s", codec->systemCodecInfo.name.c_str());
#endif
auto media_tr = getIceMediaTransport();
if (media_tr) {
JAMI_DBG("\t- Medias: %s", media_tr->link().c_str());
if (mediaTransport_) {
JAMI_DBG("\t- Medias: %s", mediaTransport_->link().c_str());
}
}
@ -2954,30 +2940,30 @@ SIPCall::initIceMediaTransport(bool master, std::optional<IceTransportOptions> o
// Destroy old ice on a separate io pool
{
std::lock_guard<std::mutex> lk(transportMtx_);
resetTransport(std::move(tmpMediaTransport_));
tmpMediaTransport_ = std::move(transport);
resetTransport(std::move(mediaTransport_));
mediaTransport_ = iceTransportFactory.createTransport(getCallId().c_str(), iceOptions);
}
if (tmpMediaTransport_) {
if (mediaTransport_) {
JAMI_DBG("[call:%s] Successfully created media ICE transport [ice:%p]",
getCallId().c_str(),
tmpMediaTransport_.get());
mediaTransport_.get());
mediaTransport_->initIceInstance();
} else {
JAMI_ERR("[call:%s] Failed to create media ICE transport", getCallId().c_str());
}
return static_cast<bool>(tmpMediaTransport_);
return static_cast<bool>(mediaTransport_);
}
std::vector<std::string>
SIPCall::getLocalIceCandidates(unsigned compId) const
{
auto iceTransp = getIceMediaTransport();
if (not iceTransp) {
if (not mediaTransport_) {
JAMI_WARN("[call:%s] no media ICE transport", getCallId().c_str());
return {};
}
return iceTransp->getLocalCandidates(compId);
return mediaTransport_->getLocalCandidates(compId);
}
void
@ -3014,15 +3000,16 @@ SIPCall::merge(Call& call)
localVideoPort_ = subcall.localVideoPort_;
{
std::lock_guard<std::mutex> lk(transportMtx_);
resetTransport(std::move(mediaTransport_));
mediaTransport_ = std::move(subcall.mediaTransport_);
tmpMediaTransport_ = std::move(subcall.tmpMediaTransport_);
}
peerUserAgent_ = subcall.peerUserAgent_;
peerSupportMultiStream_ = subcall.peerSupportMultiStream_;
Call::merge(subcall);
startIceMedia();
if (isIceEnabled())
startIceMedia();
}
bool

View File

@ -277,12 +277,6 @@ public:
std::unique_ptr<pjsip_inv_session, InvSessionDeleter> inviteSession_;
private:
IceTransport* getIceMediaTransport() const
{
std::lock_guard<std::mutex> lk(transportMtx_);
return tmpMediaTransport_ ? tmpMediaTransport_.get() : mediaTransport_.get();
}
void generateMediaPorts();
void openPortsUPnP();
@ -437,9 +431,6 @@ private:
///< Transport used for media streams
std::shared_ptr<IceTransport> mediaTransport_;
///< Temporary transport for media. Replace mediaTransport_ when connected with success
std::unique_ptr<IceTransport> tmpMediaTransport_;
std::string peerUri_ {};
bool readyToRecord_ {false};

View File

@ -140,6 +140,7 @@ IceTest::testRawIceConnection()
ice_master = Manager::instance().getIceTransportFactory().createTransport("master ICE",
ice_config);
ice_master->initIceInstance();
cv_create.notify_all();
ice_config.onInitDone = [&](bool ok) {
CPPUNIT_ASSERT(ok);
@ -174,6 +175,8 @@ IceTest::testRawIceConnection()
ice_slave = Manager::instance().getIceTransportFactory().createTransport("slave ICE",
ice_config);
ice_slave->initIceInstance();
cv_create.notify_all();
CPPUNIT_ASSERT(
cv.wait_for(lk, std::chrono::seconds(10), [&] { return iceMasterReady && iceSlaveReady; }));
@ -246,6 +249,7 @@ IceTest::testTurnMasterIceConnection()
ice_config.compCountPerStream = 1;
ice_master = Manager::instance().getIceTransportFactory().createTransport("master ICE",
ice_config);
ice_master->initIceInstance();
cv_create.notify_all();
ice_config.turnServers = {};
ice_config.onInitDone = [&](bool ok) {
@ -289,6 +293,8 @@ IceTest::testTurnMasterIceConnection()
ice_config.compCountPerStream = 1;
ice_slave = Manager::instance().getIceTransportFactory().createTransport("slave ICE",
ice_config);
ice_slave->initIceInstance();
cv_create.notify_all();
CPPUNIT_ASSERT(
cv.wait_for(lk, std::chrono::seconds(10), [&] { return iceMasterReady && iceSlaveReady; }));
@ -356,6 +362,7 @@ IceTest::testTurnSlaveIceConnection()
ice_config.compCountPerStream = 1;
ice_master = Manager::instance().getIceTransportFactory().createTransport("master ICE",
ice_config);
ice_master->initIceInstance();
cv_create.notify_all();
ice_config.onInitDone = [&](bool ok) {
CPPUNIT_ASSERT(ok);
@ -403,6 +410,7 @@ IceTest::testTurnSlaveIceConnection()
ice_config.compCountPerStream = 1;
ice_slave = Manager::instance().getIceTransportFactory().createTransport("slave ICE",
ice_config);
ice_slave->initIceInstance();
cv_create.notify_all();
CPPUNIT_ASSERT(
cv.wait_for(lk, std::chrono::seconds(10), [&] { return iceMasterReady && iceSlaveReady; }));
@ -467,6 +475,7 @@ IceTest::testReceiveTooManyCandidates()
ice_master = Manager::instance().getIceTransportFactory().createTransport("master ICE",
ice_config);
ice_master->initIceInstance();
cv_create.notify_all();
ice_config.onInitDone = [&](bool ok) {
CPPUNIT_ASSERT(ok);
@ -509,6 +518,7 @@ IceTest::testReceiveTooManyCandidates()
ice_slave = Manager::instance().getIceTransportFactory().createTransport("slave ICE",
ice_config);
ice_slave->initIceInstance();
cv_create.notify_all();
CPPUNIT_ASSERT(
cv.wait_for(lk, std::chrono::seconds(10), [&] { return iceMasterReady && iceSlaveReady; }));
@ -575,6 +585,7 @@ IceTest::testCompleteOnFailure()
ice_config.compCountPerStream = 1;
ice_master = Manager::instance().getIceTransportFactory().createTransport("master ICE",
ice_config);
ice_master->initIceInstance();
cv_create.notify_all();
ice_config.onInitDone = [&](bool ok) {
CPPUNIT_ASSERT(ok);
@ -622,6 +633,7 @@ IceTest::testCompleteOnFailure()
ice_config.compCountPerStream = 1;
ice_slave = Manager::instance().getIceTransportFactory().createTransport("slave ICE",
ice_config);
ice_slave->initIceInstance();
cv_create.notify_all();
// Check that nego failed and callback called
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(120), [&] {