Skip to content
Snippets Groups Projects
Commit ecf94dcf authored by Sébastien Blin's avatar Sébastien Blin Committed by Adrien Béraud
Browse files

sipcall: no more polling, use callbacks

Remove all addTask() calls. We can use callbacks now.

Change-Id: Ib0c8de5db57baa142aa094e915b46cf9ed7a06ad
GitLab: #355
parent e8a83cd6
Branches
No related tags found
No related merge requests found
......@@ -587,6 +587,8 @@ Sdp::getFilteredSdp(const pjmedia_sdp_session* session, unsigned media_keep, uns
std::vector<MediaDescription>
Sdp::getMediaSlots(const pjmedia_sdp_session* session, bool remote) const
{
if (!session)
return {};
static constexpr pj_str_t STR_RTPMAP {sip_utils::CONST_PJ_STR("rtpmap")};
static constexpr pj_str_t STR_FMTP {sip_utils::CONST_PJ_STR("fmtp")};
......
......@@ -1085,7 +1085,7 @@ SIPCall::getAudioCodec() const
void
SIPCall::startAllMedia()
{
if (!transport_)
if (!transport_ or !sdp_)
return;
JAMI_WARN("[call:%s] startAllMedia()", getCallId().c_str());
if (isSecure() && not transport_->isSecure()) {
......@@ -1320,82 +1320,64 @@ SIPCall::onMediaUpdate()
return;
}
if (not this_->isSubcall())
this_->waitForIceAndStartMedia();
this_->startIceMedia();
}
});
}
void
SIPCall::waitForIceAndStartMedia()
SIPCall::startIceMedia()
{
// Initialization waiting task
Manager::instance().addTask([weak_call = weak()] {
// TODO: polling algo, to it by event
if (auto call = weak_call.lock()) {
auto ice = call->getIceMediaTransport();
auto ice = getIceMediaTransport();
if (not ice or ice->isFailed()) {
JAMI_ERR("[call:%s] Media ICE init failed", call->getCallId().c_str());
call->onFailure(EIO);
return false;
JAMI_ERR("[call:%s] Media ICE init failed", getCallId().c_str());
onFailure(EIO);
return;
}
if (!ice->isInitialized())
return true;
if (ice->isStarted()) {
// NOTE: for incoming calls, the ice is already there and running
if (ice->isRunning())
onIceNegoSucceed();
return;
}
if (!ice->isInitialized()) {
// In this case, onInitDone will occurs after the startIceMedia
waitForIceInit_ = true;
return;
}
// Start transport on SDP data and wait for negotiation
auto rem_ice_attrs = call->sdp_->getIceAttributes();
auto rem_ice_attrs = sdp_->getIceAttributes();
if (rem_ice_attrs.ufrag.empty() or rem_ice_attrs.pwd.empty()) {
JAMI_ERR("[call:%s] Media ICE attributes empty", call->getCallId().c_str());
call->onFailure(EIO);
return false;
JAMI_ERR("[call:%s] Media ICE attributes empty", getCallId().c_str());
onFailure(EIO);
return;
}
if (not ice->start(rem_ice_attrs, call->getAllRemoteCandidates())) {
JAMI_ERR("[call:%s] Media ICE start failed", call->getCallId().c_str());
call->onFailure(EIO);
return false;
if (not ice->start(rem_ice_attrs, getAllRemoteCandidates())) {
JAMI_ERR("[call:%s] Media ICE start failed", getCallId().c_str());
onFailure(EIO);
}
// Negotiation waiting task
Manager::instance().addTask([weak_call] {
if (auto call = weak_call.lock()) {
std::lock_guard<std::recursive_mutex> lk {call->callMutex_};
auto ice = call->getIceMediaTransport();
if (not ice or ice->isFailed()) {
JAMI_ERR("[call:%s] Media ICE negotiation failed",
call->getCallId().c_str());
call->onFailure(EIO);
return false;
}
if (not ice->isRunning())
return true;
void
SIPCall::onIceNegoSucceed()
{
// Nego succeed: move to the new media transport
call->stopAllMedia();
stopAllMedia();
{
std::lock_guard<std::mutex> lk(call->transportMtx_);
if (call->tmpMediaTransport_) {
std::lock_guard<std::mutex> lk(transportMtx_);
if (tmpMediaTransport_) {
// Destroy the ICE media transport on another thread. This can take
// quite some time.
if (call->mediaTransport_)
dht::ThreadPool::io().run(
[ice = std::make_shared<decltype(call->mediaTransport_)>(
std::move(call->mediaTransport_))] {});
call->mediaTransport_ = std::move(call->tmpMediaTransport_);
if (mediaTransport_)
dht::ThreadPool::io().run([ice = std::move(mediaTransport_)] {});
mediaTransport_ = std::move(tmpMediaTransport_);
}
}
call->startAllMedia();
return false;
}
return false;
});
return false;
}
return false;
});
startAllMedia();
}
void
......@@ -1610,6 +1592,43 @@ SIPCall::initIceMediaTransport(bool master,
JAMI_DBG("[call:%s] create media ICE transport", getCallId().c_str());
auto iceOptions = options == std::nullopt ? acc->getIceOptions() : *options;
auto optOnInitDone = std::move(iceOptions.onInitDone);
auto optOnNegoDone = std::move(iceOptions.onNegoDone);
iceOptions.onInitDone = [w = weak(), cb = std::move(optOnInitDone)](bool ok) {
runOnMainThread([w = std::move(w), cb = std::move(cb), ok] {
auto call = w.lock();
if (cb)
cb(ok);
if (!ok or !call or !call->waitForIceInit_.exchange(false))
return;
std::lock_guard<std::recursive_mutex> lk {call->callMutex_};
auto rem_ice_attrs = call->sdp_->getIceAttributes();
// Init done but no remote_ice_attributes, the ice->start will be triggered lated
if (rem_ice_attrs.ufrag.empty() or rem_ice_attrs.pwd.empty())
return;
call->startIceMedia();
});
};
iceOptions.onNegoDone = [w = weak(), cb = std::move(optOnNegoDone)](bool ok) {
runOnMainThread([w = std::move(w), cb = std::move(cb), ok] {
if (cb)
cb(ok);
if (auto call = w.lock()) {
// The ICE is related to subcalls, but medias are handled by parent call
std::lock_guard<std::recursive_mutex> lk {call->callMutex_};
call = call->isSubcall() ? std::dynamic_pointer_cast<SIPCall>(call->parent_) : call;
if (!ok) {
JAMI_ERR("[call:%s] Media ICE negotiation failed", call->getCallId().c_str());
call->onFailure(EIO);
return;
}
call->onIceNegoSucceed();
}
});
};
auto& iceTransportFactory = Manager::instance().getIceTransportFactory();
tmpMediaTransport_ = iceTransportFactory.createUTransport(getCallId().c_str(),
channel_num,
......@@ -1646,8 +1665,7 @@ SIPCall::merge(Call& call)
}
Call::merge(subcall);
waitForIceAndStartMedia();
startIceMedia();
}
void
......@@ -1666,7 +1684,7 @@ SIPCall::setRemoteSdp(const pjmedia_sdp_session* sdp)
if (not initIceMediaTransport(false)) {
// Fatal condition
// TODO: what's SIP rfc says about that?
// (same question in waitForIceAndStartMedia)
// (same question in startIceMedia)
onFailure(EIO);
return;
}
......
......@@ -284,7 +284,8 @@ private:
void setCallMediaLocal();
void waitForIceAndStartMedia();
void startIceMedia();
void onIceNegoSucceed();
void startAllMedia();
void stopAllMedia();
......@@ -380,6 +381,8 @@ private:
OnReadyCb offHoldCb_ {};
bool peerRecording_ {false};
std::atomic_bool waitForIceInit_ {false};
};
// Helpers
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment